diff -r 4697dfb2d7ad -r 238255e8b033 messagingapp/msgui/unifiedviewer/src/univiewertextitem.cpp --- /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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +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::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(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(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(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(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(sender()); + + if(action) + { + QString url = action->data().toString(); + url.remove(URL_RULE); + //invoke browser service & pass url. + } +} + +void UniViewerTextItem::addToBookmarks() +{ + HbAction* action = qobject_cast(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(sender()); + + if(action) + { + QList 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(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 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(); + } + } +}