phonebookui/pbkcommonui/src/cntcontactcardview_p.cpp
changeset 59 a642906a277a
parent 47 7cbcb2896f0e
child 65 ae724a111993
--- a/phonebookui/pbkcommonui/src/cntcontactcardview_p.cpp	Tue Jul 06 14:05:47 2010 +0300
+++ b/phonebookui/pbkcommonui/src/cntcontactcardview_p.cpp	Wed Aug 18 09:39:00 2010 +0300
@@ -63,6 +63,7 @@
 #include "cntactionlauncher.h"
 #include "cntpresencelistener.h"
 #include "cntactionpopup.h"
+#include "cntvcarddetailhandler.h"
 
 #define CNT_MAPTILE_PROGRESS_TIMER  100 //100 msec
 #define CNT_UNKNOWN_MAPTILE_STATUS  -1
@@ -74,7 +75,7 @@
 Constructor, initialize member variables.
 \a viewManager is the parent that creates this view. \a parent is a pointer to parent QGraphicsItem (by default this is 0)
 */
-CntContactCardViewPrivate::CntContactCardViewPrivate() :
+CntContactCardViewPrivate::CntContactCardViewPrivate(bool isTemporary) :
     QObject(), 
     mScrollArea(NULL),
     mContainerWidget(NULL),
@@ -96,7 +97,9 @@
     mSendKeyListModel(NULL),
     mPresenceListener(NULL),
     mMaptile(NULL),
-	mProgressTimer(NULL)
+	mProgressTimer(NULL),
+	mIsTemporary(isTemporary),
+	mIsExecutingAction(false)
 {
     bool ok;
     document()->load(CNT_CONTACTCARDVIEW_XML, &ok);
@@ -119,7 +122,7 @@
     mBackKey = new HbAction(Hb::BackNaviAction, mView);
     mView->setNavigationAction(mBackKey);  
     connect(mBackKey, SIGNAL(triggered()), this, SLOT(showPreviousView()));
-	
+    
     mProgressTimer = new QTimer(this);
     mProgressTimer->setSingleShot(true);
     connect(mProgressTimer, SIGNAL(timeout()),this, SLOT(updateSpinningIndicator())); 
@@ -169,7 +172,8 @@
     
     delete mPresenceListener;
     mPresenceListener = NULL;
-	delete mMaptile;
+    
+    delete mMaptile;
     mMaptile = NULL;
     
     delete mProgressTimer;
@@ -195,14 +199,22 @@
     
     //save the contact if avatar has been changed.
     QContact contact = contactManager()->contact(mContact->localId());
-    if ( contact != *mContact )
+    if ( contact != *mContact && contactManager()->error() == QContactManager::NoError)
     {
         contactManager()->saveContact(mContact);
     }
-       
+    
     mViewManager->back( mArgs );
 }
 
+/*!
+Activates the root view
+*/
+void CntContactCardViewPrivate::showRootView()
+{
+    mViewManager->back( mArgs, true );
+}
+
 /*
 Activates a default view and setup name label texts
 */
@@ -213,13 +225,14 @@
     mViewManager = aMgr;
     mArgs = aArgs;
     
-    mView->installEventFilter(this);
-    
     HbMainWindow* window = mView->mainWindow();
-    connect(window, SIGNAL(orientationChanged(Qt::Orientation)), this, SLOT(setOrientation(Qt::Orientation)));
-    connect(window, SIGNAL(keyPressed(QKeyEvent*)), this, SLOT(keyPressed(QKeyEvent*)));
-    
-    setOrientation(window->orientation());
+    if (window)
+    {
+        connect(window, SIGNAL(orientationChanged(Qt::Orientation)), this, SLOT(setOrientation(Qt::Orientation)));
+        window->installEventFilter(this);
+        
+        setOrientation(window->orientation());
+    }
         
     QContact contact = aArgs.value(ESelectedContact).value<QContact>();
     mContact = new QContact( contact );
@@ -234,6 +247,12 @@
     {
         mView->toolBar()->removeAction(static_cast<HbAction*>(document()->findObject(QString("cnt:sendMyCard"))));
     }
