--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingapp/msgui/unifiedviewer/src/univieweraddresswidget.cpp Tue Aug 31 15:11:31 2010 +0300
@@ -0,0 +1,589 @@
+/*
+ * Copyright (c) 2009 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:Custom widget derived from HbTextEdit which provides rich text
+ * processing
+ *
+ */
+
+#include "univieweraddresswidget.h"
+
+// SYSTEM INCLUDES
+#include <QTextCursor>
+#include <QTextBlock>
+#include <QApplication>
+#include <QClipboard>
+
+#include <HbMenu>
+#include <HbAction>
+#include <HbTapGesture>
+
+#include <xqservicerequest.h>
+#include <xqappmgr.h>
+#include <cntservicescontact.h>
+#include <qtcontacts.h>
+#include <xqservicerequest.h>
+#include <xqaiwrequest.h>
+#include "msgcontacthandler.h"
+
+// LOCAL CONSTANTS
+const QString ADDRESS_SEPARATOR("; ");
+const QString ADDRESS_OPEN(" (");
+const QString ADDRESS_CLOSE(")");
+const QString SPACE(" ");
+
+//localization
+#define LOC_CONTACT_INFO hbTrId("txt_messaging_menu_contact_info")
+#define LOC_CALL hbTrId("txt_common_menu_call_verb")
+#define LOC_SEND_MESSAGE hbTrId("txt_common_menu_send_message")
+#define LOC_SAVE_TO_CONTACTS hbTrId("txt_common_menu_save_to_contacts")
+#define LOC_COPY hbTrId("txt_common_menu_copy")
+
+const QString BG_FRAME_GRAPHICS("qtg_fr_lineedit_normal");
+
+//---------------------------------------------------------------
+// UniViewerAddressWidget::UniViewerAddressWidget
+// @see header file
+//---------------------------------------------------------------
+UniViewerAddressWidget::UniViewerAddressWidget(QGraphicsItem * parent) :
+HbTextEdit(parent),
+mCursorPos(-1)
+{
+ this->setReadOnly(true);
+ this->setScrollable(false);
+ this->setFlag(QGraphicsItem::ItemIsFocusable,false);
+ this->setCursorVisibility(Hb::TextCursorHidden);
+ this->setBackgroundItem(0);
+
+ HbFontSpec fontSpec(HbFontSpec::Secondary);
+ QFont font = fontSpec.font();
+ this->setFont(font);
+
+ mFormatNormal.setForeground(palette().link());
+ mFormatNormal.setBackground(Qt::transparent);
+
+ mFormatHighlight.setBackground(palette().highlight());
+ mFormatHighlight.setForeground(palette().highlightedText());
+
+ connect(this, SIGNAL(aboutToShowContextMenu(HbMenu*,QPointF)),
+ this, SLOT(aboutToShowContextMenu(HbMenu*,QPointF)));
+}
+
+//---------------------------------------------------------------
+// UniViewerAddressWidget::~UniViewerAddressWidget
+// @see header file
+//---------------------------------------------------------------
+UniViewerAddressWidget::~UniViewerAddressWidget()
+{
+}
+
+//---------------------------------------------------------------
+//UniViewerAddressWidget :: gestureEvent
+// @see header file
+//---------------------------------------------------------------
+void UniViewerAddressWidget::gestureEvent(QGestureEvent* event)
+{
+ //handle gesture to highlight and dehighlight find item.
+
+ if(HbTapGesture *tap = qobject_cast<HbTapGesture*>(event->gesture(Qt::TapGesture)))
+ {
+ //capturing gesture position, and map to local co-ordinates.
+ QPointF pos = mapFromScene(tap->scenePosition());
+
+ switch (tap->state())
+ {
+ case Qt::GestureStarted:
+ {
+ //highlight find item.
+ QTextDocument* doc = this->document();
+ mCursorPos = doc->documentLayout()->hitTest(pos, Qt::ExactHit);
+ highlightText(true);
+ break;
+ }
+
+ case Qt::GestureFinished:
+ {
+ if (HbTapGesture::Tap == tap->tapStyleHint())
+ {
+ //gesture is finshed dehighlight text.
+ highlightText(false);
+
+ QString anchor = this->anchorAt(pos);
+
+ //do short tap action.
+ if (!anchor.isEmpty() && !this->textCursor().hasSelection())
+ {
+ shortTapAction(anchor,tap->scenePosition());
+ }
+ }
+ break;
+ }
+
+ case Qt::GestureCanceled:
+ {
+ //gesture is canceled due to pan or swipe, dehighlight text.
+ if (HbTapGesture::Tap == tap->tapStyleHint())
+ {
+ highlightText(false);
+ break;
+ }
+ }
+ default:
+ break;
+ }
+
+ event->accept();
+ }
+ else
+ {
+ event->ignore();
+ }
+
+ //passing gesture event to base class.
+ HbTextEdit::gestureEvent(event);
+}
+
+
+//----------------------------------------------------------------------------
+// UniViewerAddressWidget::populate
+// @see header file
+//----------------------------------------------------------------------------
+void UniViewerAddressWidget::populate(const QString &label,
+ const QString &address,
+ const QString &alias)
+{
+ QString labelText = label;
+ labelText.trimmed();
+ labelText += SPACE;
+
+ //Font.
+ HbFontSpec fontSpec(HbFontSpec::Secondary);
+ qreal fontHeight = 0.0;
+ style()->parameter("hb-param-text-height-tiny", fontHeight);
+ fontSpec.setTextHeight(fontHeight);
+ QFont font = fontSpec.font();
+
+ QTextCharFormat labelFormat;
+ labelFormat.setFont(font);
+
+ QTextCharFormat addressFormat;
+ addressFormat.setForeground(palette().link());
+ addressFormat.setFontUnderline(true);
+
+ // Insert the label then the addresses
+ QTextCursor cursor(this->textCursor());
+ cursor.insertText(labelText,labelFormat);
+
+ QString address1 = QString();
+ if (!(alias.isEmpty()))
+ {
+ address1.append(alias);
+ QString alias1 = QString();
+
+ int totalNumbers = 0;
+ MsgContactHandler::resolveContactDisplayName(
+ address,
+ alias1,
+ totalNumbers);
+ if (totalNumbers > 1)
+ {
+ address1.append(ADDRESS_OPEN);
+ address1.append(address);
+ address1.append(ADDRESS_CLOSE);
+ }
+ }
+ else
+ {
+ address1.append(address);
+ }
+ addressFormat.setAnchorHref(address);
+ cursor.insertText(address1, addressFormat);
+}
+
+//----------------------------------------------------------------------------
+// UniViewerAddressWidget::populate
+// @see header file
+//----------------------------------------------------------------------------
+void UniViewerAddressWidget::populate(const QString &label,
+ ConvergedMessageAddressList addressList)
+{
+ QString labelText = label;
+ labelText.trimmed();
+ labelText += SPACE;
+
+ //Font.
+ HbFontSpec fontSpec(HbFontSpec::Secondary);
+ qreal fontHeight = 0.0;
+ style()->parameter("hb-param-text-height-tiny", fontHeight);
+ fontSpec.setTextHeight(fontHeight);
+ QFont font = fontSpec.font();
+
+ QTextCharFormat labelFormat;
+ labelFormat.setFont(font);
+
+ QTextCharFormat defaultFormat;
+ defaultFormat.setForeground(palette().link());
+
+ QTextCharFormat addressFormat;
+ addressFormat.setForeground(palette().link());
+ addressFormat.setFontUnderline(true);
+
+ // Insert the label then the addresses
+ QTextCursor cursor(this->document());
+ cursor.insertText(labelText,labelFormat);
+
+ int addressCount = addressList.count();
+
+ for (int i = 0; i < addressCount; ++i)
+ {
+
+ QString address = QString();
+ if (! (addressList[i]->alias().isEmpty()))
+ {
+ address.append(addressList[i]->alias());
+ QString alias = QString();
+
+ int totalNumbers = 0;
+ MsgContactHandler::resolveContactDisplayName(
+ addressList[i]->address(),
+ alias,
+ totalNumbers);
+ if (totalNumbers > 1)
+ {
+ address.append(ADDRESS_OPEN);
+ address.append(addressList[i]->address());
+ address.append(ADDRESS_CLOSE);
+ }
+ }
+ else
+ {
+ address.append(addressList[i]->address());
+ }
+
+ addressFormat.setAnchorHref(addressList[i]->address());
+ cursor.insertText(address, addressFormat);
+
+ if (addressCount - 1 != i)
+ {
+ cursor.insertText(ADDRESS_SEPARATOR, defaultFormat);
+ }
+
+ }
+}
+
+//----------------------------------------------------------------------------
+// UniViewerAddressWidget::clearContent
+// @see header file
+//----------------------------------------------------------------------------
+void UniViewerAddressWidget::clearContent()
+{
+ this->document()->clear();
+}
+
+//----------------------------------------------------------------------------
+// UniViewerAddressWidget::menuClosed
+// @see header file
+//----------------------------------------------------------------------------
+void UniViewerAddressWidget::menuClosed()
+{
+ highlightText(false);
+}
+
+//----------------------------------------------------------------------------
+// UniViewerAddressWidget::highlightText
+// @see header file
+//----------------------------------------------------------------------------
+void UniViewerAddressWidget::highlightText(bool highlight)
+{
+ QTextBlock textBlock = this->document()->findBlock(mCursorPos);
+
+ QTextBlock::iterator it;
+
+ for (it = textBlock.begin(); !(it.atEnd()); ++it)
+ {
+ QTextFragment currentFragment = it.fragment();
+
+ if (currentFragment.isValid() && currentFragment.contains(mCursorPos)
+ && currentFragment.charFormat().fontUnderline())
+ {
+ int start = currentFragment.position();
+ int length = currentFragment.length();
+
+ QTextCursor cursor = this->textCursor();
+ cursor.clearSelection();
+ cursor.setPosition(start);
+ cursor.setPosition(start + length,QTextCursor::KeepAnchor);
+
+ if(highlight)
+ {
+ cursor.mergeCharFormat(mFormatHighlight);
+ }
+ else
+ {
+ cursor.mergeCharFormat(mFormatNormal);
+ }
+
+ cursor.clearSelection();
+ break;
+ }
+ }
+}
+
+void UniViewerAddressWidget::aboutToShowContextMenu(HbMenu *contextMenu, const QPointF &pos)
+{
+ //remove default actions.
+ contextMenu->clearActions();
+
+ // Check if there is an anchor at this pos
+ QString anchor = this->anchorAt(pos);
+
+ if(!anchor.isEmpty() && !this->textCursor().hasSelection())
+ {
+ populateMenu(contextMenu,anchor);
+ }
+}
+
+void UniViewerAddressWidget::populateMenu(HbMenu* contextMenu,const QString& data)
+{
+ HbAction* action = NULL;
+
+ int contactId = MsgContactHandler::resolveContactDisplayName(
+ data,
+ QContactPhoneNumber::DefinitionName,
+ QContactPhoneNumber::FieldNumber);
+
+ if(contactId > 0)
+ {
+ action = contextMenu->addAction(LOC_CONTACT_INFO, this, SLOT(openContactInfo()));
+ action->setData(data);
+ }
+ else
+ {
+ action = contextMenu->addAction(LOC_SAVE_TO_CONTACTS, this, SLOT(saveToContacts()));
+ action->setData(data);
+ }
+
+ action = contextMenu->addAction(LOC_CALL, this, SLOT(call()));
+ action->setData(data);
+
+ action = contextMenu->addAction(LOC_SEND_MESSAGE, this, SLOT(sendMessage()));
+ action->setData(data);
+
+ action = contextMenu->addAction(LOC_COPY, this, SLOT(copyToClipboard()));
+ action->setData(data);
+
+ connect(contextMenu,SIGNAL(aboutToClose()),this,SLOT(menuClosed()));
+}
+
+void UniViewerAddressWidget::shortTapAction(QString anchor,const QPointF& pos)
+{
+ HbAction action;
+ action.setData(anchor);
+
+
+ int contactId = MsgContactHandler::resolveContactDisplayName(
+ anchor,
+ QContactPhoneNumber::DefinitionName,
+ QContactPhoneNumber::FieldNumber);
+
+ if(contactId > 0 )
+ {
+ //if resolved conatct open contact card
+ connect(&action,SIGNAL(triggered()),this,SLOT(openContactInfo()));
+ }
+ else
+ {
+ //unresolved contact show popup.
+ highlightText(true);
+
+ HbMenu* contextMenu = new HbMenu();
+ contextMenu->setDismissPolicy(HbPopup::TapAnywhere);
+ contextMenu->setAttribute(Qt::WA_DeleteOnClose, true);
+ contextMenu->setPreferredPos(pos);
+
+ populateMenu(contextMenu,anchor);
+
+ contextMenu->show();
+ }
+
+ action.trigger();
+}
+
+void UniViewerAddressWidget::copyToClipboard()
+{
+ HbAction* action = qobject_cast<HbAction*>(sender());
+
+ if(action)
+ {
+ QMimeData* data = new QMimeData();
+ QString str = action->data().toString();
+ data->setText(str);
+ QApplication::clipboard()->setMimeData(data);
+ }
+}
+
+void UniViewerAddressWidget::call()
+{
+ HbAction* action = qobject_cast<HbAction*>(sender());
+
+ if(action)
+ {
+ QString phoneNumber = action->data().toString();
+
+ //invoke dialer service and pass phoneNumber.
+ QString serviceName("com.nokia.symbian.ICallDial");
+ QString operation("dial(QString)");
+
+ XQServiceRequest* serviceRequest = new XQServiceRequest(serviceName,operation,false);
+
+ connect(serviceRequest, SIGNAL(requestCompleted(QVariant)),
+ this, SLOT(onServiceRequestCompleted()));
+
+ connect(serviceRequest, SIGNAL(requestError(int)),
+ this, SLOT(onServiceRequestCompleted()));
+
+ *serviceRequest << phoneNumber;
+ serviceRequest->send();
+ }
+}
+
+void UniViewerAddressWidget::onServiceRequestCompleted()
+ {
+ //service request is now complete. delete it.
+ XQServiceRequest* request = qobject_cast<XQServiceRequest*>(sender());
+
+ if(request)
+ {
+ delete request;
+ }
+ }
+
+
+void UniViewerAddressWidget::openContactInfo()
+{
+ HbAction* action = qobject_cast<HbAction*>(sender());
+
+ if(action)
+ {
+ QList<QVariant> args;
+ QString operation;
+
+ QString data = action->data().toString();
+
+ int contactId = MsgContactHandler::resolveContactDisplayName(
+ data,
+ QContactPhoneNumber::DefinitionName,
+ QContactPhoneNumber::FieldNumber);
+
+ // if contact is unresolved on phone number field
+ // then, try resolving it on email address field
+ if(contactId <= 0)
+ {
+ contactId = MsgContactHandler::resolveContactDisplayName(
+ data,
+ QContactEmailAddress::DefinitionName,
+ QContactEmailAddress::FieldEmailAddress);
+ }
+
+ if(contactId > 0)
+ {
+ //open contact card
+ operation = QString("open(int)");
+ args << contactId;
+ }
+ else
+ {
+ //save to contacts with phone number field prefilled.
+
+ operation = QString("editCreateNew(QString,QString)");
+ QString type = QContactPhoneNumber::DefinitionName;
+
+ args << type;
+ args << data;
+ }
+
+ //service stuff.
+ QString serviceName("com.nokia.services.phonebookservices");
+
+ XQAiwRequest* request;
+ XQApplicationManager appManager;
+ request = appManager.create(serviceName, "Fetch", operation, true); // embedded
+ if ( request == NULL )
+ {
+ return;
+ }
+
+ // Result handlers
+ connect (request, SIGNAL(requestOk(const QVariant&)),
+ this, SLOT(handleOk(const QVariant&)));
+ connect (request, SIGNAL(requestError(const QVariant&)),
+ this, SLOT(handleError(const QVariant&)));
+
+ request->setArguments(args);
+ request->send();
+ delete request;
+ }
+}
+
+void UniViewerAddressWidget::handleOk(const QVariant& result)
+ {
+ Q_UNUSED(result)
+ }
+
+void UniViewerAddressWidget::handleError(int errorCode, const QString& errorMessage)
+ {
+ Q_UNUSED(errorMessage)
+ Q_UNUSED(errorCode)
+ }
+
+void UniViewerAddressWidget::saveToContacts()
+{
+ openContactInfo();
+}
+
+void UniViewerAddressWidget::sendMessage()
+{
+ HbAction* action = qobject_cast<HbAction*>(sender());
+
+ if(action)
+ {
+ QString phoneNumber = action->data().toString();
+ QString alias;
+
+ QTextBlock textBlock = this->document()->findBlock(mCursorPos);
+
+ QTextBlock::iterator it;
+
+ for (it = textBlock.begin(); !(it.atEnd()); ++it)
+ {
+ QTextFragment currentFragment = it.fragment();
+
+ if (currentFragment.isValid() && currentFragment.contains(mCursorPos)
+ && currentFragment.charFormat().fontUnderline())
+ {
+ QString txt = currentFragment.text();
+ if(txt != phoneNumber)
+ {
+ alias = txt;
+ }
+ break;
+ }
+ }
+
+
+ //invoke editor & pass phoneNumber.
+ emit sendMessage(phoneNumber,alias);
+ }
+}
+
+// EOF