contactwidgethsplugin/contactwidgeths/src/commlauncherwidget.cpp
branchRCL_3
changeset 62 5b6f26637ad3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contactwidgethsplugin/contactwidgeths/src/commlauncherwidget.cpp	Tue Aug 31 15:05:21 2010 +0300
@@ -0,0 +1,553 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Communication Launcher widget for Friend widget 
+*
+*/
+
+#include <QDebug>
+#include <HbStyleLoader>
+#include <QGraphicsLinearLayout>
+#include <HbEffect>
+#include <HbPushButton>
+#include <qtcontacts.h>
+#include <hbdocumentloader.h>
+#include <xqappmgr.h>
+
+#include "commlauncherwidget.h"
+
+// ContactManager backend
+#ifdef Q_OS_SYMBIAN
+    QString cmBackend = "symbian";
+#else
+    QString cmBackend = "memory"; 
+#endif
+const QString commLauncherDocml = ":/commlauncherwidget.docml";
+// Note: these are case sensitive
+const QString callButtonName     = "ButtonCall";
+const QString emailButtonName    = "ButtonEmail";
+const QString messageButtonName  = "ButtonMessage";
+const QString mycardButtonName   = "ButtonMycard";
+
+const QString appearTL = "appear_tl";
+const QString appearTR = "appear_tr";
+const QString appearBL = "appear_bl";
+const QString appearBR = "appear_br"; 
+
+const int commLauncherMargin = 120;  // heights of titlebar & comm.launcher 
+
+/*!
+  \class CommLauncherWidget
+*/
+
+/*!
+    Constructor
+*/
+CommLauncherWidget::CommLauncherWidget(QGraphicsItem *parent) :
+ HbPopup(parent),
+ mContact(0),
+ mButtonCount(0),
+ mRequest(NULL),
+ mCallButton(0),
+ mSendMsgButton(0),
+ mEmailButton(0),
+ mPhonebookButton(0),
+ mApplicationManager(0)
+{    
+    
+    HbStyleLoader::registerFilePath(":/commlauncherbuttons.css");
+    // effect triggers
+    connect(this, SIGNAL(aboutToShow()),  SLOT(popupAboutToShow()));
+    connect(this, SIGNAL(aboutToClose()), SLOT(popupAboutToClose()));
+    
+    // create layout
+    mLayout = new QGraphicsLinearLayout(this);
+    qreal verticalMargin = 0.0;
+    style()->parameter("hb-param-margin-gene-middle-vertical", verticalMargin);
+    qreal horizontalMargin = 0.0;
+    style()->parameter("hb-param-margin-gene-middle-horizontal", horizontalMargin);
+    
+    mLayout->setContentsMargins(horizontalMargin, verticalMargin,
+                                horizontalMargin, 2*verticalMargin);
+    
+    // create document loader
+    HbDocumentLoader *documentLoader = new HbDocumentLoader();
+    bool result = false;
+    documentLoader->load(commLauncherDocml, &result);
+    ASSERT(result);
+    
+    // create buttons
+    const QString callIconName = "qtg_large_active_call";
+    mCallButton = createButton(callIconName, callButtonName, documentLoader);
+    connect(mCallButton, SIGNAL(clicked()), this, SLOT(makeCall()));
+    
+    const QString messagingIconName = "qtg_large_message";
+    mSendMsgButton = createButton(messagingIconName, messageButtonName, documentLoader);
+    connect(mSendMsgButton, SIGNAL(clicked()), this, SLOT(sendMessage()));
+    
+    const QString emailIconName = "qtg_large_email";
+    mEmailButton = createButton(emailIconName, emailButtonName, documentLoader);
+    // EMAIL FUNCTIONALITY COMMENTED OUT BECAUSE PLATFORM DOES NOT SUPPORT IT!
+    //connect(mEmailButton, SIGNAL(clicked()), this, SLOT(sendEmail()));
+    
+    const QString phonebookIconName = "qtg_large_mycard";
+    mPhonebookButton = createButton(phonebookIconName, mycardButtonName, documentLoader);
+    connect(mPhonebookButton, SIGNAL(clicked()), this, SLOT(openPhonebook()));
+        
+    delete documentLoader;
+}
+
+/*!
+    Destructor
+*/
+CommLauncherWidget::~CommLauncherWidget()
+{
+    // Deleting request cancels all pending requests 
+    if (mRequest) {
+        delete mRequest;
+        mRequest = NULL;
+    }
+
+}
+
+/*!
+    Sets the contact for the widget
+*/
+void CommLauncherWidget::setContact(QContact &contact)
+{
+    mContact = &contact;
+}
+
+/*!
+    Sets the application manager for the widget
+*/
+void CommLauncherWidget::setApplicationManager(XQApplicationManager &appManager)
+{
+    mApplicationManager = &appManager;
+}
+
+/*!
+    Creates the UI for the widget
+*/
+void CommLauncherWidget::createUI()
+{        
+    mButtonCount = 0;
+    // Create call button, if number is available
+    QList<QContactActionDescriptor> callActionDescriptors = 
+            QContactAction::actionDescriptors("call", cmBackend);
+    if (callActionDescriptors.count() > 0) {
+        QList<QContactPhoneNumber> numberList = mContact->details<QContactPhoneNumber>();
+        if (numberList.count() > 0) {
+            mLayout->addItem(mCallButton);
+            mCallButton->show();
+            mButtonCount++;
+
+        } else {
+            mCallButton->hide();
+            mLayout->removeItem(mCallButton);
+            mLayout->invalidate();
+            mLayout->activate();
+        }
+    } else {
+        qDebug() << "Call button is not created";
+    }
+    
+    // Create sms button, if number is available
+    QList<QContactActionDescriptor> messageActionDescriptors =
+            QContactAction::actionDescriptors("message", cmBackend);
+    if (messageActionDescriptors.count() > 0) {
+        QList<QContactPhoneNumber> numberList = mContact->details<QContactPhoneNumber>();
+        if (numberList.count() > 0) {
+            mLayout->addItem(mSendMsgButton);
+            mSendMsgButton->show();
+            mButtonCount++;
+        } else {
+            mSendMsgButton->hide();
+            mLayout->removeItem(mSendMsgButton);
+            mLayout->invalidate();
+            mLayout->activate();
+        }
+    } else {
+        qDebug() << "Sms button is not created";
+    }
+        
+    // Create email button, if email count exists
+    // EMAIL FUNCTIONALITY COMMENTED OUT BECAUSE PLATFORM DOES NOT SUPPORT IT!
+    /*QList<QContactActionDescriptor> emailActionDescriptors =
+            QContactAction::actionDescriptors("email", cmBackend);
+    if (emailActionDescriptors.count() > 0) {
+        QList<QContactEmailAddress> emailList = mContact->details<QContactEmailAddress>();
+        if (emailList.count() > 0) {
+            mLayout->addItem(mEmailButton);
+            mEmailButton->show();
+            mButtonCount++;
+        } else {
+            mEmailButton->hide();
+            mLayout->removeItem(mEmailButton);
+            mLayout->invalidate();
+            mLayout->activate();
+        }
+    } else {
+        qDebug() << "Email button not created";
+    }
+    */
+
+    mLayout->addItem(mPhonebookButton);
+    mButtonCount++;
+
+    // add Effects
+    HbEffect::add(this, QString(":/friend_expand_tl.fxml"), appearTL);
+    HbEffect::add(this, QString(":/friend_expand_tr.fxml"), appearTR);
+    HbEffect::add(this, QString(":/friend_expand_bl.fxml"), appearBL);
+    HbEffect::add(this, QString(":/friend_expand_br.fxml"), appearBR);       
+    HbEffect::add(this, QString(":/friend_minimize.fxml"),  "disappear");
+    
+    setLayout(mLayout);    
+}
+
+/*!
+    This widget is about to show, show effect
+*/
+void CommLauncherWidget::popupAboutToShow()
+{ 
+    HbEffect::start(this, mAppearEffect);  
+}
+
+/*
+ * Select which appear effect to use depending on FriendWidget position
+ */
+void CommLauncherWidget::selectAppearEffect(QPointF FriendPos, QPointF LauncherPos)
+{
+    bool left=true;
+    bool top=true;
+    
+    qDebug() << "FriendPos "   << FriendPos;
+    qDebug() << "LauncherPos " << LauncherPos;
+    
+    if (LauncherPos.y() > FriendPos.y()) {
+        top = false;
+    }
+    if (LauncherPos.x() > FriendPos.x()) {
+        left = false;
+    }	
+
+    if (top && left) {
+        mAppearEffect = appearTL;
+    }
+    else if (top && !left) {
+        mAppearEffect = appearTR;
+    }
+    else if (!top && left) {
+        mAppearEffect = appearBL;
+    }
+    else {
+        mAppearEffect = appearBR;
+    }
+    qDebug() << "---------------top " << top << "--- left " << left << " " << mAppearEffect;
+}
+
+/*!
+    This widget is about to close, show effect
+*/
+void CommLauncherWidget::popupAboutToClose()
+{
+    HbEffect::start(this, "disappear");  
+    emit launcherClosed();
+}
+
+/*!
+    Returns a button with a given name and icon to layout
+*/
+HbPushButton* CommLauncherWidget::createButton(const QString iconName, const QString buttonName,
+                                               const HbDocumentLoader *documentLoader)
+{
+    HbPushButton *button = 0;
+    button = qobject_cast<HbPushButton *>
+                    (documentLoader->findWidget(buttonName));
+    if (button) {
+        button->setIcon(HbIcon(iconName));
+    }
+
+    return button;
+}
+
+  
+/*!
+    Returns screen position for communication launcher for a widget
+*/
+QPointF CommLauncherWidget::commLauncherPosition(QPointF widgetPosition, QRectF& widgetBoundingRect,
+                                              QRectF& sceneRect, QRectF& launcherRect)
+{    
+    QPointF commLauncherPosition(widgetPosition.x(), commLauncherMargin);        
+    qDebug() << "friend widgetPosition " << widgetPosition.x() << widgetPosition.y();
+    
+    qreal topMargin = 0.0; 
+    style()->parameter("hb-param-margin-gene-top",topMargin);
+    qDebug() << "topMargin------------ " << topMargin;
+    qDebug() << "launcher size.y " << launcherRect.size().height();
+    
+    // Calculate vertical position
+    if (widgetPosition.y() > commLauncherMargin) {
+        commLauncherPosition.setY(widgetPosition.y() - launcherRect.size().height() + topMargin );
+    } else {
+        commLauncherPosition.setY(widgetPosition.y() + widgetBoundingRect.height() 
+                                  - launcherRect.size().height()/2);
+    }
+        
+    // Calculate horizontal position
+    if ((widgetPosition.x() + widgetBoundingRect.width()/2) < sceneRect.width()/2 ) {
+        // Communication launcher to the right
+        qDebug() << "launcher to right";
+        commLauncherPosition.setX(widgetPosition.x() + widgetBoundingRect.width()/2);
+        
+    } else {
+        // Communication launcher to the left
+        qDebug() << "launcher to left";
+        // The width needs to be calculated based on visible buttons.
+        launcherRect.setWidth(commLauncherWidth());
+        commLauncherPosition.setX(widgetPosition.x() + widgetBoundingRect.width()/2 
+        		                  - launcherRect.size().width());
+    }
+    
+    // Check that the communication launcher is not positioned outside the scene in y-axis
+    // HbPopup takes care that the launcher is not positioned outside the scene in x-axis
+    if (commLauncherPosition.y() > sceneRect.height()) {
+        commLauncherPosition.setY(sceneRect.height());
+    } else if (commLauncherPosition.y() < sceneRect.y()){
+        commLauncherPosition.setY(sceneRect.y());
+    }
+    
+    qDebug() << "commLauncherPosition " << commLauncherPosition.x() << commLauncherPosition.y();
+    return commLauncherPosition;
+}
+
+
+/*!
+    Makes a phone call to contact.
+*/
+void CommLauncherWidget::makeCall()
+{
+    QList<QContactActionDescriptor> callActionDescriptors = 
+                QContactAction::actionDescriptors("call", cmBackend); 
+    if (callActionDescriptors.count() > 0) {
+        //Get preferred number
+        QContactDetail detail = mContact->preferredDetail("call");
+        QContactPhoneNumber phoneNumber;
+            
+        //If preferred number is available, cast it to phonenumber
+        if(!detail.isEmpty()) {
+            phoneNumber = static_cast<QContactPhoneNumber>(detail);
+        } else {
+            //if preferred is not set select the first number
+            phoneNumber = mContact->detail<QContactPhoneNumber>();
+        }
+        // invoke action
+        QContactAction *callAction = QContactAction::action(callActionDescriptors.at(0));
+        if (!phoneNumber.isEmpty()) {
+            callAction->invokeAction(*mContact, phoneNumber);
+            
+            qDebug() << "call to number " << phoneNumber.number();
+        }
+    } else {
+        qDebug() << "contact has no Actions, can't make a call";
+    }
+    
+    close();
+}
+
+/*!
+    Sends a message to contact.
+*/
+void CommLauncherWidget::sendMessage()
+{
+    QList<QContactActionDescriptor> messageActionDescriptors = 
+                    QContactAction::actionDescriptors("message", cmBackend); 
+    if (messageActionDescriptors.count() > 0) {
+        //Get preferred message number
+        QContactDetail detail = mContact->preferredDetail("message");
+        QContactPhoneNumber messageNumber;
+            
+        //If preferred number is available, cast it to phonenumber
+        if(!detail.isEmpty()) {
+            messageNumber = static_cast<QContactPhoneNumber>(detail);
+        } else {
+            //if preferred is not set select the first number
+            messageNumber = mContact->detail<QContactPhoneNumber>();
+        }
+        // invoke action
+        QContactAction *messageAction = QContactAction::action(messageActionDescriptors.at(0));
+        if (!messageNumber.isEmpty()) {
+            messageAction->invokeAction(*mContact, messageNumber);
+            
+            qDebug() << "send to number " << messageNumber.number();
+        }
+    } else {
+        qDebug() << "contact has no Actions, can't send a message";
+    }
+    
+    close();
+}
+
+/*!
+    Sends an email to contact.
+*/
+// EMAIL FUNCTIONALITY COMMENTED OUT BECAUSE WK20 PLATFORM DOES NOT SUPPORT IT!
+
+/*
+void CommLauncherWidget::sendEmail()
+{
+
+    QList<QContactActionDescriptor> emailActionDescriptors =
+                QContactAction::actionDescriptors("email", cmBackend);
+    if (emailActionDescriptors.count() > 0) {
+        QContactAction *emailAction = QContactAction::action(emailActionDescriptors.at(0));
+    //TODO: implement
+        QList<QContactEmailAddress> emailList = mContact->details<QContactEmailAddress>();
+        if (emailList.count() > 0) {
+            emailAction->invokeAction(*mContact, emailList.at(0));
+       
+            QString emailAddress = emailList.at(0).emailAddress();
+            qDebug() << "send to email " << emailAddress;
+        }
+    } else {
+        qDebug() << "contact has no Actions, can't send a email";
+    }
+
+    // Deleting request cancels all pending requests
+    if (mRequest) {
+        delete mRequest;
+        mRequest = NULL;
+    }
+    
+    QMap<QString, QVariant> map;
+    static const QString emailSendToKey = "to";
+    QString emailAddress;
+    QList<QContactEmailAddress> emailList = mContact->details<QContactEmailAddress>();    
+    if (emailList.count() > 0) {
+        emailAddress = emailList.at(0).emailAddress();
+    }
+    
+    // Add to recipient:
+    map.insert(emailSendToKey, QVariant::fromValue(emailAddress));
+    QVariant mapAsVariant = QVariant::fromValue(map);
+    
+    mRequest = mApplicationManager->create("com.nokia.symbian.IMessage",
+                                           "Send", "send(QVariant)", false);
+    if (mRequest) {
+        mRequest->setSynchronous(false);
+        QList<QVariant> arguments;
+        arguments.append(mapAsVariant);
+        mRequest->setArguments(arguments);
+        bool result = mRequest->send();
+        if (!result) {
+            qDebug() << "Sending request failed: " << mRequest->lastErrorMessage();
+        }
+    } else {
+            qDebug() << "Creating service request failed";
+    }
+    
+    close();
+}
+*/
+
+/*!
+    Opens contact card from phonebook to contact.
+*/
+void CommLauncherWidget::openPhonebook()
+{
+    // Deleting request cancels all pending requests
+    if (mRequest) {
+        delete mRequest;
+        mRequest = NULL;
+    }
+    mRequest = mApplicationManager->create("com.nokia.services.phonebookservices",
+                                           "Fetch", "open(int)", false);
+    if (mRequest) {
+        mRequest->setSynchronous(false);
+        QList<QVariant> arguments;
+        arguments.append(QVariant(mContact->localId()));
+        mRequest->setArguments(arguments);
+        bool result = mRequest->send();
+        if (!result) {
+            qDebug() << "Sending request failed: " << mRequest->lastErrorMessage();
+        }
+    } else {
+        qDebug() << "Creating service request failed";
+    }
+    
+    close();
+}
+
+/*!
+    Opens phonebook to create a new contact.
+*/
+void CommLauncherWidget::openPhonebookCreateNew()
+{
+    // Deleting request cancels all pending requests
+    if (mRequest) {
+        delete mRequest;
+        mRequest = NULL;
+    }
+    mRequest = mApplicationManager->create("com.nokia.services.phonebookservices",
+                                           "Fetch", "editCreateNew(QString,QString)", false);
+    if (mRequest) {
+        QList<QVariant> arguments;
+        QString type = QContactPhoneNumber::DefinitionName;
+        arguments.append(QVariant( type ));
+        arguments.append(QVariant( "" ));        
+        mRequest->setArguments(arguments);
+   
+        bool result = mRequest->send();
+        if (!result) {
+            qDebug() << "Sending request failed: " << mRequest->lastErrorMessage();
+        }
+    
+    } else {
+        qDebug() << "Creating service request failed";
+    }
+}
+
+/*!
+    Handles call key events
+*/
+void CommLauncherWidget::keyPressEvent(QKeyEvent *event)
+{
+	qDebug() << "keyPressEvent event=" << event->key();
+    if (event->key() == Qt::Key_Yes) {
+        // Call key initializes a call
+        makeCall();
+        event->accept();
+    } else {
+      close();
+      //HbPopup::keyPressEvent(event);
+    } 
+}
+
+/*!
+    Counts the width for the launcher. 
+    The width is not known before the launcher is drawn for the first time.
+*/
+int CommLauncherWidget::commLauncherWidth()
+{
+    int width = 0;    
+    qreal verticalMargin = 0.0;
+    style()->parameter("hb-param-margin-gene-middle-vertical", verticalMargin);
+    qreal unit = HbDeviceProfile::current().unitValue(); 
+    const int buttonSize = 9 * unit;
+    
+    width = mButtonCount * buttonSize + (mButtonCount + 1) * verticalMargin;
+    
+    return width;
+}
+
+