source: SMSSender/src/ui/VCMain/vcmain.cpp @ 67:578192d6fe64

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