emailuis/nmailui/src/nmsendserviceinterface.cpp
changeset 18 578830873419
child 20 ecc8def7944a
equal deleted inserted replaced
4:e7aa27f58ae1 18:578830873419
       
     1 /*
       
     2  * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3  * All rights reserved.
       
     4  * This component and the accompanying materials are made available
       
     5  * under the terms of "Eclipse Public License v1.0"
       
     6  * which accompanies this distribution, and is available
       
     7  * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8  *
       
     9  * Initial Contributors:
       
    10  * Nokia Corporation - initial contribution.
       
    11  *
       
    12  * Contributors:
       
    13  *
       
    14  * Description: NMail Application Launcher interface used for interfacing between
       
    15  *              QT highway and other applications
       
    16  *
       
    17  */
       
    18 
       
    19 //  INCLUDES
       
    20 #include "nmuiheaders.h"
       
    21 
       
    22 //  CONSTANTS
       
    23 static const QString emailSendSubjectKey = "subject";
       
    24 static const QString emailSendToKey = "to";
       
    25 static const QString emailSendCcKey = "cc";
       
    26 static const QString emailSendBccKey = "bcc";
       
    27 
       
    28 
       
    29 /*!
       
    30     \class NmStartParamDataHelper
       
    31     \brief A helper class for processing the data given to the actual service.
       
    32 */
       
    33 class NmStartParamDataHelper
       
    34 {
       
    35 public:
       
    36 
       
    37     /*!
       
    38         Class constructor.
       
    39     */
       
    40     inline NmStartParamDataHelper()
       
    41     : mSubject(0),
       
    42       mToAddresses(0),
       
    43       mCcAddresses(0),
       
    44       mBccAddresses(0),
       
    45       mAttachmentList(0),
       
    46       mEditorStartMode(NmUiEditorCreateNew)
       
    47     {
       
    48     }
       
    49 
       
    50     /*!
       
    51         Class destructor.
       
    52     */
       
    53     inline ~NmStartParamDataHelper()
       
    54     {
       
    55     }
       
    56 
       
    57     /*!
       
    58         Extracts the data from the given QVariant into the class members.
       
    59         \param data QVariant containing the data.
       
    60         \return True if success, false otherwise.
       
    61     */
       
    62     inline bool extractData(const QVariant &data)
       
    63     {
       
    64         QVariant::Type dataType = data.type();
       
    65         bool success = false;
       
    66 
       
    67         switch (dataType) {
       
    68             case QVariant::String: {
       
    69                 // The given data contains a single attachment.
       
    70                 QString attachment = data.toString();
       
    71                 mAttachmentList = new QStringList(attachment);
       
    72                 success = true;
       
    73                 break;
       
    74             }
       
    75             case QVariant::StringList: {
       
    76                 // The given data contains a list of attachments.
       
    77                 QStringList attachmentList = data.toStringList();
       
    78                 mAttachmentList = new QStringList(attachmentList);
       
    79                 success = true;
       
    80                 break;
       
    81             }
       
    82             case QVariant::Map: {
       
    83                 // The given data may contain a mail subject and recipient lists.
       
    84                 QMap<QString, QVariant> map = data.toMap();
       
    85                 success = processMap(map);
       
    86                 break;
       
    87             }
       
    88             default: {
       
    89                 // Data type not supported!
       
    90                 NMLOG("NmStartParamDataHelper::extractData(): Data type not supported!");
       
    91                 break;
       
    92             }
       
    93         } // switch ()
       
    94 
       
    95         // Determine the editor start mode.
       
    96         if (mToAddresses || mCcAddresses || mBccAddresses) {
       
    97             mEditorStartMode = NmUiEditorMailto;
       
    98         }
       
    99         else if (mAttachmentList) {
       
   100             mEditorStartMode = NmUiEditorCreateNew;
       
   101         }
       
   102 
       
   103         return success;
       
   104     }
       
   105 
       
   106     /*!
       
   107         Deletes the class members. Must be used if NmUiStartParam does not
       
   108         take ownership of the members.
       
   109     */
       
   110     inline void deleteData()
       
   111     {
       
   112         delete mSubject;
       
   113         mSubject = 0;
       
   114 
       
   115         if (mToAddresses) {
       
   116             qDeleteAll(*mToAddresses);
       
   117             delete mToAddresses;
       
   118             mToAddresses = 0;
       
   119         }
       
   120 
       
   121         if (mCcAddresses) {
       
   122             qDeleteAll(*mCcAddresses);
       
   123             delete mCcAddresses;
       
   124             mCcAddresses = 0;
       
   125         }
       
   126 
       
   127         if (mBccAddresses) {
       
   128             qDeleteAll(*mBccAddresses);
       
   129             delete mBccAddresses;
       
   130             mBccAddresses = 0;
       
   131         }
       
   132 
       
   133         delete mAttachmentList;
       
   134         mAttachmentList = 0;
       
   135     }
       
   136 
       
   137 
       
   138 private:
       
   139 
       
   140     /*!
       
   141         Extracts the data from the given map into the class members.
       
   142         \param map The map to extract the data from.
       
   143         \return True if success, false otherwise.
       
   144     */
       
   145     inline bool processMap(const QMap<QString, QVariant> &map)
       
   146     {
       
   147         QMap<QString, QVariant>::const_iterator i = map.constBegin();
       
   148         QString key;
       
   149         QVariant value;
       
   150         
       
   151         while (i != map.constEnd()) {
       
   152             key = i.key();
       
   153             value = i.value();
       
   154             
       
   155             if (!key.compare(emailSendSubjectKey, Qt::CaseInsensitive) &&
       
   156                 value.type() == QVariant::String) {
       
   157                 // Extract the mail subject.
       
   158                 if (mSubject) {
       
   159                     // A subject string has already been extracted! Discard the
       
   160                     // old subject.
       
   161                     delete mSubject;
       
   162                 }
       
   163 
       
   164                 mSubject = new QString(value.toString());
       
   165             }
       
   166             else if (!key.compare(emailSendToKey, Qt::CaseInsensitive)) {
       
   167                 // Extract the "to" recipients.
       
   168                 addAddressesToList(value, &mToAddresses);
       
   169             }
       
   170             else if (!key.compare(emailSendCcKey, Qt::CaseInsensitive)) {
       
   171                 // Extract the "cc" recipients.
       
   172                 addAddressesToList(value, &mCcAddresses);
       
   173             }
       
   174             else if (!key.compare(emailSendBccKey, Qt::CaseInsensitive)) {
       
   175                 // Extract the "bcc" recipients.
       
   176                 addAddressesToList(value, &mBccAddresses);
       
   177             }
       
   178 
       
   179             ++i;
       
   180         }
       
   181 
       
   182         // In principle it is ok even if the map does not contain any data e.g.
       
   183         // in a case where the editor view needs to be opened without any
       
   184         // predefined data. Therefore, we always return true.
       
   185         return true;
       
   186     }
       
   187 
       
   188     /*!
       
   189         Appends the given addresses into the given list.
       
   190         \param address The addresses to append.
       
   191         \param list The list where the addresses are appended to.
       
   192     */
       
   193     inline void addAddressesToList(const QVariant &addresses,
       
   194                                    QList<NmAddress*> **list)
       
   195     {
       
   196       
       
   197         if (!list) {
       
   198             // Invalid argument!
       
   199             return;
       
   200         }
       
   201 
       
   202         QVariant::Type dataType = addresses.type();
       
   203         QList<NmAddress*> foundAddresses;
       
   204 
       
   205         switch (dataType) {
       
   206             case QVariant::String: {
       
   207                 // A single address.
       
   208                 NmAddress *address = new NmAddress(addresses.toString());
       
   209                 foundAddresses.append(address);
       
   210                 break;
       
   211             }
       
   212             case QVariant::StringList: {
       
   213                 // A list of addresses.
       
   214                 QStringList addressList = addresses.toStringList();
       
   215 
       
   216                 foreach (QString addressAsString, addressList) {
       
   217                     NmAddress *address = new NmAddress(addressAsString);
       
   218                     foundAddresses.append(address);
       
   219                 }
       
   220 
       
   221                 break;
       
   222             }
       
   223             default: {
       
   224                 break;
       
   225             }
       
   226         }
       
   227 
       
   228         if (foundAddresses.count()) {
       
   229             // Append the found addresses into the given list.
       
   230             if (!(*list)) {
       
   231                 *list = new QList<NmAddress*>();
       
   232             }
       
   233 
       
   234             (*list)->append(foundAddresses);
       
   235         }
       
   236     }
       
   237 
       
   238 
       
   239 public: // Data
       
   240 
       
   241     QString *mSubject; // Not owned.
       
   242     QList<NmAddress*> *mToAddresses; // Not owned.
       
   243     QList<NmAddress*> *mCcAddresses; // Not owned.
       
   244     QList<NmAddress*> *mBccAddresses; // Not owned.
       
   245     QStringList *mAttachmentList; // Not owned.
       
   246     NmUiEditorStartMode mEditorStartMode;
       
   247 };
       
   248 
       
   249 
       
   250 
       
   251 /*!
       
   252     \class NmSendServiceInterface
       
   253     \brief NMail application service interface which provides an email sending
       
   254            interface for other application using the Qt Highway. 
       
   255 */
       
   256 
       
   257 /*!
       
   258     Class constructor.
       
   259 */
       
   260 NmSendServiceInterface::NmSendServiceInterface(QObject *parent,
       
   261                                                NmUiEngine &uiEngine,
       
   262                                                NmApplication *application)
       
   263 #ifndef NM_WINS_ENV
       
   264     : XQServiceProvider(QLatin1String("com.nokia.symbian.IMessage.Send"), parent),
       
   265 #else
       
   266     : QObject(parent),
       
   267 #endif
       
   268       mApplication(application),
       
   269       mUiEngine(uiEngine),
       
   270       mAsyncReqId(0)
       
   271 {
       
   272 #ifndef NM_WINS_ENV
       
   273     publishAll();
       
   274 #endif
       
   275 }
       
   276 
       
   277 
       
   278 /*!
       
   279     Class desctructor.
       
   280 */
       
   281 NmSendServiceInterface::~NmSendServiceInterface()
       
   282 {
       
   283 }
       
   284 
       
   285 
       
   286 /*!
       
   287     Queries the user for a mailbox to use.
       
   288     \param mailboxId Where the ID of the selected mailbox is set.
       
   289     \return True if a mailbox was selected, false otherwise.
       
   290 */
       
   291 bool NmSendServiceInterface::selectMailbox(NmId& mailboxId)
       
   292 {
       
   293 	NmMailboxSelectionDialog *dialog =
       
   294 	    new NmMailboxSelectionDialog(mUiEngine.mailboxListModel());
       
   295 	bool ok = dialog->exec(mailboxId);
       
   296 	delete dialog;
       
   297 	return ok;
       
   298 }
       
   299 
       
   300 
       
   301 /*!
       
   302     Used for sending email messages from external applications. Used by the
       
   303     Share UI. In addition, the interface can be used to send email to a contact
       
   304     from another application. The method sets the given data (e.g. recipients,
       
   305     attachments) to a mail composer (editor) view and displays it.
       
   306 
       
   307     \param data If used by Share UI, will contain the list of filenames to
       
   308                 attach. Can also contain a map with key value pairs containing
       
   309                 subject and recipient data. 
       
   310 */
       
   311 void NmSendServiceInterface::send(QVariant data)
       
   312 {
       
   313     NMLOG("NmSendServiceInterface::send()");
       
   314 
       
   315 #ifndef NM_WINS_ENV
       
   316     // Make sure the NMail application is on the foreground.
       
   317     XQServiceUtil::toBackground(false);
       
   318     HbMainWindow *mainWindow = mApplication->mainWindow();
       
   319     HbView *currentView = mainWindow->currentView();
       
   320 
       
   321     // Hide the current view.
       
   322     if (currentView) {
       
   323         currentView->hide();
       
   324     }
       
   325 
       
   326     // Check the given data.
       
   327     NmStartParamDataHelper dataHelper;
       
   328     bool validData = dataHelper.extractData(data);
       
   329 
       
   330     NmMailboxListModel &mailboxListModel = mUiEngine.mailboxListModel();
       
   331     const int count = mailboxListModel.rowCount();
       
   332     NmId mailboxId(0);
       
   333     bool launchEditor(true);
       
   334 
       
   335     if (!validData) {
       
   336         // Failed to extract the data!
       
   337         NMLOG("NmSendServiceInterface::send(): Failed to process the given data!");
       
   338         launchEditor = false;
       
   339     }
       
   340     else if (count == 0) {
       
   341         // No mailboxes.
       
   342         HbMessageBox note(hbTrId("txt_mail_dialog_no_mailboxes_defined"),
       
   343                           HbMessageBox::MessageTypeInformation);
       
   344         note.setTimeout(HbMessageBox::NoTimeout);
       
   345         note.exec();
       
   346         launchEditor = false;
       
   347     }
       
   348     else if (count == 1) {
       
   349         // A single mailbox exists.
       
   350         QModelIndex modelIndex = mailboxListModel.index(0, 0);
       
   351         QVariant mailbox(mailboxListModel.data(modelIndex));
       
   352         NmMailboxMetaData *mailboxMetaData = mailbox.value<NmMailboxMetaData*>();
       
   353         mailboxId = mailboxMetaData->id();
       
   354     }
       
   355     else if (count > 1 && !selectMailbox(mailboxId)) {
       
   356         // More than one mailboxes exist but the user cancelled the mailbox
       
   357         // selection dialog.
       
   358         launchEditor = false;
       
   359     }
       
   360 
       
   361     mAsyncReqId = setCurrentRequestAsync();
       
   362     
       
   363     if (launchEditor) {
       
   364         // Make the previous view visible again.
       
   365         if (currentView) {
       
   366             currentView->show();
       
   367         }
       
   368 
       
   369         NmUiStartParam *startParam = new NmUiStartParam(
       
   370             NmUiViewMessageEditor,
       
   371             mailboxId,
       
   372             0, // folder id
       
   373             0, // message id
       
   374             dataHelper.mEditorStartMode, // editor start mode
       
   375             dataHelper.mToAddresses, // address list
       
   376             dataHelper.mAttachmentList, // attachment list
       
   377             true, // start as service
       
   378             dataHelper.mSubject, // message subject
       
   379             dataHelper.mCcAddresses, // list containing cc recipient addresses
       
   380             dataHelper.mBccAddresses // list containing bcc recipient addresses
       
   381         );
       
   382 
       
   383         mApplication->enterNmUiView(startParam);
       
   384         completeRequest(mAsyncReqId, 1);
       
   385     } 
       
   386     else {
       
   387         // Delete the extracted data since the editor was not launched and thus
       
   388         // NmUiStartParam did not take the ownership of the data.
       
   389         dataHelper.deleteData();
       
   390 
       
   391         // If the service was started as embedded, do not hide the app.
       
   392 		if (!XQServiceUtil::isEmbedded()) {
       
   393 			XQServiceUtil::toBackground(true);
       
   394 		}
       
   395 
       
   396         completeRequest(mAsyncReqId, 0);
       
   397 
       
   398         // If started as service, the application must be closed now.
       
   399         if (XQServiceUtil::isService()) {
       
   400             connect(this, SIGNAL(returnValueDelivered()),
       
   401                     mApplication, SLOT(delayedExitApplication()));
       
   402         }
       
   403         else {
       
   404             // Make the previous view visible again.
       
   405             if (currentView) {
       
   406                 currentView->show();
       
   407             }
       
   408         }
       
   409     }
       
   410 #endif /* NM_WINS_ENV */
       
   411 }
       
   412 
       
   413 
       
   414 // End of file.