--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emailuis/nmailuiengine/src/nmuiengine.cpp Tue Aug 31 15:04:17 2010 +0300
@@ -0,0 +1,1299 @@
+/*
+* Copyright (c) 2009 - 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+*
+*/
+
+
+#include "nmuiengineheaders.h"
+
+/*!
+ \class NmUiEngine
+ \brief NmUiEngine provides a controller-type services for the email UI.
+
+*/
+
+NmUiEngine *NmUiEngine::mInstance;
+int NmUiEngine::mReferenceCount;
+
+const QString syncIndicatorName = "com.nokia.nmail.indicatorplugin.sync/1.0";
+
+/*!
+ Constructor
+*/
+NmUiEngine::NmUiEngine()
+: mMailboxListModel(NULL),
+ mInboxListModel(NULL),
+ mMessageListModel(NULL),
+ mMessageSearchListModel(NULL),
+ mSendOperation(NULL),
+ mRemoveDraftOperation(NULL),
+ mSaveDraftOperation(NULL),
+ mDraftMessage(NULL)
+{
+ NM_FUNCTION;
+
+ mPluginFactory = NmDataPluginFactory::instance();
+ mDataManager = new NmDataManager();
+ // Connect to the plugins to receive change notifications
+ QList<QObject*> *dataPlugins = mPluginFactory->pluginInstances();
+ for (int i(0); i < dataPlugins->count(); i++) {
+ QObject *plugin = (*dataPlugins)[i];
+ if (plugin) {
+ // connet mailbox events
+ QObject::connect(plugin, SIGNAL(mailboxEvent(NmMailboxEvent, const QList<NmId> &)),
+ this, SLOT(handleMailboxEvent(NmMailboxEvent, const QList<NmId> &)),
+ Qt::UniqueConnection);
+ // connect message events
+ QObject::connect(plugin,
+ SIGNAL(messageEvent(NmMessageEvent, const NmId &, const QList<NmId> &, const NmId&)),
+ this, SLOT(handleMessageEvent(NmMessageEvent, const NmId &, const QList<NmId> &, const NmId &)),
+ Qt::UniqueConnection);
+ // connect connection events
+ QObject::connect(plugin,
+ SIGNAL(connectionEvent(NmConnectState, const NmId &, const int)),
+ this,
+ SLOT(handleConnectEvent(NmConnectState, const NmId &, const int)),
+ Qt::UniqueConnection);
+ // do the subscriptions also
+ NmDataPluginInterface *pluginInterface = mPluginFactory->interfaceInstance(plugin);
+ if (pluginInterface) {
+ QList<NmId> mailboxIdList;
+ pluginInterface->listMailboxIds(mailboxIdList);
+ for (int j(0); j < mailboxIdList.count(); j++) {
+ pluginInterface->subscribeMailboxEvents(mailboxIdList[j]);
+ }
+ mailboxIdList.clear();
+ }
+ }
+ }
+}
+
+
+/*!
+ Class destructor.
+*/
+NmUiEngine::~NmUiEngine()
+{
+ NM_FUNCTION;
+
+ enableSyncIndicator(false);
+
+ if (mMessageSearchListModel) {
+ delete mMessageSearchListModel;
+ mMessageSearchListModel = NULL;
+ }
+
+ if (mInboxListModel) {
+ delete mInboxListModel;
+ mInboxListModel = NULL;
+ }
+
+ if (mMessageListModel) {
+ delete mMessageListModel;
+ mMessageListModel = NULL;
+ }
+
+ if (mMailboxListModel) {
+ delete mMailboxListModel;
+ mMailboxListModel = NULL;
+ }
+
+ // Do the unsubscriptions.
+ QList<NmId> mailboxIdList;
+ mDataManager->listMailboxIds(mailboxIdList);
+
+ for (int i(0); i < mailboxIdList.count(); i++) {
+ NmId id = mailboxIdList[i];
+ NmDataPluginInterface *pluginInterface =
+ mPluginFactory->interfaceInstance(id);
+
+ if (pluginInterface) {
+ pluginInterface->unsubscribeMailboxEvents(id);
+ }
+ }
+
+ mailboxIdList.clear();
+
+ NmDataPluginFactory::releaseInstance(mPluginFactory);
+
+ delete mDataManager;
+
+ // Cancel all operations.
+ if (mSendOperation && mSendOperation->isRunning()) {
+ mSendOperation->cancelOperation();
+ }
+
+ if (mRemoveDraftOperation && mRemoveDraftOperation->isRunning()) {
+ mRemoveDraftOperation->cancelOperation();
+ }
+
+ if (mSaveDraftOperation && mSaveDraftOperation->isRunning()) {
+ mSaveDraftOperation->cancelOperation();
+ }
+
+ // Call processEvents() to ensure that the cancelled operations get the time
+ // they need to destroy themselves.
+ qApp->processEvents();
+
+ if(mDraftMessage) {
+ delete mDraftMessage;
+ mDraftMessage = NULL;
+ }
+}
+
+
+/*!
+
+*/
+NmUiEngine *NmUiEngine::instance()
+{
+ NM_FUNCTION;
+
+ if (!mInstance) {
+ mInstance = new NmUiEngine();
+ }
+ mReferenceCount++;
+ return mInstance;
+}
+
+/*!
+
+*/
+void NmUiEngine::releaseInstance(NmUiEngine *&instance)
+{
+ NM_FUNCTION;
+
+ //can't have passed out instances if we don't have any
+ if (mInstance) {
+ if(instance == mInstance) {
+ instance = NULL;
+ mReferenceCount--;
+ }
+ if (0 >= mReferenceCount) {
+ delete mInstance;
+ mInstance = NULL;
+ }
+ }
+}
+
+/*!
+ Returns a list model populated with the mailbox and top level folder objects. The model is
+ updated dynamically. The ownership of the model object is not moved to the caller.
+*/
+NmMailboxListModel &NmUiEngine::mailboxListModel()
+{
+ NM_FUNCTION;
+
+ if (!mMailboxListModel) {
+ refreshMailboxListModel(); // creates the model too
+ }
+
+ return *mMailboxListModel;
+}
+
+/*!
+ Populate the list model with the mailbox and top level folder objects. The model is
+ updated dynamically. Creates the model if needed.
+*/
+void NmUiEngine::refreshMailboxListModel()
+{
+ NM_FUNCTION;
+
+ if (!mMailboxListModel) {
+ mMailboxListModel = new NmMailboxListModel(*mDataManager);
+
+ // Connect the model to the plugins to receive change notifications
+ QList<QObject*> *dataPlugins = mPluginFactory->pluginInstances();
+ for (int i = 0; i < dataPlugins->count(); i++) {
+ QObject *plugin = (*dataPlugins)[i];
+ if (plugin) {
+ connect(plugin, SIGNAL(mailboxEvent(NmMailboxEvent, const QList<NmId> &)),
+ mMailboxListModel, SLOT(handleMailboxEvent(NmMailboxEvent, const QList<NmId> &)));
+ }
+ }
+ } else {
+ mMailboxListModel->clear();
+ }
+
+ QList<NmMailbox*> mailboxList;
+ mDataManager->listMailboxes(mailboxList);
+ mMailboxListModel->refresh(mailboxList);
+ while (!mailboxList.isEmpty()) {
+ delete mailboxList.takeFirst();
+ }
+}
+
+
+/*!
+ Returns a message list model for a folder identified by \a mailboxId and
+ \a folderId. The model is updated dynamically. The ownership of the model
+ object is not moved to the caller.
+*/
+NmMessageListModel &NmUiEngine::messageListModel(const NmId &mailboxId,
+ const NmId &folderId)
+{
+ NM_FUNCTION;
+
+ QObject *plugin = mPluginFactory->pluginInstance(mailboxId);
+ bool isInbox(false);
+ if (standardFolderId(mailboxId,NmFolderInbox)==folderId){
+ isInbox=true;
+ }
+ if (plugin) {
+ // Connect plugin message events to handler slot messageEventForListModel
+ QObject::connect(plugin, SIGNAL(messageEvent(NmMessageEvent, const NmId &,
+ const QList<NmId> &, const NmId&)),
+ this, SLOT(messageEventForListModel(NmMessageEvent,
+ const NmId &, const QList<NmId> &, const NmId&)), Qt::UniqueConnection );
+ // Create inbox list model only once when entering to inbox for the first time
+ // or re-create inbox list model when mailbox has changed
+ if ((!mInboxListModel&&isInbox)||
+ (mInboxListModel&&isInbox&&mailboxId!=mInboxListModel->currentMailboxId())){
+ // Delete previous model and set to NULL. Deleting model will also
+ // delete all items in model.
+ if (mInboxListModel){
+ delete mInboxListModel;
+ mInboxListModel=NULL;
+ }
+ // Create new inbox model
+ mInboxListModel = new NmMessageListModel(*mDataManager);
+ // Initial fill up of inbox list model, otherwise updated in the background
+ QList<NmMessageEnvelope*> messageEnvelopeList;
+ mDataManager->listMessages(mailboxId, folderId, messageEnvelopeList);
+ mInboxListModel->refresh(mailboxId, folderId, messageEnvelopeList);
+
+ while (!messageEnvelopeList.isEmpty()) {
+ delete messageEnvelopeList.takeFirst();
+ }
+ }
+ // Selected folder is not inbox folder for the mailbox
+ else if (!isInbox){
+ // Recreate model for other folders when needed, previous model
+ // items are deleted from the memory with the old model
+ if (mMessageListModel){
+ delete mMessageListModel;
+ mMessageListModel=NULL;
+ }
+ mMessageListModel = new NmMessageListModel(*mDataManager);
+
+ // Fill up other model
+ QList<NmMessageEnvelope*> messageEnvelopeList;
+ mDataManager->listMessages(mailboxId, folderId, messageEnvelopeList);
+ mMessageListModel->refresh(mailboxId, folderId, messageEnvelopeList);
+
+ while (!messageEnvelopeList.isEmpty()) {
+ delete messageEnvelopeList.takeFirst();
+ }
+ }
+ }
+
+ // Connect sync state changed
+ if (plugin){
+ QObject::connect(
+ plugin, SIGNAL(syncStateEvent(NmSyncState, const NmOperationCompletionEvent &)),
+ this, SLOT(handleSyncStateEvent(NmSyncState, const NmOperationCompletionEvent &)),
+ Qt::UniqueConnection);
+ }
+ NmMessageListModel* ret(NULL);
+ if (isInbox){
+ ret = mInboxListModel;
+ // Inbox list model is queried, other model is not
+ // needed anymore and memory should be freeded
+ if (mMessageListModel){
+ delete mMessageListModel;
+ mMessageListModel=NULL;
+ }
+ }
+ else {
+ ret = mMessageListModel;
+ }
+ return *ret;
+}
+
+
+/*!
+ Returns a message list model used in the search view.
+
+ \param mailboxId The ID of the mailbox to search messages from.
+
+ \return A message list model.
+*/
+NmMessageListModel &NmUiEngine::messageListModelForSearch(const NmId &mailboxId)
+{
+ NM_FUNCTION;
+
+ Q_UNUSED(mailboxId);
+
+ if (!mMessageSearchListModel) {
+ mMessageSearchListModel = new NmMessageListModel(*mDataManager);
+ mMessageSearchListModel->setIgnoreFolderIds(true);
+ }
+ else {
+ mMessageSearchListModel->clear();
+ }
+
+ QObject *plugin = mPluginFactory->pluginInstance(mailboxId);
+
+ if (plugin) {
+ QObject::connect(plugin,
+ SIGNAL(messageEvent(NmMessageEvent, const NmId &, const QList<NmId> &, const NmId &)),
+ mMessageSearchListModel,
+ SLOT(handleMessageEvent(NmMessageEvent, const NmId &, const QList<NmId> &, const NmId &)),
+ Qt::UniqueConnection);
+ }
+
+ // Refresh to set the mailbox ID.
+ QList<NmMessageEnvelope*> messageEnvelopeList;
+ mMessageSearchListModel->refresh(mailboxId, 0, messageEnvelopeList);
+
+ return *mMessageSearchListModel;
+}
+
+
+/*!
+ Get the identifier of the standard folder of a type \a folderType
+ from the mailbox \a mailboxId.
+*/
+NmId NmUiEngine::standardFolderId(
+ const NmId &mailboxId,
+ NmFolderType folderType)
+{
+ NM_FUNCTION;
+
+ NmId value;
+ if (folderType != NmFolderOther) {
+ NmDataPluginInterface *plugin =
+ mPluginFactory->interfaceInstance(mailboxId);
+ if(plugin) {
+ value = plugin->getStandardFolderId(mailboxId, folderType);
+ }
+ }
+ return value;
+}
+
+/*!
+ Returns a message identified by \a mailboxId, \a folderId and \amessageId.
+ The ownership of the object is moved to the caller.
+ Returns null pointer if the message is not found.
+*/
+NmMessage *NmUiEngine::message(const NmId &mailboxId,
+ const NmId &folderId,
+ const NmId &messageId)
+{
+ NM_FUNCTION;
+
+ NmMessage *message = mDataManager->message(mailboxId, folderId, messageId);
+ return message;
+}
+
+/*!
+
+*/
+QPointer<NmOperation> NmUiEngine::fetchMessage( const NmId &mailboxId,
+ const NmId &folderId,
+ const NmId &messageId )
+{
+ NM_FUNCTION;
+
+ QPointer<NmOperation> value(NULL);
+ NmDataPluginInterface *plugin =
+ mPluginFactory->interfaceInstance(mailboxId);
+ if (plugin) {
+ value = plugin->fetchMessage(mailboxId, folderId, messageId);
+ }
+ return value;
+}
+
+/*!
+
+*/
+QPointer<NmOperation> NmUiEngine::fetchMessagePart(
+ const NmId &mailboxId,
+ const NmId &folderId,
+ const NmId &messageId,
+ const NmId &messagePartId)
+{
+ NM_FUNCTION;
+
+ QPointer<NmOperation> value(NULL);
+ NmDataPluginInterface *plugin =
+ mPluginFactory->interfaceInstance(mailboxId);
+ if (plugin) {
+ value = plugin->fetchMessagePart(mailboxId, folderId, messageId, messagePartId);
+ }
+ return value;
+}
+
+/*!
+
+*/
+QPointer<NmOperation> NmUiEngine::fetchMessageParts(
+ const NmId &mailboxId,
+ const NmId &folderId,
+ const NmId &messageId,
+ const QList<NmId> &messagePartIds)
+{
+ NM_FUNCTION;
+
+ QPointer<NmOperation> value(NULL);
+ NmDataPluginInterface *plugin =
+ mPluginFactory->interfaceInstance(mailboxId);
+ if (plugin) {
+ value = plugin->fetchMessageParts(mailboxId, folderId, messageId, messagePartIds);
+ }
+ return value;
+}
+
+/*!
+
+*/
+XQSharableFile NmUiEngine::messagePartFile(
+ const NmId &mailboxId,
+ const NmId &folderId,
+ const NmId &messageId,
+ const NmId &messagePartId)
+{
+ NM_FUNCTION;
+
+ NmDataPluginInterface *plugin =
+ mPluginFactory->interfaceInstance(mailboxId);
+ if (plugin) {
+ return plugin->messagePartFile(mailboxId, folderId, messageId, messagePartId);
+ }
+ else {
+ // empty file handle
+ return XQSharableFile();
+ }
+}
+/*!
+ Get content to message part
+*/
+int NmUiEngine::contentToMessagePart(
+ const NmId &mailboxId,
+ const NmId &folderId,
+ const NmId &messageId,
+ NmMessagePart &messagePart)
+{
+ NM_FUNCTION;
+
+ return mDataManager->contentToMessagePart(mailboxId, folderId, messageId, messagePart);
+}
+
+
+/*!
+ Deletes messages from the model and forwards the call to plugin.
+
+ \param mailboxId The ID of the mailbox which contains the deleted message(s).
+ \param folderId The ID of the folder which contains the deleted message(s).
+ \param messageIdList A list containing the IDs of the message to be deleted.
+
+ \return A possible error code (returned by the plugin).
+*/
+int NmUiEngine::deleteMessages(const NmId &mailboxId,
+ const NmId &folderId,
+ const QList<NmId> &messageIdList)
+{
+ NM_FUNCTION;
+
+ int result(NmNotFoundError);
+
+ bool isInbox(false);
+ if (standardFolderId(mailboxId,NmFolderInbox)==folderId){
+ isInbox=true;
+ }
+ if (isInbox&&mInboxListModel){
+ mInboxListModel->handleMessageEvent(NmMessageDeleted, folderId,
+ messageIdList, mailboxId);
+ }
+ else if (mMessageListModel) {
+ mMessageListModel->handleMessageEvent(NmMessageDeleted, folderId,
+ messageIdList, mailboxId);
+ }
+
+ // If the search list model exists and contains message, remove the
+ // message from it too.
+ if (mMessageSearchListModel && mMessageSearchListModel->rowCount()) {
+ mMessageSearchListModel->handleMessageEvent(NmMessageDeleted, folderId,
+ messageIdList, mailboxId);
+ }
+
+ NmDataPluginInterface *plugin =
+ mPluginFactory->interfaceInstance(mailboxId);
+
+ if (plugin) {
+ result = plugin->deleteMessages(mailboxId, folderId, messageIdList);
+ }
+
+ return result;
+}
+
+
+/*!
+ Sets the envelope property for the given envelopes.
+ The operation is automatically deleted after the completion or cancelling.
+
+ \param mailboxId The ID of the mailbox containing the envelope(s).
+ \param folderId The ID of the folder containing the envelope(s).
+ \param property The property to set.
+ \param envelopeList The list containing the envelopes.
+
+ \return The constructed operation.
+*/
+QPointer<NmStoreEnvelopesOperation> NmUiEngine::setEnvelopes(
+ const NmId &mailboxId,
+ const NmId &folderId,
+ NmEnvelopeProperties property,
+ const QList<const NmMessageEnvelope*> &envelopeList)
+{
+ NM_FUNCTION;
+
+ QPointer<NmStoreEnvelopesOperation> operation(NULL);
+ NmMessageListModel *theMessageListModel = mMessageListModel;
+
+ if (!theMessageListModel) {
+ theMessageListModel = &messageListModel(mailboxId, folderId);
+ }
+
+ if (theMessageListModel && envelopeList.count()) {
+ QList<NmId> messageIdList;
+
+ for (int i(0); i < envelopeList.count(); i++){
+ messageIdList.append(envelopeList[i]->messageId());
+ }
+
+ theMessageListModel->setEnvelopeProperties(property, messageIdList);
+
+ if (mMessageSearchListModel && mMessageSearchListModel->rowCount()) {
+ // Update the envelopes in the search list model as well.
+ mMessageSearchListModel->setEnvelopeProperties(property,
+ messageIdList);
+ }
+
+ // Store the new envelopes to plugin.
+ NmDataPluginInterface *plugin =
+ mPluginFactory->interfaceInstance(mailboxId);
+
+ if (plugin) {
+ operation =
+ plugin->storeEnvelopes(mailboxId, folderId, envelopeList);
+ }
+
+ messageIdList.clear();
+ }
+
+ return operation;
+}
+
+
+/*!
+ Returns a mailbox meta data object from model with the ID \a mailboxId.
+ Ownership of the return value is not moved to the caller.
+ Returns NULL if the mailbox is not found.
+*/
+NmMailboxMetaData *NmUiEngine::mailboxById(const NmId &mailboxId)
+{
+ NmMailboxMetaData *meta(NULL);
+ if (mMailboxListModel) {
+ for (int i(0); i < mMailboxListModel->rowCount(); i++) {
+ QModelIndex index = mMailboxListModel->index(i,0);
+ NmMailboxMetaData *mailbox =
+ mMailboxListModel->data(index, Qt::DisplayRole).value<NmMailboxMetaData*>();
+ if (mailbox && mailbox->id() == mailboxId) {
+ meta = mailbox;
+ break;
+ }
+ }
+ }
+ return meta;
+}
+
+
+/*!
+ Creates a new message (into Drafts-folder).
+ Operation is automatically deleted after completion or cancelling.
+*/
+QPointer<NmMessageCreationOperation> NmUiEngine::createNewMessage(const NmId &mailboxId)
+{
+ NM_FUNCTION;
+
+ QPointer<NmMessageCreationOperation> value(NULL);
+ NmDataPluginInterface *plugin =
+ mPluginFactory->interfaceInstance(mailboxId);
+ if (plugin) {
+ value = plugin->createNewMessage(mailboxId);
+ }
+ return value;
+}
+
+/*!
+ Creates a new forward message (into Drafts-folder).
+ Operation is automatically deleted after completion or cancelling.
+*/
+QPointer<NmMessageCreationOperation> NmUiEngine::createForwardMessage(
+ const NmId &mailboxId,
+ const NmId &originalMessageId)
+{
+ NM_FUNCTION;
+
+ QPointer<NmMessageCreationOperation> value(NULL);
+ NmDataPluginInterface *plugin =
+ mPluginFactory->interfaceInstance(mailboxId);
+ if (plugin) {
+ value = plugin->createForwardMessage(mailboxId, originalMessageId);
+ }
+ return value;
+}
+
+/*!
+ Creates a new reply message (into Drafts-folder).
+ Operation is automatically deleted after completion or cancelling.
+*/
+QPointer<NmMessageCreationOperation> NmUiEngine::createReplyMessage(
+ const NmId &mailboxId,
+ const NmId &originalMessageId,
+ bool replyAll)
+{
+ NM_FUNCTION;
+
+ QPointer<NmMessageCreationOperation> value(NULL);
+ NmDataPluginInterface *plugin =
+ mPluginFactory->interfaceInstance(mailboxId);
+ if (plugin) {
+ value = plugin->createReplyMessage(mailboxId, originalMessageId, replyAll);
+ }
+ return value;
+}
+
+/*!
+ Saves a message (into message store).
+*/
+int NmUiEngine::saveMessage(const NmMessage &message)
+{
+ NM_FUNCTION;
+
+ const NmId &mailboxId = message.envelope().mailboxId();
+ int ret(NmNotFoundError);
+ NmDataPluginInterface *plugin =
+ mPluginFactory->interfaceInstance(mailboxId);
+ if (plugin) {
+ ret = plugin->saveMessage(message);
+ }
+ return ret;
+}
+
+/*!
+ Refreshes mailbox.
+*/
+int NmUiEngine::refreshMailbox(const NmId &mailboxId )
+{
+ NM_FUNCTION;
+
+ int ret(NmNotFoundError);
+ NmDataPluginInterface *plugin =
+ mPluginFactory->interfaceInstance(mailboxId);
+ if (plugin) {
+ ret = plugin->refreshMailbox(mailboxId);
+ if (NmNoError == ret) {
+ enableSyncIndicator(true);
+ }
+ }
+ return ret;
+}
+
+/*!
+ Online mailbox.
+*/
+int NmUiEngine::goOnline(const NmId &mailboxId )
+{
+ NM_FUNCTION;
+
+ int ret(NmNotFoundError);
+ NmDataPluginInterface *plugin =
+ mPluginFactory->interfaceInstance(mailboxId);
+ if (plugin) {
+ ret = plugin->goOnline(mailboxId);
+ }
+ return ret;
+}
+
+/*!
+ Offline mailbox.
+*/
+int NmUiEngine::goOffline(const NmId &mailboxId )
+{
+ NM_FUNCTION;
+
+ int ret(NmNotFoundError);
+ NmDataPluginInterface *plugin =
+ mPluginFactory->interfaceInstance(mailboxId);
+ if (plugin) {
+ ret = plugin->goOffline(mailboxId);
+ }
+ return ret;
+}
+
+/*!
+ Removes message from given mailbox and folder
+ - routes call to plugin
+*/
+int NmUiEngine::removeMessage(
+ const NmId &mailboxId,
+ const NmId &folderId,
+ const NmId &messageId)
+{
+ NM_FUNCTION;
+
+ int result(NmNotFoundError);
+ NmDataPluginInterface *plugin =
+ mPluginFactory->interfaceInstance(mailboxId);
+ if (plugin) {
+ result = plugin->removeMessage(mailboxId, folderId, messageId);
+ }
+ return result;
+}
+
+
+/*!
+ Handles draft message deletion after editor has closed, takes ownership of message.
+ */
+void NmUiEngine::removeDraftMessage(NmMessage *message)
+{
+ NM_FUNCTION;
+
+ if (message) {
+ NmDataPluginInterface *plugin =
+ mPluginFactory->interfaceInstance(message->envelope().mailboxId());
+
+ if (plugin) {
+ // to be on the safer side:
+ // we shouldn't even be here if mRemoveDraftOperation != NULL
+ if (mRemoveDraftOperation && mRemoveDraftOperation->isRunning()) {
+ mRemoveDraftOperation->cancelOperation();
+ }
+ // ownership of message changes
+ mRemoveDraftOperation = plugin->removeDraftMessage(message);
+
+ if (mRemoveDraftOperation) {
+ connect(mRemoveDraftOperation,
+ SIGNAL(operationCompleted(int)),
+ this,
+ SLOT(handleCompletedRemoveDraftOperation()));
+ }
+ }
+ }
+}
+
+/*!
+ Handles draft message saving after editor has closed, takes ownership of message.
+ */
+void NmUiEngine::saveDraftMessage(NmMessage *message,
+ const QList<NmOperation*> &preliminaryOperations)
+{
+ NM_FUNCTION;
+
+ if (message) {
+ NmDataPluginInterface *plugin =
+ mPluginFactory->interfaceInstance(message->envelope().mailboxId());
+
+ if (plugin) {
+ // to be on the safer side:
+ // we shouldn't even be here if mSaveDraftOperation != NULL
+ if (mSaveDraftOperation && mSaveDraftOperation->isRunning()) {
+ mSaveDraftOperation->cancelOperation();
+ }
+
+ mSaveDraftOperation = plugin->saveMessageWithSubparts(*message);
+
+ if (mSaveDraftOperation) {
+ // Ownership of message changes but saveMessageWithSubparts operation only makes a
+ // copy so we handle the msg object deletion in engine. mDraftMessage is deleted
+ // in handleCompletedSaveDraftOperation once operation finishes.
+ if(mDraftMessage) {
+ delete mDraftMessage;
+ mDraftMessage = NULL;
+ }
+ mDraftMessage = message;
+ message = NULL;
+
+ for (int i(0); i < preliminaryOperations.count(); i++ ) {
+ QPointer<NmOperation> op = preliminaryOperations[i];
+ mSaveDraftOperation->addPreliminaryOperation(op);
+ }
+
+ connect(mSaveDraftOperation,
+ SIGNAL(operationCompleted(int)),
+ this,
+ SLOT(handleCompletedSaveDraftOperation()));
+
+ }
+ }
+ }
+}
+
+/*!
+ Sends the given message.
+ */
+void NmUiEngine::sendMessage(NmMessage *message, const QList<NmOperation *> &preliminaryOperations)
+{
+ NM_FUNCTION;
+
+ //First trigger message storing
+ if (message) {
+ NmDataPluginInterface *plugin =
+ mPluginFactory->interfaceInstance(message->envelope().mailboxId());
+
+ if (plugin) {
+ // to be on the safer side:
+ // we shouldn't even be here if mSendOperation != NULL
+ if (mSendOperation && mSendOperation->isRunning()) {
+ mSendOperation->cancelOperation();
+ }
+ // ownership of message changes
+ mSendOperation = plugin->sendMessage(message);
+ // don't put this to mOperations as we need to handle this
+ // operation separately
+ if (mSendOperation) {
+ for (int i(0); i < preliminaryOperations.count(); i++ ) {
+ QPointer<NmOperation> op = preliminaryOperations[i];
+ mSendOperation->addPreliminaryOperation(op);
+ }
+
+ connect(mSendOperation,
+ SIGNAL(operationCompleted(int)),
+ this,
+ SLOT(handleCompletedSendOperation()));
+ }
+ }
+ }
+}
+
+/*!
+ Is sending operation in progress.
+ */
+bool NmUiEngine::isSendingMessage() const
+{
+ NM_FUNCTION;
+
+ int ret(false);
+ if (mSendOperation && mSendOperation->isRunning()) {
+ ret = true;
+ }
+ return ret;
+}
+
+/*!
+ Returns a pointer to the message that is being sent. Returns NULL if not sending.
+ */
+const NmMessage *NmUiEngine::messageBeingSent() const
+{
+ NM_FUNCTION;
+
+ const NmMessage *message = NULL;
+
+ if (mSendOperation != NULL) {
+ message = mSendOperation->getMessage();
+ }
+
+ return message;
+}
+
+/*!
+ Add file attachment into given message. Return the operation object for
+ observing/cancelling. Operation is automatically deleted after completion or cancelling.
+ */
+QPointer<NmAddAttachmentsOperation> NmUiEngine::addAttachments(
+ const NmMessage &message,
+ const QList<QString> &fileList)
+{
+ NM_FUNCTION;
+
+ NmDataPluginInterface *plugin =
+ mPluginFactory->interfaceInstance(message.envelope().mailboxId());
+
+ QPointer<NmAddAttachmentsOperation> ret(NULL);
+ if (plugin) {
+ ret = plugin->addAttachments(message, fileList);
+ }
+ return ret;
+}
+
+/*!
+ Remove attached file from given message. Return the operation object for
+ observing/cancelling. Operation is automatically deleted after completion or cancelling.
+ */
+QPointer<NmOperation> NmUiEngine::removeAttachment(
+ const NmMessage &message,
+ const NmId &attachmentPartId)
+{
+ NM_FUNCTION;
+
+ NmDataPluginInterface *plugin =
+ mPluginFactory->interfaceInstance(message.envelope().mailboxId());
+
+ QPointer<NmOperation> ret(NULL);
+ if (plugin) {
+ ret = plugin->removeAttachment(message, attachmentPartId);
+ }
+ return ret;
+}
+
+/*!
+ Returns the current sync state of the mailbox
+ */
+NmSyncState NmUiEngine::syncState(const NmId& mailboxId)
+{
+ NM_FUNCTION;
+
+ NmDataPluginInterface *plugin =
+ mPluginFactory->interfaceInstance(mailboxId);
+ if (plugin) {
+ return plugin->syncState(mailboxId);
+ }
+ else {
+ return SyncComplete;
+ }
+}
+
+/*!
+ Returns the current connection state of the mailbox
+ */
+NmConnectState NmUiEngine::connectionState(const NmId& mailboxId)
+{
+ NM_FUNCTION;
+
+ NmDataPluginInterface *plugin =
+ mPluginFactory->interfaceInstance(mailboxId);
+ if (plugin) {
+ return plugin->connectionState(mailboxId);
+ }
+ else {
+ return Disconnected;
+ }
+}
+
+
+/*!
+ Starts the search.
+
+ \param mailboxId The ID of the mailbox to search from.
+ \param searchStrings The strings to search with.
+
+ \return A possible error code.
+*/
+int NmUiEngine::search(const NmId &mailboxId,
+ const QStringList &searchStrings)
+{
+ NM_FUNCTION;
+
+ // Get the plugin instance.
+ QObject *pluginInstance = mPluginFactory->pluginInstance(mailboxId);
+
+ if (pluginInstance) {
+ // Make sure the required signals are connected.
+ connect(pluginInstance, SIGNAL(matchFound(const NmId &, const NmId &)),
+ this, SIGNAL(matchFound(const NmId &, const NmId &)),
+ Qt::UniqueConnection);
+
+ connect(pluginInstance, SIGNAL(matchFound(const NmId &, const NmId &)),
+ this, SLOT(handleMatchFound(const NmId &, const NmId &)),
+ Qt::UniqueConnection);
+
+ connect(pluginInstance, SIGNAL(searchComplete()),
+ this, SIGNAL(searchComplete()),
+ Qt::UniqueConnection);
+ }
+
+ int retVal(NmNoError);
+
+ // Get the plugin interface.
+ NmDataPluginInterface *pluginInterface =
+ mPluginFactory->interfaceInstance(mailboxId);
+
+ if (pluginInterface) {
+ // Start the search.
+ retVal = pluginInterface->search(mailboxId, searchStrings);
+ }
+
+ return retVal;
+}
+
+
+/*!
+ Cancels the search operation if one is ongoing.
+
+ \param mailboxId The ID of the mailbox running the search.
+
+ \return A possible error code.
+*/
+int NmUiEngine::cancelSearch(const NmId &mailboxId)
+{
+ NM_FUNCTION;
+
+ int retVal(NmNoError);
+
+ // Get the plugin interface.
+ NmDataPluginInterface *pluginInterface =
+ mPluginFactory->interfaceInstance(mailboxId);
+
+ if (pluginInterface) {
+ // Cancel the search.
+ retVal = pluginInterface->cancelSearch(mailboxId);
+ }
+ return retVal;
+}
+
+/*!
+ Get mailbox folder type by folder id
+ \param mailboxId id of the mailbox
+ \param folderId id of the folder
+ \return Folder type
+*/
+NmFolderType NmUiEngine::folderTypeById(NmId mailboxId, NmId folderId)
+{
+ NM_FUNCTION;
+
+ NmFolderType ret(NmFolderInbox);
+ if (mDataManager){
+ ret = mDataManager->folderTypeById(mailboxId,folderId);
+ }
+ return ret;
+}
+
+/*!
+ Indicates application state information to protocol plugin
+ \param mailboxId Id of active mailbox, 0 if application is closed.
+ \param folderId Id of active folder, 0 if application is closed.
+*/
+void NmUiEngine::updateActiveFolder(const NmId &mailboxId, const NmId &folderId)
+{
+ NM_FUNCTION;
+
+ NmApplicationStateInterface *interface =
+ mPluginFactory->applicationStateInterfaceInstance(mailboxId);
+ if (interface) {
+ interface->updateActiveFolder(mailboxId, folderId);
+ }
+}
+
+/*!
+ Handle completed send operation.
+*/
+void NmUiEngine::handleCompletedSendOperation()
+{
+ NM_FUNCTION;
+
+ emit sendOperationCompleted();
+}
+
+/*!
+ Handle completed remove draft operation.
+*/
+void NmUiEngine::handleCompletedRemoveDraftOperation()
+{
+ NM_FUNCTION;
+
+ // draft message deletion observing not yet implemented...
+}
+
+/*!
+ Handle completed save draft operation.
+*/
+void NmUiEngine::handleCompletedSaveDraftOperation()
+{
+ NM_FUNCTION;
+
+ // delete message object since it's not needed anymore
+ if(mDraftMessage) {
+ delete mDraftMessage;
+ mDraftMessage = NULL;
+ }
+}
+
+/*!
+ Handles synch operation related events
+ */
+void NmUiEngine::handleSyncStateEvent(NmSyncState syncState, const NmOperationCompletionEvent &event)
+{
+ NM_FUNCTION;
+
+ if ( syncState == SyncComplete ) {
+ // signal for reporting about (sync) operation completion status
+ emit operationCompleted(event);
+
+ enableSyncIndicator(false);
+ }
+
+ // signal for handling sync state icons
+ emit syncStateEvent(syncState, event.mMailboxId);
+}
+
+/*!
+ Enable or disable sync indicator
+
+ \param enabled true if indicator is enabled, false if disabled
+*/
+void NmUiEngine::enableSyncIndicator(bool enabled)
+{
+ NM_FUNCTION;
+
+ HbIndicator indicator;
+ if (enabled) {
+ indicator.activate(syncIndicatorName, QVariant());
+ }
+ else {
+ indicator.deactivate(syncIndicatorName, QVariant());
+ }
+}
+
+/*!
+ Gets the signature for the given mailbox.
+
+ \param mailboxId The mailbox id whose signature is asked.
+ \param signature The reference to the signature string pointer. NULL if no signature.
+*/
+int NmUiEngine::getSignature(const NmId &mailboxId, QString *&signature)
+{
+ NM_FUNCTION;
+
+ int retVal(NmNoError);
+
+ // Get the plugin interface.
+ NmDataPluginInterface *pluginInterface =
+ mPluginFactory->interfaceInstance(mailboxId);
+
+ if (pluginInterface) {
+ retVal = pluginInterface->getSignature(mailboxId, signature);
+ }
+
+ return retVal;
+}
+
+/*!
+ Emits signals based on message events coming from plugins.
+ Currently only NmMessageDeleted is handled.
+*/
+void NmUiEngine::handleMessageEvent(NmMessageEvent event,
+ const NmId &folderId,
+ const QList<NmId> &messageIds,
+ const NmId& mailboxId)
+{
+ NM_FUNCTION;
+
+ switch (event) {
+ case NmMessageDeleted:
+ {
+ for (int i(0); i < messageIds.count(); i++) {
+ emit messageDeleted(mailboxId, folderId, messageIds[i]);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+/*!
+ Emits signals based on mailbox events coming from plugins.
+ Currently only NmMailboxDeleted is handled.
+*/
+void NmUiEngine::handleMailboxEvent(NmMailboxEvent event,
+ const QList<NmId> &mailboxIds)
+{
+ NM_FUNCTION;
+
+ switch (event) {
+ case NmMailboxDeleted:
+ {
+ for (int i(0); i < mailboxIds.count(); i++) {
+ emit mailboxDeleted(mailboxIds[i]);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+
+/*!
+ Adds the found message into the search model.
+
+ \param messageId The ID of the found message.
+ \param folderId The ID of the folder where the message is located.
+*/
+void NmUiEngine::handleMatchFound(const NmId &messageId, const NmId &folderId)
+{
+ NM_FUNCTION;
+
+ if (!mMessageSearchListModel) {
+ // No search list model!
+ return;
+ }
+
+ // Resolve the folder type.
+ NmId mailboxId = mMessageSearchListModel->currentMailboxId();
+ NmFolderType folderType = folderTypeById(mailboxId, folderId);
+
+ // Do not display matches from outbox or draft folders.
+ if (folderType != NmFolderOutbox && folderType != NmFolderDrafts) {
+ // Add the found message into the search model.
+ QList<NmId> messageIdList;
+ messageIdList.append(messageId);
+
+ mMessageSearchListModel->handleMessageEvent(NmMessageFound, folderId,
+ messageIdList, mailboxId);
+ }
+}
+
+/*!
+ Function sens events from plugin to both models. Inbox model for
+ active mailbox is always alove whereas mMessageListModel can represent
+ other folder in the device (sent, outbox, drafts, etc.)
+*/
+void NmUiEngine::messageEventForListModel(NmMessageEvent event,
+ const NmId &folderId,
+ const QList<NmId> &messageIds,
+ const NmId& mailboxId)
+{
+ NM_FUNCTION;
+
+ // Forward event to both list models. Models will take care of checking
+ // whether event really belongs to current mailbox & folder
+ if (mInboxListModel){
+ mInboxListModel->handleMessageEvent(event, folderId,
+ messageIds, mailboxId);
+ }
+ if (mMessageListModel){
+ mMessageListModel->handleMessageEvent(event, folderId,
+ messageIds, mailboxId);
+ }
+}
+
+/*!
+ receives events when going online, and offline.
+*/
+void NmUiEngine::handleConnectEvent(NmConnectState connectState, const NmId &mailboxId, const int errorCode)
+{
+ NM_FUNCTION;
+
+ // signal for connection state icon handling
+ emit connectionEvent(connectState, mailboxId);
+
+ // in case going offline w/ error, emit signal to UI
+ if ( connectState == Disconnected && errorCode!= NmNoError ) {
+ NmOperationCompletionEvent event={NoOp, errorCode, mailboxId, 0, 0};
+ emit operationCompleted(event);
+ }
+}