diff -r dcf0eedfc1a3 -r d189ee25cf9d emailuis/nmailuiengine/src/nmuiengine.cpp --- /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 *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 &)), + this, SLOT(handleMailboxEvent(NmMailboxEvent, const QList &)), + Qt::UniqueConnection); + // connect message events + QObject::connect(plugin, + SIGNAL(messageEvent(NmMessageEvent, const NmId &, const QList &, const NmId&)), + this, SLOT(handleMessageEvent(NmMessageEvent, const NmId &, const QList &, 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 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 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 *dataPlugins = mPluginFactory->pluginInstances(); + for (int i = 0; i < dataPlugins->count(); i++) { + QObject *plugin = (*dataPlugins)[i]; + if (plugin) { + connect(plugin, SIGNAL(mailboxEvent(NmMailboxEvent, const QList &)), + mMailboxListModel, SLOT(handleMailboxEvent(NmMailboxEvent, const QList &))); + } + } + } else { + mMailboxListModel->clear(); + } + + QList 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 &, const NmId&)), + this, SLOT(messageEventForListModel(NmMessageEvent, + const NmId &, const QList &, 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 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 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 &, const NmId &)), + mMessageSearchListModel, + SLOT(handleMessageEvent(NmMessageEvent, const NmId &, const QList &, const NmId &)), + Qt::UniqueConnection); + } + + // Refresh to set the mailbox ID. + QList 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 NmUiEngine::fetchMessage( const NmId &mailboxId, + const NmId &folderId, + const NmId &messageId ) +{ + NM_FUNCTION; + + QPointer value(NULL); + NmDataPluginInterface *plugin = + mPluginFactory->interfaceInstance(mailboxId); + if (plugin) { + value = plugin->fetchMessage(mailboxId, folderId, messageId); + } + return value; +} + +/*! + +*/ +QPointer NmUiEngine::fetchMessagePart( + const NmId &mailboxId, + const NmId &folderId, + const NmId &messageId, + const NmId &messagePartId) +{ + NM_FUNCTION; + + QPointer value(NULL); + NmDataPluginInterface *plugin = + mPluginFactory->interfaceInstance(mailboxId); + if (plugin) { + value = plugin->fetchMessagePart(mailboxId, folderId, messageId, messagePartId); + } + return value; +} + +/*! + +*/ +QPointer NmUiEngine::fetchMessageParts( + const NmId &mailboxId, + const NmId &folderId, + const NmId &messageId, + const QList &messagePartIds) +{ + NM_FUNCTION; + + QPointer 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 &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 NmUiEngine::setEnvelopes( + const NmId &mailboxId, + const NmId &folderId, + NmEnvelopeProperties property, + const QList &envelopeList) +{ + NM_FUNCTION; + + QPointer operation(NULL); + NmMessageListModel *theMessageListModel = mMessageListModel; + + if (!theMessageListModel) { + theMessageListModel = &messageListModel(mailboxId, folderId); + } + + if (theMessageListModel && envelopeList.count()) { + QList 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(); + 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 NmUiEngine::createNewMessage(const NmId &mailboxId) +{ + NM_FUNCTION; + + QPointer 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 NmUiEngine::createForwardMessage( + const NmId &mailboxId, + const NmId &originalMessageId) +{ + NM_FUNCTION; + + QPointer 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 NmUiEngine::createReplyMessage( + const NmId &mailboxId, + const NmId &originalMessageId, + bool replyAll) +{ + NM_FUNCTION; + + QPointer 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 &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 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 &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 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 NmUiEngine::addAttachments( + const NmMessage &message, + const QList &fileList) +{ + NM_FUNCTION; + + NmDataPluginInterface *plugin = + mPluginFactory->interfaceInstance(message.envelope().mailboxId()); + + QPointer 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 NmUiEngine::removeAttachment( + const NmMessage &message, + const NmId &attachmentPartId) +{ + NM_FUNCTION; + + NmDataPluginInterface *plugin = + mPluginFactory->interfaceInstance(message.envelope().mailboxId()); + + QPointer 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 &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 &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 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 &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); + } +}