--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingapp/msgui/unifiedviewer/src/univiewertextitem.cpp Fri Apr 16 14:56:15 2010 +0300
@@ -0,0 +1,530 @@
+/*
+ * 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:
+ * Message body preview class.
+ * has in built logic for finding phone number, email, url.
+ *
+ */
+
+#include "univiewertextitem.h"
+
+#include <QRegExp>
+#include <QGraphicsSceneMouseEvent>
+#include <QApplication>
+#include <QClipboard>
+#include <QTextBlock>
+
+#include <HbMenu>
+#include <HbAction>
+#include <cntservicescontact.h>
+#include <qtcontacts.h>
+#include <XQServiceRequest.h>
+
+
+QTM_USE_NAMESPACE
+
+//consts
+
+//regexp
+const QString NUMBER_PATTERN("(\\(|\\+|\\d)((?:\\d{2,})((?:[\\s-/.\\)\\()])*(?:(\\d+|\\))))*)|((\\*#)(?:\\d+(\\*|#)(?:\\d+#)?))");
+
+const QString EMAIL_PATTERN("[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?");
+
+const QString URL_PATTERN("(((ht|f|rt)(tp|sp)(s?)\\:\\/\\/)|(www|wap)(?:\\.))(([-\\w]*[0-9a-zA-Z])+(:(0-9)*)*(\\/?)([a-zA-Z0-9\\-\\?\\,\'\\/\\\\+&%\\$#_=~]*)(\\.)([-\\w]*[0-9a-zA-Z])+(:(0-9)*)*(\\/?)([a-zA-Z0-9\\-\\?\\,\'\\/\\\\+&%\\$#_=~]*))+");
+
+//rules
+const QString NUMBER_RULE("NUMBER_RULE");
+const QString EMAIL_RULE("EMAIL_RULE");
+const QString URL_RULE("URL_RULE");
+
+//localization
+#define LOC_OPEN_CONTACT_INFO hbTrId("txt_messaging_menu_open_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")
+#define LOC_CREATE_EMAIL hbTrId("txt_messaging_menu_create_mail")
+#define LOC_OPEN_LINK hbTrId("txt_messaging_menu_open_link")
+#define LOC_ADD_TO_BOOKMARKS hbTrId("txt_messaging_menu_add_to_bookmarks")
+#define LOC_COPY_LINK hbTrId("txt_messaging_menu_copy_link")
+
+UniViewerTextItem::UniViewerTextItem(QGraphicsItem* parent):
+HbTextEdit(parent),
+mFindOn(true),
+mCursorPos(-1)
+{
+ this->setReadOnly(true);
+ this->setCursorVisibility(Hb::TextCursorHidden);
+
+ //inserting rules and patterns to map.
+ mRules.insert(NUMBER_RULE,NUMBER_PATTERN);
+ mRules.insert(EMAIL_RULE,EMAIL_PATTERN);
+ mRules.insert(URL_RULE,URL_PATTERN);
+
+ 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)));
+}
+
+UniViewerTextItem::~UniViewerTextItem()
+ {
+ }
+
+void UniViewerTextItem::setFindOn(bool on)
+{
+ mFindOn = on;
+}
+
+void UniViewerTextItem::setText(const QString& text)
+{
+
+ this->setPlainText(text);
+ applyRule();
+}
+
+void UniViewerTextItem::applyRule()
+{
+
+ if(mFindOn == false)
+ {
+ return;
+ }
+
+ QMap<QString, QString>::const_iterator i;
+ for (i = mRules.constBegin(); i != mRules.constEnd(); ++i)
+ {
+ QString ruleName = i.key();
+ QString rule = i.value();
+ QRegExp ruleExp(rule);
+
+ QTextCursor cursor = this->document()->find(ruleExp);
+
+ while(cursor.hasSelection())
+ {
+ // Insert anchor in the document
+ QTextCharFormat f;
+ f.setFontUnderline(true);
+ f.setForeground(palette().link());
+
+ //prepending rule name to identiy different fragment to which
+ //catagory it belongs to.
+ QString txt = cursor.selectedText().prepend(ruleName);
+
+ if(ruleName == NUMBER_RULE)
+ {
+ //removing special char(s) from phone numbers.
+ QRegExp numberCharExp("[\\s-/.\\(\\)]");
+ txt = txt.remove(numberCharExp);
+ }
+
+ f.setAnchorHref(txt);
+ f.setAnchor(true);
+ cursor.mergeCharFormat(f);
+
+ // Find next
+ cursor = this->document()->find(ruleExp, cursor);
+ }
+ }
+}
+
+
+void UniViewerTextItem::aboutToShowContextMenu(HbMenu *contextMenu, const QPointF &pos)
+{
+ // Check if there is an anchor at this pos
+ QString anchor = this->anchorAt(pos);
+
+ if(!anchor.isEmpty() && !this->textCursor().hasSelection())
+ {
+ //remove default actions.
+ contextMenu->clearActions();
+
+ if(anchor.contains(QRegExp("^"+NUMBER_RULE)))
+ {
+ addNumberMenu(contextMenu,anchor);
+ }
+ else if(anchor.contains(QRegExp("^"+EMAIL_RULE)))
+ {
+ addEmailMenu(contextMenu,anchor);
+ }
+ else if(anchor.contains(QRegExp("^"+URL_RULE)))
+ {
+ addUrlMenu(contextMenu,anchor);
+ }
+ }
+
+ connect(contextMenu,SIGNAL(aboutToClose()),this,SLOT(menuClosed()));
+
+}
+
+
+void UniViewerTextItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ HbTextEdit::mouseReleaseEvent(event);
+
+ highlightText(false);
+
+ QString anchor = this->anchorAt(event->pos());
+
+ if(!anchor.isEmpty() && !this->textCursor().hasSelection())
+ {
+ shortTapAction(anchor);
+ }
+}
+
+void UniViewerTextItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ HbTextEdit::mousePressEvent(event);
+
+ QTextDocument* doc = this->document();
+
+ mCursorPos = doc->documentLayout()->hitTest(event->pos(), Qt::ExactHit);
+
+ highlightText(true);
+}
+
+void UniViewerTextItem::addNumberMenu(HbMenu* contextMenu,const QString& data)
+{
+ HbAction* action = NULL;
+
+ action = contextMenu->addAction(LOC_OPEN_CONTACT_INFO, this, SLOT(openContactInfo()));
+ 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_SAVE_TO_CONTACTS, this, SLOT(saveToContacts()));
+ action->setData(data);
+
+ action = contextMenu->addAction(LOC_COPY, this, SLOT(copyToClipboard()));
+ action->setData(data);
+}
+
+void UniViewerTextItem::addEmailMenu(HbMenu* contextMenu,const QString& data)
+{
+ HbAction* action = NULL;
+
+ action = contextMenu->addAction(LOC_CREATE_EMAIL, this, SLOT(createEmail()));
+ action->setData(data);
+
+ action = contextMenu->addAction(LOC_OPEN_CONTACT_INFO, this, SLOT(openContactInfo()));
+ action->setData(data);
+
+ action = contextMenu->addAction(LOC_SAVE_TO_CONTACTS, this, SLOT(saveToContacts()));
+ action->setData(data);
+
+ action = contextMenu->addAction(LOC_COPY, this, SLOT(copyToClipboard()));
+ action->setData(data);
+}
+
+void UniViewerTextItem::addUrlMenu(HbMenu* contextMenu,const QString& data)
+{
+ HbAction* action = NULL;
+
+ action = contextMenu->addAction(LOC_OPEN_LINK, this, SLOT(openLink()));
+ action->setData(data);
+
+ action = contextMenu->addAction(LOC_ADD_TO_BOOKMARKS, this, SLOT(addToBookmarks()));
+ action->setData(data);
+
+ action = contextMenu->addAction(LOC_COPY_LINK, this, SLOT(copyToClipboard()));
+ action->setData(data);
+}
+
+void UniViewerTextItem::shortTapAction(QString anchor)
+{
+ HbAction action;
+ action.setData(anchor);
+
+ if(anchor.contains(NUMBER_RULE))
+ {
+ //open vcard template.
+ connect(&action,SIGNAL(triggered()),this,SLOT(openContactInfo()));
+ }
+ else if(anchor.contains(EMAIL_RULE))
+ {
+ //Create email
+ connect(&action,SIGNAL(triggered()),this,SLOT(createEmail()));
+ }
+ else if(anchor.contains(URL_RULE))
+ {
+ //Open link in the browser
+ connect(&action,SIGNAL(triggered()),this,SLOT(openLink()));
+ }
+
+ action.trigger();
+}
+
+
+void UniViewerTextItem::copyToClipboard()
+{
+ HbAction* action = qobject_cast<HbAction*>(sender());
+
+ if(action)
+ {
+ QMimeData* data = new QMimeData();
+ QString str = action->data().toString();
+
+ //removing rule name before setting it to clipboard.
+ str.remove(QRegExp("^"+NUMBER_RULE));
+ str.remove(QRegExp("^"+EMAIL_RULE));
+ str.remove(QRegExp("^"+URL_RULE));
+
+ data->setText(str);
+ QApplication::clipboard()->setMimeData(data);
+ }
+}
+
+void UniViewerTextItem::call()
+{
+ HbAction* action = qobject_cast<HbAction*>(sender());
+
+ if(action)
+ {
+ QString phoneNumber = action->data().toString();
+ phoneNumber.remove(NUMBER_RULE);
+
+ //invoke dialer service and pass phoneNumber.
+ QString serviceName("com.nokia.services.telephony");
+ 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 UniViewerTextItem::sendMessage()
+{
+ HbAction* action = qobject_cast<HbAction*>(sender());
+
+ if(action)
+ {
+ QString phoneNumber = action->data().toString();
+ phoneNumber.remove(NUMBER_RULE);
+
+ //invoke editor & pass phoneNumber.
+ emit sendMessage(phoneNumber);
+ }
+}
+
+void UniViewerTextItem::createEmail()
+{
+ HbAction* action = qobject_cast<HbAction*>(sender());
+
+ if(action)
+ {
+ QString emailId = action->data().toString();
+ emailId.remove(EMAIL_RULE);
+ //invoke email editor service & pass emailId.
+ }
+}
+
+void UniViewerTextItem::openLink()
+{
+ HbAction* action = qobject_cast<HbAction*>(sender());
+
+ if(action)
+ {
+ QString url = action->data().toString();
+ url.remove(URL_RULE);
+ //invoke browser service & pass url.
+ }
+}
+
+void UniViewerTextItem::addToBookmarks()
+{
+ HbAction* action = qobject_cast<HbAction*>(sender());
+
+ if(action)
+ {
+ QString url = action->data().toString();
+ url.remove(URL_RULE);
+ //invoke browser service to save url.
+ }
+}
+
+void UniViewerTextItem::openContactInfo()
+{
+ HbAction* action = qobject_cast<HbAction*>(sender());
+
+ if(action)
+ {
+ QList<QVariant> args;
+ QString operation;
+
+ QString data = action->data().toString();
+
+ if(data.contains(QRegExp("^"+NUMBER_RULE)))
+ {
+ data.remove(NUMBER_RULE);
+
+ int contactId = resolveContactId(data,
+ QContactPhoneNumber::DefinitionName,
+ QContactPhoneNumber::FieldNumber);
+
+ 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;
+ }
+ }
+ else if(data.contains(QRegExp("^"+EMAIL_RULE)))
+ {
+ data.remove(EMAIL_RULE);
+
+ int contactId = resolveContactId(data,
+ QContactEmailAddress::DefinitionName,
+ QContactEmailAddress::FieldEmailAddress);
+
+ if(contactId > 0)
+ {
+ //open contact card
+ operation = QString("open(int)");
+ args << contactId;
+ }
+ else
+ {
+ //save to contacts with e-mail field prefilled.
+
+ operation = QString("editCreateNew(QString,QString)");
+
+ QString type = QContactEmailAddress::DefinitionName;
+
+ args << type;
+ args << data;
+ }
+ }
+
+ //service stuff.
+ QString serviceName("com.nokia.services.phonebookservices.Fetch");
+
+ XQServiceRequest* serviceRequest = new XQServiceRequest(serviceName,operation,false);
+
+ connect(serviceRequest, SIGNAL(requestCompleted(QVariant)),
+ this, SLOT(onServiceRequestCompleted()));
+
+ connect(serviceRequest, SIGNAL(requestError(int)),
+ this, SLOT(onServiceRequestCompleted()));
+
+ serviceRequest->setArguments(args);
+ serviceRequest->send();
+ }
+}
+
+
+void UniViewerTextItem::saveToContacts()
+{
+ //handler for save to contacts.
+}
+
+void UniViewerTextItem::onServiceRequestCompleted()
+ {
+ //service request is now complete. delete it.
+
+ XQServiceRequest* request = qobject_cast<XQServiceRequest*>(sender());
+
+ if(request)
+ {
+ delete request;
+ }
+ }
+
+int UniViewerTextItem::resolveContactId(const QString& value,
+ const QString& fieldName,
+ const QString& fieldType)
+ {
+ int contactId = -1;
+
+ QContactManager phonebookManager("symbian");
+
+ QContactDetailFilter phoneFilter;
+ phoneFilter.setDetailDefinitionName(fieldName, fieldType);
+ phoneFilter.setValue(value);
+ phoneFilter.setMatchFlags(QContactFilter::MatchEndsWith);
+
+ QList<QContactLocalId> matchingContacts = phonebookManager.contacts(phoneFilter);
+
+ if ( matchingContacts.count() > 0 )
+ {
+ contactId = matchingContacts.at(0);
+ }
+
+ return contactId;
+ }
+
+void UniViewerTextItem::menuClosed()
+{
+ highlightText(false);
+}
+
+void UniViewerTextItem::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();
+ }
+ }
+}