emailuis/nmailui/src/nmeditorview.cpp
changeset 20 ecc8def7944a
parent 18 578830873419
child 23 2dc6caa42ec3
equal deleted inserted replaced
18:578830873419 20:ecc8def7944a
    23 static const char *NMUI_EDITOR_SCROLL_AREA_CONTENTS = "scrollAreaContents";
    23 static const char *NMUI_EDITOR_SCROLL_AREA_CONTENTS = "scrollAreaContents";
    24 
    24 
    25 static const int nmOrientationTimer=100;
    25 static const int nmOrientationTimer=100;
    26 
    26 
    27 static const QString Delimiter("; ");
    27 static const QString Delimiter("; ");
    28 #define IMAGE_FETCHER_INTERFACE "Image"
       
    29 #define FETCHER_OPERATION "fetch(QVariantMap,QVariant)"
       
    30 
    28 
    31 /*!
    29 /*!
    32 	\class NmEditorView
    30 	\class NmEditorView
    33 	\brief Mail editor view
    31 	\brief Mail editor view
    34 */
    32 */
    39 NmEditorView::NmEditorView(
    37 NmEditorView::NmEditorView(
    40     NmApplication &application,
    38     NmApplication &application,
    41     NmUiStartParam* startParam,
    39     NmUiStartParam* startParam,
    42     NmUiEngine &uiEngine,
    40     NmUiEngine &uiEngine,
    43     QGraphicsItem *parent)
    41     QGraphicsItem *parent)
    44 : NmBaseView(startParam, parent),
    42     : NmBaseView(startParam, parent),
    45 mApplication(application),
    43       mApplication(application),
    46 mUiEngine(uiEngine),
    44       mUiEngine(uiEngine),
    47 mDocumentLoader(NULL),
    45       mDocumentLoader(NULL),
    48 mScrollArea(NULL),
    46       mScrollArea(NULL),
    49 mEditWidget(NULL),
    47       mEditWidget(NULL),
    50 mHeaderWidget(NULL),
    48       mHeaderWidget(NULL),
    51 mMessage(NULL),
    49       mMessage(NULL),
    52 mContentWidget(NULL),
    50       mContentWidget(NULL),
    53 mAttachContextMenu(NULL),
    51       mAttachmentListContextMenu(NULL),
    54 mMessageCreationOperation(NULL),
    52       mMessageCreationOperation(NULL),
    55 mAddAttachmentOperation(NULL),
    53       mAddAttachmentOperation(NULL),
    56 mRemoveAttachmentOperation(NULL),
    54       mRemoveAttachmentOperation(NULL),
    57 mCheckOutboxOperation(NULL)
    55       mCheckOutboxOperation(NULL),
       
    56       mWaitDialog(NULL),
       
    57       mAttachmentPicker(NULL)
    58 {
    58 {
    59     mDocumentLoader	= new HbDocumentLoader();
    59     mDocumentLoader	= new HbDocumentLoader();
    60     // Set object name
    60     // Set object name
    61     setObjectName("NmEditorView");
    61     setObjectName("NmEditorView");
    62     // Load view layout
    62     // Load view layout
    70 /*!
    70 /*!
    71     Destructor
    71     Destructor
    72 */
    72 */
    73 NmEditorView::~NmEditorView()
    73 NmEditorView::~NmEditorView()
    74 {
    74 {
       
    75     // It is clearer that the operations are not owned by parent QObject as
       
    76     // they are not allocated in the constructor.
       
    77     delete mRemoveAttachmentOperation;
       
    78     delete mAddAttachmentOperation;
    75     delete mMessageCreationOperation;
    79     delete mMessageCreationOperation;
    76     delete mCheckOutboxOperation;
    80     delete mCheckOutboxOperation;
    77 
       
    78     delete mMessage;
    81     delete mMessage;
    79 
       
    80     mWidgetList.clear();
    82     mWidgetList.clear();
    81     delete mDocumentLoader;
    83     delete mDocumentLoader;
    82 
       
    83     delete mContentWidget;
    84     delete mContentWidget;
    84 
       
    85     delete mPrioritySubMenu;
    85     delete mPrioritySubMenu;
    86     delete mAttachContextMenu;
    86     
       
    87     if (mAttachmentListContextMenu) {
       
    88         mAttachmentListContextMenu->clearActions();
       
    89         delete mAttachmentListContextMenu;
       
    90     }
       
    91     delete mWaitDialog;
       
    92     delete mAttachmentPicker;    
    87 }
    93 }
    88 
    94 
    89 /*!
    95 /*!
    90     View layout loading from XML
    96     View layout loading from XML
    91 */
    97 */
   107         mScrollArea = qobject_cast<NmBaseViewScrollArea *>
   113         mScrollArea = qobject_cast<NmBaseViewScrollArea *>
   108             (mDocumentLoader->findObject(NMUI_EDITOR_SCROLL_AREA));
   114             (mDocumentLoader->findObject(NMUI_EDITOR_SCROLL_AREA));
   109         mScrollAreaContents = qobject_cast<HbWidget *>
   115         mScrollAreaContents = qobject_cast<HbWidget *>
   110              (mDocumentLoader->findObject(NMUI_EDITOR_SCROLL_AREA_CONTENTS));
   116              (mDocumentLoader->findObject(NMUI_EDITOR_SCROLL_AREA_CONTENTS));
   111 
   117 
   112         mContentWidget = new NmEditorContent(mScrollArea, this, mDocumentLoader);
   118         mContentWidget = new NmEditorContent(mScrollArea, this, mDocumentLoader, 
       
   119             mApplication.networkAccessManager());
   113         mEditWidget = mContentWidget->editor();
   120         mEditWidget = mContentWidget->editor();
   114         mHeaderWidget = mContentWidget->header();
   121         mHeaderWidget = mContentWidget->header();
   115 
   122 
   116         // Set default color for user - entered text if editor is in re/reAll/fw mode
   123         // Set default color for user - entered text if editor is in re/reAll/fw mode
   117         NmUiEditorStartMode mode = mStartParam->editorStartMode();
   124         NmUiEditorStartMode mode = mStartParam->editorStartMode();
   149 	
   156 	
   150     // Connect to observe orientation change events
   157     // Connect to observe orientation change events
   151     connect(mApplication.mainWindow(), SIGNAL(orientationChanged(Qt::Orientation)),
   158     connect(mApplication.mainWindow(), SIGNAL(orientationChanged(Qt::Orientation)),
   152             this, SLOT(orientationChanged(Qt::Orientation)));
   159             this, SLOT(orientationChanged(Qt::Orientation)));
   153     // Signal for handling the attachment list selection
   160     // Signal for handling the attachment list selection
   154     connect(mHeaderWidget, SIGNAL(attachmentRemoved(const NmId)),
   161     connect(mHeaderWidget, SIGNAL(attachmentLongPressed(NmId, QPointF)),
   155             this, SLOT(removeAttachment(const NmId)));
   162             this, SLOT(attachmentLongPressed(NmId, QPointF)));
   156 }
   163 }
   157 
   164 
   158 /*!
   165 /*!
   159     Reload view contents with new start parameters
   166     Reload view contents with new start parameters
   160     Typically when view is already open and external view activation occurs
   167     Typically when view is already open and external view activation occurs
   191 void NmEditorView::orientationChanged(Qt::Orientation orientation)
   198 void NmEditorView::orientationChanged(Qt::Orientation orientation)
   192 {
   199 {
   193     Q_UNUSED(orientation);
   200     Q_UNUSED(orientation);
   194     // Adjust content height
   201     // Adjust content height
   195     QTimer::singleShot(nmOrientationTimer, this, SLOT(adjustViewDimensions()));
   202     QTimer::singleShot(nmOrientationTimer, this, SLOT(adjustViewDimensions()));
       
   203     QTimer::singleShot(nmOrientationTimer, mHeaderWidget, SLOT(sendHeaderHeightChanged()));
   196 }
   204 }
   197 
   205 
   198 /*!
   206 /*!
   199     Set new dimensions after orientation change.
   207     Set new dimensions after orientation change.
   200 */
   208 */
   223     return mScrollAreaContents;
   231     return mScrollAreaContents;
   224 }
   232 }
   225 
   233 
   226 /*
   234 /*
   227    Query user if we want to exit the editor
   235    Query user if we want to exit the editor
   228  */
   236 */
   229 bool NmEditorView::okToExitView()
   237 bool NmEditorView::okToExitView()
   230 {
   238 {
   231     bool okToExit = true;
   239     bool okToExit = true;
   232 
   240 
   233     // show the query if the message has not been sent
   241     // show the query if the message has not been sent
   278     pressed back key and editor needs to delete the draft message. This is
   286     pressed back key and editor needs to delete the draft message. This is
   279     called when "auto-exiting" after a successful mail sending.
   287     called when "auto-exiting" after a successful mail sending.
   280 */
   288 */
   281 void NmEditorView::aboutToExitView()
   289 void NmEditorView::aboutToExitView()
   282 {
   290 {
       
   291     if (mStartParam && mStartParam->service() && mUiEngine.isSendingMessage()) {
       
   292         // The application was started as a service and is about to close.
       
   293         // A message is still being sent and in order to make sure that the
       
   294         // send operation is not cancelled, let us display a modal wait dialog.
       
   295 
       
   296         // When the send operation is completed, the dialog is automatically
       
   297         // closed.
       
   298         connect(&mUiEngine, SIGNAL(sendOperationCompleted()),
       
   299                 this, SLOT(handleSendOperationCompleted()));
       
   300 
       
   301         // Close and delete the previous wait dialog if one exists.
       
   302         if (mWaitDialog) {
       
   303             mWaitDialog->close();
       
   304             delete mWaitDialog;
       
   305         }
       
   306 
       
   307         // Construct and setup the wait dialog.
       
   308         mWaitDialog = new HbProgressDialog();
       
   309         mWaitDialog->setText(hbTrId("txt_mail_shareui_sending_please_wait"));
       
   310 
       
   311         if (!XQServiceUtil::isEmbedded()) {
       
   312             // Hide the application.
       
   313             XQServiceUtil::toBackground(true);
       
   314         }
       
   315 
       
   316         // Display the wait dialog.
       
   317         mWaitDialog->exec();
       
   318         delete mWaitDialog;
       
   319         mWaitDialog = NULL;
       
   320     }
       
   321 
   283     // These operations need to be stopped before message can be deleted
   322     // These operations need to be stopped before message can be deleted
   284     delete mAddAttachmentOperation;
   323     delete mAddAttachmentOperation;
       
   324     mAddAttachmentOperation = NULL;
   285     delete mRemoveAttachmentOperation;
   325     delete mRemoveAttachmentOperation;
       
   326     mRemoveAttachmentOperation = NULL;
   286 
   327 
   287     if (mMessage) { // this is NULL if sending is started
   328     if (mMessage) { // this is NULL if sending is started
   288         // Delete message from drafts
   329         // Delete message from drafts
   289         NmId mailboxId = mMessage->mailboxId();
   330         NmId mailboxId = mMessage->mailboxId();
   290         NmId folderId = mMessage->parentId();
   331         NmId folderId = mMessage->parentId();
   295 
   336 
   296 /*!
   337 /*!
   297     Find message data based on start parameters.  Method is called
   338     Find message data based on start parameters.  Method is called
   298     when editor is started. If message data is found it means that
   339     when editor is started. If message data is found it means that
   299     operation is forward or reply message.
   340     operation is forward or reply message.
   300  */
   341 */
   301 void NmEditorView::setMessageData()
   342 void NmEditorView::setMessageData()
   302 {
   343 {
   303     // Check the outbox.
   344     // Check the outbox.
   304     delete mCheckOutboxOperation;
   345     delete mCheckOutboxOperation;
   305 	mCheckOutboxOperation = NULL;
   346     mCheckOutboxOperation = NULL;
   306 	
   347 	
   307 	mCheckOutboxOperation = mUiEngine.checkOutbox(mStartParam->mailboxId());
   348     mCheckOutboxOperation = mUiEngine.checkOutbox(mStartParam->mailboxId());
   308     
   349     
   309     if (mCheckOutboxOperation) {
   350     if (mCheckOutboxOperation) {
   310         connect(mCheckOutboxOperation, SIGNAL(operationCompleted(int)),
   351         connect(mCheckOutboxOperation, SIGNAL(operationCompleted(int)),
   311                 this, SLOT(outboxChecked(int)));
   352                 this, SLOT(outboxChecked(int)));
   312     }
   353     }
   314         startMessageCreation( mStartParam->editorStartMode() );
   355         startMessageCreation( mStartParam->editorStartMode() );
   315     }
   356     }
   316 }
   357 }
   317 
   358 
   318 /*!
   359 /*!
   319  */
   360 */
   320 void NmEditorView::startMessageCreation(NmUiEditorStartMode startMode)
   361 void NmEditorView::startMessageCreation(NmUiEditorStartMode startMode)
   321 {
   362 {
   322     NmId mailboxId = mStartParam->mailboxId();
   363     NmId mailboxId = mStartParam->mailboxId();
   323     NmId folderId = mStartParam->folderId();
   364     NmId folderId = mStartParam->folderId();
   324     NmId msgId = mStartParam->messageId();
   365     NmId msgId = mStartParam->messageId();
   325     
   366     
   326     delete mMessageCreationOperation;
   367     delete mMessageCreationOperation;
   327 	mMessageCreationOperation = NULL;
   368     mMessageCreationOperation = NULL;
   328 	
   369 	
   329 	// original message is now fetched so start message creation
   370     // original message is now fetched so start message creation
   330     if (startMode == NmUiEditorForward) {
   371     if (startMode == NmUiEditorForward) {
   331         mMessageCreationOperation = mUiEngine.createForwardMessage(mailboxId, msgId);
   372         mMessageCreationOperation = mUiEngine.createForwardMessage(mailboxId, msgId);
   332     }
   373     }
   333     else if (startMode == NmUiEditorReply || startMode == NmUiEditorReplyAll) {
   374     else if (startMode == NmUiEditorReply || startMode == NmUiEditorReplyAll) {
   334         mMessageCreationOperation = mUiEngine.createReplyMessage(mailboxId, 
   375         mMessageCreationOperation = mUiEngine.createReplyMessage(mailboxId, 
   348     }    
   389     }    
   349 }
   390 }
   350 
   391 
   351 /*!
   392 /*!
   352     Starting the message sending is handled here.
   393     Starting the message sending is handled here.
   353  */
   394 */
   354 void NmEditorView::startSending()
   395 void NmEditorView::startSending()
   355 {
   396 {
   356     // The message contents should be verified
   397     // The message contents should be verified
   357     updateMessageWithEditorContents();
   398     updateMessageWithEditorContents();
   358     
   399     
   359     // verify addresses before sending
   400     // verify addresses before sending
   360     QList<NmAddress> invalidAddresses;
   401     QList<NmAddress> invalidAddresses;
   361     NmUtilities::getRecipientsFromMessage(*mMessage, invalidAddresses, NmUtilities::InvalidAddress);
   402     if (mMessage) {
       
   403         NmUtilities::getRecipientsFromMessage(*mMessage, invalidAddresses, NmUtilities::InvalidAddress);
       
   404     }
   362     
   405     
   363     bool okToSend = true;
   406     bool okToSend = true;
   364     if (invalidAddresses.count() > 0) {
   407     if (invalidAddresses.count() > 0) {
   365         
   408         
   366         // invalid addresses found, verify send from user
   409         // invalid addresses found, verify send from user
   375         HbAction *action = messageBox->exec();
   418         HbAction *action = messageBox->exec();
   376         okToSend = (action == messageBox->primaryAction());
   419         okToSend = (action == messageBox->primaryAction());
   377     }
   420     }
   378     
   421     
   379     if (okToSend) {
   422     if (okToSend) {
   380         // ownership of mMessage changes
   423         QList<NmOperation *> preliminaryOperations;
   381         mUiEngine.sendMessage(mMessage);
   424         preliminaryOperations.append(mAddAttachmentOperation);
       
   425         preliminaryOperations.append(mRemoveAttachmentOperation);
       
   426         // ownership of mMessage is transferred
       
   427         // ownerships of NmOperations in preliminaryOperations are transferred
       
   428         mUiEngine.sendMessage(mMessage, preliminaryOperations);
   382         mMessage = NULL;
   429         mMessage = NULL;
       
   430         mAddAttachmentOperation = NULL;
       
   431         mRemoveAttachmentOperation = NULL;
       
   432         preliminaryOperations.clear();
   383         // sending animation should be shown here, then exit
   433         // sending animation should be shown here, then exit
   384         QTimer::singleShot(1000, &mApplication, SLOT(popView()));
   434         QTimer::singleShot(1000, &mApplication, SLOT(popView()));
   385     }
   435     }
   386 }
   436 }
   387 
   437 
   388 /*!
   438 /*!
   389     This is signalled by mMessageCreationOperation when message is created.
   439     This is signalled by mMessageCreationOperation when message is created.
   390  */
   440 */
   391 void NmEditorView::messageCreated(int result)
   441 void NmEditorView::messageCreated(int result)
   392 {
   442 {
   393     delete mMessage;
   443     delete mMessage;
   394     mMessage = NULL;
   444     mMessage = NULL;
   395 
   445 
   406     }
   456     }
   407 }
   457 }
   408 
   458 
   409 /*!
   459 /*!
   410    Updates the message with the editor contents.
   460    Updates the message with the editor contents.
   411  */
   461 */
   412 void NmEditorView::updateMessageWithEditorContents()
   462 void NmEditorView::updateMessageWithEditorContents()
   413 {
   463 {
   414     if (mMessage) {
   464     if (mMessage) {
   415         if (mContentWidget && mContentWidget->editor()) {
   465         if (mContentWidget && mContentWidget->editor()) {
   416             NmMessagePart* bodyPart = mMessage->htmlBodyPart();
   466             NmMessagePart* bodyPart = mMessage->htmlBodyPart();
   459 
   509 
   460 
   510 
   461 /*!
   511 /*!
   462     Updates the message with the editor contents. Called only once when the
   512     Updates the message with the editor contents. Called only once when the
   463     editor is launched.
   513     editor is launched.
   464  */
   514 */
   465 void NmEditorView::fillEditorWithMessageContents()
   515 void NmEditorView::fillEditorWithMessageContents()
   466 {
   516 {
   467     if (!mMessage || !mContentWidget) {
   517     if (!mMessage || !mContentWidget) {
   468         return;
   518         return;
   469     }
   519     }
   569                                        mMessage->parentId(),
   619                                        mMessage->parentId(),
   570                                        mMessage->envelope().id(),
   620                                        mMessage->envelope().id(),
   571                                        *attachmentHtml);
   621                                        *attachmentHtml);
   572     }
   622     }
   573 
   623 
   574     mContentWidget->setMessageData(mMessage);
   624     // Set content data
       
   625     if (editorStartMode==NmUiEditorReply||
       
   626         editorStartMode==NmUiEditorReplyAll||
       
   627         editorStartMode==NmUiEditorForward){
       
   628         // Pass envelope ptr only when needed for reaply header creation
       
   629         NmMessage *originalMessage = mUiEngine.message(mStartParam->mailboxId(), 
       
   630                                                        mStartParam->folderId(), 
       
   631                                                        mStartParam->messageId());
       
   632         mContentWidget->setMessageData(*mMessage, &originalMessage->envelope()); 
       
   633         delete originalMessage;
       
   634     }
       
   635     else{
       
   636         // Reply header not needed, do not pass envelope ptr
       
   637         mContentWidget->setMessageData(*mMessage);     
       
   638     }
   575     
   639     
   576     // Get list of attachments from the message and set those into UI attachment list
   640     // Get list of attachments from the message and set those into UI attachment list
   577     QList<NmMessagePart*> attachments;
   641     QList<NmMessagePart*> attachments;
   578     mMessage->attachmentList(attachments);
   642     mMessage->attachmentList(attachments);
   579 
   643 
   618             // If action has NmSendable condition, it is shown only when send action
   682             // If action has NmSendable condition, it is shown only when send action
   619             // is available, i.e. when at least one recipient field has data.
   683             // is available, i.e. when at least one recipient field has data.
   620             if( list[i]->availabilityCondition() == NmAction::NmSendable ) {
   684             if( list[i]->availabilityCondition() == NmAction::NmSendable ) {
   621                 list[i]->setEnabled(false);
   685                 list[i]->setEnabled(false);
   622             }
   686             }
   623         }
   687             //object name set in NmBaseClientPlugin::createEditorViewCommands
       
   688             //temporary solution
       
   689             else if (list[i]->objectName() == "baseclientplugin_attachaction") {
       
   690                 HbToolBarExtension* extension = new HbToolBarExtension();
       
   691                 mAttachmentPicker = new NmAttachmentPicker(this);
       
   692                 
       
   693                 if (extension && mAttachmentPicker) {
       
   694                     connect(mAttachmentPicker, SIGNAL(attachmentsFetchOk(const QVariant &)),
       
   695                         this, SLOT(onAttachmentReqCompleted(const QVariant &)));            
       
   696                                                 
       
   697                     HbAction* actionPhoto = 
       
   698                         extension->addAction(hbTrId("txt_mail_list_photo"), extension, SLOT(close()));
       
   699                     connect(actionPhoto, SIGNAL(triggered()), mAttachmentPicker, SLOT(fetchImage()));
       
   700                     
       
   701                     HbAction* actionMusic = 
       
   702                         extension->addAction(hbTrId("txt_mail_list_music"), extension, SLOT(close()));
       
   703                     connect(actionMusic, SIGNAL(triggered()), mAttachmentPicker, SLOT(fetchAudio()));
       
   704                     
       
   705                     HbAction* actionVideo = 
       
   706                         extension->addAction(hbTrId("txt_mail_list_video"), extension, SLOT(close()));                
       
   707                     HbAction* actionOther = 
       
   708                         extension->addAction(hbTrId("txt_mail_list_other"), extension, SLOT(close()));
       
   709             
       
   710                     list[i]->setToolBarExtension(extension);
       
   711                 }
       
   712             }            
       
   713         }        
   624     }
   714     }
   625 }
   715 }
   626 
   716 
   627 /*!
   717 /*!
   628     createOptionsMenu. Functions asks menu commands from extension
   718     createOptionsMenu. Functions asks menu commands from extension
   661     if (actionResponse.menuType() == NmActionOptionsMenu) {
   751     if (actionResponse.menuType() == NmActionOptionsMenu) {
   662         setPriority(responseCommand);
   752         setPriority(responseCommand);
   663     }
   753     }
   664     else if (actionResponse.menuType() == NmActionToolbar) {
   754     else if (actionResponse.menuType() == NmActionToolbar) {
   665         switch (responseCommand) {
   755         switch (responseCommand) {
   666             case NmActionResponseCommandSendMail: {
   756         case NmActionResponseCommandSendMail: {
       
   757             // Just in case send mail would be somehow accessible during message creation or
       
   758             // outobox checking
       
   759             if (!mCheckOutboxOperation->isRunning()
       
   760                 && (!mMessageCreationOperation || !mMessageCreationOperation->isRunning())) {
   667                 startSending();
   761                 startSending();
   668                 break;
   762             }
   669             }
   763             break;
   670             case NmActionResponseCommandAttach : {
   764         }
   671                 // Do nothing if previous addAttachment operation is still ongoing.
   765         default:
   672                 if(!mAddAttachmentOperation || !mAddAttachmentOperation->isRunning()) {
   766             break;
   673                     //will be replaced by toolbar extension                                
   767         }
   674                     if (!mAttachContextMenu) {
   768     }
   675                         QList<NmAction *> actionList;
   769     else if (actionResponse.menuType() == NmActionContextMenu) {
   676                         NmAction* actionPhoto = new NmAction(0);
   770         switch (responseCommand) {
   677                         actionPhoto->setText(QObject::tr("Photo", "txt_nmailui_photo_attach"));
   771         case NmActionResponseCommandRemoveAttachment: {
   678                         actionList.append(actionPhoto);
   772             removeAttachmentTriggered();
   679                         connect(actionPhoto, SIGNAL(triggered()), this, SLOT(attachImage()));
   773             break;
   680                                 
   774         }
   681                         mAttachContextMenu = new HbMenu();
   775         case NmActionResponseCommandOpenAttachment: {
   682                         mAttachContextMenu->clearActions();
   776             openAttachmentTriggered();
   683 
   777             break;
   684                         for (int i=0;i<actionList.count();i++) {
   778         }
   685                             mAttachContextMenu->addAction(actionList[i]);
   779         default:
   686                         }
   780         	break;
   687                     }
       
   688                 
       
   689                     QPointF menuPos(qreal(20),qreal(520));
       
   690                     mAttachContextMenu->exec(menuPos);
       
   691                 }
       
   692                 break;
       
   693             }
       
   694             default:
       
   695                 break;
       
   696         }
   781         }
   697     }
   782     }
   698 }
   783 }
   699 
   784 
   700 /*!
   785 /*!
   701     This function converts background scroll area coordinate point into
   786     This function converts background scroll area coordinate point into
   702     body text editor coordinate point.
   787     body text editor coordinate point.
   703  */
   788 */
   704 QPointF NmEditorView::viewCoordinateToEditCoordinate(QPointF orgPoint)
   789 QPointF NmEditorView::viewCoordinateToEditCoordinate(QPointF orgPoint)
   705 {
   790 {
   706     QPointF contentWidgetPos = mScrollAreaContents->pos();
   791     QPointF contentWidgetPos = mScrollAreaContents->pos();
   707     qreal y = orgPoint.y() - mHeaderWidget->headerHeight();
   792     qreal y = orgPoint.y() - mHeaderWidget->headerHeight();
   708     y -= contentWidgetPos.y();
   793     y -= contentWidgetPos.y();
   843 }
   928 }
   844 
   929 
   845 /*!
   930 /*!
   846    Adds a prefix to the subject for reply or forward. 
   931    Adds a prefix to the subject for reply or forward. 
   847    Strips other occurrences of the prefix from the beginning.
   932    Strips other occurrences of the prefix from the beginning.
   848  */
   933 */
   849 QString NmEditorView::addSubjectPrefix( NmUiEditorStartMode startMode, const QString &subject )
   934 QString NmEditorView::addSubjectPrefix( NmUiEditorStartMode startMode, const QString &subject )
   850 {
   935 {
   851     QString newSubject(subject.trimmed());
   936     QString newSubject(subject.trimmed());
   852     
   937     
   853     if (startMode == NmUiEditorReply || startMode == NmUiEditorReplyAll || 
   938     if (startMode == NmUiEditorReply || startMode == NmUiEditorReplyAll || 
   884     }
   969     }
   885     
   970     
   886     return newSubject;
   971     return newSubject;
   887 }
   972 }
   888 
   973 
   889 #ifdef Q_OS_SYMBIAN
       
   890 
       
   891 void NmEditorView::attachImage()
       
   892 {      
       
   893     XQAiwRequest *request;
       
   894     XQApplicationManager mAppmgr;
       
   895     request = mAppmgr.create(IMAGE_FETCHER_INTERFACE, FETCHER_OPERATION, true);
       
   896         
       
   897     if (request) {
       
   898         connect(request, SIGNAL(requestOk(const QVariant&)), this, SLOT(onAttachmentReqCompleted(const QVariant&)));
       
   899     }
       
   900     else {
       
   901         //create request failed
       
   902         NMLOG("appmgr: create request failed");
       
   903         return;
       
   904     }               
       
   905 
       
   906     if (!(request)->send()) {
       
   907         //sending request failed
       
   908         NMLOG("appmgr: send request failed");
       
   909     }
       
   910     delete request;
       
   911 }
       
   912 
   974 
   913 /*!
   975 /*!
   914     This slot is called when 'attachment picker' request has been performed succesfully
   976     This slot is called when 'attachment picker' request has been performed succesfully
   915     Parameter 'value' contains file currently one file name but later list of the files. 
   977     Parameter 'value' contains file currently one file name but later list of the files. 
   916 */
   978 */
   919     if (!value.isNull()) {
   981     if (!value.isNull()) {
   920         addAttachments(value.toStringList());
   982         addAttachments(value.toStringList());
   921     }
   983     }
   922 }
   984 }
   923 
   985 
   924 #endif
   986 
       
   987 /*!
       
   988     Closes the wait dialog if one exists.
       
   989     
       
   990     This slot is called if the mail application has been started as a service
       
   991     and is about to close. Closing the application while still sending a message
       
   992     may cause unwanted cancelling of the operation.
       
   993 */
       
   994 void NmEditorView::handleSendOperationCompleted()
       
   995 {
       
   996     if (mWaitDialog) {
       
   997         mWaitDialog->close();
       
   998     }
       
   999 }
       
  1000 
   925 
  1001 
   926 /*!
  1002 /*!
   927     Add list of attachments
  1003     Add list of attachments
   928 */
  1004 */
   929 void NmEditorView::addAttachments(const QStringList& fileNames) 
  1005 void NmEditorView::addAttachments(const QStringList& fileNames) 
   935         // At this phase attachment size and nmid are not known
  1011         // At this phase attachment size and nmid are not known
   936         mHeaderWidget->addAttachment(fileName, QString("0"), NmId(0));
  1012         mHeaderWidget->addAttachment(fileName, QString("0"), NmId(0));
   937         NMLOG(fileName);
  1013         NMLOG(fileName);
   938     }
  1014     }
   939 
  1015 
   940     // Start operation to attach file or list of files into mail message
  1016     // Delete previous operation if it's not running.
   941     // This will also copy files into message store
       
   942     // Delete previous operation
       
   943     if (mAddAttachmentOperation) {
  1017     if (mAddAttachmentOperation) {
   944         if (!mAddAttachmentOperation->isRunning()) {
  1018         if (!mAddAttachmentOperation->isRunning()) {
   945             delete mAddAttachmentOperation;
  1019             delete mAddAttachmentOperation;
   946             mAddAttachmentOperation = NULL;
  1020             mAddAttachmentOperation = NULL;
   947         }
  1021         }
   948     }
  1022     }
   949     if (!mAddAttachmentOperation) {
  1023     if (!mAddAttachmentOperation) {
       
  1024         // Start operation to attach file or list of files into mail message.
       
  1025         // This will also copy files into message store.
   950         mAddAttachmentOperation = mUiEngine.addAttachments(*mMessage, fileNames);
  1026         mAddAttachmentOperation = mUiEngine.addAttachments(*mMessage, fileNames);
   951 
  1027 
   952         if (mAddAttachmentOperation) {
  1028         if (mAddAttachmentOperation) {
       
  1029             enableToolBarAttach(false);
   953             // Signal to inform completion of one attachment
  1030             // Signal to inform completion of one attachment
   954             connect(mAddAttachmentOperation,
  1031             connect(mAddAttachmentOperation,
   955                     SIGNAL(operationPartCompleted(const QString &, const NmId &, int)),
  1032                     SIGNAL(operationPartCompleted(const QString &, const NmId &, int)),
   956                     this,
  1033                     this,
   957                     SLOT(oneAttachmentAdded(const QString &, const NmId &, int)));
  1034                     SLOT(oneAttachmentAdded(const QString &, const NmId &, int)));
   964         }
  1041         }
   965     }
  1042     }
   966 }
  1043 }
   967 
  1044 
   968 /*!
  1045 /*!
   969     This slot is called when attachment has been deleted from UI
  1046     This slot is called to create context menu when attachment has been selected
   970 */
  1047     from UI by longpress.
   971 void NmEditorView::removeAttachment(const NmId attachmentPartId)
  1048 */
   972 {
  1049 void NmEditorView::attachmentLongPressed(NmId attachmentPartId, QPointF point)
   973     // Delete previous operation
  1050 {
   974     if (mRemoveAttachmentOperation) {
  1051     // Store id of the attachment to be removed into member.
   975         if (!mRemoveAttachmentOperation->isRunning()) {
  1052     // It is used by removeAttachmentTriggered later if 'remove' selected.
   976             delete mRemoveAttachmentOperation;
  1053     mSelectedAttachment = attachmentPartId;
   977             mRemoveAttachmentOperation = NULL;
  1054 	
   978         }
  1055     if (!mAttachmentListContextMenu) {
   979     }
  1056         mAttachmentListContextMenu = new HbMenu();
   980     if (!mRemoveAttachmentOperation) {
  1057     }
   981         mRemoveAttachmentOperation = mUiEngine.removeAttachment(*mMessage, attachmentPartId);
  1058     mAttachmentListContextMenu->clearActions();
   982     }
  1059     NmActionRequest request(this, NmActionContextMenu, NmActionContextViewEditor,
       
  1060         NmActionContextDataMessage, mStartParam->mailboxId(), mStartParam->folderId(),
       
  1061         mStartParam->messageId());
       
  1062     NmUiExtensionManager &extensionManager = mApplication.extManager();
       
  1063     if (&extensionManager) {
       
  1064         QList<NmAction*> actionList;
       
  1065         extensionManager.getActions(request, actionList);
       
  1066         for (int i = 0; i < actionList.count(); ++i) {
       
  1067             mAttachmentListContextMenu->addAction(actionList[i]);
       
  1068         }
       
  1069     }
       
  1070 
       
  1071     // Add menu position check here, so that it does not go outside of the screen
       
  1072     QPointF menuPos(point.x(),point.y());
       
  1073     mAttachmentListContextMenu->exec(menuPos);
   983 }
  1074 }
   984 
  1075 
   985 /*!
  1076 /*!
   986     This is signalled by mAddAttachmentOperation when the operation is
  1077     This is signalled by mAddAttachmentOperation when the operation is
   987     completed for one attachment.
  1078     completed for one attachment.
   988  */
  1079 */
   989 void NmEditorView::oneAttachmentAdded(const QString &fileName, const NmId &msgPartId, int result)
  1080 void NmEditorView::oneAttachmentAdded(const QString &fileName, const NmId &msgPartId, int result)
   990 {
  1081 {
   991     if (result == NmNoError) {
  1082     if (result == NmNoError && mMessage) {
   992         // Get file size from the message when it works
  1083         // Need to get the message again because new attachment part has been added.
   993         mHeaderWidget->setAttachmentParameters(fileName, msgPartId, QString("0"), result);
  1084         NmId mailboxId = mMessage->mailboxId();
       
  1085         NmId folderId = mMessage->parentId();
       
  1086         NmId msgId = mMessage->envelope().id();
       
  1087 
       
  1088         delete mMessage;
       
  1089         mMessage = NULL;
       
  1090         
       
  1091         mMessage = mUiEngine.message(mailboxId, folderId, msgId);
       
  1092 
       
  1093         if (mMessage) {
       
  1094             // Get attachment list from the message
       
  1095             QList<NmMessagePart*> attachmentList;
       
  1096             mMessage->attachmentList(attachmentList);
       
  1097         
       
  1098             // Search newly added attachment from the list
       
  1099             for (int i=0; i<attachmentList.count(); i++) {
       
  1100                 if (attachmentList[i]->id() == msgPartId) {
       
  1101                     // Get attachment file size and set it into UI
       
  1102                     mHeaderWidget->setAttachmentParameters(fileName,
       
  1103                         msgPartId,
       
  1104                         QString().setNum(attachmentList[i]->size()),
       
  1105                         result);
       
  1106                 }
       
  1107             }
       
  1108         }
   994     }
  1109     }
   995     else {
  1110     else {
   996         // Attachment adding failed. Show an error note and remove from UI attachment list.
  1111         // Attachment adding failed. Show an error note and remove from UI attachment list.
   997         NMLOG(QString("nmailui: attachment adding into message failed: %1").arg(fileName));
  1112         NMLOG(QString("nmailui: attachment adding into message failed: %1").arg(fileName));
   998         mHeaderWidget->removeAttachment(fileName);
  1113         mHeaderWidget->removeAttachment(fileName);
  1000 }
  1115 }
  1001 
  1116 
  1002 /*!
  1117 /*!
  1003     This is signalled by mAddAttachmentOperation when the operation is
  1118     This is signalled by mAddAttachmentOperation when the operation is
  1004     completed totally.
  1119     completed totally.
  1005  */
  1120 */
  1006 void NmEditorView::allAttachmentsAdded(int result)
  1121 void NmEditorView::allAttachmentsAdded(int result)
  1007 {
  1122 {
       
  1123     enableToolBarAttach(true);
  1008     if (result != NmNoError) {
  1124     if (result != NmNoError) {
  1009         HbMessageBox::warning(hbTrId("txt_mail_dialog_unable_to_add_attachment"));
  1125         HbMessageBox::warning(hbTrId("txt_mail_dialog_unable_to_add_attachment"));
  1010     }
  1126     }
  1011 }
  1127 }
  1012 
  1128 
  1013 /*!
  1129 /*!
  1014     This is signalled by mCheckOutboxOperation when the operation is complete.
  1130     This is signalled by mCheckOutboxOperation when the operation is complete.
  1015  */
  1131 */
  1016 void NmEditorView::outboxChecked(int result)
  1132 void NmEditorView::outboxChecked(int result)
  1017 {
  1133 {
  1018     bool messageInOutbox = false;
  1134     bool messageInOutbox = false;
  1019     
  1135     
  1020     if (result == NmNoError && mCheckOutboxOperation) {
  1136     if (result == NmNoError && mCheckOutboxOperation) {
  1118     }
  1234     }
  1119 
  1235 
  1120     return addressesString;
  1236     return addressesString;
  1121 }
  1237 }
  1122 
  1238 
       
  1239 /*!
       
  1240     This slot is called when 'remove' is selected from attachment list context menu.
       
  1241 */
       
  1242 void NmEditorView::removeAttachmentTriggered()
       
  1243 {
       
  1244     // Delete previous operation
       
  1245     if (mRemoveAttachmentOperation) {
       
  1246         if (!mRemoveAttachmentOperation->isRunning()) {
       
  1247             delete mRemoveAttachmentOperation;
       
  1248             mRemoveAttachmentOperation = NULL;
       
  1249         }
       
  1250     }
       
  1251     if (!mRemoveAttachmentOperation) {
       
  1252         // Remove from UI
       
  1253         mHeaderWidget->removeAttachment(mSelectedAttachment);
       
  1254         // Remove from message store
       
  1255         mRemoveAttachmentOperation = mUiEngine.removeAttachment(*mMessage, mSelectedAttachment);
       
  1256         if (mRemoveAttachmentOperation) {
       
  1257             // Signal to inform the remove operation completion
       
  1258             connect(mRemoveAttachmentOperation,
       
  1259                     SIGNAL(operationCompleted(int)),
       
  1260                     this,
       
  1261                     SLOT(attachmentRemoved(int)));
       
  1262         }
       
  1263     }
       
  1264 }
       
  1265 
       
  1266 /*!
       
  1267     This slot is called by mRemoveAttachmentOperation when the operation is
       
  1268     completed. There is no need to update UI because it was already updated.
       
  1269  */
       
  1270 void NmEditorView::attachmentRemoved(int result)
       
  1271 {
       
  1272     // It is not desided yet what to do if operation fails
       
  1273     Q_UNUSED(result);
       
  1274     
       
  1275     if (mMessage) {
       
  1276         // Reload message because one attachment has been removed
       
  1277         NmId mailboxId = mMessage->mailboxId();
       
  1278         NmId folderId = mMessage->parentId();
       
  1279         NmId msgId = mMessage->envelope().id();
       
  1280 
       
  1281         delete mMessage;
       
  1282         mMessage = NULL;
       
  1283     
       
  1284         mMessage = mUiEngine.message(mailboxId, folderId, msgId);
       
  1285     }
       
  1286 }
       
  1287 
       
  1288 /*!
       
  1289     This slot is called when 'open' is selected from attachment list context menu.
       
  1290 */
       
  1291 void NmEditorView::openAttachmentTriggered()
       
  1292 {
       
  1293     mHeaderWidget->launchAttachment(mSelectedAttachment);
       
  1294 }
       
  1295 
       
  1296 /*!
       
  1297    Enables/disables toolbar extension for attach
       
  1298 */
       
  1299 void NmEditorView::enableToolBarAttach(bool enable)
       
  1300 {
       
  1301     HbToolBar *tb = toolBar();
       
  1302     if (tb) {
       
  1303         QList<QAction *> toolbarList = tb->actions();
       
  1304         int count = toolbarList.count();
       
  1305         for (int i = 0; i < count; i++) {
       
  1306             NmAction *action = static_cast<NmAction *>(toolbarList[i]);
       
  1307             //object name set in NmBaseClientPlugin::createEditorViewCommands
       
  1308             //temporary solution
       
  1309             if (action->objectName() == "baseclientplugin_attachaction") {
       
  1310                 action->setEnabled(enable);
       
  1311             }
       
  1312         }
       
  1313     }
       
  1314 }
       
  1315 
  1123 
  1316 
  1124 // End of file.
  1317 // End of file.