|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the Qt Mobility Components. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:BSD$ |
|
10 ** You may use this file under the terms of the BSD license as follows: |
|
11 ** |
|
12 ** "Redistribution and use in source and binary forms, with or without |
|
13 ** modification, are permitted provided that the following conditions are |
|
14 ** met: |
|
15 ** * Redistributions of source code must retain the above copyright |
|
16 ** notice, this list of conditions and the following disclaimer. |
|
17 ** * Redistributions in binary form must reproduce the above copyright |
|
18 ** notice, this list of conditions and the following disclaimer in |
|
19 ** the documentation and/or other materials provided with the |
|
20 ** distribution. |
|
21 ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor |
|
22 ** the names of its contributors may be used to endorse or promote |
|
23 ** products derived from this software without specific prior written |
|
24 ** permission. |
|
25 ** |
|
26 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
27 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
28 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
29 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
30 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
31 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
32 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
33 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
34 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
35 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
36 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." |
|
37 ** $QT_END_LICENSE$ |
|
38 ** |
|
39 ****************************************************************************/ |
|
40 |
|
41 #include "addressfinder.h" |
|
42 |
|
43 #include <qcontactdetailfilter.h> |
|
44 #include <qcontactemailaddress.h> |
|
45 #include <qcontactmanager.h> |
|
46 #include <qcontactphonenumber.h> |
|
47 #include <qmessage.h> |
|
48 #include <qmessageservice.h> |
|
49 |
|
50 #include <QCheckBox> |
|
51 #include <QComboBox> |
|
52 #include <QDateTime> |
|
53 #include <QGroupBox> |
|
54 #include <QLabel> |
|
55 #include <QLayout> |
|
56 #include <QListWidget> |
|
57 #include <QMessageBox> |
|
58 #include <QPushButton> |
|
59 #include <QTimer> |
|
60 #include <QDebug> |
|
61 #include <QApplication> |
|
62 #include <QMenuBar> |
|
63 #include <QTabWidget> |
|
64 #include <QScrollArea> |
|
65 |
|
66 namespace { |
|
67 |
|
68 QString simpleAddress(const QString &recipient) |
|
69 { |
|
70 QString name; |
|
71 QString addressOnly; |
|
72 |
|
73 QMessageAddress::parseEmailAddress(recipient, &name, &addressOnly); |
|
74 |
|
75 return addressOnly; |
|
76 } |
|
77 |
|
78 QString simpleAddress(const QMessageAddress &address) |
|
79 { |
|
80 return simpleAddress(address.addressee()); |
|
81 } |
|
82 |
|
83 //! [contact-lookup] |
|
84 QString contactDisplayName(const QMessageAddress &address) |
|
85 { |
|
86 QString addressOnly(simpleAddress(address)); |
|
87 |
|
88 // See if we can match this address to a contact |
|
89 QContactDetailFilter filter; |
|
90 if (address.type() == QMessageAddress::Email) { |
|
91 // Match contacts on email address data |
|
92 filter.setDetailDefinitionName(QContactEmailAddress::DefinitionName); |
|
93 filter.setValue(addressOnly); |
|
94 filter.setMatchFlags(QContactFilter::MatchContains); |
|
95 } else if (address.type() == QMessageAddress::Phone) { |
|
96 // Match contacts on phone number data |
|
97 filter.setDetailDefinitionName(QContactPhoneNumber::DefinitionName); |
|
98 filter.setValue(addressOnly); |
|
99 filter.setMatchFlags(QContactFilter::MatchPhoneNumber); |
|
100 } |
|
101 |
|
102 QContactManager manager; |
|
103 foreach (const QContactLocalId &contactId, manager.contactIds(filter)) { |
|
104 // Any match is acceptable |
|
105 const QContact &contact(manager.contact(contactId)); |
|
106 return contact.displayLabel(); |
|
107 } |
|
108 |
|
109 // We couldn't match anything, so return the original address |
|
110 return address.addressee(); |
|
111 } |
|
112 //! [contact-lookup] |
|
113 |
|
114 } |
|
115 |
|
116 AddressFinder::AddressFinder(QWidget *parent, Qt::WindowFlags flags) |
|
117 : QMainWindow(parent, flags), |
|
118 tabWidget(0), |
|
119 includePeriod(0), |
|
120 excludePeriod(0), |
|
121 excludeCheckBox(0), |
|
122 searchAction(0), |
|
123 searchButton(0), |
|
124 contactList(0), |
|
125 messageCombo(0) |
|
126 { |
|
127 setupUi(); |
|
128 |
|
129 connect(&service, SIGNAL(stateChanged(QMessageService::State)), this, SLOT(stateChanged(QMessageService::State))); |
|
130 connect(&service, SIGNAL(messagesFound(QMessageIdList)), this, SLOT(messagesFound(QMessageIdList))); |
|
131 } |
|
132 |
|
133 AddressFinder::~AddressFinder() |
|
134 { |
|
135 } |
|
136 |
|
137 void AddressFinder::includePeriodChanged(int selected) |
|
138 { |
|
139 // Only allow smaller periods to be excluded |
|
140 excludePeriod->clear(); |
|
141 |
|
142 switch (selected) { |
|
143 case 0: excludePeriod->insertItem(0, "9 Months"); // fall through: |
|
144 case 1: excludePeriod->insertItem(0, "6 Months"); |
|
145 case 2: excludePeriod->insertItem(0, "3 Months"); |
|
146 case 3: excludePeriod->insertItem(0, "Month"); |
|
147 case 4: excludePeriod->insertItem(0, "Week"); |
|
148 default: break; |
|
149 } |
|
150 |
|
151 excludePeriod->setCurrentIndex(0); |
|
152 } |
|
153 |
|
154 void AddressFinder::excludePeriodEnabled(int state) |
|
155 { |
|
156 excludePeriod->setEnabled(state == Qt::Checked); |
|
157 } |
|
158 |
|
159 //! [address-selected] |
|
160 void AddressFinder::addressSelected(const QString &address) |
|
161 { |
|
162 messageCombo->clear(); |
|
163 |
|
164 QString addressOnly(simpleAddress(address)); |
|
165 |
|
166 // Add the subject of each message to this address to the message pane |
|
167 typedef QPair<QString, QMessageId> MessageDetails; |
|
168 foreach (const MessageDetails &message, addressMessages[addressOnly]) { |
|
169 messageCombo->addItem(message.first); |
|
170 } |
|
171 } |
|
172 //! [address-selected] |
|
173 |
|
174 void AddressFinder::searchMessages() |
|
175 { |
|
176 setSearchActionEnabled(false); |
|
177 |
|
178 contactList->clear(); |
|
179 messageCombo->clear(); |
|
180 excludedAddresses.clear(); |
|
181 addressList.clear(); |
|
182 addressMessages.clear(); |
|
183 inclusionMessages.clear(); |
|
184 exclusionMessages.clear(); |
|
185 |
|
186 //! [create-date-range] |
|
187 QDateTime now(QDateTime::currentDateTime()); |
|
188 bool useExclusionPeriod(excludeCheckBox->isChecked()); |
|
189 |
|
190 // Determine the dates that demarcate the selected range |
|
191 QDateTime minimumDate(now); |
|
192 switch (includePeriod->currentIndex()) { |
|
193 case 0: minimumDate = minimumDate.addMonths(-12); break; |
|
194 case 1: minimumDate = minimumDate.addMonths(-9); break; |
|
195 case 2: minimumDate = minimumDate.addMonths(-6); break; |
|
196 case 3: minimumDate = minimumDate.addMonths(-3); break; |
|
197 case 4: minimumDate = minimumDate.addMonths(-1); break; |
|
198 case 5: minimumDate = minimumDate.addDays(-7); break; |
|
199 default: break; |
|
200 } |
|
201 |
|
202 QDateTime maximumDate(now); |
|
203 if (useExclusionPeriod) { |
|
204 // We have an exclusion period to apply |
|
205 switch (excludePeriod->currentIndex()) { |
|
206 case 0: maximumDate = maximumDate.addDays(-7); break; |
|
207 case 1: maximumDate = maximumDate.addMonths(-1); break; |
|
208 case 2: maximumDate = maximumDate.addMonths(-3); break; |
|
209 case 3: maximumDate = maximumDate.addMonths(-6); break; |
|
210 case 4: maximumDate = maximumDate.addMonths(-9); break; |
|
211 default: break; |
|
212 } |
|
213 } |
|
214 //! [create-date-range] |
|
215 |
|
216 //! [create-simple-filters] |
|
217 // We will include addresses contacted following the minimum date |
|
218 QMessageFilter includeFilter(QMessageFilter::byTimeStamp(minimumDate, QMessageDataComparator::GreaterThanEqual)); |
|
219 // Windows mobile only sets a receptionTimeStamp for sent messsages |
|
220 includeFilter |= QMessageFilter::byReceptionTimeStamp(minimumDate, QMessageDataComparator::GreaterThanEqual); |
|
221 |
|
222 QMessageFilter excludeFilter; |
|
223 if (useExclusionPeriod) { |
|
224 // We will exclude addresses contacted following the maximum date |
|
225 excludeFilter = QMessageFilter::byTimeStamp(maximumDate, QMessageDataComparator::GreaterThanEqual); |
|
226 excludeFilter |= QMessageFilter::byReceptionTimeStamp(maximumDate, QMessageDataComparator::GreaterThanEqual); |
|
227 } |
|
228 //! [create-simple-filters] |
|
229 |
|
230 //! [create-composite-filters] |
|
231 // We only want to match messages that we sent |
|
232 QMessageFilter sentFilter(QMessageFilter::byStandardFolder(QMessage::SentFolder)); |
|
233 |
|
234 // Create the filter needed to locate messages to search for addresses to include |
|
235 if (useExclusionPeriod) { |
|
236 inclusionFilter = (sentFilter & includeFilter & ~excludeFilter); |
|
237 } else { |
|
238 inclusionFilter = (sentFilter & includeFilter); |
|
239 } |
|
240 //! [create-composite-filters] |
|
241 |
|
242 //! [begin-search] |
|
243 if (useExclusionPeriod) { |
|
244 // Create the filter needed to locate messages whose address we will exclude |
|
245 QMessageFilter exclusionFilter; |
|
246 exclusionFilter = (sentFilter & excludeFilter); |
|
247 |
|
248 // Start the search for messages containing addresses to exclude |
|
249 service.queryMessages(exclusionFilter); |
|
250 } else { |
|
251 // Only search for messages containing addresses to include |
|
252 service.queryMessages(inclusionFilter); |
|
253 |
|
254 // Clear the inclusion filter to indicate that we have searched for it |
|
255 inclusionFilter = QMessageFilter(); |
|
256 } |
|
257 //! [begin-search] |
|
258 } |
|
259 |
|
260 //! [handle-search-result] |
|
261 void AddressFinder::stateChanged(QMessageService::State newState) |
|
262 { |
|
263 if (newState == QMessageService::FinishedState) { |
|
264 if (service.error() == QMessageManager::NoError) { |
|
265 if (!inclusionFilter.isEmpty()) { |
|
266 // Now find the included messages |
|
267 service.queryMessages(inclusionFilter); |
|
268 |
|
269 // Clear the inclusion filter to indicate that we have searched for it |
|
270 inclusionFilter = QMessageFilter(); |
|
271 } else { |
|
272 // We have found the exclusion and inclusion message sets |
|
273 if (!inclusionMessages.isEmpty()) { |
|
274 // Begin processing the message sets |
|
275 QTimer::singleShot(0, this, SLOT(continueSearch())); |
|
276 //! [handle-search-result] |
|
277 } else { |
|
278 QMessageBox::information(0, tr("Empty"), tr("No messages found")); |
|
279 searchAction->setEnabled(true); |
|
280 #ifdef USE_SEARCH_BUTTON |
|
281 searchButton->setEnabled(true); |
|
282 #endif |
|
283 } |
|
284 } |
|
285 } else { |
|
286 QMessageBox::warning(0, tr("Failed"), tr("Unable to perform search")); |
|
287 setSearchActionEnabled(true); |
|
288 } |
|
289 } |
|
290 } |
|
291 |
|
292 //! [accumulate-matches] |
|
293 void AddressFinder::messagesFound(const QMessageIdList &ids) |
|
294 { |
|
295 // Add these IDs to the relevant set |
|
296 if (!inclusionFilter.isEmpty()) { |
|
297 exclusionMessages << ids; |
|
298 } else { |
|
299 inclusionMessages << ids; |
|
300 } |
|
301 } |
|
302 //! [accumulate-matches] |
|
303 |
|
304 //! [continue-search] |
|
305 void AddressFinder::continueSearch() |
|
306 { |
|
307 if (!exclusionMessages.isEmpty()) { |
|
308 // Take the first message whose addreses we should exclude |
|
309 QMessageId id(exclusionMessages.takeFirst()); |
|
310 const QMessage message(id); |
|
311 |
|
312 // All recipient addresses are to be excluded |
|
313 foreach (const QMessageAddress &address, message.to() + message.cc() + message.bcc()) { |
|
314 excludedAddresses.insert(simpleAddress(address)); |
|
315 } |
|
316 } else if (!inclusionMessages.isEmpty()) { |
|
317 // Take the first message to inspect for suitable addresses |
|
318 QMessageId id(inclusionMessages.takeFirst()); |
|
319 const QMessage message(id); |
|
320 |
|
321 QString details; |
|
322 |
|
323 // For each recipient of this message |
|
324 foreach (const QMessageAddress &address, message.to() + message.cc() + message.bcc()) { |
|
325 QString addressOnly(simpleAddress(address)); |
|
326 |
|
327 // Ignore recipients whose addresses we have added to the exclusion set |
|
328 if (!excludedAddresses.contains(addressOnly)) { |
|
329 // Link this message to this address |
|
330 QList<QPair<QString, QMessageId> > &messageList(addressMessages[addressOnly]); |
|
331 if (messageList.isEmpty()) { |
|
332 addressList.append(addressOnly); |
|
333 |
|
334 // Add the recipient to our visible list of contacts to keep in touch with |
|
335 contactList->addItem(contactDisplayName(address)); |
|
336 } |
|
337 |
|
338 if (details.isEmpty()) { |
|
339 // Determine the properties of the message |
|
340 details = QString("[%1] %2").arg(message.date().toString("MMM d")).arg(message.subject()); |
|
341 } |
|
342 messageList.append(qMakePair(details, id)); |
|
343 } |
|
344 } |
|
345 } |
|
346 |
|
347 if (!exclusionMessages.isEmpty() || !inclusionMessages.isEmpty()) { |
|
348 // There are more messages to process |
|
349 QTimer::singleShot(0, this, SLOT(continueSearch())); |
|
350 } else { |
|
351 // We're finished our search |
|
352 setSearchActionEnabled(true); |
|
353 #ifndef USE_SEARCH_BUTTON |
|
354 tabChanged(1); |
|
355 #endif |
|
356 |
|
357 if ( |
|
358 #ifdef USE_CONTACTS_COMBOBOX |
|
359 contactList->currentIndex() != -1 |
|
360 #else |
|
361 contactList->currentItem() |
|
362 #endif |
|
363 ) { |
|
364 // Select the first address automatically |
|
365 addressSelected( |
|
366 #ifdef USE_CONTACTS_COMBOBOX |
|
367 contactList->currentText() |
|
368 #else |
|
369 contactList->currentItem()->text() |
|
370 #endif |
|
371 ); |
|
372 } |
|
373 } |
|
374 } |
|
375 //! [continue-search] |
|
376 |
|
377 #ifndef USE_SEARCH_BUTTON |
|
378 void AddressFinder::tabChanged(int index) |
|
379 { |
|
380 QWidget* currentTab = tabWidget->currentWidget(); |
|
381 QAction* action = 0; |
|
382 if(currentTab && !currentTab->actions().isEmpty()) |
|
383 action = currentTab->actions().first(); |
|
384 menuBar()->setDefaultAction(action); |
|
385 |
|
386 Q_UNUSED(index) |
|
387 } |
|
388 #endif |
|
389 |
|
390 void AddressFinder::setupUi() |
|
391 { |
|
392 setWindowTitle(tr("Keep In Touch")); |
|
393 |
|
394 #ifndef USE_SEARCH_BUTTON |
|
395 tabWidget = new QTabWidget(this); |
|
396 setCentralWidget(tabWidget); |
|
397 connect(tabWidget,SIGNAL(currentChanged(int)),this,SLOT(tabChanged(int))); |
|
398 #else |
|
399 QWidget* centralWidget = new QWidget(this); |
|
400 QScrollArea* scrollArea = new QScrollArea(this); |
|
401 scrollArea->setWidget(centralWidget); |
|
402 scrollArea->setWidgetResizable(true); |
|
403 setCentralWidget(scrollArea); |
|
404 QVBoxLayout* centralLayout = new QVBoxLayout(centralWidget); |
|
405 #endif |
|
406 |
|
407 QGroupBox *inputGroup = new QGroupBox(tr("Find addresses")); |
|
408 inputGroup->setAlignment(Qt::AlignLeft); |
|
409 #ifndef USE_SEARCH_BUTTON |
|
410 tabWidget->addTab(inputGroup,"Search"); |
|
411 #else |
|
412 centralLayout->addWidget(inputGroup); |
|
413 #endif |
|
414 |
|
415 QGridLayout *filterLayout = new QGridLayout(inputGroup); |
|
416 #ifdef Q_WS_MAEMO_5 |
|
417 // Maemo 5 style doesn't take group box titles into account. |
|
418 int spacingHack = QFontMetrics(QFont()).height(); |
|
419 filterLayout->setContentsMargins(0, spacingHack, 0, 0); |
|
420 #endif |
|
421 |
|
422 QLabel *includeLabel = new QLabel(tr("Contacted in the last")); |
|
423 filterLayout->addWidget(includeLabel, 0, 0); |
|
424 filterLayout->setAlignment(includeLabel, Qt::AlignRight); |
|
425 |
|
426 excludeCheckBox = new QCheckBox(tr("But not in the last")); |
|
427 #ifdef Q_WS_MAEMO_5 |
|
428 // Maemo 5 style cuts off check box text. |
|
429 excludeCheckBox->setText(excludeCheckBox->text() + " "); |
|
430 #endif |
|
431 connect(excludeCheckBox, SIGNAL(stateChanged(int)), this, SLOT(excludePeriodEnabled(int))); |
|
432 filterLayout->addWidget(excludeCheckBox, 1, 0); |
|
433 filterLayout->setAlignment(excludeCheckBox, Qt::AlignRight); |
|
434 |
|
435 includePeriod = new QComboBox; |
|
436 includePeriod->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); |
|
437 includePeriod->addItem(tr("Year")); |
|
438 includePeriod->addItem(tr("9 Months")); |
|
439 includePeriod->addItem(tr("6 Months")); |
|
440 includePeriod->addItem(tr("3 Months")); |
|
441 includePeriod->addItem(tr("Month")); |
|
442 includePeriod->addItem(tr("Week")); |
|
443 connect(includePeriod, SIGNAL(currentIndexChanged(int)), this, SLOT(includePeriodChanged(int))); |
|
444 filterLayout->addWidget(includePeriod, 0, 1); |
|
445 |
|
446 excludePeriod = new QComboBox; |
|
447 excludePeriod->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); |
|
448 filterLayout->addWidget(excludePeriod, 1, 1); |
|
449 excludePeriod->setEnabled(false); |
|
450 |
|
451 #ifdef USE_SEARCH_BUTTON |
|
452 searchButton = new QPushButton(tr("Search")); |
|
453 searchButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); |
|
454 connect(searchButton, SIGNAL(clicked()), this, SLOT(searchMessages()), Qt::QueuedConnection); |
|
455 filterLayout->addWidget(searchButton, 2, 1); |
|
456 #endif |
|
457 |
|
458 #ifdef USE_CONTACTS_COMBOBOX |
|
459 contactList = new QComboBox(this); |
|
460 connect(contactList, SIGNAL(currentIndexChanged(QString)), this, SLOT(addressSelected(QString))); |
|
461 #else |
|
462 contactList = new QListWidget(this); |
|
463 connect(contactList, SIGNAL(currentTextChanged(QString)), this, SLOT(addressSelected(QString))); |
|
464 #endif |
|
465 |
|
466 #ifndef USE_SEARCH_BUTTON |
|
467 QWidget* resultsWidget = new QWidget(this); |
|
468 QVBoxLayout* resultsLayout = new QVBoxLayout(resultsWidget); |
|
469 tabWidget->addTab(resultsWidget,"Results"); |
|
470 #else |
|
471 QVBoxLayout* resultsLayout = centralLayout; |
|
472 #endif |
|
473 |
|
474 QGroupBox *addressGroup = new QGroupBox(tr("Contacts")); |
|
475 addressGroup->setAlignment(Qt::AlignLeft); |
|
476 addressGroup->setLayout(new QVBoxLayout); |
|
477 #ifdef Q_WS_MAEMO_5 |
|
478 addressGroup->layout()->setContentsMargins(0, spacingHack, 0, 0); |
|
479 #endif |
|
480 addressGroup->layout()->addWidget(contactList); |
|
481 resultsLayout->addWidget(addressGroup); |
|
482 |
|
483 QGroupBox *messageGroup = new QGroupBox(tr("Messages")); |
|
484 messageGroup->setAlignment(Qt::AlignLeft); |
|
485 |
|
486 QVBoxLayout *groupLayout = new QVBoxLayout; |
|
487 #ifdef Q_WS_MAEMO_5 |
|
488 groupLayout->setContentsMargins(0, spacingHack, 0, 0); |
|
489 #endif |
|
490 |
|
491 messageCombo = new QComboBox; |
|
492 connect(messageCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(messageIndexChanged(int))); |
|
493 |
|
494 groupLayout->addWidget(messageCombo); |
|
495 |
|
496 showButton = new QPushButton(tr("Show...")); |
|
497 showButton->setEnabled(false); |
|
498 connect(showButton, SIGNAL(clicked()), this, SLOT(showMessage())); |
|
499 |
|
500 forwardButton = new QPushButton(tr("Forward...")); |
|
501 forwardButton->setEnabled(false); |
|
502 connect(forwardButton, SIGNAL(clicked()), this, SLOT(forwardMessage())); |
|
503 |
|
504 QHBoxLayout *buttonLayout = new QHBoxLayout; |
|
505 buttonLayout->addWidget(showButton); |
|
506 buttonLayout->addWidget(forwardButton); |
|
507 |
|
508 groupLayout->addLayout(buttonLayout); |
|
509 |
|
510 messageGroup->setLayout(groupLayout); |
|
511 resultsLayout->addWidget(messageGroup); |
|
512 |
|
513 searchAction = new QAction("Search",this); |
|
514 inputGroup->addAction(searchAction); |
|
515 connect(searchAction,SIGNAL(triggered()),this,SLOT(searchMessages()),Qt::QueuedConnection); |
|
516 QAction* quitAction = menuBar()->addAction("Quit"); |
|
517 connect(quitAction,SIGNAL(triggered()),qApp,SLOT(quit())); |
|
518 |
|
519 includePeriodChanged(0); |
|
520 #ifndef USE_SEARCH_BUTTON |
|
521 tabChanged(0); |
|
522 #endif |
|
523 |
|
524 QWidgetList focusableWidgets; |
|
525 focusableWidgets << excludeCheckBox |
|
526 << includePeriod |
|
527 << excludePeriod |
|
528 << contactList |
|
529 << messageCombo |
|
530 << showButton |
|
531 #ifndef USE_SEARCH_BUTTON |
|
532 << tabWidget |
|
533 #else |
|
534 << searchButton |
|
535 << scrollArea |
|
536 #endif |
|
537 << forwardButton; |
|
538 |
|
539 foreach(QWidget* w, focusableWidgets) |
|
540 w->setContextMenuPolicy(Qt::NoContextMenu); |
|
541 |
|
542 excludePeriod->setFocus(); |
|
543 } |
|
544 |
|
545 void AddressFinder::setSearchActionEnabled(bool val) |
|
546 { |
|
547 searchAction->setEnabled(val); |
|
548 #ifdef USE_SEARCH_BUTTON |
|
549 searchButton->setEnabled(val); |
|
550 #endif |
|
551 } |
|
552 |
|
553 void AddressFinder::messageIndexChanged(int index) |
|
554 { |
|
555 bool messageSelected(index != -1); |
|
556 showButton->setEnabled(messageSelected); |
|
557 forwardButton->setEnabled(messageSelected); |
|
558 } |
|
559 |
|
560 //! [show-message] |
|
561 void AddressFinder::showMessage() |
|
562 { |
|
563 int index = messageCombo->currentIndex(); |
|
564 if (index != -1) { |
|
565 // Find the address currently selected |
|
566 const QString &selectedAddress(addressList[ |
|
567 #ifdef USE_CONTACTS_COMBOBOX |
|
568 contactList->currentIndex() |
|
569 #else |
|
570 contactList->currentRow() |
|
571 #endif |
|
572 ]); |
|
573 |
|
574 // Show the message selected |
|
575 QMessageId &messageId((addressMessages[selectedAddress])[index].second); |
|
576 service.show(messageId); |
|
577 } |
|
578 } |
|
579 //! [show-message] |
|
580 |
|
581 //! [compose-message] |
|
582 void AddressFinder::forwardMessage() |
|
583 { |
|
584 int index = messageCombo->currentIndex(); |
|
585 if (index != -1) { |
|
586 // Find the address currently selected |
|
587 const QString &selectedAddress(addressList[ |
|
588 #ifdef USE_CONTACTS_COMBOBOX |
|
589 contactList->currentIndex() |
|
590 #else |
|
591 contactList->currentRow() |
|
592 #endif |
|
593 ]); |
|
594 |
|
595 // Find the selected message |
|
596 QMessageId &messageId((addressMessages[selectedAddress])[index].second); |
|
597 QMessage original(messageId); |
|
598 |
|
599 // Create a message which forwards the selected message to the same recipient |
|
600 QMessage fwd(original.createResponseMessage(QMessage::Forward)); |
|
601 fwd.setTo(original.to()); |
|
602 service.compose(fwd); |
|
603 } |
|
604 } |
|
605 //! [compose-message] |
|
606 |