messagingapp/msgui/conversationview/src/msgconversationview.cpp
branchRCL_3
changeset 57 ebe688cedc25
equal deleted inserted replaced
54:fa1df4b99609 57:ebe688cedc25
       
     1 /*
       
     2  * Copyright (c) 2009 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:Conversation (chat) view for messaging application.
       
    15  *
       
    16  */
       
    17 
       
    18 #include "msgconversationview.h"
       
    19 
       
    20 // SYSTEM INCLUDES
       
    21 #include <HbMenu>
       
    22 #include <HbAction>
       
    23 #include <HbListView>
       
    24 #include <HbMessageBox>
       
    25 #include <HbNotificationDialog>
       
    26 #include <HbFrameBackground>
       
    27 #include <xqservicerequest.h>
       
    28 #include <HbStaticVkbHost>
       
    29 #include <HbStyleLoader>
       
    30 #include <xqaiwrequest.h>
       
    31 #include <xqappmgr.h>
       
    32 #include <HbMainWindow>
       
    33 
       
    34 #include <QDir>
       
    35 #include <QDateTime>
       
    36 #include <QGraphicsLinearLayout>
       
    37 #include <QStandardItemModel>
       
    38 
       
    39 #include <cntservicescontact.h>
       
    40 #include <ccsdefs.h>
       
    41 #include <centralrepository.h>
       
    42 #include <MmsEngineDomainCRKeys.h>
       
    43 
       
    44 // USER INCLUDES
       
    45 #include "msgcontactsutil.h"
       
    46 #include "msgsendutil.h"
       
    47 #include "msgconversationviewitem.h"
       
    48 #include "conversationsengine.h"
       
    49 #include "convergedmessageid.h"
       
    50 #include "conversationsenginedefines.h"
       
    51 #include "msgcontactcardwidget.h"
       
    52 #include "msgeditorwidget.h"
       
    53 #include "msgviewdefines.h"
       
    54 #include "debugtraces.h"
       
    55 #include "unidatamodelloader.h"
       
    56 #include "unidatamodelplugininterface.h"
       
    57 #include "ringbc.h"
       
    58 #include "mmsconformancecheck.h"
       
    59 #include "msgsettingsview.h"
       
    60 #include "msgaudiofetcherview.h"
       
    61 #include "unieditorpluginloader.h"
       
    62 #include "unieditorplugininterface.h"
       
    63 
       
    64 //Item specific menu.
       
    65 
       
    66 #define LOC_COMMON_OPEN hbTrId("txt_common_menu_open")
       
    67 #define LOC_COMMON_DELETE hbTrId("txt_common_menu_delete")
       
    68 #define LOC_COMMON_FORWARD hbTrId("txt_common_menu_forward")
       
    69 #define LOC_COMMON_DOWNLOAD hbTrId("txt_messaging_menu_download")
       
    70 #define LOC_COMMON_SEND  hbTrId("txt_common_button_send") 
       
    71 #define LOC_COMMON_SAVE  hbTrId("txt_common_menu_save")
       
    72 
       
    73 #define LOC_DELETE_MESSAGE hbTrId("txt_messaging_dialog_delete_message")
       
    74 #define LOC_DELETE_SHARED_MESSAGE hbTrId("txt_messaging_dialog_same_message_exists_in_multip")
       
    75 #define LOC_SAVE_TO_CONTACTS hbTrId("txt_messaging_menu_save_to_contacts")
       
    76 
       
    77 //main menu
       
    78 #define LOC_ATTACH          hbTrId("txt_messaging_opt_attach")
       
    79 #define LOC_PHOTO           hbTrId("txt_messaging_opt_attach_sub_photo")
       
    80 #define LOC_SOUND           hbTrId("txt_messaging_opt_attach_sub_sound")
       
    81 #define LOC_VCARD           hbTrId("txt_messaging_list_business_card")
       
    82 #define LOC_ADD_RECIPIENTS  hbTrId("txt_messaging_opt_add_recipients")
       
    83 #define LOC_ADD_SUBJECT     hbTrId("txt_messaging_opt_add_subject")
       
    84 
       
    85 #define LOC_MSG_SEND_FAILED hbTrId("txt_messaging_dialog_message_sending_failed")
       
    86 #define LOC_DIALOG_SMS_SETTINGS_INCOMPLETE hbTrId("txt_messaging_dialog_sms_message_centre_does_not_e")
       
    87 #define LOC_DIALOG_SAVE_RINGTONE hbTrId("txt_conversations_dialog_save_ringing_tone")
       
    88 #define LOC_MMS_RETRIEVAL_FAILED hbTrId("txt_messaging_dialog_mms_retrieval_failed")
       
    89 
       
    90 
       
    91 const int INVALID_MSGID = -1;
       
    92 const int INVALID_CONVID = -1;
       
    93 const int CONTACT_INSERTION_MODE = 1;
       
    94 const int VCARD_INSERTION_MODE = 0;
       
    95 
       
    96 //---------------------------------------------------------------
       
    97 // MsgConversationView::MsgConversationView
       
    98 // @see header file
       
    99 //---------------------------------------------------------------
       
   100 MsgConversationView::MsgConversationView(MsgContactCardWidget *contactCardWidget,
       
   101     QGraphicsItem *parent) :
       
   102     MsgBaseView(parent),
       
   103     mConversationList(NULL),
       
   104     mMessageModel(NULL),
       
   105     mEditorWidget(NULL),
       
   106     mContactCardWidget(contactCardWidget),
       
   107     mSendUtil(NULL),
       
   108     mVkbHost(NULL),
       
   109     mVisibleIndex(),
       
   110     mModelPopulated(false),
       
   111     mViewReady(false)
       
   112 {
       
   113     //create send utils
       
   114     mSendUtil = new MsgSendUtil(this);
       
   115     //initialize view
       
   116     setupView();
       
   117     setupMenu();
       
   118     
       
   119     connect(ConversationsEngine::instance(), 
       
   120                      SIGNAL(conversationModelUpdated()),
       
   121                      this, 
       
   122                      SLOT(scrollToBottom()));
       
   123 
       
   124     connect(ConversationsEngine::instance(), 
       
   125                          SIGNAL(conversationViewEmpty()),
       
   126                          this, 
       
   127                          SLOT(onConversationViewEmpty()));
       
   128 }
       
   129 
       
   130 //---------------------------------------------------------------
       
   131 // MsgConversationView::~MsgConversationView
       
   132 // @see header file
       
   133 //---------------------------------------------------------------
       
   134 MsgConversationView::~MsgConversationView()
       
   135 {
       
   136     
       
   137 }
       
   138 //---------------------------------------------------------------
       
   139 // MsgConversationView::setupView
       
   140 // @see header file
       
   141 //---------------------------------------------------------------
       
   142 void MsgConversationView::setupView()
       
   143 {
       
   144     // Create HbListView and set properties
       
   145     mConversationList = new HbListView();
       
   146     if (!HbStyleLoader::registerFilePath(":/layouts")) {
       
   147         QDEBUG_WRITE("ERROR: ConversationView -> HbStyleLoader::registerFilePath");
       
   148     }
       
   149     mConversationList->setLayoutName("custom");
       
   150     mConversationList->setItemRecycling(true);
       
   151     MsgConversationViewItem *item = new MsgConversationViewItem(this);
       
   152     HbFrameBackground defaultBackground;
       
   153     defaultBackground.setFrameGraphicsName(QString(""));
       
   154     item->setDefaultFrame(defaultBackground);
       
   155     mConversationList->setItemPrototype(item);
       
   156     mConversationList->setSelectionMode(HbListView::NoSelection);
       
   157     mConversationList->setClampingStyle(HbScrollArea::BounceBackClamping);
       
   158     mConversationList->setScrollingStyle(HbScrollArea::PanOrFlick);
       
   159 
       
   160     mMessageModel = ConversationsEngine::instance()->getConversationsModel();
       
   161     
       
   162     connect(ConversationsEngine::instance(), 
       
   163             SIGNAL(conversationModelPopulated()), 
       
   164             this, 
       
   165             SLOT(populateConversationsView()));
       
   166     
       
   167     connect(mConversationList, SIGNAL(activated(QModelIndex)),
       
   168             this, SLOT(openItem(QModelIndex)));
       
   169     connect(this->mainWindow(), SIGNAL(aboutToChangeOrientation()),
       
   170                 this, SLOT(onOrientationAboutToBeChanged()));
       
   171     
       
   172     connect(this->mainWindow(), SIGNAL(orientationChanged(Qt::Orientation)),
       
   173                     this, SLOT(onOrientationChanged(Qt::Orientation)));
       
   174 
       
   175     // Long tap list item
       
   176     connect(mConversationList, SIGNAL(longPressed(HbAbstractViewItem*, QPointF)),
       
   177             this, SLOT(longPressed(HbAbstractViewItem*, QPointF)));
       
   178 
       
   179     // Create message editor widget, will be displayed based on msg type.
       
   180     mEditorWidget = new MsgEditorWidget(this);
       
   181     mEditorWidget->hide();
       
   182 
       
   183     connect(mEditorWidget, SIGNAL(sendMessage()), this, SLOT(send()));
       
   184     connect(mEditorWidget, SIGNAL(smsCharLimitReached()), 
       
   185         this, SLOT(handleSmsCharLimitReached()));
       
   186     connect(mEditorWidget, SIGNAL(replyStarted()), this, SIGNAL(replyStarted()));
       
   187 
       
   188     qreal spacing = HbDeviceProfile::profile(mConversationList).unitValue();
       
   189     
       
   190     mMainLayout = new QGraphicsLinearLayout(Qt::Vertical,this); 
       
   191     
       
   192     mMainLayout->setContentsMargins(CONTENT_MARGIN, CONTENT_MARGIN,
       
   193                                     CONTENT_MARGIN, CONTENT_MARGIN);   
       
   194     mMainLayout->setSpacing(spacing);
       
   195 
       
   196     mMainLayout->addItem(mConversationList);
       
   197 
       
   198     setLayout(mMainLayout);
       
   199 
       
   200     //Create VKB instance and listen to VKB open and close signals for resizing the view.
       
   201     mVkbHost = new HbStaticVkbHost(this);
       
   202 	connect(mVkbHost, SIGNAL(keypadOpened()), this, SLOT(vkbOpened()));
       
   203 	connect(mVkbHost, SIGNAL(keypadClosed()), this, SLOT(vkbClosed()));
       
   204 
       
   205     // Refresh view to show the header details
       
   206     refreshView();
       
   207 }
       
   208 
       
   209 //---------------------------------------------------------------
       
   210 // MsgConversationView::addMenu
       
   211 // @see header file
       
   212 //---------------------------------------------------------------
       
   213 void MsgConversationView::setupMenu()
       
   214 {
       
   215     // Just create dummy menu.
       
   216     // Actual menu will be created in menuAboutToShow()
       
   217     HbMenu *mainMenu = this->menu();
       
   218     HbAction* clearConversation = mainMenu->addAction(QString());
       
   219     connect(mainMenu, SIGNAL(aboutToShow()), this, SLOT(menuAboutToShow()));
       
   220 }
       
   221 
       
   222 //---------------------------------------------------------------
       
   223 // MsgConversationView::fetchMoreConversations
       
   224 // @see header file
       
   225 //---------------------------------------------------------------
       
   226 void MsgConversationView::fetchMoreConversations()
       
   227 {
       
   228     if (mViewReady && mModelPopulated) {
       
   229         ConversationsEngine::instance()->fetchMoreConversations();
       
   230         mViewReady = mModelPopulated = false;
       
   231     }
       
   232 }
       
   233 
       
   234 //---------------------------------------------------------------
       
   235 // MsgConversationView::refreshView()
       
   236 // @see header file
       
   237 //---------------------------------------------------------------
       
   238 void MsgConversationView::refreshView()
       
   239 {
       
   240     // Hide editor in case of BT conversations.
       
   241     qint64 convId = ConversationsEngine::instance()->getCurrentConversationId();
       
   242     if (INVALID_CONVID != convId) {
       
   243         if (KBluetoothMsgsConversationId == convId) {
       
   244             mMainLayout->removeItem(mEditorWidget);
       
   245             mEditorWidget->hide();
       
   246             mEditorWidget->setParent(this);
       
   247         }
       
   248         else {
       
   249             mMainLayout->addItem(mEditorWidget);
       
   250             TRAP_IGNORE(mEditorWidget->setEncodingSettingsL());
       
   251             mEditorWidget->show();
       
   252         }
       
   253         mContactCardWidget->updateContents();
       
   254     }
       
   255 }
       
   256 
       
   257 //---------------------------------------------------------------
       
   258 // MsgConversationView::scrollToBottom()
       
   259 // @see header file
       
   260 //---------------------------------------------------------------
       
   261 void MsgConversationView::scrollToBottom()
       
   262 {
       
   263     const int rowCnt = mMessageModel->rowCount();
       
   264     mConversationList->scrollTo(
       
   265             mMessageModel->index(rowCnt - 1, 0));
       
   266 }
       
   267 
       
   268 void MsgConversationView::onConversationViewEmpty()
       
   269 {
       
   270     QVariantList param;
       
   271     param << MsgBaseView::CLV; // target view
       
   272     param << MsgBaseView::CV; // source view
       
   273     emit switchView(param);
       
   274 }
       
   275 
       
   276 //---------------------------------------------------------------
       
   277 // MsgConversationView::longPressed
       
   278 // @see header file
       
   279 //---------------------------------------------------------------
       
   280 void MsgConversationView::longPressed(HbAbstractViewItem* viewItem, const QPointF& point)
       
   281 { 
       
   282     showContextMenu(viewItem,point,HbPopup::TopLeftCorner);
       
   283 }
       
   284 
       
   285 //---------------------------------------------------------------
       
   286 // MsgConversationView::setContextMenu
       
   287 // @see header
       
   288 //---------------------------------------------------------------
       
   289 void MsgConversationView::setContextMenu(MsgConversationViewItem* item, HbMenu* contextMenu, int sendingState)
       
   290 {
       
   291     addOpenItemToContextMenu(item , contextMenu,sendingState);
       
   292     addResendItemToContextMenu(item, contextMenu, sendingState);
       
   293     addForwardItemToContextMenu(item, contextMenu, sendingState);
       
   294     addDownloadItemToContextMenu(item, contextMenu);
       
   295     addSaveItemToContextMenu(item , contextMenu,sendingState);
       
   296     addDeleteItemToContextMenu(item, contextMenu, sendingState);
       
   297 }
       
   298 
       
   299 
       
   300 //---------------------------------------------------------------
       
   301 // MsgEditorPrivate::addSaveItemToContextMenu
       
   302 // @see header
       
   303 //---------------------------------------------------------------
       
   304 void MsgConversationView::addSaveItemToContextMenu(MsgConversationViewItem* item,
       
   305     HbMenu* contextMenu, int sendingState)
       
   306 {
       
   307     Q_UNUSED(sendingState)
       
   308 
       
   309     int messageSubType = item->modelIndex().data(MessageSubType).toInt();
       
   310     int direction =  item->modelIndex().data(Direction).toInt();
       
   311     if ((messageSubType == ConvergedMessage::RingingTone) && 
       
   312         (direction == ConvergedMessage::Incoming)) {
       
   313         HbAction *contextItem = contextMenu->addAction(LOC_COMMON_SAVE);
       
   314         connect(contextItem, SIGNAL(triggered()), this, SLOT(saveRingingTone()));
       
   315     }
       
   316 }
       
   317 
       
   318 //---------------------------------------------------------------
       
   319 // MsgEditorPrivate::addOpenItemToContextMenu
       
   320 // @see header
       
   321 //---------------------------------------------------------------
       
   322 
       
   323 void MsgConversationView::addOpenItemToContextMenu(MsgConversationViewItem* item, HbMenu* contextMenu, int sendingState)
       
   324 {
       
   325     int direction = item->modelIndex().data(Direction).toInt();
       
   326     int messageType = item->modelIndex().data(MessageType).toInt();
       
   327     int messageSubType = item->modelIndex().data(MessageSubType).toInt();
       
   328     
       
   329     if((messageSubType == ConvergedMessage::VCal) ||
       
   330         (messageSubType == ConvergedMessage::RingingTone) ||
       
   331         (messageType == ConvergedMessage::MmsNotification))
       
   332         {
       
   333         return;
       
   334         }
       
   335     if ((messageSubType == ConvergedMessage::VCard) &&
       
   336         (direction == ConvergedMessage::Incoming))
       
   337         {
       
   338         HbAction *contextItem = contextMenu->addAction(LOC_SAVE_TO_CONTACTS);
       
   339         connect(contextItem, SIGNAL(triggered()),this, SLOT(saveVCard()));
       
   340         return;
       
   341         }
       
   342     if( (sendingState == ConvergedMessage::SentState &&
       
   343          messageSubType != ConvergedMessage::VCard) ||
       
   344         (direction == ConvergedMessage::Incoming))
       
   345     {
       
   346         HbAction *contextItem = contextMenu->addAction(LOC_COMMON_OPEN);
       
   347         connect(contextItem, SIGNAL(triggered()),this, SLOT(openItem()));
       
   348     }
       
   349     
       
   350 }
       
   351 
       
   352 //---------------------------------------------------------------
       
   353 // MsgEditorPrivate::addResendItemToContextMenu
       
   354 // @see header
       
   355 //---------------------------------------------------------------
       
   356 
       
   357 void MsgConversationView::addResendItemToContextMenu(MsgConversationViewItem* item, HbMenu* contextMenu, int sendingState)
       
   358 {
       
   359     Q_UNUSED(item)
       
   360     int direction = item->modelIndex().data(Direction).toInt();
       
   361     int messageSubType = item->modelIndex().data(MessageSubType).toInt();
       
   362     
       
   363     
       
   364     if( ((direction == ConvergedMessage::Outgoing) &&
       
   365         (messageSubType != ConvergedMessage::VCard))&&
       
   366         ((sendingState == ConvergedMessage::Resend ) ||
       
   367         
       
   368         (sendingState == ConvergedMessage::Failed )))
       
   369     {
       
   370         HbAction *contextItem = contextMenu->addAction(LOC_COMMON_SEND);
       
   371         connect(contextItem, SIGNAL(triggered()),this, SLOT(resendMessage()));
       
   372     }
       
   373 }
       
   374 
       
   375 //---------------------------------------------------------------
       
   376 // MsgEditorPrivate::addForwardItemToContextMenu
       
   377 // @see header
       
   378 //---------------------------------------------------------------
       
   379 void MsgConversationView::addForwardItemToContextMenu(MsgConversationViewItem* item, HbMenu* contextMenu, int sendingState)
       
   380 {
       
   381     int messageType = item->modelIndex().data(MessageType).toInt();
       
   382     int direction = item->modelIndex().data(Direction).toInt();
       
   383     int messageSubType = item->modelIndex().data(MessageSubType).toInt();
       
   384     
       
   385     if( (messageType == ConvergedMessage::BT) ||
       
   386         (messageType == ConvergedMessage::MmsNotification) ||
       
   387         (messageSubType == ConvergedMessage::Provisioning ) ||
       
   388         (messageSubType == ConvergedMessage::RingingTone) ||
       
   389         (messageSubType == ConvergedMessage::VCal))
       
   390     {
       
   391         return;
       
   392     }
       
   393     
       
   394     qint32 messageId = item->modelIndex().data(ConvergedMsgId).toInt();
       
   395     qint32 messageProperty = item->modelIndex().data(MessageProperty).toInt();
       
   396     
       
   397     bool canForwardMessage  = true;
       
   398     if (messageType == ConvergedMessage::Mms){
       
   399         canForwardMessage = (messageProperty & EPreviewForward)? true:false;
       
   400     }            
       
   401 
       
   402     if( ((sendingState == ConvergedMessage::SentState) ||
       
   403         (sendingState == ConvergedMessage::Resend) ||
       
   404         (sendingState == ConvergedMessage::Failed) ||
       
   405         (sendingState == ConvergedMessage::Suspended )||
       
   406         (direction == ConvergedMessage::Incoming) ) &&
       
   407         canForwardMessage)
       
   408     {
       
   409         HbAction *contextItem = contextMenu->addAction(LOC_COMMON_FORWARD);
       
   410         connect(contextItem, SIGNAL(triggered()),this, SLOT(forwardMessage()));
       
   411     }
       
   412 
       
   413 }
       
   414 
       
   415 //---------------------------------------------------------------
       
   416 // MsgEditorPrivate::addDeleteItemToContextMenu
       
   417 // @see header
       
   418 //---------------------------------------------------------------
       
   419 void MsgConversationView::addDeleteItemToContextMenu(MsgConversationViewItem* item, HbMenu* contextMenu, int sendingState)
       
   420 {
       
   421     int direction = item->modelIndex().data(Direction).toInt();
       
   422     int messageType = item->modelIndex().data(MessageType).toInt();
       
   423     int notificationState = item->modelIndex().data(NotificationStatus).toInt();
       
   424     
       
   425     if( (messageType == ConvergedMessage::MmsNotification) && 
       
   426         ((notificationState == ConvergedMessage::NotifNull) || 
       
   427          (notificationState ==  ConvergedMessage::NotifRetrieving) ||
       
   428          (notificationState == ConvergedMessage::NotifWaiting)))
       
   429     {
       
   430         return;
       
   431     }
       
   432     
       
   433     if( (sendingState == ConvergedMessage::SentState) ||
       
   434         (sendingState == ConvergedMessage::Resend) ||
       
   435         (sendingState == ConvergedMessage::Suspended) ||
       
   436         (sendingState == ConvergedMessage::Failed) ||
       
   437         (direction == ConvergedMessage::Incoming))
       
   438     {
       
   439         HbAction *contextItem = contextMenu->addAction(LOC_COMMON_DELETE);
       
   440         connect(contextItem, SIGNAL(triggered()),this, SLOT(deleteItem()));
       
   441     }  
       
   442 }
       
   443 
       
   444 //---------------------------------------------------------------
       
   445 // MsgEditorPrivate::addDownloadItemToContextMenu
       
   446 // @see header
       
   447 //---------------------------------------------------------------
       
   448 void MsgConversationView::addDownloadItemToContextMenu(MsgConversationViewItem* item, HbMenu* contextMenu)
       
   449 {
       
   450     int notificationState = item->modelIndex().data(NotificationStatus).toInt();
       
   451     int messageType = item->modelIndex().data(MessageType).toInt();
       
   452     qint32 messageId = item->modelIndex().data(ConvergedMsgId).toLongLong();
       
   453         
       
   454     if( messageType == ConvergedMessage::MmsNotification &&
       
   455         ConversationsEngine::instance()->downloadOperationSupported(messageId))
       
   456     {            
       
   457         HbAction *contextItem = contextMenu->addAction(LOC_COMMON_DOWNLOAD);
       
   458         connect(contextItem, SIGNAL(triggered()),this, SLOT(downloadMessage()));
       
   459     }
       
   460 }
       
   461 //---------------------------------------------------------------
       
   462 // MsgEditorPrivate::send
       
   463 // @see header
       
   464 //---------------------------------------------------------------
       
   465 void MsgConversationView::send()
       
   466 {
       
   467     activateInputBlocker();
       
   468     ConvergedMessageAddressList addresses;
       
   469     addresses = mContactCardWidget->address();
       
   470     int sendResult = KErrNone;
       
   471 
       
   472     // Populate the ConvergedMessage.
       
   473     if (!addresses.isEmpty())
       
   474     {
       
   475         ConvergedMessage msg;
       
   476         populateForSending(msg);
       
   477         msg.addToRecipients(addresses);
       
   478 
       
   479         // Send
       
   480         sendResult = mSendUtil->send(msg);
       
   481                    
       
   482         if( sendResult == KErrNone)
       
   483         {
       
   484             mEditorWidget->clear();
       
   485         }
       
   486     }
       
   487     deactivateInputBlocker();
       
   488     if( sendResult == KErrNotFound)
       
   489     {
       
   490     HbMessageBox::question(LOC_DIALOG_SMS_SETTINGS_INCOMPLETE, this,
       
   491                            SLOT(onDialogSettingsLaunch(HbAction*)), 
       
   492                            HbMessageBox::Ok | HbMessageBox::Cancel);
       
   493     }
       
   494 }
       
   495 
       
   496 //---------------------------------------------------------------
       
   497 // MsgConversationView::contactsFetchedForVCards
       
   498 // @see header file
       
   499 //---------------------------------------------------------------
       
   500 void MsgConversationView::contactsFetchedForVCards(const QVariant& value)
       
   501 {
       
   502     // get received contact-list and launch unieditor
       
   503     CntServicesContactList contactList = 
       
   504             qVariantValue<CntServicesContactList>(value);
       
   505     int cntCount = contactList.count();
       
   506     if(cntCount > 0)
       
   507     {
       
   508         QVariantList params;
       
   509         params << MsgBaseView::ADD_VCARD;
       
   510         params << value;
       
   511         launchUniEditor(params);        
       
   512     }
       
   513 }
       
   514 
       
   515 //---------------------------------------------------------------
       
   516 // MsgConversationView::fetchContacts
       
   517 // @see header file
       
   518 //---------------------------------------------------------------
       
   519 void MsgConversationView::fetchContacts()
       
   520 {
       
   521     HbAction* action = qobject_cast<HbAction*>(sender());
       
   522 
       
   523     if(!action)
       
   524         return;
       
   525 
       
   526     QList<QVariant> args;
       
   527     QString serviceName("com.nokia.services.phonebookservices");
       
   528     QString operation("fetch(QString,QString,QString)");
       
   529     XQAiwRequest* request;
       
   530     XQApplicationManager appManager;
       
   531     request = appManager.create(serviceName, "Fetch", operation, true); //embedded
       
   532     if ( request == NULL )
       
   533     {
       
   534         return;       
       
   535     }
       
   536 
       
   537     int mode = action->data().toInt();
       
   538     
       
   539     if( VCARD_INSERTION_MODE == mode) //vcard-insert mode
       
   540     {
       
   541         connect(request, SIGNAL(requestOk(const QVariant&)),
       
   542             this, SLOT(contactsFetchedForVCards(const QVariant&)));      
       
   543     }
       
   544     else  //contact-insert mode
       
   545     {
       
   546         connect(request, SIGNAL(requestOk(const QVariant&)),
       
   547             this, SLOT(contactsFetched(const QVariant&)));
       
   548     }
       
   549     connect (request, SIGNAL(requestError(int,const QString&)), 
       
   550         this, SLOT(serviceRequestError(int,const QString&)));
       
   551 
       
   552     args << QString(tr("Phonebook")); 
       
   553     args << KCntActionAll;
       
   554     args << KCntFilterDisplayAll;
       
   555 
       
   556     request->setArguments(args);
       
   557     request->send();
       
   558     delete request;
       
   559 }
       
   560 //---------------------------------------------------------------
       
   561 // MsgConversationView::fetchImages
       
   562 // @see header file
       
   563 //---------------------------------------------------------------
       
   564 void MsgConversationView::fetchImages()
       
   565 {
       
   566     QString service("photos");
       
   567     QString interface("com.nokia.symbian.IImageFetch");
       
   568     QString operation("fetch()");
       
   569     XQAiwRequest* request = NULL;
       
   570     XQApplicationManager appManager;
       
   571     request = appManager.create(service,interface, operation, true); // embedded
       
   572     request->setSynchronous(true); // synchronous
       
   573     if(!request)
       
   574     {
       
   575         QDEBUG_WRITE("AIW-ERROR: NULL request");
       
   576         return;
       
   577     }
       
   578 
       
   579     connect(request, SIGNAL(requestOk(const QVariant&)),
       
   580         this, SLOT(imagesFetched(const QVariant&)));
       
   581     connect(request, SIGNAL(requestError(int,const QString&)),
       
   582         this, SLOT(serviceRequestError(int,const QString&)));
       
   583 
       
   584     // Make the request
       
   585     if (!request->send())
       
   586     {
       
   587         QDEBUG_WRITE_FORMAT("AIW-ERROR: Request Send failed:" , request->lastError());
       
   588     }  
       
   589     delete request;
       
   590 }
       
   591 
       
   592 //---------------------------------------------------------------
       
   593 // MsgConversationView::fetchAudio
       
   594 // @see header file
       
   595 //---------------------------------------------------------------
       
   596 void MsgConversationView::fetchAudio()
       
   597 {
       
   598     // Launch Audio fetcher view
       
   599     QVariantList params;
       
   600     QByteArray dataArray;
       
   601     QDataStream messageStream
       
   602     (&dataArray, QIODevice::WriteOnly | QIODevice::Append);
       
   603 
       
   604     ConvergedMessage message;
       
   605     message.setBodyText(mEditorWidget->content());
       
   606     // add address from contact-card to to-field
       
   607     ConvergedMessageAddress address;
       
   608     address.setAlias(mContactCardWidget->address().at(0)->alias());
       
   609     address.setAddress(mContactCardWidget->address().at(0)->address());
       
   610     message.addToRecipient(address);
       
   611     message.serialize(messageStream);
       
   612 
       
   613     params << MsgBaseView::AUDIOFETCHER; // target view
       
   614     params << MsgBaseView::CV; // source view
       
   615     params << dataArray;
       
   616     emit switchView(params);
       
   617 }
       
   618 
       
   619 //---------------------------------------------------------------
       
   620 // MsgConversationView::contactsFetched
       
   621 // @see header file
       
   622 //---------------------------------------------------------------
       
   623 void MsgConversationView::contactsFetched(const QVariant& value)
       
   624 {
       
   625     //switch to editor.
       
   626     QVariantList params;
       
   627     params << MsgBaseView::ADD_RECIPIENTS;
       
   628     params << value;
       
   629     launchUniEditor(params);
       
   630 }
       
   631 
       
   632 //---------------------------------------------------------------
       
   633 // MsgConversationView::imagesFetched()
       
   634 // @see header file
       
   635 //---------------------------------------------------------------
       
   636 void MsgConversationView::imagesFetched(const QVariant& result )
       
   637 {
       
   638     if(result.canConvert<QStringList>())
       
   639     {
       
   640         QStringList fileList = result.value<QStringList>();
       
   641         if ( fileList.size()>0 )
       
   642         {
       
   643             QString filepath(QDir::toNativeSeparators(fileList.at(0)));
       
   644             QVariantList params;
       
   645             params << MsgBaseView::ADD_PHOTO;
       
   646             params << filepath;
       
   647             launchUniEditor(params);
       
   648         }
       
   649     }
       
   650 }
       
   651 
       
   652 //---------------------------------------------------------------
       
   653 // MsgConversationView::addSubject()
       
   654 // @see header file
       
   655 //---------------------------------------------------------------
       
   656 void MsgConversationView::addSubject()
       
   657 {
       
   658 
       
   659     QString filepath;
       
   660     QVariantList params;
       
   661     params << MsgBaseView::ADD_SUBJECT;
       
   662     launchUniEditor(params);
       
   663 }
       
   664 
       
   665 //---------------------------------------------------------------
       
   666 // MsgConversationView::forwardMessage()
       
   667 // Forwards the message
       
   668 //---------------------------------------------------------------
       
   669 void MsgConversationView::forwardMessage()
       
   670 {
       
   671     QModelIndex index = mConversationList->currentIndex();
       
   672     //messageId & messageType to be forwarded
       
   673     qint32 messageId = index.data(ConvergedMsgId).toLongLong();
       
   674     int messageType = index.data(MessageType).toInt();
       
   675  
       
   676     //Mark the message to read before forwarding.
       
   677     if(index.data(UnReadStatus).toBool())
       
   678     {
       
   679         QList<int> msgIdList;
       
   680         msgIdList.append(messageId);
       
   681         ConversationsEngine::instance()->markMessagesRead(msgIdList);
       
   682     }
       
   683     // populate params and launch editor 
       
   684     QVariantList params;
       
   685     params << MsgBaseView::FORWARD_MSG;
       
   686     params << messageId;
       
   687     params << messageType;
       
   688     launchUniEditor(params);
       
   689 }
       
   690 
       
   691 //---------------------------------------------------------------
       
   692 // MsgConversationView::resendMessage()
       
   693 // Resends the message in the failed messages case
       
   694 //---------------------------------------------------------------
       
   695 void MsgConversationView::resendMessage()
       
   696 {
       
   697     QModelIndex index = mConversationList->currentIndex();
       
   698     if(index.isValid())
       
   699     {
       
   700         qint32 messageId = index.data(ConvergedMsgId).toLongLong();    
       
   701         if(!(ConversationsEngine::instance()->resendMessage(messageId)))
       
   702         {
       
   703             HbMessageBox::warning(LOC_MSG_SEND_FAILED, 0, 0, HbMessageBox::Ok);
       
   704         }
       
   705     }
       
   706     
       
   707 }
       
   708 
       
   709 //---------------------------------------------------------------
       
   710 // MsgConversationView::downloadMessage()
       
   711 // @see header
       
   712 //---------------------------------------------------------------
       
   713 void MsgConversationView::downloadMessage()
       
   714 {
       
   715     QModelIndex index = mConversationList->currentIndex();
       
   716     if(index.isValid())
       
   717     {
       
   718         qint32 messageId = index.data(ConvergedMsgId).toLongLong();
       
   719         if(ConversationsEngine::instance()->downloadMessage(messageId)!=KErrNone)
       
   720         {
       
   721             HbMessageBox::warning(LOC_MMS_RETRIEVAL_FAILED, 0, 0, HbMessageBox::Ok);
       
   722         }
       
   723     }
       
   724     
       
   725 }
       
   726 
       
   727 //---------------------------------------------------------------
       
   728 // MsgConversationView::deleteItem()
       
   729 // Deletes the message
       
   730 //---------------------------------------------------------------
       
   731 void MsgConversationView::deleteItem()
       
   732 {
       
   733     QString str = LOC_DELETE_MESSAGE;
       
   734 
       
   735     QModelIndex index = mConversationList->currentIndex();
       
   736     if(index.isValid())
       
   737     {
       
   738         int messageType = index.data(MessageType).toInt();        
       
   739         int direction = index.data(Direction).toInt();
       
   740 
       
   741         if ( direction == ConvergedMessage::Outgoing &&
       
   742             messageType == ConvergedMessage::Mms )
       
   743         {
       
   744             qint32 messageId = index.data(ConvergedMsgId).toLongLong();
       
   745 
       
   746             if(isSharedMessage(messageId))
       
   747             {
       
   748                 str = LOC_DELETE_SHARED_MESSAGE;  
       
   749             }
       
   750         }
       
   751     }
       
   752 
       
   753 
       
   754     HbMessageBox::question(str,this,SLOT(onDialogdeleteMsg(HbAction*)),
       
   755                            HbMessageBox::Delete | HbMessageBox::Cancel);
       
   756 }
       
   757 
       
   758 //---------------------------------------------------------------
       
   759 // MsgConversationView::openItem()
       
   760 // Opens the message
       
   761 //---------------------------------------------------------------
       
   762 void MsgConversationView::openItem()
       
   763 {
       
   764     QModelIndex index = mConversationList->currentIndex();
       
   765     openItem(index);
       
   766 }
       
   767 
       
   768 //---------------------------------------------------------------
       
   769 // MsgConversationView::clearEditors()
       
   770 // @See header
       
   771 //---------------------------------------------------------------
       
   772 void MsgConversationView::clearEditors()
       
   773 {
       
   774     mEditorWidget->clear();
       
   775     mConversationList->setModel(NULL);
       
   776     mContactCardWidget->clearContent();
       
   777 }
       
   778 
       
   779 //---------------------------------------------------------------
       
   780 // MsgConversationView::saveContentToDrafts()
       
   781 // @See header
       
   782 //---------------------------------------------------------------
       
   783 int MsgConversationView::saveContentToDrafts()
       
   784 {
       
   785     int msgId = INVALID_MSGID;
       
   786     if(!mEditorWidget->content().isEmpty())
       
   787     {
       
   788         activateInputBlocker();
       
   789         ConvergedMessageAddressList addresses;
       
   790         addresses = mContactCardWidget->address();
       
   791 
       
   792         // Populate the ConvergedMessage.
       
   793         if (!addresses.isEmpty())
       
   794         {
       
   795             ConvergedMessage msg;
       
   796             populateForSending(msg);
       
   797             msg.addToRecipients(addresses);
       
   798             
       
   799             // save to drafts
       
   800             msgId = mSendUtil->saveToDrafts(msg);
       
   801                      
       
   802             mEditorWidget->clear();
       
   803         }
       
   804         deactivateInputBlocker();
       
   805     }
       
   806     return msgId;
       
   807 }
       
   808 
       
   809 //---------------------------------------------------------------
       
   810 //MsgConversationView::populateForSending()
       
   811 //@see header
       
   812 //---------------------------------------------------------------
       
   813 void MsgConversationView::populateForSending(ConvergedMessage &message)
       
   814 {
       
   815     message.setMessageType(ConvergedMessage::Sms);
       
   816     message.setBodyText(mEditorWidget->content());
       
   817     message.setDirection(ConvergedMessage::Outgoing);
       
   818     QDateTime time = QDateTime::currentDateTime();
       
   819     message.setTimeStamp(time.toTime_t());
       
   820 }
       
   821 
       
   822 //---------------------------------------------------------------
       
   823 //MsgConversationView::launchBtDisplayService()
       
   824 //@see header
       
   825 //---------------------------------------------------------------
       
   826 void MsgConversationView::launchBtDisplayService(const QModelIndex & index)
       
   827 {
       
   828     qint32 messageId = index.data(ConvergedMsgId).toLongLong();
       
   829 
       
   830     QList<QVariant> args;
       
   831     QString serviceName("com.nokia.services.btmsgdispservices");
       
   832     QString operation("displaymsg(int)");
       
   833     XQAiwRequest* request;
       
   834     XQApplicationManager appManager;
       
   835     request = appManager.create(serviceName, "displaymsg", operation, false); // embedded
       
   836     
       
   837     if ( request == NULL )
       
   838         {
       
   839         return;
       
   840         }
       
   841 
       
   842     args << QVariant(messageId);
       
   843     request->setSynchronous(true);
       
   844     
       
   845     request->setArguments(args);
       
   846     request->send();
       
   847     delete request;    
       
   848 }
       
   849 
       
   850 //---------------------------------------------------------------
       
   851 // MsgConversationView::menuAboutToShow()
       
   852 // @See header
       
   853 //---------------------------------------------------------------
       
   854 void MsgConversationView::menuAboutToShow()
       
   855 {
       
   856     // Clear all the previously added actions.
       
   857     HbMenu *mainMenu = this->menu();
       
   858     mainMenu->clearActions();
       
   859 
       
   860     // Message type specific menu items
       
   861     QModelIndex index = ConversationsEngine::instance()->getConversationsModel()->index(0, 0);
       
   862     if (ConvergedMessage::BT != index.data(MessageType).toInt())
       
   863     {
       
   864         // Attach sub-menu
       
   865         HbMenu *attachSubMenu = mainMenu->addMenu(LOC_ATTACH);
       
   866         
       
   867         attachSubMenu->addAction(LOC_PHOTO,this, SLOT(fetchImages()));
       
   868         attachSubMenu->addAction(LOC_SOUND,this, SLOT(fetchAudio()));
       
   869 		
       
   870         HbAction* addVCard = attachSubMenu->addAction(LOC_VCARD);
       
   871         addVCard->setData(VCARD_INSERTION_MODE);        
       
   872         connect(addVCard, SIGNAL(triggered()),this,SLOT(fetchContacts()));
       
   873 
       
   874         HbAction *addRecipients = mainMenu->addAction(LOC_ADD_RECIPIENTS);
       
   875         addRecipients->setData(CONTACT_INSERTION_MODE);        
       
   876         connect(addRecipients, SIGNAL(triggered()), this, SLOT(fetchContacts()));
       
   877 
       
   878         mainMenu->addAction(LOC_ADD_SUBJECT,this, SLOT(addSubject()));
       
   879     }
       
   880 }
       
   881 
       
   882 //---------------------------------------------------------------
       
   883 //MsgConversationView::openItem
       
   884 //@see header
       
   885 //---------------------------------------------------------------
       
   886 void MsgConversationView::openItem(const QModelIndex & index)
       
   887 {
       
   888     // Return if invalid index.
       
   889     if (!index.isValid())
       
   890     {
       
   891         return;
       
   892     }
       
   893     
       
   894     int messageType = index.data(MessageType).toInt();
       
   895     int messageSubType = index.data(MessageSubType).toInt();
       
   896     int messageId = index.data(ConvergedMsgId).toInt();
       
   897     
       
   898     if (ConvergedMessage::BioMsg == messageType)
       
   899     {
       
   900         if (ConvergedMessage::RingingTone == messageSubType)
       
   901         {
       
   902             HbMessageBox::question(LOC_DIALOG_SAVE_RINGTONE, this,
       
   903                                    SLOT(onDialogSaveTone(HbAction*)), 
       
   904                                    HbMessageBox::Save | HbMessageBox::Cancel);
       
   905             return;
       
   906         }
       
   907         else if(ConvergedMessage::Provisioning == messageSubType)
       
   908         {
       
   909             int messageId = index.data(ConvergedMsgId).toInt();
       
   910             handleProvisoningMsg(messageId);
       
   911             QList<int> msgIdList;
       
   912             if(index.data(UnReadStatus).toInt())
       
   913             {
       
   914                 msgIdList.clear();
       
   915                 msgIdList << messageId;
       
   916                 ConversationsEngine::instance()->markMessagesRead(msgIdList);
       
   917             }
       
   918             return;
       
   919         }
       
   920         else if(ConvergedMessage::VCard == messageSubType)
       
   921         {
       
   922             handleShortTap();
       
   923             return;
       
   924         }
       
   925         else if(ConvergedMessage::VCal == messageSubType)
       
   926         {
       
   927             return;
       
   928         }
       
   929     }
       
   930     else if (ConvergedMessage::BT == messageType)
       
   931     {
       
   932         launchBtDisplayService(index);
       
   933         QList<int> msgIdList;
       
   934         if(index.data(UnReadStatus).toInt())
       
   935             {
       
   936             msgIdList.clear();
       
   937             msgIdList << messageId;
       
   938             ConversationsEngine::instance()->markMessagesRead(msgIdList);
       
   939             }
       
   940         return;
       
   941     }
       
   942     else if(ConvergedMessage::MmsNotification == messageType)
       
   943     {
       
   944         qint32 messageId = index.data(ConvergedMsgId).toLongLong();
       
   945         if(!ConversationsEngine::instance()->downloadOperationSupported(messageId))           
       
   946         {
       
   947            int notificationState = index.data(NotificationStatus).toInt();
       
   948            if( notificationState == ConvergedMessage::NotifExpired)
       
   949            {
       
   950                deleteItem();
       
   951            }
       
   952            return;
       
   953         }
       
   954         else
       
   955         {
       
   956             //TODO: use logical str name
       
   957             HbMessageBox::question("Download Message?",this,
       
   958                                    SLOT(onDialogDownLoadMsg(HbAction*)),
       
   959                                    HbMessageBox::Yes | HbMessageBox::Cancel);
       
   960             return;
       
   961         }
       
   962     }
       
   963 
       
   964     int direction = index.data(Direction).toInt();
       
   965 
       
   966     if (direction == ConvergedMessage::Outgoing && ConvergedMessage::Sms == messageType
       
   967         && ConversationsEngine::instance()->getMsgSubType(messageId)== ConvergedMessage::NokiaService)
       
   968     {
       
   969         return;
       
   970     }
       
   971     
       
   972     // check whether message is in sending progress, then donot launch viewer.
       
   973     int location = index.data(MessageLocation).toInt();
       
   974     int sendingState = index.data(SendingState).toInt();
       
   975     
       
   976     // For suspended message both short tap and long tap needs to show the same
       
   977     // context menu.....
       
   978     if(direction == ConvergedMessage::Outgoing 
       
   979         	&&sendingState == ConvergedMessage::Suspended )
       
   980     {
       
   981         handleShortTap();
       
   982         return;
       
   983     }
       
   984     
       
   985     //If message is in any other state other than 'Sent'
       
   986     //do not open the message
       
   987     if(direction == ConvergedMessage::Outgoing 
       
   988             && sendingState != ConvergedMessage::SentState )
       
   989            
       
   990     {
       
   991         return;
       
   992     }
       
   993 
       
   994    
       
   995     
       
   996     // contact Id
       
   997     qint32 contactId = index.data(ContactId).toLongLong();  
       
   998 	    
       
   999     //if message unread, mark as read before opening view
       
  1000     QList<int> msgIdList;
       
  1001     if(index.data(UnReadStatus).toInt())
       
  1002     {
       
  1003         msgIdList.clear();
       
  1004         msgIdList << messageId;
       
  1005         ConversationsEngine::instance()->markMessagesRead(msgIdList);
       
  1006     }
       
  1007 
       
  1008     //switch view
       
  1009     QVariantList param;
       
  1010     param << MsgBaseView::UNIVIEWER;  // target view
       
  1011     param << MsgBaseView::CV; // source view
       
  1012 
       
  1013     param << contactId;
       
  1014     param << messageId;
       
  1015     param << mMessageModel->rowCount();
       
  1016     emit switchView(param);
       
  1017 }
       
  1018 
       
  1019 //---------------------------------------------------------------
       
  1020 // MsgConversationView::launchUniEditor
       
  1021 // @see header file
       
  1022 //---------------------------------------------------------------
       
  1023 void MsgConversationView::launchUniEditor(const QVariantList& data)
       
  1024 {
       
  1025     // param list for switching to editor view
       
  1026     QVariantList params;
       
  1027     QByteArray dataArray;
       
  1028     QDataStream messageStream
       
  1029     (&dataArray, QIODevice::WriteOnly | QIODevice::Append);
       
  1030 
       
  1031     // first arg is always the editor operation
       
  1032     int editorOperation = data.at(0).toInt();
       
  1033     
       
  1034     ConvergedMessage message;
       
  1035     QVariant data2;
       
  1036     if( editorOperation != MsgBaseView::FORWARD_MSG )
       
  1037     {
       
  1038         message.setBodyText(mEditorWidget->content());
       
  1039 
       
  1040         // add address from contact-card to to-field
       
  1041         ConvergedMessageAddress address;
       
  1042         address.setAlias(mContactCardWidget->address().at(0)->alias());
       
  1043         address.setAddress(mContactCardWidget->address().at(0)->address());
       
  1044         message.addToRecipient(address);
       
  1045 
       
  1046         if(editorOperation == MsgBaseView::ADD_PHOTO ||
       
  1047            editorOperation == MsgBaseView::ADD_AUDIO ||
       
  1048            editorOperation == MsgBaseView::ADD_VIDEO )
       
  1049         {
       
  1050             // filepath is sent in cases like ADD_PHOTO, ADD_AUDIO etc.
       
  1051             QString filepath;
       
  1052             filepath = data.at(1).toString();
       
  1053             if(!filepath.isEmpty())
       
  1054             {
       
  1055                 ConvergedMessageAttachment* attachment = 
       
  1056                         new ConvergedMessageAttachment(filepath);
       
  1057                 ConvergedMessageAttachmentList attachmentList;
       
  1058                 attachmentList.append(attachment);
       
  1059                 message.addAttachments(attachmentList);
       
  1060             }            
       
  1061         }
       
  1062         else if(editorOperation == MsgBaseView::ADD_VCARD)
       
  1063         {
       
  1064             // filepath is not sent in cases like VCards & recipients
       
  1065             // instead, we will get a list of contacts. Pass it as it is.
       
  1066             data2 = data.at(1);
       
  1067         }
       
  1068         else if(editorOperation == MsgBaseView::ADD_RECIPIENTS)
       
  1069         {
       
  1070             ConvergedMessageAddressList addresses;
       
  1071             CntServicesContactList contactList = 
       
  1072                     qVariantValue<CntServicesContactList>(data.at(1));
       
  1073             // now add fetched contacts from contact selection dialog
       
  1074             for(int i = 0; i < contactList.count(); i++ )
       
  1075             {
       
  1076                 ConvergedMessageAddress* address = new ConvergedMessageAddress;
       
  1077                 address->setAlias(contactList[i].mDisplayName);
       
  1078                 if(!contactList[i].mPhoneNumber.isEmpty())
       
  1079                 {
       
  1080                     address->setAddress(contactList[i].mPhoneNumber);
       
  1081                 }
       
  1082                 else
       
  1083                 {
       
  1084                     address->setAddress(contactList[i].mEmailAddress);
       
  1085                 }
       
  1086                 addresses.append(address);
       
  1087             }
       
  1088             message.addToRecipients(addresses);
       
  1089         }
       
  1090     }
       
  1091     else
       
  1092     {
       
  1093         qint32 msgId = (qint32)data.at(1).toInt();
       
  1094         int msgType = data.at(2).toInt();
       
  1095         ConvergedMessageId id(msgId);
       
  1096         message.setMessageId(id);
       
  1097         message.setMessageType((ConvergedMessage::MessageType)msgType);
       
  1098     }
       
  1099 
       
  1100     message.serialize(messageStream);
       
  1101     params << MsgBaseView::UNIEDITOR;
       
  1102     params << MsgBaseView::CV;
       
  1103     params << dataArray;
       
  1104     params << editorOperation;
       
  1105     if(!data2.isNull())
       
  1106         params << data2;
       
  1107 
       
  1108     clearEditors();
       
  1109     emit switchView(params);
       
  1110 }
       
  1111 
       
  1112 //---------------------------------------------------------------
       
  1113 // MsgConversationView::populateConversationsView
       
  1114 // @see header file
       
  1115 //---------------------------------------------------------------
       
  1116 void MsgConversationView::populateConversationsView()
       
  1117 {    
       
  1118     mModelPopulated = true;
       
  1119     mConversationList->setModel(mMessageModel);
       
  1120     
       
  1121     refreshView();
       
  1122     scrollToBottom();
       
  1123     fetchMoreConversations();
       
  1124 }
       
  1125 
       
  1126 //---------------------------------------------------------------
       
  1127 // MsgConversationView::saveRingingTone
       
  1128 // @see header file
       
  1129 //---------------------------------------------------------------
       
  1130 void MsgConversationView::saveRingingTone()
       
  1131 {
       
  1132     QModelIndex index = mConversationList->currentIndex();
       
  1133     int messageId = index.data(ConvergedMsgId).toInt();
       
  1134 
       
  1135     UniDataModelLoader* pluginLoader = new UniDataModelLoader();
       
  1136     UniDataModelPluginInterface* pluginInterface = 
       
  1137     pluginLoader->getDataModelPlugin(ConvergedMessage::BioMsg);
       
  1138     pluginInterface->setMessageId(messageId);
       
  1139     UniMessageInfoList attachments = pluginInterface->attachmentList();
       
  1140     if(attachments.count() > 0)
       
  1141     {
       
  1142         QString attachmentPath = attachments[0]->path();
       
  1143 
       
  1144         RingBc* ringBc = new RingBc();
       
  1145 
       
  1146         ringBc->saveTone(attachmentPath);
       
  1147 
       
  1148         // clear attachement list : its allocated at data model
       
  1149         while(!attachments.isEmpty())
       
  1150         {
       
  1151             delete attachments.takeFirst();
       
  1152         }
       
  1153 
       
  1154         delete ringBc;
       
  1155     }
       
  1156     delete pluginLoader;
       
  1157 }
       
  1158 
       
  1159 //---------------------------------------------------------------
       
  1160 // MsgConversationView::handleSmsCharLimitReached
       
  1161 // @see header file
       
  1162 //---------------------------------------------------------------
       
  1163 void MsgConversationView::handleSmsCharLimitReached()   
       
  1164 {
       
  1165     QString filepath;
       
  1166     QVariantList params;
       
  1167     params << MsgBaseView::ADD_OTHERS;
       
  1168     launchUniEditor(params);   
       
  1169 }
       
  1170 
       
  1171 //---------------------------------------------------------------
       
  1172 // MsgConversationView::vkbOpened
       
  1173 // @see header file
       
  1174 //---------------------------------------------------------------
       
  1175 void MsgConversationView::vkbOpened()
       
  1176 {
       
  1177     emit vkbOpened(true);
       
  1178     
       
  1179     scrollToBottom();
       
  1180     
       
  1181     QRectF appRect = mVkbHost->applicationArea();    
       
  1182     qreal spacing = 0.0;
       
  1183     qreal cardHeight = 0.0;
       
  1184     if(mContactCardWidget->isVisible())
       
  1185         {
       
  1186         cardHeight = mContactCardWidget->rect().height();
       
  1187         spacing = HbDeviceProfile::profile(this).unitValue();
       
  1188         }
       
  1189     
       
  1190     this->setMaximumHeight(appRect.height()- cardHeight - spacing);
       
  1191     mConversationList->adjustSize();
       
  1192     
       
  1193     disconnect(mVkbHost,SIGNAL(keypadOpened()),this,SLOT(vkbOpened()));
       
  1194 
       
  1195 }
       
  1196 	  
       
  1197 //---------------------------------------------------------------
       
  1198 // MsgConversationView::vkbClosed
       
  1199 // @see header file
       
  1200 //---------------------------------------------------------------
       
  1201 void MsgConversationView::vkbClosed()
       
  1202 {
       
  1203     emit vkbOpened(false);
       
  1204     
       
  1205     scrollToBottom();
       
  1206     
       
  1207     this->setMaximumHeight(-1);
       
  1208     mConversationList->adjustSize();    
       
  1209     
       
  1210     connect(mVkbHost,SIGNAL(keypadOpened()),this,SLOT(vkbOpened()));
       
  1211 }
       
  1212 
       
  1213 //---------------------------------------------------------------
       
  1214 // MsgConversationView::serviceRequestError
       
  1215 // @see header file
       
  1216 //---------------------------------------------------------------
       
  1217 void MsgConversationView::serviceRequestError(int errorCode, const QString& errorMessage)
       
  1218 {
       
  1219     QDEBUG_WRITE_FORMAT(errorMessage,errorCode);
       
  1220 }
       
  1221 
       
  1222 //---------------------------------------------------------------
       
  1223 // MsgConversationView::activateInputBlocker
       
  1224 // @see header file
       
  1225 //---------------------------------------------------------------
       
  1226 void MsgConversationView::activateInputBlocker()
       
  1227 {
       
  1228     mainWindow()->setInteractive(false);
       
  1229 }
       
  1230 
       
  1231 //---------------------------------------------------------------
       
  1232 // MsgConversationView::deactivateInputBlocker
       
  1233 // @see header file
       
  1234 //---------------------------------------------------------------
       
  1235 void MsgConversationView::deactivateInputBlocker()
       
  1236 {
       
  1237     mainWindow()->setInteractive(true);
       
  1238 }
       
  1239 
       
  1240 //---------------------------------------------------------------
       
  1241 // MsgConversationView::handleProvisoningMsg
       
  1242 // @see header file
       
  1243 //---------------------------------------------------------------
       
  1244 void MsgConversationView::handleProvisoningMsg(int msgId)
       
  1245 	{
       
  1246 		QString messageId;
       
  1247     messageId.setNum(msgId);
       
  1248 
       
  1249     XQApplicationManager* aiwMgr = new XQApplicationManager();
       
  1250 
       
  1251     XQAiwRequest* request = aiwMgr->create("com.nokia.services.MDM", 
       
  1252             "Provisioning",
       
  1253             "ProcessMessage(QString)", true); // embedded
       
  1254 
       
  1255     if (request) {
       
  1256     QList<QVariant> args;
       
  1257     args << QVariant(messageId);
       
  1258     request->setArguments(args);
       
  1259 
       
  1260     // Send the request
       
  1261     bool res = request->send();
       
  1262 
       
  1263     // Cleanup
       
  1264     delete request;
       
  1265     }
       
  1266 
       
  1267     delete aiwMgr;
       
  1268 	}
       
  1269 
       
  1270 //---------------------------------------------------------------
       
  1271 // MsgConversationView::onDialogSettingsLaunch
       
  1272 // @see header file
       
  1273 //---------------------------------------------------------------
       
  1274 void MsgConversationView::onDialogSettingsLaunch(HbAction* action)
       
  1275 {
       
  1276     HbMessageBox *dlg = qobject_cast<HbMessageBox*> (sender());
       
  1277     if (action == dlg->actions().at(0)) {
       
  1278         //switch to settings view
       
  1279          QVariantList param;
       
  1280          param << MsgBaseView::MSGSETTINGS;
       
  1281          param << MsgBaseView::CV;
       
  1282          param << MsgSettingsView::SMSView;
       
  1283          emit switchView(param);
       
  1284     }
       
  1285 
       
  1286 }
       
  1287 
       
  1288 //---------------------------------------------------------------
       
  1289 // MsgConversationView::onDialogdeleteMsg
       
  1290 // @see header file
       
  1291 //---------------------------------------------------------------
       
  1292 void MsgConversationView::onDialogdeleteMsg(HbAction* action)
       
  1293 {
       
  1294     HbMessageBox *dlg = qobject_cast<HbMessageBox*> (sender());
       
  1295     if (action == dlg->actions().at(0)) {
       
  1296         QModelIndex index = mConversationList->currentIndex();
       
  1297         if (index.isValid()) {
       
  1298             int count = mMessageModel->rowCount();
       
  1299             //delete message
       
  1300             qint32 messageId = index.data(ConvergedMsgId).toLongLong();
       
  1301             if (messageId) {
       
  1302                 QList<int> msgIdList;
       
  1303                 msgIdList.append(messageId);
       
  1304                 ConversationsEngine::instance()->deleteMessages(msgIdList);
       
  1305                 //switch view               
       
  1306                 if (count == 1) {
       
  1307                     QVariantList param;
       
  1308                     param << MsgBaseView::CLV; // target view
       
  1309                     param << MsgBaseView::CV; // source view
       
  1310                     emit switchView(param);
       
  1311                 }
       
  1312             }
       
  1313         }
       
  1314 
       
  1315     }
       
  1316 
       
  1317 }
       
  1318 
       
  1319 //---------------------------------------------------------------
       
  1320 // MsgConversationView::onDialogDownLoadMsg
       
  1321 // @see header file
       
  1322 //--------------------------------------------------------------
       
  1323 void MsgConversationView::onDialogDownLoadMsg(HbAction* action)
       
  1324 {
       
  1325     HbMessageBox *dlg = qobject_cast<HbMessageBox*> (sender());
       
  1326     if (action == dlg->actions().at(0)) {
       
  1327         downloadMessage();
       
  1328     }
       
  1329     
       
  1330     //if message unread, mark as read now
       
  1331     QModelIndex index = mConversationList->currentIndex();
       
  1332     qint32 messageId = index.data(ConvergedMsgId).toLongLong();
       
  1333     QList<int> msgIdList;
       
  1334     if(index.data(UnReadStatus).toInt())
       
  1335     {
       
  1336         msgIdList.clear();
       
  1337         msgIdList << messageId;
       
  1338         ConversationsEngine::instance()->markMessagesRead(msgIdList);
       
  1339     }
       
  1340 }
       
  1341 
       
  1342 //---------------------------------------------------------------
       
  1343 // MsgConversationView::onDialogSaveTone
       
  1344 // @see header file
       
  1345 //--------------------------------------------------------------
       
  1346 void MsgConversationView::onDialogSaveTone(HbAction* action)
       
  1347     {
       
  1348     HbMessageBox *dlg = qobject_cast<HbMessageBox*> (sender());
       
  1349     if (action == dlg->actions().at(0)) {
       
  1350         saveRingingTone();
       
  1351     }
       
  1352 }
       
  1353 
       
  1354 //---------------------------------------------------------------
       
  1355 // MsgConversationView::onOrientationChanged
       
  1356 // @see header file
       
  1357 //---------------------------------------------------------------
       
  1358 void MsgConversationView::onOrientationChanged(Qt::Orientation newOrientation)
       
  1359 {
       
  1360     Q_UNUSED(newOrientation)
       
  1361 
       
  1362     // On orientation change always make the preserved index(last visible item) to be visible
       
  1363     if(mVisibleIndex.isValid())
       
  1364     {
       
  1365     mConversationList->scrollTo(mVisibleIndex, HbAbstractItemView::PositionAtBottom);
       
  1366     mVisibleIndex = QModelIndex();
       
  1367     }
       
  1368 }
       
  1369 
       
  1370 //---------------------------------------------------------------
       
  1371 // MsgConversationView::onOrientationAboutToBeChanged
       
  1372 // @see header file
       
  1373 //---------------------------------------------------------------
       
  1374 void MsgConversationView::onOrientationAboutToBeChanged()
       
  1375 {
       
  1376     // Preserve the model index of the last visible item to be scrolled on orientation change
       
  1377     QList<HbAbstractViewItem *>items = mConversationList->visibleItems();
       
  1378     if (items.count() > 0) {
       
  1379         mVisibleIndex = items.last()->modelIndex();
       
  1380     }
       
  1381 }
       
  1382 
       
  1383 //---------------------------------------------------------------
       
  1384 // MsgConversationView::onViewReady
       
  1385 // @see header file
       
  1386 //---------------------------------------------------------------
       
  1387 void MsgConversationView::onViewReady()
       
  1388 {
       
  1389     mViewReady = true;
       
  1390     //Disconnect list View's signals, for avoiding execution of the default implementaion
       
  1391     disconnect(mainWindow(), SIGNAL(aboutToChangeOrientation()), mConversationList, 0);
       
  1392     disconnect(mainWindow(), SIGNAL(orientationChanged(Qt: rientation)), mConversationList, 0);
       
  1393     
       
  1394    fetchMoreConversations();
       
  1395 }
       
  1396 
       
  1397 //---------------------------------------------------------------
       
  1398 // MsgConversationView::handleShortTap
       
  1399 // @see header file
       
  1400 //---------------------------------------------------------------
       
  1401 void MsgConversationView::handleShortTap()
       
  1402 {
       
  1403     HbAbstractViewItem* item = mConversationList->currentViewItem();
       
  1404     QRectF rc = item->rect();
       
  1405     QPointF p = item->mapToScene(rc.center());
       
  1406     
       
  1407     showContextMenu(item,p,HbPopup::TopEdgeCenter);
       
  1408 }
       
  1409 
       
  1410 //---------------------------------------------------------------
       
  1411 // MsgConversationView::handleShortTap
       
  1412 // @see header file
       
  1413 //---------------------------------------------------------------
       
  1414 void MsgConversationView::showContextMenu(HbAbstractViewItem* viewItem,const QPointF& point, int placement)
       
  1415 {    
       
  1416     MsgConversationViewItem* item = qgraphicsitem_cast<MsgConversationViewItem *>(viewItem);
       
  1417 
       
  1418     // Show the item-specific menu
       
  1419     if (this->isVisible())
       
  1420     {
       
  1421         //If message is in Sending state or is Scheduled to be sent later,
       
  1422         //do not allow any operations on the message
       
  1423         int sendingState = item->modelIndex().data(SendingState).toInt();
       
  1424         
       
  1425         if(sendingState == ConvergedMessage::Scheduled ||
       
  1426             sendingState == ConvergedMessage::Sending ||
       
  1427             sendingState == ConvergedMessage::Waiting)
       
  1428             {
       
  1429                 return;
       
  1430             }
       
  1431         // Create new menu
       
  1432         HbMenu* contextMenu = new HbMenu();
       
  1433         contextMenu->setAttribute(Qt::WA_DeleteOnClose);
       
  1434         contextMenu->setPreferredPos(point,HbPopup::Placement(placement));
       
  1435         setContextMenu(item, contextMenu, sendingState);
       
  1436         contextMenu->show();
       
  1437     }
       
  1438 }
       
  1439 
       
  1440 //---------------------------------------------------------------
       
  1441 // MsgConversationView::saveVCard
       
  1442 // @see header file
       
  1443 //---------------------------------------------------------------
       
  1444 void MsgConversationView::saveVCard()
       
  1445 {
       
  1446     QModelIndex index = mConversationList->currentIndex();
       
  1447     
       
  1448     QString filepath = index.data(Attachments).toStringList().at(0);
       
  1449     bool result = MsgContactsUtil::launchVCardViewer(filepath);
       
  1450     if(result)
       
  1451     {
       
  1452         int messageId = index.data(ConvergedMsgId).toInt();
       
  1453         QList<int> msgIdList;
       
  1454         if(index.data(UnReadStatus).toInt())
       
  1455         {
       
  1456             msgIdList.clear();
       
  1457             msgIdList << messageId;
       
  1458             ConversationsEngine::instance()->markMessagesRead(msgIdList);
       
  1459         }
       
  1460     } 
       
  1461 }
       
  1462 
       
  1463 //---------------------------------------------------------------
       
  1464 // MsgConversationView::isSharedMessage
       
  1465 // @see header file
       
  1466 //---------------------------------------------------------------
       
  1467 bool MsgConversationView::isSharedMessage(qint32 messageId)
       
  1468 {
       
  1469     bool shared = false;
       
  1470 
       
  1471     UniDataModelLoader* pluginLoader = new UniDataModelLoader();
       
  1472     
       
  1473     UniDataModelPluginInterface* pluginInterface =
       
  1474         pluginLoader->getDataModelPlugin(ConvergedMessage::Mms);
       
  1475     
       
  1476     CMsvSession* session = pluginInterface->session();
       
  1477 
       
  1478     TMsvEntry entry; 
       
  1479     TMsvId service;
       
  1480     session->GetEntry(messageId, service, entry);
       
  1481     
       
  1482     if(entry.MultipleRecipients())
       
  1483     {
       
  1484         shared = true;
       
  1485     }
       
  1486     delete pluginLoader;    
       
  1487 
       
  1488     return shared;
       
  1489 }
       
  1490 
       
  1491 // EOF