212 { |
506 { |
213 updateEmailAccounts(); |
507 updateEmailAccounts(); |
214 return iAccounts[id.toString()]; |
508 return iAccounts[id.toString()]; |
215 } |
509 } |
216 |
510 |
217 QMessageAccountId ModestEngine::defaultAccount(QMessage::Type type) const |
511 QMessageAccountId ModestEngine::defaultAccount() const |
218 { |
512 { |
219 updateEmailAccounts(); |
513 updateEmailAccounts(); |
220 return iDefaultEmailAccountId; |
514 return iDefaultEmailAccountId; |
221 } |
515 } |
222 |
516 |
|
517 QFileInfoList ModestEngine::localFolders() const |
|
518 { |
|
519 QDir dir(localRootFolder()); |
|
520 dir.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot); |
|
521 QFileInfoList fileInfoList = dir.entryInfoList(); |
|
522 appendLocalSubFolders(fileInfoList, 0); |
|
523 return fileInfoList; |
|
524 } |
|
525 |
|
526 void ModestEngine::appendLocalSubFolders(QFileInfoList& fileInfoList, int startIndex) const |
|
527 { |
|
528 int endIndex = fileInfoList.count(); |
|
529 for (int i=startIndex; i < endIndex; i++) { |
|
530 QDir dir(fileInfoList[i].absoluteFilePath()); |
|
531 if (dir.exists()) { |
|
532 dir.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot); |
|
533 QFileInfoList dirs = dir.entryInfoList(); |
|
534 for (int j = 0; j < dirs.count(); j++) { |
|
535 QString fileName = dirs[j].fileName(); |
|
536 if (fileName != "cur" && fileName != "new" && fileName != "tmp") { |
|
537 fileInfoList.append(dirs[j]); |
|
538 } |
|
539 } |
|
540 } |
|
541 } |
|
542 if (fileInfoList.count() > endIndex) { |
|
543 appendLocalSubFolders(fileInfoList, endIndex); |
|
544 } |
|
545 } |
|
546 |
|
547 void ModestEngine::appendIMAPSubFolders(QFileInfoList& fileInfoList, int startIndex) const |
|
548 { |
|
549 int endIndex = fileInfoList.count(); |
|
550 for (int i=startIndex; i < endIndex; i++) { |
|
551 QDir dir(fileInfoList[i].absoluteFilePath()+QString("/subfolders")); |
|
552 if (dir.exists()) { |
|
553 dir.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot); |
|
554 fileInfoList.append(dir.entryInfoList()); |
|
555 } |
|
556 } |
|
557 if (fileInfoList.count() > endIndex) { |
|
558 appendIMAPSubFolders(fileInfoList, endIndex); |
|
559 } |
|
560 } |
|
561 |
|
562 QString ModestEngine::localRootFolder() const |
|
563 { |
|
564 return QDir::home().absolutePath()+QString("/.modest/local_folders"); |
|
565 } |
|
566 |
|
567 QString ModestEngine::accountRootFolder(QMessageAccountId& accountId) const |
|
568 { |
|
569 QString modestAccountId = escapeString(modestAccountIdFromAccountId(accountId)); |
|
570 |
|
571 QString userName; |
|
572 QString hostName; |
|
573 QString port; |
|
574 QString protocol; |
|
575 |
|
576 gchar* store_account_key = g_strconcat(MODESTENGINE_ACCOUNT_NAMESPACE, "/", modestAccountId.toUtf8().data(), "/", MODESTENGINE_ACCOUNT_STORE_ACCOUNT, NULL); |
|
577 gchar* store_account_name = gconf_client_get_string(m_gconfclient, store_account_key, NULL); |
|
578 g_free(store_account_key); |
|
579 gchar* escaped_store_account_name = gconf_escape_key(store_account_name, strlen(store_account_name)); |
|
580 g_free(store_account_name); |
|
581 |
|
582 gchar* username_key = g_strconcat(MODESTENGINE_SERVER_ACCOUNT_NAMESPACE, "/", escaped_store_account_name, "/", MODESTENGINE_ACCOUNT_USERNAME, NULL); |
|
583 gchar* account_username = gconf_client_get_string(m_gconfclient, username_key, NULL); |
|
584 userName = QString::fromUtf8(account_username); |
|
585 g_free(account_username); |
|
586 g_free(username_key); |
|
587 |
|
588 gchar* hostname_key = g_strconcat(MODESTENGINE_SERVER_ACCOUNT_NAMESPACE, "/", escaped_store_account_name, "/", MODESTENGINE_ACCOUNT_HOSTNAME, NULL); |
|
589 gchar* account_hostname = gconf_client_get_string(m_gconfclient, hostname_key, NULL); |
|
590 hostName = QString::fromUtf8(account_hostname); |
|
591 g_free(account_hostname); |
|
592 g_free(hostname_key); |
|
593 |
|
594 gchar* port_key = g_strconcat(MODESTENGINE_SERVER_ACCOUNT_NAMESPACE, "/", escaped_store_account_name, "/", MODESTENGINE_ACCOUNT_PORT, NULL); |
|
595 gint account_port = gconf_client_get_int(m_gconfclient, port_key, NULL); |
|
596 port = QString::number(account_port); |
|
597 g_free(port_key); |
|
598 |
|
599 gchar* protocol_key = g_strconcat(MODESTENGINE_SERVER_ACCOUNT_NAMESPACE, "/", escaped_store_account_name, "/", MODESTENGINE_ACCOUNT_PROTOCOL, NULL); |
|
600 gchar* account_protocol = gconf_client_get_string(m_gconfclient, protocol_key, NULL); |
|
601 protocol = QString::fromUtf8(account_protocol); |
|
602 g_free(account_protocol); |
|
603 g_free(protocol_key); |
|
604 |
|
605 g_free(escaped_store_account_name); |
|
606 |
|
607 if (protocol == "pop") { |
|
608 return QDir::home().absolutePath()+"/.modest/cache/mail/"+protocol+"/"+userName+"__"+hostName+"_"+port; |
|
609 } else if (protocol == "imap") { |
|
610 return QDir::home().absolutePath()+"/.modest/cache/mail/"+protocol+"/"+userName+"__"+hostName+"_"+port+"/folders"; |
|
611 } |
|
612 return QString(); |
|
613 } |
|
614 |
|
615 QFileInfoList ModestEngine::accountFolders(QMessageAccountId& accountId) const |
|
616 { |
|
617 QFileInfoList fileInfoList; |
|
618 |
|
619 EmailProtocol protocol = accountEmailProtocol(accountId); |
|
620 |
|
621 if (protocol == ModestEngine::EmailProtocolPop3) { |
|
622 QFileInfo fileInfo = QFileInfo(accountRootFolder(accountId)+"/cache"); |
|
623 fileInfoList.append(fileInfo); |
|
624 } else if (protocol == ModestEngine::EmailProtocolIMAP) { |
|
625 QDir dir(accountRootFolder(accountId)); |
|
626 dir.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot); |
|
627 fileInfoList = dir.entryInfoList(); |
|
628 appendIMAPSubFolders(fileInfoList, 0); |
|
629 } |
|
630 |
|
631 return fileInfoList; |
|
632 } |
|
633 |
|
634 ModestEngine::EmailProtocol ModestEngine::accountEmailProtocol(QMessageAccountId& accountId) const |
|
635 { |
|
636 EmailProtocol protocol = EmailProtocolUnknown; |
|
637 |
|
638 QString modestAccountId = escapeString(modestAccountIdFromAccountId(accountId)); |
|
639 |
|
640 gchar* store_account_key = g_strconcat(MODESTENGINE_ACCOUNT_NAMESPACE, "/", modestAccountId.toUtf8().data(), "/", MODESTENGINE_ACCOUNT_STORE_ACCOUNT, NULL); |
|
641 gchar* store_account_name = gconf_client_get_string(m_gconfclient, store_account_key, NULL); |
|
642 g_free(store_account_key); |
|
643 gchar* escaped_store_account_name = gconf_escape_key(store_account_name, strlen(store_account_name)); |
|
644 g_free(store_account_name); |
|
645 |
|
646 gchar* protocol_key = g_strconcat(MODESTENGINE_SERVER_ACCOUNT_NAMESPACE, "/", escaped_store_account_name, "/", MODESTENGINE_ACCOUNT_PROTOCOL, NULL); |
|
647 gchar* account_protocol = gconf_client_get_string(m_gconfclient, protocol_key, NULL); |
|
648 if (QString("pop") == account_protocol) { |
|
649 protocol = EmailProtocolPop3; |
|
650 } else if (QString("imap") == account_protocol) { |
|
651 protocol = EmailProtocolIMAP; |
|
652 } |
|
653 g_free(account_protocol); |
|
654 g_free(protocol_key); |
|
655 |
|
656 g_free(escaped_store_account_name); |
|
657 |
|
658 return protocol; |
|
659 } |
|
660 |
|
661 QString ModestEngine::accountEmailProtocolAsString(const QMessageAccountId& accountId) const |
|
662 { |
|
663 QString protocol; |
|
664 |
|
665 QString modestAccountId = escapeString(modestAccountIdFromAccountId(accountId)); |
|
666 |
|
667 gchar* store_account_key = g_strconcat(MODESTENGINE_ACCOUNT_NAMESPACE, "/", modestAccountId.toUtf8().data(), "/", MODESTENGINE_ACCOUNT_STORE_ACCOUNT, NULL); |
|
668 gchar* store_account_name = gconf_client_get_string(m_gconfclient, store_account_key, NULL); |
|
669 g_free(store_account_key); |
|
670 gchar* escaped_store_account_name = gconf_escape_key(store_account_name, strlen(store_account_name)); |
|
671 g_free(store_account_name); |
|
672 |
|
673 gchar* protocol_key = g_strconcat(MODESTENGINE_SERVER_ACCOUNT_NAMESPACE, "/", escaped_store_account_name, "/", MODESTENGINE_ACCOUNT_PROTOCOL, NULL); |
|
674 gchar* account_protocol = gconf_client_get_string(m_gconfclient, protocol_key, NULL); |
|
675 protocol = QString::fromUtf8(account_protocol); |
|
676 g_free(account_protocol); |
|
677 g_free(protocol_key); |
|
678 |
|
679 g_free(escaped_store_account_name); |
|
680 |
|
681 return protocol; |
|
682 } |
|
683 |
|
684 QString ModestEngine::accountUsername(QMessageAccountId& accountId) const |
|
685 { |
|
686 QString username; |
|
687 |
|
688 QString modestAccountId = escapeString(modestAccountIdFromAccountId(accountId)); |
|
689 |
|
690 gchar* store_account_key = g_strconcat(MODESTENGINE_ACCOUNT_NAMESPACE, "/", modestAccountId.toUtf8().data(), "/", MODESTENGINE_ACCOUNT_STORE_ACCOUNT, NULL); |
|
691 gchar* store_account_name = gconf_client_get_string(m_gconfclient, store_account_key, NULL); |
|
692 g_free(store_account_key); |
|
693 gchar* escaped_store_account_name = gconf_escape_key(store_account_name, strlen(store_account_name)); |
|
694 g_free(store_account_name); |
|
695 |
|
696 gchar* username_key = g_strconcat(MODESTENGINE_SERVER_ACCOUNT_NAMESPACE, "/", escaped_store_account_name, "/", MODESTENGINE_ACCOUNT_USERNAME, NULL); |
|
697 gchar* account_username = gconf_client_get_string(m_gconfclient, username_key, NULL); |
|
698 username = QString::fromUtf8(account_username); |
|
699 g_free(account_username); |
|
700 g_free(username_key); |
|
701 |
|
702 g_free(escaped_store_account_name); |
|
703 |
|
704 return username; |
|
705 } |
|
706 |
|
707 QString ModestEngine::accountHostname(QMessageAccountId& accountId) const |
|
708 { |
|
709 QString host; |
|
710 |
|
711 QString modestAccountId = escapeString(modestAccountIdFromAccountId(accountId)); |
|
712 |
|
713 gchar* store_account_key = g_strconcat(MODESTENGINE_ACCOUNT_NAMESPACE, "/", modestAccountId.toUtf8().data(), "/", MODESTENGINE_ACCOUNT_STORE_ACCOUNT, NULL); |
|
714 gchar* store_account_name = gconf_client_get_string(m_gconfclient, store_account_key, NULL); |
|
715 g_free(store_account_key); |
|
716 gchar* escaped_store_account_name = gconf_escape_key(store_account_name, strlen(store_account_name)); |
|
717 g_free(store_account_name); |
|
718 |
|
719 gchar* host_key = g_strconcat(MODESTENGINE_SERVER_ACCOUNT_NAMESPACE, "/", escaped_store_account_name, "/", MODESTENGINE_ACCOUNT_HOSTNAME, NULL); |
|
720 gchar* account_host = gconf_client_get_string(m_gconfclient, host_key, NULL); |
|
721 host = QString::fromUtf8(account_host); |
|
722 g_free(account_host); |
|
723 g_free(host_key); |
|
724 |
|
725 g_free(escaped_store_account_name); |
|
726 |
|
727 return host; |
|
728 } |
|
729 |
|
730 QMessageFolderIdList ModestEngine::queryFolders(const QMessageFolderFilter &filter, const QMessageFolderSortOrder &sortOrder, |
|
731 uint limit, uint offset, bool &isFiltered, bool &isSorted) const |
|
732 { |
|
733 Q_UNUSED(sortOrder) |
|
734 Q_UNUSED(limit) |
|
735 Q_UNUSED(offset) |
|
736 |
|
737 QMessageFolderIdList folderIds; |
|
738 |
|
739 updateEmailAccounts(); |
|
740 |
|
741 //QDBusMessage msg = m_ModestDBusInterface->call(MODEST_DBUS_METHOD_GET_FOLDERS); |
|
742 QFileInfoList localFolders = this->localFolders(); |
|
743 QString localRootFolder = this->localRootFolder(); |
|
744 |
|
745 foreach (QMessageAccount value, iAccounts) { |
|
746 QMessageAccountId accountId = value.id(); |
|
747 QString rootFolder = accountRootFolder(accountId); |
|
748 QFileInfoList folders = this->accountFolders(accountId); |
|
749 |
|
750 for (int i=0; i < folders.count(); i++) { |
|
751 QString filePath = folders[i].absoluteFilePath(); |
|
752 QString id = accountId.toString()+"&"+accountEmailProtocolAsString(accountId)+"&"+filePath.right(filePath.size()-rootFolder.size()-1); |
|
753 id = id.remove("/subfolders"); |
|
754 folderIds.append(QMessageFolderId(id)); |
|
755 } |
|
756 |
|
757 // Each account sees local folders as account folders |
|
758 for (int i=0; i < localFolders.count(); i++) { |
|
759 QString filePath = localFolders[i].absoluteFilePath(); |
|
760 QString id = accountId.toString()+"&"+"maildir"+"&"+filePath.right(filePath.size()-localRootFolder.size()-1); |
|
761 folderIds.append(QMessageFolderId(id)); |
|
762 } |
|
763 } |
|
764 |
|
765 MessagingHelper::filterFolders(folderIds, filter); |
|
766 isFiltered = true; |
|
767 isSorted = false; |
|
768 return folderIds; |
|
769 } |
|
770 |
|
771 int ModestEngine::countFolders(const QMessageFolderFilter &filter) const |
|
772 { |
|
773 bool isFiltered, isSorted; |
|
774 return queryFolders(filter, QMessageFolderSortOrder(), 0, 0, isFiltered, isSorted).count(); |
|
775 } |
|
776 |
|
777 QMessageFolder ModestEngine::folder(const QMessageFolderId &id) const |
|
778 { |
|
779 QString idString = id.toString(); |
|
780 int endOfAccountId = idString.indexOf('&'); |
|
781 int endOfProtocolString = idString.lastIndexOf('&'); |
|
782 QString accountId = idString.left(endOfAccountId); |
|
783 QString protocolString = idString.mid(endOfAccountId+1, endOfProtocolString-endOfAccountId-1); |
|
784 QString folder = idString.right(idString.length()-idString.lastIndexOf('&')-1); |
|
785 QMessageFolderId parentId; |
|
786 QString name; |
|
787 if (folder.lastIndexOf('/') == -1) { |
|
788 // Folder does not have subfolders |
|
789 name = folder; |
|
790 if ((protocolString == "pop") && (name == "cache")) { |
|
791 name = "Inbox"; |
|
792 } |
|
793 } else { |
|
794 // Folder has subfolders |
|
795 name = folder.right(folder.length()-folder.lastIndexOf('/')-1); |
|
796 parentId = idString.left(idString.lastIndexOf('/')); |
|
797 } |
|
798 return QMessageFolderPrivate::from(id, QMessageAccountId(accountId), parentId, name, folder); |
|
799 } |
|
800 |
|
801 void ModestEngine::watchAllKnownEmailFolders() |
|
802 { |
|
803 QFileInfoList localFolders = this->localFolders(); |
|
804 |
|
805 // Changes in local Email folders can be monitored using directory |
|
806 // monitoring. <=> All messages are stored as individual files. |
|
807 for (int i=0; i < localFolders.count(); i++) { |
|
808 m_MailFoldersWatcher.addDirectory(localFolders[i].absoluteFilePath()+"/cur", IN_MOVED_TO | IN_DELETE); |
|
809 } |
|
810 |
|
811 // Monitor changes also in root folder to see if new folders are added |
|
812 m_MailFoldersWatcher.addDirectory(localRootFolder(), IN_CREATE); |
|
813 |
|
814 // Changes in remote Email folders must be monitored using file monitoring. |
|
815 // That's because message headers are stored into summary.mmap file (and summary.mmap |
|
816 // file maybe the only place that contains message information). |
|
817 // => summary.mmap files will be monitored |
|
818 foreach (QMessageAccount value, iAccounts) { |
|
819 QMessageAccountId accountId = value.id(); |
|
820 QString rootFolder = accountRootFolder(accountId); |
|
821 EmailProtocol protocol = accountEmailProtocol(accountId); |
|
822 QFileInfoList folders = this->accountFolders(accountId); |
|
823 |
|
824 for (int i=0; i < folders.count(); i++) { |
|
825 if (protocol == ModestEngine::EmailProtocolPop3) { |
|
826 QString folder = folders[i].absoluteFilePath(); |
|
827 m_MailFoldersWatcher.addDirectory(folder, IN_CREATE); |
|
828 } else if (protocol == ModestEngine::EmailProtocolIMAP) { |
|
829 m_MailFoldersWatcher.addDirectory(folders[i].absoluteFilePath(), IN_MOVED_TO | IN_DELETE); |
|
830 } |
|
831 } |
|
832 |
|
833 } |
|
834 } |
|
835 |
|
836 void ModestEngine::fileChangedSlot(int watchDescriptor, QString filePath, uint events) |
|
837 { |
|
838 Q_UNUSED(watchDescriptor) |
|
839 |
|
840 if (events & IN_CREATE) { |
|
841 if (QFileInfo(filePath).isDir()) { |
|
842 // New directory was added |
|
843 // => Start watching new folder |
|
844 QString newDirPath = QString(filePath.toUtf8()); |
|
845 m_MailFoldersWatcher.addDirectory(newDirPath + "/cur"); |
|
846 } |
|
847 } |
|
848 |
|
849 int filenameBegin = filePath.lastIndexOf('/')+1; |
|
850 QString fileName = filePath.mid(filenameBegin,filePath.lastIndexOf('.')-filenameBegin); |
|
851 if (fileName != "summary") { |
|
852 if (events & (IN_MOVED_TO | IN_CREATE)) { |
|
853 if (events != (IN_MOVED_TO | IN_MOVED_FROM)) { |
|
854 notification(messageIdFromModestMessageFilePath(filePath), ModestEngine::Added); |
|
855 } |
|
856 } else if (events & IN_DELETE) { |
|
857 notification(messageIdFromModestMessageFilePath(filePath), ModestEngine::Removed); |
|
858 } |
|
859 } |
|
860 } |
|
861 |
223 bool ModestEngine::sendEmail(QMessage &message) |
862 bool ModestEngine::sendEmail(QMessage &message) |
224 { |
863 { |
225 return composeEmail(message); |
864 ModestStringMap senderInfo; |
|
865 ModestStringMap recipients; |
|
866 ModestStringMap messageData; |
|
867 ModestStringMapList attachments; |
|
868 ModestStringMapList images; |
|
869 uint priority = 0; |
|
870 ModestStringMap headers; |
|
871 |
|
872 senderInfo = getModestSenderInfo(message); |
|
873 |
|
874 if (senderInfo.isEmpty()) { |
|
875 return false; |
|
876 } |
|
877 |
|
878 recipients = getModestRecipients(message); |
|
879 |
|
880 if (recipients.isEmpty()) { |
|
881 return false; |
|
882 } |
|
883 |
|
884 messageData = getModestMessageData(message); |
|
885 attachments = getModestAttachments(message); |
|
886 images = getModestImages(message); |
|
887 priority = getModestPriority(message); |
|
888 headers = getModestHeaders(message); |
|
889 |
|
890 qDebug() << "Sending D-BUS message"; |
|
891 |
|
892 QDBusPendingCall call = m_QtmPluginDBusInterface->asyncCall ( |
|
893 "SendEmail", |
|
894 QVariant::fromValue (senderInfo), |
|
895 QVariant::fromValue (recipients), |
|
896 QVariant::fromValue (messageData), |
|
897 QVariant::fromValue (attachments), |
|
898 QVariant::fromValue (images), |
|
899 priority, |
|
900 QVariant::fromValue (headers)); |
|
901 |
|
902 qDebug() << "Message sent"; |
|
903 |
|
904 if (call.isError()) { |
|
905 qWarning() << "Call failed! " << call.error(); |
|
906 return false; |
|
907 } |
|
908 |
|
909 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher (call, this); |
|
910 |
|
911 connect (watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), |
|
912 this, SLOT(sendEmailCallEnded(QDBusPendingCallWatcher*))); |
|
913 |
|
914 return true; |
226 } |
915 } |
227 |
916 |
228 bool ModestEngine::composeEmail(const QMessage &message) |
917 bool ModestEngine::composeEmail(const QMessage &message) |
229 { |
918 { |
230 QString mailString("mailto:"); |
919 QString mailString("mailto:"); |
231 QList<QMessageAddress> list(message.to()); |
920 QList<QMessageAddress> list(message.to()); |
232 if (!list.empty()){ |
921 if (!list.empty()){ |
233 for (int i = 0; i < list.size(); ++i) { |
922 for (int i = 0; i < list.size(); ++i) { |
234 if (i == 0) { |
923 if (i == 0) { |
235 mailString += list.at(i).recipient(); |
924 mailString += list.at(i).addressee(); |
236 } else { |
925 } else { |
237 mailString += QString("%2C%20"); |
926 mailString += QString("%2C%20"); |
238 mailString += list.at(i).recipient(); |
927 mailString += list.at(i).addressee(); |
239 } |
928 } |
240 } |
929 } |
241 } |
930 } |
242 |
931 |
243 bool firstParameter = true; |
932 bool firstParameter = true; |
272 QDBusMessage msg = dbusif.call(MODEST_DBUS_METHOD_MAIL_TO, url.toString()); |
961 QDBusMessage msg = dbusif.call(MODEST_DBUS_METHOD_MAIL_TO, url.toString()); |
273 |
962 |
274 return true; |
963 return true; |
275 } |
964 } |
276 |
965 |
|
966 bool ModestEngine::showMessage(const QMessageId &id) |
|
967 { |
|
968 QMessage msg = message(id, false); |
|
969 QMessagePrivate* privateMessage = QMessagePrivate::implementation(msg); |
|
970 if (privateMessage->_url.isEmpty()) { |
|
971 return false; |
|
972 } else { |
|
973 m_ModestDBusInterface->call(MODEST_DBUS_METHOD_OPEN_MESSAGE, |
|
974 privateMessage->_url); |
|
975 } |
|
976 return true; |
|
977 } |
|
978 |
|
979 bool ModestEngine::exportUpdates(const QMessageAccountId &id) |
|
980 { |
|
981 Q_UNUSED(id) // Modest does not offer Account specific updates |
|
982 |
|
983 m_ModestDBusInterface->call(MODEST_DBUS_METHOD_SEND_RECEIVE); |
|
984 return true; |
|
985 } |
|
986 |
|
987 QMessage ModestEngine::message(const QMessageId &id, bool useCache) const |
|
988 { |
|
989 if (useCache) { |
|
990 QMessage message = m_messageCache.value(id.toString()); |
|
991 if (message.type() != QMessage::NoType) { |
|
992 return message; |
|
993 } |
|
994 } |
|
995 |
|
996 QString modestAccountId = modestAccountIdFromMessageId(id); |
|
997 QString modestFolderId = modestFolderIdFromMessageId(id); |
|
998 QString modestMessageId = modestMessageIdFromMessageId(id); |
|
999 |
|
1000 MessagingModestMessage modestMessage = messageFromModest(modestAccountId, |
|
1001 modestFolderId, |
|
1002 modestMessageId); |
|
1003 |
|
1004 if (modestMessage.flags & MessagingModestMessageDeleted) { |
|
1005 return QMessage(); |
|
1006 } |
|
1007 |
|
1008 if (modestMessage.accountId.isEmpty()) { |
|
1009 return QMessage(); |
|
1010 } |
|
1011 |
|
1012 return messageFromModestMessage(modestMessage, accountIdFromMessageId(id)); |
|
1013 } |
|
1014 |
|
1015 QMessage::StandardFolder ModestEngine::standardFolderFromModestFolderId(const QString& modestFolderId) const |
|
1016 { |
|
1017 if (!QString::compare(modestFolderId, "INBOX", Qt::CaseInsensitive)) { |
|
1018 return QMessage::InboxFolder; |
|
1019 } else if (!QString::compare(modestFolderId, "drafts", Qt::CaseInsensitive)) { |
|
1020 return QMessage::DraftsFolder; |
|
1021 } else if (!QString::compare(modestFolderId, "sent", Qt::CaseInsensitive)) { |
|
1022 return QMessage::SentFolder; |
|
1023 } |
|
1024 |
|
1025 return QMessage::DraftsFolder; |
|
1026 } |
|
1027 |
|
1028 QString ModestEngine::modestFolderIdFromStandardFolder(QMessage::StandardFolder standardFolder) const |
|
1029 { |
|
1030 switch (standardFolder) { |
|
1031 case QMessage::InboxFolder: return "INBOX"; |
|
1032 case QMessage::DraftsFolder: return "drafts"; |
|
1033 case QMessage::SentFolder: return "sent"; |
|
1034 case QMessage::OutboxFolder: return "outbox"; |
|
1035 case QMessage::TrashFolder: return "thrash"; |
|
1036 } |
|
1037 return "drafts"; |
|
1038 } |
|
1039 |
|
1040 QMessage ModestEngine::messageFromModestMessage(const MessagingModestMessage& modestMessage, |
|
1041 QMessageAccountId accountId) const |
|
1042 { |
|
1043 QMessage message; |
|
1044 QMessagePrivate* privateMessage = QMessagePrivate::implementation(message); |
|
1045 QMessageContentContainerPrivate* container = QMessagePrivate::containerImplementation(message); |
|
1046 |
|
1047 // Type |
|
1048 message.setType(QMessage::Email); |
|
1049 |
|
1050 // Parent Account Id |
|
1051 QMessageAccountId parentAccountId; |
|
1052 if (accountId.isValid()) { |
|
1053 parentAccountId = accountId; |
|
1054 } else { |
|
1055 parentAccountId = realAccountId(modestMessage); |
|
1056 } |
|
1057 message.setParentAccountId(parentAccountId); |
|
1058 |
|
1059 // Parent Folder Id |
|
1060 QMessageFolderId folderId; |
|
1061 if (modestMessage.accountId == "local_folders") { |
|
1062 folderId = folderIdFromModestFolderId(parentAccountId, true, modestMessage.folderId); |
|
1063 } else { |
|
1064 // Since Message is not in local folder, message status can be set to Incoming |
|
1065 privateMessage->_status = privateMessage->_status | QMessage::Incoming; |
|
1066 folderId = folderIdFromModestFolderId(parentAccountId, false, modestMessage.folderId); |
|
1067 } |
|
1068 privateMessage->_parentFolderId = folderId; |
|
1069 |
|
1070 // Message Id |
|
1071 QMessageId messageId = QMessageId(folderId.toString()+"/"+modestMessage.id); |
|
1072 privateMessage->_id = messageId; |
|
1073 |
|
1074 // Dates |
|
1075 message.setDate(QDateTime::fromTime_t(modestMessage.dateSent)); |
|
1076 message.setReceivedDate(QDateTime::fromTime_t(modestMessage.dateReceived)); |
|
1077 |
|
1078 // Priority |
|
1079 switch (modestMessage.priority) { |
|
1080 case QtMobility::MessagingModestMessageHighPriority: |
|
1081 message.setPriority(QMessage::HighPriority); |
|
1082 break; |
|
1083 case QtMobility::MessagingModestMessageNormalPriority: |
|
1084 message.setPriority(QMessage::NormalPriority); |
|
1085 break; |
|
1086 case QtMobility::MessagingModestMessageLowPriority: |
|
1087 message.setPriority(QMessage::LowPriority); |
|
1088 break; |
|
1089 case QtMobility::MessagingModestMessageSuspendedPriority: |
|
1090 message.setPriority(QMessage::NormalPriority); |
|
1091 break; |
|
1092 } |
|
1093 |
|
1094 // Standard Folder |
|
1095 QMessagePrivate::setStandardFolder(message, |
|
1096 standardFolderFromModestFolderId(modestMessage.folderId)); |
|
1097 |
|
1098 // Body & Attachments handling |
|
1099 for (int i=0; i < modestMessage.mimeParts.count(); i++) { |
|
1100 if (!modestMessage.mimeParts[i].isAttachment) { |
|
1101 // Body |
|
1102 QByteArray fullMimeType = modestMessage.mimeParts[i].mimeType.toUtf8(); |
|
1103 QString contentId = modestMessage.mimeParts[i].contentId; |
|
1104 QByteArray fileName = modestMessage.mimeParts[i].fileName.toAscii(); |
|
1105 |
|
1106 QByteArray mainType("text"); |
|
1107 QByteArray subType("plain"); |
|
1108 QByteArray charset; |
|
1109 |
|
1110 int index = fullMimeType.indexOf("/"); |
|
1111 if (index != -1) { |
|
1112 mainType = fullMimeType.left(index).trimmed(); |
|
1113 |
|
1114 subType = fullMimeType.mid(index + 1).trimmed(); |
|
1115 index = subType.indexOf(";"); |
|
1116 if (index != -1) { |
|
1117 QString remainder = subType.mid(index + 1); |
|
1118 subType = subType.left(index).trimmed(); |
|
1119 |
|
1120 QRegExp charsetPattern("charset=(\\S+)"); |
|
1121 index = charsetPattern.indexIn(remainder); |
|
1122 if (index != -1) { |
|
1123 charset = charsetPattern.cap(1).toLatin1(); |
|
1124 } |
|
1125 } |
|
1126 } |
|
1127 |
|
1128 if (charset.isEmpty()) { |
|
1129 charset = "UTF-8"; |
|
1130 } |
|
1131 |
|
1132 QMessageContentContainerId existingBodyId(message.bodyId()); |
|
1133 if (existingBodyId.isValid()) { |
|
1134 if (existingBodyId == container->bodyContentId()) { |
|
1135 // The body content is in the message itself |
|
1136 container->_containingMessageId = messageId.toString(); |
|
1137 container->_attachmentId = contentId; |
|
1138 container->_name = fileName; |
|
1139 container->_type = mainType; |
|
1140 container->_subType = subType; |
|
1141 container->_charset = charset; |
|
1142 container->_size = 0; |
|
1143 container->_available = true; |
|
1144 } else { |
|
1145 // The body content is in the first attachment |
|
1146 QMessageContentContainerPrivate *attachmentContainer(QMessageContentContainerPrivate::implementation(*container->attachment(existingBodyId))); |
|
1147 attachmentContainer->_containingMessageId = messageId.toString(); |
|
1148 attachmentContainer->_attachmentId = contentId; |
|
1149 attachmentContainer->_name = fileName; |
|
1150 attachmentContainer->_type = mainType; |
|
1151 attachmentContainer->_subType = subType; |
|
1152 attachmentContainer->_charset = charset; |
|
1153 attachmentContainer->_size = 0; |
|
1154 attachmentContainer->_available = true; |
|
1155 } |
|
1156 } else { |
|
1157 if (container->_attachments.isEmpty()) { |
|
1158 // Put the content directly into the message |
|
1159 container->_containingMessageId = messageId.toString(); |
|
1160 container->_attachmentId = contentId; |
|
1161 container->_name = fileName; |
|
1162 container->_type = mainType; |
|
1163 container->_subType = subType; |
|
1164 container->_charset = charset; |
|
1165 container->_size = 0; |
|
1166 container->_available = true; |
|
1167 privateMessage->_bodyId = container->bodyContentId(); |
|
1168 } else { |
|
1169 // Add the body as the first attachment |
|
1170 QMessageContentContainer newBody; |
|
1171 QMessageContentContainerPrivate *attachmentContainer = QMessageContentContainerPrivate::implementation(newBody); |
|
1172 attachmentContainer->_containingMessageId = messageId.toString(); |
|
1173 attachmentContainer->_attachmentId = contentId; |
|
1174 attachmentContainer->_name = fileName; |
|
1175 attachmentContainer->_type = mainType; |
|
1176 attachmentContainer->_subType = subType; |
|
1177 attachmentContainer->_charset = charset; |
|
1178 attachmentContainer->_size = 0; |
|
1179 attachmentContainer->_available = true; |
|
1180 privateMessage->_bodyId = container->prependContent(newBody); |
|
1181 } |
|
1182 } |
|
1183 } else { |
|
1184 // Attachment |
|
1185 QString fullMimeType = modestMessage.mimeParts[i].mimeType; |
|
1186 QString contentId = modestMessage.mimeParts[i].contentId; |
|
1187 int slashIndex = fullMimeType.indexOf('/'); |
|
1188 QByteArray mimeType = fullMimeType.left(slashIndex).toAscii(); |
|
1189 QByteArray mimeSubType = fullMimeType.mid(slashIndex+1).toAscii(); |
|
1190 // TODO: Attachment size |
|
1191 QByteArray fileName = modestMessage.mimeParts[i].fileName.toAscii(); |
|
1192 fileName = fileName.mid(fileName.lastIndexOf('/')+1); |
|
1193 QString msgId = messageId.toString(); |
|
1194 QMessageContentContainer attachment = |
|
1195 QMessageContentContainerPrivate::from(msgId, |
|
1196 contentId, |
|
1197 fileName, |
|
1198 mimeType, |
|
1199 mimeSubType, |
|
1200 0); |
|
1201 appendAttachmentToMessage(message, attachment); |
|
1202 } |
|
1203 } |
|
1204 |
|
1205 // From |
|
1206 if (modestMessage.from.size() > 0) { |
|
1207 message.setFrom(QMessageAddress(QMessageAddress::Email, modestMessage.from)); |
|
1208 QMessagePrivate::setSenderName(message, modestMessage.from); |
|
1209 } |
|
1210 |
|
1211 // To |
|
1212 if (modestMessage.to.size() > 0) { |
|
1213 QMessageAddressList toAddresses; |
|
1214 foreach (const QString &element, modestMessage.to.split(",", QString::SkipEmptyParts)) { |
|
1215 QMessageAddress addr; |
|
1216 addr.setType(QMessageAddress::Email); |
|
1217 addr.setAddressee(element.trimmed()); |
|
1218 toAddresses.append(addr); |
|
1219 } |
|
1220 message.setTo(toAddresses); |
|
1221 } |
|
1222 |
|
1223 // Cc |
|
1224 if (modestMessage.cc.size() > 0) { |
|
1225 QMessageAddressList ccAddresses; |
|
1226 foreach (const QString &element, modestMessage.cc.split(",", QString::SkipEmptyParts)) { |
|
1227 QMessageAddress addr; |
|
1228 addr.setType(QMessageAddress::Email); |
|
1229 addr.setAddressee(element.trimmed()); |
|
1230 ccAddresses.append(addr); |
|
1231 } |
|
1232 message.setCc(ccAddresses); |
|
1233 } |
|
1234 |
|
1235 // Bcc |
|
1236 if (modestMessage.bcc.size() > 0) { |
|
1237 QMessageAddressList bccAddresses; |
|
1238 foreach (const QString &element, modestMessage.bcc.split(",", QString::SkipEmptyParts)) { |
|
1239 QMessageAddress addr; |
|
1240 addr.setType(QMessageAddress::Email); |
|
1241 addr.setAddressee(element.trimmed()); |
|
1242 bccAddresses.append(addr); |
|
1243 } |
|
1244 message.setBcc(bccAddresses); |
|
1245 } |
|
1246 |
|
1247 // Subject |
|
1248 message.setSubject(modestMessage.subject); |
|
1249 |
|
1250 // Size |
|
1251 privateMessage->_size = modestMessage.size; |
|
1252 |
|
1253 // Read Status |
|
1254 if (modestMessage.flags & MessagingModestMessageSeen) { |
|
1255 privateMessage->_status = privateMessage->_status | QMessage::Read; |
|
1256 } |
|
1257 |
|
1258 // Message MIME type |
|
1259 QString fullMimeType = modestMessage.mimeType; |
|
1260 int slashIndex = fullMimeType.indexOf('/'); |
|
1261 QByteArray mimeType = fullMimeType.left(slashIndex).toAscii(); |
|
1262 QByteArray mimeSubType = fullMimeType.mid(slashIndex+1).toAscii(); |
|
1263 container->_type = mimeType.data(); |
|
1264 container->_subType = mimeSubType.data(); |
|
1265 |
|
1266 // Modest specific url |
|
1267 privateMessage->_url = modestMessage.url; |
|
1268 |
|
1269 // Modified flag |
|
1270 privateMessage->_modified = false; |
|
1271 |
|
1272 return message; |
|
1273 } |
|
1274 |
|
1275 void ModestEngine::appendAttachmentToMessage(QMessage& message, QMessageContentContainer& attachment) const |
|
1276 { |
|
1277 QMessagePrivate* privateMessage = QMessagePrivate::implementation(message); |
|
1278 QMessageContentContainerPrivate* container = QMessagePrivate::containerImplementation(message); |
|
1279 |
|
1280 if (container->_attachments.isEmpty()) { |
|
1281 QMessageContentContainerId existingBodyId(message.bodyId()); |
|
1282 if (existingBodyId == QMessageContentContainerPrivate::bodyContentId()) { |
|
1283 // The body content is in the message itself - move it to become the first attachment |
|
1284 QMessageContentContainer newBody(message); |
|
1285 QMessageContentContainerPrivate::implementation(newBody)->setDerivedMessage(0); |
|
1286 |
|
1287 container->setContentType("multipart", "mixed", ""); |
|
1288 privateMessage->_bodyId = container->prependContent(newBody); |
|
1289 } else { |
|
1290 // This message is now multipart |
|
1291 container->setContentType("multipart", "mixed", ""); |
|
1292 } |
|
1293 |
|
1294 container->_available = true; |
|
1295 } |
|
1296 |
|
1297 container->appendContent(attachment); |
|
1298 |
|
1299 bool haveAttachments = !container->_attachments.isEmpty(); |
|
1300 message.setStatus(QMessage::HasAttachments,haveAttachments); |
|
1301 |
|
1302 privateMessage->_modified = true; |
|
1303 } |
|
1304 |
|
1305 bool ModestEngine::addMessage(QMessage &message) |
|
1306 { |
|
1307 QString modestFolder; |
|
1308 ModestStringMap senderInfo; |
|
1309 ModestStringMap recipients; |
|
1310 ModestStringMap messageData; |
|
1311 ModestStringMapList attachments; |
|
1312 ModestStringMapList images; |
|
1313 uint priority = 0; |
|
1314 ModestStringMap headers; |
|
1315 |
|
1316 qDebug() << __PRETTY_FUNCTION__; |
|
1317 |
|
1318 senderInfo = getModestSenderInfo (message); |
|
1319 recipients = getModestRecipients (message); |
|
1320 messageData = getModestMessageData (message); |
|
1321 attachments = getModestAttachments (message); |
|
1322 images = getModestImages (message); |
|
1323 priority = getModestPriority (message); |
|
1324 headers = getModestHeaders (message); |
|
1325 |
|
1326 QString accountName; |
|
1327 if (message.parentFolderId().isValid()) { |
|
1328 modestFolder = modestFolderIdFromFolderId (message.parentFolderId()); |
|
1329 accountName = modestAccountIdFromFolderId(message.parentFolderId()); |
|
1330 } else { |
|
1331 modestFolder = modestFolderIdFromStandardFolder(message.standardFolder()); |
|
1332 if (message.standardFolder() == QMessage::DraftsFolder) { |
|
1333 accountName = "local_folders"; |
|
1334 } else { |
|
1335 accountName = modestAccountIdFromAccountId(message.parentAccountId()); |
|
1336 } |
|
1337 } |
|
1338 senderInfo["account-name"] = accountName; |
|
1339 |
|
1340 QDBusPendingCall pendingCall = m_QtmPluginDBusInterface->asyncCall ( |
|
1341 "AddMessage", |
|
1342 QVariant::fromValue (modestFolder), |
|
1343 QVariant::fromValue (senderInfo), |
|
1344 QVariant::fromValue (recipients), |
|
1345 QVariant::fromValue (messageData), |
|
1346 QVariant::fromValue (attachments), |
|
1347 QVariant::fromValue (images), |
|
1348 priority, |
|
1349 QVariant::fromValue (headers)); |
|
1350 |
|
1351 if (pendingCall.isError()) { |
|
1352 qWarning() << "DBus call failed! " << pendingCall.error(); |
|
1353 return false; |
|
1354 } |
|
1355 |
|
1356 QDBusPendingCallWatcher pendingCallWatcher(pendingCall); |
|
1357 pendingCallWatcher.waitForFinished(); |
|
1358 QDBusMessage msg = pendingCallWatcher.reply(); |
|
1359 if (msg.type() == QDBusMessage::ErrorMessage) { |
|
1360 qWarning() << "Failed to add message via modest: " << msg.errorMessage(); |
|
1361 return false; |
|
1362 } |
|
1363 |
|
1364 QMessagePrivate* privateMessage = QMessagePrivate::implementation(message); |
|
1365 QString messageId; |
|
1366 if (message.parentFolderId().isValid()) { |
|
1367 messageId = message.parentFolderId().toString()+"/"+msg.arguments()[0].toString(); |
|
1368 } else if (accountName == "local_folders") { |
|
1369 messageId = message.parentAccountId().toString()+ |
|
1370 "&maildir&"+modestFolder+"/"+msg.arguments()[0].toString(); |
|
1371 } else { |
|
1372 messageId = message.parentAccountId().toString()+"&"+ |
|
1373 accountEmailProtocolAsString(message.parentAccountId())+ |
|
1374 "&"+modestFolder+"/"+msg.arguments()[0].toString(); |
|
1375 } |
|
1376 privateMessage->_id = QMessageId(messageId); |
|
1377 |
|
1378 return true; |
|
1379 } |
|
1380 |
|
1381 bool ModestEngine::updateMessage(QMessage &message) |
|
1382 { |
|
1383 Q_UNUSED(message) // TODO: |
|
1384 |
|
1385 return false; |
|
1386 } |
|
1387 |
|
1388 bool ModestEngine::removeMessage(const QMessageId &id, QMessageManager::RemovalOption option) |
|
1389 { |
|
1390 Q_UNUSED(option) // TODO: |
|
1391 |
|
1392 QMessage msg = message(id, false); |
|
1393 QMessagePrivate* privateMessage = QMessagePrivate::implementation(msg); |
|
1394 if (privateMessage->_url.isEmpty()) { |
|
1395 return false; |
|
1396 } else { |
|
1397 m_ModestDBusInterface->call(MODEST_DBUS_METHOD_DELETE_MESSAGE, |
|
1398 privateMessage->_url); |
|
1399 // Make sure that there will instant notification about removed message |
|
1400 notification(id, ModestEngine::Removed); |
|
1401 } |
|
1402 return true; |
|
1403 } |
|
1404 |
|
1405 bool ModestEngine::filterMessage(const QMessage& message, QMessageFilterPrivate::SortedMessageFilterList filterList, int start) const |
|
1406 { |
|
1407 if (filterList.count() > start) { |
|
1408 for (int j=start; j < filterList.count(); j++) { |
|
1409 QMessageFilterPrivate* pf = QMessageFilterPrivate::implementation(filterList[j]); |
|
1410 if (!pf->filter(message)) { |
|
1411 return false; |
|
1412 } |
|
1413 } |
|
1414 } |
|
1415 return true; |
|
1416 } |
|
1417 |
|
1418 QMessageIdList ModestEngine::queryMessagesSync(const QMessageFilter &filter, const QMessageSortOrder &sortOrder, |
|
1419 uint limit, uint offset, bool &isFiltered, bool &isSorted) const |
|
1420 { |
|
1421 QMessageIdList ids; |
|
1422 |
|
1423 QMessageServicePrivate* privateService = QMessageServicePrivate::implementation(m_service); |
|
1424 if (privateService->queryMessages(m_service, filter, sortOrder, limit, offset, |
|
1425 QMessageServicePrivate::EnginesToCallModest)) { |
|
1426 QObject::connect(&m_service, SIGNAL(stateChanged(QMessageService::State)), |
|
1427 this, SLOT(stateChanged(QMessageService::State))); |
|
1428 |
|
1429 m_eventLoop.exec(); |
|
1430 |
|
1431 isSorted = m_isSorted; |
|
1432 isFiltered = m_isFiltered; |
|
1433 ids = m_ids; |
|
1434 m_ids.clear(); |
|
1435 } |
|
1436 |
|
1437 return ids; |
|
1438 } |
|
1439 |
|
1440 QMessageIdList ModestEngine::queryMessagesSync(const QMessageFilter &filter, const QString &body, |
|
1441 QMessageDataComparator::MatchFlags matchFlags, |
|
1442 const QMessageSortOrder &sortOrder, uint limit, uint offset, |
|
1443 bool &isFiltered, bool &isSorted) const |
|
1444 { |
|
1445 QMessageIdList ids; |
|
1446 |
|
1447 QMessageServicePrivate* privateService = QMessageServicePrivate::implementation(m_service); |
|
1448 if (privateService->queryMessages(m_service, filter, body, matchFlags, |
|
1449 sortOrder, limit, offset, |
|
1450 QMessageServicePrivate::EnginesToCallModest)) { |
|
1451 QObject::connect(&m_service, SIGNAL(stateChanged(QMessageService::State)), |
|
1452 this, SLOT(stateChanged(QMessageService::State))); |
|
1453 |
|
1454 m_eventLoop.exec(); |
|
1455 |
|
1456 isSorted = m_isSorted; |
|
1457 isFiltered = m_isFiltered; |
|
1458 ids = m_ids; |
|
1459 m_ids.clear(); |
|
1460 } |
|
1461 |
|
1462 return ids; |
|
1463 } |
|
1464 |
|
1465 int ModestEngine::countMessagesSync(const QMessageFilter &filter) const |
|
1466 { |
|
1467 int count; |
|
1468 |
|
1469 QMessageServicePrivate* privateService = QMessageServicePrivate::implementation(m_service); |
|
1470 if (privateService->countMessages(m_service, filter, QMessageServicePrivate::EnginesToCallModest)) { |
|
1471 QObject::connect(&m_service, SIGNAL(stateChanged(QMessageService::State)), |
|
1472 this, SLOT(stateChanged(QMessageService::State))); |
|
1473 |
|
1474 m_eventLoop.exec(); |
|
1475 |
|
1476 count = m_count; |
|
1477 } |
|
1478 |
|
1479 return count; |
|
1480 } |
|
1481 |
|
1482 void ModestEngine::stateChanged(QMessageService::State newState) |
|
1483 { |
|
1484 if (newState == QMessageService::FinishedState) { |
|
1485 QMessageServicePrivate* privateService = QMessageServicePrivate::implementation(m_service); |
|
1486 |
|
1487 m_ids = privateService->_ids; |
|
1488 m_isSorted = privateService->_sorted; |
|
1489 m_isFiltered = privateService->_filtered; |
|
1490 m_count = privateService->_count; |
|
1491 |
|
1492 m_eventLoop.quit(); |
|
1493 } |
|
1494 } |
|
1495 |
277 bool ModestEngine::queryMessages(QMessageService& messageService, const QMessageFilter &filter, const QMessageSortOrder &sortOrder, uint limit, uint offset) const |
1496 bool ModestEngine::queryMessages(QMessageService& messageService, const QMessageFilter &filter, const QMessageSortOrder &sortOrder, uint limit, uint offset) const |
278 { |
1497 { |
|
1498 return queryMessages(messageService, filter, QString(), 0, sortOrder, limit, offset); |
|
1499 } |
|
1500 |
|
1501 bool ModestEngine::countMessages(QMessageService& messageService, const QMessageFilter &filter) |
|
1502 { |
|
1503 m_pendingMessageQueries.append(MessageQueryInfo()); |
|
1504 |
|
1505 MessageQueryInfo &queryInfo = m_pendingMessageQueries[m_pendingMessageQueries.count()-1]; |
|
1506 |
|
1507 queryInfo.filter = filter; |
|
1508 queryInfo.limit = 0; |
|
1509 queryInfo.offset = 0; |
|
1510 queryInfo.privateService = QMessageServicePrivate::implementation(messageService); |
|
1511 queryInfo.currentFilterListIndex = 0; |
|
1512 queryInfo.handledFiltersCount = 0; |
|
1513 queryInfo.isQuery = false; |
|
1514 queryInfo.returnWithSingleShot = false; |
|
1515 |
|
1516 if (!startQueryingAndFilteringMessages(m_pendingMessageQueries[m_pendingMessageQueries.count()-1])) { |
|
1517 QMessageServicePrivate::implementation(messageService)->setFinished(false); |
|
1518 m_pendingMessageQueries.removeAt(m_pendingMessageQueries.count()-1); |
|
1519 return false; |
|
1520 } |
|
1521 |
279 return true; |
1522 return true; |
280 } |
1523 } |
281 |
1524 |
282 bool ModestEngine::queryMessages(QMessageService& messageService, const QMessageFilter &filter, const QString &body, QMessageDataComparator::MatchFlags matchFlags, const QMessageSortOrder &sortOrder, uint limit, uint offset) const |
1525 bool ModestEngine::queryMessages(QMessageService& messageService, const QMessageFilter &filter, const QString &body, |
283 { |
1526 QMessageDataComparator::MatchFlags matchFlags, const QMessageSortOrder &sortOrder, |
|
1527 uint limit, uint offset) const |
|
1528 { |
|
1529 m_pendingMessageQueries.append(MessageQueryInfo()); |
|
1530 |
|
1531 MessageQueryInfo &queryInfo = m_pendingMessageQueries[m_pendingMessageQueries.count()-1]; |
|
1532 |
|
1533 queryInfo.body = body; |
|
1534 queryInfo.matchFlags = matchFlags; |
|
1535 queryInfo.filter = filter; |
|
1536 queryInfo.sortOrder = sortOrder; |
|
1537 queryInfo.limit = limit; |
|
1538 queryInfo.offset = offset; |
|
1539 queryInfo.privateService = QMessageServicePrivate::implementation(messageService); |
|
1540 queryInfo.currentFilterListIndex = 0; |
|
1541 queryInfo.handledFiltersCount = 0; |
|
1542 queryInfo.isQuery = true; |
|
1543 queryInfo.returnWithSingleShot = false; |
|
1544 |
|
1545 if (!startQueryingAndFilteringMessages(m_pendingMessageQueries[m_pendingMessageQueries.count()-1])) { |
|
1546 QMessageServicePrivate::implementation(messageService)->setFinished(false); |
|
1547 m_pendingMessageQueries.removeAt(m_pendingMessageQueries.count()-1); |
|
1548 return false; |
|
1549 } |
|
1550 |
284 return true; |
1551 return true; |
285 } |
1552 } |
286 |
1553 |
287 bool ModestEngine::countMessages(QMessageService& messageService, const QMessageFilter &filter) |
1554 bool ModestEngine::startQueryingAndFilteringMessages(MessageQueryInfo &msgQueryInfo) const |
288 { |
1555 { |
|
1556 QMessageFilterPrivate* pf = QMessageFilterPrivate::implementation(msgQueryInfo.filter); |
|
1557 if (pf->_filterList.count() == 0) { |
|
1558 if ((pf->_field == QMessageFilterPrivate::None) && |
|
1559 (pf->_filterList.count() == 0) && |
|
1560 (pf->_notFilter)) { |
|
1561 // There is only one filter: empty ~QMessageFilter() |
|
1562 // => return empty QMessageIdList |
|
1563 msgQueryInfo.ids.clear(); |
|
1564 msgQueryInfo.returnWithSingleShot = true; |
|
1565 QTimer::singleShot(0, (ModestEngine*)this, SLOT(returnQueryResultsSlot())); |
|
1566 return true; |
|
1567 } else { |
|
1568 // One single filter to be handled |
|
1569 QMessageFilter newFilter; |
|
1570 QMessageFilterPrivate* pfNew = QMessageFilterPrivate::implementation(newFilter); |
|
1571 pfNew->_filterList.append(QMessageFilterPrivate::SortedMessageFilterList()); |
|
1572 pfNew->_filterList[0] << msgQueryInfo.filter; |
|
1573 msgQueryInfo.filter = newFilter; |
|
1574 } |
|
1575 } |
|
1576 |
|
1577 return queryAndFilterMessages(msgQueryInfo); |
|
1578 } |
|
1579 |
|
1580 void ModestEngine::returnQueryResultsSlot() |
|
1581 { |
|
1582 for (int i=m_pendingMessageQueries.count()-1; i >= 0; i--) { |
|
1583 if (m_pendingMessageQueries[i].returnWithSingleShot) { |
|
1584 if (m_pendingMessageQueries[i].isQuery) { |
|
1585 m_pendingMessageQueries[i].privateService->messagesFound(m_pendingMessageQueries[i].ids, true, true); |
|
1586 } else { |
|
1587 m_pendingMessageQueries[i].privateService->messagesCounted(m_pendingMessageQueries[i].ids.count()); |
|
1588 } |
|
1589 m_pendingMessageQueries.removeAt(i); |
|
1590 } |
|
1591 } |
|
1592 } |
|
1593 |
|
1594 bool ModestEngine::queryAndFilterMessages(MessageQueryInfo &msgQueryInfo) const |
|
1595 { |
|
1596 QStringList accountIds; |
|
1597 QStringList folderUris; |
|
1598 QDateTime startTimeStamp; |
|
1599 QDateTime endTimeStamp; |
|
1600 QDateTime startReceptionTimeStamp; |
|
1601 QDateTime endReceptionTimeStamp; |
|
1602 |
|
1603 QMessageFilterPrivate* pf = QMessageFilterPrivate::implementation(msgQueryInfo.filter); |
|
1604 |
|
1605 // Filters have been sorted into matrix of filters: |
|
1606 // - there is AND operation between every filter in one row |
|
1607 // - there is OR operation between every row |
|
1608 // => Every row can be handled individually |
|
1609 // => Final result set can be created by combining result sets |
|
1610 // from individual row based queries |
|
1611 QMessageFilterPrivate::SortedMessageFilterList filters = pf->_filterList[msgQueryInfo.currentFilterListIndex]; |
|
1612 |
|
1613 msgQueryInfo.realAccountId = QString(); |
|
1614 |
|
1615 int handledFiltersCount = 0; |
|
1616 pf = QMessageFilterPrivate::implementation(filters[handledFiltersCount]); |
|
1617 if ((filters.count() == 1) && |
|
1618 (pf->_field == QMessageFilterPrivate::None) && |
|
1619 (pf->_filterList.count() == 0)) { |
|
1620 if (pf->_notFilter) { |
|
1621 // There is only one filter: empty ~QMessageFilter() |
|
1622 // => this query results empty QMessageIdList |
|
1623 // => Skip to next query round |
|
1624 int index = -1; |
|
1625 for (int i=0; i < m_pendingMessageQueries.count(); i++) { |
|
1626 if (m_pendingMessageQueries[i].queryId == msgQueryInfo.queryId) { |
|
1627 index = i; |
|
1628 break; |
|
1629 } |
|
1630 } |
|
1631 if (index >= 0) { |
|
1632 handleQueryFinished(index); |
|
1633 } |
|
1634 return true; |
|
1635 } else { |
|
1636 // There is only one filter: empty QMessageFilter() |
|
1637 // => return all messages |
|
1638 handledFiltersCount++; |
|
1639 } |
|
1640 } |
|
1641 |
|
1642 bool handled = true; |
|
1643 while (handledFiltersCount < filters.count() && handled) { |
|
1644 handled = false; |
|
1645 pf = QMessageFilterPrivate::implementation(filters[handledFiltersCount]); |
|
1646 switch (pf->_field) { |
|
1647 case QMessageFilterPrivate::Id: |
|
1648 break; |
|
1649 case QMessageFilterPrivate::ParentAccountId: |
|
1650 { |
|
1651 if (pf->_comparatorType == QMessageFilterPrivate::Equality) { |
|
1652 if (accountIds.count()) { |
|
1653 // Only one account/one query can be used |
|
1654 break; |
|
1655 } |
|
1656 QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue)); |
|
1657 if (cmp == QMessageDataComparator::Equal) { |
|
1658 if (pf->_value.toString().length() > 0) { |
|
1659 accountIds.append(modestAccountIdFromAccountId(pf->_value.toString())); |
|
1660 msgQueryInfo.realAccountId = pf->_value.toString(); |
|
1661 handled = true; |
|
1662 } |
|
1663 } |
|
1664 } |
|
1665 break; |
|
1666 } |
|
1667 case QMessageFilterPrivate::ParentFolderId: |
|
1668 { |
|
1669 if (pf->_comparatorType == QMessageFilterPrivate::Equality) { |
|
1670 QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue)); |
|
1671 if (cmp == QMessageDataComparator::Equal) { |
|
1672 if (pf->_value.toString().length() > 0) { |
|
1673 folderUris.append(modestFolderIdFromFolderId(pf->_value.toString())); |
|
1674 if (accountIds.count() == 0) { |
|
1675 accountIds.append(modestAccountIdFromFolderId(pf->_value.toString())); |
|
1676 |
|
1677 // Note: Even though local folders belong to "local_folders" account |
|
1678 // inside Modest, local folders can belong to any "real" |
|
1679 // POP3 or IMAP account in Qt Mobility Messaging side |
|
1680 // <=> Qt Mobility Messaging does not have "Local Folders" |
|
1681 // account |
|
1682 // If folder is local folder, "local_folders" accountId will be |
|
1683 // added to accountIds list to enable correct filtering inside |
|
1684 // Modest Plugin |
|
1685 accountIds.append("local_folders"); |
|
1686 |
|
1687 // realAccountId will contain id of Qt Mobility Messaging account |
|
1688 // (AccountId can be found from the beginning of folderId string) |
|
1689 // <=> realAccountId will not ever be "local_folders" |
|
1690 msgQueryInfo.realAccountId = accountIdFromFolderId(pf->_value.toString()).toString(); |
|
1691 } |
|
1692 handled = true; |
|
1693 } |
|
1694 } |
|
1695 } |
|
1696 break; |
|
1697 } |
|
1698 case QMessageFilterPrivate::AncestorFolderIds: |
|
1699 break; |
|
1700 case QMessageFilterPrivate::Type: |
|
1701 break; |
|
1702 case QMessageFilterPrivate::StandardFolder: |
|
1703 if (pf->_comparatorType == QMessageFilterPrivate::Equality) { |
|
1704 QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue)); |
|
1705 if (cmp == QMessageDataComparator::Equal) { |
|
1706 QMessage::StandardFolder standardFolder = static_cast<QMessage::StandardFolder>(pf->_value.toInt()); |
|
1707 if (standardFolder == QMessage::SentFolder) { |
|
1708 folderUris.append("sent"); |
|
1709 if (accountIds.count() == 0) { |
|
1710 accountIds.append("local_folders"); |
|
1711 } |
|
1712 } |
|
1713 handled = true; |
|
1714 } |
|
1715 } |
|
1716 break; |
|
1717 case QMessageFilterPrivate::ParentAccountIdFilter: |
|
1718 break; |
|
1719 case QMessageFilterPrivate::ParentFolderIdFilter: |
|
1720 break; |
|
1721 case QMessageFilterPrivate::TimeStamp: |
|
1722 { |
|
1723 if (pf->_comparatorType == QMessageFilterPrivate::Equality) { |
|
1724 QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue)); |
|
1725 if (cmp == QMessageDataComparator::Equal) { |
|
1726 endTimeStamp = pf->_value.toDateTime(); |
|
1727 startTimeStamp = pf->_value.toDateTime(); |
|
1728 handled = true; |
|
1729 } |
|
1730 } |
|
1731 if (pf->_comparatorType == QMessageFilterPrivate::Relation) { |
|
1732 QMessageDataComparator::RelationComparator cmp(static_cast<QMessageDataComparator::RelationComparator>(pf->_comparatorValue)); |
|
1733 if (cmp == QMessageDataComparator::LessThan) { |
|
1734 endTimeStamp = pf->_value.toDateTime(); |
|
1735 handled = true; |
|
1736 } else if (cmp == QMessageDataComparator::LessThanEqual) { |
|
1737 endTimeStamp = pf->_value.toDateTime(); |
|
1738 handled = true; |
|
1739 } else if (cmp == QMessageDataComparator::GreaterThan) { |
|
1740 startTimeStamp = pf->_value.toDateTime(); |
|
1741 handled = true; |
|
1742 } if (cmp == QMessageDataComparator::GreaterThanEqual) { |
|
1743 startTimeStamp = pf->_value.toDateTime(); |
|
1744 handled = true; |
|
1745 } |
|
1746 } |
|
1747 break; |
|
1748 } |
|
1749 case QMessageFilterPrivate::ReceptionTimeStamp: |
|
1750 { |
|
1751 if (pf->_comparatorType == QMessageFilterPrivate::Equality) { |
|
1752 QMessageDataComparator::EqualityComparator cmp(static_cast<QMessageDataComparator::EqualityComparator>(pf->_comparatorValue)); |
|
1753 if (cmp == QMessageDataComparator::Equal) { |
|
1754 endReceptionTimeStamp = pf->_value.toDateTime(); |
|
1755 startReceptionTimeStamp = pf->_value.toDateTime(); |
|
1756 handled = true; |
|
1757 } |
|
1758 } |
|
1759 if (pf->_comparatorType == QMessageFilterPrivate::Relation) { |
|
1760 QMessageDataComparator::RelationComparator cmp(static_cast<QMessageDataComparator::RelationComparator>(pf->_comparatorValue)); |
|
1761 if (cmp == QMessageDataComparator::LessThan) { |
|
1762 endReceptionTimeStamp = pf->_value.toDateTime(); |
|
1763 handled = true; |
|
1764 } else if (cmp == QMessageDataComparator::LessThanEqual) { |
|
1765 endReceptionTimeStamp = pf->_value.toDateTime(); |
|
1766 handled = true; |
|
1767 } else if (cmp == QMessageDataComparator::GreaterThan) { |
|
1768 startReceptionTimeStamp = pf->_value.toDateTime(); |
|
1769 handled = true; |
|
1770 } if (cmp == QMessageDataComparator::GreaterThanEqual) { |
|
1771 startReceptionTimeStamp = pf->_value.toDateTime(); |
|
1772 handled = true; |
|
1773 } |
|
1774 } |
|
1775 break; |
|
1776 } |
|
1777 case QMessageFilterPrivate::Sender: |
|
1778 break; |
|
1779 case QMessageFilterPrivate::Recipients: |
|
1780 break; |
|
1781 case QMessageFilterPrivate::Subject: |
|
1782 break; |
|
1783 case QMessageFilterPrivate::Status: |
|
1784 break; |
|
1785 case QMessageFilterPrivate::Priority: |
|
1786 break; |
|
1787 case QMessageFilterPrivate::Size: |
|
1788 break; |
|
1789 case QMessageFilterPrivate::None: |
|
1790 break; |
|
1791 } |
|
1792 handledFiltersCount++; |
|
1793 } |
|
1794 |
|
1795 msgQueryInfo.handledFiltersCount = 0; // Do filtering also for filters which has been handled above |
|
1796 |
|
1797 return searchMessages(msgQueryInfo, accountIds, folderUris, msgQueryInfo.body, startTimeStamp, |
|
1798 endTimeStamp, startReceptionTimeStamp, endReceptionTimeStamp); |
|
1799 } |
|
1800 |
|
1801 bool ModestEngine::searchMessages(MessageQueryInfo &msgQueryInfo, const QStringList& accountIds, |
|
1802 const QStringList& folderUris, const QString& body, |
|
1803 const QDateTime& startTimeStamp, const QDateTime& endTimeStamp, |
|
1804 const QDateTime& startReceptionTimeStamp, const QDateTime& endReceptionTimeStamp) const |
|
1805 { |
|
1806 Q_UNUSED(body) //TODO: Body search |
|
1807 |
|
1808 qulonglong sDate = 0; |
|
1809 if (startTimeStamp.isValid() && startReceptionTimeStamp.isValid()) { |
|
1810 if (startTimeStamp < startReceptionTimeStamp) { |
|
1811 sDate = startTimeStamp.toTime_t(); |
|
1812 } else { |
|
1813 sDate = startReceptionTimeStamp.toTime_t(); |
|
1814 } |
|
1815 } else { |
|
1816 if (startTimeStamp.isValid()) { |
|
1817 sDate = startTimeStamp.toTime_t(); |
|
1818 } else if (startReceptionTimeStamp.isValid()) { |
|
1819 sDate = startReceptionTimeStamp.toTime_t(); |
|
1820 } |
|
1821 } |
|
1822 |
|
1823 |
|
1824 qulonglong eDate = 0; |
|
1825 if (endTimeStamp.isValid() && endReceptionTimeStamp.isValid()) { |
|
1826 if (endTimeStamp > endReceptionTimeStamp) { |
|
1827 eDate = endTimeStamp.toTime_t(); |
|
1828 } else { |
|
1829 eDate = endReceptionTimeStamp.toTime_t(); |
|
1830 } |
|
1831 } else { |
|
1832 if (endTimeStamp.isValid()) { |
|
1833 eDate = endTimeStamp.toTime_t(); |
|
1834 } else if (endReceptionTimeStamp.isValid()) { |
|
1835 eDate = endReceptionTimeStamp.toTime_t(); |
|
1836 } |
|
1837 } |
|
1838 |
|
1839 if (m_pendingMessageQueries.count() == 1) { |
|
1840 // This is the first query in pending queries queue |
|
1841 // => connect to signals |
|
1842 m_QtmPluginDBusInterface->connection().connect(MODESTENGINE_QTM_PLUGIN_NAME, |
|
1843 MODESTENGINE_QTM_PLUGIN_PATH, |
|
1844 MODESTENGINE_QTM_PLUGIN_NAME, |
|
1845 "HeadersReceived", |
|
1846 (ModestEngine*)this, |
|
1847 SLOT(searchMessagesHeadersReceivedSlot(QDBusMessage))); |
|
1848 |
|
1849 m_QtmPluginDBusInterface->connection().connect(MODESTENGINE_QTM_PLUGIN_NAME, |
|
1850 MODESTENGINE_QTM_PLUGIN_PATH, |
|
1851 MODESTENGINE_QTM_PLUGIN_NAME, |
|
1852 "HeadersFetched", |
|
1853 (ModestEngine*)this, |
|
1854 SLOT(searchMessagesHeadersFetchedSlot(QDBusMessage))); |
|
1855 } |
|
1856 |
|
1857 QDBusMessage reply = m_QtmPluginDBusInterface->call("GetHeaders", |
|
1858 accountIds, |
|
1859 folderUris, |
|
1860 sDate, |
|
1861 eDate, |
|
1862 false); |
|
1863 if (reply.type() != QDBusMessage::ErrorMessage) { |
|
1864 m_messageCache.clear(); |
|
1865 msgQueryInfo.queryId = reply.arguments().takeFirst().toInt(); |
|
1866 } else { |
|
1867 // Request failed |
|
1868 int index = -1; |
|
1869 for (int i=0; i < m_pendingMessageQueries.count(); i++) { |
|
1870 if (m_pendingMessageQueries[i].queryId == msgQueryInfo.queryId) { |
|
1871 index = i; |
|
1872 break; |
|
1873 } |
|
1874 } |
|
1875 if (index > -1) { |
|
1876 m_pendingMessageQueries.removeAt(index); |
|
1877 } |
|
1878 msgQueryInfo.privateService->setFinished(false); |
|
1879 |
|
1880 if (m_pendingMessageQueries.count() == 0) { |
|
1881 // This was last query in pending queries queue |
|
1882 // => Disconnect from "GetHeaders" request related DBus signals |
|
1883 // Note: Disconnecting signals is done to optimize signal handling |
|
1884 // <=> Disconnecting prevents unnecessary handling of signals |
|
1885 // which have been sent from other applications using |
|
1886 // Qt Mobility Messaging API |
|
1887 m_QtmPluginDBusInterface->connection().disconnect(MODESTENGINE_QTM_PLUGIN_NAME, |
|
1888 MODESTENGINE_QTM_PLUGIN_PATH, |
|
1889 MODESTENGINE_QTM_PLUGIN_NAME, |
|
1890 "HeadersReceived", |
|
1891 (ModestEngine*)this, |
|
1892 SLOT(searchMessagesHeadersReceivedSlot(QDBusMessage))); |
|
1893 |
|
1894 m_QtmPluginDBusInterface->connection().disconnect(MODESTENGINE_QTM_PLUGIN_NAME, |
|
1895 MODESTENGINE_QTM_PLUGIN_PATH, |
|
1896 MODESTENGINE_QTM_PLUGIN_NAME, |
|
1897 "HeadersFetched", |
|
1898 (ModestEngine*)this, |
|
1899 SLOT(searchMessagesHeadersFetchedSlot(QDBusMessage))); |
|
1900 } |
|
1901 return false; |
|
1902 } |
|
1903 |
289 return true; |
1904 return true; |
290 } |
1905 } |
291 |
1906 |
|
1907 void ModestEngine::searchMessagesHeadersReceivedSlot(QDBusMessage msg) |
|
1908 { |
|
1909 QList<QVariant> arguments = msg.arguments(); |
|
1910 int queryId = arguments.takeFirst().toInt(); |
|
1911 |
|
1912 int index = -1; |
|
1913 for (int i=0; i < m_pendingMessageQueries.count(); i++) { |
|
1914 if (m_pendingMessageQueries[i].queryId == queryId) { |
|
1915 index = i; |
|
1916 break; |
|
1917 } |
|
1918 } |
|
1919 if (index == -1) { |
|
1920 // Received DBus Message is not reply for the DBus query |
|
1921 // that was sent from this process/instance of modest engine |
|
1922 // => Continue waiting |
|
1923 return; |
|
1924 } |
|
1925 |
|
1926 MessageQueryInfo &queryInfo = m_pendingMessageQueries[index]; |
|
1927 |
|
1928 QString reportedAccountId = arguments.takeFirst().toString(); |
|
1929 QString accountId; |
|
1930 if (!queryInfo.realAccountId.isEmpty()) { |
|
1931 // Search was done to Modest "local_folders" account |
|
1932 // => Correct Qt Mobility Messaging AccountId |
|
1933 // can be taken realAccountId field |
|
1934 // => Transform Messaging AccountId to Modest accountId |
|
1935 // by removing "MO_" from the beginning of accountId string |
|
1936 accountId = queryInfo.realAccountId; |
|
1937 accountId.remove(0,3); |
|
1938 } else { |
|
1939 accountId = reportedAccountId.remove("_store"); |
|
1940 } |
|
1941 |
|
1942 QString folderId = arguments.takeFirst().toString(); |
|
1943 QVariant variant = arguments.takeFirst(); |
|
1944 QDBusArgument argument = variant.value<QDBusArgument>(); |
|
1945 QList<QMap<QString, QVariant> > messages; |
|
1946 argument >> messages; |
|
1947 |
|
1948 QMessageFilterPrivate::SortedMessageFilterList filters; |
|
1949 int firstUnhandledFilterIndex = 0; |
|
1950 |
|
1951 QMessageFilterPrivate* pf = QMessageFilterPrivate::implementation(queryInfo.filter); |
|
1952 if (pf->_filterList.count() == 0) { |
|
1953 filters.append(queryInfo.filter); |
|
1954 } else { |
|
1955 if (queryInfo.handledFiltersCount < pf->_filterList[queryInfo.currentFilterListIndex].count()) { |
|
1956 filters = pf->_filterList[queryInfo.currentFilterListIndex]; |
|
1957 } |
|
1958 } |
|
1959 firstUnhandledFilterIndex = queryInfo.handledFiltersCount; |
|
1960 |
|
1961 for (int i=0; i < messages.count(); i++) { |
|
1962 MessagingModestMessage modestMessage; |
|
1963 modestMessage.accountId = accountId; |
|
1964 modestMessage.folderId = folderId; |
|
1965 modestMessage.dateReceived = 0; |
|
1966 modestMessage.dateSent = 0; |
|
1967 modestMessage.size = 0; |
|
1968 modestMessage.flags = MessagingModestMessageNotDefined; |
|
1969 modestMessage.priority = MessagingModestMessagePriorityDefined; |
|
1970 QMapIterator<QString, QVariant> j(messages[i]); |
|
1971 while (j.hasNext()) { |
|
1972 j.next(); |
|
1973 if (j.key() == "url") { |
|
1974 modestMessage.url = j.value().toString(); |
|
1975 } else if (j.key() == "message-uid") { |
|
1976 modestMessage.id = j.value().toString(); |
|
1977 } else if (j.key() == "from") { |
|
1978 modestMessage.from = j.value().toString(); |
|
1979 } else if (j.key() == "to") { |
|
1980 modestMessage.to = j.value().toString(); |
|
1981 } else if (j.key() == "cc") { |
|
1982 modestMessage.cc = j.value().toString(); |
|
1983 } else if (j.key() == "bcc") { |
|
1984 modestMessage.bcc = j.value().toString(); |
|
1985 } else if (j.key() == "replyto") { |
|
1986 modestMessage.replyTo = j.value().toString(); |
|
1987 } else if (j.key() == "subject") { |
|
1988 modestMessage.subject = j.value().toString(); |
|
1989 } else if (j.key() == "date-received") { |
|
1990 modestMessage.dateReceived = j.value().toLongLong(); |
|
1991 } else if (j.key() == "date-sent") { |
|
1992 modestMessage.dateSent = j.value().toLongLong(); |
|
1993 } else if (j.key() == "size") { |
|
1994 modestMessage.size = j.value().toLongLong(); |
|
1995 } else if (j.key() == "flags") { |
|
1996 modestMessage.flags = static_cast<MessagingModestMessageFlags>(j.value().toUInt()); |
|
1997 } else if (j.key() == "priority") { |
|
1998 modestMessage.priority = static_cast<MessagingModestMessagePriority>(j.value().toUInt()); |
|
1999 } |
|
2000 } |
|
2001 |
|
2002 QMessage message = messageFromModestMessage(modestMessage); |
|
2003 if (reportedAccountId == "local_folders") { |
|
2004 QMessagePrivate* privateMessage = QMessagePrivate::implementation(message); |
|
2005 QString id = privateMessage->_id.toString(); |
|
2006 QString newProtocol = "maildir"; |
|
2007 replaceProtocol(id, newProtocol); |
|
2008 privateMessage->_id = QMessageId(id); |
|
2009 id = privateMessage->_parentFolderId.toString(); |
|
2010 replaceProtocol(id, newProtocol); |
|
2011 privateMessage->_parentFolderId = QMessageFolderId(id); |
|
2012 } |
|
2013 if (filterMessage(message, filters, 0)) { |
|
2014 if (!queryInfo.ids.contains(message.id())) { |
|
2015 if (m_messageCache.size() < maxCacheSize) { |
|
2016 m_messageCache.insert(message.id().toString(), message); |
|
2017 } |
|
2018 queryInfo.ids.append(message.id()); |
|
2019 } |
|
2020 } |
|
2021 } |
|
2022 } |
|
2023 |
|
2024 void ModestEngine::searchMessagesHeadersFetchedSlot(QDBusMessage msg) |
|
2025 { |
|
2026 QList<QVariant> arguments = msg.arguments(); |
|
2027 int queryId = arguments.takeFirst().toInt(); |
|
2028 |
|
2029 int index = -1; |
|
2030 for (int i=0; i < m_pendingMessageQueries.count(); i++) { |
|
2031 if (m_pendingMessageQueries[i].queryId == queryId) { |
|
2032 index = i; |
|
2033 break; |
|
2034 } |
|
2035 } |
|
2036 if (index == -1) { |
|
2037 // Received DBus Message is not reply for the DBus query |
|
2038 // that was sent from this process/instance of modest engine |
|
2039 // => Continue waiting |
|
2040 return; |
|
2041 } |
|
2042 |
|
2043 handleQueryFinished(index); |
|
2044 } |
|
2045 |
|
2046 void ModestEngine::handleQueryFinished(int index) const |
|
2047 { |
|
2048 MessageQueryInfo &queryInfo = m_pendingMessageQueries[index]; |
|
2049 |
|
2050 queryInfo.currentFilterListIndex++; |
|
2051 QMessageFilterPrivate* pf = QMessageFilterPrivate::implementation(queryInfo.filter); |
|
2052 if (queryInfo.currentFilterListIndex < pf->_filterList.count()) { |
|
2053 if (queryAndFilterMessages(queryInfo)) { |
|
2054 // Continue searching |
|
2055 return; |
|
2056 } |
|
2057 } |
|
2058 |
|
2059 MessagingHelper::orderMessages(queryInfo.ids, queryInfo.sortOrder); |
|
2060 MessagingHelper::applyOffsetAndLimitToMessageIdList(queryInfo.ids, queryInfo.limit, queryInfo.offset); |
|
2061 |
|
2062 // Search finished |
|
2063 if (queryInfo.isQuery) { |
|
2064 queryInfo.privateService->messagesFound(queryInfo.ids, true, true); |
|
2065 } else { |
|
2066 queryInfo.privateService->messagesCounted(queryInfo.ids.count()); |
|
2067 } |
|
2068 m_pendingMessageQueries.removeAt(index); |
|
2069 |
|
2070 if (m_pendingMessageQueries.count() == 0) { |
|
2071 // This was last query in pending queries queue |
|
2072 // => Disconnect from "GetHeaders" request related DBus signals |
|
2073 // Note: Disconnecting signals is done to optimize signal handling |
|
2074 // <=> Disconnecting prevents unnecessary handling of signals |
|
2075 // which have been sent from other applications using |
|
2076 // Qt Mobility Messaging API |
|
2077 m_QtmPluginDBusInterface->connection().disconnect(MODESTENGINE_QTM_PLUGIN_NAME, |
|
2078 MODESTENGINE_QTM_PLUGIN_PATH, |
|
2079 MODESTENGINE_QTM_PLUGIN_NAME, |
|
2080 "HeadersReceived", |
|
2081 (ModestEngine*)this, |
|
2082 SLOT(searchMessagesHeadersReceivedSlot(QDBusMessage))); |
|
2083 |
|
2084 m_QtmPluginDBusInterface->connection().disconnect(MODESTENGINE_QTM_PLUGIN_NAME, |
|
2085 MODESTENGINE_QTM_PLUGIN_PATH, |
|
2086 MODESTENGINE_QTM_PLUGIN_NAME, |
|
2087 "HeadersFetched", |
|
2088 (ModestEngine*)this, |
|
2089 SLOT(searchMessagesHeadersFetchedSlot(QDBusMessage))); |
|
2090 } |
|
2091 } |
|
2092 |
|
2093 void |
|
2094 ModestEngine::sendEmailCallEnded(QDBusPendingCallWatcher *watcher) |
|
2095 { |
|
2096 if (watcher->isError ()) { |
|
2097 // TODO: Emit a failure |
|
2098 qWarning() << "Failed to send email via modest: " << watcher->error(); |
|
2099 } else { |
|
2100 // TODO: Emit a success (or put to outbox) |
|
2101 qDebug() << "Message should be outboxed now..."; |
|
2102 } |
|
2103 } |
|
2104 |
|
2105 void |
|
2106 ModestEngine::addMessageCallEnded(QDBusPendingCallWatcher *watcher) |
|
2107 { |
|
2108 QDBusPendingReply<QString> reply = *watcher; |
|
2109 if (reply.isError ()) { |
|
2110 // TODO: Emit a failure |
|
2111 qWarning() << "Failed to add message via modest: " << reply.error(); |
|
2112 } else { |
|
2113 QString id = reply.argumentAt<0>(); |
|
2114 // TODO: Emit a success ... with message's id? |
|
2115 qDebug() << "Message with id" << id << "should be added now"; |
|
2116 } |
|
2117 } |
|
2118 |
|
2119 void ModestEngine::folderUpdatedSlot(QDBusMessage msg) |
|
2120 { |
|
2121 QList<QVariant> arguments = msg.arguments(); |
|
2122 QString modestAccountId = arguments.takeFirst().toString(); |
|
2123 QString modestFolderId = arguments.takeFirst().toString(); |
|
2124 QMessageFolderId updatedFolderId; |
|
2125 |
|
2126 if (modestAccountId == "local_folders") { |
|
2127 updatedFolderId = QMessageFolderId("MO_LOCAL&maildir&"+modestFolderId); |
|
2128 } else { |
|
2129 QMessageAccountId accountId = QMessageAccountId("MO_"+escapeString(modestAccountId)); |
|
2130 QString protocol = accountEmailProtocolAsString(accountId); |
|
2131 if ((protocol == "pop") && (modestFolderId == "INBOX")) { |
|
2132 modestFolderId = "cache"; |
|
2133 } |
|
2134 updatedFolderId = QMessageFolderId(accountId.toString()+"&"+protocol+"&"+modestFolderId); |
|
2135 } |
|
2136 |
|
2137 int messagesPerAccount = 5; |
|
2138 QDBusPendingCall pendingCall = m_ModestDBusInterface->asyncCall(MODEST_DBUS_METHOD_GET_UNREAD_MESSAGES, |
|
2139 messagesPerAccount); |
|
2140 QDBusPendingCallWatcher* pendingCallWatcher = new QDBusPendingCallWatcher(pendingCall); |
|
2141 pendingCallWatcher->setProperty("folderId", updatedFolderId.toString()); |
|
2142 connect(pendingCallWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), |
|
2143 this, SLOT(pendingGetUnreadMessagesFinishedSlot(QDBusPendingCallWatcher*))); |
|
2144 } |
|
2145 |
|
2146 void ModestEngine::pendingGetUnreadMessagesFinishedSlot(QDBusPendingCallWatcher* pendingCallWatcher) |
|
2147 { |
|
2148 QDBusMessage msg = pendingCallWatcher->reply(); |
|
2149 QVariant variant = msg.arguments().takeFirst(); |
|
2150 QDBusArgument argument = variant.value<QDBusArgument>(); |
|
2151 QList<ModestAccountsUnreadMessagesDBusStruct> accountsWithUnreadMessages; |
|
2152 argument >> accountsWithUnreadMessages; |
|
2153 |
|
2154 bool setOnlyDates = false; |
|
2155 if (pendingCallWatcher->property("setOnlyDates").isValid()) { |
|
2156 setOnlyDates = true; |
|
2157 } |
|
2158 QMessageFolderId folderId; |
|
2159 if (pendingCallWatcher->property("folderId").isValid()) { |
|
2160 folderId = QMessageFolderId(pendingCallWatcher->property("folderId").toString()); |
|
2161 } |
|
2162 |
|
2163 for (int i=0; i < accountsWithUnreadMessages.count(); i++) { |
|
2164 QDateTime newLatestTimeStamp; |
|
2165 QDateTime latestTimeStamp = accountsLatestTimestamp.take(accountsWithUnreadMessages[i].accountId); |
|
2166 for (int j=0; j < accountsWithUnreadMessages[i].unreadMessages.count(); j++) { |
|
2167 ModestUnreadMessageDBusStruct unreadMessage = accountsWithUnreadMessages[i].unreadMessages[j]; |
|
2168 QDateTime time = QDateTime::fromTime_t(unreadMessage.timeStamp); |
|
2169 if (time > newLatestTimeStamp) { |
|
2170 newLatestTimeStamp = time; |
|
2171 } |
|
2172 if (!setOnlyDates) { |
|
2173 if (time > latestTimeStamp) { |
|
2174 searchNewMessages(unreadMessage.subject, QString(), time, time, MODEST_DBUS_SEARCH_SUBJECT, 0); |
|
2175 } |
|
2176 } |
|
2177 } |
|
2178 if (newLatestTimeStamp.isValid()) { |
|
2179 accountsLatestTimestamp.remove(accountsWithUnreadMessages[i].accountId); |
|
2180 accountsLatestTimestamp.insert(accountsWithUnreadMessages[i].accountId, newLatestTimeStamp); |
|
2181 } else { |
|
2182 accountsLatestTimestamp.insert(accountsWithUnreadMessages[i].accountId, QDateTime::currentDateTime()); |
|
2183 } |
|
2184 } |
|
2185 } |
|
2186 |
|
2187 void ModestEngine::searchNewMessages(const QString& searchString, const QString& folderToSearch, |
|
2188 const QDateTime& startDate, const QDateTime& endDate, |
|
2189 int searchflags, uint minimumMessageSize) const |
|
2190 { |
|
2191 qlonglong sDate = 0; |
|
2192 if (startDate.isValid()) { |
|
2193 sDate = startDate.toTime_t(); |
|
2194 } |
|
2195 qlonglong eDate = 0; |
|
2196 if (endDate.isValid()) { |
|
2197 eDate = endDate.toTime_t(); |
|
2198 } |
|
2199 |
|
2200 QDBusInterface interface(MODEST_DBUS_SERVICE, MODEST_DBUS_OBJECT, MODEST_DBUS_IFACE); |
|
2201 QDBusPendingCall pendingCall = interface.asyncCall(MODEST_DBUS_METHOD_SEARCH, |
|
2202 searchString, |
|
2203 folderToSearch, |
|
2204 sDate, |
|
2205 eDate, |
|
2206 searchflags, |
|
2207 minimumMessageSize); |
|
2208 QDBusPendingCallWatcher* pendingCallWatcher = new QDBusPendingCallWatcher(pendingCall); |
|
2209 connect(pendingCallWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), |
|
2210 this, SLOT(pendingSearchFinishedSlot(QDBusPendingCallWatcher*))); |
|
2211 } |
|
2212 |
|
2213 void ModestEngine::pendingSearchFinishedSlot(QDBusPendingCallWatcher* pendingCallWatcher) |
|
2214 { |
|
2215 QDBusMessage msg = pendingCallWatcher->reply(); |
|
2216 QVariant variant = msg.arguments().takeFirst(); |
|
2217 QDBusArgument argument = variant.value<QDBusArgument>(); |
|
2218 QList<ModestMessage> messages; |
|
2219 argument >> messages; |
|
2220 |
|
2221 for (int i=0; i < messages.count(); i++) { |
|
2222 notification(messageIdFromModestMessageId(messages[i].id), ModestEngine::Added); |
|
2223 } |
|
2224 } |
|
2225 |
|
2226 void ModestEngine::messageReadChangedSlot(QDBusMessage msg) |
|
2227 { |
|
2228 QString changedMessageId = msg.arguments().takeFirst().toString(); |
|
2229 notification(messageIdFromModestMessageId(changedMessageId), ModestEngine::Updated); |
|
2230 } |
|
2231 |
|
2232 QMessageManager::NotificationFilterId ModestEngine::registerNotificationFilter(QMessageStorePrivate& messageStore, |
|
2233 const QMessageFilter &filter, |
|
2234 QMessageManager::NotificationFilterId id) |
|
2235 { |
|
2236 m_messageStore = &messageStore; |
|
2237 |
|
2238 int filterId = id; |
|
2239 if (filterId == 0) { |
|
2240 filterId = ++m_filterId; |
|
2241 } |
|
2242 m_filters.insert(filterId, filter); |
|
2243 return filterId; |
|
2244 } |
|
2245 |
|
2246 void ModestEngine::unregisterNotificationFilter(QMessageManager::NotificationFilterId notificationFilterId) |
|
2247 { |
|
2248 m_filters.remove(notificationFilterId); |
|
2249 } |
|
2250 |
|
2251 QByteArray ModestEngine::getMimePart (const QMessageId &id, const QString &attachmentId) |
|
2252 { |
|
2253 QByteArray result; |
|
2254 |
|
2255 QString modestAccountId = modestAccountIdFromMessageId(id); |
|
2256 QString modestFolderId = modestFolderIdFromMessageId(id); |
|
2257 QString modestMessageId = modestMessageIdFromMessageId(id); |
|
2258 |
|
2259 QString filePath, mimeType; |
|
2260 int mimeSize = -1; |
|
2261 bool expunge = false, isAttachment = false; |
|
2262 |
|
2263 QDBusPendingReply<QString, QString, int, bool, bool> reply = |
|
2264 m_QtmPluginDBusInterface->asyncCall( |
|
2265 "GetMimePart", |
|
2266 QVariant::fromValue(modestAccountId), |
|
2267 QVariant::fromValue(modestFolderId), |
|
2268 QVariant::fromValue(modestMessageId), |
|
2269 QVariant::fromValue(attachmentId)); |
|
2270 |
|
2271 reply.waitForFinished(); |
|
2272 |
|
2273 if (reply.isError()) { |
|
2274 qWarning () << reply.error(); |
|
2275 return result; |
|
2276 } |
|
2277 |
|
2278 filePath = reply.argumentAt<0>(); |
|
2279 mimeType = reply.argumentAt<1>(); |
|
2280 mimeSize = reply.argumentAt<2>(); |
|
2281 isAttachment = reply.argumentAt<3>(); |
|
2282 expunge = reply.argumentAt<4>(); |
|
2283 |
|
2284 if (filePath.isEmpty()) { |
|
2285 qWarning() << "Received empty file path!"; |
|
2286 return result; |
|
2287 } |
|
2288 |
|
2289 QFile file(filePath); |
|
2290 |
|
2291 if (file.open(QIODevice::ReadWrite) == false) { |
|
2292 qWarning() << "Failed to open file" << filePath << ": " |
|
2293 << file.error(); |
|
2294 return result; |
|
2295 } |
|
2296 |
|
2297 result = file.readAll(); |
|
2298 |
|
2299 if (expunge) { |
|
2300 file.remove(); |
|
2301 } else { |
|
2302 file.close(); |
|
2303 } |
|
2304 |
|
2305 return result; |
|
2306 } |
|
2307 |
|
2308 void ModestEngine::notification(const QMessageId& messageId, NotificationType notificationType) const |
|
2309 { |
|
2310 QMessageId realMessageId = messageId; |
|
2311 |
|
2312 if (notificationType == ModestEngine::Removed) { |
|
2313 // Make sure that there will not be many Removed notifications |
|
2314 // in a row for a same message |
|
2315 QString modestMessageId = modestMessageIdFromMessageId(messageId); |
|
2316 if (!m_latestRemoveNotifications.contains(modestMessageId)) { |
|
2317 if (m_latestRemoveNotifications.count() > 10) { |
|
2318 // Remove oldest notification from the beginning of the list |
|
2319 m_latestRemoveNotifications.removeFirst(); |
|
2320 } |
|
2321 // Append new notification |
|
2322 m_latestRemoveNotifications.append(modestMessageId); |
|
2323 } else { |
|
2324 return; |
|
2325 } |
|
2326 } |
|
2327 |
|
2328 QMessageManager::NotificationFilterIdSet matchingFilters; |
|
2329 |
|
2330 // Copy the filter map to protect against modification during traversal |
|
2331 QMap<int, QMessageFilter> filters(m_filters); |
|
2332 QMap<int, QMessageFilter>::const_iterator it = filters.begin(), end = filters.end(); |
|
2333 QMessage message; |
|
2334 bool messageRetrieved = false; |
|
2335 for ( ; it != end; ++it) { |
|
2336 const QMessageFilter &filter(it.value()); |
|
2337 |
|
2338 if (!messageRetrieved) { |
|
2339 QString modestAccountId = modestAccountIdFromMessageId(messageId); |
|
2340 QString modestFolderId = modestFolderIdFromMessageId(messageId); |
|
2341 QString modestMessageId = modestMessageIdFromMessageId(messageId); |
|
2342 |
|
2343 MessagingModestMessage modestMessage = messageFromModest(modestAccountId, |
|
2344 modestFolderId, |
|
2345 modestMessageId); |
|
2346 |
|
2347 if (modestMessage.accountId.isEmpty()) { |
|
2348 return; |
|
2349 } |
|
2350 |
|
2351 if (modestMessage.flags & MessagingModestMessageDeleted) { |
|
2352 notificationType = ModestEngine::Removed; |
|
2353 } |
|
2354 if (modestMessage.size == 0) { |
|
2355 notificationType = ModestEngine::Removed; |
|
2356 } |
|
2357 |
|
2358 message = messageFromModestMessage(modestMessage); |
|
2359 realMessageId =message.id(); |
|
2360 messageRetrieved = true; |
|
2361 } |
|
2362 |
|
2363 if (filter.isEmpty()) { |
|
2364 // Empty filter matches to all messages |
|
2365 matchingFilters.insert(it.key()); |
|
2366 } else { |
|
2367 if (message.type() == QMessage::NoType) { |
|
2368 continue; |
|
2369 } |
|
2370 QMessageFilterPrivate* privateMessageFilter = QMessageFilterPrivate::implementation(filter); |
|
2371 if (privateMessageFilter->filter(message)) { |
|
2372 matchingFilters.insert(it.key()); |
|
2373 } |
|
2374 } |
|
2375 } |
|
2376 |
|
2377 if (matchingFilters.count() > 0) { |
|
2378 if (notificationType == ModestEngine::Added) { |
|
2379 m_messageStore->messageNotification(QMessageStorePrivate::Added, realMessageId, matchingFilters); |
|
2380 } else if (notificationType == ModestEngine::Updated) { |
|
2381 m_messageStore->messageNotification(QMessageStorePrivate::Updated, realMessageId, matchingFilters); |
|
2382 } else if (notificationType == ModestEngine::Removed) { |
|
2383 m_messageStore->messageNotification(QMessageStorePrivate::Removed, realMessageId, matchingFilters); |
|
2384 } |
|
2385 } |
|
2386 } |
|
2387 |
|
2388 QMessageAccountId ModestEngine::accountIdFromModestMessageId(const QString& modestMessageId) const |
|
2389 { |
|
2390 // Modest messageId format is following: |
|
2391 // <email protocol>://<username>@<hostname>:<port>... |
|
2392 QMessageAccountId accountId; |
|
2393 |
|
2394 int usernameBegin = modestMessageId.indexOf("//")+2; |
|
2395 int usernameEnd = modestMessageId.indexOf("@"); |
|
2396 QString username = QUrl::fromPercentEncoding(modestMessageId.mid(usernameBegin, usernameEnd-usernameBegin).toUtf8()); |
|
2397 int hostnameBegin = usernameEnd+1; |
|
2398 int hostnameEnd = modestMessageId.indexOf(':',hostnameBegin); |
|
2399 QString hostname = QUrl::fromPercentEncoding(modestMessageId.mid(hostnameBegin, hostnameEnd-hostnameBegin).toUtf8()); |
|
2400 |
|
2401 foreach (QMessageAccount value, iAccounts) { |
|
2402 QMessageAccountId accId = value.id(); |
|
2403 if ((accountUsername(accId) == username) && |
|
2404 (accountHostname(accId) == hostname)) { |
|
2405 accountId = accId; |
|
2406 } |
|
2407 } |
|
2408 |
|
2409 if (!accountId.isValid()) { |
|
2410 if (modestMessageId.left(modestMessageId.indexOf(':')) == "maildir") { |
|
2411 accountId = QMessageAccountId("MO_LOCAL"); |
|
2412 } |
|
2413 } |
|
2414 |
|
2415 return accountId; |
|
2416 } |
|
2417 |
|
2418 QMessageFolderId ModestEngine::folderIdFromModestMessageId(const QString& modestMessageId, |
|
2419 const QMessageAccountId accountId) const |
|
2420 { |
|
2421 // Modest messageId format is following: |
|
2422 // <email protocol>://<username>@<hostname>:<port>... |
|
2423 QMessageFolderId folderId; |
|
2424 QString folderIdAsString; |
|
2425 |
|
2426 if (!accountId.isValid()) { |
|
2427 folderIdAsString = accountIdFromModestMessageId(modestMessageId).toString(); |
|
2428 } else { |
|
2429 folderIdAsString = accountId.toString(); |
|
2430 } |
|
2431 |
|
2432 int protocolEnd = modestMessageId.indexOf(':'); |
|
2433 QString protocol = modestMessageId.left(protocolEnd); |
|
2434 folderIdAsString += "&" + protocol; |
|
2435 if (protocol == "pop") { |
|
2436 folderIdAsString += "&cache"; |
|
2437 } else if (protocol == "imap") { |
|
2438 int pathBegin = modestMessageId.indexOf('/',modestMessageId.lastIndexOf(':'))+1; |
|
2439 int pathEnd = modestMessageId.lastIndexOf('/'); |
|
2440 folderIdAsString += "&" + modestMessageId.mid(pathBegin, pathEnd-pathBegin); |
|
2441 } else if (protocol == "maildir") { |
|
2442 int pathBegin = modestMessageId.indexOf('#')+1; |
|
2443 int pathEnd = modestMessageId.lastIndexOf('/'); |
|
2444 folderIdAsString += "&" + modestMessageId.mid(pathBegin, pathEnd-pathBegin); |
|
2445 } |
|
2446 folderId = QMessageFolderId(QUrl::fromPercentEncoding(folderIdAsString.toUtf8())); |
|
2447 |
|
2448 return folderId; |
|
2449 } |
|
2450 |
|
2451 QString ModestEngine::modestAccountIdFromAccountId(const QMessageAccountId& accountId) const |
|
2452 { |
|
2453 // Just remove "MO_" prefix from the beginning of id string |
|
2454 return accountId.toString().remove(0,3); |
|
2455 } |
|
2456 |
|
2457 QString ModestEngine::modestFolderIdFromFolderId(const QMessageFolderId& folderId) const |
|
2458 { |
|
2459 QString modestFolderId; |
|
2460 |
|
2461 QString folderIdString = folderId.toString(); |
|
2462 int protocolBegin = folderIdString.indexOf('&'); |
|
2463 int protocolEnd = folderIdString.lastIndexOf('&'); |
|
2464 |
|
2465 modestFolderId = folderIdString.mid(protocolEnd+1); |
|
2466 QString protocol = folderIdString.mid(protocolBegin+1,protocolEnd-protocolBegin-1); |
|
2467 if ((protocol == "pop") && (modestFolderId == "cache")) { |
|
2468 modestFolderId = "INBOX"; |
|
2469 } |
|
2470 |
|
2471 return modestFolderId; |
|
2472 } |
|
2473 |
|
2474 QString ModestEngine::modestFolderUriFromFolderId(const QMessageFolderId& folderId) const |
|
2475 { |
|
2476 Q_UNUSED(folderId) //TODO: |
|
2477 return QString(); |
|
2478 } |
|
2479 |
|
2480 QString ModestEngine::modestAccountIdFromMessageId(const QMessageId& messageId, |
|
2481 bool checkProtocol) const |
|
2482 { |
|
2483 QString id = messageId.toString(); |
|
2484 int protocolBegin = id.indexOf('&'); |
|
2485 int protocolEnd = id.lastIndexOf('&'); |
|
2486 QString protocol = id.mid(protocolBegin+1,protocolEnd-protocolBegin-1); |
|
2487 if (checkProtocol && protocol == "maildir") { |
|
2488 return "local_folders"; |
|
2489 } |
|
2490 |
|
2491 return unescapeString(id.left(protocolBegin).remove(0,3)); |
|
2492 } |
|
2493 |
|
2494 QMessageAccountId ModestEngine::accountIdFromFolderId(const QMessageFolderId& folderId) const |
|
2495 { |
|
2496 QString id = folderId.toString(); |
|
2497 int protocolBegin = id.indexOf('&'); |
|
2498 return QMessageAccountId(id.left(protocolBegin)); |
|
2499 } |
|
2500 |
|
2501 QMessageAccountId ModestEngine::accountIdFromMessageId(const QMessageId& messageId) const |
|
2502 { |
|
2503 QString id = messageId.toString(); |
|
2504 int protocolBegin = id.indexOf('&'); |
|
2505 return QMessageAccountId(id.left(protocolBegin)); |
|
2506 } |
|
2507 |
|
2508 QString ModestEngine::modestAccountIdFromFolderId(const QMessageFolderId& folderId, |
|
2509 bool checkProtocol) const |
|
2510 { |
|
2511 QString id = folderId.toString(); |
|
2512 int protocolBegin = id.indexOf('&'); |
|
2513 int protocolEnd = id.lastIndexOf('&'); |
|
2514 QString protocol = id.mid(protocolBegin+1,protocolEnd-protocolBegin-1); |
|
2515 if (checkProtocol && protocol == "maildir") { |
|
2516 return "local_folders"; |
|
2517 } |
|
2518 |
|
2519 return unescapeString(id.left(protocolBegin).remove(0,3)); |
|
2520 } |
|
2521 |
|
2522 QString ModestEngine::modestFolderIdFromMessageId(const QMessageId& messageId) const |
|
2523 { |
|
2524 QString id = messageId.toString(); |
|
2525 |
|
2526 int protocolBegin = id.indexOf('&'); |
|
2527 int protocolEnd = id.lastIndexOf('&'); |
|
2528 int folderEnd = id.lastIndexOf('/'); |
|
2529 |
|
2530 QString protocol = id.mid(protocolBegin+1,protocolEnd-protocolBegin-1); |
|
2531 id = id.mid(protocolEnd+1,folderEnd-protocolEnd-1); |
|
2532 if ((protocol == "pop") && (id == "cache")) { |
|
2533 id = "INBOX"; |
|
2534 } |
|
2535 |
|
2536 return id; |
|
2537 } |
|
2538 |
|
2539 void ModestEngine::replaceProtocol(QString& id, const QString& newProtocol) const |
|
2540 { |
|
2541 int protocolBegin = id.indexOf('&'); |
|
2542 int protocolEnd = id.lastIndexOf('&'); |
|
2543 id.remove(protocolBegin+1,protocolEnd-protocolBegin-1); |
|
2544 id.insert(protocolBegin+1, newProtocol); |
|
2545 } |
|
2546 |
|
2547 QMessageAccountId ModestEngine::realAccountId(const MessagingModestMessage& modestMessage) const |
|
2548 { |
|
2549 QMessageAccountId accountId; |
|
2550 |
|
2551 if (modestMessage.accountId == "local_folders") { |
|
2552 QString accountIdString; |
|
2553 // Message is in local foldar, but message can be linked |
|
2554 // to actual account using 'From', 'To', 'Cc' or 'Bcc' fields |
|
2555 foreach (QMessageAccount value, iAccounts) { |
|
2556 QMessageAccountPrivate* privAccount = QMessageAccountPrivate::implementation(value); |
|
2557 if (modestMessage.from.contains(privAccount->_address.addressee())) { |
|
2558 accountIdString = value.id().toString(); |
|
2559 break; |
|
2560 } else if (modestMessage.to.contains(privAccount->_address.addressee())) { |
|
2561 accountIdString = value.id().toString(); |
|
2562 break; |
|
2563 } else if (modestMessage.cc.contains(privAccount->_address.addressee())) { |
|
2564 accountIdString = value.id().toString(); |
|
2565 break; |
|
2566 } else if (modestMessage.bcc.contains(privAccount->_address.addressee())) { |
|
2567 accountIdString = value.id().toString(); |
|
2568 break; |
|
2569 } |
|
2570 } |
|
2571 if (!accountIdString.isEmpty()) { |
|
2572 accountId = QMessageAccountId(accountIdString); |
|
2573 } |
|
2574 } else { |
|
2575 accountId = accountIdFromModestAccountId(modestMessage.accountId); |
|
2576 } |
|
2577 |
|
2578 return accountId; |
|
2579 } |
|
2580 |
|
2581 QString ModestEngine::modestMessageIdFromMessageId(const QMessageId& messageId) const |
|
2582 { |
|
2583 QString id = messageId.toString(); |
|
2584 return id.mid(id.lastIndexOf('/')+1); |
|
2585 } |
|
2586 |
|
2587 QMessageAccountId ModestEngine::accountIdFromModestAccountId(const QString& accountId) const |
|
2588 { |
|
2589 // Just add "MO_" prefix to the beginning of id string & escape created Id |
|
2590 return QMessageAccountId(escapeString("MO_"+accountId)); |
|
2591 } |
|
2592 |
|
2593 QMessageFolderId ModestEngine::folderIdFromModestFolderId(const QMessageAccountId& accountId, |
|
2594 bool isLocalFolder, |
|
2595 const QString& modestFolderId) const |
|
2596 { |
|
2597 // Format: <accountId>&<email protocol>&<Modest folderId> |
|
2598 QMessageFolderId folderId; |
|
2599 |
|
2600 if (isLocalFolder) { |
|
2601 folderId = QMessageFolderId(accountId.toString()+"&maildir&"+modestFolderId); |
|
2602 } else { |
|
2603 QString protocol = accountEmailProtocolAsString(accountId); |
|
2604 if ((protocol == "pop") && (modestFolderId == "INBOX")) { |
|
2605 folderId = QMessageFolderId(accountId.toString()+"&"+protocol+"&cache"); |
|
2606 } else { |
|
2607 folderId = QMessageFolderId(accountId.toString()+"&"+protocol+"&"+modestFolderId); |
|
2608 } |
|
2609 } |
|
2610 |
|
2611 return folderId; |
|
2612 } |
|
2613 |
|
2614 QMessageId ModestEngine::messageIdFromModestMessageId(const QString& messageId) const |
|
2615 { |
|
2616 QString messageIdString = folderIdFromModestMessageId(messageId).toString(); |
|
2617 int idPartBegin = messageId.lastIndexOf('/'); |
|
2618 messageIdString += messageId.mid(idPartBegin, idPartBegin-messageId.length()); |
|
2619 return QMessageId(messageIdString); |
|
2620 } |
|
2621 |
|
2622 QMessageId ModestEngine::messageIdFromModestMessageFilePath(const QString& messageFilePath) const |
|
2623 { |
|
2624 QString messageIdString; |
|
2625 |
|
2626 QString filePath = messageFilePath; |
|
2627 QString localRootFolder = this->localRootFolder(); |
|
2628 if (filePath.startsWith(localRootFolder)) { |
|
2629 messageIdString = "MO_LOCAL&maildir&"; |
|
2630 filePath.remove(0,localRootFolder.length()+1); |
|
2631 filePath.remove("/cur"); |
|
2632 messageIdString += filePath.left(filePath.lastIndexOf('!')); |
|
2633 } else { |
|
2634 foreach (QMessageAccount value, iAccounts) { |
|
2635 QMessageAccountId accountId = value.id(); |
|
2636 QString rootFolder = accountRootFolder(accountId); |
|
2637 if (filePath.startsWith(rootFolder)) { |
|
2638 QString protocol = accountEmailProtocolAsString(accountId); |
|
2639 messageIdString = accountId.toString()+"&"+protocol+"&"; |
|
2640 filePath.remove(0,rootFolder.length()+1); |
|
2641 filePath.remove("/subfolders"); |
|
2642 messageIdString += filePath.left(filePath.lastIndexOf('.')); |
|
2643 if (protocol == "pop") { |
|
2644 QDir dir(messageFilePath); |
|
2645 dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot); |
|
2646 QFileInfoList dirs = dir.entryInfoList(); |
|
2647 if (dirs.count() > 0) { |
|
2648 QString fileName = dirs[0].fileName(); |
|
2649 // Remove folder that contains actual message |
|
2650 messageIdString = messageIdString.left(messageIdString.lastIndexOf('/')+1); |
|
2651 // Add message name |
|
2652 messageIdString = messageIdString+fileName; |
|
2653 } |
|
2654 } |
|
2655 } |
|
2656 } |
|
2657 } |
|
2658 |
|
2659 return QMessageId(messageIdString); |
|
2660 } |
|
2661 |
|
2662 QString ModestEngine::unescapeString(const QString& string) |
|
2663 { |
|
2664 QString unescapedString; |
|
2665 |
|
2666 QByteArray str = string.toUtf8(); |
|
2667 gchar* unescaped_string = gconf_unescape_key(str.data(), str.length()); |
|
2668 unescapedString = QString::fromUtf8(unescaped_string); |
|
2669 g_free(unescaped_string); |
|
2670 |
|
2671 return unescapedString; |
|
2672 } |
|
2673 |
|
2674 QString ModestEngine::escapeString(const QString& string) |
|
2675 { |
|
2676 QString escapedString; |
|
2677 |
|
2678 QByteArray str = unescapeString(string).toUtf8(); |
|
2679 gchar* escaped_string = gconf_escape_key(str.data(), str.length()); |
|
2680 escapedString = QString::fromUtf8(escaped_string); |
|
2681 g_free(escaped_string); |
|
2682 |
|
2683 return escapedString; |
|
2684 } |
|
2685 |
|
2686 INotifyWatcher::INotifyWatcher() |
|
2687 { |
|
2688 // Initialize inotify instance |
|
2689 // => returned file descriptor is associated with |
|
2690 // a new inotify event queue |
|
2691 // O_CLOEXEC flag makes sure that file descriptor |
|
2692 // is closed if execution is transfered |
|
2693 // from this process to a new program |
|
2694 // (Check more info from 'execve' documentation) |
|
2695 #ifdef IN_CLOEXEC |
|
2696 m_inotifyFileDescriptor = inotify_init1(IN_CLOEXEC); |
|
2697 #else |
|
2698 m_inotifyFileDescriptor = inotify_init(); |
|
2699 if (m_inotifyFileDescriptor >= 0) { |
|
2700 ::fcntl(m_inotifyFileDescriptor, F_SETFD, FD_CLOEXEC); |
|
2701 } |
|
2702 #endif |
|
2703 if (m_inotifyFileDescriptor >= 0) { |
|
2704 // Change thread affinity for this object to this |
|
2705 // thread. |
|
2706 // => Event processing (for this objects events) will |
|
2707 // be done in this thread |
|
2708 moveToThread(this); |
|
2709 } |
|
2710 } |
|
2711 |
|
2712 INotifyWatcher::~INotifyWatcher() |
|
2713 { |
|
2714 // Tell the thread's event loop to exit |
|
2715 // => thread returns from the call to exec() |
|
2716 exit(); |
|
2717 |
|
2718 // Wait until this thread has finished execution |
|
2719 // <=> waits until thread returns from run() |
|
2720 wait(); |
|
2721 |
|
2722 clear(); |
|
2723 |
|
2724 // Close file descriptor that's referring to inotify instance |
|
2725 // => The underlying inotify object and its resources are freed |
|
2726 ::close(m_inotifyFileDescriptor); |
|
2727 } |
|
2728 |
|
2729 void INotifyWatcher::clear() |
|
2730 { |
|
2731 // Remove all watches from inotify instance watch list |
|
2732 QMapIterator<int, QString> i(m_dirs); |
|
2733 while (i.hasNext()) { |
|
2734 inotify_rm_watch(m_inotifyFileDescriptor, i.next().key()); |
|
2735 } |
|
2736 m_dirs.clear(); |
|
2737 |
|
2738 QMapIterator<int, QString> j(m_files); |
|
2739 while (j.hasNext()) { |
|
2740 inotify_rm_watch(m_inotifyFileDescriptor, j.next().key()); |
|
2741 } |
|
2742 m_files.clear(); |
|
2743 } |
|
2744 |
|
2745 void INotifyWatcher::run() |
|
2746 { |
|
2747 // Start listening inotify |
|
2748 QSocketNotifier socketNotifier(m_inotifyFileDescriptor, QSocketNotifier::Read, this); |
|
2749 connect(&socketNotifier, SIGNAL(activated(int)), SLOT(notifySlot())); |
|
2750 |
|
2751 // Enter the thread event loop |
|
2752 (void) exec(); |
|
2753 } |
|
2754 |
|
2755 int INotifyWatcher::addFile(const QString& path, uint eventsToWatch) |
|
2756 { |
|
2757 int watchDescriptor = 0; |
|
2758 QMutexLocker locker(&m_mutex); |
|
2759 |
|
2760 if (m_inotifyFileDescriptor >= 0) { |
|
2761 int watchDescriptor = 0; |
|
2762 if (eventsToWatch == 0) { |
|
2763 watchDescriptor = inotify_add_watch(m_inotifyFileDescriptor, |
|
2764 QFile::encodeName(path), |
|
2765 0 | IN_ATTRIB |
|
2766 | IN_MODIFY |
|
2767 | IN_MOVE |
|
2768 | IN_MOVE_SELF |
|
2769 | IN_DELETE_SELF); |
|
2770 } else { |
|
2771 watchDescriptor = inotify_add_watch(m_inotifyFileDescriptor, |
|
2772 QFile::encodeName(path), |
|
2773 eventsToWatch); |
|
2774 } |
|
2775 if (watchDescriptor > 0) { |
|
2776 m_files.insert(watchDescriptor, path); |
|
2777 } else { |
|
2778 watchDescriptor = 0; |
|
2779 } |
|
2780 } |
|
2781 |
|
2782 // Start thread (if thread is not already running) |
|
2783 start(); |
|
2784 |
|
2785 return watchDescriptor; |
|
2786 } |
|
2787 |
|
2788 int INotifyWatcher::addDirectory(const QString& path, uint eventsToWatch) |
|
2789 { |
|
2790 int watchDescriptor = 0; |
|
2791 QMutexLocker locker(&m_mutex); |
|
2792 |
|
2793 if (m_inotifyFileDescriptor >= 0) { |
|
2794 int watchDescriptor = 0; |
|
2795 if (eventsToWatch == 0) { |
|
2796 watchDescriptor = inotify_add_watch(m_inotifyFileDescriptor, |
|
2797 QFile::encodeName(path), |
|
2798 0 | IN_ATTRIB |
|
2799 | IN_MOVE |
|
2800 | IN_CREATE |
|
2801 | IN_DELETE |
|
2802 | IN_DELETE_SELF); |
|
2803 } else { |
|
2804 watchDescriptor = inotify_add_watch(m_inotifyFileDescriptor, |
|
2805 QFile::encodeName(path), |
|
2806 eventsToWatch); |
|
2807 } |
|
2808 if (watchDescriptor > 0) { |
|
2809 m_dirs.insert(watchDescriptor, path); |
|
2810 } else { |
|
2811 watchDescriptor = 0; |
|
2812 } |
|
2813 } |
|
2814 |
|
2815 // Start thread (if thread is not already running) |
|
2816 start(); |
|
2817 |
|
2818 return watchDescriptor; |
|
2819 } |
|
2820 |
|
2821 QStringList INotifyWatcher::directories() const |
|
2822 { |
|
2823 return m_dirs.values(); |
|
2824 } |
|
2825 |
|
2826 QStringList INotifyWatcher::files() const |
|
2827 { |
|
2828 return m_dirs.values(); |
|
2829 } |
|
2830 |
|
2831 void INotifyWatcher::notifySlot() |
|
2832 { |
|
2833 QMutexLocker locker(&m_mutex); |
|
2834 |
|
2835 int bufferSize = 0; |
|
2836 ioctl(m_inotifyFileDescriptor, FIONREAD, (char*) &bufferSize); |
|
2837 QVarLengthArray<char, 4096> buffer(bufferSize); |
|
2838 bufferSize = read(m_inotifyFileDescriptor, buffer.data(), bufferSize); |
|
2839 const char* at = buffer.data(); |
|
2840 const char* const end = at + bufferSize; |
|
2841 |
|
2842 QMap<int, INotifyEvent> eventsForWatchedFile; |
|
2843 QMap<QString, INotifyEvent> eventsForFileInWatchedDirectory; |
|
2844 while (at < end) { |
|
2845 const inotify_event *event = reinterpret_cast<const inotify_event *>(at); |
|
2846 if (m_files.contains(event->wd)) { |
|
2847 // File event handling |
|
2848 if (eventsForWatchedFile.contains(event->wd)) { |
|
2849 // There is already unhandled event for this file in queue |
|
2850 // => Mask is ORed to existing event |
|
2851 eventsForWatchedFile[event->wd].mask |= event->mask; |
|
2852 } else { |
|
2853 // There is no event for this file in queue |
|
2854 // => New event is created |
|
2855 INotifyEvent inotifyEvent; |
|
2856 inotifyEvent.watchDescriptor = event->wd; |
|
2857 inotifyEvent.mask = event->mask; |
|
2858 inotifyEvent.fileName = QString::fromAscii(event->name, event->len); |
|
2859 eventsForWatchedFile.insert(event->wd, inotifyEvent); |
|
2860 } |
|
2861 } else { |
|
2862 // Directory event handling |
|
2863 QString changeForFileInDirectory = QString::fromAscii(event->name, event->len); |
|
2864 // Remove unnecessary postfix (starting with '!') from the file name |
|
2865 changeForFileInDirectory = changeForFileInDirectory.left(changeForFileInDirectory.lastIndexOf('!')); |
|
2866 if (!changeForFileInDirectory.isEmpty()) { |
|
2867 QString eventId = QString::number(event->wd)+changeForFileInDirectory; |
|
2868 if (eventsForFileInWatchedDirectory.contains(eventId)) { |
|
2869 // There is already unhandled event for this file in queue |
|
2870 // => Mask is ORed to existing event |
|
2871 eventsForFileInWatchedDirectory[eventId].mask |= event->mask; |
|
2872 } else { |
|
2873 // There is no event for this file in queue |
|
2874 // => New event is created |
|
2875 INotifyEvent inotifyEvent; |
|
2876 inotifyEvent.watchDescriptor = event->wd; |
|
2877 inotifyEvent.mask = event->mask; |
|
2878 inotifyEvent.fileName = QString::fromAscii(event->name, event->len); |
|
2879 eventsForFileInWatchedDirectory.insert(eventId, inotifyEvent); |
|
2880 } |
|
2881 } |
|
2882 } |
|
2883 at += sizeof(inotify_event) + event->len; |
|
2884 } |
|
2885 |
|
2886 QMap<int, INotifyEvent>::const_iterator it = eventsForWatchedFile.constBegin(); |
|
2887 while (it != eventsForWatchedFile.constEnd()) { |
|
2888 INotifyEvent event = *it; |
|
2889 QString file = m_files.value(event.watchDescriptor); |
|
2890 if (!file.isEmpty()) { |
|
2891 emit fileChanged(event.watchDescriptor, file, event.mask); |
|
2892 } |
|
2893 ++it; |
|
2894 } |
|
2895 |
|
2896 QMap<QString, INotifyEvent>::const_iterator jt = eventsForFileInWatchedDirectory.constBegin(); |
|
2897 while (jt != eventsForFileInWatchedDirectory.constEnd()) { |
|
2898 INotifyEvent event = *jt; |
|
2899 QString file = m_dirs.value(event.watchDescriptor)+"/"+event.fileName; |
|
2900 emit fileChanged(event.watchDescriptor, file, event.mask); |
|
2901 ++jt; |
|
2902 } |
|
2903 } |
|
2904 |
|
2905 ModestStringMap ModestEngine::getModestSenderInfo(QMessage &message) |
|
2906 { |
|
2907 QMessageAddress address; |
|
2908 ModestStringMap senderInfo; |
|
2909 QMessageAccountId accountId; |
|
2910 QString value; |
|
2911 |
|
2912 accountId = message.parentAccountId(); |
|
2913 if (accountId.isValid() == false) { |
|
2914 qWarning () << "Account ID is invalid"; |
|
2915 return ModestStringMap(); |
|
2916 } |
|
2917 |
|
2918 senderInfo["account-name"] = unescapeString(modestAccountIdFromAccountId(accountId)); |
|
2919 |
|
2920 QMessageAccount messageAccount = account(accountId); |
|
2921 QMessageAccountPrivate* privAccount = QMessageAccountPrivate::implementation(messageAccount); |
|
2922 address = privAccount->_address; |
|
2923 value = address.addressee(); |
|
2924 |
|
2925 if (value.isEmpty() == false && value.isNull() == false) { |
|
2926 senderInfo["from"] = value; |
|
2927 } |
|
2928 |
|
2929 return senderInfo; |
|
2930 } |
|
2931 |
|
2932 ModestStringMap ModestEngine::getModestRecipients(QMessage &message) |
|
2933 { |
|
2934 QMessageAddressList addresses; |
|
2935 QMessageAddress address; |
|
2936 ModestStringMap recipients; |
|
2937 QString value; |
|
2938 |
|
2939 addresses = message.to(); |
|
2940 value.clear(); |
|
2941 for (int i = 0; i < addresses.length(); i++) { |
|
2942 address = addresses[i]; |
|
2943 |
|
2944 if (value.isEmpty()) { |
|
2945 value = address.addressee(); |
|
2946 } else { |
|
2947 value.append (","); |
|
2948 value.append (address.addressee()); |
|
2949 } |
|
2950 } |
|
2951 |
|
2952 if (value.isEmpty() == false && value.isNull() == false) { |
|
2953 recipients["to"] = value; |
|
2954 } |
|
2955 |
|
2956 addresses = message.cc(); |
|
2957 value.clear(); |
|
2958 for (int i = 0; i < addresses.length(); i++) { |
|
2959 address = addresses[i]; |
|
2960 |
|
2961 if (value.isEmpty()) { |
|
2962 value = address.addressee(); |
|
2963 } else { |
|
2964 value.append (","); |
|
2965 value.append (address.addressee()); |
|
2966 } |
|
2967 } |
|
2968 |
|
2969 if (value.isEmpty() == false && value.isNull() == false) { |
|
2970 recipients["cc"] = value; |
|
2971 } |
|
2972 |
|
2973 addresses = message.bcc(); |
|
2974 value.clear(); |
|
2975 for (int i = 0; i < addresses.length(); i++) { |
|
2976 address = addresses[i]; |
|
2977 |
|
2978 if (value.isEmpty()) { |
|
2979 value = address.addressee(); |
|
2980 } else { |
|
2981 value.append (","); |
|
2982 value.append (address.addressee()); |
|
2983 } |
|
2984 } |
|
2985 |
|
2986 if (value.isEmpty() == false && value.isNull() == false) { |
|
2987 recipients["bcc"] = value; |
|
2988 } |
|
2989 |
|
2990 return recipients; |
|
2991 } |
|
2992 |
|
2993 ModestStringMap ModestEngine::getModestMessageData(QMessage &message) |
|
2994 { |
|
2995 QMessageContentContainerId bodyId; |
|
2996 QMessageContentContainer body; |
|
2997 ModestStringMap messageData; |
|
2998 QString value; |
|
2999 |
|
3000 value = message.subject(); |
|
3001 |
|
3002 if (value.isEmpty() == false && value.isNull() == false) { |
|
3003 messageData["subject"] = value; |
|
3004 } |
|
3005 |
|
3006 bodyId = message.bodyId(); |
|
3007 if (bodyId.isValid()) { |
|
3008 body = message.find (bodyId); |
|
3009 } else { |
|
3010 body = message; |
|
3011 } |
|
3012 |
|
3013 value = body.contentType(); |
|
3014 |
|
3015 if (value == "text") { |
|
3016 QString key, data; |
|
3017 bool hasContent = false; |
|
3018 |
|
3019 value = body.contentSubType(); |
|
3020 |
|
3021 if ((hasContent = body.isContentAvailable()) == true) { |
|
3022 data = body.textContent(); |
|
3023 } |
|
3024 |
|
3025 if (value == "plain") { |
|
3026 key = "plain-body"; |
|
3027 } else if (value == "html") { |
|
3028 key = "html-body"; |
|
3029 } |
|
3030 |
|
3031 if (key.isEmpty() == false && key.isNull() == false && hasContent) { |
|
3032 messageData[key] = data; |
|
3033 } |
|
3034 } |
|
3035 |
|
3036 return messageData; |
|
3037 } |
|
3038 |
|
3039 ModestStringMapList ModestEngine::getModestAttachments(QMessage &message) |
|
3040 { |
|
3041 QMessageContentContainerIdList attachmentIds; |
|
3042 ModestStringMapList attachments; |
|
3043 QMessage::StatusFlags messageStatus; |
|
3044 QString value; |
|
3045 |
|
3046 messageStatus = message.status(); |
|
3047 |
|
3048 if (messageStatus & QMessage::HasAttachments) { |
|
3049 attachmentIds = message.attachmentIds(); |
|
3050 |
|
3051 foreach (QMessageContentContainerId identifier, attachmentIds) { |
|
3052 ModestStringMap attachmentData; |
|
3053 QMessageContentContainer attachmentCont; |
|
3054 |
|
3055 if (identifier.isValid() == false) continue; |
|
3056 |
|
3057 attachmentCont = message.find (identifier); |
|
3058 |
|
3059 if (attachmentCont.isContentAvailable () == false) continue; |
|
3060 |
|
3061 attachmentData.clear(); |
|
3062 |
|
3063 value = attachmentCont.contentType(); |
|
3064 |
|
3065 if (value.isEmpty() == false) { |
|
3066 value.append("/"); |
|
3067 value.append (attachmentCont.contentSubType()); |
|
3068 attachmentData["mime-type"] = value; |
|
3069 |
|
3070 qDebug() << "mime-type: " << value; |
|
3071 } |
|
3072 |
|
3073 value = QMessageContentContainerPrivate::attachmentFilename ( |
|
3074 attachmentCont); |
|
3075 |
|
3076 if (value.isEmpty() == false) { |
|
3077 attachmentData["filename"] = value; |
|
3078 qDebug() << "filename: " << value; |
|
3079 } |
|
3080 |
|
3081 qDebug() << "Charset: " << attachmentCont.contentCharset(); |
|
3082 qDebug() << "Headers: " << attachmentCont.headerFields(); |
|
3083 |
|
3084 if (attachmentData.isEmpty() == false) { |
|
3085 attachmentData["content-id"] = identifier.toString(); |
|
3086 attachments.append (attachmentData); |
|
3087 } |
|
3088 } |
|
3089 } |
|
3090 |
|
3091 return attachments; |
|
3092 } |
|
3093 |
|
3094 ModestStringMapList ModestEngine::getModestImages(QMessage &message) |
|
3095 { |
|
3096 Q_UNUSED(message); |
|
3097 // Don't know if this even makes sense. Modest expects inlined images |
|
3098 // to be in a separate list, but that doesn't make much sense? |
|
3099 return ModestStringMapList(); |
|
3100 } |
|
3101 |
|
3102 uint ModestEngine::getModestPriority(QMessage &message) |
|
3103 { |
|
3104 uint priority = 0; |
|
3105 |
|
3106 switch (message.priority()) { |
|
3107 case QMessage::HighPriority: |
|
3108 priority = MODESTENGINE_HIGH_PRIORITY; |
|
3109 break; |
|
3110 |
|
3111 default: |
|
3112 case QMessage::NormalPriority: |
|
3113 priority = MODESTENGINE_NORMAL_PRIORITY; |
|
3114 break; |
|
3115 |
|
3116 case QMessage::LowPriority: |
|
3117 priority = MODESTENGINE_LOW_PRIORITY; |
|
3118 break; |
|
3119 } |
|
3120 |
|
3121 return priority; |
|
3122 } |
|
3123 |
|
3124 ModestStringMap ModestEngine::getModestHeaders(QMessage &message) |
|
3125 { |
|
3126 Q_UNUSED(message); |
|
3127 return ModestStringMap(); // stub |
|
3128 } |
|
3129 |
|
3130 #include "moc_modestengine_maemo_p.cpp" |
292 |
3131 |
293 QTM_END_NAMESPACE |
3132 QTM_END_NAMESPACE |