source: SMSSender/src/ui/VCMain/vcmain.cpp @ 56:e63ceb8090cd

3.0
Last change on this file since 56:e63ceb8090cd was 56:e63ceb8090cd, checked in by Sämy Zehnder <saemy.zehnder@…>, 12 years ago
  • Renamed accountmodel to accounttreemodel
  • Implemented creation of new contact if number is unknown in vcmain
  • Areacode is now in its own field in vceditcontact
  • Accountlist in vcmain is now controlled by a model (Needs filtering of only active ones)
  • Settingspath is dynamic and user-based now
File size: 12.7 KB
Line 
1#include "vcmain.h"
2
3#include <QSortFilterProxyModel>
4#include <QMessageBox>
5
6#include <QCompleter>
7#include <QDebug>
8
9#include <algorithm>
10
11#include <snumber.h>
12#include <typeconvert.h>
13
14#include <icontact.h>
15
16#include "../../business/BusinessFactory.h"
17#include "../../business/BCAccountManager.h"
18#include "../../business/BCContactManager.h"
19#include "../../business/BCGroupManager.h"
20
21#include "../UIHelper.h"
22
23#include "../VCAccountList/vcaccountlist.h"
24#include "../VCAddressBook/vcaddressbook.h"
25#include "../VCEditContact/vceditcontact.h"
26#include "../VCSettings/vcsettings.h"
27
28#include "../completers/bettercompleter.h"
29#include "../models/aliascompletionmodel.h"
30
31#include "../delegates/aligndelegate.h"
32
33
34VCMain::VCMain(QWidget *parent): QMainWindow(parent){
35        ui.setupUi(this);
36
37        /* Accounts */
38        accountModel_       = new AccountTreeModel(this);
39        accountFilterModel_ = new QSortFilterProxyModel(this);
40        accountFilterModel_->setSourceModel(accountModel_);
41        accountFilterModel_->setSortCaseSensitivity(Qt::CaseInsensitive);
42        accountFilterModel_->setDynamicSortFilter(true);
43        accountFilterModel_->setFilterKeyColumn(AccountTreeModel::ColEnabled);
44        accountFilterModel_->setFilterRole(Qt::CheckStateRole);
45        accountFilterModel_->setFilterFixedString("1"); // Get only enabled ones
46        accountFilterModel_->sort(AccountTreeModel::ColName, Qt::AscendingOrder);
47        ui.lstAccounts->setModel(accountFilterModel_);
48
49        /* Contact / Groups */
50        contactGroupListModel_ = new ContactGroupListModel(this);
51        contactGroupSortModel_ = new QSortFilterProxyModel(this);
52        contactGroupSortModel_->setSourceModel(contactGroupListModel_);
53        contactGroupSortModel_->setDynamicSortFilter(true);
54        contactGroupSortModel_->setSortCaseSensitivity(Qt::CaseInsensitive);
55        contactGroupSortModel_->sort(0, Qt::AscendingOrder);
56    ui.lstContacts->setModel(contactGroupSortModel_);
57
58        QSortFilterProxyModel* completionModel = new AliasCompletionModel(this);
59    completionModel->setSourceModel(contactGroupListModel_);
60    BetterCompleter* aliasCompleter = new BetterCompleter(completionModel, this);
61    aliasCompleter->setCompletionMode(QCompleter::PopupCompletion);
62    aliasCompleter->setCaseSensitivity(Qt::CaseInsensitive);
63
64    ui.lstContacts->setCompleter(aliasCompleter);
65    ui.lstContacts->completer()->popup()->setIconSize(QSize(24, 24));
66
67    connect(ui.lstContacts->lineEdit(), SIGNAL(returnPressed()),
68            this, SLOT(on_btnAddRecipient_clicked()));
69
70    connect(aliasCompleter, SIGNAL(highlighted(const QString&)),
71            this, SLOT(on_lstContacts_completer_changed(const QString&)));
72
73
74    connect(BCAccountLoadManager::instance(), SIGNAL(accountLoadStateChanged(IAccount*, AccountLoadState)),
75            this, SLOT(on_accountLoadStateChanged(IAccount*, AccountLoadState)));
76    connect(BCAccountLoadManager::instance(), SIGNAL(accountLoaded(IAccount*)),
77            this, SLOT(on_accountLoaded(IAccount*)));
78    connect(BCAccountLoadManager::instance(), SIGNAL(accountLoadingFailed(IAccount*, EException*)),
79            this, SLOT(on_accountLoadingFailed(IAccount*, EException*)));
80
81
82    // First "signal" to initialize some slots
83    on_treeRecipients_itemSelectionChanged();
84
85        ui.lstContacts->setCurrentIndex(-1);
86}
87
88/* Contacts & Recipients... */
89bool VCMain::isContactNode(const QTreeWidgetItem* node){
90    return nodeToContact.contains(const_cast<QTreeWidgetItem*>(node));
91}
92bool VCMain::isGroupNode(const QTreeWidgetItem* node){
93    return nodeToGroup.contains(const_cast<QTreeWidgetItem*>(node));
94}
95
96IContact* VCMain::getContactOfNode(const QTreeWidgetItem* node){
97    if (!isContactNode(node)){
98        return (IContact*)0;
99    } else {
100        return nodeToContact[const_cast<QTreeWidgetItem*>(node)];
101    }
102}
103IGroup* VCMain::getGroupOfNode(const QTreeWidgetItem* node){
104    if (!isGroupNode(node)){
105        return (IGroup*)0;
106    } else {
107        return nodeToGroup[const_cast<QTreeWidgetItem*>(node)];
108    }
109}
110
111bool VCMain::isNodeContactOrHasContact(const QTreeWidgetItem* node, IContact* contact){
112    if (isContactNode(node)){
113        IContact* contact_ = getContactOfNode(node);
114        if (contact->id() == contact_->id()){
115            return true;
116        }
117    } else {
118        // group...
119        for (int x = 0; x < node->childCount(); ++x){
120            if (isNodeContactOrHasContact(node->child(x), contact)){
121                return true;
122            }
123        }
124    }
125    return false;
126
127}
128
129bool VCMain::isContactAlreadyRecipient(IContact* contact){
130    return getRecipientContacts(true).contains(contact);
131}
132bool VCMain::isGroupAlreadyRecipient(IGroup* group){
133    return getRecipientGroups().contains(group);
134}
135
136QSet<IContact*> VCMain::getRecipientContacts(bool withGroupContacts /* = true */, QTreeWidgetItem* node /* = NULL */) {
137    QSet<IContact*> result;
138
139    if (node == NULL) {
140        for (int i = 0; i < ui.treeRecipients->topLevelItemCount(); ++i) {
141            result.unite(getRecipientContacts(withGroupContacts, ui.treeRecipients->topLevelItem(i)));
142        }
143    }
144
145    if (isContactNode(node)) {
146        result.insert(getContactOfNode(node));
147    } else if (withGroupContacts && isGroupNode(node)) {
148        for (int i = 0; i < node->childCount(); ++i) {
149            result.unite(getRecipientContacts(withGroupContacts, node->child(i)));
150        }
151    }
152
153    return result;
154}
155
156QSet<IGroup*> VCMain::getRecipientGroups() {
157    QSet<IGroup*> result;
158    for (int x = 0; x < ui.treeRecipients->topLevelItemCount(); ++x){
159        if (isGroupNode(ui.treeRecipients->topLevelItem(x))){
160            result.insert(getGroupOfNode(ui.treeRecipients->topLevelItem(x)));
161        }
162    }
163    return result;
164}
165
166
167void VCMain::addRecipient(IContact* contact, QTreeWidgetItem* parent /* = NULL */){
168    if ((contact == NULL) || isContactAlreadyRecipient(contact)){
169        return;
170    }
171
172    // TODO: Check if the given recipient/number is a valid recipient for the selected gateway
173
174    contactGroupListModel_->addFilteredContact(contact);
175
176    QTreeWidgetItem* node;
177    if (parent) {
178        node = new QTreeWidgetItem(parent); // parent->addChild is done in here
179    } else {
180        node = new QTreeWidgetItem(ui.treeRecipients);
181        ui.treeRecipients->addTopLevelItem(node);
182    }
183
184    node->setText(0, contact->name());
185    node->setIcon(0, QPixmap::fromImage(contact->image()));
186    nodeToContact[node] = contact;
187}
188
189void VCMain::addRecipient(IGroup* group){
190    if ((group == NULL) || isGroupAlreadyRecipient(group)){
191        return;
192    }
193
194    QTreeWidgetItem* node = new QTreeWidgetItem(ui.treeRecipients);
195    ui.treeRecipients->addTopLevelItem(node);
196
197    node->setText(0, group->name());
198    node->setIcon(0, QPixmap::fromImage(group->image()));
199    nodeToGroup[node] = group;
200
201    foreach (IContact* contact, group->contacts()) {
202        addRecipient(contact, node);
203    }
204}
205
206void VCMain::removeNode(QTreeWidgetItem* node){
207    QTreeWidgetItem* parent = node->parent();
208    if (parent){
209        parent->removeChild(node);
210
211        if (parent->childCount() == 0){
212            removeRecipient(parent);
213        }
214    } else {
215        ui.treeRecipients->takeTopLevelItem(ui.treeRecipients->indexOfTopLevelItem(node));
216    }
217}
218void VCMain::removeRecipient(QTreeWidgetItem* node){
219    if (isContactNode(node)){
220        IContact* contact = nodeToContact[node];
221        contactGroupListModel_->removeFilteredContact(contact);
222
223        removeNode(node);
224        nodeToContact.remove(node);
225    } else { // Group
226        for (int x = 0; x < node->childCount(); ++x){
227            removeRecipient(node->child(x)); // Remove all contacts of this group
228        }
229
230        removeNode(node);
231        nodeToGroup.remove(node);
232    }
233}
234
235
236void VCMain::reloadAccountList() {
237/*    accountStrToAccount.clear();
238    QComboBox* accLst = ui.lstAccounts;
239
240    QString selectedAccount = accLst->currentText();
241
242    accLst->clear();
243    foreach(IAccount* account, BCAccountManager::instance()->getAccountListByLoadState(Loaded)) {
244        accLst->addItem(account->name());
245        accountStrToAccount.insert(account->name(), account);
246    }
247
248    int index = accLst->findText(selectedAccount);
249    index = std::max(index, 0);
250    accLst->setCurrentIndex(index);*/
251}
252
253void VCMain::enableSendBtnIfAllFilled() {
254    ui.btnSend->setEnabled((ui.txtMessage->toPlainText().trimmed() != "")
255                           && (ui.treeRecipients->topLevelItemCount() > 0)
256                           && (ui.lstAccounts->currentIndex() > -1));
257}
258
259
260void VCMain::clearMessage() {
261    ui.txtMessage->clear();
262    ui.treeRecipients->clear();
263    ui.txtMessage->setFocus();
264}
265
266void VCMain::sendMessage() {
267    QModelIndex idx            = accountFilterModel_->mapToSource(accountFilterModel_->index(ui.lstAccounts->currentIndex(), 0));
268    IAccount* account          = accountModel_->dataObject(idx);
269    QString message            = ui.txtMessage->toPlainText().trimmed();
270    QSet<IContact*> recipients = getRecipientContacts(true);
271
272    if (account != NULL) {
273        account->sendSMS(message, recipients);
274        QMessageBox::information(this, tr("SMS sent"), tr("Your sms has successfully been sent."), QMessageBox::Ok, QMessageBox::Ok);
275    }
276}
277
278
279/* SLOTS... */
280
281void VCMain::on_btnSend_clicked() {
282    sendMessage();
283}
284
285void VCMain::on_treeRecipients_itemSelectionChanged(){
286    ui.btnRemoveRecipient->setEnabled(ui.treeRecipients->selectedItems().count() > 0);
287}
288
289void VCMain::on_lstContacts_completer_changed(const QString& text) {
290    qDebug() << text << ui.lstContacts->findText(text);
291    ui.lstContacts->setCurrentIndex(ui.lstContacts->findText(text));
292}
293
294
295void VCMain:: on_btnAddRecipient_clicked(){
296    QModelIndex idx = contactGroupSortModel_->mapToSource(contactGroupSortModel_->index(ui.lstContacts->currentIndex(), 0));
297    if (idx.isValid()) {
298        IInterface* recipient = contactGroupListModel_->dataObject(idx);
299        addRecipient(dynamic_cast<IContact*>(recipient));
300        addRecipient(dynamic_cast<IGroup*>(recipient));
301    } else {
302        SNumber number = SNumber::fromString(ui.lstContacts->lineEdit()->text().trimmed(), SNumber::GuessFormat);
303        if (!number.isValid()) {
304            number = SNumber::fromString("+41 " + ui.lstContacts->lineEdit()->text().trimmed(), SNumber::GuessFormat);
305        }
306        if (number.isValid()) {
307            IContact* recipient = BCContactManager::instance()->getContactByNumber(number);
308
309            if (recipient != NULL) {
310                addRecipient(recipient);
311            } else {
312                IContact* recipient = BusinessFactory::instance()->getContactInstance();
313                recipient->setNumber(number);
314
315                if (QMessageBox::Yes == QMessageBox::question(this, tr("SMSSender"),
316                                                              tr("This number is not yet in your address book. Do you want to add it?"),
317                                                              QMessageBox::Yes,
318                                                              QMessageBox::No | QMessageBox::Default | QMessageBox::Escape)){
319                    VCEditContact* ec = new VCEditContact(recipient, this);
320                    if (ec->exec() == QDialog::Accepted){ // Wait for return
321                        BCContactManager::instance()->saveContact(recipient);
322                    }
323                }
324                if (recipient->name() == "") {
325                    recipient->setName(number.toString(SNumber::IsoFormatShort));
326                }
327                addRecipient(recipient);
328            }
329        }
330    }
331    ui.lstContacts->setCurrentIndex(-1);
332    ui.lstContacts->clearEditText();
333    enableSendBtnIfAllFilled();
334}
335
336void VCMain::on_btnRemoveRecipient_clicked(){
337    QListIterator<QTreeWidgetItem*> i(ui.treeRecipients->selectedItems());
338    while (i.hasNext()){
339        removeRecipient(i.next());
340    }
341    enableSendBtnIfAllFilled();
342}
343
344
345/* File menu */
346
347void VCMain::on_actionNewMessage_activated() {
348    clearMessage();
349}
350
351/* Edit menu */
352
353void VCMain::on_actionAccounts_activated() {
354    VCAccountList* cl = new VCAccountList(this);
355    cl->show();
356}
357
358void VCMain::on_actionAddressBook_activated(){
359    VCAddressBook* cl = new VCAddressBook(this);
360    cl->show();
361}
362
363void VCMain::on_actionPreferences_activated(){
364        VCSettings* s = new VCSettings(this);
365        s->show();
366}
367
368
369/* Help menu */
370
371void VCMain::on_actionAbout_activated(){
372        //
373}
374
375
376void VCMain::on_txtMessage_textChanged() {
377    enableSendBtnIfAllFilled();
378}
379void VCMain::on_selAccounts_currentIndexChanged(int index) {
380    enableSendBtnIfAllFilled();
381}
382
383
384/* Account loading */
385void VCMain::on_accountLoadStateChanged(IAccount* account, AccountLoadState state) {
386
387}
388
389void VCMain::on_accountLoaded(IAccount* account) {
390    reloadAccountList();
391}
392
393void VCMain::on_accountLoadingFailed(IAccount* account, EException* exception) {
394    QMessageBox::critical(this, tr("Error occured"), tr("An unknown error has occured!") + "\n\n" + QString(exception->what()), QMessageBox::Ok, QMessageBox::Ok);
395    reloadAccountList();
396}
397
Note: See TracBrowser for help on using the repository browser.