source: SMSSender/src/ui/VCMain/vcmain.cpp @ 71:415b45c71663

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