+    if (mIsTemporary)
+    {
+        mView->menu()->clearActions();
+        mView->toolBar()->clearActions();
+        mView->toolBar()->addAction(static_cast<HbAction*>(document()->findObject(QString("cnt:addtocontact"))));
+    }
     
     // add heading widget to the content
     QGraphicsWidget *c = document()->findWidget(QString("content"));
@@ -241,19 +260,32 @@
 
     mHeadingItem = static_cast<CntContactCardHeadingItem*>(document()->findWidget(QString("cnt_contactcard_heading")));
     mHeadingItem->setDetails(mContact);
-    connect(mHeadingItem, SIGNAL(passLongPressed(const QPointF&)), this, SLOT(drawMenu(const QPointF&)));
-    connect(mHeadingItem, SIGNAL(passShortPressed(const QPointF&)), this, SLOT(doChangeImage()));
+    
+    mImageLabel = static_cast<CntImageLabel*>(document()->findWidget("cnt_contactcard_image"));
+         
+    if (!mIsTemporary)
+    {
+        connect(mHeadingItem, SIGNAL(passLongPressed(const QPointF&)), this, SLOT(drawMenu(const QPointF&)));
+        connect(mHeadingItem, SIGNAL(passShortPressed(const QPointF&)), this, SLOT(doChangeImage())); 
+        connect(mImageLabel, SIGNAL(iconClicked()), this, SLOT(doChangeImage()));
+        connect(mImageLabel, SIGNAL(iconLongPressed(const QPointF&)), this, SLOT(drawMenu(const QPointF&)));
+    }
+    else
+    {
+        mHeadingItem->ungrabGesture(Qt::TapGesture);
+        mImageLabel->ungrabGesture(Qt::TapGesture);
+    }
     
     // presence listener
     mPresenceListener = new CntPresenceListener(*mContact);
     connect(mPresenceListener, SIGNAL(fullPresenceUpdated(bool)), mHeadingItem, SLOT(setOnlineStatus(bool)));
+    connect(mPresenceListener, SIGNAL(accountPresenceUpdated(const QString&, bool)), 
+            this, SLOT(updateItemPresence(const QString&, bool)));
     bool online;
-    mPresenceListener->initialPresences(online);
+    QMap<QString, bool> presences = mPresenceListener->initialPresences(online);
     mHeadingItem->setOnlineStatus(online);
 
-    mImageLabel = static_cast<CntImageLabel*>(document()->findWidget("cnt_contactcard_image"));
-    connect(mImageLabel, SIGNAL(iconClicked()), this, SLOT(doChangeImage()));
-    connect(mImageLabel, SIGNAL(iconLongPressed(const QPointF&)), this, SLOT(drawMenu(const QPointF&)));
+   
     
     // avatar
     QList<QContactAvatar> details = mContact->details<QContactAvatar>();
@@ -295,13 +327,36 @@
             CntContactCardDetailItem* item = new CntContactCardDetailItem(index, mContainerWidget);
 
             connect(item, SIGNAL(clicked()), this, SLOT(onItemActivated()));
-            connect(item, SIGNAL(longPressed(const QPointF&)), this, SLOT(onLongPressed(const QPointF&)));
-   
+            
+            if (!mIsTemporary)
+            {
+                connect(item, SIGNAL(longPressed(const QPointF&)), this, SLOT(onLongPressed(const QPointF&)));
+            }
+            
             if (mContact->isPreferredDetail(dataItem->action(), dataItem->detail()))
             {
                 dataItem->setSecondaryIcon(HbIcon("qtg_mono_favourites"));
                 mPreferredItems.insert(dataItem->action(), item);
             }
+            
+            if (dataItem->detail().definitionName() == QContactOnlineAccount::DefinitionName)
+            {
+                for (int i = 0;i < presences.keys().count();i++)
+                {
+                    QString fullAccount = presences.keys().at(i);
+                    QContactOnlineAccount account = dataItem->detail();
+                    QString currentFullAccount = account.serviceProvider() + ':' + account.accountUri();
+                    if (fullAccount == currentFullAccount)
+                    {
+                        if (presences.values().at(i))
+                        {
+                            dataItem->setSecondaryIcon(HbIcon("qtg_small_online"));
+                        }
+                        mPresenceItems.insert(fullAccount, item);
+                        break;
+                    }
+                }
+            }
          
             item->setDetails(dataItem);
             mContainerLayout->addItem(item);
