diff -r 84d9eb65b26f -r 518b245aa84c messagingapp/msgui/unifiedviewer/src/univieweraddresswidget.cpp --- a/messagingapp/msgui/unifiedviewer/src/univieweraddresswidget.cpp Mon May 03 12:29:07 2010 +0300 +++ b/messagingapp/msgui/unifiedviewer/src/univieweraddresswidget.cpp Fri Jun 25 15:47:40 2010 +0530 @@ -11,51 +11,149 @@ * * Contributors: * - * Description: + * Description:Custom widget derived from HbTextEdit which provides rich text + * processing * */ #include "univieweraddresswidget.h" -#include "univiewerfeeder_p.h" + // SYSTEM INCLUDES -#include -#include #include +#include +#include +#include + #include +#include +#include -// USER INCLUDES -#include "unitexteditor.h" +#include +#include +#include +#include +#include +#include +#include "msgcontacthandler.h" // LOCAL CONSTANTS const QString ADDRESS_SEPARATOR("; "); const QString ADDRESS_OPEN(" ("); const QString ADDRESS_CLOSE(")"); +const QString SPACE(" "); -//---------------------------------------------------------------------------- +//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") + +const QString BG_FRAME_GRAPHICS("qtg_fr_lineedit_normal"); + +//--------------------------------------------------------------- // UniViewerAddressWidget::UniViewerAddressWidget // @see header file -//---------------------------------------------------------------------------- -UniViewerAddressWidget::UniViewerAddressWidget(QGraphicsItem *parent) : - HbWidget(parent), mAddress(NULL) +//--------------------------------------------------------------- +UniViewerAddressWidget::UniViewerAddressWidget(QGraphicsItem * parent) : +HbTextEdit(parent), +mCursorPos(-1) { - mAddress = new UniTextEditor(this); - HbStyle::setItemName(mAddress, "addressField"); + this->setReadOnly(true); + this->setScrollable(false); + this->setFlag(QGraphicsItem::ItemIsFocusable,false); + this->setCursorVisibility(Hb::TextCursorHidden); + this->setBackgroundItem(0); - connect(mAddress, SIGNAL(aboutToShowContextMenu(HbMenu *,QPointF)), this, - SLOT(handleAboutToShowContextMenu(HbMenu *,QPointF))); + HbFontSpec fontSpec(HbFontSpec::Secondary); + QFont font = fontSpec.font(); + this->setFont(font); - // TODO: Wrapping fix breaking normal scenarios. - // this->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + 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(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); + } + } + 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 @@ -64,22 +162,40 @@ const QString &address, const QString &alias) { - - QTextCursor cursor(mAddress->document()); - - QTextCharFormat addressFormat = cursor.charFormat(); - addressFormat.setFontWeight(QFont::Bold); - addressFormat.setForeground(QApplication::palette().link()); - addressFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline); + 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 - cursor.insertText(label); + QTextCursor cursor(this->textCursor()); + cursor.insertText(labelText,labelFormat); + QString address1 = QString(); if (!(alias.isEmpty())) { address1.append(alias); QString alias1 = QString(); - if (UniViewerFeederPrivate::GetNameFromContacts(address, alias1) > 1) + + int totalNumbers = 0; + MsgContactHandler::resolveContactDisplayName( + address, + alias1, + totalNumbers); + if (totalNumbers > 1) { address1.append(ADDRESS_OPEN); address1.append(address); @@ -92,7 +208,6 @@ } addressFormat.setAnchorHref(address); cursor.insertText(address1, addressFormat); - repolish(); } //---------------------------------------------------------------------------- @@ -102,19 +217,30 @@ void UniViewerAddressWidget::populate(const QString &label, ConvergedMessageAddressList addressList) { - QTextCursor cursor(mAddress->document()); + 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 defaultFormat = cursor.charFormat(); - defaultFormat.setFontWeight(QFont::Bold); - defaultFormat.setForeground(QApplication::palette().link()); - - QTextCharFormat addressFormat = cursor.charFormat(); - addressFormat.setFontWeight(QFont::Bold); - addressFormat.setForeground(QApplication::palette().link()); - addressFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline); + QTextCharFormat addressFormat; + addressFormat.setForeground(palette().link()); + addressFormat.setFontUnderline(true); // Insert the label then the addresses - cursor.insertText(label); + QTextCursor cursor(this->document()); + cursor.insertText(labelText,labelFormat); int addressCount = addressList.count(); @@ -126,8 +252,13 @@ { address.append(addressList[i]->alias()); QString alias = QString(); - if (UniViewerFeederPrivate::GetNameFromContacts(addressList[i]->address(), - alias) > 1) + + int totalNumbers = 0; + MsgContactHandler::resolveContactDisplayName( + addressList[i]->address(), + alias, + totalNumbers); + if (totalNumbers > 1) { address.append(ADDRESS_OPEN); address.append(addressList[i]->address()); @@ -148,7 +279,6 @@ } } - repolish(); } //---------------------------------------------------------------------------- @@ -157,17 +287,264 @@ //---------------------------------------------------------------------------- void UniViewerAddressWidget::clearContent() { - mAddress->document()->clear(); + this->document()->clear(); +} + +//---------------------------------------------------------------------------- +// UniViewerAddressWidget::menuClosed +// @see header file +//---------------------------------------------------------------------------- +void UniViewerAddressWidget::menuClosed() +{ + highlightText(false); } //---------------------------------------------------------------------------- -// UniViewerAddressWidget::handleAboutToShowContextMenu +// UniViewerAddressWidget::highlightText // @see header file //---------------------------------------------------------------------------- -void UniViewerAddressWidget::handleAboutToShowContextMenu(HbMenu *contextMenu, const QPointF &pos) +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()) + { + + HbAction* action = NULL; + + action = contextMenu->addAction(LOC_OPEN_CONTACT_INFO, this, SLOT(openContactInfo())); + action->setData(anchor); + + action = contextMenu->addAction(LOC_CALL, this, SLOT(call())); + action->setData(anchor); + + action = contextMenu->addAction(LOC_SEND_MESSAGE, this, SLOT(sendMessage())); + action->setData(anchor); + + action = contextMenu->addAction(LOC_SAVE_TO_CONTACTS, this, SLOT(saveToContacts())); + action->setData(anchor); + + action = contextMenu->addAction(LOC_COPY, this, SLOT(copyToClipboard())); + action->setData(anchor); + + } + + connect(contextMenu,SIGNAL(aboutToClose()),this,SLOT(menuClosed())); +} + +void UniViewerAddressWidget::shortTapAction(QString anchor) +{ + HbAction action; + action.setData(anchor); + connect(&action,SIGNAL(triggered()),this,SLOT(openContactInfo())); + action.trigger(); +} + +void UniViewerAddressWidget::copyToClipboard() +{ + HbAction* action = qobject_cast(sender()); + + if(action) + { + QMimeData* data = new QMimeData(); + QString str = action->data().toString(); + data->setText(str); + QApplication::clipboard()->setMimeData(data); + } +} + +void UniViewerAddressWidget::call() { - Q_UNUSED(pos) - contextMenu->clearActions(); + HbAction* action = qobject_cast(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(sender()); + + if(request) + { + delete request; + } + } + + +void UniViewerAddressWidget::openContactInfo() +{ + HbAction* action = qobject_cast(sender()); + + if(action) + { + QList 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() +{ + //handler for save to contacts. +} + +void UniViewerAddressWidget::sendMessage() +{ + HbAction* action = qobject_cast(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