summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGareth Pethig <gareth.pethig@nokia.com>2009-05-15 20:34:20 +1000
committerGareth Pethig <gareth.pethig@nokia.com>2009-05-15 20:34:20 +1000
commit1c9dea79bee0fca57a037858b15db7418bc7cade (patch)
tree2884f94a4eb875dd9e2cbe46586dc649015867da
parent38206e96976cbed50359d915c5266eb1254c1c94 (diff)
parent9dfb47145caf4b82bda7235d8cac2c711b083159 (diff)
Merge branch 'qmf-1.0' into pkg
-rw-r--r--src/applications/qtmail/emailclient.cpp23
-rw-r--r--src/applications/qtmail/qtmailwindow.cpp62
-rw-r--r--src/applications/qtmail/qtmailwindow.h4
-rw-r--r--src/applications/qtmail/writemail.cpp27
-rw-r--r--src/applications/qtmail/writemail.h2
-rw-r--r--src/libraries/messageserver/qmailauthenticator.cpp1
-rw-r--r--src/libraries/messageserver/qmailmessageclassifier.cpp1
-rw-r--r--src/libraries/messageserver/qmailmessageservice.cpp94
-rw-r--r--src/libraries/messageserver/qmailserviceconfiguration.cpp1
-rw-r--r--src/libraries/messageserver/qmailstoreaccountfilter.cpp1
-rw-r--r--src/libraries/messageserver/qmailtransport.cpp6
-rw-r--r--src/libraries/qmfutil/qmailcomposer.cpp2
-rw-r--r--src/libraries/qmfutil/qmailmessagedelegate.cpp2
-rw-r--r--src/libraries/qmfutil/qmailviewer.cpp2
-rw-r--r--src/libraries/qtopiamail/CHANGES.qdoc13
-rw-r--r--src/libraries/qtopiamail/qmailaccount.cpp1
-rw-r--r--src/libraries/qtopiamail/qmailaccountconfiguration.cpp2
-rw-r--r--src/libraries/qtopiamail/qmailaccountkey.cpp1
-rw-r--r--src/libraries/qtopiamail/qmailaccountkey.h4
-rw-r--r--src/libraries/qtopiamail/qmailaccountlistmodel.cpp1
-rw-r--r--src/libraries/qtopiamail/qmailaccountsortkey.cpp1
-rw-r--r--src/libraries/qtopiamail/qmailaddress.cpp1
-rw-r--r--src/libraries/qtopiamail/qmailcodec.cpp5
-rw-r--r--src/libraries/qtopiamail/qmailcontentmanager.cpp4
-rw-r--r--src/libraries/qtopiamail/qmaildatacomparator.cpp1
-rw-r--r--src/libraries/qtopiamail/qmailfolder.cpp1
-rw-r--r--src/libraries/qtopiamail/qmailfolderkey.cpp1
-rw-r--r--src/libraries/qtopiamail/qmailfolderkey.h4
-rw-r--r--src/libraries/qtopiamail/qmailfoldersortkey.cpp1
-rw-r--r--src/libraries/qtopiamail/qmailid.cpp3
-rw-r--r--src/libraries/qtopiamail/qmailkeyargument.cpp2
-rw-r--r--src/libraries/qtopiamail/qmailmessage.cpp10
-rw-r--r--src/libraries/qtopiamail/qmailmessagefwd.cpp6
-rw-r--r--src/libraries/qtopiamail/qmailmessagekey.cpp9
-rw-r--r--src/libraries/qtopiamail/qmailmessagekey.h4
-rw-r--r--src/libraries/qtopiamail/qmailmessagelistmodel.cpp1
-rw-r--r--src/libraries/qtopiamail/qmailmessageremovalrecord.cpp1
-rw-r--r--src/libraries/qtopiamail/qmailmessageserver.cpp47
-rw-r--r--src/libraries/qtopiamail/qmailmessageset.cpp14
-rw-r--r--src/libraries/qtopiamail/qmailmessagesortkey.cpp1
-rw-r--r--src/libraries/qtopiamail/qmailserviceaction.cpp91
-rw-r--r--src/libraries/qtopiamail/qmailstore.cpp147
-rw-r--r--src/libraries/qtopiamail/qmailstore.h19
-rw-r--r--src/libraries/qtopiamail/qmailstore_p.cpp96
-rw-r--r--src/libraries/qtopiamail/qmailstore_p.h4
-rw-r--r--src/libraries/qtopiamail/qmailstoreimplementation_p.cpp86
-rw-r--r--src/libraries/qtopiamail/qmailstoreimplementation_p.h23
-rw-r--r--src/libraries/qtopiamail/qmailtimestamp.cpp1
-rw-r--r--src/libraries/qtopiamail/qprivateimplementation.cpp3
-rw-r--r--src/libraries/qtopiamail/support/qcopchannel.cpp62
-rw-r--r--src/libraries/qtopiamail/support/qcopchannel_p.h58
-rw-r--r--src/plugins/composers/email/attachmentlistwidget.cpp35
-rw-r--r--src/plugins/composers/email/attachmentlistwidget.h12
-rw-r--r--src/plugins/composers/email/emailcomposer.cpp120
-rw-r--r--src/plugins/composers/email/emailcomposer.h2
-rw-r--r--src/plugins/contentmanagers/qtopiamailfile/qtopiamailfilemanager.cpp26
-rw-r--r--src/plugins/messageservices/imap/imapclient.cpp17
-rw-r--r--src/plugins/messageservices/imap/imapprotocol.cpp6
-rw-r--r--src/plugins/messageservices/imap/imapservice.cpp35
-rw-r--r--src/plugins/messageservices/imap/imapstrategy.cpp725
-rw-r--r--src/plugins/messageservices/imap/imapstrategy.h94
-rw-r--r--src/tools/messageserver/messageserver.cpp2
-rw-r--r--src/tools/messageserver/servicehandler.cpp223
-rw-r--r--src/tools/messageserver/servicehandler.h14
-rw-r--r--tests/tests.pro1
-rw-r--r--tests/tst_qmailstorekeys/tst_qmailstorekeys.cpp3
66 files changed, 1496 insertions, 776 deletions
diff --git a/src/applications/qtmail/emailclient.cpp b/src/applications/qtmail/emailclient.cpp
index b341ae38..575a2bee 100644
--- a/src/applications/qtmail/emailclient.cpp
+++ b/src/applications/qtmail/emailclient.cpp
@@ -44,6 +44,7 @@
#include <qmailnamespace.h>
#include <QSplitter>
#include <QListView>
+#include <QToolBar>
static const int defaultWidth = 1024;
static const int defaultHeight = 768;
@@ -282,7 +283,7 @@ void MessageUiBase::presentMessage(const QMailMessageId &id, QMailViewerFactory:
WriteMail* MessageUiBase::createWriteMailWidget()
{
WriteMail* writeMail = new WriteMail(this);
- writeMail->setGeometry(0,0,400,400);
+ writeMail->setGeometry(0,0,500,400);
writeMail->setObjectName("write-mail");
connect(writeMail, SIGNAL(enqueueMail(QMailMessage)), this, SLOT(enqueueMail(QMailMessage)));
@@ -650,6 +651,14 @@ void EmailClient::initActions()
this,SLOT(quit()));
connect(fileMenu, SIGNAL(aboutToShow()), this, SLOT(updateActions()));
+ QToolBar* toolBar = mw->toolBar();
+ toolBar->addAction( composeButton );
+ toolBar->addAction( getMailButton );
+ toolBar->addAction( cancelButton );
+ toolBar->addAction( searchButton );
+ toolBar->addSeparator();
+ toolBar->addAction( settingsAction );
+
updateGetMailButton();
folderView()->addAction( synchronizeAction );
@@ -702,7 +711,9 @@ void EmailClient::delayedInit()
// Whenever these actions occur, we need to reload accounts that may have changed
connect(store, SIGNAL(accountsAdded(QMailAccountIdList)), this, SLOT(accountsAdded(QMailAccountIdList)));
+ connect(store, SIGNAL(accountsAdded(QMailAccountIdList)), this, SLOT(updateActions()));
connect(store, SIGNAL(accountsRemoved(QMailAccountIdList)), this, SLOT(accountsRemoved(QMailAccountIdList)));
+ connect(store, SIGNAL(accountsRemoved(QMailAccountIdList)), this, SLOT(updateActions()));
connect(store, SIGNAL(accountsUpdated(QMailAccountIdList)), this, SLOT(accountsUpdated(QMailAccountIdList)));
// We need to detect when messages are marked as deleted during downloading
@@ -713,6 +724,7 @@ void EmailClient::delayedInit()
// Ideally would make actions functions methods and delay their
// creation until context menu is shown.
initActions();
+ updateActions();
QTimer::singleShot(0, this, SLOT(openFiles()) );
}
@@ -787,6 +799,10 @@ void EmailClient::cancelOperation()
retrievalAction->cancelOperation();
setRetrievalInProgress( false );
}
+
+ if (flagRetrievalAction->activity() == QMailServiceAction::InProgress) {
+ flagRetrievalAction->cancelOperation();
+ }
}
/* Enqueue mail must always store the mail in the outbox */
@@ -1819,7 +1835,11 @@ void EmailClient::composeActivated()
{
delayedInit();
if(writeMailWidget()->prepareComposer())
+ {
writeMailWidget()->show();
+ writeMailWidget()->raise();
+ writeMailWidget()->activateWindow();
+ }
}
void EmailClient::sendMessageTo(const QMailAddress &address, QMailMessage::MessageType type)
@@ -1993,6 +2013,7 @@ void EmailClient::transferStatusUpdate(int status)
// UI updates
setActionVisible(cancelButton, transferStatus != Inactive);
updateGetMailButton();
+ updateActions();
}
}
diff --git a/src/applications/qtmail/qtmailwindow.cpp b/src/applications/qtmail/qtmailwindow.cpp
index 53a0b6c0..a634e3b8 100644
--- a/src/applications/qtmail/qtmailwindow.cpp
+++ b/src/applications/qtmail/qtmailwindow.cpp
@@ -21,6 +21,8 @@
#include <QStatusBar>
#include <QMenuBar>
#include <QApplication>
+#include <QToolBar>
+#include <QDesktopWidget>
QTMailWindow *QTMailWindow::self = 0;
@@ -53,6 +55,9 @@ void QTMailWindow::init()
m_contextMenu = file;
+ m_toolBar = new QToolBar(this);
+ addToolBar(m_toolBar);
+
// Add the email client to our central widget stack
emailClient = new EmailClient(views);
@@ -98,6 +103,58 @@ void QTMailWindow::setVisible(bool visible)
if (noShow && visible)
return;
+ QPoint p(0, 0);
+ int extraw = 0, extrah = 0, scrn = 0;
+ QWidget* w = 0;
+ if (w)
+ w = w->window();
+ QRect desk;
+ if (w) {
+ scrn = QApplication::desktop()->screenNumber(w);
+ } else if (QApplication::desktop()->isVirtualDesktop()) {
+ scrn = QApplication::desktop()->screenNumber(QCursor::pos());
+ } else {
+ scrn = QApplication::desktop()->screenNumber(this);
+ }
+ desk = QApplication::desktop()->availableGeometry(scrn);
+
+ QWidgetList list = QApplication::topLevelWidgets();
+ for (int i = 0; (extraw == 0 || extrah == 0) && i < list.size(); ++i) {
+ QWidget * current = list.at(i);
+ if (current->isVisible()) {
+ int framew = current->geometry().x() - current->x();
+ int frameh = current->geometry().y() - current->y();
+
+ extraw = qMax(extraw, framew);
+ extrah = qMax(extrah, frameh);
+ }
+ }
+
+ // sanity check for decoration frames. With embedding, we
+ // might get extraordinary values
+ if (extraw == 0 || extrah == 0 || extraw >= 10 || extrah >= 40) {
+ extrah = 40;
+ extraw = 10;
+ }
+
+ p = QPoint(desk.x() + desk.width()/2, desk.y() + desk.height()/2);
+
+ // p = origin of this
+ p = QPoint(p.x()-width()/2 - extraw,
+ p.y()-height()/2 - extrah);
+
+
+ if (p.x() + extraw + width() > desk.x() + desk.width())
+ p.setX(desk.x() + desk.width() - width() - extraw);
+ if (p.x() < desk.x())
+ p.setX(desk.x());
+
+ if (p.y() + extrah + height() > desk.y() + desk.height())
+ p.setY(desk.y() + desk.height() - height() - extrah);
+ if (p.y() < desk.y())
+ p.setY(desk.y());
+
+ move(p);
QWidget::setVisible(visible);
}
@@ -111,6 +168,11 @@ QMenu* QTMailWindow::contextMenu() const
return m_contextMenu;
}
+QToolBar* QTMailWindow::toolBar() const
+{
+ return m_toolBar;
+}
+
QTMailWindow* QTMailWindow::singleton()
{
return self;
diff --git a/src/applications/qtmail/qtmailwindow.h b/src/applications/qtmail/qtmailwindow.h
index d68f4b1a..7841c359 100644
--- a/src/applications/qtmail/qtmailwindow.h
+++ b/src/applications/qtmail/qtmailwindow.h
@@ -21,6 +21,7 @@ class StatusDisplay;
class QStackedWidget;
class EmailClient;
class QMenu;
+class QToolBar;
class QTMailWindow : public QMainWindow
{
@@ -36,8 +37,8 @@ public:
void setVisible(bool visible);
QWidget* currentWidget() const;
-
QMenu* contextMenu() const;
+ QToolBar* toolBar() const;
public slots:
void closeEvent(QCloseEvent *e);
@@ -54,6 +55,7 @@ protected:
private:
QMenu* m_contextMenu;
+ QToolBar* m_toolBar;
};
#endif
diff --git a/src/applications/qtmail/writemail.cpp b/src/applications/qtmail/writemail.cpp
index f37e9b4c..ad326057 100644
--- a/src/applications/qtmail/writemail.cpp
+++ b/src/applications/qtmail/writemail.cpp
@@ -118,7 +118,7 @@ void WriteMail::init()
m_toolbar->addAction(m_draftAction);
m_toolbar->addSeparator();
- setWindowTitle(tr("Composer"));
+ setWindowTitle(tr("Compose"));
}
bool WriteMail::sendStage()
@@ -589,6 +589,31 @@ bool WriteMail::forcedClosure()
return false;
}
+void WriteMail::setVisible(bool visible)
+{
+ if (visible) {
+
+ //center the window on the parent
+ QWidget* w = qobject_cast<QWidget*>(parent());
+
+ QPoint p;
+
+ if (w) {
+ // Use mapToGlobal rather than geometry() in case w might
+ // be embedded in another application
+ QPoint pp = w->mapToGlobal(QPoint(0,0));
+ p = QPoint(pp.x() + w->width()/2,
+ pp.y() + w->height()/ 2);
+ }
+
+ p = QPoint(p.x()-width()/2,
+ p.y()-height()/2);
+
+ move(p);
+ }
+ QWidget::setVisible(visible);
+}
+
bool WriteMail::largeAttachments()
{
static int limit = 0;
diff --git a/src/applications/qtmail/writemail.h b/src/applications/qtmail/writemail.h
index ad68a360..ccb22892 100644
--- a/src/applications/qtmail/writemail.h
+++ b/src/applications/qtmail/writemail.h
@@ -40,6 +40,8 @@ public:
QString composer() const;
bool forcedClosure();
+ void setVisible(bool visible);
+
public slots:
bool saveChangesOnRequest();
bool prepareComposer( QMailMessage::MessageType = QMailMessage::AnyType);
diff --git a/src/libraries/messageserver/qmailauthenticator.cpp b/src/libraries/messageserver/qmailauthenticator.cpp
index e0354069..4499c3a9 100644
--- a/src/libraries/messageserver/qmailauthenticator.cpp
+++ b/src/libraries/messageserver/qmailauthenticator.cpp
@@ -13,7 +13,6 @@
/*!
\class QMailAuthenticator
- \inpublicgroup QtMessagingModule
\ingroup libmessageserver
\preliminary
diff --git a/src/libraries/messageserver/qmailmessageclassifier.cpp b/src/libraries/messageserver/qmailmessageclassifier.cpp
index 5e41839e..9b7ccabf 100644
--- a/src/libraries/messageserver/qmailmessageclassifier.cpp
+++ b/src/libraries/messageserver/qmailmessageclassifier.cpp
@@ -15,7 +15,6 @@
/*!
\class QMailMessageClassifier
- \inpublicgroup QtMessagingModule
\ingroup libmessageserver
\preliminary
diff --git a/src/libraries/messageserver/qmailmessageservice.cpp b/src/libraries/messageserver/qmailmessageservice.cpp
index 47e604f0..81244442 100644
--- a/src/libraries/messageserver/qmailmessageservice.cpp
+++ b/src/libraries/messageserver/qmailmessageservice.cpp
@@ -62,7 +62,6 @@ QMailMessageServicePlugin *mapping(const QString &key)
/*!
\class QMailMessageServiceFactory
- \inpublicgroup QtMessagingModule
\ingroup libmessageserver
\brief The QMailMessageServiceFactory class creates objects implementing the QMailMessageService interface.
@@ -153,7 +152,6 @@ QMailMessageServiceConfigurator *QMailMessageServiceFactory::createServiceConfig
/*!
\class QMailMessageServicePluginInterface
- \inpublicgroup QtMessagingModule
\ingroup libmessageserver
\brief The QMailMessageServicePluginInterface class defines the interface to plugins that provide messaging services.
@@ -199,7 +197,6 @@ QMailMessageServiceConfigurator *QMailMessageServicePluginInterface::createServi
/*!
\class QMailMessageServicePlugin
- \inpublicgroup QtMessagingModule
\ingroup libmessageserver
\brief The QMailMessageServicePlugin class defines a base class for implementing messaging service plugins.
@@ -361,7 +358,6 @@ QMailMessageSourcePrivate::QMailMessageSourcePrivate(QMailMessageService *servic
/*!
\class QMailMessageSource
- \inpublicgroup QtMessagingModule
\ingroup libmessageserver
\brief The QMailMessageSource class defines the interface to objects that provide access to externally sourced
@@ -403,9 +399,16 @@ QMailStore::MessageRemovalOption QMailMessageSource::messageRemovalOption() cons
/*!
Invoked by the message server to initiate a folder listing operation.
- Retrieve folders available for the account \a accountId; if \a folderId is valid, folders
- within that folder should be retieved, otherwise in the root folder of the account.
- If \a descending is true, also retrieve folders located by descending the folder hierarchy.
+ Retrieve the set of folders available for the account \a accountId.
+ If \a folderId is valid, only the identified folder is searched for child folders;
+ otherwise the search begins at the root of the account. If \a descending is true,
+ the search should also recursively search for child folders within folders
+ discovered during the search.
+
+ The QMailFolder::serverCount(), QMailFolder::serverUnreadCount() and
+ QMailFolder::serverUndiscoveredCount() properties should be updated for each
+ folder that is searched for child folders; these properties need not be updated
+ for folders that are merely discovered by searching.
Return true if an operation is initiated.
@@ -424,17 +427,26 @@ bool QMailMessageSource::retrieveFolderList(const QMailAccountId &accountId, con
/*!
Invoked by the message server to initiate a message listing operation.
- Retrieve messages available for the account \a accountId;
- if \a folderId is valid, then only messages within that folder should be retrieved; otherwise
- messages within all folders in the account should be retrieved. If a folder messages are being
- retrieved from contains at least \a minimum messages then the messageserver should ensure that at
- least \a minimum messages are available from the mail store for that folder; otherwise if the
- folder contains less than \a minimum messages the messageserver should ensure all the messages for
- that folder are available from the mail store.
+ Retrieve the list of messages available for the account \a accountId.
+ If \a folderId is valid, then only messages within that folder should be retrieved; otherwise
+ messages within all folders in the account should be retrieved. If \a minimum is non-zero,
+ then that value will be used to restrict the number of messages to be retrieved from
+ each folder; otherwise, all messages will be retrieved.
+
+ If \a sort is not empty, reported the discovered messages in the ordering indicated by the
+ sort criterion, if possible. Message sources are not required to support this facility.
+
+ If a folder messages are being retrieved from contains at least \a minimum messages then the
+ messageserver should ensure that at least \a minimum messages are available from the mail
+ store for that folder; otherwise if the folder contains less than \a minimum messages the
+ messageserver should ensure all the messages for that folder are available from the mail store.
+ If a folder has messages locally available, then all previously undiscovered messages should be
+ retrieved for that folder, even if that number exceeds \a minimum.
+
+ The QMailFolder::serverCount(), QMailFolder::serverUnreadCount() and
+ QMailFolder::serverUndiscoveredCount() properties should be updated for each folder
+ from which messages are retrieved.
- If \a sort is not empty, messages should be discovered by locating messages in the
- ordering indicated by the sort criterion, if possible.
-
New messages should be added to the mail store in meta data form as they are discovered,
and marked with the \l QMailMessage::New status flag. Messages that are present
in the mail store but found to be no longer available should be marked with the
@@ -470,6 +482,10 @@ bool QMailMessageSource::retrieveMessageList(const QMailAccountId &accountId, co
If \a spec is \l QMailRetrievalAction::Content, then the message server should
retrieve the entirety of each message listed in \a ids.
+
+ The QMailFolder::serverCount(), QMailFolder::serverUnreadCount() and
+ QMailFolder::serverUndiscoveredCount() properties should be updated for each folder
+ from which messages are retrieved.
Return true if an operation is initiated.
*/
@@ -486,6 +502,10 @@ bool QMailMessageSource::retrieveMessages(const QMailMessageIdList &ids, QMailRe
Invoked by the message server to initiate a message part retrieval operation.
Retrieve the content of the message part indicated by the location \a partLocation.
+
+ The QMailFolder::serverCount(), QMailFolder::serverUnreadCount() and
+ QMailFolder::serverUndiscoveredCount() properties should be updated for the folder
+ from which the part is retrieved.
Return true if an operation is initiated.
*/
@@ -503,6 +523,10 @@ bool QMailMessageSource::retrieveMessagePart(const QMailMessagePart::Location &p
Retrieve a portion of the content of the message identified by \a messageId, ensuring
that at least \a minimum bytes are available in the mail store.
+ The QMailFolder::serverCount(), QMailFolder::serverUnreadCount() and
+ QMailFolder::serverUndiscoveredCount() properties should be updated for the folder
+ from which the message is retrieved.
+
Return true if an operation is initiated.
*/
bool QMailMessageSource::retrieveMessageRange(const QMailMessageId &messageId, uint minimum)
@@ -520,6 +544,10 @@ bool QMailMessageSource::retrieveMessageRange(const QMailMessageId &messageId, u
Retrieve a portion of the content of the message part indicated by the location
\a partLocation, ensuring that at least \a minimum bytes are available in the mail store.
+ The QMailFolder::serverCount(), QMailFolder::serverUnreadCount() and
+ QMailFolder::serverUndiscoveredCount() properties should be updated for the folder
+ from which the part is retrieved.
+
Return true if an operation is initiated.
*/
bool QMailMessageSource::retrieveMessagePartRange(const QMailMessagePart::Location &partLocation, uint minimum)
@@ -536,6 +564,16 @@ bool QMailMessageSource::retrieveMessagePartRange(const QMailMessagePart::Locati
Retrieve all folders and meta data for all messages available for the account \a accountId.
+ All folders within the account should be discovered and searched for child folders.
+ The QMailFolder::serverCount(), QMailFolder::serverUnreadCount() and
+ QMailFolder::serverUndiscoveredCount() properties should be updated for each folder
+ in the account.
+
+ New messages should be added to the mail store in meta data form as they are discovered,
+ and marked with the \l QMailMessage::New status flag. Messages that are present
+ in the mail store but found to be no longer available should be marked with the
+ \l QMailMessage::Removed status flag.
+
Return true if an operation is initiated.
\sa retrieveFolderList(), retrieveMessageList(), synchronize()
@@ -574,6 +612,15 @@ bool QMailMessageSource::exportUpdates(const QMailAccountId &accountId)
Newly discovered messages should have their meta data retrieved,
and local changes to message status should be exported to the external server.
+ New messages should be added to the mail store in meta data form as they are discovered,
+ and marked with the \l QMailMessage::New status flag. Messages that are present
+ in the mail store but found to be no longer available should be marked with the
+ \l QMailMessage::Removed status flag.
+
+ The folder structure of the account should be synchronized with that available from
+ the external service. The QMailFolder::serverCount(), QMailFolder::serverUnreadCount() and
+ QMailFolder::serverUndiscoveredCount() properties should be updated for each folder.
+
Return true if an operation is initiated.
\sa retrieveAll(), exportUpdates()
@@ -878,7 +925,6 @@ QMailMessageSinkPrivate::QMailMessageSinkPrivate(QMailMessageService *service)
/*!
\class QMailMessageSink
- \inpublicgroup QtMessagingModule
\ingroup libmessageserver
\brief The QMailMessageSink class defines the interface to objects that provide external message transmission
@@ -939,7 +985,6 @@ void QMailMessageSink::notImplemented()
/*!
\class QMailMessageService
- \inpublicgroup QtMessagingModule
\ingroup libmessageserver
\preliminary
@@ -955,6 +1000,12 @@ void QMailMessageSink::notImplemented()
information about the actions of messaging service components. It also provides the
\l{QMailMessageService::source()}{source} and \l{QMailMessageService::sink()}{sink} functions that
the message server uses to acquire access to the functionality that the service may implement.
+
+ Subclasses of QMailMessageService are instantiated by the message server process, one for each
+ enabled account that is configured to use that service. The QMailMessageService interface does
+ not cater for concurrent actions; each instance may only service a single request at any given
+ time. The message server process provides request queueing so that QMailMessageService objects
+ see only a sequential series of requests.
*/
/*!
@@ -1114,6 +1165,9 @@ void QMailMessageService::updateStatus(int code, const QString &text, const QMai
} else {
static ErrorMap socketErrorMap(socketErrorInit());
+ // Code has been offset by +2 on transmit to normalise range
+ code -= 2;
+
// See if we can convert the error code into a system error message
QString message(text);
decorate(&message, code, (ErrorSet() << socketErrorMap));
@@ -1125,7 +1179,6 @@ void QMailMessageService::updateStatus(int code, const QString &text, const QMai
/*!
\class QMailMessageServiceEditor
- \inpublicgroup QtMessagingModule
\ingroup libmessageserver
\preliminary
@@ -1159,7 +1212,6 @@ QMailMessageServiceEditor::~QMailMessageServiceEditor()
/*!
\class QMailMessageServiceConfigurator
- \inpublicgroup QtMessagingModule
\ingroup libmessageserver
\preliminary
diff --git a/src/libraries/messageserver/qmailserviceconfiguration.cpp b/src/libraries/messageserver/qmailserviceconfiguration.cpp
index 8058090f..a8a5f1c4 100644
--- a/src/libraries/messageserver/qmailserviceconfiguration.cpp
+++ b/src/libraries/messageserver/qmailserviceconfiguration.cpp
@@ -14,7 +14,6 @@
/*!
\class QMailServiceConfiguration
- \inpublicgroup QtMessagingModule
\ingroup libmessageserver
\preliminary
diff --git a/src/libraries/messageserver/qmailstoreaccountfilter.cpp b/src/libraries/messageserver/qmailstoreaccountfilter.cpp
index 1a574ea4..01bdeb1c 100644
--- a/src/libraries/messageserver/qmailstoreaccountfilter.cpp
+++ b/src/libraries/messageserver/qmailstoreaccountfilter.cpp
@@ -366,7 +366,6 @@ void QMailStoreAccountFilterPrivate::incrementConnectionCount(const char *signal
/*!
\class QMailStoreAccountFilter
- \inpublicgroup QtMessagingModule
\ingroup libmessageserver
\preliminary
diff --git a/src/libraries/messageserver/qmailtransport.cpp b/src/libraries/messageserver/qmailtransport.cpp
index 44ca4592..9aa41100 100644
--- a/src/libraries/messageserver/qmailtransport.cpp
+++ b/src/libraries/messageserver/qmailtransport.cpp
@@ -90,7 +90,6 @@ qint64 QMailTransport::Socket::bytesSinceMark() const
/*!
\class QMailTransport
- \inpublicgroup QtMessagingModule
\ingroup libmessageserver
\preliminary
@@ -410,8 +409,11 @@ void QMailTransport::errorHandling(int status, QString msg)
mConnected = false;
mInUse = false;
mSocket->abort();
+
emit updateStatus(tr("Error occurred"));
- emit errorOccurred(status, msg);
+
+ // Socket errors run from -1; offset this value by +2
+ emit errorOccurred(status + 2, msg);
}
/*! \internal */
diff --git a/src/libraries/qmfutil/qmailcomposer.cpp b/src/libraries/qmfutil/qmailcomposer.cpp
index 4d49da2a..dd4c3a0c 100644
--- a/src/libraries/qmfutil/qmailcomposer.cpp
+++ b/src/libraries/qmfutil/qmailcomposer.cpp
@@ -57,7 +57,6 @@ static QMailComposerInterface* mapping(const QString& key)
/*!
\class QMailComposerInterface
- \inpublicgroup QtMessagingModule
\ingroup qmfutil
\brief The QMailComposerInterface class defines the interface to objects that can compose a mail message.
@@ -280,7 +279,6 @@ QString QMailComposerInterface::status() const
/*!
\class QMailComposerFactory
- \inpublicgroup QtMessagingModule
\ingroup qmfutil
\brief The QMailComposerFactory class creates objects implementing the QMailComposerInterface interface.
diff --git a/src/libraries/qmfutil/qmailmessagedelegate.cpp b/src/libraries/qmfutil/qmailmessagedelegate.cpp
index c3d72665..1baabd97 100644
--- a/src/libraries/qmfutil/qmailmessagedelegate.cpp
+++ b/src/libraries/qmfutil/qmailmessagedelegate.cpp
@@ -109,7 +109,6 @@ public:
/*!
\class QMailMessageDelegate
- \inpublicgroup QtMessagingModule
\ingroup qmfutil
\preliminary
@@ -387,7 +386,6 @@ public:
/*!
\class QtopiaHomeMailMessageDelegate
- \inpublicgroup QtMessagingModule
\ingroup qmfutil
\preliminary
diff --git a/src/libraries/qmfutil/qmailviewer.cpp b/src/libraries/qmfutil/qmailviewer.cpp
index e4d1cc8d..222fc96c 100644
--- a/src/libraries/qmfutil/qmailviewer.cpp
+++ b/src/libraries/qmfutil/qmailviewer.cpp
@@ -54,7 +54,6 @@ static QMailViewerInterface* mapping(const QString& key)
/*!
\class QMailViewerInterface
- \inpublicgroup QtMessagingModule
\ingroup qmfutil
\brief The QMailViewerInterface class defines the interface to objects that can display a mail message.
@@ -275,7 +274,6 @@ void QMailViewerInterface::setResource(const QUrl& name, QVariant value)
/*!
\class QMailViewerFactory
- \inpublicgroup QtMessagingModule
\ingroup qmfutil
\brief The QMailViewerFactory class creates objects implementing the QMailViewerInterface interface.
diff --git a/src/libraries/qtopiamail/CHANGES.qdoc b/src/libraries/qtopiamail/CHANGES.qdoc
index 25cc0356..1d975061 100644
--- a/src/libraries/qtopiamail/CHANGES.qdoc
+++ b/src/libraries/qtopiamail/CHANGES.qdoc
@@ -13,6 +13,19 @@ Changes since the development preview release on 03/04/09:
1. Added 'QMailFolder::serverUndiscoveredCount() const' and
'QMailFolder::setServerUndiscoveredCount()'.
+2. Added 'QMailStore::retrievalInProgress()',
+ 'QMailStore::setRetrievalInProgress()',
+ 'QMailStore::transmissionInProgress()' and
+ 'QMailStore::setTransmissionInProgress()'.
+
+3. Replaced 'QMailStore::initialized() const' and
+ 'QMailStore::storeInitialized()' with
+ 'QMailStore::InitializationState QMailStore::initializationState()'.
+
+4. Changed 'QMailMessageKey::status(...)',
+ 'QMailFolderKey::status(...)' and
+ 'QMailMessageKey::status(...)' so that the overload taking a QMailDataComparator::InclusionComparator has the default argument.
+
*****************************************************************************
diff --git a/src/libraries/qtopiamail/qmailaccount.cpp b/src/libraries/qtopiamail/qmailaccount.cpp
index d784070a..22696965 100644
--- a/src/libraries/qtopiamail/qmailaccount.cpp
+++ b/src/libraries/qtopiamail/qmailaccount.cpp
@@ -132,7 +132,6 @@ private:
/*!
\class QMailAccount
- \inpublicgroup QtMessagingModule
\preliminary
\ingroup messaginglibrary
diff --git a/src/libraries/qtopiamail/qmailaccountconfiguration.cpp b/src/libraries/qtopiamail/qmailaccountconfiguration.cpp
index d8894be2..ad903fce 100644
--- a/src/libraries/qtopiamail/qmailaccountconfiguration.cpp
+++ b/src/libraries/qtopiamail/qmailaccountconfiguration.cpp
@@ -74,7 +74,6 @@ private:
/*!
\class QMailAccountConfiguration::ServiceConfiguration
- \inpublicgroup QtMessagingModule
\preliminary
\brief The ServiceConfiguration class provides access to the configuration parameters
@@ -227,7 +226,6 @@ QMailAccountConfiguration::ServiceConfiguration &QMailAccountConfigurationPrivat
/*!
\class QMailAccountConfiguration
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailAccountConfiguration class contains the configuration parameters of an account.
diff --git a/src/libraries/qtopiamail/qmailaccountkey.cpp b/src/libraries/qtopiamail/qmailaccountkey.cpp
index c309e830..29310c54 100644
--- a/src/libraries/qtopiamail/qmailaccountkey.cpp
+++ b/src/libraries/qtopiamail/qmailaccountkey.cpp
@@ -17,7 +17,6 @@ using namespace QMailDataComparator;
/*!
\class QMailAccountKey
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailAccountKey class defines the parameters used for querying a subset of
diff --git a/src/libraries/qtopiamail/qmailaccountkey.h b/src/libraries/qtopiamail/qmailaccountkey.h
index 8ea46771..208188fa 100644
--- a/src/libraries/qtopiamail/qmailaccountkey.h
+++ b/src/libraries/qtopiamail/qmailaccountkey.h
@@ -89,8 +89,8 @@ public:
static QMailAccountKey fromAddress(const QString &value, QMailDataComparator::EqualityComparator cmp = QMailDataComparator::Equal);
static QMailAccountKey fromAddress(const QString &value, QMailDataComparator::InclusionComparator cmp);
- static QMailAccountKey status(quint64 mask, QMailDataComparator::EqualityComparator cmp = QMailDataComparator::Equal);
- static QMailAccountKey status(quint64 mask, QMailDataComparator::InclusionComparator cmp);
+ static QMailAccountKey status(quint64 mask, QMailDataComparator::InclusionComparator cmp = QMailDataComparator::Includes);
+ static QMailAccountKey status(quint64 mask, QMailDataComparator::EqualityComparator cmp);
static QMailAccountKey customField(const QString &name, QMailDataComparator::PresenceComparator cmp = QMailDataComparator::Present);
static QMailAccountKey customField(const QString &name, const QString &value, QMailDataComparator::EqualityComparator cmp = QMailDataComparator::Equal);
diff --git a/src/libraries/qtopiamail/qmailaccountlistmodel.cpp b/src/libraries/qtopiamail/qmailaccountlistmodel.cpp
index 9fe8bc5a..ca8fbfe3 100644
--- a/src/libraries/qtopiamail/qmailaccountlistmodel.cpp
+++ b/src/libraries/qtopiamail/qmailaccountlistmodel.cpp
@@ -124,7 +124,6 @@ QMailAccountIdList::iterator QMailAccountListModelPrivate::lowerBound(const QMai
/*!
\class QMailAccountListModel
- \inpublicgroup QtMessagingModule
\preliminary
\ingroup messaginglibrary
diff --git a/src/libraries/qtopiamail/qmailaccountsortkey.cpp b/src/libraries/qtopiamail/qmailaccountsortkey.cpp
index 4c836050..900f01c7 100644
--- a/src/libraries/qtopiamail/qmailaccountsortkey.cpp
+++ b/src/libraries/qtopiamail/qmailaccountsortkey.cpp
@@ -13,7 +13,6 @@
/*!
\class QMailAccountSortKey
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailAccountSortKey class defines the parameters used for sorting a subset of
diff --git a/src/libraries/qtopiamail/qmailaddress.cpp b/src/libraries/qtopiamail/qmailaddress.cpp
index 83db7913..3fdaf0ae 100644
--- a/src/libraries/qtopiamail/qmailaddress.cpp
+++ b/src/libraries/qtopiamail/qmailaddress.cpp
@@ -764,7 +764,6 @@ void QMailAddressPrivate::deserialize(Stream &stream)
/*!
\class QMailAddress
- \inpublicgroup QtMessagingModule
\brief The QMailAddress class provides an interface for manipulating message address strings.
\ingroup messaginglibrary
diff --git a/src/libraries/qtopiamail/qmailcodec.cpp b/src/libraries/qtopiamail/qmailcodec.cpp
index 7ce84e24..2066a08d 100644
--- a/src/libraries/qtopiamail/qmailcodec.cpp
+++ b/src/libraries/qtopiamail/qmailcodec.cpp
@@ -25,7 +25,6 @@ int QTOPIAMAIL_EXPORT QuotedPrintableMaxLineLength = 74;
/*!
\class QMailCodec
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailCodec class provides mechanisms for encoding and decoding between 7-bit ASCII strings
@@ -363,7 +362,6 @@ static inline unsigned char base64Index(const char ascii)
/*!
\class QMailBase64Codec
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailBase64Codec class encodes or decodes between 8-bit data and 7-bit ASCII, using the Base64
@@ -663,7 +661,6 @@ static inline unsigned char decodeCharacter(unsigned char value)
/*!
\class QMailQuotedPrintableCodec
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailQuotedPrintableCodec class encodes or decodes between 8-bit data and 7-bit ASCII,
@@ -935,7 +932,6 @@ static void writeStream(QDataStream& out, const char* it, int length)
/*!
\class QMailPassThroughCodec
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailPassThroughCodec class uses the QMailCodec interface to move data between streams
@@ -989,7 +985,6 @@ void QMailPassThroughCodec::decodeChunk(QDataStream& out, const char* it, int le
/*!
\class QMailLineEndingCodec
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailLineEndingCodec class encodes textual data to use CR/LF line endings required for SMTP transmission.
diff --git a/src/libraries/qtopiamail/qmailcontentmanager.cpp b/src/libraries/qtopiamail/qmailcontentmanager.cpp
index 3bd453f8..0e44b0af 100644
--- a/src/libraries/qtopiamail/qmailcontentmanager.cpp
+++ b/src/libraries/qtopiamail/qmailcontentmanager.cpp
@@ -53,7 +53,6 @@ QMailContentManager *mapping(const QString &scheme)
/*!
\class QMailContentManagerFactory
- \inpublicgroup QtMessagingModule
\brief The QMailContentManagerFactory class creates objects implementing the QMailContentManager interface.
\ingroup messaginglibrary
@@ -125,7 +124,6 @@ void QMailContentManagerFactory::clearContent()
/*!
\class QMailContentManagerPluginInterface
- \inpublicgroup QtMessagingModule
\brief The QMailContentManagerPluginInterface class defines the interface to plugins that provide message content management facilities.
\ingroup messaginglibrary
@@ -151,7 +149,6 @@ void QMailContentManagerFactory::clearContent()
/*!
\class QMailContentManagerPlugin
- \inpublicgroup QtMessagingModule
\brief The QMailContentManagerPlugin class defines a base class for implementing message content manager plugins.
\ingroup messaginglibrary
@@ -188,7 +185,6 @@ QStringList QMailContentManagerPlugin::keys() const
/*!
\class QMailContentManager
- \inpublicgroup QtMessagingModule
\brief The QMailContentManager class defines the interface to objects that provide a storage facility for message content.
\ingroup messaginglibrary
diff --git a/src/libraries/qtopiamail/qmaildatacomparator.cpp b/src/libraries/qtopiamail/qmaildatacomparator.cpp
index 10825958..4cf3fc7d 100644
--- a/src/libraries/qtopiamail/qmaildatacomparator.cpp
+++ b/src/libraries/qtopiamail/qmaildatacomparator.cpp
@@ -10,7 +10,6 @@
/*!
\namespace QMailDataComparator
- \inpublicgroup QtMessagingModule
\ingroup messaginglibrary
\brief The QMailDataComparator namespace contains types used in specifying the comparison
diff --git a/src/libraries/qtopiamail/qmailfolder.cpp b/src/libraries/qtopiamail/qmailfolder.cpp
index 9c386e00..3cda844f 100644
--- a/src/libraries/qtopiamail/qmailfolder.cpp
+++ b/src/libraries/qtopiamail/qmailfolder.cpp
@@ -107,7 +107,6 @@ private:
/*!
\class QMailFolder
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailFolder class represents a folder for mail messages in the mail store.
diff --git a/src/libraries/qtopiamail/qmailfolderkey.cpp b/src/libraries/qtopiamail/qmailfolderkey.cpp
index c60df4b3..a60c506e 100644
--- a/src/libraries/qtopiamail/qmailfolderkey.cpp
+++ b/src/libraries/qtopiamail/qmailfolderkey.cpp
@@ -18,7 +18,6 @@ using namespace QMailKey;
/*!
\class QMailFolderKey
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailFolderKey class defines the parameters used for querying a subset of
diff --git a/src/libraries/qtopiamail/qmailfolderkey.h b/src/libraries/qtopiamail/qmailfolderkey.h
index 6993ca05..79e38d53 100644
--- a/src/libraries/qtopiamail/qmailfolderkey.h
+++ b/src/libraries/qtopiamail/qmailfolderkey.h
@@ -100,8 +100,8 @@ public:
static QMailFolderKey displayName(const QString &value, QMailDataComparator::InclusionComparator cmp);
static QMailFolderKey displayName(const QStringList &values, QMailDataComparator::InclusionComparator cmp = QMailDataComparator::Includes);
- static QMailFolderKey status(quint64 mask, QMailDataComparator::EqualityComparator cmp = QMailDataComparator::Equal);
- static QMailFolderKey status(quint64 mask, QMailDataComparator::InclusionComparator cmp);
+ static QMailFolderKey status(quint64 mask, QMailDataComparator::InclusionComparator cmp = QMailDataComparator::Includes);
+ static QMailFolderKey status(quint64 mask, QMailDataComparator::EqualityComparator cmp);
static QMailFolderKey ancestorFolderIds(const QMailFolderId &id, QMailDataComparator::InclusionComparator cmp = QMailDataComparator::Includes);
static QMailFolderKey ancestorFolderIds(const QMailFolderIdList &ids, QMailDataComparator::InclusionComparator cmp = QMailDataComparator::Includes);
diff --git a/src/libraries/qtopiamail/qmailfoldersortkey.cpp b/src/libraries/qtopiamail/qmailfoldersortkey.cpp
index a38d5730..7dcc03c2 100644
--- a/src/libraries/qtopiamail/qmailfoldersortkey.cpp
+++ b/src/libraries/qtopiamail/qmailfoldersortkey.cpp
@@ -14,7 +14,6 @@
/*!
\class QMailFolderSortKey
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailFolderSortKey class defines the parameters used for sorting a subset of
diff --git a/src/libraries/qtopiamail/qmailid.cpp b/src/libraries/qtopiamail/qmailid.cpp
index 201ca86d..ce5f6013 100644
--- a/src/libraries/qtopiamail/qmailid.cpp
+++ b/src/libraries/qtopiamail/qmailid.cpp
@@ -95,7 +95,6 @@ QTextStream& operator<< (QTextStream& s, const MailId &id)
/*!
\class QMailAccountId
- \inpublicgroup QtMessagingModule
\ingroup messaginglibrary
\preliminary
@@ -234,7 +233,6 @@ Q_IMPLEMENT_USER_METATYPE_TYPEDEF(QMailAccountIdList, QMailAccountIdList)
/*!
\class QMailFolderId
- \inpublicgroup QtMessagingModule
\ingroup messaginglibrary
\preliminary
@@ -373,7 +371,6 @@ Q_IMPLEMENT_USER_METATYPE_TYPEDEF(QMailFolderIdList, QMailFolderIdList)
/*!
\class QMailMessageId
- \inpublicgroup QtMessagingModule
\ingroup messaginglibrary
\preliminary
diff --git a/src/libraries/qtopiamail/qmailkeyargument.cpp b/src/libraries/qtopiamail/qmailkeyargument.cpp
index b0666d76..a8a975da 100644
--- a/src/libraries/qtopiamail/qmailkeyargument.cpp
+++ b/src/libraries/qtopiamail/qmailkeyargument.cpp
@@ -10,7 +10,6 @@
/*!
\class QMailKeyArgument
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailKeyArgument class template defines a class representing a single criterion
@@ -63,7 +62,6 @@
/*!
\class QMailKeyArgument::ValueList
- \inpublicgroup QtMessagingModule
\ingroup messaginglibrary
\brief The ValueList class provides a list of variant values that can be serialized to a stream, and compared.
diff --git a/src/libraries/qtopiamail/qmailmessage.cpp b/src/libraries/qtopiamail/qmailmessage.cpp
index 97545589..cbabce7c 100644
--- a/src/libraries/qtopiamail/qmailmessage.cpp
+++ b/src/libraries/qtopiamail/qmailmessage.cpp
@@ -1456,7 +1456,6 @@ template class QPrivatelyImplemented<QMailMessageHeaderFieldPrivate>;
/*!
\class QMailMessageHeaderField
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailMessageHeaderField class encapsulates the parsing of message header fields.
@@ -1772,7 +1771,6 @@ void QMailMessageHeaderField::deserialize(Stream &stream)
/*!
\class QMailMessageContentType
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailMessageContentType class encapsulates the parsing of the RFC 2822
@@ -1966,7 +1964,6 @@ void QMailMessageContentType::setCharset(const QByteArray& charset)
/*!
\class QMailMessageContentDisposition
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailMessageContentDisposition class encapsulates the parsing of the RFC 2822
@@ -2366,7 +2363,6 @@ template class QPrivatelyImplemented<QMailMessageHeaderPrivate>;
/*!
\class QMailMessageHeader
- \inpublicgroup QtMessagingModule
\internal
*/
@@ -2821,7 +2817,6 @@ template class QPrivatelyImplemented<QMailMessageBodyPrivate>;
/*!
\class QMailMessageBody
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailMessageBody class contains the body element of a message or message part.
@@ -3853,7 +3848,6 @@ template class QPrivatelyImplemented<QMailMessagePartContainerPrivate>;
/*!
\class QMailMessagePartContainer
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailMessagePartContainer class provides access to a collection of message parts.
@@ -4398,7 +4392,6 @@ QMailMessagePartContainerPrivate* QMailMessagePartContainerPrivate::privatePoint
/*!
\class QMailMessagePart
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailMessagePart class provides a convenient interface for working
@@ -4425,7 +4418,6 @@ QMailMessagePartContainerPrivate* QMailMessagePartContainerPrivate::privatePoint
/*!
\class QMailMessagePart::Location
- \inpublicgroup QtMessagingModule
\preliminary
\brief The Location class contains a specification of the location of a message part
@@ -5459,7 +5451,6 @@ template class QPrivatelyImplemented<QMailMessageMetaDataPrivate>;
/*!
\class QMailMessageMetaData
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailMessageMetaData class provides information about a message stored by Qtopia.
@@ -6451,7 +6442,6 @@ void QMailMessagePrivate::deserialize(Stream &stream)
/*!
\class QMailMessage
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailMessage class provides a convenient interface for working with messages.
diff --git a/src/libraries/qtopiamail/qmailmessagefwd.cpp b/src/libraries/qtopiamail/qmailmessagefwd.cpp
index 9c5cdd1c..f9f2aa9e 100644
--- a/src/libraries/qtopiamail/qmailmessagefwd.cpp
+++ b/src/libraries/qtopiamail/qmailmessagefwd.cpp
@@ -8,12 +8,6 @@
**
****************************************************************************/
-/*
- TODO: Do we need these?
- \inpublicgroup QtMessagingModule
- \ingroup messaginglibrary
-*/
-
/*!
\class QMailMessageHeaderFieldFwd
\preliminary
diff --git a/src/libraries/qtopiamail/qmailmessagekey.cpp b/src/libraries/qtopiamail/qmailmessagekey.cpp
index b9a771a2..6137a5b3 100644
--- a/src/libraries/qtopiamail/qmailmessagekey.cpp
+++ b/src/libraries/qtopiamail/qmailmessagekey.cpp
@@ -25,7 +25,6 @@ using namespace QMailKey;
/*!
\class QMailMessageKey
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailMessageKey class defines the parameters used for querying a subset of
@@ -593,6 +592,14 @@ QMailMessageKey QMailMessageKey::serverUid(const QString &uid, QMailDataComparat
*/
QMailMessageKey QMailMessageKey::serverUid(const QStringList &uids, QMailDataComparator::InclusionComparator cmp)
{
+#ifndef USE_ALTERNATE_MAILSTORE_IMPLEMENTATION
+ if (uids.count() >= IdLookupThreshold) {
+ // If there are a large number of UIDs, they will be inserted into a temporary table
+ // with a uniqueness constraint; ensure only unique values are supplied
+ return QMailMessageKey(uids.toSet().toList(), ServerUid, QMailKey::comparator(cmp));
+ }
+#endif
+
return QMailMessageKey(uids, ServerUid, QMailKey::comparator(cmp));
}
diff --git a/src/libraries/qtopiamail/qmailmessagekey.h b/src/libraries/qtopiamail/qmailmessagekey.h
index 600a0fd0..85c13b2e 100644
--- a/src/libraries/qtopiamail/qmailmessagekey.h
+++ b/src/libraries/qtopiamail/qmailmessagekey.h
@@ -122,8 +122,8 @@ public:
static QMailMessageKey receptionTimeStamp(const QDateTime &value, QMailDataComparator::EqualityComparator cmp = QMailDataComparator::Equal);
static QMailMessageKey receptionTimeStamp(const QDateTime &value, QMailDataComparator::RelationComparator cmp);
- static QMailMessageKey status(quint64 mask, QMailDataComparator::EqualityComparator cmp = QMailDataComparator::Equal);
- static QMailMessageKey status(quint64 mask, QMailDataComparator::InclusionComparator cmp);
+ static QMailMessageKey status(quint64 mask, QMailDataComparator::InclusionComparator cmp = QMailDataComparator::Includes);
+ static QMailMessageKey status(quint64 mask, QMailDataComparator::EqualityComparator cmp);
static QMailMessageKey serverUid(const QString &uid, QMailDataComparator::EqualityComparator cmp = QMailDataComparator::Equal);
static QMailMessageKey serverUid(const QString &uid, QMailDataComparator::InclusionComparator cmp);
diff --git a/src/libraries/qtopiamail/qmailmessagelistmodel.cpp b/src/libraries/qtopiamail/qmailmessagelistmodel.cpp
index f5929678..1b0c8e55 100644
--- a/src/libraries/qtopiamail/qmailmessagelistmodel.cpp
+++ b/src/libraries/qtopiamail/qmailmessagelistmodel.cpp
@@ -498,7 +498,6 @@ QList<QMailMessageListModelPrivate::LocationSequence> QMailMessageListModelPriva
/*!
\class QMailMessageListModel
- \inpublicgroup QtMessagingModule
\preliminary
\ingroup messaginglibrary
diff --git a/src/libraries/qtopiamail/qmailmessageremovalrecord.cpp b/src/libraries/qtopiamail/qmailmessageremovalrecord.cpp
index 087770b3..d2749efe 100644
--- a/src/libraries/qtopiamail/qmailmessageremovalrecord.cpp
+++ b/src/libraries/qtopiamail/qmailmessageremovalrecord.cpp
@@ -34,7 +34,6 @@ public:
/*!
\class QMailMessageRemovalRecord
- \inpublicgroup QtMessagingModule
\preliminary
\ingroup messaginglibrary
diff --git a/src/libraries/qtopiamail/qmailmessageserver.cpp b/src/libraries/qtopiamail/qmailmessageserver.cpp
index 6498976d..20c56c57 100644
--- a/src/libraries/qtopiamail/qmailmessageserver.cpp
+++ b/src/libraries/qtopiamail/qmailmessageserver.cpp
@@ -154,7 +154,6 @@ QMailMessageServerPrivate::~QMailMessageServerPrivate()
/*!
\class QMailMessageServer
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailMessageServer class provides signals and slots which implement a convenient
@@ -174,10 +173,6 @@ QMailMessageServerPrivate::~QMailMessageServerPrivate()
For most messaging client applications, the QMailServiceAction objects offer a simpler
interface for requesting actions from the messageserver, and assessing their results.
- Note: the functions performed by the message server and the interface to them provided
- by the QMailMessageServer class are expected to change in a future release of Qt Extended,
- to provide a finer-grained interface for communicating with external services.
-
\section1 New Messages
When a client initiates communication with the MessageServer, the server informs the
@@ -192,44 +187,22 @@ QMailMessageServerPrivate::~QMailMessageServerPrivate()
To send messages, the client should construct instances of the QMailMessage class
formulated to contain the desired content. These messages should be stored to the
- mail store, then submitted for transmission by their QMailMessageId values, via the send()
- slot. The MessageServer will determine how to transmit each message by inspecting
- the account associated with the message.
-
- If the MessageServer application succeeds in sending a message, the messageSent()
- signal is emitted to notify the client. After transmission has been attempted for
- each message in the list, the sendCompleted() signal is emitted; any messages
- for which a messageSent() signal was not emitted were not successfully transmitted.
+ mail store, within the Outbox folder configured for the parent account.
- After a send operation is initiated, the MessageServer emits the sendTotal() signal
- to indicate the approximate extent of the transmission effort. As progress is made
- in performing the transmission operation, the sendProgress() signal is repeatedly
- emitted to report the progress toward completion of the operation.
+ An instance of QMailTransmitAction should be used to request transmission of the
+ outgoing messages.
\section1 Retrieving Messages
- TODO
-
- \section2 Folder Retrieval
-
- It is possible to retrieve only the folder structure of an account rather than the
- messages contained by the folders, by invoking retrieve() retrieve slot with the
- \c foldersOnly option set to true. When the folder retrieval operation is complete,
- it is not necessary to invoke the completeRetrieval() operation.
-
- \section1 Cancellation
-
- In order to cancel an operation previously initiated, the client can invoke the
- cancelTransfer() slot.
-
- \section1 Server Status
+ There are a variety of mechanisms for retrieving messages, at various levels of
+ granularity. In all cases, retrieved messages are added directly to the mail
+ store by the message server, from where clients can retrieve their meta data or
+ content.
- As the MessageServer application performs the operations requested of it, it indicates
- the tasks it is performing by emitting the statusChanged() signal. If it encounters
- an error that prevents an operation from being performed, the actionCompleted(bool) signal
- is emitted with the parameter \c false.
+ An instance of QMailRetrievalAction should be used to request retrievel of
+ folders and messages.
- \sa QMailServiceAction, QMailMessage
+ \sa QMailServiceAction, QMailStore
*/
/*!
diff --git a/src/libraries/qtopiamail/qmailmessageset.cpp b/src/libraries/qtopiamail/qmailmessageset.cpp
index b3451848..c9ca9d7f 100644
--- a/src/libraries/qtopiamail/qmailmessageset.cpp
+++ b/src/libraries/qtopiamail/qmailmessageset.cpp
@@ -41,7 +41,6 @@ template class QPrivatelyNoncopyable<QMailMessageSetContainerPrivate>;
/*!
\class QMailMessageSetContainer
- \inpublicgroup QtMessagingModule
\preliminary
\ingroup messaginglibrary
@@ -218,7 +217,6 @@ public:
/*!
\class QMailMessageSet
- \inpublicgroup QtMessagingModule
\preliminary
\ingroup messaginglibrary
@@ -376,7 +374,6 @@ public:
/*!
\class QMailFolderMessageSet
- \inpublicgroup QtMessagingModule
\preliminary
\ingroup messaginglibrary
@@ -605,7 +602,6 @@ public:
/*!
\class QMailAccountMessageSet
- \inpublicgroup QtMessagingModule
\preliminary
\ingroup messaginglibrary
@@ -844,7 +840,6 @@ public:
/*!
\class QMailFilterMessageSet
- \inpublicgroup QtMessagingModule
\preliminary
\ingroup messaginglibrary
@@ -1085,7 +1080,6 @@ public:
/*!
\class QMailMessageSetModel
- \inpublicgroup QtMessagingModule
\preliminary
\ingroup messaginglibrary
@@ -1098,7 +1092,7 @@ public:
to construct a hierarchical tree of message folders, or other, more flexible ways of
partitioning the set of messages into hierarchical groups.
- QMailMessageListModel inherits from QAbstractListModel, so it is suitable for use
+ QMailMessageSetModel inherits from QAbstractItemModel, so it is suitable for use
with the Qt View classes such as QTreeView, to visually represent the hierachical
structure.
@@ -1107,9 +1101,9 @@ public:
function is used to disable this feature.
To customize the display of QMailMessageSets, create a delegate that paints the
- object as desired, using data elements accessed via the QMailMessageSetModel
- data() method. The data() function should be overridden to support additional roles,
- or to customize the display of existing roles.
+ object as desired, using data elements accessed via the data() function.
+ The data() function should be overridden by subclasses to support additional roles,
+ or to customize the data displayed for existing roles.
To define the content of a QMailMessageSetModel, derive classes from QMailMessageSet
which select your desired message sets, and add them to the model in the init()
diff --git a/src/libraries/qtopiamail/qmailmessagesortkey.cpp b/src/libraries/qtopiamail/qmailmessagesortkey.cpp
index 67559048..4b70f06f 100644
--- a/src/libraries/qtopiamail/qmailmessagesortkey.cpp
+++ b/src/libraries/qtopiamail/qmailmessagesortkey.cpp
@@ -13,7 +13,6 @@
/*!
\class QMailMessageSortKey
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailMessageSortKey class defines the parameters used for sorting a subset of
diff --git a/src/libraries/qtopiamail/qmailserviceaction.cpp b/src/libraries/qtopiamail/qmailserviceaction.cpp
index 221feded..296e65b0 100644
--- a/src/libraries/qtopiamail/qmailserviceaction.cpp
+++ b/src/libraries/qtopiamail/qmailserviceaction.cpp
@@ -310,7 +310,6 @@ template class QPrivatelyNoncopyable<QMailServiceActionPrivate>;
/*!
\class QMailServiceAction::Status
- \inpublicgroup QtMessagingModule
\preliminary
\ingroup messaginglibrary
@@ -450,7 +449,6 @@ void QMailServiceAction::Status::deserialize(Stream &stream)
/*!
\class QMailServiceAction
- \inpublicgroup QtMessagingModule
\preliminary
\ingroup messaginglibrary
@@ -472,6 +470,15 @@ void QMailServiceAction::Status::deserialize(Stream &stream)
A user may attempt to cancel an operation after it has been initiated. The cancelOperation()
slot is provided for this purpose.
+
+ A QMailServiceAction instance supports only a single request at any time. An application
+ may, however, use multiple QMailServiceAction instances to send independent requests concurrently.
+ Each QMailServiceAction instance will report only the changes pertaining to the request
+ that instance delivered. Whether or not concurrent requests are concurrently serviced by
+ the message server depends on whether those requests must be serviced by the same
+ QMailMessageService instance.
+
+ \sa QMailMessageService
*/
/*!
@@ -720,7 +727,6 @@ template class QPrivatelyNoncopyable<QMailRetrievalActionPrivate>;
/*!
\class QMailRetrievalAction
- \inpublicgroup QtMessagingModule
\preliminary
\ingroup messaginglibrary
@@ -783,10 +789,17 @@ QMailRetrievalAction::~QMailRetrievalAction()
}
/*!
- Requests that the message server retrieve the list of folders available for the account \a accountId.
- If \a folderId is valid, the folders within that folder should be retrieved. If \a descending is true,
- the search should also recursively retrieve the folders available within the previously retrieved folders.
-
+ Requests that the message server retrieve the list of folders available for the
+ account \a accountId. If \a folderId is valid, only the identified folder is
+ searched for child folders; otherwise the search begins at the root of the
+ account. If \a descending is true, the search should also recursively search
+ for child folders within folders discovered during the search.
+
+ The QMailFolder::serverCount(), QMailFolder::serverUnreadCount() and
+ QMailFolder::serverUndiscoveredCount() properties will be updated for each
+ folder that is searched for child folders; these properties are not updated
+ for folders that are merely discovered by searching.
+
\sa retrieveAll()
*/
void QMailRetrievalAction::retrieveFolderList(const QMailAccountId &accountId, const QMailFolderId &folderId, bool descending)
@@ -797,23 +810,28 @@ void QMailRetrievalAction::retrieveFolderList(const QMailAccountId &accountId, c
/*!
Requests that the message server retrieve the list of messages available for the account \a accountId.
If \a folderId is valid, then only messages within that folder should be retrieved; otherwise
- messages within all folders in the account should be retrieved.
+ messages within all folders in the account should be retrieved. If \a minimum is non-zero,
+ then that value will be used to restrict the number of messages to be retrieved from
+ each folder; otherwise, all messages will be retrieved.
+ If \a sort is not empty, the external service will report the discovered messages in the
+ ordering indicated by the sort criterion, if possible. Services are not required to support
+ this facility.
+
If a folder messages are being retrieved from contains at least \a minimum messages then the
messageserver should ensure that at least \a minimum messages are available from the mail
- store for that folder; otherwise if the folder contains less than \a minimum messages the messageserver
- should ensure all the messages for that folder are available from the mail store.
+ store for that folder; otherwise if the folder contains less than \a minimum messages the
+ messageserver should ensure all the messages for that folder are available from the mail store.
+ If a folder has messages locally available, then all previously undiscovered messages will be
+ retrieved for that folder, even if that number exceeds \a minimum.
- Even if minimum is zero for each folder operated on \link QMailFolder::serverCount()
- QMailFolder::serverCount() \endlink and \link QMailFolder::serverUnreadCount()
- QMailFolder::serverUnreadCount() \endlink will be updated.
+ The QMailFolder::serverCount(), QMailFolder::serverUnreadCount() and
+ QMailFolder::serverUndiscoveredCount() properties will be updated for each folder
+ from which messages are retrieved.
- If \a sort is not empty, the external service will
- discover the listed messages in the ordering indicated by the sort criterion, if possible.
-
New messages will be added to the mail store as they are discovered, and
marked with the \l QMailMessage::New status flag. Messages that are present
- in the mail store but found to be no longer available should be marked with the
+ in the mail store but found to be no longer available are marked with the
\l QMailMessage::Removed status flag.
\sa retrieveAll()
@@ -836,6 +854,10 @@ void QMailRetrievalAction::retrieveMessageList(const QMailAccountId &accountId,
If \a spec is \l QMailRetrievalAction::Content, then the message server should
retrieve the entirety of each message listed in \a messageIds.
+
+ The QMailFolder::serverCount(), QMailFolder::serverUnreadCount() and
+ QMailFolder::serverUndiscoveredCount() properties will be updated for each folder
+ from which messages are retrieved.
*/
void QMailRetrievalAction::retrieveMessages(const QMailMessageIdList &messageIds, RetrievalSpecification spec)
{
@@ -845,6 +867,10 @@ void QMailRetrievalAction::retrieveMessages(const QMailMessageIdList &messageIds
/*!
Requests that the message server retrieve the message part that is indicated by the
location \a partLocation.
+
+ The QMailFolder::serverCount(), QMailFolder::serverUnreadCount() and
+ QMailFolder::serverUndiscoveredCount() properties will be updated for the folder
+ from which the part is retrieved.
*/
void QMailRetrievalAction::retrieveMessagePart(const QMailMessagePart::Location &partLocation)
{
@@ -854,6 +880,10 @@ void QMailRetrievalAction::retrieveMessagePart(const QMailMessagePart::Location
/*!
Requests that the message server retrieve a subset of the message \a messageId, such that
at least \a minimum bytes are available from the mail store.
+
+ The QMailFolder::serverCount(), QMailFolder::serverUnreadCount() and
+ QMailFolder::serverUndiscoveredCount() properties will be updated for the folder
+ from which the message is retrieved.
*/
void QMailRetrievalAction::retrieveMessageRange(const QMailMessageId &messageId, uint minimum)
{
@@ -867,6 +897,10 @@ void QMailRetrievalAction::retrieveMessageRange(const QMailMessageId &messageId,
The total size of the part on the server is given by QMailMessagePart::contentDisposition().size(),
the amount of the part available locally is given by QMailMessagePart::body().length().
+
+ The QMailFolder::serverCount(), QMailFolder::serverUnreadCount() and
+ QMailFolder::serverUndiscoveredCount() properties will be updated for the folder
+ from which the part is retrieved.
*/
void QMailRetrievalAction::retrieveMessagePartRange(const QMailMessagePart::Location &partLocation, uint minimum)
{
@@ -876,6 +910,16 @@ void QMailRetrievalAction::retrieveMessagePartRange(const QMailMessagePart::Loca
/*!
Requests that the message server retrieve all folders and meta data for messages available
for the account \a accountId.
+
+ All folders within the account will be discovered and searched for child folders.
+ The QMailFolder::serverCount(), QMailFolder::serverUnreadCount() and
+ QMailFolder::serverUndiscoveredCount() properties will be updated for each folder
+ in the account.
+
+ Meta data will be retrieved for every message found in the account.
+ New messages will be added to the mail store as they are retrieved, and
+ marked with the \l QMailMessage::New status flag. Messages that are no longer
+ available will be marked with the \l QMailMessage::Removed status flag.
\sa retrieveFolderList(), retrieveMessageList(), synchronize()
*/
@@ -904,8 +948,10 @@ void QMailRetrievalAction::exportUpdates(const QMailAccountId &accountId)
New messages will be added to the mail store as they are discovered, and
marked with the \l QMailMessage::New status flag. Messages that are no longer
available will be marked with the \l QMailMessage::Removed status flag.
- The folder structure of the account will also be synchronized with that
- available from the external service.
+
+ The folder structure of the account will be synchronized with that available from
+ the external service. The QMailFolder::serverCount(), QMailFolder::serverUnreadCount() and
+ QMailFolder::serverUndiscoveredCount() properties will be updated for each folder.
\sa retrieveAll(), exportUpdates()
*/
@@ -952,8 +998,9 @@ void QMailTransmitActionPrivate::transmitMessages(const QMailAccountId &accountI
{
_server->transmitMessages(newAction(), accountId);
+ QMailAccount account(accountId);
_ids = QMailStore::instance()->queryMessages(QMailMessageKey::parentAccountId(accountId) &
- QMailMessageKey::parentFolderId(QMailFolderId(QMailFolder::OutboxFolder)));
+ QMailMessageKey::parentFolderId(account.standardFolder(QMailFolder::OutboxFolder)));
emitChanges();
}
@@ -987,7 +1034,6 @@ template class QPrivatelyNoncopyable<QMailTransmitActionPrivate>;
/*!
\class QMailTransmitAction
- \inpublicgroup QtMessagingModule
\preliminary
\ingroup messaginglibrary
@@ -1134,7 +1180,6 @@ template class QPrivatelyNoncopyable<QMailStorageActionPrivate>;
/*!
\class QMailStorageAction
- \inpublicgroup QtMessagingModule
\preliminary
\ingroup messaginglibrary
@@ -1304,7 +1349,6 @@ template class QPrivatelyNoncopyable<QMailSearchActionPrivate>;
/*!
\class QMailSearchAction
- \inpublicgroup QtMessagingModule
\preliminary
\ingroup messaginglibrary
@@ -1446,7 +1490,6 @@ template class QPrivatelyNoncopyable<QMailProtocolActionPrivate>;
/*!
\class QMailProtocolAction
- \inpublicgroup QtMessagingModule
\preliminary
\ingroup messaginglibrary
diff --git a/src/libraries/qtopiamail/qmailstore.cpp b/src/libraries/qtopiamail/qmailstore.cpp
index bc5fecca..d0a8cdbe 100644
--- a/src/libraries/qtopiamail/qmailstore.cpp
+++ b/src/libraries/qtopiamail/qmailstore.cpp
@@ -15,7 +15,6 @@
/*!
\class QMailStore
- \inpublicgroup QtMessagingModule
\preliminary
\brief The QMailStore class represents the main interface for storage and retrieval
@@ -29,7 +28,58 @@
QMailStore also provides functions for querying and counting of QMailFolders, QMailAccounts and QMailMessages
when used in conjunction with QMailMessageKey, QMailFolderKey and QMailAccountKey classes.
- \sa QMailMessage, QMailFolder, QMailMessageKey, QMailFolderKey, QMailAccountKey
+ If a QMailStore operation fails, the lastError() function will return an error code
+ value indicating the failure mode encountered. A successful operation will set the
+ lastError() result to QMailStore::NoError.
+
+ Messaging accounts are represented by QMailAccountId objects. The data associated with
+ accounts is separated into two components: QMailAccount objects hold account properties
+ exported to mail store client applications, and QMailAccountConfiguration objects hold
+ data used only by the messageserver and the protocol plugins it loads.
+
+ Account objects are accessed via the account(), accountConfiguration(), countAccounts()
+ and queryAccounts() functions. Accounts in the mail store can be manipulated via the
+ addAccount(), updateAccount() and removeAccount() functions. Mail store manipulations
+ affecting accounts are reported via the accountsAdded(), accountsUpdated(),
+ accountContentsModified() and accountsRemoved() signals.
+
+ Fixed logical groupings of message are modelled as folders, represented by QMailFolderId objects.
+ The data associated with folders is held by instances of the QMailFolder class.
+
+ Folder objects are accessed via the folder(), countFolders() and queryFolders() functions.
+ Folders in the mail store can be manipulated via the addFolder(), updateFolder() and
+ removeFolder() functions. Mail store manipulations affecting folders are reported via
+ the foldersAdded(), foldersUpdated(), folderContentsModified() and foldersRemoved() signals.
+
+ Messages in the mail store are represented by QMailMessageId objects. The data associated
+ with a message can be retrieved in two forms: QMailMessageMetaData objects contain only
+ the meta data fields associated with a message, and QMailMessage objects contain both
+ the meta data fields and the message content proper.
+
+ Message objects are accessed via the message(), messageMetaData(), countMessages()
+ and queryMessages() functions. Additionally, the messagesMetaData() function can be
+ used to retrieve subsets of meta data pertaining to a set of messages. Messages in
+ the mail store can be manipulated via the addMessage(), updateMessage() and removeMessage()
+ functions. Multiple messages can have their meta data fields updated together via
+ the updateMessagesMetaData() function. Mail store manipulations affecting messages are
+ reported via the messagesAdded(), messagesUpdated(), messageContentsModified() and
+ messagesRemoved() signals.
+
+ Messages that have been removed can be represented by removal records, which persist
+ only to assist in keeping mail store content synchronized with the content of
+ an external message source. QMailMessageRemovalRecord objects can be accessed
+ via the messageRemovalRecords() function.
+
+ \sa QMailAccount, QMailFolder, QMailMessage
+*/
+
+/*!
+ \enum QMailStore::InitializationState
+ This enum defines the initialization states that the mail store can assume.
+
+ \value Uninitialized The mail store has not yet been instantiated and initialized.
+ \value InitializationFailed The mail store has been instantiated and initization was unsuccessful.
+ \value Initialized The mail store has been instantiated and successfully initialized.
*/
/*!
@@ -90,19 +140,11 @@ QMailStore::~QMailStore()
}
/*!
- Returns true if the QMailStore object was correctly initialized.
+ Returns the initialization state of the QMailStore.
*/
-bool QMailStore::initialized() const
+QMailStore::InitializationState QMailStore::initializationState()
{
- return QMailStore::storeInitialized();
-}
-
-/*!
- Returns true if the QMailStore was correctly initialized.
-*/
-bool QMailStore::storeInitialized()
-{
- return QMailStorePrivate::initialized();
+ return QMailStorePrivate::initializationState();
}
/*!
@@ -758,6 +800,30 @@ quint64 QMailStore::messageStatusMask(const QString& name) const
}
/*!
+ Sets the list of accounts currently retrieving from external sources to be \a ids.
+
+ \sa retrievalInProgress()
+*/
+void QMailStore::setRetrievalInProgress(const QMailAccountIdList &ids)
+{
+ if (d->setRetrievalInProgress(ids)) {
+ emitRetrievalInProgress(ids);
+ }
+}
+
+/*!
+ Sets the list of accounts currently transmitting to external sources to be \a ids.
+
+ \sa transmissionInProgress()
+*/
+void QMailStore::setTransmissionInProgress(const QMailAccountIdList &ids)
+{
+ if (d->setTransmissionInProgress(ids)) {
+ emitTransmissionInProgress(ids);
+ }
+}
+
+/*!
Forces any queued event notifications to immediately be synchronously emitted, and processed
synchronously by recipient processes.
@@ -891,18 +957,37 @@ void QMailStore::emitRemovalRecordNotification(ChangeType type, const QMailAccou
}
}
+/*! \internal */
+void QMailStore::emitRetrievalInProgress(const QMailAccountIdList &ids)
+{
+ d->notifyRetrievalInProgress(ids);
+
+ emit retrievalInProgress(ids);
+}
+
+/*! \internal */
+void QMailStore::emitTransmissionInProgress(const QMailAccountIdList &ids)
+{
+ d->notifyTransmissionInProgress(ids);
+
+ emit transmissionInProgress(ids);
+}
+
Q_GLOBAL_STATIC(QMailStore,QMailStoreInstance);
/*!
- Returns an instance of the QMailStore object.
-*/
+ Returns the single instance of the QMailStore class.
+
+ If necessary, the store will be instantiated and initialized.
+ \sa initializationState()
+*/
QMailStore* QMailStore::instance()
{
static bool init = false;
if (!init) {
init = true;
- QMailStoreInstance()->d->initStore();
+ QMailStoreInstance()->d->initialize();
}
return QMailStoreInstance();
}
@@ -1015,6 +1100,15 @@ QMailStore* QMailStore::instance()
*/
/*!
+ \fn void QMailStore::folderContentsModified(const QMailFolderIdList& ids)
+
+ Signal that is emitted when changes to messages in the mail store
+ affect the content of the folders in the list \a ids.
+
+ \sa messagesAdded(), messagesUpdated(), messagesRemoved()
+*/
+
+/*!
\fn void QMailStore::messageRemovalRecordsAdded(const QMailAccountIdList& ids)
Signal that is emitted when QMailMessageRemovalRecords are added to the store,
@@ -1033,12 +1127,25 @@ QMailStore* QMailStore::instance()
*/
/*!
- \fn void QMailStore::folderContentsModified(const QMailFolderIdList& ids)
+ \fn void QMailStore::retrievalInProgress(const QMailAccountIdList& ids)
- Signal that is emitted when changes to messages in the mail store
- affect the content of the folders in the list \a ids.
+ Signal that is emitted when the set of accounts currently retrieving from
+ external sources is modified to \a ids. Accounts listed in \a ids are likely
+ to be the source of numerous mail store signals; some clients may wish to
+ ignore updates associated with these accounts whilst they are engaged in retrieving.
- \sa messagesAdded(), messagesUpdated(), messagesRemoved()
+ \sa transmissionInProgress()
+*/
+
+/*!
+ \fn void QMailStore::transmissionInProgress(const QMailAccountIdList& ids)
+
+ Signal that is emitted when the set of accounts currently transmitting to
+ external sources is modified to \a ids. Accounts listed in \a ids are likely
+ to be the source of numerous mail store signals; some clients may wish to
+ ignore updates associated with these accounts whilst they are engaged in transmitting.
+
+ \sa retrievalInProgress()
*/
Q_IMPLEMENT_USER_METATYPE_ENUM(QMailStore::MessageRemovalOption)
diff --git a/src/libraries/qtopiamail/qmailstore.h b/src/libraries/qtopiamail/qmailstore.h
index 55ef22dc..0356ac3a 100644
--- a/src/libraries/qtopiamail/qmailstore.h
+++ b/src/libraries/qtopiamail/qmailstore.h
@@ -36,6 +36,13 @@ class QTOPIAMAIL_EXPORT QMailStore : public QObject
Q_OBJECT
public:
+ enum InitializationState
+ {
+ Uninitialized = 0,
+ InitializationFailed,
+ Initialized
+ };
+
enum ReturnOption
{
ReturnAll = 0,
@@ -69,8 +76,7 @@ public:
public:
virtual ~QMailStore();
- bool initialized() const;
- static bool storeInitialized();
+ static InitializationState initializationState();
QMailStore::ErrorCode lastError() const;
@@ -134,6 +140,9 @@ public:
bool registerMessageStatusFlag(const QString& name);
quint64 messageStatusMask(const QString& name) const;
+ void setRetrievalInProgress(const QMailAccountIdList &ids);
+ void setTransmissionInProgress(const QMailAccountIdList &ids);
+
bool asynchronousEmission() const;
void flushIpcNotifications();
@@ -164,10 +173,14 @@ signals:
void messageRemovalRecordsAdded(const QMailAccountIdList& ids);
void messageRemovalRecordsRemoved(const QMailAccountIdList& ids);
+ void retrievalInProgress(const QMailAccountIdList &ids);
+ void transmissionInProgress(const QMailAccountIdList &ids);
+
private:
friend class QMailStoreImplementationBase;
friend class QMailStorePrivate;
friend class tst_QMailStore;
+ friend class tst_QMailStoreKeys;
QMailStore();
@@ -180,6 +193,8 @@ private:
void emitFolderNotification(ChangeType type, const QMailFolderIdList &ids);
void emitMessageNotification(ChangeType type, const QMailMessageIdList &ids);
void emitRemovalRecordNotification(ChangeType type, const QMailAccountIdList &ids);
+ void emitRetrievalInProgress(const QMailAccountIdList &ids);
+ void emitTransmissionInProgress(const QMailAccountIdList &ids);
QMailStorePrivate* d;
};
diff --git a/src/libraries/qtopiamail/qmailstore_p.cpp b/src/libraries/qtopiamail/qmailstore_p.cpp
index 4d6840c3..016f2185 100644
--- a/src/libraries/qtopiamail/qmailstore_p.cpp
+++ b/src/libraries/qtopiamail/qmailstore_p.cpp
@@ -948,7 +948,11 @@ void appendWhereValues<QMailMessageKey::ArgumentType>(const QMailMessageKey::Arg
break;
case QMailMessageKey::ServerUid:
- values += extractor.serverUid();
+ if (a.valueList.count() < IdLookupThreshold) {
+ values += extractor.serverUid();
+ } else {
+ // This value match has been replaced by a table lookup
+ }
break;
case QMailMessageKey::Size:
@@ -1526,6 +1530,14 @@ QString whereClauseItem<QMailMessageKey>(const QMailMessageKey &, const QMailMes
}
break;
+ case QMailMessageKey::ServerUid:
+ if (a.valueList.count() >= IdLookupThreshold) {
+ q << baseExpression(columnName, a.op, true) << "( SELECT id FROM " << QMailStorePrivate::temporaryTableName(a) << ")";
+ } else {
+ q << expression;
+ }
+ break;
+
case QMailMessageKey::Type:
case QMailMessageKey::Status:
case QMailMessageKey::Sender:
@@ -1533,7 +1545,6 @@ QString whereClauseItem<QMailMessageKey>(const QMailMessageKey &, const QMailMes
case QMailMessageKey::Subject:
case QMailMessageKey::TimeStamp:
case QMailMessageKey::ReceptionTimeStamp:
- case QMailMessageKey::ServerUid:
case QMailMessageKey::Size:
case QMailMessageKey::ContentType:
case QMailMessageKey::ContentScheme:
@@ -1988,7 +1999,7 @@ bool QMailStorePrivate::initStore()
ProcessMutex creationMutex(pathIdentifier(QDir::rootPath()));
MutexGuard guard(creationMutex);
if (!guard.lock(1000)) {
- return init;
+ return false;
}
if (database.isOpenError()) {
@@ -2042,7 +2053,6 @@ bool QMailStorePrivate::initStore()
}
// We are now correctly initialized
- init = true;
return true;
}
@@ -2054,6 +2064,8 @@ void QMailStorePrivate::clearContent()
messageCache.clear();
uidCache.clear();
+ Transaction t(this);
+
// Drop all data
foreach (const QString &table, database.tables()) {
if (table != "versioninfo") {
@@ -2064,6 +2076,10 @@ void QMailStorePrivate::clearContent()
}
}
}
+
+ if (!t.commit()) {
+ qMailLog(Messaging) << "Could not commit clearContent operation to database";
+ }
// Remove all content
QMailContentManagerFactory::clearContent();
@@ -2128,22 +2144,27 @@ QSqlQuery QMailStorePrivate::prepare(const QString& sql)
clearQueryError();
- QSqlQuery query(database);
-
// Create any temporary tables needed for this query
while (!requiredTableKeys.isEmpty()) {
- const QMailMessageKey::ArgumentType *arg = requiredTableKeys.takeFirst();
+ QPair<const QMailMessageKey::ArgumentType *, QString> key(requiredTableKeys.takeFirst());
+ const QMailMessageKey::ArgumentType *arg = key.first;
if (!temporaryTableKeys.contains(arg)) {
QString tableName = temporaryTableName(*arg);
- QSqlQuery tableQuery(database);
- if (!tableQuery.exec(QString("CREATE TEMP TABLE %1 ( id INTEGER PRIMARY KEY )").arg(tableName))) {
- setQueryError(tableQuery.lastError(), "Failed to create temporary table", queryText(tableQuery));
- qMailLog(Messaging) << "Unable to prepare query:" << sql;
- return query;
- } else {
- temporaryTableKeys.append(arg);
+ {
+ QSqlQuery createQuery(database);
+ if (!createQuery.exec(QString("CREATE TEMP TABLE %1 ( id %2 PRIMARY KEY )").arg(tableName).arg(key.second))) {
+ setQueryError(createQuery.lastError(), "Failed to create temporary table", queryText(createQuery));
+ qMailLog(Messaging) << "Unable to prepare query:" << sql;
+ return QSqlQuery();
+ }
+ }
+ temporaryTableKeys.append(arg);
+
+ QVariantList idValues;
+
+ if (key.second == "INTEGER") {
int type = 0;
if (qVariantCanConvert<QMailMessageId>(arg->valueList.first())) {
type = 1;
@@ -2153,7 +2174,7 @@ QSqlQuery QMailStorePrivate::prepare(const QString& sql)
type = 3;
}
- // Add the ID values to the temp table
+ // Extract the ID values to INTEGER variants
foreach (const QVariant &var, arg->valueList) {
quint64 id = 0;
@@ -2170,20 +2191,43 @@ QSqlQuery QMailStorePrivate::prepare(const QString& sql)
default:
qMailLog(Messaging) << "Unable to extract ID value from valuelist!";
qMailLog(Messaging) << "Unable to prepare query:" << sql;
- return query;
+ return QSqlQuery();
+ }
+
+ idValues.append(QVariant(id));
+ }
+
+ // Add the ID values to the temp table
+ {
+ QSqlQuery insertQuery(database);
+ insertQuery.prepare(QString("INSERT INTO %1 VALUES (?)").arg(tableName));
+ insertQuery.addBindValue(idValues);
+ if (!insertQuery.execBatch()) {
+ setQueryError(insertQuery.lastError(), "Failed to populate integer temporary table", queryText(insertQuery));
+ qMailLog(Messaging) << "Unable to prepare query:" << sql;
+ return QSqlQuery();
}
+ }
+ } else if (key.second == "VARCHAR") {
+ foreach (const QVariant &var, arg->valueList) {
+ idValues.append(QVariant(var.value<QString>()));
+ }
- tableQuery = QSqlQuery(database);
- if (!tableQuery.exec(QString("INSERT INTO %1 VALUES (%2)").arg(tableName).arg(id))) {
- setQueryError(tableQuery.lastError(), "Failed to populate temporary table", queryText(tableQuery));
+ {
+ QSqlQuery insertQuery(database);
+ insertQuery.prepare(QString("INSERT INTO %1 VALUES (?)").arg(tableName));
+ insertQuery.addBindValue(idValues);
+ if (!insertQuery.execBatch()) {
+ setQueryError(insertQuery.lastError(), "Failed to populate varchar temporary table", queryText(insertQuery));
qMailLog(Messaging) << "Unable to prepare query:" << sql;
- return query;
+ return QSqlQuery();
}
}
}
}
}
+ QSqlQuery query(database);
query.setForwardOnly(true);
if (!query.prepare(sql)) {
setQueryError(query.lastError(), "Failed to prepare query", queryText(query));
@@ -2270,7 +2314,7 @@ void QMailStorePrivate::setQueryError(const QSqlError &error, const QString &des
void QMailStorePrivate::clearQueryError(void)
{
- lastQueryError = 0;
+ lastQueryError = QSqlError::NoError;
}
template<bool PtrSizeExceedsLongSize>
@@ -2291,9 +2335,9 @@ QString QMailStorePrivate::temporaryTableName(const QMailMessageKey::ArgumentTyp
return QString("qtopiamail_idmatch_%1").arg(numericPtrValue<(sizeof(void*) > sizeof(unsigned long))>(ptr));
}
-void QMailStorePrivate::createTemporaryTable(const QMailMessageKey::ArgumentType& arg) const
+void QMailStorePrivate::createTemporaryTable(const QMailMessageKey::ArgumentType& arg, const QString &dataType) const
{
- requiredTableKeys.append(&arg);
+ requiredTableKeys.append(qMakePair(&arg, dataType));
}
void QMailStorePrivate::destroyTemporaryTables()
@@ -2574,7 +2618,9 @@ QString QMailStorePrivate::buildWhereClause(const Key& key, bool nested, bool fi
// See if we need to create any temporary tables to use in this query
foreach (const QMailMessageKey::ArgumentType &a, messageKey.arguments()) {
if (a.property == QMailMessageKey::Id && a.valueList.count() >= IdLookupThreshold) {
- createTemporaryTable(a);
+ createTemporaryTable(a, "INTEGER");
+ } else if (a.property == QMailMessageKey::ServerUid && a.valueList.count() >= IdLookupThreshold) {
+ createTemporaryTable(a, "VARCHAR");
}
}
@@ -5964,7 +6010,7 @@ QSqlQuery QMailStorePrivate::performQuery(const QString& statement, bool batch,
}
QSqlQuery query(prepare(statement + keyStatements));
- if (query.lastError().type() != QSqlError::NoError) {
+ if (queryError() != QSqlError::NoError) {
qMailLog(Messaging) << "Could not prepare query" << descriptor;
} else {
foreach (const QVariant& value, bindValues)
diff --git a/src/libraries/qtopiamail/qmailstore_p.h b/src/libraries/qtopiamail/qmailstore_p.h
index 81cb3346..4b011d77 100644
--- a/src/libraries/qtopiamail/qmailstore_p.h
+++ b/src/libraries/qtopiamail/qmailstore_p.h
@@ -187,7 +187,7 @@ private:
typedef QPair<quint64, QString> FolderInfo;
bool setupFolders(const QList<FolderInfo> &folderList);
- void createTemporaryTable(const QMailMessageKey::ArgumentType &arg) const;
+ void createTemporaryTable(const QMailMessageKey::ArgumentType &arg, const QString &dataType) const;
void destroyTemporaryTables(void);
bool transaction(void);
@@ -480,7 +480,7 @@ private:
mutable IdCache<QMailFolder, QMailFolderId> folderCache;
mutable IdCache<QMailAccount, QMailAccountId> accountCache;
- mutable QList<const QMailMessageKey::ArgumentType*> requiredTableKeys;
+ mutable QList<QPair<const QMailMessageKey::ArgumentType*, QString> > requiredTableKeys;
mutable QList<const QMailMessageKey::ArgumentType*> temporaryTableKeys;
QList<const QMailMessageKey::ArgumentType*> expiredTableKeys;
diff --git a/src/libraries/qtopiamail/qmailstoreimplementation_p.cpp b/src/libraries/qtopiamail/qmailstoreimplementation_p.cpp
index 097b7ec2..afc2c2f7 100644
--- a/src/libraries/qtopiamail/qmailstoreimplementation_p.cpp
+++ b/src/libraries/qtopiamail/qmailstoreimplementation_p.cpp
@@ -84,13 +84,15 @@ void dispatchNotifications(IDSetType &ids, const QString &sig)
}
-bool QMailStoreImplementationBase::init = false;
+QMailStore::InitializationState QMailStoreImplementationBase::initState = QMailStore::Uninitialized;
QMailStoreImplementationBase::QMailStoreImplementationBase(QMailStore* parent)
: QObject(parent),
q(parent),
errorCode(QMailStore::NoError),
- asyncEmission(false)
+ asyncEmission(false),
+ retrievalSetInitialized(false),
+ transmissionSetInitialized(false)
{
Q_ASSERT(q);
@@ -119,14 +121,14 @@ QMailStoreImplementationBase::QMailStoreImplementationBase(QMailStore* parent)
SLOT(aboutToQuit()));
}
-bool QMailStoreImplementationBase::initStore()
+void QMailStoreImplementationBase::initialize()
{
- return false;
+ initState = (initStore() ? QMailStore::Initialized : QMailStore::InitializationFailed);
}
-bool QMailStoreImplementationBase::initialized()
+QMailStore::InitializationState QMailStoreImplementationBase::initializationState()
{
- return init;
+ return initState;
}
QMailStore::ErrorCode QMailStoreImplementationBase::lastError() const
@@ -159,6 +161,11 @@ void QMailStoreImplementationBase::flushIpcNotifications()
QCopAdaptor a("QPE/Qtopiamail");
QCopAdaptorEnvelope e = a.send("forceIpcFlush");
e << ::getpid();
+
+ if (flushTimer.isActive()) {
+ // We interrupted a batching period - reset the flush timer to its full period
+ flushTimer.start(flushTimeout);
+ }
}
void QMailStoreImplementationBase::processIpcMessageQueue()
@@ -249,7 +256,6 @@ void QMailStoreImplementationBase::notifyAccountsChange(QMailStore::ChangeType c
break;
}
} else {
- flushNotifications();
emitIpcUpdates(ids, sig[changeType]);
preFlushTimer.start(preFlushTimeout);
@@ -287,7 +293,6 @@ void QMailStoreImplementationBase::notifyMessagesChange(QMailStore::ChangeType c
break;
}
} else {
- flushNotifications();
emitIpcUpdates(ids, sig[changeType]);
preFlushTimer.start(preFlushTimeout);
@@ -325,7 +330,6 @@ void QMailStoreImplementationBase::notifyFoldersChange(QMailStore::ChangeType ch
break;
}
} else {
- flushNotifications();
emitIpcUpdates(ids, sig[changeType]);
preFlushTimer.start(preFlushTimeout);
@@ -357,13 +361,52 @@ void QMailStoreImplementationBase::notifyMessageRemovalRecordsChange(QMailStore:
break;
}
} else {
- flushNotifications();
emitIpcUpdates(ids, sig[changeType]);
preFlushTimer.start(preFlushTimeout);
}
}
+void QMailStoreImplementationBase::notifyRetrievalInProgress(const QMailAccountIdList& ids)
+{
+ // Clients may want to enable or disable event handling based on this event, therefore
+ // we must ensure that all previous events are actually delivered before this one is.
+ flushIpcNotifications();
+
+ emitIpcUpdates(ids, retrievalInProgressSig());
+}
+
+void QMailStoreImplementationBase::notifyTransmissionInProgress(const QMailAccountIdList& ids)
+{
+ flushIpcNotifications();
+
+ emitIpcUpdates(ids, transmissionInProgressSig());
+}
+
+bool QMailStoreImplementationBase::setRetrievalInProgress(const QMailAccountIdList& ids)
+{
+ QSet<QMailAccountId> idSet(ids.toSet());
+ if ((idSet != retrievalInProgressIds) || !retrievalSetInitialized) {
+ retrievalInProgressIds = idSet;
+ retrievalSetInitialized = true;
+ return true;
+ }
+
+ return false;
+}
+
+bool QMailStoreImplementationBase::setTransmissionInProgress(const QMailAccountIdList& ids)
+{
+ QSet<QMailAccountId> idSet(ids.toSet());
+ if ((idSet != transmissionInProgressIds) || !transmissionSetInitialized) {
+ transmissionInProgressIds = idSet;
+ transmissionSetInitialized = true;
+ return true;
+ }
+
+ return false;
+}
+
QString QMailStoreImplementationBase::accountAddedSig()
{
static QString s("accountAdded(int,QList<quint64>)");
@@ -448,6 +491,18 @@ QString QMailStoreImplementationBase::messageRemovalRecordsRemovedSig()
return s;
}
+QString QMailStoreImplementationBase::retrievalInProgressSig()
+{
+ static QString s("retrievalInProgress(QList<quint64>)");
+ return s;
+}
+
+QString QMailStoreImplementationBase::transmissionInProgressSig()
+{
+ static QString s("transmissionInProgress(QList<quint64>)");
+ return s;
+}
+
QMailStoreImplementationBase::AccountUpdateSignalMap QMailStoreImplementationBase::initAccountUpdateSignals()
{
AccountUpdateSignalMap sig;
@@ -525,7 +580,18 @@ void QMailStoreImplementationBase::ipcMessage(const QString& message, const QByt
// We have been told to flush any pending ipc notifications
queueTimer.stop();
while (emitIpcNotification()) {}
+ } else if ((message == retrievalInProgressSig()) || (message == transmissionInProgressSig())) {
+ // Emit this message immediately
+ QMailAccountIdList ids;
+ ds >> ids;
+
+ if (message == retrievalInProgressSig()) {
+ emitIpcNotification(&QMailStore::retrievalInProgress, ids);
+ } else {
+ emitIpcNotification(&QMailStore::transmissionInProgress, ids);
+ }
} else {
+ // Queue this message for batched delivery
messageQueue.append(qMakePair(message, data));
queueTimer.start(0);
}
diff --git a/src/libraries/qtopiamail/qmailstoreimplementation_p.h b/src/libraries/qtopiamail/qmailstoreimplementation_p.h
index 405683e1..cbeaa8df 100644
--- a/src/libraries/qtopiamail/qmailstoreimplementation_p.h
+++ b/src/libraries/qtopiamail/qmailstoreimplementation_p.h
@@ -37,8 +37,8 @@ class QMailStoreImplementationBase : public QObject
public:
QMailStoreImplementationBase(QMailStore* parent);
- virtual bool initStore();
- static bool initialized();
+ void initialize();
+ static QMailStore::InitializationState initializationState();
QMailStore::ErrorCode lastError() const;
void setLastError(QMailStore::ErrorCode code) const;
@@ -51,6 +51,11 @@ public:
void notifyMessagesChange(QMailStore::ChangeType changeType, const QMailMessageIdList& ids);
void notifyFoldersChange(QMailStore::ChangeType changeType, const QMailFolderIdList& ids);
void notifyMessageRemovalRecordsChange(QMailStore::ChangeType changeType, const QMailAccountIdList& ids);
+ void notifyRetrievalInProgress(const QMailAccountIdList& ids);
+ void notifyTransmissionInProgress(const QMailAccountIdList& ids);
+
+ bool setRetrievalInProgress(const QMailAccountIdList &ids);
+ bool setTransmissionInProgress(const QMailAccountIdList &ids);
static QString accountAddedSig();
static QString accountRemovedSig();
@@ -70,6 +75,9 @@ public:
static QString messageRemovalRecordsAddedSig();
static QString messageRemovalRecordsRemovedSig();
+ static QString retrievalInProgressSig();
+ static QString transmissionInProgressSig();
+
static const int maxNotifySegmentSize = 0;
public slots:
@@ -91,13 +99,15 @@ protected:
typedef QMap<QString, MessageUpdateSignal> MessageUpdateSignalMap;
static MessageUpdateSignalMap initMessageUpdateSignals();
- static bool init;
+ static QMailStore::InitializationState initState;
virtual void emitIpcNotification(AccountUpdateSignal signal, const QMailAccountIdList &ids);
virtual void emitIpcNotification(FolderUpdateSignal signal, const QMailFolderIdList &ids);
virtual void emitIpcNotification(MessageUpdateSignal signal, const QMailMessageIdList &ids);
private:
+ virtual bool initStore() = 0;
+
bool emitIpcNotification();
QMailStore* q;
@@ -127,6 +137,12 @@ private:
QSet<QMailAccountId> accountContentsModifiedBuffer;
QSet<QMailMessageId> messageContentsModifiedBuffer;
+ bool retrievalSetInitialized;
+ bool transmissionSetInitialized;
+
+ QSet<QMailAccountId> retrievalInProgressIds;
+ QSet<QMailAccountId> transmissionInProgressIds;
+
QTimer queueTimer;
QList<QPair<QString, QByteArray> > messageQueue;
};
@@ -137,7 +153,6 @@ class QMailStoreImplementation : public QMailStoreImplementationBase
public:
QMailStoreImplementation(QMailStore* parent);
- virtual bool initStore() = 0;
virtual void clearContent() = 0;
virtual bool addAccount(QMailAccount *account, QMailAccountConfiguration *config,
diff --git a/src/libraries/qtopiamail/qmailtimestamp.cpp b/src/libraries/qtopiamail/qmailtimestamp.cpp
index cc0431fb..63053d12 100644
--- a/src/libraries/qtopiamail/qmailtimestamp.cpp
+++ b/src/libraries/qtopiamail/qmailtimestamp.cpp
@@ -292,7 +292,6 @@ bool QMailTimeStampPrivate::operator>= (const QMailTimeStampPrivate& other) cons
/*!
\class QMailTimeStamp
- \inpublicgroup QtMessagingModule
\brief The QMailTimeStamp class manages message time stamps.
\ingroup messaginglibrary
diff --git a/src/libraries/qtopiamail/qprivateimplementation.cpp b/src/libraries/qtopiamail/qprivateimplementation.cpp
index ab13a48d..f6e9f1d1 100644
--- a/src/libraries/qtopiamail/qprivateimplementation.cpp
+++ b/src/libraries/qtopiamail/qprivateimplementation.cpp
@@ -10,7 +10,6 @@
/*!
\class QPrivateImplementationBase
- \inpublicgroup QtMessagingModule
\brief The QPrivateImplementationBase provides a base class for implicitly
shared implementation classes.
@@ -21,7 +20,6 @@
/*!
\class QPrivateImplementationPointer
- \inpublicgroup QtMessagingModule
\brief The QPrivateImplementationPointer is a smart pointer which manages
implicit sharing of classes derived from QPrivateImplementationBase.
@@ -32,7 +30,6 @@
/*!
\class QPrivatelyImplemented
- \inpublicgroup QtMessagingModule
\brief The QPrivatelyImplemented class template allows a class to delegate
its implementation to an incomplete template parameter class.
diff --git a/src/libraries/qtopiamail/support/qcopchannel.cpp b/src/libraries/qtopiamail/support/qcopchannel.cpp
index 3f8a19ba..e3f0f763 100644
--- a/src/libraries/qtopiamail/support/qcopchannel.cpp
+++ b/src/libraries/qtopiamail/support/qcopchannel.cpp
@@ -165,11 +165,15 @@ QCopChannel::QCopChannel(const QString& channel, QObject *parent)
/* !
\internal
- Resend all channel registrations This function is obsolete.
+ Resend all channel registrations.
*/
void QCopChannel::reregisterAll()
{
- // Exists for backwards-compatibility only. Not needed any more.
+ QCopThreadData *td = qcopThreadData();
+
+ foreach (const QString &channel, td->clientMap.keys()) {
+ td->clientConnection()->registerChannel(channel);
+ }
}
/* !
@@ -632,22 +636,13 @@ struct QCopPacketHeader
int forwardToLength;
};
-QCopClient::QCopClient()
- : QObject()
-{
- socket = new QCopLocalSocket(this);
- device = socket;
- server = false;
- init();
- connectToServer();
-}
-
QCopClient::QCopClient(QIODevice *device, QCopLocalSocket *socket)
: QObject()
{
this->device = device;
this->socket = socket;
server = true;
+ disconnectHandler = 0;
init();
}
@@ -657,6 +652,7 @@ QCopClient::QCopClient(QIODevice *device, bool isServer)
this->device = device;
this->socket = 0;
server = isServer;
+ disconnectHandler = 0;
init();
}
@@ -676,6 +672,7 @@ void QCopClient::init()
retryCount = 0;
connecting = false;
+ reconnecting = false;
channelCount = 0;
@@ -686,8 +683,14 @@ void QCopClient::init()
QCopClient::~QCopClient()
{
- if (socket)
+ if (disconnectHandler) {
+ delete disconnectHandler;
+ disconnectHandler = 0;
+ }
+ if (socket) {
delete socket;
+ socket = 0;
+ }
}
void QCopClient::registerChannel(const QString& ch)
@@ -986,12 +989,21 @@ void QCopClient::disconnected()
if (!finished) {
finished = true;
if (server) {
- detachAll();
+ detachAll();
deleteLater();
+ } else if (disconnectHandler) {
+ (*disconnectHandler)();
}
}
}
+void QCopClient::reconnect()
+{
+ // Attempt to reconnect after a pause
+ reconnecting = true;
+ QTimer::singleShot(1000, this, SLOT(connectToServer()));
+}
+
#ifndef QT_NO_QCOP_LOCAL_SOCKET
QString QCopThreadData::socketPath()
@@ -1023,7 +1035,14 @@ void QCopClient::connectToServer()
socket->connectToHost(QHostAddress::LocalHost, QCopThreadData::listenPort());
#endif
if (socket->waitForConnected()) {
+ if (reconnecting) {
+ reconnecting = false;
+ foreach (const QString &channel, qcopThreadData()->clientMap.keys()) {
+ registerChannel(channel);
+ }
+ }
connecting = false;
+ retryCount = 0;
device = socket;
connectSignals();
if (pendingData.size() > 0) {
@@ -1035,10 +1054,17 @@ void QCopClient::connectToServer()
delete socket;
socket = 0;
device = 0;
- if (++retryCount < 30)
- QTimer::singleShot(200, this, SLOT(connectToServer()));
- else
- qWarning() << "Could not connect to QCop server; probably not running.";
+
+ if ((++retryCount % 30) == 0) {
+ if (reconnecting) {
+ qWarning() << "Cannot connect to QCop server; retrying...";
+ } else {
+ qWarning() << "Could not connect to QCop server; probably not running.";
+ return;
+ }
+ }
+
+ QTimer::singleShot(retryCount <= 30 ? 200 : 1000, this, SLOT(connectToServer()));
}
}
diff --git a/src/libraries/qtopiamail/support/qcopchannel_p.h b/src/libraries/qtopiamail/support/qcopchannel_p.h
index 1d657371..b1ba7ae1 100644
--- a/src/libraries/qtopiamail/support/qcopchannel_p.h
+++ b/src/libraries/qtopiamail/support/qcopchannel_p.h
@@ -62,8 +62,42 @@ class QCopLoopbackDevice;
class QCopClient : public QObject
{
Q_OBJECT
+
+ struct MemberInvokerBase
+ {
+ virtual ~MemberInvokerBase() {}
+
+ virtual void operator()() = 0;
+ };
+
+ template<typename T>
+ struct MemberInvoker : public MemberInvokerBase
+ {
+ T* instance;
+ void (T::*function)();
+
+ MemberInvoker(T* inst, void (T::*func)())
+ : instance(inst), function(func) {}
+
+ virtual void operator()() { (instance->*function)(); }
+ };
+
public:
- QCopClient();
+ template<typename T>
+ QCopClient(bool connectImmediately, T *instance = 0, void (T::*func)() = 0)
+ : QObject(),
+ server(false),
+ socket(new QCopLocalSocket(this)),
+ device(socket),
+ disconnectHandler(instance ? new MemberInvoker<T>(instance, func) : 0)
+ {
+ init();
+
+ if (connectImmediately) {
+ connectToServer();
+ }
+ }
+
QCopClient(QIODevice *device, QCopLocalSocket *socket);
QCopClient(QIODevice *device, bool isServer);
~QCopClient();
@@ -88,6 +122,8 @@ public:
bool isStartupComplete;
+ void reconnect();
+
signals:
void startupComplete();
@@ -100,9 +136,10 @@ private slots:
private:
bool server;
bool finished;
- QIODevice *device;
QCopLoopbackDevice *loopback;
QCopLocalSocket *socket;
+ QIODevice *device;
+ MemberInvokerBase *disconnectHandler;
void init();
@@ -116,6 +153,7 @@ private:
QByteArray pendingData;
int retryCount;
bool connecting;
+ bool reconnecting;
int channelCount;
void detachAll();
@@ -316,8 +354,9 @@ public:
// Get the client connection object for this thread.
inline QCopClient *clientConnection()
{
- if (!conn)
- conn = new QCopClient();
+ if (!conn) {
+ conn = new QCopClient(true, this, &QCopThreadData::disconnected);
+ }
return conn;
}
@@ -346,6 +385,17 @@ public:
QCopServer *server;
QCopClient *conn;
+
+private:
+ void disconnected()
+ {
+ if (conn) {
+ conn->deleteLater();
+
+ conn = new QCopClient(false, this, &QCopThreadData::disconnected);
+ conn->reconnect();
+ }
+ }
};
#endif
diff --git a/src/plugins/composers/email/attachmentlistwidget.cpp b/src/plugins/composers/email/attachmentlistwidget.cpp
index a245f710..3613bff7 100644
--- a/src/plugins/composers/email/attachmentlistwidget.cpp
+++ b/src/plugins/composers/email/attachmentlistwidget.cpp
@@ -1,3 +1,13 @@
+/****************************************************************************
+**
+** This file is part of the $PACKAGE_NAME$.
+**
+** Copyright (C) $THISYEAR$ $COMPANY_NAME$.
+**
+** $QT_EXTENDED_DUAL_LICENSE$
+**
+****************************************************************************/
+
#include "attachmentlistwidget.h"
#include <QStringListModel>
#include <QListView>
@@ -47,6 +57,7 @@ protected:
void mousePressEvent(QMouseEvent* e);
bool overRemoveLink(QMouseEvent* e);
+
private:
AttachmentListWidget* m_parent;
mutable QRect m_removeButtonRect;
@@ -108,11 +119,15 @@ bool AttachmentListHeader::overRemoveLink(QMouseEvent* e)
class AttachmentListDelegate : public QItemDelegate
{
+ Q_OBJECT
public:
AttachmentListDelegate(AttachmentListWidget* parent = 0);
void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
bool isOverRemoveLink(const QRect& parentRect, const QPoint& pos) const;
+protected slots:
+ bool helpEvent(QHelpEvent * event, QAbstractItemView * view, const QStyleOptionViewItem & option, const QModelIndex & index);
+
private:
QPointer<AttachmentListWidget> m_parent;
};
@@ -150,6 +165,16 @@ bool AttachmentListDelegate::isOverRemoveLink(const QRect& parentRect, const QPo
return textRect.contains(pos);
}
+bool AttachmentListDelegate::helpEvent(QHelpEvent * event, QAbstractItemView * view, const QStyleOptionViewItem & option, const QModelIndex & index )
+{
+ if(!index.isValid())
+ view->setToolTip(QString());
+
+ QString attachment = m_parent->attachmentAt(index.row());
+ view->setToolTip(attachment);
+ return false;
+}
+
class AttachmentListView : public QTreeView
{
Q_OBJECT
@@ -344,6 +369,16 @@ QStringList AttachmentListWidget::attachments() const
return m_attachments;
}
+QString AttachmentListWidget::attachmentAt(int index) const
+{
+ return m_attachments.at(index);
+}
+
+int AttachmentListWidget::count() const
+{
+ return m_attachments.count();
+}
+
bool AttachmentListWidget::isEmpty() const
{
return m_attachments.isEmpty();
diff --git a/src/plugins/composers/email/attachmentlistwidget.h b/src/plugins/composers/email/attachmentlistwidget.h
index 7c72e167..5166c9b3 100644
--- a/src/plugins/composers/email/attachmentlistwidget.h
+++ b/src/plugins/composers/email/attachmentlistwidget.h
@@ -1,3 +1,13 @@
+/****************************************************************************
+**
+** This file is part of the $PACKAGE_NAME$.
+**
+** Copyright (C) $THISYEAR$ $COMPANY_NAME$.
+**
+** $QT_EXTENDED_DUAL_LICENSE$
+**
+****************************************************************************/
+
#ifndef ATTACHMENTLISTWIDGET_H
#define ATTACHMENTLISTWIDGET_H
@@ -19,6 +29,8 @@ class AttachmentListWidget : public QWidget
public:
AttachmentListWidget(QWidget* parent = 0);
QStringList attachments() const;
+ QString attachmentAt(int index) const;
+ int count() const;
bool isEmpty() const;
public slots:
diff --git a/src/plugins/composers/email/emailcomposer.cpp b/src/plugins/composers/email/emailcomposer.cpp
index 7cffbcfa..da2e931c 100644
--- a/src/plugins/composers/email/emailcomposer.cpp
+++ b/src/plugins/composers/email/emailcomposer.cpp
@@ -39,6 +39,7 @@
#include <QFileDialog>
#include "attachmentlistwidget.h"
#include <support/qmailnamespace.h>
+#include <QUrl>
static int minimumLeftWidth = 65;
static const QString placeholder("(no subject)");
@@ -313,16 +314,6 @@ void RecipientListWidget::removeRecipientWidget()
return;
int index = m_widgetList.indexOf(r);
- /*
- bool isEmptySlot = (r->isEmpty() && emptyRecipientSlots() == 1);
- if(r->isEmpty())
- {
- //just move focus back to previous slot
- if(index > 0)
- m_widgetList.at(index-1)->setFocus();
- return;
- }
-*/
r->deleteLater();
m_widgetList.removeAll(r);
@@ -458,49 +449,10 @@ void EmailComposerInterface::setCursorPosition()
}
}
-void EmailComposerInterface::updateAttachmentsLabel()
-{
- /*
- int count = 0;
- int sizeKB = 0;
-
- foreach (const AttachmentItem* item, m_addAttDialog->attachedFiles()) {
- ++count;
- sizeKB += item->sizeKB();
- }
-
- if (count == 0) {
- m_attachmentsLabel->hide();
- } else {
- m_attachmentsLabel->setText(QString("<center><small>") + tr("%n Attachment(s): %1KB","", count).arg(sizeKB)+"</small></center>");
- m_attachmentsLabel->show();
- }
- */
-}
-
void EmailComposerInterface::selectAttachment()
{
QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Select attachments"));
m_attachmentListWidget->addAttachments(fileNames);
-
- /*
- if (m_attachments.isEmpty() && m_addAttDialog->documentSelector()->documents().isEmpty()) {
- QMessageBox::warning(this,
- tr("No documents"),
- tr("There are no existing documents to attach"),
- tr("OK") );
- } else {
- if (QtopiaApplication::execDialog(m_addAttDialog) == QDialog::Accepted) {
- m_attachments.clear();
- foreach (const AttachmentItem *item, m_addAttDialog->attachedFiles())
- m_attachments.append(qMakePair(item->document(), item->action()));
- } else {
- m_addAttDialog->clear();
- foreach (const AttachmentDetail &att, m_attachments)
- m_addAttDialog->attach(att.first, att.second);
- }
- }
- */
}
EmailComposerInterface::EmailComposerInterface( QWidget *parent )
@@ -521,14 +473,6 @@ EmailComposerInterface::EmailComposerInterface( QWidget *parent )
EmailComposerInterface::~EmailComposerInterface()
{
- /*
- // Delete any temporary files we don't need
- foreach (const AttachmentDetail &att, m_attachments) {
- if (att.second == QMailMessage::CopyAndDeleteAttachments) {
- const_cast<QContent&>(att.first).removeFiles();
- }
- }
- */
}
void EmailComposerInterface::init()
@@ -570,11 +514,6 @@ void EmailComposerInterface::init()
m_attachmentsLabel->hide();
layout->addWidget(m_attachmentListWidget = new AttachmentListWidget(this));
-// m_addAttDialog = new AddAttDialog(this, "attachmentDialog");
-// connect(m_addAttDialog,SIGNAL(attachmentsChanged()),this,SLOT(updateAttachmentsLabel()));
-// connect(m_addAttDialog,SIGNAL(attachmentsChanged()),this,SLOT(updateLabel()));
-// connect(m_addAttDialog,SIGNAL(attachmentsChanged()),this,SIGNAL(changed()));
-
//menus
m_attachmentAction = new QAction( QIcon( ":icon/attach" ), tr("Attachments") + "...", this);
connect( m_attachmentAction, SIGNAL(triggered()), this, SLOT(selectAttachment()) );
@@ -665,6 +604,7 @@ QMailMessage EmailComposerInterface::message() const
disposition.setFilename(partName.toLatin1());
QMailMessagePart part = QMailMessagePart::fromFile(filePath, disposition, type, QMailMessageBody::Base64, QMailMessageBody::RequiresEncoding);
+ part.setContentLocation(QUrl::fromLocalFile(filePath).toString());
mail.appendPart(part);
}
}
@@ -682,27 +622,7 @@ void EmailComposerInterface::clear()
m_bodyEdit->clear();
m_attachmentListWidget->clear();
- //m_addAttDialog->clear();
-
- // Delete any temporary files we don't need
- /*
- foreach (const AttachmentDetail &att, m_attachments) {
- if (att.second == QMailMessage::CopyAndDeleteAttachments) {
- const_cast<QContent&>(att.first).removeFiles();
- }
- }
-
- m_attachments.clear();
- */
-}
-
-/*
-void EmailComposerInterface::attach( const QContent &lnk, QMailMessage::AttachmentsAction action )
-{
- m_attachments.append(qMakePair(lnk, action));
- m_addAttDialog->attach(lnk, action);
}
-*/
void EmailComposerInterface::setSignature( const QString &sig )
{
@@ -760,42 +680,16 @@ void EmailComposerInterface::create(const QMailMessage& sourceMail)
int textPart = -1;
for ( uint i = 0; i < sourceMail.partCount(); ++i ) {
QMailMessagePart &part = const_cast<QMailMessagePart&>(sourceMail.partAt(i));
+ QString contentLocation = part.contentLocation().remove(QRegExp("\\s"));
+ bool isLocalAttachment = part.hasBody() && QFile::exists(QUrl(contentLocation).toLocalFile());
- if (textPart == -1 && part.hasBody() && (part.contentType().type().toLower() == "text")) {
+ if (textPart == -1 && part.hasBody() && (part.contentType().type().toLower() == "text") && !isLocalAttachment) {
// This is the first text part, we will use as the forwarded text body
textPart = i;
- } else {
- // Save the existing part data to a temporary file
- QString fileName(part.writeBodyTo(QMail::tempPath()));
- if (fileName.isEmpty()) {
- qWarning() << "Unable to save part to temporary file!";
- } else {
- /*
- // Create a content object for the file
- QContent doc(fileName);
-
- if (part.referenceType() == QMailMessagePart::None) {
- QMailMessageContentType type(part.contentType());
-
- if (doc.drmState() == QContent::Unprotected)
- doc.setType(type.content());
- } else {
- QString partLocation = part.location().toString(true);
- if (!partLocation.isEmpty()) {
- doc.setProperty("qtopiamail/partLocation", partLocation);
- }
- }
-
- doc.setName(part.displayName());
- doc.setRole(QContent::Data);
- doc.commit();
-
- attach(doc, QMailMessage::CopyAndDeleteAttachments);
- */
+ } else if(isLocalAttachment) {
+ m_attachmentListWidget->addAttachment(QUrl(contentLocation).toLocalFile());
}
}
- }
-
if (textPart != -1) {
const QMailMessagePart& part = sourceMail.partAt(textPart);
setPlainText( part.body().data(), m_signature );
diff --git a/src/plugins/composers/email/emailcomposer.h b/src/plugins/composers/email/emailcomposer.h
index aae3a7e1..b04b0cf9 100644
--- a/src/plugins/composers/email/emailcomposer.h
+++ b/src/plugins/composers/email/emailcomposer.h
@@ -50,14 +50,12 @@ public:
public slots:
void clear();
- //void attach( const QContent &lnk, QMailMessage::AttachmentsAction = QMailMessage::LinkToAttachments );
void setSignature( const QString &sig );
protected slots:
void selectAttachment();
void updateLabel();
void setCursorPosition();
- void updateAttachmentsLabel();
private:
void create(const QMailMessage& source);
diff --git a/src/plugins/contentmanagers/qtopiamailfile/qtopiamailfilemanager.cpp b/src/plugins/contentmanagers/qtopiamailfile/qtopiamailfilemanager.cpp
index c53478ff..9a8b0a66 100644
--- a/src/plugins/contentmanagers/qtopiamailfile/qtopiamailfilemanager.cpp
+++ b/src/plugins/contentmanagers/qtopiamailfile/qtopiamailfilemanager.cpp
@@ -20,6 +20,7 @@
#include <unistd.h>
#include <time.h>
#include <QtPlugin>
+#include <QUrl>
namespace {
@@ -62,7 +63,7 @@ QString generateUniqueFileName(const QMailAccountId &accountId, const QString &n
// Format: seconds_epoch.pid.randomchars
bool exists = true;
const qint64 pid = ::getpid();
-
+
QString filename;
QString path;
@@ -209,10 +210,11 @@ QMailStore::ErrorCode QtopiamailfileManager::addOrRename(QMailMessage *message,
// Write the message to file (not including sub-part contents)
QDataStream out(&file);
- message->toRfc2822(out, QMailMessage::StorageFormat);
+ message->toRfc2822(out, QMailMessage::StorageFormat);
+ bool isOk = out.status() != QDataStream::Ok;
if ((out.status() != QDataStream::Ok) ||
// Write each part to file
- ((message->multipartType() != QMailMessagePartContainer::MultipartNone) &&
+ ((message->multipartType() != QMailMessagePartContainer::MultipartNone) &&
!addOrRenameParts(message, *message, message->contentIdentifier(), existingIdentifier))) {
// Remove the file
qMailLog(Messaging) << "Unable to save message content, removing temporary file:" << filePath;
@@ -416,6 +418,12 @@ QString QtopiamailfileManager::messagePartDirectory(const QString &fileName)
return fileName + "-parts";
}
+static bool isLocalAttachment(const QMailMessagePart& part)
+{
+ QString contentLocation = part.contentLocation().remove(QRegExp("\\s"));
+ return QFile::exists(QUrl(contentLocation).toLocalFile()) && !part.hasBody();
+}
+
bool QtopiamailfileManager::addOrRenameParts(QMailMessage *message, const QMailMessagePartContainer &container, const QString &fileName, const QString &existing)
{
// Ensure that the part directory exists
@@ -445,7 +453,7 @@ bool QtopiamailfileManager::addOrRenameParts(QMailMessage *message, const QMailM
additionRequired = true;
}
- if (additionRequired) {
+ if (additionRequired && !isLocalAttachment(part)) {
// We can only write the content in decoded form if it is complete
QMailMessageBody::EncodingFormat outputFormat(part.contentAvailable() ? QMailMessageBody::Decoded : QMailMessageBody::Encoded);
@@ -463,7 +471,7 @@ bool QtopiamailfileManager::addOrRenameParts(QMailMessage *message, const QMailM
}
}
}
-
+
QFile file(partFilePath);
if (!file.open(QIODevice::WriteOnly)) {
qMailLog(Messaging) << "Unable to open new message part content file:" << partFilePath;
@@ -533,7 +541,13 @@ bool QtopiamailfileManager::loadParts(QMailMessage *message, QMailMessagePartCon
}
} else {
if (part.multipartType() == QMailMessagePartContainer::MultipartNone) {
- QString partFilePath(messagePartFilePath(part, fileName));
+ QString partFilePath;
+ bool localAttachment = QFile::exists(QUrl(part.contentLocation()).toLocalFile()) && !part.hasBody();
+ if(localAttachment)
+ partFilePath = QUrl(part.contentLocation()).toLocalFile();
+ else
+ partFilePath = (messagePartFilePath(part, fileName));
+
if (QFile::exists(partFilePath)) {
// Is the file content in encoded or decoded form? Since we're delivering
// server-side data, the parameter seems reversed...
diff --git a/src/plugins/messageservices/imap/imapclient.cpp b/src/plugins/messageservices/imap/imapclient.cpp
index 8a9c7b6e..af239b1a 100644
--- a/src/plugins/messageservices/imap/imapclient.cpp
+++ b/src/plugins/messageservices/imap/imapclient.cpp
@@ -639,8 +639,8 @@ void ImapClient::mailboxListed(QString &flags, QString &delimiter, QString &path
if (boxId.isValid()) {
// This element already exists
if (mailboxPath == path) {
- QMailFolder folder(boxId);
- _strategyContext->mailboxListed(folder, flags);
+ QMailFolder folder(boxId);
+ _strategyContext->mailboxListed(folder, flags, delimiter);
}
parentId = boxId;
@@ -650,9 +650,16 @@ void ImapClient::mailboxListed(QString &flags, QString &delimiter, QString &path
folder.setDisplayName(decodeFolderName(*it));
folder.setStatus(QMailFolder::SynchronizationEnabled, true);
- _strategyContext->mailboxListed(folder, flags);
+ // The reported flags pertain to the listed folder only
+ QString folderFlags;
+ if (mailboxPath == path) {
+ folderFlags = flags;
+ }
+
+ _strategyContext->mailboxListed(folder, folderFlags, delimiter);
boxId = mailboxId(mailboxPath);
+ parentId = boxId;
}
}
}
@@ -1021,13 +1028,13 @@ void ImapClient::cancelTransfer()
void ImapClient::retrieveOperationCompleted()
{
+ deactivateConnection();
+
// This retrieval may have been asynchronous
emit allMessagesReceived();
// Or it may have been requested by a waiting client
emit retrievalCompleted();
-
- deactivateConnection();
}
void ImapClient::deactivateConnection()
diff --git a/src/plugins/messageservices/imap/imapprotocol.cpp b/src/plugins/messageservices/imap/imapprotocol.cpp
index 52a2ada6..97409ce1 100644
--- a/src/plugins/messageservices/imap/imapprotocol.cpp
+++ b/src/plugins/messageservices/imap/imapprotocol.cpp
@@ -1091,6 +1091,12 @@ void UidFetchState::untaggedResponse(ImapContext *c, const QString &line)
parseFlags(str, fp.mNewMsgFlags);
}
+ if (fp.mNewMsgFlags & MFlag_Deleted) {
+ // This message has been deleted - there is no more information to process
+ emit nonexistentUid(fp.mNewMsgUid);
+ return;
+ }
+
if (fp.mDataItems & F_Date) {
fp.mDate = extractDate(str);
}
diff --git a/src/plugins/messageservices/imap/imapservice.cpp b/src/plugins/messageservices/imap/imapservice.cpp
index 96849e04..ded9fbc4 100644
--- a/src/plugins/messageservices/imap/imapservice.cpp
+++ b/src/plugins/messageservices/imap/imapservice.cpp
@@ -30,6 +30,7 @@ public:
_service(service),
_flagsCheckQueued(false),
_queuedMailCheckInProgress(false),
+ _mailCheckPhase(RetrieveFolders),
_unavailable(false),
_synchronizing(false),
_actionCompletedSignal(0)
@@ -81,9 +82,13 @@ public slots:
private:
virtual bool setStrategy(ImapStrategy *strategy, void (ImapService::Source::*signal)(const QMailMessageIdList&) = 0);
+ enum MailCheckPhase { RetrieveFolders = 0, RetrieveMessages, CheckFlags };
+
ImapService *_service;
bool _flagsCheckQueued;
bool _queuedMailCheckInProgress;
+ MailCheckPhase _mailCheckPhase;
+ QMailFolderId _mailCheckFolderId;
bool _unavailable;
bool _synchronizing;
QTimer _intervalTimer;
@@ -101,6 +106,7 @@ bool ImapService::Source::retrieveFolderList(const QMailAccountId &accountId, co
_service->_client.strategyContext()->foldersOnlyStrategy.setBase(folderId);
_service->_client.strategyContext()->foldersOnlyStrategy.setDescending(descending);
+ _service->_client.strategyContext()->foldersOnlyStrategy.clearSelection();
return setStrategy(&_service->_client.strategyContext()->foldersOnlyStrategy);
}
@@ -119,11 +125,15 @@ bool ImapService::Source::retrieveMessageList(const QMailAccountId &accountId, c
if (folderId.isValid()) {
folderIds.append(folderId);
} else {
- // Retrieve messages for all folders in the account
- folderIds = QMailStore::instance()->queryFolders(QMailFolderKey::parentAccountId(accountId), QMailFolderSortKey::id(Qt::AscendingOrder));
+ // Retrieve messages for all folders in the account that have undiscovered messages
+ QMailFolderKey accountKey(QMailFolderKey::parentAccountId(accountId));
+ QMailFolderKey undiscoveredKey(QMailFolderKey::serverUndiscoveredCount(0, QMailDataComparator::GreaterThan));
+
+ folderIds = QMailStore::instance()->queryFolders(accountKey & undiscoveredKey, QMailFolderSortKey::id(Qt::AscendingOrder));
}
_service->_client.strategyContext()->retrieveMessageListStrategy.setMinimum(minimum);
+ _service->_client.strategyContext()->retrieveMessageListStrategy.clearSelection();
_service->_client.strategyContext()->retrieveMessageListStrategy.selectedFoldersAppend(folderIds);
return setStrategy(&_service->_client.strategyContext()->retrieveMessageListStrategy);
}
@@ -227,6 +237,7 @@ bool ImapService::Source::retrieveAll(const QMailAccountId &accountId)
_service->_client.strategyContext()->retrieveAllStrategy.setBase(QMailFolderId());
_service->_client.strategyContext()->retrieveAllStrategy.setDescending(true);
+ _service->_client.strategyContext()->retrieveAllStrategy.clearSelection();
_service->_client.strategyContext()->retrieveAllStrategy.setOperation(QMailRetrievalAction::MetaData);
return setStrategy(&_service->_client.strategyContext()->retrieveAllStrategy);
}
@@ -237,11 +248,8 @@ bool ImapService::Source::exportUpdates(const QMailAccountId &accountId)
_service->errorOccurred(QMailServiceAction::Status::ErrInvalidData, tr("No account specified"));
return false;
}
- _service->_client.strategyContext()->exportUpdatesStrategy.setBase(QMailFolderId());
- _service->_client.strategyContext()->exportUpdatesStrategy.setDescending(true);
- _service->_client.strategyContext()->exportUpdatesStrategy.setOperation(QMailRetrievalAction::Content);
+
_service->_client.strategyContext()->exportUpdatesStrategy.clearSelection();
- _service->_client.strategyContext()->exportUpdatesStrategy.selectedMailsAppend(QMailMessageIdList());
return setStrategy(&_service->_client.strategyContext()->exportUpdatesStrategy);
}
@@ -254,6 +262,7 @@ bool ImapService::Source::synchronize(const QMailAccountId &accountId)
_service->_client.strategyContext()->synchronizeAccountStrategy.setBase(QMailFolderId());
_service->_client.strategyContext()->synchronizeAccountStrategy.setDescending(true);
+ _service->_client.strategyContext()->synchronizeAccountStrategy.clearSelection();
_service->_client.strategyContext()->synchronizeAccountStrategy.setOperation(QMailRetrievalAction::MetaData);
return setStrategy(&_service->_client.strategyContext()->synchronizeAccountStrategy);
}
@@ -388,8 +397,13 @@ void ImapService::Source::retrievalCompleted()
_unavailable = false;
if (_queuedMailCheckInProgress) {
- _queuedMailCheckInProgress = false;
- emit _service->availabilityChanged(true);
+ if (_mailCheckPhase == RetrieveFolders) {
+ _mailCheckPhase = RetrieveMessages;
+ retrieveMessageList(_service->accountId(), _mailCheckFolderId, 1, QMailMessageSortKey());
+ } else {
+ _queuedMailCheckInProgress = false;
+ emit _service->availabilityChanged(true);
+ }
}
emit _service->activityChanged(QMailServiceAction::Successful);
@@ -431,9 +445,11 @@ void ImapService::Source::queueMailCheck(QMailFolderId folderId)
_queuedFolders.removeAll(folderId);
_queuedMailCheckInProgress = true;
+ _mailCheckPhase = RetrieveFolders;
+ _mailCheckFolderId = folderId;
emit _service->availabilityChanged(false);
- retrieveMessageList(_service->accountId(), folderId, 1, QMailMessageSortKey());
+ retrieveFolderList(_service->accountId(), folderId, true);
}
void ImapService::Source::queueFlagsChangedCheck()
@@ -445,6 +461,7 @@ void ImapService::Source::queueFlagsChangedCheck()
_flagsCheckQueued = false;
_queuedMailCheckInProgress = true;
+ _mailCheckPhase = CheckFlags;
emit _service->availabilityChanged(false);
diff --git a/src/plugins/messageservices/imap/imapstrategy.cpp b/src/plugins/messageservices/imap/imapstrategy.cpp
index 5dc1fce8..7d3add87 100644
--- a/src/plugins/messageservices/imap/imapstrategy.cpp
+++ b/src/plugins/messageservices/imap/imapstrategy.cpp
@@ -92,21 +92,12 @@ static void updateMessagesMetaData(ImapStrategyContextBase *context,
context->completedMessageAction(uid);
}
- // Compensate for MS exchange temporarily failing to report existence of messages
- QMailMessageKey existentUidKey(storedKey & reportedKey);
- QMailMessageKey removedUidKey(QMailMessageKey::status(QMailMessage::Removed, QMailDataComparator::Includes));
- QMailMessageKey onServerButRemovedInStore(removedUidKey & existentUidKey);
- if (!QMailStore::instance()->updateMessagesMetaData(onServerButRemovedInStore, QMailMessage::Removed, false)) {
- qWarning() << "Unable to update unremoved message metadata for account:" << context->config().id();
- }
-
// Update any messages that are reported as read elsewhere, that previously were not
if (!QMailStore::instance()->updateMessagesMetaData(seenKey & unreadElsewhereKey, QMailMessage::ReadElsewhere, true)) {
qWarning() << "Unable to update read message metadata for account:" << context->config().id();
}
}
-
ImapClient *ImapStrategyContextBase::client()
{
return _client;
@@ -164,6 +155,9 @@ void ImapStrategy::newConnection(ImapStrategyContextBase *context)
{
_transferState = Init;
+ ImapConfiguration imapCfg(context->config());
+ _baseFolder = imapCfg.baseFolder();
+
initialAction(context);
}
@@ -180,11 +174,18 @@ void ImapStrategy::initialAction(ImapStrategyContextBase *context)
}
}
-void ImapStrategy::mailboxListed(ImapStrategyContextBase *, QMailFolder& folder, const QString &flags)
+void ImapStrategy::mailboxListed(ImapStrategyContextBase *, QMailFolder& folder, const QString &flags, const QString &delimiter)
{
if (!folder.id().isValid()) {
- if (!QMailStore::instance()->addFolder(&folder)) {
- qWarning() << "Unable to add folder for account:" << folder.parentAccountId() << "path:" << folder.path();
+ // Only folders beneath the base folder are relevant
+ QString path(folder.path());
+
+ if (_baseFolder.isEmpty() ||
+ (path.startsWith(_baseFolder, Qt::CaseInsensitive) && (path.length() == _baseFolder.length())) ||
+ (path.startsWith(_baseFolder + delimiter, Qt::CaseInsensitive))) {
+ if (!QMailStore::instance()->addFolder(&folder)) {
+ qWarning() << "Unable to add folder for account:" << folder.parentAccountId() << "path:" << folder.path();
+ }
}
}
@@ -263,7 +264,7 @@ void ImapStrategy::downloadSize(ImapStrategyContextBase *context, const QString
/* A strategy that provides an interface for defining a set of messages
- or message parts to operate on, and an abstract interface messageAction()
+ or message parts to operate on, and an abstract interface messageListMessageAction()
for operating on messages.
Also implements logic to determine which messages or message part to operate
@@ -272,6 +273,7 @@ void ImapStrategy::downloadSize(ImapStrategyContextBase *context, const QString
void ImapMessageListStrategy::clearSelection()
{
_selectionMap.clear();
+ _folderItr = _selectionMap.end();
}
void ImapMessageListStrategy::selectedMailsAppend(const QMailMessageIdList& ids)
@@ -345,13 +347,13 @@ void ImapMessageListStrategy::transition(ImapStrategyContextBase *context, ImapC
void ImapMessageListStrategy::handleLogin(ImapStrategyContextBase *context)
{
- messageAction(context);
+ messageListMessageAction(context);
}
void ImapMessageListStrategy::handleSelect(ImapStrategyContextBase *context)
{
// We're completing a message or section
- messageAction(context);
+ messageListMessageAction(context);
}
bool ImapMessageListStrategy::computeStartEndPartRange(ImapStrategyContextBase *context)
@@ -384,6 +386,11 @@ bool ImapMessageListStrategy::selectNextMessageSequence(ImapStrategyContextBase
QMailMessagePart::Location location;
int minimum = SectionProperties::All;
+ if (_folderItr == _selectionMap.end()) {
+ messageListCompleted(context);
+ return false;
+ }
+
FolderMap::ConstIterator selectionEnd = _folderItr.value().end();
while (_selectionItr == selectionEnd) {
++_folderItr;
@@ -396,7 +403,7 @@ bool ImapMessageListStrategy::selectNextMessageSequence(ImapStrategyContextBase
if ((_folderItr == _selectionMap.end()) || !_folderItr.key().isValid()) {
_currentMailbox = QMailFolder();
_selectionMap.clear();
- folderAction(context);
+ messageListFolderAction(context);
return false;
}
@@ -404,7 +411,7 @@ bool ImapMessageListStrategy::selectNextMessageSequence(ImapStrategyContextBase
mailboxId = _folderItr.key();
if (mailboxId != _currentMailbox.id()) {
_currentMailbox = QMailFolder(mailboxId);
- folderAction(context);
+ messageListFolderAction(context);
return false;
}
mailboxIdStr = QString::number(mailboxId.toULongLong()) + '|';
@@ -443,7 +450,7 @@ bool ImapMessageListStrategy::selectNextMessageSequence(ImapStrategyContextBase
return true;
}
-void ImapMessageListStrategy::folderAction(ImapStrategyContextBase *context)
+void ImapMessageListStrategy::messageListFolderAction(ImapStrategyContextBase *context)
{
if (_currentMailbox.id().isValid()) {
if (_currentMailbox.id() == context->mailbox().id) {
@@ -453,11 +460,11 @@ void ImapMessageListStrategy::folderAction(ImapStrategyContextBase *context)
context->protocol().sendSelect(_currentMailbox);
}
} else {
- completedAction(context);
+ messageListCompleted(context);
}
}
-void ImapMessageListStrategy::completedAction(ImapStrategyContextBase *context)
+void ImapMessageListStrategy::messageListCompleted(ImapStrategyContextBase *context)
{
context->operationCompleted();
}
@@ -586,15 +593,15 @@ void ImapFetchSelectedMessagesStrategy::handleLogin(ImapStrategyContextBase *con
if (_totalRetrievalSize)
context->progressChanged(0, _totalRetrievalSize);
- messageAction(context);
+ messageListMessageAction(context);
}
void ImapFetchSelectedMessagesStrategy::handleUidFetch(ImapStrategyContextBase *context)
{
- messageAction(context);
+ messageListMessageAction(context);
}
-void ImapFetchSelectedMessagesStrategy::messageAction(ImapStrategyContextBase *context)
+void ImapFetchSelectedMessagesStrategy::messageListMessageAction(ImapStrategyContextBase *context)
{
if (selectNextMessageSequence(context)) {
QStringList uids;
@@ -712,14 +719,14 @@ void ImapFolderListStrategy::handleLogin(ImapStrategyContextBase *context)
{
_transferState = List;
- processNextMailbox(context);
+ processNextFolder(context);
}
void ImapFolderListStrategy::handleList(ImapStrategyContextBase *context)
{
if (!_currentMailbox.id().isValid()) {
// Try to proceed to another mailbox
- processNextMailbox(context);
+ processNextFolder(context);
} else {
// If the current folder is not yet selected
if (_currentMailbox.id() != context->mailbox().id) {
@@ -727,7 +734,7 @@ void ImapFolderListStrategy::handleList(ImapStrategyContextBase *context)
FolderStatus folderState = _folderStatus[_currentMailbox.id()];
if (folderState & NoSelect) {
// We can't select this folder
- processNextMailbox(context);
+ processNextFolder(context);
} else {
// Select this folder
context->protocol().sendSelect( _currentMailbox );
@@ -735,11 +742,11 @@ void ImapFolderListStrategy::handleList(ImapStrategyContextBase *context)
}
} else {
// This folder does not exist, according to the listing...
- processNextMailbox(context);
+ processNextFolder(context);
}
} else {
// This mailbox is selected
- processMailbox(context);
+ folderListFolderAction(context);
}
}
}
@@ -750,14 +757,19 @@ void ImapFolderListStrategy::handleSelect(ImapStrategyContextBase *context)
// We have selected this folder - find out how many undiscovered messages exist
// We need the UID of the most recent message we have previously discovered in this folder
- QMailMessageKey key(QMailMessageKey::parentFolderId(_currentMailbox.id()));
- QMailMessageSortKey sortKey(QMailMessageSortKey::id(Qt::DescendingOrder));
-
- QMailMessageIdList messageIds(QMailStore::instance()->queryMessages(key, sortKey));
- if (!messageIds.isEmpty()) {
- // Find this message's MSN
- QMailMessageMetaData message(messageIds.first());
- context->protocol().sendSearch(0, QString("UID ") + ImapProtocol::uid(message.serverUid()));
+ QMailFolderId folderId(context->mailbox().id);
+ QMailFolder folder(folderId);
+
+ // toUint returns 0 on error, which is an invalid IMAP uid
+ int clientMax(folder.customField("qmf-max-serveruid").toUInt());
+
+ if (clientMax && context->mailbox().exists) {
+ if (context->mailbox().uidNext > (clientMax + 1)) {
+ context->protocol().sendSearch(0, QString("UID %1:%2").arg(clientMax + 1).arg(context->mailbox().uidNext));
+ } else {
+ // There's no need to search if (clientMax <= (UIDNEXT - 1))
+ handleSearch(context);
+ }
} else {
// No messages - nothing to discover...
handleSearch(context);
@@ -772,29 +784,28 @@ void ImapFolderListStrategy::handleSearch(ImapStrategyContextBase *context)
updateUndiscoveredCount(context);
// We have finished with this folder
- processMailbox(context);
+ folderListFolderAction(context);
}
-void ImapFolderListStrategy::processMailbox(ImapStrategyContextBase *context)
+void ImapFolderListStrategy::folderListFolderAction(ImapStrategyContextBase *context)
{
// The current mailbox is now selected - subclasses clients should do something now
// Go onto the next mailbox
- processNextMailbox(context);
+ processNextFolder(context);
}
-void ImapFolderListStrategy::processNextMailbox(ImapStrategyContextBase *context)
+void ImapFolderListStrategy::processNextFolder(ImapStrategyContextBase *context)
{
- if (getnextMailbox()) {
- newfolderAction(context);
+ if (nextFolder()) {
+ processFolder(context);
return;
}
- listCompleted(context);
+ folderListCompleted(context);
}
-// TODO: change this name
-bool ImapFolderListStrategy::getnextMailbox()
+bool ImapFolderListStrategy::nextFolder()
{
while (!_mailboxIds.isEmpty()) {
QMailFolderId folderId(_mailboxIds.takeFirst());
@@ -818,70 +829,57 @@ bool ImapFolderListStrategy::getnextMailbox()
return false;
}
-// TODO: change this name
-void ImapFolderListStrategy::newfolderAction(ImapStrategyContextBase *context)
+void ImapFolderListStrategy::processFolder(ImapStrategyContextBase *context)
{
- if (_folderStatus.contains(_currentMailbox.id())) {
- // We already have the status for this folder - select it
- context->protocol().sendSelect(_currentMailbox);
- } else {
- // List the contents of the parent of this folder, to see if we can select it
- QMailFolderId parentFolderId(_currentMailbox.parentFolderId());
- if (parentFolderId.isValid()) {
- context->protocol().sendList(QMailFolder(parentFolderId), "%");
- } else {
- QMailFolder root;
- ImapConfiguration imapCfg(context->config());
- if (!imapCfg.baseFolder().isEmpty()) {
- root.setPath(imapCfg.baseFolder());
- }
-
- context->protocol().sendList(root, "%");
- }
- }
+ // Attempt to select the current folder
+ context->protocol().sendSelect(_currentMailbox);
}
-void ImapFolderListStrategy::listCompleted(ImapStrategyContextBase *context)
+void ImapFolderListStrategy::folderListCompleted(ImapStrategyContextBase *context)
{
- // We have retrieved all the folders
- completedAction(context);
+ // We have retrieved all the folders - process any messages
+ messageListMessageAction(context);
}
-void ImapFolderListStrategy::mailboxListed(ImapStrategyContextBase *context, QMailFolder &folder, const QString &flags)
+void ImapFolderListStrategy::mailboxListed(ImapStrategyContextBase *context, QMailFolder &folder, const QString &flags, const QString &delimiter)
{
- ImapStrategy::mailboxListed(context, folder, flags);
+ ImapStrategy::mailboxListed(context, folder, flags, delimiter);
- // Record the status of the listed mailbox
- int status = 0;
- if (flags.indexOf("NoInferiors", 0, Qt::CaseInsensitive) != -1)
- status |= NoInferiors;
- if (flags.indexOf("NoSelect", 0, Qt::CaseInsensitive) != -1)
- status |= NoSelect;
- if (flags.indexOf("Marked", 0, Qt::CaseInsensitive) != -1)
- status |= Marked;
- if (flags.indexOf("Unmarked", 0, Qt::CaseInsensitive) != -1)
- status |= Unmarked;
- if (flags.indexOf("HasChildren", 0, Qt::CaseInsensitive) != -1)
- status |= HasChildren;
- if (flags.indexOf("HasNoChildren", 0, Qt::CaseInsensitive) != -1)
- status |= HasNoChildren;
+ if (folder.id().isValid()) {
+ // Record the status of the listed mailbox
+ int status = 0;
+ if (flags.indexOf("NoInferiors", 0, Qt::CaseInsensitive) != -1)
+ status |= NoInferiors;
+ if (flags.indexOf("NoSelect", 0, Qt::CaseInsensitive) != -1)
+ status |= NoSelect;
+ if (flags.indexOf("Marked", 0, Qt::CaseInsensitive) != -1)
+ status |= Marked;
+ if (flags.indexOf("Unmarked", 0, Qt::CaseInsensitive) != -1)
+ status |= Unmarked;
+ if (flags.indexOf("HasChildren", 0, Qt::CaseInsensitive) != -1)
+ status |= HasChildren;
+ if (flags.indexOf("HasNoChildren", 0, Qt::CaseInsensitive) != -1)
+ status |= HasNoChildren;
- _folderStatus[folder.id()] = static_cast<FolderStatus>(status);
+ _folderStatus[folder.id()] = static_cast<FolderStatus>(status);
+ }
}
void ImapFolderListStrategy::updateUndiscoveredCount(ImapStrategyContextBase *context)
{
- // We should have the MSN of the our most recent message
- uint msn = 0;
- if (!context->mailbox().msnList.isEmpty()) {
- msn = context->mailbox().msnList.first();
- }
+ // Initial case set the undiscovered count to exists in the case of no
+ // max-serveruid set for the folder
+ int undiscovered(context->mailbox().exists);
- // The difference between the server count and the MSN of our message should yield the undiscovered count
- // Note: MSN is 1-based, count is 0-based.
QMailFolder folder(_currentMailbox.id());
- int undiscovered = folder.serverCount() - msn;
- if ((undiscovered >= 0) && (uint(undiscovered) != folder.serverUndiscoveredCount())) {
+ int clientMax(folder.customField("qmf-max-serveruid").toUInt());
+ if (clientMax) {
+ // The undiscovered count for a folder is the number of messages on the server newer
+ // than the most recent (highest server uid) message in the folder.
+ undiscovered = context->mailbox().msnList.count();
+ }
+
+ if (uint(undiscovered) != folder.serverUndiscoveredCount()) {
folder.setServerUndiscoveredCount(undiscovered);
if (!QMailStore::instance()->updateFolder(&folder)) {
@@ -917,7 +915,7 @@ void ImapSynchronizeBaseStrategy::handleSelect(ImapStrategyContextBase *context)
fetchNextMailPreview(context);
} else if (_transferState == Complete) {
// We're completing a message or section
- messageAction(context);
+ messageListMessageAction(context);
} else {
ImapFolderListStrategy::handleSelect(context);
}
@@ -928,7 +926,7 @@ void ImapSynchronizeBaseStrategy::handleUidFetch(ImapStrategyContextBase *contex
if (_transferState == Preview) { //getting headers
fetchNextMailPreview(context);
} else if (_transferState == Complete) { //getting complete messages
- messageAction(context);
+ messageListMessageAction(context);
}
}
@@ -952,52 +950,44 @@ void ImapSynchronizeBaseStrategy::previewDiscoveredMessages(ImapStrategyContextB
_transferState = Preview;
- if (!selectNextMailbox(context)) {
+ if (!selectNextPreviewFolder(context)) {
// Could be no mailbox has been selected to be stored locally
- completedAction(context);
+ messageListCompleted(context);
}
}
-bool ImapSynchronizeBaseStrategy::selectNextMailbox(ImapStrategyContextBase *context)
+bool ImapSynchronizeBaseStrategy::selectNextPreviewFolder(ImapStrategyContextBase *context)
{
- _newUids = QStringList();
+ if (_retrieveUids.isEmpty()) {
+ _currentMailbox = QMailFolder();
+ _newUids = QStringList();
+ return false;
+ }
- if (nextMailbox(context)) {
- FolderStatus folderState = _folderStatus[_currentMailbox.id()];
- if (folderState & NoSelect) {
- // Bypass the select and UID search, and go directly to the search result handler
- processUidSearchResults(context);
- } else {
- if (_currentMailbox.id() == context->mailbox().id) {
- // We already have the appropriate mailbox selected
- handleSelect(context);
- } else {
- if (_transferState == List) {
- QString status = QObject::tr("Checking", "Checking <mailbox name>") + QChar(' ') + _currentMailbox.displayName();
- context->updateStatus( status );
- }
+ // In preview mode, select the mailboxes where retrievable messages are located
+ QPair<QMailFolderId, QStringList> next = _retrieveUids.takeFirst();
+ _currentMailbox = QMailFolder(next.first);
+ _newUids = next.second;
- context->protocol().sendSelect( _currentMailbox );
- }
- }
- return true;
+ FolderStatus folderState = _folderStatus[_currentMailbox.id()];
+ if (folderState & NoSelect) {
+ // Bypass the select and UID search, and go directly to the search result handler
+ processUidSearchResults(context);
} else {
- return false;
- }
-}
+ if (_currentMailbox.id() == context->mailbox().id) {
+ // We already have the appropriate mailbox selected
+ handleSelect(context);
+ } else {
+ if (_transferState == List) {
+ QString status = QObject::tr("Checking", "Checking <mailbox name>") + QChar(' ') + _currentMailbox.displayName();
+ context->updateStatus( status );
+ }
-bool ImapSynchronizeBaseStrategy::nextMailbox(ImapStrategyContextBase *)
-{
- if ((_transferState == Preview) && !_retrieveUids.isEmpty()) {
- // In fetch mode, return the mailboxes where retrievable messages are located
- QPair<QMailFolderId, QStringList> next = _retrieveUids.takeFirst();
- _currentMailbox = QMailFolder(next.first);
- _newUids = next.second;
- return true;
+ context->protocol().sendSelect( _currentMailbox );
+ }
}
- _currentMailbox = QMailFolder();
- return false;
+ return true;
}
void ImapSynchronizeBaseStrategy::fetchNextMailPreview(ImapStrategyContextBase *context)
@@ -1010,13 +1000,19 @@ void ImapSynchronizeBaseStrategy::fetchNextMailPreview(ImapStrategyContextBase *
context->protocol().sendUidFetch(MetaDataFetchFlags, IntegerRegion(uidList).toString());
_newUids = _newUids.mid(uidList.count());
- } else if (!selectNextMailbox(context)) {
+ return;
+ }
+
+ previewingCompleted(context);
+ if (!selectNextPreviewFolder(context)) {
+ // No more messages to preview
if ((_transferState == Preview) || (_retrieveUids.isEmpty())) {
if (!_completionList.isEmpty() || !_completionSectionList.isEmpty()) {
// Fetch the messages that need completion
clearSelection();
+
selectedMailsAppend(_completionList);
- _completionList.clear();
+
QList<QPair<QMailMessagePart::Location, uint> >::const_iterator it = _completionSectionList.begin(), end = _completionSectionList.end();
for ( ; it != end; ++it) {
if (it->second != 0) {
@@ -1025,15 +1021,23 @@ void ImapSynchronizeBaseStrategy::fetchNextMailPreview(ImapStrategyContextBase *
selectedSectionsAppend(it->first);
}
}
+
+ _completionList.clear();
_completionSectionList.clear();
- messageAction(context);
+
+ messageListMessageAction(context);
} else {
- completedAction(context);
+ // No messages to be completed
+ messageListCompleted(context);
}
}
}
}
+void ImapSynchronizeBaseStrategy::previewingCompleted(ImapStrategyContextBase *)
+{
+}
+
void ImapSynchronizeBaseStrategy::recursivelyCompleteParts(ImapStrategyContextBase *context,
const QMailMessagePartContainer &partContainer,
int &partsToRetrieve,
@@ -1137,6 +1141,7 @@ void ImapRetrieveFolderListStrategy::setDescending(bool descending)
void ImapRetrieveFolderListStrategy::newConnection(ImapStrategyContextBase *context)
{
_mailboxList.clear();
+ _ancestorPaths.clear();
ImapSynchronizeBaseStrategy::newConnection(context);
}
@@ -1151,8 +1156,6 @@ void ImapRetrieveFolderListStrategy::handleLogin(ImapStrategyContextBase *contex
ImapConfiguration imapCfg(context->config());
if (_baseId.isValid()) {
folderId = _baseId;
- } else {
- folderId = context->client()->mailboxId(imapCfg.baseFolder());
}
_transferState = List;
@@ -1163,12 +1166,7 @@ void ImapRetrieveFolderListStrategy::handleLogin(ImapStrategyContextBase *contex
ImapSynchronizeBaseStrategy::handleLogin(context);
} else {
// We need to search for folders at the account root
- QMailFolder root;
- if (!imapCfg.baseFolder().isEmpty()) {
- root.setPath(imapCfg.baseFolder());
- }
-
- context->protocol().sendList(root, "%");
+ context->protocol().sendList(QMailFolder(), "%");
}
}
@@ -1182,41 +1180,73 @@ void ImapRetrieveFolderListStrategy::handleSearch(ImapStrategyContextBase *conte
// Find the child folders of this mailbox
context->protocol().sendList(_currentMailbox, "%");
} else {
- processMailbox(context);
+ folderListFolderAction(context);
+ }
+}
+
+void ImapRetrieveFolderListStrategy::handleList(ImapStrategyContextBase *context)
+{
+ if (!_currentMailbox.id().isValid()) {
+ // See if there are any more ancestors to search
+ if (!_ancestorSearchPaths.isEmpty()) {
+ QMailFolder ancestor;
+ ancestor.setPath(_ancestorSearchPaths.takeFirst());
+
+ context->protocol().sendList(ancestor, "%");
+ return;
+ }
}
+
+ ImapSynchronizeBaseStrategy::handleList(context);
}
-void ImapRetrieveFolderListStrategy::processNextMailbox(ImapStrategyContextBase *context)
+void ImapRetrieveFolderListStrategy::processNextFolder(ImapStrategyContextBase *context)
{
- if (getnextMailbox()) {
- newfolderAction(context);
+ if (nextFolder()) {
+ processFolder(context);
return;
}
// We should have discovered all available mailboxes now
_mailboxList = context->client()->mailboxIds();
- listCompleted(context);
+ folderListCompleted(context);
}
-void ImapRetrieveFolderListStrategy::listCompleted(ImapStrategyContextBase *context)
+void ImapRetrieveFolderListStrategy::folderListCompleted(ImapStrategyContextBase *context)
{
removeDeletedMailboxes(context);
- // We have retrieved all the folders
- completedAction(context);
+ // We have retrieved all the folders - process any messages
+ messageListMessageAction(context);
}
-void ImapRetrieveFolderListStrategy::mailboxListed(ImapStrategyContextBase *context, QMailFolder &folder, const QString &flags)
+void ImapRetrieveFolderListStrategy::mailboxListed(ImapStrategyContextBase *context, QMailFolder &folder, const QString &flags, const QString &delimiter)
{
- ImapSynchronizeBaseStrategy::mailboxListed(context, folder, flags);
+ ImapSynchronizeBaseStrategy::mailboxListed(context, folder, flags, delimiter);
_mailboxPaths.append(folder.path());
if (_descending) {
- if (folder.id() != _currentMailbox.id()) {
- // We need to list this folder's contents, too
- selectedFoldersAppend(QMailFolderIdList() << folder.id());
+ QString path(folder.path());
+
+ if (folder.id().isValid()) {
+ if (folder.id() != _currentMailbox.id()) {
+ if (_baseFolder.isEmpty() ||
+ (path.startsWith(_baseFolder, Qt::CaseInsensitive) && (path.length() == _baseFolder.length())) ||
+ (path.startsWith(_baseFolder + delimiter, Qt::CaseInsensitive))) {
+ // We need to list this folder's contents, too
+ selectedFoldersAppend(QMailFolderIdList() << folder.id());
+ }
+ }
+ } else {
+ if (!_ancestorPaths.contains(path)) {
+ if (_baseFolder.startsWith(path + delimiter, Qt::CaseInsensitive)) {
+ // This folder must be an ancestor of the base folder - list its contents
+ _ancestorPaths.insert(path);
+ _ancestorSearchPaths.append(path);
+ }
+ }
}
}
}
@@ -1258,7 +1288,7 @@ void ImapRetrieveFolderListStrategy::removeDeletedMailboxes(ImapStrategyContextB
*/
ImapSynchronizeAllStrategy::ImapSynchronizeAllStrategy()
{
- _options = (Options)(RetrieveMail | ImportChanges | ExportChanges);
+ _options = static_cast<Options>(RetrieveMail | ImportChanges | ExportChanges);
}
void ImapSynchronizeAllStrategy::setOptions(Options options)
@@ -1295,42 +1325,6 @@ void ImapSynchronizeAllStrategy::transition(ImapStrategyContextBase *context, Im
}
}
-void ImapSynchronizeAllStrategy::listCompleted(ImapStrategyContextBase *context)
-{
- removeDeletedMailboxes(context);
-
- previewDiscoveredMessages(context);
-}
-
-bool ImapSynchronizeAllStrategy::selectNextMailbox(ImapStrategyContextBase *context)
-{
- _seenUids = QStringList();
- _unseenUids = QStringList();
- _readUids = QStringList();
- _removedUids = QStringList();
- _expungeRequired = false;
-
- _searchState = Seen;
- return ImapRetrieveFolderListStrategy::selectNextMailbox(context);
-}
-
-void ImapSynchronizeAllStrategy::handleSelect(ImapStrategyContextBase *context)
-{
- // We have selected the current mailbox
- if (_transferState == List) {
- // We're searching mailboxes
- if (context->mailbox().exists > 0) {
- // Start by looking for previously-seen and unseen messages
- context->protocol().sendUidSearch(MFlag_Seen);
- } else {
- // No messages, so no need to perform search
- processUidSearchResults(context);
- }
- } else {
- ImapRetrieveFolderListStrategy::handleSelect(context);
- }
-}
-
void ImapSynchronizeAllStrategy::handleUidSearch(ImapStrategyContextBase *context)
{
switch(_searchState)
@@ -1339,8 +1333,14 @@ void ImapSynchronizeAllStrategy::handleUidSearch(ImapStrategyContextBase *contex
{
_seenUids = context->mailbox().uidList;
- _searchState = Unseen;
- context->protocol().sendUidSearch(MFlag_Unseen);
+ if (_seenUids.count() == context->mailbox().exists) {
+ // All of the messages are seen
+ _unseenUids.clear();
+ processUidSearchResults(context);
+ } else {
+ _searchState = Unseen;
+ context->protocol().sendUidSearch(MFlag_Unseen);
+ }
break;
}
case Unseen:
@@ -1378,16 +1378,55 @@ void ImapSynchronizeAllStrategy::handleUidSearch(ImapStrategyContextBase *contex
}
}
+void ImapSynchronizeAllStrategy::handleUidStore(ImapStrategyContextBase *context)
+{
+ if (!(_options & ExportChanges)) {
+ processNextFolder(context);
+ return;
+ }
+ if (!setNextSeen(context))
+ if (!setNextDeleted(context))
+ processNextFolder(context);
+}
+
+void ImapSynchronizeAllStrategy::handleExpunge(ImapStrategyContextBase *context)
+{
+ processNextFolder(context);
+}
+
+void ImapSynchronizeAllStrategy::folderListFolderAction(ImapStrategyContextBase *context)
+{
+ _seenUids = QStringList();
+ _unseenUids = QStringList();
+ _readUids = QStringList();
+ _removedUids = QStringList();
+ _expungeRequired = false;
+
+ // Search for messages in the current mailbox
+ _searchState = Seen;
+
+ if (context->mailbox().exists > 0) {
+ // Start by looking for previously-seen and unseen messages
+ context->protocol().sendUidSearch(MFlag_Seen);
+ } else {
+ // No messages, so no need to perform search
+ processUidSearchResults(context);
+ }
+}
+
+void ImapSynchronizeAllStrategy::folderListCompleted(ImapStrategyContextBase *context)
+{
+ removeDeletedMailboxes(context);
+
+ previewDiscoveredMessages(context);
+}
+
void ImapSynchronizeAllStrategy::processUidSearchResults(ImapStrategyContextBase *context)
{
QMailFolderId boxId = _currentMailbox.id();
QMailMessageKey accountKey(QMailMessageKey::parentAccountId(context->config().id()));
QMailFolder folder(boxId);
- // Folder min/max invalidated
- folder.removeCustomField("qmf-min-serveruid");
- folder.removeCustomField("qmf-max-serveruid");
-
if ((_currentMailbox.status() & QMailFolder::SynchronizationEnabled) &&
!(_currentMailbox.status() & QMailFolder::Synchronized)) {
// We have just synchronized this folder
@@ -1446,18 +1485,7 @@ void ImapSynchronizeAllStrategy::processUidSearchResults(ImapStrategyContextBase
void ImapSynchronizeAllStrategy::searchInconclusive(ImapStrategyContextBase *context)
{
- fetchNextMailPreview(context);
-}
-
-void ImapSynchronizeAllStrategy::handleUidStore(ImapStrategyContextBase *context)
-{
- if (!(_options & ExportChanges)) {
- fetchNextMailPreview(context);
- return;
- }
- if (!setNextSeen(context))
- if (!setNextDeleted(context))
- fetchNextMailPreview(context);
+ processNextFolder(context);
}
bool ImapSynchronizeAllStrategy::setNextSeen(ImapStrategyContextBase *context)
@@ -1503,16 +1531,21 @@ bool ImapSynchronizeAllStrategy::setNextDeleted(ImapStrategyContextBase *context
return false;
}
-void ImapSynchronizeAllStrategy::handleExpunge(ImapStrategyContextBase *context)
+void ImapSynchronizeAllStrategy::previewingCompleted(ImapStrategyContextBase *context)
{
- fetchNextMailPreview(context);
-}
+ QMailFolder folder(context->mailbox().id);
+ if (context->mailbox().exists > 0) {
+ folder.setCustomField("qmf-min-serveruid", QString::number(1));
+ folder.setCustomField("qmf-max-serveruid", QString::number(context->mailbox().uidNext - 1));
+ folder.setServerUndiscoveredCount(0);
-void ImapSynchronizeAllStrategy::fetchNextMailPreview(ImapStrategyContextBase *context)
-{
- ImapRetrieveFolderListStrategy::fetchNextMailPreview(context);
+ if (!QMailStore::instance()->updateFolder(&folder)) {
+ qWarning() << "Unable to update folder for account:" << context->config().id();
+ }
+ }
}
+
/* A strategy to retrieve all messages from an account.
That is to retrieve message previews for all known messages
@@ -1520,91 +1553,92 @@ void ImapSynchronizeAllStrategy::fetchNextMailPreview(ImapStrategyContextBase *c
*/
ImapRetrieveAllStrategy::ImapRetrieveAllStrategy()
{
- setOptions((Options)(RetrieveMail | ImportChanges));
+ // This is just synchronize without update-exporting
+ setOptions(static_cast<Options>(RetrieveMail | ImportChanges));
}
+
/* A strategy to exports changes made on the client to the server.
That is to export flag changes (unseen -> seen) and deletes.
*/
ImapExportUpdatesStrategy::ImapExportUpdatesStrategy()
{
- setOptions((Options)(ExportChanges));
+ setOptions(ExportChanges);
}
void ImapExportUpdatesStrategy::handleLogin(ImapStrategyContextBase *context)
{
- ImapConfiguration imapCfg(context->config());
+ _transferState = List;
_completionList.clear();
_completionSectionList.clear();
- _mailboxList.clear();
+
+ ImapConfiguration imapCfg(context->config());
if (!imapCfg.canDeleteMail()) {
- QMailAccountId id(context->config().id());
- QString name(QMailAccount(id).name());
- qMailLog(Messaging) << "Not exporting deletions. Deleting mail is "
- "disabled for account name" << name << "id" << id;
- }
- QMailFolderIdList folders(context->client()->mailboxIds());
- QMailMessageKey statusKey(QMailMessageKey::status(QMailMessage::Read, QMailDataComparator::Includes));
- statusKey &= ~QMailMessageKey::status(QMailMessage::ReadElsewhere, QMailDataComparator::Includes);
+ QString name(QMailAccount(context->config().id()).name());
+ qMailLog(Messaging) << "Not exporting deletions. Deleting mail is disabled for account name" << name;
+ }
+
+ QMailMessageKey statusKey(QMailMessageKey::status(QMailMessage::Read, QMailDataComparator::Includes));
+ statusKey &= ~QMailMessageKey::status(QMailMessage::ReadElsewhere, QMailDataComparator::Includes);
+
+ _folderMessageUids.clear();
+
ImapClient *c(context->client());
- foreach(QMailFolderId folderId, folders) {
- QStringList deletedUids;
- if (imapCfg.canDeleteMail())
- deletedUids = context->client()->deletedMessages(folderId);
+ foreach (const QMailFolderId &folderId, context->client()->mailboxIds()) {
QMailMessageKey folderKey(c->messagesKey(folderId) | c->trashKey(folderId));
+
+ // Find messages marked as read locally
+ QStringList deletedUids;
QStringList readUids = c->serverUids(folderKey & statusKey);
- if (!deletedUids.isEmpty() || !readUids.isEmpty())
- _mailboxList.append(folderId);
+
+ if (imapCfg.canDeleteMail()) {
+ // Also find messages deleted locally
+ deletedUids = context->client()->deletedMessages(folderId);
+ }
+
+ if (!readUids.isEmpty() || !deletedUids.isEmpty())
+ _folderMessageUids.insert(folderId, qMakePair(readUids, deletedUids));
}
- _transferState = List;
- if (!selectNextMailbox(context)) {
- // No changes to export
- completedAction(context);
- }
+ processNextFolder(context);
+}
+
+void ImapExportUpdatesStrategy::handleUidSearch(ImapStrategyContextBase *context)
+{
+ _serverReportedUids = context->mailbox().uidList;
+
+ processUidSearchResults(context);
}
-void ImapExportUpdatesStrategy::handleSelect(ImapStrategyContextBase *context)
+void ImapExportUpdatesStrategy::folderListFolderAction(ImapStrategyContextBase *context)
{
- _clientDeletedUids = QStringList();
- _clientReadUids = QStringList();
_serverReportedUids = QStringList();
// We have selected the current mailbox
- if (_transferState == List) {
- // We're searching mailboxes
- if (context->mailbox().exists > 0) {
- // Only interested in messages that are going to be operated on
- ImapConfiguration imapCfg(context->config());
- QMailFolderId folderId(_currentMailbox.id());
- QMailMessageKey statusKey(QMailMessageKey::status(QMailMessage::Read, QMailDataComparator::Includes));
- statusKey &= ~QMailMessageKey::status(QMailMessage::ReadElsewhere, QMailDataComparator::Includes);
- ImapClient *c(context->client());
- QMailMessageKey folderKey(c->messagesKey(folderId) | c->trashKey(folderId));
- _clientReadUids = c->serverUids(folderKey & statusKey);
- if (imapCfg.canDeleteMail())
- _clientDeletedUids = context->client()->deletedMessages(folderId);
-
- if (_clientDeletedUids.isEmpty() && _clientReadUids.isEmpty()) {
- processUidSearchResults(context);
- return;
- }
- QStringList changedUids = _clientDeletedUids + _clientReadUids;
- QString uidList = "UID " + stripFolderPrefix(changedUids).join(",");
- context->protocol().sendUidSearch(MFlag_All, uidList);
- } else {
- // No messages, so no need to perform search
- processUidSearchResults(context);
- }
+ if (context->mailbox().exists > 0) {
+ // Find which of our messages-of-interest are still on the server
+ IntegerRegion clientRegion(stripFolderPrefix(_clientReadUids + _clientDeletedUids));
+ context->protocol().sendUidSearch(MFlag_All, "UID " + clientRegion.toString());
} else {
- ImapRetrieveFolderListStrategy::handleSelect(context);
+ // No messages, so no need to perform search
+ processUidSearchResults(context);
}
}
-void ImapExportUpdatesStrategy::handleUidSearch(ImapStrategyContextBase *context)
+bool ImapExportUpdatesStrategy::nextFolder()
{
- _serverReportedUids = context->mailbox().uidList;
- processUidSearchResults(context);
+ if (_folderMessageUids.isEmpty()) {
+ return false;
+ }
+
+ QMap<QMailFolderId, QPair<QStringList, QStringList> >::iterator it = _folderMessageUids.begin();
+
+ _currentMailbox = QMailFolder(it.key());
+ _clientReadUids = it.value().first;
+ _clientDeletedUids = it.value().second;
+
+ _folderMessageUids.erase(it);
+ return true;
}
void ImapExportUpdatesStrategy::processUidSearchResults(ImapStrategyContextBase *context)
@@ -1628,7 +1662,9 @@ void ImapExportUpdatesStrategy::processUidSearchResults(ImapStrategyContextBase
void ImapUpdateMessagesFlagsStrategy::clearSelection()
{
ImapFolderListStrategy::clearSelection();
+
_monitoredFoldersIds.clear();
+ _selectedMessageIds.clear();
_folderMessageUids.clear();
}
@@ -1656,9 +1692,9 @@ void ImapUpdateMessagesFlagsStrategy::transition(ImapStrategyContextBase *contex
void ImapUpdateMessagesFlagsStrategy::handleLogin(ImapStrategyContextBase *context)
{
- _serverUids.clear();
_transferState = List;
- _searchState = Seen;
+ _serverUids.clear();
+ _searchState = Unseen;
// Associate each message to the relevant folder
_folderMessageUids.clear();
@@ -1671,55 +1707,71 @@ void ImapUpdateMessagesFlagsStrategy::handleLogin(ImapStrategyContextBase *conte
}
}
- processNextMailbox(context);
-}
-
-void ImapUpdateMessagesFlagsStrategy::handleSelect(ImapStrategyContextBase *context)
-{
- if (_transferState == List) {
- // We're searching mailboxes
- if (context->mailbox().exists > 0) {
- IntegerRegion clientRegion(stripFolderPrefix(_serverUids));
- _filter = clientRegion.toString();
- _searchState = Seen;
-
- // Start by looking for previously-seen and unseen messages
- context->protocol().sendUidSearch(MFlag_Seen, "UID " + _filter);
- } else {
- // No messages, so no need to perform search
- processUidSearchResults(context);
- }
- } else {
- ImapFolderListStrategy::handleSelect(context);
- }
+ processNextFolder(context);
}
void ImapUpdateMessagesFlagsStrategy::handleUidSearch(ImapStrategyContextBase *context)
{
switch(_searchState)
{
- case Seen:
+ case Unseen:
{
- _seenUids = context->mailbox().uidList;
+ _unseenUids = context->mailbox().uidList;
- _searchState = Unseen;
- context->protocol().sendUidSearch(MFlag_Unseen, "UID " + _filter);
+ if (_unseenUids.count() == _serverUids.count()) {
+ // All of the messages are unseen
+ _seenUids.clear();
+ processUidSearchResults(context);
+ } else {
+ _searchState = Seen;
+ context->protocol().sendUidSearch(MFlag_Seen, "UID " + _filter);
+ }
break;
}
- case Unseen:
+ case Seen:
{
- _unseenUids = context->mailbox().uidList;
+ _seenUids = context->mailbox().uidList;
processUidSearchResults(context);
break;
}
default:
qMailLog(IMAP) << "Unknown search status in transition";
Q_ASSERT(0);
- completedAction(context);
+
+ processNextFolder(context);
}
}
-bool ImapUpdateMessagesFlagsStrategy::getnextMailbox()
+void ImapUpdateMessagesFlagsStrategy::folderListFolderAction(ImapStrategyContextBase *context)
+{
+ if (context->mailbox().exists > 0) {
+ IntegerRegion clientRegion(stripFolderPrefix(_serverUids));
+ _filter = clientRegion.toString();
+ _searchState = Unseen;
+
+ // Start by looking for previously-unseen messages
+ // If a message is moved from Unseen to Seen between our two searches, then we will
+ // miss this change by searching Unseen first; if, however, we were to search Seen first,
+ // then we would miss the message altogether and mark it as deleted...
+ context->protocol().sendUidSearch(MFlag_Unseen, "UID " + _filter);
+ } else {
+ // No messages, so no need to perform search
+ processUidSearchResults(context);
+ }
+}
+
+void ImapUpdateMessagesFlagsStrategy::folderListCompleted(ImapStrategyContextBase *context)
+{
+ // Only allow monitoring of one folder other than the inbox
+ if (_monitoredFoldersIds.count() > 1)
+ _monitoredFoldersIds.clear();
+
+ context->client()->monitor(_monitoredFoldersIds);
+
+ messageListCompleted(context);
+}
+
+bool ImapUpdateMessagesFlagsStrategy::nextFolder()
{
if (_folderMessageUids.isEmpty()) {
return false;
@@ -1734,7 +1786,7 @@ bool ImapUpdateMessagesFlagsStrategy::getnextMailbox()
return true;
}
-void ImapUpdateMessagesFlagsStrategy::newfolderAction(ImapStrategyContextBase *context)
+void ImapUpdateMessagesFlagsStrategy::processFolder(ImapStrategyContextBase *context)
{
QMailFolderId folderId(_currentMailbox.id());
if ((folderId != context->client()->mailboxId("INBOX")) &&
@@ -1750,7 +1802,7 @@ void ImapUpdateMessagesFlagsStrategy::processUidSearchResults(ImapStrategyContex
QMailFolderId folderId(_currentMailbox.id());
if (!folderId.isValid()) {
// Folder was removed while we were updating messages flags in it
- processNextMailbox(context);
+ processNextFolder(context);
return;
}
@@ -1765,18 +1817,7 @@ void ImapUpdateMessagesFlagsStrategy::processUidSearchResults(ImapStrategyContex
updateMessagesMetaData(context, storedKey, unseenKey, seenKey, unreadElsewhereKey);
- processNextMailbox(context);
-}
-
-void ImapUpdateMessagesFlagsStrategy::listCompleted(ImapStrategyContextBase *context)
-{
- // Only allow monitoring of one folder other than the inbox
- if (_monitoredFoldersIds.count() > 1)
- _monitoredFoldersIds.clear();
-
- context->client()->monitor(_monitoredFoldersIds);
-
- completedAction(context);
+ processNextFolder(context);
}
@@ -1819,7 +1860,7 @@ void ImapRetrieveMessageListStrategy::handleLogin(ImapStrategyContextBase *conte
ImapSynchronizeBaseStrategy::handleLogin(context);
}
-void ImapRetrieveMessageListStrategy::completedAction(ImapStrategyContextBase *context)
+void ImapRetrieveMessageListStrategy::messageListCompleted(ImapStrategyContextBase *context)
{
foreach (const QMailFolderId &folderId, _updatedFolders) {
QMailFolder folder(folderId);
@@ -1843,10 +1884,10 @@ void ImapRetrieveMessageListStrategy::completedAction(ImapStrategyContextBase *c
_updatedFolders.clear();
_newMinMaxMap.clear();
- ImapSynchronizeBaseStrategy::completedAction(context);
+ ImapSynchronizeBaseStrategy::messageListCompleted(context);
}
-void ImapRetrieveMessageListStrategy::listCompleted(ImapStrategyContextBase *context)
+void ImapRetrieveMessageListStrategy::folderListCompleted(ImapStrategyContextBase *context)
{
previewDiscoveredMessages(context);
}
@@ -1909,7 +1950,7 @@ void ImapRetrieveMessageListStrategy::handleUidSearch(ImapStrategyContextBase *c
processUidSearchResults(context);
}
-void ImapRetrieveMessageListStrategy::processMailbox(ImapStrategyContextBase *context)
+void ImapRetrieveMessageListStrategy::folderListFolderAction(ImapStrategyContextBase *context)
{
// The current mailbox is now selected
QMailFolderId folderId(context->mailbox().id);
@@ -1975,7 +2016,7 @@ void ImapRetrieveMessageListStrategy::processMailbox(ImapStrategyContextBase *co
void ImapRetrieveMessageListStrategy::processUidSearchResults(ImapStrategyContextBase *context)
{
- processNextMailbox(context);
+ processNextFolder(context);
}
@@ -2044,7 +2085,7 @@ void ImapCopyMessagesStrategy::handleSelect(ImapStrategyContextBase *context)
//_uidNext = context->mailbox().uidNext;
// Begin copying messages
- messageAction(context);
+ messageListMessageAction(context);
} else if (_transferState == Search) {
// We have selected the destination folder - find the newly added messages
//context->protocol().sendUidSearch(MFlag_Recent, QString("UID %1:*").arg(ImapProtocol::uid(_uidNext)));
@@ -2056,7 +2097,7 @@ void ImapCopyMessagesStrategy::handleSelect(ImapStrategyContextBase *context)
void ImapCopyMessagesStrategy::handleUidCopy(ImapStrategyContextBase *context)
{
- messageAction(context);
+ messageListMessageAction(context);
}
void ImapCopyMessagesStrategy::handleUidSearch(ImapStrategyContextBase *context)
@@ -2070,7 +2111,7 @@ void ImapCopyMessagesStrategy::handleUidFetch(ImapStrategyContextBase *context)
fetchNextCopy(context);
}
-void ImapCopyMessagesStrategy::messageAction(ImapStrategyContextBase *context)
+void ImapCopyMessagesStrategy::messageListMessageAction(ImapStrategyContextBase *context)
{
if (selectNextMessageSequence(context, 1)) {
QStringList uids;
@@ -2086,10 +2127,10 @@ void ImapCopyMessagesStrategy::messageAction(ImapStrategyContextBase *context)
}
}
-void ImapCopyMessagesStrategy::completedAction(ImapStrategyContextBase *context)
+void ImapCopyMessagesStrategy::messageListCompleted(ImapStrategyContextBase *context)
{
if (_transferState == Search) {
- ImapFetchSelectedMessagesStrategy::completedAction(context);
+ ImapFetchSelectedMessagesStrategy::messageListCompleted(context);
} else {
// We have copied all the messages - now we need to retrieve the copies
_transferState = Search;
@@ -2146,7 +2187,7 @@ void ImapCopyMessagesStrategy::fetchNextCopy(ImapStrategyContextBase *context)
QString firstUid = ImapProtocol::uid(_createdUids.takeFirst());
context->protocol().sendUidFetch(MetaDataFetchFlags, firstUid);
} else {
- completedAction(context);
+ messageListCompleted(context);
}
}
@@ -2206,7 +2247,7 @@ void ImapMoveMessagesStrategy::handleUidCopy(ImapStrategyContextBase *context)
void ImapMoveMessagesStrategy::handleUidStore(ImapStrategyContextBase *context)
{
_lastMailbox = _currentMailbox;
- messageAction(context);
+ messageListMessageAction(context);
}
void ImapMoveMessagesStrategy::handleClose(ImapStrategyContextBase *context)
@@ -2218,7 +2259,7 @@ void ImapMoveMessagesStrategy::handleClose(ImapStrategyContextBase *context)
void ImapMoveMessagesStrategy::handleExamine(ImapStrategyContextBase *context)
{
// Select the next folder
- ImapCopyMessagesStrategy::folderAction(context);
+ ImapCopyMessagesStrategy::messageListFolderAction(context);
}
void ImapMoveMessagesStrategy::handleUidFetch(ImapStrategyContextBase *context)
@@ -2227,17 +2268,17 @@ void ImapMoveMessagesStrategy::handleUidFetch(ImapStrategyContextBase *context)
fetchNextCopy(context);
}
-void ImapMoveMessagesStrategy::folderAction(ImapStrategyContextBase *context)
+void ImapMoveMessagesStrategy::messageListFolderAction(ImapStrategyContextBase *context)
{
// If we're already in a mailbox, we need to close it to expunge the messages
if ((context->mailbox().isSelected()) && (_lastMailbox.id().isValid())) {
context->protocol().sendClose();
} else {
- ImapCopyMessagesStrategy::folderAction(context);
+ ImapCopyMessagesStrategy::messageListFolderAction(context);
}
}
-void ImapMoveMessagesStrategy::messageAction(ImapStrategyContextBase *context)
+void ImapMoveMessagesStrategy::messageListMessageAction(ImapStrategyContextBase *context)
{
if (selectNextMessageSequence(context, 1)) {
QStringList uids;
@@ -2253,7 +2294,7 @@ void ImapMoveMessagesStrategy::messageAction(ImapStrategyContextBase *context)
}
}
-void ImapMoveMessagesStrategy::completedAction(ImapStrategyContextBase *context)
+void ImapMoveMessagesStrategy::messageListCompleted(ImapStrategyContextBase *context)
{
if (_transferState == Search) {
// We don't need to keep the source messages any longer
@@ -2266,7 +2307,7 @@ void ImapMoveMessagesStrategy::completedAction(ImapStrategyContextBase *context)
}
}
- ImapCopyMessagesStrategy::completedAction(context);
+ ImapCopyMessagesStrategy::messageListCompleted(context);
}
static void transferPartBodies(QMailMessagePartContainer &destination, const QMailMessagePartContainer &source)
@@ -2346,7 +2387,7 @@ void ImapDeleteMessagesStrategy::handleUidStore(ImapStrategyContextBase *context
_storedList += _retrieveUid.split("\n");
_lastMailbox = _currentMailbox;
- messageAction(context);
+ messageListMessageAction(context);
}
void ImapDeleteMessagesStrategy::handleClose(ImapStrategyContextBase *context)
@@ -2369,10 +2410,10 @@ void ImapDeleteMessagesStrategy::handleClose(ImapStrategyContextBase *context)
void ImapDeleteMessagesStrategy::handleExamine(ImapStrategyContextBase *context)
{
// Select the next folder
- ImapFetchSelectedMessagesStrategy::folderAction(context);
+ ImapFetchSelectedMessagesStrategy::messageListFolderAction(context);
}
-void ImapDeleteMessagesStrategy::messageAction(ImapStrategyContextBase *context)
+void ImapDeleteMessagesStrategy::messageListMessageAction(ImapStrategyContextBase *context)
{
if (selectNextMessageSequence(context, 1000)) {
QStringList uids;
@@ -2383,7 +2424,7 @@ void ImapDeleteMessagesStrategy::messageAction(ImapStrategyContextBase *context)
}
}
-void ImapDeleteMessagesStrategy::folderAction(ImapStrategyContextBase *context)
+void ImapDeleteMessagesStrategy::messageListFolderAction(ImapStrategyContextBase *context)
{
// If we're already in a mailbox, we need to close it to expunge the messages
if ((context->mailbox().isSelected()) && (_lastMailbox.id().isValid())) {
@@ -2391,17 +2432,17 @@ void ImapDeleteMessagesStrategy::folderAction(ImapStrategyContextBase *context)
} else {
// Select the next folder, and clear the stored list
_storedList.clear();
- ImapFetchSelectedMessagesStrategy::folderAction(context);
+ ImapFetchSelectedMessagesStrategy::messageListFolderAction(context);
}
}
-void ImapDeleteMessagesStrategy::completedAction(ImapStrategyContextBase *context)
+void ImapDeleteMessagesStrategy::messageListCompleted(ImapStrategyContextBase *context)
{
// If we're already in a mailbox, we need to close it to expunge the messages
if ((context->mailbox().isSelected()) && (_lastMailbox.id().isValid())) {
context->protocol().sendClose();
} else {
- ImapFetchSelectedMessagesStrategy::completedAction(context);
+ ImapFetchSelectedMessagesStrategy::messageListCompleted(context);
}
}
diff --git a/src/plugins/messageservices/imap/imapstrategy.h b/src/plugins/messageservices/imap/imapstrategy.h
index 91b1d1b6..8f7547b9 100644
--- a/src/plugins/messageservices/imap/imapstrategy.h
+++ b/src/plugins/messageservices/imap/imapstrategy.h
@@ -75,7 +75,7 @@ public:
virtual void newConnection(ImapStrategyContextBase *context);
virtual void transition(ImapStrategyContextBase*, const ImapCommand, const OperationStatus) = 0;
- virtual void mailboxListed(ImapStrategyContextBase *context, QMailFolder& folder, const QString &flags);
+ virtual void mailboxListed(ImapStrategyContextBase *context, QMailFolder& folder, const QString &flags, const QString &delimiter);
virtual void messageFetched(ImapStrategyContextBase *context, QMailMessage &message);
virtual void dataFetched(ImapStrategyContextBase *context, QMailMessage &message, const QString &uid, const QString &section);
virtual void nonexistentUid(ImapStrategyContextBase *context, const QString &uid);
@@ -89,6 +89,7 @@ protected:
enum TransferState { Init, List, Search, Preview, Complete };
TransferState _transferState;
+ QString _baseFolder;
};
class ImapMessageListStrategy : public ImapStrategy
@@ -110,9 +111,9 @@ protected:
virtual void handleLogin(ImapStrategyContextBase *context);
virtual void handleSelect(ImapStrategyContextBase *context);
- virtual void folderAction(ImapStrategyContextBase *context);
- virtual void messageAction(ImapStrategyContextBase *context) = 0;
- virtual void completedAction(ImapStrategyContextBase *context);
+ virtual void messageListFolderAction(ImapStrategyContextBase *context);
+ virtual void messageListMessageAction(ImapStrategyContextBase *context) = 0;
+ virtual void messageListCompleted(ImapStrategyContextBase *context);
virtual bool computeStartEndPartRange(ImapStrategyContextBase *context);
virtual bool selectNextMessageSequence(ImapStrategyContextBase *context, int maximum = DefaultBatchSize);
@@ -149,7 +150,7 @@ protected:
virtual void handleLogin(ImapStrategyContextBase *context);
virtual void handleUidFetch(ImapStrategyContextBase *context);
- virtual void messageAction(ImapStrategyContextBase *context);
+ virtual void messageListMessageAction(ImapStrategyContextBase *context);
virtual void itemFetched(ImapStrategyContextBase *context, const QString &uid);
@@ -176,7 +177,7 @@ public:
virtual void newConnection(ImapStrategyContextBase *context);
virtual void transition(ImapStrategyContextBase*, const ImapCommand, const OperationStatus);
- virtual void mailboxListed(ImapStrategyContextBase *context, QMailFolder& folder, const QString &flags);
+ virtual void mailboxListed(ImapStrategyContextBase *context, QMailFolder& folder, const QString &flags, const QString &delimiter);
protected:
virtual void handleLogin(ImapStrategyContextBase *context);
@@ -184,13 +185,12 @@ protected:
virtual void handleSelect(ImapStrategyContextBase *context);
virtual void handleSearch(ImapStrategyContextBase *context);
- virtual void listCompleted(ImapStrategyContextBase *context);
+ virtual void folderListFolderAction(ImapStrategyContextBase *context);
+ virtual void folderListCompleted(ImapStrategyContextBase *context);
- virtual void processMailbox(ImapStrategyContextBase *context);
-
- virtual void processNextMailbox(ImapStrategyContextBase *context);
- virtual bool getnextMailbox();
- virtual void newfolderAction(ImapStrategyContextBase *context);
+ virtual void processNextFolder(ImapStrategyContextBase *context);
+ virtual bool nextFolder();
+ virtual void processFolder(ImapStrategyContextBase *context);
void updateUndiscoveredCount(ImapStrategyContextBase *context);
@@ -221,15 +221,15 @@ public:
protected:
virtual void handleLogin(ImapStrategyContextBase *context);
- virtual void handleSelect(ImapStrategyContextBase *context);
virtual void handleUidSearch(ImapStrategyContextBase *context);
- virtual bool getnextMailbox();
- virtual void newfolderAction(ImapStrategyContextBase *context);
+ virtual void folderListFolderAction(ImapStrategyContextBase *context);
+ virtual void folderListCompleted(ImapStrategyContextBase *context);
- virtual void processUidSearchResults(ImapStrategyContextBase *context);
+ virtual bool nextFolder();
+ virtual void processFolder(ImapStrategyContextBase *context);
- virtual void listCompleted(ImapStrategyContextBase *context);
+ virtual void processUidSearchResults(ImapStrategyContextBase *context);
private:
QMailMessageIdList _selectedMessageIds;
@@ -260,10 +260,10 @@ protected:
virtual void handleUidFetch(ImapStrategyContextBase *context);
virtual void previewDiscoveredMessages(ImapStrategyContextBase *context);
- virtual bool selectNextMailbox(ImapStrategyContextBase *context);
- virtual bool nextMailbox(ImapStrategyContextBase *context);
+ virtual bool selectNextPreviewFolder(ImapStrategyContextBase *context);
virtual void fetchNextMailPreview(ImapStrategyContextBase *context);
+ virtual void previewingCompleted(ImapStrategyContextBase *context);
virtual void processUidSearchResults(ImapStrategyContextBase *context);
@@ -291,21 +291,24 @@ public:
virtual void newConnection(ImapStrategyContextBase *context);
- virtual void mailboxListed(ImapStrategyContextBase *context, QMailFolder& folder, const QString &flags);
+ virtual void mailboxListed(ImapStrategyContextBase *context, QMailFolder& folder, const QString &flags, const QString &delimiter);
protected:
virtual void handleLogin(ImapStrategyContextBase *context);
virtual void handleSearch(ImapStrategyContextBase *context);
+ virtual void handleList(ImapStrategyContextBase *context);
- virtual void listCompleted(ImapStrategyContextBase *context);
+ virtual void folderListCompleted(ImapStrategyContextBase *context);
- virtual void processNextMailbox(ImapStrategyContextBase *context);
+ virtual void processNextFolder(ImapStrategyContextBase *context);
void removeDeletedMailboxes(ImapStrategyContextBase *context);
QMailFolderId _baseId;
bool _descending;
QStringList _mailboxPaths;
+ QSet<QString> _ancestorPaths;
+ QStringList _ancestorSearchPaths;
QMailFolderIdList _mailboxList;
};
@@ -323,11 +326,11 @@ protected:
virtual void handleLogin(ImapStrategyContextBase *context);
virtual void handleUidSearch(ImapStrategyContextBase *context);
- virtual void completedAction(ImapStrategyContextBase *context);
- virtual void listCompleted(ImapStrategyContextBase *context);
+ virtual void messageListCompleted(ImapStrategyContextBase *context);
+ virtual void folderListCompleted(ImapStrategyContextBase *context);
virtual void processUidSearchResults(ImapStrategyContextBase *context);
- virtual void processMailbox(ImapStrategyContextBase *context);
+ virtual void folderListFolderAction(ImapStrategyContextBase *context);
uint _minimum;
bool _fillingGap;
@@ -355,17 +358,21 @@ public:
virtual void transition(ImapStrategyContextBase*, const ImapCommand, const OperationStatus);
protected:
- virtual void listCompleted(ImapStrategyContextBase *context);
- virtual bool selectNextMailbox(ImapStrategyContextBase *context);
- virtual void handleSelect(ImapStrategyContextBase *context);
virtual void handleUidSearch(ImapStrategyContextBase *context);
+ virtual void handleUidStore(ImapStrategyContextBase *context);
+ virtual void handleExpunge(ImapStrategyContextBase *context);
+
+ virtual void folderListFolderAction(ImapStrategyContextBase *context);
+
virtual void processUidSearchResults(ImapStrategyContextBase *context);
virtual void searchInconclusive(ImapStrategyContextBase *context);
- virtual void handleUidStore(ImapStrategyContextBase *context);
+
+ virtual void folderListCompleted(ImapStrategyContextBase *context);
+
virtual bool setNextSeen(ImapStrategyContextBase *context);
virtual bool setNextDeleted(ImapStrategyContextBase *context);
- virtual void handleExpunge(ImapStrategyContextBase *context);
- virtual void fetchNextMailPreview(ImapStrategyContextBase *context);
+
+ virtual void previewingCompleted(ImapStrategyContextBase *context);
protected:
QStringList _readUids;
@@ -397,13 +404,18 @@ public:
protected:
virtual void handleLogin(ImapStrategyContextBase *context);
- virtual void handleSelect(ImapStrategyContextBase *context);
virtual void handleUidSearch(ImapStrategyContextBase *context);
+
+ virtual void folderListFolderAction(ImapStrategyContextBase *context);
+ virtual bool nextFolder();
+
virtual void processUidSearchResults(ImapStrategyContextBase *context);
QStringList _serverReportedUids;
QStringList _clientDeletedUids;
QStringList _clientReadUids;
+
+ QMap<QMailFolderId, QPair<QStringList, QStringList> > _folderMessageUids;
};
class ImapCopyMessagesStrategy : public ImapFetchSelectedMessagesStrategy
@@ -427,8 +439,8 @@ protected:
virtual void handleUidSearch(ImapStrategyContextBase *context);
virtual void handleUidFetch(ImapStrategyContextBase *context);
- virtual void messageAction(ImapStrategyContextBase *context);
- virtual void completedAction(ImapStrategyContextBase *context);
+ virtual void messageListMessageAction(ImapStrategyContextBase *context);
+ virtual void messageListCompleted(ImapStrategyContextBase *context);
virtual void updateCopiedMessage(ImapStrategyContextBase *context, QMailMessage &message, const QMailMessage &source);
@@ -458,9 +470,9 @@ protected:
virtual void handleUidFetch(ImapStrategyContextBase *context);
virtual void handleExamine(ImapStrategyContextBase *context);
- virtual void folderAction(ImapStrategyContextBase *context);
- virtual void messageAction(ImapStrategyContextBase *context);
- virtual void completedAction(ImapStrategyContextBase *context);
+ virtual void messageListFolderAction(ImapStrategyContextBase *context);
+ virtual void messageListMessageAction(ImapStrategyContextBase *context);
+ virtual void messageListCompleted(ImapStrategyContextBase *context);
virtual void updateCopiedMessage(ImapStrategyContextBase *context, QMailMessage &message, const QMailMessage &source);
@@ -482,9 +494,9 @@ protected:
virtual void handleClose(ImapStrategyContextBase *context);
virtual void handleExamine(ImapStrategyContextBase *context);
- virtual void messageAction(ImapStrategyContextBase *context);
- virtual void folderAction(ImapStrategyContextBase *context);
- virtual void completedAction(ImapStrategyContextBase *context);
+ virtual void messageListFolderAction(ImapStrategyContextBase *context);
+ virtual void messageListMessageAction(ImapStrategyContextBase *context);
+ virtual void messageListCompleted(ImapStrategyContextBase *context);
QStringList _storedList;
bool _removal;
@@ -510,7 +522,7 @@ public:
void newConnection() { _strategy->newConnection(this); }
void commandTransition(const ImapCommand command, const OperationStatus status) { _strategy->transition(this, command, status); }
- void mailboxListed(QMailFolder& folder, const QString &flags) { _strategy->mailboxListed(this, folder, flags); }
+ void mailboxListed(QMailFolder& folder, const QString &flags, const QString &delimiter) { _strategy->mailboxListed(this, folder, flags, delimiter); }
void messageFetched(QMailMessage &message) { _strategy->messageFetched(this, message); }
void dataFetched(QMailMessage &message, const QString &uid, const QString &section) { _strategy->dataFetched(this, message, uid, section); }
void nonexistentUid(const QString &uid) { _strategy->nonexistentUid(this, uid); }
diff --git a/src/tools/messageserver/messageserver.cpp b/src/tools/messageserver/messageserver.cpp
index f4d30d3c..2e5cf88e 100644
--- a/src/tools/messageserver/messageserver.cpp
+++ b/src/tools/messageserver/messageserver.cpp
@@ -36,7 +36,7 @@ MessageServer::MessageServer(QObject *parent)
it.value() = 0;
QMailStore *store = QMailStore::instance();
- if (!store->initialized()) {
+ if (store->initializationState() != QMailStore::Initialized) {
qFatal("Messaging DB Invalid: Messaging cannot operate due to database incompatibilty!");
// Do not close, however, or QPE will start another instance.
} else {
diff --git a/src/tools/messageserver/servicehandler.cpp b/src/tools/messageserver/servicehandler.cpp
index 78e72dec..a7c773d8 100644
--- a/src/tools/messageserver/servicehandler.cpp
+++ b/src/tools/messageserver/servicehandler.cpp
@@ -16,10 +16,10 @@
#include <qmailmessageserver.h>
#include <qmailserviceconfiguration.h>
#include <qmailstore.h>
-#include <QTimer>
#include <qmaillog.h>
#include <QApplication>
-#include <QFile>
+#include <QDir>
+#include <QTimer>
// Account preparation is handled by an external function
extern void prepareAccounts();
@@ -224,6 +224,11 @@ bool messageBodyContainsText(const QMailMessage &message, const QString& text)
return false;
}
+QString requestsFileName()
+{
+ return QDir::tempPath() + "/qmf-messageserver-requests";
+}
+
}
@@ -292,7 +297,8 @@ QMailMessageIdList ServiceHandler::MessageSearch::takeBatch()
ServiceHandler::ServiceHandler(QObject* parent)
- : QObject(parent)
+ : QObject(parent),
+ _requestsFile(requestsFileName())
{
LongStream::cleanupTempFiles();
@@ -308,6 +314,39 @@ ServiceHandler::ServiceHandler(QObject* parent)
}
connect(this, SIGNAL(remoteSearchCompleted(quint64)), this, SLOT(finaliseSearch(quint64)));
+
+ // See if there are any requests remaining from our previous run
+ if (_requestsFile.exists()) {
+ if (!_requestsFile.open(QIODevice::ReadOnly)) {
+ qWarning() << "Unable to open requests file for read!";
+ } else {
+ QString line;
+
+ // Every request still in the file failed to complete
+ for (QByteArray line = _requestsFile.readLine(); !line.isEmpty(); line = _requestsFile.readLine()) {
+ if (quint64 action = line.trimmed().toULongLong()) {
+ _failedRequests.append(action);
+ }
+ }
+
+ _requestsFile.close();
+ }
+ }
+
+ if (!_requestsFile.open(QIODevice::WriteOnly)) {
+ qWarning() << "Unable to open requests file for write!" << _requestsFile.fileName();
+ } else {
+ if (!_requestsFile.resize(0)) {
+ qWarning() << "Unable to truncate requests file!";
+ } else {
+ _requestsFile.flush();
+ }
+ }
+
+ if (!_failedRequests.isEmpty()) {
+ // Allow the clients some time to reconnect, then report our failures
+ QTimer::singleShot(2000, this, SLOT(reportFailures()));
+ }
}
ServiceHandler::~ServiceHandler()
@@ -602,6 +641,16 @@ void ServiceHandler::enqueueRequest(quint64 action, const QByteArray &data, cons
req.completion = completion;
mRequests.append(req);
+
+ // Add this request to the outstanding list
+ if (!_outstandingRequests.contains(action)) {
+ _outstandingRequests.insert(action);
+
+ QByteArray requestNumber(QByteArray::number(action));
+ _requestsFile.write(requestNumber.append("\n"));
+ _requestsFile.flush();
+ }
+
QTimer::singleShot(0, this, SLOT(dispatchRequest()));
}
@@ -643,6 +692,7 @@ void ServiceHandler::activateAction(quint64 action, const QSet<QMailMessageServi
data.services = services;
data.completion = completion;
data.expiry = QTime::currentTime().addMSecs(ExpiryPeriod);
+ data.reported = false;
mActiveActions.insert(action, data);
@@ -688,10 +738,35 @@ void ServiceHandler::expireAction()
QSet<QMailAccountId> serviceAccounts;
+ bool retrievalSetModified(false);
+ bool transmissionSetModified(false);
+
// Remove this action
foreach (QMailMessageService *service, data.services) {
serviceAccounts.insert(service->accountId());
mServiceAction.remove(service);
+
+ QMailAccountId accountId(service->accountId());
+ if (accountId.isValid()) {
+ if (data.completion == &ServiceHandler::retrievalCompleted) {
+ if (_retrievalAccountIds.contains(accountId)) {
+ _retrievalAccountIds.remove(accountId);
+ retrievalSetModified = true;
+ }
+ } else if (data.completion == &ServiceHandler::transmissionCompleted) {
+ if (_transmissionAccountIds.contains(accountId)) {
+ _transmissionAccountIds.remove(accountId);
+ transmissionSetModified = true;
+ }
+ }
+ }
+ }
+
+ if (retrievalSetModified) {
+ QMailStore::instance()->setRetrievalInProgress(_retrievalAccountIds.toList());
+ }
+ if (transmissionSetModified) {
+ QMailStore::instance()->setTransmissionInProgress(_transmissionAccountIds.toList());
}
mActiveActions.erase(it);
@@ -722,9 +797,35 @@ void ServiceHandler::cancelTransfer(quint64 action)
{
QMap<quint64, ActionData>::iterator it = mActiveActions.find(action);
if (it != mActiveActions.end()) {
- foreach (QMailMessageService *service, it.value().services) {
+ bool retrievalSetModified(false);
+ bool transmissionSetModified(false);
+
+ const ActionData &data(it.value());
+ foreach (QMailMessageService *service, data.services) {
service->cancelOperation();
mServiceAction.remove(service);
+
+ QMailAccountId accountId(service->accountId());
+ if (accountId.isValid()) {
+ if (data.completion == &ServiceHandler::retrievalCompleted) {
+ if (_retrievalAccountIds.contains(accountId)) {
+ _retrievalAccountIds.remove(accountId);
+ retrievalSetModified = true;
+ }
+ } else if (data.completion == &ServiceHandler::transmissionCompleted) {
+ if (_transmissionAccountIds.contains(accountId)) {
+ _transmissionAccountIds.remove(accountId);
+ transmissionSetModified = true;
+ }
+ }
+ }
+ }
+
+ if (retrievalSetModified) {
+ QMailStore::instance()->setRetrievalInProgress(_retrievalAccountIds.toList());
+ }
+ if (transmissionSetModified) {
+ QMailStore::instance()->setTransmissionInProgress(_transmissionAccountIds.toList());
}
mActiveActions.erase(it);
@@ -737,9 +838,12 @@ void ServiceHandler::cancelTransfer(quint64 action)
for ( ; it != end; ++it) {
if ((*it).action == action) {
mRequests.erase(it);
- return;
+ break;
}
}
+
+ // Report this action as failed
+ reportFailure(action, QMailServiceAction::Status::ErrCancel, tr("Cancelled by user"));
}
}
@@ -763,13 +867,18 @@ bool ServiceHandler::dispatchTransmitMessages(quint64 action, const QByteArray &
if (QMailMessageSink *sink = accountSink(accountId)) {
// Transmit any messages in the Outbox for this account
QMailMessageKey accountKey(QMailMessageKey::parentAccountId(accountId));
- QMailMessageKey folderKey(QMailMessageKey::parentFolderId(QMailFolderId(QMailFolder::OutboxFolder)));
+
+ QMailAccount account(accountId);
+ QMailMessageKey folderKey(QMailMessageKey::parentFolderId(account.standardFolder(QMailFolder::OutboxFolder)));
// TODO: Prepare any unresolved messages for transmission
if (!sink->transmitMessages(QMailStore::instance()->queryMessages(accountKey & folderKey))) {
qMailLog(Messaging) << "Unable to service request to add messages to sink for account:" << accountId;
return false;
+ } else {
+ // This account is now transmitting
+ setTransmissionInProgress(accountId, true);
}
} else {
reportFailure(action, QMailServiceAction::Status::ErrFrameworkFault, tr("Unable to locate sink for account"), accountId);
@@ -801,6 +910,9 @@ bool ServiceHandler::dispatchRetrieveFolderListAccount(quint64 action, const QBy
if (!source->retrieveFolderList(accountId, folderId, descending)) {
qMailLog(Messaging) << "Unable to service request to retrieve folder list for account:" << accountId;
return false;
+ } else {
+ // This account is now retrieving (arguably...)
+ setRetrievalInProgress(accountId, true);
}
} else {
reportFailure(action, QMailServiceAction::Status::ErrFrameworkFault, tr("Unable to locate source for account"), accountId);
@@ -833,6 +945,9 @@ bool ServiceHandler::dispatchRetrieveMessageList(quint64 action, const QByteArra
if (!source->retrieveMessageList(accountId, folderId, minimum, sort)) {
qMailLog(Messaging) << "Unable to service request to retrieve message list for folder:" << folderId;
return false;
+ } else {
+ // This account is now retrieving
+ setRetrievalInProgress(accountId, true);
}
} else {
reportFailure(action, QMailServiceAction::Status::ErrFrameworkFault, tr("Unable to locate source for account"), accountId);
@@ -867,6 +982,11 @@ bool ServiceHandler::dispatchRetrieveMessages(quint64 action, const QByteArray &
if (!source->retrieveMessages(it.value(), spec)) {
qMailLog(Messaging) << "Unable to service request to retrieve messages for account:" << it.key();
return false;
+ } else if (spec != QMailRetrievalAction::Flags) {
+ // This account is now retrieving
+ if (!_retrievalAccountIds.contains(it.key())) {
+ _retrievalAccountIds.insert(it.key());
+ }
}
} else {
reportFailure(action, QMailServiceAction::Status::ErrFrameworkFault, tr("Unable to locate source for account"), it.key());
@@ -874,6 +994,7 @@ bool ServiceHandler::dispatchRetrieveMessages(quint64 action, const QByteArray &
}
}
+ QMailStore::instance()->setRetrievalInProgress(_retrievalAccountIds.toList());
return true;
}
@@ -899,6 +1020,9 @@ bool ServiceHandler::dispatchRetrieveMessagePart(quint64 action, const QByteArra
if (!source->retrieveMessagePart(partLocation)) {
qMailLog(Messaging) << "Unable to service request to retrieve part for message:" << partLocation.containingMessageId();
return false;
+ } else {
+ // This account is now retrieving
+ setRetrievalInProgress(accountId, true);
}
} else {
reportFailure(action, QMailServiceAction::Status::ErrFrameworkFault, tr("Unable to locate source for account"), accountId);
@@ -931,6 +1055,9 @@ bool ServiceHandler::dispatchRetrieveMessageRange(quint64 action, const QByteArr
if (!source->retrieveMessageRange(messageId, minimum)) {
qMailLog(Messaging) << "Unable to service request to retrieve range:" << minimum << "for message:" << messageId;
return false;
+ } else {
+ // This account is now retrieving
+ setRetrievalInProgress(accountId, true);
}
} else {
reportFailure(action, QMailServiceAction::Status::ErrFrameworkFault, tr("Unable to locate source for account"), accountId);
@@ -963,6 +1090,9 @@ bool ServiceHandler::dispatchRetrieveMessagePartRange(quint64 action, const QByt
if (!source->retrieveMessagePartRange(partLocation, minimum)) {
qMailLog(Messaging) << "Unable to service request to retrieve range:" << minimum << "for part in message:" << partLocation.containingMessageId();
return false;
+ } else {
+ // This account is now retrieving
+ setRetrievalInProgress(accountId, true);
}
} else {
reportFailure(action, QMailServiceAction::Status::ErrFrameworkFault, tr("Unable to locate source for account"), accountId);
@@ -992,6 +1122,9 @@ bool ServiceHandler::dispatchRetrieveAll(quint64 action, const QByteArray &data)
if (!source->retrieveAll(accountId)) {
qMailLog(Messaging) << "Unable to service request to retrieve all messages for account:" << accountId;
return false;
+ } else {
+ // This account is now retrieving
+ setRetrievalInProgress(accountId, true);
}
} else {
reportFailure(action, QMailServiceAction::Status::ErrFrameworkFault, tr("Unable to locate source for account"), accountId);
@@ -1050,6 +1183,9 @@ bool ServiceHandler::dispatchSynchronize(quint64 action, const QByteArray &data)
if (!source->synchronize(accountId)) {
qMailLog(Messaging) << "Unable to service request to synchronize account:" << accountId;
return false;
+ } else {
+ // This account is now retrieving
+ setRetrievalInProgress(accountId, true);
}
} else {
reportFailure(action, QMailServiceAction::Status::ErrFrameworkFault, tr("Unable to locate source for account"), accountId);
@@ -1499,14 +1635,25 @@ void ServiceHandler::actionCompleted(bool success)
// Remove this service from the set for the action
data.services.erase(sit);
+ // This account is no longer retrieving/transmitting
+ QMailAccountId accountId(service->accountId());
+ if (accountId.isValid()) {
+ if (data.completion == &ServiceHandler::retrievalCompleted) {
+ setRetrievalInProgress(accountId, false);
+ } else if (data.completion == &ServiceHandler::transmissionCompleted) {
+ setTransmissionInProgress(accountId, false);
+ }
+ }
+
if (success) {
- if (data.services.isEmpty() && data.completion != 0) {
+ if (data.services.isEmpty() && (data.reported == false)) {
// Report success
emit (this->*data.completion)(action);
+ data.reported = true;
}
} else {
- // This action has failed - remove the completion signal so it can't be reported as successful
- data.completion = 0;
+ // This action has failed - mark it so that it can't be reported as successful
+ data.reported = true;
}
}
@@ -1516,6 +1663,18 @@ void ServiceHandler::actionCompleted(bool success)
}
}
+ if (_outstandingRequests.contains(action)) {
+ _outstandingRequests.remove(action);
+
+ // Ensure this request is no longer in the file
+ _requestsFile.resize(0);
+ foreach (quint64 req, _outstandingRequests) {
+ QByteArray requestNumber(QByteArray::number(req));
+ _requestsFile.write(requestNumber.append("\n"));
+ }
+ _requestsFile.flush();
+ }
+
mServiceAction.remove(service);
}
}
@@ -1606,3 +1765,49 @@ void ServiceHandler::finaliseSearch(quint64 action)
}
}
+void ServiceHandler::reportFailures()
+{
+ // We have no active accounts at this point
+ QMailStore::instance()->setRetrievalInProgress(QMailAccountIdList());
+ QMailStore::instance()->setTransmissionInProgress(QMailAccountIdList());
+
+ while (!_failedRequests.isEmpty()) {
+ quint64 action(_failedRequests.takeFirst());
+ reportFailure(action, QMailServiceAction::Status::ErrFrameworkFault, tr("Failed to perform requested action!"));
+ }
+}
+
+void ServiceHandler::setRetrievalInProgress(const QMailAccountId &accountId, bool inProgress)
+{
+ bool modified(false);
+
+ if (inProgress && !_retrievalAccountIds.contains(accountId)) {
+ _retrievalAccountIds.insert(accountId);
+ modified = true;
+ } else if (!inProgress && _retrievalAccountIds.contains(accountId)) {
+ _retrievalAccountIds.remove(accountId);
+ modified = true;
+ }
+
+ if (modified) {
+ QMailStore::instance()->setRetrievalInProgress(_retrievalAccountIds.toList());
+ }
+}
+
+void ServiceHandler::setTransmissionInProgress(const QMailAccountId &accountId, bool inProgress)
+{
+ bool modified(false);
+
+ if (inProgress && !_transmissionAccountIds.contains(accountId)) {
+ _transmissionAccountIds.insert(accountId);
+ modified = true;
+ } else if (!inProgress && _transmissionAccountIds.contains(accountId)) {
+ _transmissionAccountIds.remove(accountId);
+ modified = true;
+ }
+
+ if (modified) {
+ QMailStore::instance()->setTransmissionInProgress(_transmissionAccountIds.toList());
+ }
+}
+
diff --git a/src/tools/messageserver/servicehandler.h b/src/tools/messageserver/servicehandler.h
index f6d9e790..972763e0 100644
--- a/src/tools/messageserver/servicehandler.h
+++ b/src/tools/messageserver/servicehandler.h
@@ -12,6 +12,7 @@
#define SERVICEHANDLER_H
#include <QByteArray>
+#include <QFile>
#include <QLinkedList>
#include <QList>
#include <qmailmessageserver.h>
@@ -107,6 +108,8 @@ private slots:
void expireAction();
+ void reportFailures();
+
private:
QMailAccountId transmissionAccountId(const QMailAccountId &accountId) const;
@@ -168,6 +171,9 @@ private:
void activateAction(quint64, const QSet<QMailMessageService*> &, CompletionSignal);
void updateAction(quint64);
+ void setRetrievalInProgress(const QMailAccountId &id, bool inProgress);
+ void setTransmissionInProgress(const QMailAccountId &id, bool inProgress);
+
QMap<QPair<QMailAccountId, QString>, QMailMessageService*> serviceMap;
QMap<QMailAccountId, QMailMessageSource*> sourceMap;
QMap<QMailAccountId, QMailMessageSink*> sinkMap;
@@ -183,6 +189,7 @@ private:
QSet<QMailMessageService*> services;
CompletionSignal completion;
QTime expiry;
+ bool reported;
};
QMap<quint64, ActionData> mActiveActions;
@@ -233,6 +240,13 @@ private:
QList<MessageSearch> mSearches;
QMailMessageIdList mMatchingIds;
+
+ QFile _requestsFile;
+ QSet<quint64> _outstandingRequests;
+ QList<quint64> _failedRequests;
+
+ QSet<QMailAccountId> _retrievalAccountIds;
+ QSet<QMailAccountId> _transmissionAccountIds;
};
#endif
diff --git a/tests/tests.pro b/tests/tests.pro
index b0deaf82..6cd0a154 100644
--- a/tests/tests.pro
+++ b/tests/tests.pro
@@ -1,4 +1,5 @@
TEMPLATE = subdirs
+CONFIG += ordered
SUBDIRS = \
tst_python_email \
tst_qmailaddress \
diff --git a/tests/tst_qmailstorekeys/tst_qmailstorekeys.cpp b/tests/tst_qmailstorekeys/tst_qmailstorekeys.cpp
index f78b3002..55b89f8b 100644
--- a/tests/tst_qmailstorekeys/tst_qmailstorekeys.cpp
+++ b/tests/tst_qmailstorekeys/tst_qmailstorekeys.cpp
@@ -119,7 +119,7 @@ tst_QMailStoreKeys::~tst_QMailStoreKeys()
void tst_QMailStoreKeys::initTestCase()
{
- // Instantiate the store to initialise the values of the status flags
+ // Instantiate the store to initialise the values of the status flags and create the standard folders
QMailStore::instance();
// Create the data set we will test our keys upon
@@ -446,6 +446,7 @@ void tst_QMailStoreKeys::initTestCase()
void tst_QMailStoreKeys::cleanupTestCase()
{
+ QMailStore::instance()->clearContent();
}
using namespace QMailDataComparator;