@@ -355,7 +410,7 @@
                     CntContactCardMapTileDetail* detail = new CntContactCardMapTileDetail;
                     if( detail )
                     {
-                        detail->mContactId = mContact->id().localId();
+                        detail->mContactId = mContact->localId();
                             
                         if( dataItem->titleText() == hbTrId("txt_phob_formlabel_address") )
                         {
@@ -395,8 +450,8 @@
             setAsFavorite = CntFavourite::isMemberOfFavouriteGroup( contactManager(), mContact );
             mHeadingItem->setFavoriteStatus( setAsFavorite ); // if contact is part of favourites group
         }
-        qobject_cast<HbAction *>(document()->findObject("cnt:setasfavorite"))->setVisible( !setAsFavorite );
-        qobject_cast<HbAction *>(document()->findObject("cnt:removefromfavorite"))->setVisible( setAsFavorite );
+        static_cast<HbAction *>(document()->findObject("cnt:setasfavorite"))->setVisible( !setAsFavorite );
+        static_cast<HbAction *>(document()->findObject("cnt:removefromfavorite"))->setVisible( setAsFavorite );
     }
     document()->findWidget("viewToolbar")->setParent(mView);
     document()->findWidget("viewMenu")->setParent(mView);
@@ -410,8 +465,15 @@
     connectAction("cnt:edit", SLOT(editContact()));
     connectAction("cnt:history", SLOT(viewHistory()));
     connectAction("cnt:sendMyCard", SLOT(sendBusinessCard()));
+    connectAction("cnt:addtocontact", SLOT(onAddedToContacts()));
     connectAction("cnt:activityStream", NULL);      // placeholder until this action is implemented (needed to avoid memory leak)
     
+    // disabled until this action is implemented 
+    static_cast<HbAction *>(document()->findObject("cnt:activityStream"))->setEnabled(false);
+        
+    connect(contactManager(), SIGNAL(contactsRemoved(const QList<QContactLocalId>&)), 
+        this, SLOT(contactDeletedFromOtherSource(const QList<QContactLocalId>&)));
+    
     emit viewActivated( mViewManager, aArgs );
 
     CNT_EXIT
@@ -458,7 +520,7 @@
             CntMapTileService::ContactAddressType sourceAddressType =
                     static_cast <CntMapTileService::ContactAddressType>( mAddressList[index]->mAddressType );
              
