|
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:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 #include "qmessageservice.h" |
|
42 #include "qmessageservice_maemo_p.h" |
|
43 |
|
44 #include "maemohelpers_p.h" |
|
45 #include "modestengine_maemo_p.h" |
|
46 #include "telepathyengine_maemo_p.h" |
|
47 #include "eventloggerengine_maemo_p.h" |
|
48 #include <QUrl> |
|
49 #include "hildon-uri.h" |
|
50 |
|
51 QTM_BEGIN_NAMESPACE |
|
52 #define EVENTLOGGER_THREAD |
|
53 |
|
54 |
|
55 QMessageServicePrivate::QMessageServicePrivate(QMessageService* parent) |
|
56 : q_ptr(parent), |
|
57 _state(QMessageService::InactiveState), |
|
58 _error(QMessageManager::NoError), |
|
59 _active(false), _actionId(-1), |
|
60 _pendingRequestCount(0) |
|
61 { |
|
62 #ifdef EVENTLOGGER_THREAD |
|
63 connect(EventLoggerEngine::instance(),SIGNAL(messagesFound(const QMessageIdList &,bool,bool)),this,SLOT(messagesFound(const QMessageIdList &,bool,bool))); |
|
64 |
|
65 #endif |
|
66 } |
|
67 |
|
68 QMessageServicePrivate::~QMessageServicePrivate() |
|
69 { |
|
70 } |
|
71 |
|
72 QMessageServicePrivate* QMessageServicePrivate::implementation(const QMessageService &service) |
|
73 { |
|
74 return service.d_ptr; |
|
75 } |
|
76 |
|
77 bool QMessageServicePrivate::queryMessages(QMessageService &messageService, |
|
78 const QMessageFilter &filter, |
|
79 const QMessageSortOrder &sortOrder, |
|
80 uint limit, uint offset, |
|
81 EnginesToCall enginesToCall) |
|
82 { |
|
83 if (_active) { |
|
84 return false; |
|
85 } |
|
86 |
|
87 _filter = filter; |
|
88 MessagingHelper::handleNestedFiltersFromMessageFilter(_filter); |
|
89 |
|
90 _ids.clear(); |
|
91 _sorted = true; |
|
92 _filtered = true; |
|
93 |
|
94 _active = true; |
|
95 _error = QMessageManager::NoError; |
|
96 |
|
97 _pendingRequestCount = 0; |
|
98 |
|
99 if (enginesToCall & EnginesToCallTelepathy) { |
|
100 #ifndef EVENTLOGGER_THREAD |
|
101 _ids = EventLoggerEngine::instance()->filterAndOrderMessages(filter,sortOrder,QString(),QMessageDataComparator::MatchFlags()); |
|
102 QMetaObject::invokeMethod(this, "messagesFoundSlot", Qt::QueuedConnection); |
|
103 #else |
|
104 EventLoggerEngine::instance()->filterMessages(_filter,sortOrder,QString(),QMessageDataComparator::MatchFlags()); |
|
105 #endif |
|
106 _pendingRequestCount++; |
|
107 } |
|
108 |
|
109 if (enginesToCall & EnginesToCallModest) { |
|
110 if (ModestEngine::instance()->queryMessages(messageService, _filter, sortOrder, limit, offset)) { |
|
111 _pendingRequestCount++; |
|
112 } |
|
113 } |
|
114 |
|
115 if (_pendingRequestCount > 0) { |
|
116 _sortOrder = sortOrder; |
|
117 _limit = limit; |
|
118 _offset = offset; |
|
119 |
|
120 stateChanged(QMessageService::ActiveState); |
|
121 } else { |
|
122 _filter = QMessageFilter(); |
|
123 setFinished(false); |
|
124 } |
|
125 |
|
126 return _active; |
|
127 } |
|
128 |
|
129 bool QMessageServicePrivate::queryMessages(QMessageService &messageService, |
|
130 const QMessageFilter &filter, |
|
131 const QString &body, |
|
132 QMessageDataComparator::MatchFlags matchFlags, |
|
133 const QMessageSortOrder &sortOrder, |
|
134 uint limit, uint offset, |
|
135 EnginesToCall enginesToCall) |
|
136 { |
|
137 if (_active) { |
|
138 return false; |
|
139 } |
|
140 |
|
141 _filter = filter; |
|
142 MessagingHelper::handleNestedFiltersFromMessageFilter(_filter); |
|
143 |
|
144 _ids.clear(); |
|
145 _sorted = true; |
|
146 _filtered = true; |
|
147 |
|
148 _active = true; |
|
149 _error = QMessageManager::NoError; |
|
150 |
|
151 _pendingRequestCount = 0; |
|
152 |
|
153 if (enginesToCall & EnginesToCallTelepathy) { |
|
154 #ifndef EVENTLOGGER_THREAD |
|
155 _ids= EventLoggerEngine::instance()->filterAndOrderMessages(filter,sortOrder,body,matchFlags); |
|
156 QMetaObject::invokeMethod(this, "messagesFoundSlot", Qt::QueuedConnection); |
|
157 #else |
|
158 EventLoggerEngine::instance()->filterMessages(_filter,sortOrder,body,matchFlags); |
|
159 #endif |
|
160 _pendingRequestCount++; |
|
161 } |
|
162 |
|
163 if (enginesToCall & EnginesToCallModest) { |
|
164 if (ModestEngine::instance()->queryMessages(messageService, _filter, body, matchFlags, |
|
165 sortOrder, limit, offset)) { |
|
166 _pendingRequestCount++; |
|
167 } |
|
168 } |
|
169 |
|
170 if (_pendingRequestCount > 0) { |
|
171 _sortOrder = sortOrder; |
|
172 _limit = limit; |
|
173 _offset = offset; |
|
174 |
|
175 stateChanged(QMessageService::ActiveState); |
|
176 } else { |
|
177 _filter = QMessageFilter(); |
|
178 setFinished(false); |
|
179 } |
|
180 |
|
181 return _active; |
|
182 } |
|
183 |
|
184 bool QMessageServicePrivate::countMessages(QMessageService &messageService, |
|
185 const QMessageFilter &filter, |
|
186 EnginesToCall enginesToCall) |
|
187 { |
|
188 if (_active) { |
|
189 return false; |
|
190 } |
|
191 |
|
192 QMessageFilter handledFilter = filter; |
|
193 MessagingHelper::handleNestedFiltersFromMessageFilter(handledFilter); |
|
194 |
|
195 _count = 0; |
|
196 |
|
197 _active = true; |
|
198 _error = QMessageManager::NoError; |
|
199 |
|
200 _pendingRequestCount = 0; |
|
201 |
|
202 //TODO: SMS count support |
|
203 //if (enginesToCall & EnginesToCallTelepathy) { |
|
204 //} |
|
205 |
|
206 if (enginesToCall & EnginesToCallModest) { |
|
207 if (ModestEngine::instance()->countMessages(messageService, handledFilter)) { |
|
208 _pendingRequestCount++; |
|
209 } |
|
210 } |
|
211 |
|
212 if (_pendingRequestCount > 0) { |
|
213 stateChanged(QMessageService::ActiveState); |
|
214 } else { |
|
215 setFinished(false); |
|
216 } |
|
217 |
|
218 return _active; |
|
219 } |
|
220 |
|
221 |
|
222 void QMessageServicePrivate::setFinished(bool successful) |
|
223 { |
|
224 if (!successful && _pendingRequestCount > 0) { |
|
225 _pendingRequestCount--; |
|
226 } |
|
227 |
|
228 if (_pendingRequestCount == 0) { |
|
229 if (!successful && (_error == QMessageManager::NoError)) { |
|
230 // We must report an error of some sort |
|
231 _error = QMessageManager::RequestIncomplete; |
|
232 } |
|
233 |
|
234 _active = false; |
|
235 stateChanged(QMessageService::FinishedState); |
|
236 } |
|
237 } |
|
238 |
|
239 void QMessageServicePrivate::stateChanged(QMessageService::State state) |
|
240 { |
|
241 _state = state; |
|
242 emit q_ptr->stateChanged(_state); |
|
243 } |
|
244 |
|
245 void QMessageServicePrivate::messagesFound(const QMessageIdList &ids, bool isFiltered, bool isSorted) |
|
246 { |
|
247 _pendingRequestCount--; |
|
248 |
|
249 if (!isFiltered) { |
|
250 _filtered = false; |
|
251 } |
|
252 |
|
253 if (!isSorted) { |
|
254 _sorted = false; |
|
255 } else { |
|
256 if ((ids.count() > 0) && (_ids.count() > 0)) { |
|
257 _sorted = false; |
|
258 } |
|
259 } |
|
260 |
|
261 _ids.append(ids); |
|
262 |
|
263 if (_pendingRequestCount == 0) { |
|
264 if (!_filtered) { |
|
265 MessagingHelper::filterMessages(_ids, _filter); |
|
266 } |
|
267 if (!_sorted) { |
|
268 MessagingHelper::orderMessages(_ids, _sortOrder); |
|
269 } |
|
270 MessagingHelper::applyOffsetAndLimitToMessageIdList(_ids, _limit, _offset); |
|
271 |
|
272 ModestEngine::instance()->clearHeaderCache(); |
|
273 |
|
274 emit q_ptr->messagesFound(_ids); |
|
275 |
|
276 setFinished(true); |
|
277 |
|
278 _ids.clear(); |
|
279 _filter = QMessageFilter(); |
|
280 _sortOrder = QMessageSortOrder(); |
|
281 } |
|
282 } |
|
283 |
|
284 void QMessageServicePrivate::messagesCounted(int count) |
|
285 { |
|
286 _pendingRequestCount--; |
|
287 |
|
288 _count += count; |
|
289 |
|
290 if (_pendingRequestCount == 0) { |
|
291 ModestEngine::instance()->clearHeaderCache(); |
|
292 |
|
293 emit q_ptr->messagesCounted(_count); |
|
294 |
|
295 setFinished(true); |
|
296 |
|
297 _count = 0; |
|
298 } |
|
299 } |
|
300 |
|
301 void QMessageServicePrivate::progressChanged(uint value, uint total) |
|
302 { |
|
303 emit q_ptr->progressChanged(value, total); |
|
304 } |
|
305 |
|
306 void QMessageServicePrivate::messagesFoundSlot() |
|
307 { |
|
308 messagesFound(QMessageIdList(), true, false); |
|
309 } |
|
310 |
|
311 void QMessageServicePrivate::messagesCountedSlot() |
|
312 { |
|
313 messagesCounted(0); |
|
314 } |
|
315 |
|
316 |
|
317 QMessageService::QMessageService(QObject *parent) |
|
318 : QObject(parent), |
|
319 d_ptr(new QMessageServicePrivate(this)) |
|
320 { |
|
321 EventLoggerEngine::instance(); |
|
322 TelepathyEngine::instance(); |
|
323 } |
|
324 |
|
325 QMessageService::~QMessageService() |
|
326 { |
|
327 } |
|
328 |
|
329 bool QMessageService::queryMessages(const QMessageFilter &filter, const QMessageSortOrder &sortOrder, uint limit, uint offset) |
|
330 { |
|
331 return d_ptr->queryMessages(*this, filter, sortOrder, limit, offset); |
|
332 } |
|
333 |
|
334 bool QMessageService::queryMessages(const QMessageFilter &filter, const QString &body, QMessageDataComparator::MatchFlags matchFlags, const QMessageSortOrder &sortOrder, uint limit, uint offset) |
|
335 { |
|
336 return d_ptr->queryMessages(*this, filter, body, matchFlags, sortOrder, limit, offset); |
|
337 } |
|
338 |
|
339 bool QMessageService::countMessages(const QMessageFilter &filter) |
|
340 { |
|
341 return d_ptr->countMessages(*this, filter); |
|
342 } |
|
343 |
|
344 bool QMessageService::send(QMessage &message) |
|
345 { |
|
346 qDebug() << "QMessageService::send"; |
|
347 if (d_ptr->_active) { |
|
348 return false; |
|
349 } |
|
350 |
|
351 d_ptr->_active = true; |
|
352 d_ptr->_error = QMessageManager::NoError; |
|
353 |
|
354 bool retVal = true; |
|
355 |
|
356 d_ptr->_state = QMessageService::ActiveState; |
|
357 emit stateChanged(d_ptr->_state); |
|
358 |
|
359 QMessageAccountId accountId = message.parentAccountId(); |
|
360 QMessage::Type msgType = QMessage::NoType; |
|
361 |
|
362 // Check message type |
|
363 if (message.type() == QMessage::AnyType || message.type() == QMessage::NoType) { |
|
364 QMessage::TypeFlags types = QMessage::NoType; |
|
365 if (accountId.isValid()) { |
|
366 // ParentAccountId was defined => Message type can be read |
|
367 // from parent account |
|
368 QMessageAccount account = QMessageAccount(accountId); |
|
369 QMessage::TypeFlags types = account.messageTypes(); |
|
370 if (types & QMessage::Sms) { |
|
371 msgType = QMessage::Sms; |
|
372 } else if (account.messageTypes() & QMessage::InstantMessage) { |
|
373 msgType = QMessage::InstantMessage; |
|
374 } else if (types & QMessage::Mms) { |
|
375 msgType = QMessage::Mms; |
|
376 } else if (types & QMessage::Email) { |
|
377 msgType = QMessage::Email; |
|
378 } |
|
379 } |
|
380 if (msgType == QMessage::NoType) { |
|
381 d_ptr->_error = QMessageManager::ConstraintFailure; |
|
382 retVal = false; |
|
383 } |
|
384 } |
|
385 |
|
386 if (retVal) { |
|
387 // Check account |
|
388 if (!accountId.isValid()) { |
|
389 accountId = QMessageAccount::defaultAccount(message.type()); |
|
390 if (!accountId.isValid()) { |
|
391 d_ptr->_error = QMessageManager::InvalidId; |
|
392 retVal = false; |
|
393 } |
|
394 } |
|
395 } |
|
396 |
|
397 QMessageAccount account(accountId); |
|
398 if (retVal) { |
|
399 // Check account/message type compatibility |
|
400 if (!(account.messageTypes() & message.type()) && (msgType == QMessage::NoType)) { |
|
401 d_ptr->_error = QMessageManager::ConstraintFailure; |
|
402 retVal = false; |
|
403 } |
|
404 } |
|
405 |
|
406 if (retVal) { |
|
407 // Check recipients |
|
408 QMessageAddressList recipients = message.to() + message.bcc() + message.cc(); |
|
409 if (recipients.isEmpty()) { |
|
410 d_ptr->_error = QMessageManager::ConstraintFailure; |
|
411 retVal = false; |
|
412 } |
|
413 } |
|
414 |
|
415 if (retVal) { |
|
416 QMessage outgoing(message); |
|
417 |
|
418 // Set default account if unset |
|
419 if (!outgoing.parentAccountId().isValid()) { |
|
420 outgoing.setParentAccountId(accountId); |
|
421 } |
|
422 |
|
423 if (account.messageTypes() & QMessage::Sms) { |
|
424 retVal = TelepathyEngine::instance()->sendMessage(outgoing); |
|
425 } else if (account.messageTypes() & QMessage::InstantMessage) { |
|
426 retVal = TelepathyEngine::instance()->sendMessage(outgoing); |
|
427 } else if (account.messageTypes() & QMessage::Mms) { |
|
428 d_ptr->_error = QMessageManager::NotYetImplemented; |
|
429 qWarning() << "QMessageService::send not yet implemented for MMS"; |
|
430 retVal = false; |
|
431 } else if (account.messageTypes() & QMessage::Email) { |
|
432 retVal = ModestEngine::instance()->sendEmail(message); |
|
433 } |
|
434 } |
|
435 |
|
436 d_ptr->setFinished(retVal); |
|
437 qDebug() << "send returns=" << retVal; |
|
438 return retVal; |
|
439 } |
|
440 |
|
441 bool QMessageService::compose(const QMessage &message) |
|
442 { |
|
443 // qDebug() << "qMessageService::compose"; |
|
444 if (d_ptr->_active) { |
|
445 return false; |
|
446 } |
|
447 |
|
448 d_ptr->_active = true; |
|
449 d_ptr->_error = QMessageManager::NoError; |
|
450 |
|
451 bool retVal=false; |
|
452 d_ptr->_state = QMessageService::ActiveState; |
|
453 emit stateChanged(d_ptr->_state); |
|
454 qDebug() << "qMessageService::compose stateChanged"; |
|
455 |
|
456 if (message.type() == QMessage::Sms && !message.to().isEmpty() && !message.to().first().addressee().isEmpty()) { |
|
457 QUrl smsUrl((QString("sms:%1").arg(message.to().first().addressee()))); |
|
458 smsUrl.addQueryItem("body",message.textContent()); |
|
459 // qDebug() << "compose SMS url=" << smsUrl.toString(); |
|
460 hildon_uri_open(smsUrl.toString().toStdString().c_str(),NULL,NULL); |
|
461 retVal = true; |
|
462 |
|
463 |
|
464 } else if (message.type() == QMessage::Mms) { |
|
465 d_ptr->_error = QMessageManager::NotYetImplemented; //TODO: |
|
466 qWarning() << "QMessageService::compose not yet implemented for MMS"; |
|
467 retVal = false; |
|
468 } else if (message.type() == QMessage::Email) { |
|
469 retVal = ModestEngine::instance()->composeEmail(message); |
|
470 } |
|
471 |
|
472 d_ptr->setFinished(retVal); |
|
473 // qDebug() << "compose returns=" << retVal; |
|
474 return retVal; |
|
475 } |
|
476 |
|
477 |
|
478 |
|
479 bool QMessageService::retrieveHeader(const QMessageId& id) |
|
480 { |
|
481 Q_UNUSED(id) |
|
482 return false; // stub |
|
483 } |
|
484 |
|
485 bool QMessageService::retrieveBody(const QMessageId& id) |
|
486 { |
|
487 if (d_ptr->_active) { |
|
488 return false; |
|
489 } |
|
490 |
|
491 if (!id.isValid()) { |
|
492 d_ptr->_error = QMessageManager::InvalidId; |
|
493 return false; |
|
494 } |
|
495 |
|
496 d_ptr->_active = true; |
|
497 d_ptr->_error = QMessageManager::NoError; |
|
498 |
|
499 bool retVal = true; |
|
500 d_ptr->stateChanged(QMessageService::ActiveState); |
|
501 |
|
502 if (id.toString().startsWith("MO_")) { |
|
503 retVal = ModestEngine::instance()->retrieveBody(*this, id); |
|
504 if (retVal == true) { |
|
505 d_ptr->_pendingRequestCount = 1; |
|
506 } |
|
507 } else { |
|
508 retVal = false; |
|
509 } |
|
510 |
|
511 if (retVal == false) { |
|
512 d_ptr->setFinished(retVal); |
|
513 } |
|
514 |
|
515 return retVal; |
|
516 } |
|
517 |
|
518 bool QMessageService::retrieve(const QMessageId &messageId, const QMessageContentContainerId& id) |
|
519 { |
|
520 if (d_ptr->_active) { |
|
521 return false; |
|
522 } |
|
523 |
|
524 if (!id.isValid()) { |
|
525 d_ptr->_error = QMessageManager::InvalidId; |
|
526 return false; |
|
527 } |
|
528 |
|
529 d_ptr->_active = true; |
|
530 d_ptr->_error = QMessageManager::NoError; |
|
531 |
|
532 bool retVal = true; |
|
533 d_ptr->stateChanged(QMessageService::ActiveState); |
|
534 |
|
535 if (messageId.toString().startsWith("MO_")) { |
|
536 retVal = ModestEngine::instance()->retrieve(*this, messageId, id, NULL); |
|
537 if (retVal == true) { |
|
538 d_ptr->_pendingRequestCount = 1; |
|
539 } |
|
540 } else { |
|
541 retVal = false; |
|
542 } |
|
543 |
|
544 if (retVal == false) { |
|
545 d_ptr->setFinished(retVal); |
|
546 } |
|
547 |
|
548 return retVal; |
|
549 } |
|
550 |
|
551 bool QMessageService::show(const QMessageId& id) |
|
552 { |
|
553 if (d_ptr->_active) { |
|
554 return false; |
|
555 } |
|
556 |
|
557 if (!id.isValid()) { |
|
558 d_ptr->_error = QMessageManager::InvalidId; |
|
559 return false; |
|
560 } |
|
561 |
|
562 d_ptr->_active = true; |
|
563 d_ptr->_error = QMessageManager::NoError; |
|
564 |
|
565 bool retVal = true; |
|
566 d_ptr->_state = QMessageService::ActiveState; |
|
567 emit stateChanged(d_ptr->_state); |
|
568 |
|
569 if (id.toString().startsWith("MO_")) { |
|
570 retVal = ModestEngine::instance()->showMessage(id); |
|
571 } else { |
|
572 retVal = false; |
|
573 } |
|
574 |
|
575 d_ptr->setFinished(retVal); |
|
576 return retVal; |
|
577 } |
|
578 |
|
579 bool QMessageService::exportUpdates(const QMessageAccountId &id) |
|
580 { |
|
581 if (d_ptr->_active) { |
|
582 return false; |
|
583 } |
|
584 |
|
585 if (!id.isValid()) { |
|
586 d_ptr->_error = QMessageManager::InvalidId; |
|
587 return false; |
|
588 } |
|
589 |
|
590 d_ptr->_active = true; |
|
591 d_ptr->_error = QMessageManager::NoError; |
|
592 |
|
593 bool retVal = true; |
|
594 d_ptr->_state = QMessageService::ActiveState; |
|
595 emit stateChanged(d_ptr->_state); |
|
596 |
|
597 if (id.toString().startsWith("MO_")) { |
|
598 retVal = ModestEngine::instance()->exportUpdates(id); |
|
599 } else { |
|
600 retVal = false; |
|
601 } |
|
602 |
|
603 d_ptr->setFinished(retVal); |
|
604 return retVal; |
|
605 } |
|
606 |
|
607 QMessageService::State QMessageService::state() const |
|
608 { |
|
609 return d_ptr->_state; |
|
610 } |
|
611 |
|
612 void QMessageService::cancel() |
|
613 { |
|
614 } |
|
615 |
|
616 QMessageManager::Error QMessageService::error() const |
|
617 { |
|
618 return d_ptr->_error; |
|
619 } |
|
620 |
|
621 #include "moc_qmessageservice_maemo_p.cpp" |
|
622 |
|
623 QTM_END_NAMESPACE |