-            QContactLocalId contactId = mContact->id().localId();
+            QContactLocalId contactId = mContact->localId();
              
             if( mAddressList[index]->mDetailItem != NULL )
             {
@@ -557,7 +619,7 @@
     //If there is no maptile displayed, return immediately
     if( mMaptileLabelList.count() > 0 )
     {
-        QContactLocalId contactId = mContact->id().localId();
+        QContactLocalId contactId = mContact->localId();
         
         QList<QContactAddress> addressDetails = mContact->details<QContactAddress>();
         
@@ -644,6 +706,27 @@
     return maptileLabel;
 }
 
+/*
+* Update the presence status icon of action item with the given accountUri
+*/
+void CntContactCardViewPrivate::updateItemPresence(const QString& accountUri, bool online)
+{
+    CntContactCardDetailItem* item = mPresenceItems.value(accountUri);
+    
+    if (item)
+    {
+        if (online)
+        {
+            mDataContainer->dataItem(item->index())->setSecondaryIcon(HbIcon("qtg_small_online"));
+        }
+        else
+        {
+            mDataContainer->dataItem(item->index())->setSecondaryIcon(HbIcon());
+        }
+        item->setDetails(mDataContainer->dataItem(item->index()));
+    }
+}
+
 void CntContactCardViewPrivate::thumbnailReady(const QPixmap& pixmap, void *data, int id, int error)
 {
     CNT_ENTRY
@@ -656,7 +739,7 @@
         mHeadingItem->setIcon(icon);
         mVCardIcon = new HbIcon(pixmap);
         mImageLabel->clear();
-        mImageLabel->setIcon(icon);
+        mImageLabel->setIcon(pixmap);
     }
     
     CNT_EXIT
@@ -668,14 +751,35 @@
 void CntContactCardViewPrivate::sendToHs()
 {
     QVariantHash preferences;
-    preferences["contactId"] = mContact->id().localId();
+    preferences["contactId"] = mContact->localId();
     
-    XQServiceRequest snd("com.nokia.services.hsapplication.IHomeScreenClient",
+    XQServiceRequest snd("com.nokia.symbian.IHomeScreenClient",
                          "addWidget(QString,QVariantHash)"
                          ,false);
     snd << QString("contactwidgethsplugin");
     snd << preferences;
     snd.send();
+
+    /* 
+    if (mRequest)
+    {
+        delete mRequest;
+        mRequest = 0;
+    }
+         
+    mRequest = mAppManager.create("com.nokia.symbian.IHomeScreenClient", "addWidget(QString,QVariantHash)", false);
+    
+    if (mRequest)
+    {
+        QList<QVariant> args;
+        QVariantHash preferences;
+        preferences["contactId"] = mContact->localId();
+        args << preferences;
+        args << QString("contactwidgethsplugin");
+        mRequest->setArguments(args);
+        mRequest->send();
+    }
+    */
 }
 
 /*!
@@ -721,23 +825,29 @@
 */
 void CntContactCardViewPrivate::deleteContact()
 {    
-    QString name = contactManager()->synthesizedDisplayLabel(*mContact);
+    QString name = contactManager()->synthesizedContactDisplayLabel(*mContact);
+    if (name.isEmpty())
+    {
+        name = hbTrId("txt_phob_list_unnamed");
+    }
     
-    HbMessageBox::question(HbParameterLengthLimiter(hbTrId("txt_phob_info_delete_1")).arg(name), this, SLOT(handleDeleteContact(HbAction*)),
-            hbTrId("txt_common_button_delete"), hbTrId("txt_common_button_cancel"));
+    HbMessageBox::question(HbParameterLengthLimiter(hbTrId("txt_phob_info_delete_1")).arg(name), this, SLOT(handleDeleteContact(int)),
+            HbMessageBox::Delete | HbMessageBox::Cancel);
 }
 
 /*!
 Handle action for deleting a contact
 */
-void CntContactCardViewPrivate::handleDeleteContact(HbAction *action)
+void CntContactCardViewPrivate::handleDeleteContact(int action)
 {
-    HbMessageBox *note = static_cast<HbMessageBox*>(sender());
-    
-    if (note && action == note->actions().first())
+    if (action == HbMessageBox::Delete)
     {
-        contactManager()->removeContact(mContact->localId());
-        mViewManager->back( mArgs );
+        disconnect(contactManager(), SIGNAL(contactsRemoved(const QList<QContactLocalId>&)),
+                this, SLOT(contactDeletedFromOtherSource(const QList<QContactLocalId>&)));
+        
+        contactManager()->removeContact(mContact->localId());  
+        emit backPressed();  
+        mViewManager->back( mArgs, true );
     }
 }
 
@@ -759,7 +869,7 @@
 */
 void CntContactCardViewPrivate::deactivate()
 {
-    mView->removeEventFilter(this);    
+    
 }
 
 /*!
@@ -767,7 +877,8 @@
 */
 void CntContactCardViewPrivate::sendBusinessCard()
 {
-    qDebug() << "CntContactCardViewPrivate::sendBusinessCard - IN";
+    CNT_ENTRY
+    
     // Check if the contact has an image.
     QList<QContactAvatar> avatars = mContact->details<QContactAvatar>();
     bool imageExists( false );
@@ -800,10 +911,11 @@
     
     if ( !imageExists )
     {
-        qDebug() << "CntContactCardViewPrivate::sendBusinessCard without image";
+        CNT_LOG_ARGS("snd vCard without image")
         handleSendBusinessCard( NULL ); // no image
     }
-    qDebug() << "CntContactCardViewPrivate::sendBusinessCard - OUT";
+    
+    CNT_EXIT
 }
 
 /*!
@@ -852,6 +964,15 @@
 */
 void CntContactCardViewPrivate::executeAction(QContact& aContact, const QContactDetail& aDetail, const QString& aAction, CntContactCardDetailItem* aItem)
 {
+    if (mIsExecutingAction)
+    {
+        return;
+    }
+    else
+    {
+        mIsExecutingAction = true;
+    }
+    
     CntActionLauncher* other = new CntActionLauncher(*contactManager(), aAction);
     connect(other, SIGNAL(actionExecuted(CntActionLauncher*)), this, SLOT(actionExecuted(CntActionLauncher*)));
     if (aItem && aContact.preferredDetail(aAction).isEmpty())
@@ -876,6 +997,7 @@
         if (detail == aDetail && action == aAction)
         {
             detailItem = static_cast<CntContactCardDetailItem*>(mContainerLayout->itemAt(index));
+            break;
         }
     }
     executeAction(aContact, aDetail, aAction, detailItem);
@@ -887,6 +1009,15 @@
 */
 void CntContactCardViewPrivate::executeDynamicAction(QContact& aContact, QContactDetail aDetail, QContactActionDescriptor aActionDescriptor)
 {
+    if (mIsExecutingAction)
+    {
+        return;
+    }
+    else
+    {
+        mIsExecutingAction = true;
+    }
+    
     CntActionLauncher* other = new CntActionLauncher(*contactManager());
     connect(other, SIGNAL(actionExecuted(CntActionLauncher*)), this, SLOT(actionExecuted(CntActionLauncher*)));
     other->execute(aContact, aDetail, aActionDescriptor);
@@ -895,6 +1026,7 @@
 void CntContactCardViewPrivate::actionExecuted(CntActionLauncher* aAction)
 {
     aAction->deleteLater();
+    mIsExecutingAction = false;
 }
 
 /*!
@@ -1063,8 +1195,9 @@
 
 void CntContactCardViewPrivate::handleSendBusinessCard( HbAction* aAction )
 {
+    CNT_ENTRY
     Q_UNUSED(aAction);
-    qDebug() << "CntContactCardViewPrivate::handleSendBusinessCard - IN";
+    
     QList<QContact> list;
     /*if ( aAction && aAction->objectName() == "cancel" )
     {
@@ -1111,21 +1244,28 @@
         }   
     }
            
-    QString vCardName = QString(mContact->displayLabel().append(".vcf"));
+    QString vCardName;
+    if ( mContact->displayLabel().isEmpty() ) {
+        vCardName = hbTrId("txt_phob_list_unnamed").append(".vcf");
+    } else
+        vCardName = mContact->displayLabel().append(".vcf");
+    
     QString vCardPath = dir.absolutePath().append(QDir::separator());
     vCardPath.append(vCardName);
     vCardPath = QDir::toNativeSeparators(vCardPath);
-        
+    
     QVersitContactExporter exporter;
+    CntVCardDetailHandler hanlder;
+    exporter.setDetailHandler(&hanlder);
     // The vCard version needs to be 2.1 due to backward compatiblity when sending 
     if (exporter.exportContacts(list, QVersitDocument::VCard21Type))
     {
-        qDebug() << "CntContactCardViewPrivate::handleSendBusinessCard, VCard21Type";
+        CNT_LOG_ARGS("VCard21Type");
         QList<QVersitDocument> docs = exporter.documents();
         QFile f(vCardPath);
         if ( f.open(QIODevice::WriteOnly) ) 
         {
-            qDebug() << "CntContactCardViewPrivate::handleSendBusinessCard write VCard";
+            CNT_LOG_ARGS("write VCard");
             // Start creating the vCard
             QVersitWriter writer;
             writer.setDevice(&f);
@@ -1142,7 +1282,8 @@
             mShareUi->send(l,false);
         }
     }
-    qDebug() << "CntContactCardViewPrivate::handleSendBusinessCard - OUT";
+    
+    CNT_EXIT
 }
 
 
@@ -1186,7 +1327,7 @@
             }
             mAvatar->setImageUrl(QUrl());
             mImageLabel->clear();
-            mImageLabel->setIcon(HbIcon("qtg_large_add_contact_picture"));
+            mImageLabel->setAvatarIcon(HbIcon("qtg_large_add_contact_picture"));
             mHeadingItem->setIcon(HbIcon("qtg_large_add_contact_picture"));
             contactManager()->saveContact(mContact);
         }
@@ -1200,7 +1341,7 @@
 {
     HbMenu *menu = new HbMenu();
     menu->addAction(hbTrId("txt_phob_menu_change_picture"), this, SLOT(doChangeImage()) );
-    if (mAvatar)
+    if (mAvatar && !mAvatar->imageUrl().isEmpty())
     {
         menu->addAction(hbTrId("txt_phob_menu_remove_image"), this, SLOT(doRemoveImage()) );
     }
@@ -1229,17 +1370,24 @@
     return mViewManager->contactManager(SYMBIAN_BACKEND);
 }
 
-void CntContactCardViewPrivate::keyPressed(QKeyEvent *event)
+bool CntContactCardViewPrivate::eventFilter(QObject *obj, QEvent *event)
 {
-    if (event->key() == Qt::Key_Yes )
+    if (event->type() == QEvent::KeyPress && obj == mView->mainWindow())
     {
-        sendKeyPressed();
+        QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
+        if (keyEvent->key() == Qt::Key_Yes)
+        {
+            return sendKeyPressed();
+        }
     }
+    return false;
 }
 
-void CntContactCardViewPrivate::sendKeyPressed()
+bool CntContactCardViewPrivate::sendKeyPressed()
 {   
     int count = 0;
+    bool keyConsumed = false;
+    
     for (int index = 0; index < mDataContainer->itemCount(); index++)
     {
         CntContactCardDataItem* dataItem = mDataContainer->dataItem(index);
@@ -1248,41 +1396,58 @@
             count++;
         }
     }
-    if (!count)
-    {
-        XQServiceRequest snd("com.nokia.services.logsservices.starter", "start(int,bool)", false);
-        snd << 0; // all calls
-        snd << true; // show dialpad
-        snd.send();
-    }
-    else
+
+    if (count)
     {
         QContactDetail preferredDetail = mContact->preferredDetail("call");
         if (!preferredDetail.isEmpty())
         {
-            executeAction(*mContact, preferredDetail, "call", NULL); 
+            keyConsumed = true;
+            executeAction(*mContact, preferredDetail, "call");
         }
         else if (count == 1 )
         {
-           mContact->setPreferredDetail("call", mContact->details<QContactPhoneNumber>().first());
-           executeAction( *mContact, mContact->details<QContactPhoneNumber>().first(), "call", NULL); 
+            keyConsumed = true;
+            executeAction( *mContact, mContact->details<QContactPhoneNumber>().first(), "call"); 
         }
         else if(count >= 2 && mAcceptSendKey)
-        {   
+        {
+            keyConsumed = true;
             mAcceptSendKey = false;
             CntActionPopup *actionPopup = new CntActionPopup(mContact);
             actionPopup->showActionPopup("call");
             connect( actionPopup, SIGNAL(executeContactAction(QContact&, QContactDetail, QString)), this, 
                     SLOT(executeAction(QContact&, QContactDetail, QString)));   
             connect( actionPopup, SIGNAL(actionPopupCancelPressed()), this, 
-                                SLOT(sendKeyCancelSlot()));   
-            
+                    SLOT(sendKeyCancelSlot()));
+        }
+        else
+        {
+            //ignore
         }
     }
+    
+    return keyConsumed;
 }
 
 void CntContactCardViewPrivate::sendKeyCancelSlot()
 {
     mAcceptSendKey = true;
 }
+
+void CntContactCardViewPrivate::onAddedToContacts()
+{
+    emit addToContacts();
+}
+
+void CntContactCardViewPrivate::contactDeletedFromOtherSource(const QList<QContactLocalId>& contactIds)
+{
+    if ( contactIds.contains(mContact->localId()) )
+    {
+        // Do not switch to the previous view immediately. List views are
+        // not updated properly if this is not done in the event loop
+        QTimer::singleShot(0, this, SLOT(showRootView()));
+    }
+}
+
 // end of file