emailuis/nmailui/src/nmutilities.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 14 May 2010 15:41:10 +0300
changeset 23 2dc6caa42ec3
parent 20 ecc8def7944a
child 27 9ba4404ef423
permissions -rw-r--r--
Revision: 201017 Kit: 201019

/*
* 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: UI utilities class
*
*/

#include "nmuiheaders.h"

static const int NmMegabyte = 1048576;
static const int NmShortInterval = 1000; // 1 sec

// taken from http://www.regular-expressions.info/email.html
static const QRegExp EmailAddressPattern("[A-Za-z\\d!#$%&'*+/=?^_`{|}~-]+"
                                         "(?:"
                                         "\\."
                                         "[A-Za-z\\d!#$%&'*+/=?^_`{|}~-]+"
                                         ")*"
                                         "@"
                                         "(?:"
                                         "[A-Za-z\\d]"
                                         "(?:"
                                         "[A-Za-z\\d-]*[A-Za-z\\d]"
                                         ")?"
                                         "\\."
                                         ")+"
                                         "[A-Za-z\\d]"
                                         "(?:"
                                         "[A-Za-z\\d-]*[A-Za-z\\d]"
                                         ")?"
                                        );

/*!
   Gets valid, invalid or all the recipients from a message
 */
void NmUtilities::getRecipientsFromMessage( const NmMessage &message,
    QList<NmAddress> &recipients,
    NmAddressValidationType type )
{
    // validate TO addresses
    QList<NmAddress> toRecipients = message.envelope().toRecipients();
    int recipientCount = toRecipients.count();

    for (int i = 0; i < recipientCount; ++i) {
        bool validAddress = isValidEmailAddress(toRecipients.at(i).address());

        if (type == Default ||
            type == ValidAddress && validAddress ||
            type == InvalidAddress && !validAddress) {
            recipients.append(toRecipients.at(i));
        }
    }

    // validate CC addresses
    QList<NmAddress> ccRecipients = message.envelope().ccRecipients();
    recipientCount = ccRecipients.count();

    for (int i = 0; i < recipientCount; ++i) {
        bool validAddress = isValidEmailAddress(ccRecipients.at(i).address());

        if (type == Default ||
            type == ValidAddress && validAddress ||
            type == InvalidAddress && !validAddress) {
            recipients.append(ccRecipients.at(i));
        }
    }

    // validate BCC addresses
    QList<NmAddress> bccRecipients = message.envelope().bccRecipients();
    recipientCount = bccRecipients.count();

    for (int i = 0; i < recipientCount; ++i) {
        bool validAddress = isValidEmailAddress(bccRecipients.at(i).address());

        if (type == Default ||
            type == ValidAddress && validAddress ||
            type == InvalidAddress && !validAddress) {
            recipients.append(bccRecipients.at(i));
        }
    }
}

/*!
  Validates the given string against an email address pattern.
*/
bool NmUtilities::isValidEmailAddress( const QString &emailAddress )
{
    return EmailAddressPattern.exactMatch(emailAddress);
}

/*!
  Generates a display string from an NmAddress object.
*/
QString NmUtilities::addressToDisplayName( const NmAddress &address )
{
    QString emailAddress = address.address();
    QString displayName = address.displayName();

    QString ret;
    if (displayName.length() > 0 && displayName != emailAddress) {
        ret = displayName + " <" + emailAddress + ">";
    }
    else {
        ret = emailAddress;
    }
    return ret;
}

/*!
  Returns an NmAddress object that is parsed from a display name string.
*/
bool NmUtilities::parseEmailAddress( const QString &emailAddress, NmAddress &address )
{
    bool foundAddress = false;

    QRegExp rx(EmailAddressPattern);
    // locate the email address in the string
    int pos = rx.indexIn(emailAddress);
    if (pos != -1) {
        // extract the email address...
        int matchedLen = rx.matchedLength();
        QString addr = emailAddress.mid(pos, matchedLen);
        address.setAddress(addr);

        // ...and use the rest as display name
        QString name = emailAddress.left(pos) + emailAddress.mid(pos + matchedLen);
        address.setDisplayName(cleanupDisplayName(name));

        foundAddress = true;
    }

    return foundAddress;
}

/*!
  Cleans up display name by stripping extra characters from the beginning and end of the string.
*/
QString NmUtilities::cleanupDisplayName( const QString &displayName )
{
    // find the first and last position that is NOT one of the characters below
    QRegExp rx("[^\\s\"<>]");
    int firstPos = std::max(rx.indexIn(displayName), 0);
    int lastPos = rx.lastIndexIn(displayName);

    if (lastPos < 0) {
        lastPos = displayName.length() - 1;
    }

    return displayName.mid(firstPos, lastPos - firstPos + 1);
}

/*!
  Opens file specified by QFile handle. Usually used by editor
  for opening added attachments
*/
int NmUtilities::openFile(QFile &file)
{
    int ret(NmNotFoundError);
    XQApplicationManager aiwMgr;
    XQAiwRequest *request(NULL);
    request = aiwMgr.create(file);
    // If request is created then there is a handler for that file
    if (request) {
         // Set request arguments
         QList<QVariant> args;
         args << file.fileName();
         request->setArguments(args);
         // Send the request, ownership of request is transferred
         bool res = request->send();
         if (res) {
             // Request ok, set error status.
             ret = NmNoError;
         }
    }
    delete request;
    return ret;
}


/*!
  Opens file specified by RFile handle. Usually used by viewer
  for opening attachments from message store as RFiles
*/
int NmUtilities::openFile(XQSharableFile &file)
{
    int ret(NmNotFoundError);
    XQApplicationManager aiwMgr;
    XQAiwRequest *request(NULL);
    request = aiwMgr.create(file);  
    // Create request for the sharable file
    if (request)
    {
        // Set request arguments
        QList<QVariant> args;
        args << qVariantFromValue(file);  
        request->setArguments(args);
        // Send the request, ownership of request is transferred
        bool res = request->send();
        if (res) {
        // Request ok, set error status.
        ret = NmNoError;
        }
    }
    return ret;
}

/*!
 * Truncate a string to a specific length. If length is less than
 * the string, ellipses are added to the end of the string.
 */
QString NmUtilities::truncate( const QString &string, int length )
{
    if (string.length() <= length) {
        return string;
    }

    QString padding = "...";

    return string.mid(0, length - padding.length()) + padding;
}

/*!
 * Shows an error note. Used by at least editor and viewer classes.
 * 
 */
void NmUtilities::displayErrorNote(QString noteText)
{
	HbNotificationDialog *note = new HbNotificationDialog();
	
	note->setIcon(HbIcon(QLatin1String("note_warning")));
	note->setTitle(noteText);
	note->setTitleTextWrapping(Hb::TextWordWrap);
	note->setDismissPolicy(HbPopup::TapAnywhere);
	note->setAttribute(Qt::WA_DeleteOnClose);
	note->setSequentialShow(false);

	note->show();
}

/*!
    Function returns localized attachment size string based
    on attachment size in bytes
 */
QString NmUtilities::attachmentSizeString(const int sizeInBytes)
{
    qreal sizeMb = (qreal)sizeInBytes / (qreal)NmMegabyte;
    if (sizeMb < 0.1) {
        // 0.1 Mb is the minimum size shown for attachment
        sizeMb = 0.1;
    }
    return QString().sprintf("(%.1f Mb)", sizeMb); // Use loc string when available    
}

/*!
    takes care of necessary error/information note displaying based on the given operation completion event
    returns boolean whether settings should be opened or not
*/
bool NmUtilities::displayOperationCompletionNote(const NmOperationCompletionEvent &event)
{
    bool openSettings(false);
    // nothing to do in successfull or cancelled case
    if(event.mCompletionCode != NmNoError && event.mCompletionCode != NmCancelError) {
        if(event.mOperationType == Synch && event.mCompletionCode == NmAuthenticationError) {
            openSettings = displayQuestionNote(hbTrId("txt_mail_dialog_address_or_password_incorrect"));
        }
        if(event.mOperationType == Synch && event.mCompletionCode == NmServerConnectionError) {
            openSettings = displayQuestionNote(hbTrId("txt_mail_dialog_server_settings_incorrect"));
        }
        // following applies to all operation/event types
        if(event.mCompletionCode == NmConnectionError) {
            displayWarningNote(hbTrId("txt_mail_dialog_mail_connection_error"));
        }
    }
    return openSettings;
}

/*!
    displays a note with Yes/No buttons. Note has no timeout, i.e. it has to be dismissed manually
    returns boolean whether primaryaction was taken (Left button ("Yes") pressed)
*/
bool NmUtilities::displayQuestionNote(QString noteText)
{
	HbMessageBox::warning(noteText);
	return true;
	/*
	 * Commented out because of exec() deprecation. Will be fixed later...
	 * 
    bool ret(false);
    HbMessageBox *messageBox = new HbMessageBox(HbMessageBox::MessageTypeQuestion);
    messageBox->setText(noteText);
    messageBox->setTimeout(HbMessageBox::NoTimeout); // note has to be dismissed manually
    HbAction *action = messageBox->exec();
    if(action == messageBox->primaryAction()) {
        ret=true; // primary/left button was pressed
    }
    delete messageBox;
    return ret;
    */
}

/*!
 * displays an error note with no buttons. Note dismisses itself after NmShortInterval.
 */
void NmUtilities::displayWarningNote(QString noteText)
{
    HbMessageBox *messageBox = new HbMessageBox(HbMessageBox::MessageTypeWarning);
    messageBox->setText(noteText);
    messageBox->setTimeout(NmShortInterval);
    messageBox->clearActions(); // gets rid of buttons from the note
    messageBox->setModal(false);
    messageBox->setBackgroundFaded(false);
    messageBox->show();

    delete messageBox;
}

/*!
    Function returns localized "Original message" header
    in html format based on envelope
*/
QString NmUtilities::createReplyHeader(const NmMessageEnvelope &env)
{
    QString ret = "<html><body><br><br>";
    // Append "----- Original message ----" text
    ret+=hbTrId("txt_mail_editor_reply_original_msg");                  
    // Append sender
    ret+="<br>";
    ret+=hbTrId("txt_mail_editor_reply_from");               
    ret+=" ";        
    if (env.sender().displayName().length()){
        ret+=env.sender().displayName();
    }
    else{
        ret+=env.sender().address();
    }   
    // Append sent time
    ret+="<br>";
    ret+=hbTrId("txt_mail_editor_reply_sent");   
    ret+=" ";  
    HbExtendedLocale locale = HbExtendedLocale::system();
    QDate sentLocalDate = env.sentTime().toLocalTime().date();
    ret+=locale.format(sentLocalDate, r_qtn_date_usual);   
    // Append to recipients
    const QList<NmAddress> &toList = env.toRecipients();
    if (toList.count()){
        ret+="<br>";
        ret+=hbTrId("txt_mail_editor_reply_to"); 
        ret+=" ";    
        for (int i=0;i<toList.count();i++){
            if (toList[i].displayName().length()){
                ret+=toList[i].displayName();
            }
            else{
                ret+=toList[i].address();
            }
            if (i!=toList.count()-1){
                ret+=";";          
            }
        }    
    }
    // Append cc recipients
    const QList<NmAddress> &ccList = env.ccRecipients();
    if (ccList.count()){
        ret+="<br>";
        ret+=hbTrId("txt_mail_editor_reply_cc"); 
        ret+=" ";         
        for (int i=0;i<ccList.count();i++){
            if (ccList[i].displayName().length()){
                ret+=ccList[i].displayName();
            }
            else{
                ret+=ccList[i].address();
            }
            if (i!=toList.count()-1){
                ret+=";";          
            }
        }    
    }
    // Append subject if there is subject to display
    if (env.subject().length()){
        ret+="<br>";
        ret+=hbTrId("txt_mail_editor_reply_subject"); 
        ret+=" ";    
        ret+=env.subject();    
    }
    // Append priority if it is other than normal  
    if (env.priority()!=NmMessagePriorityNormal){   
        ret+="<br>";
        ret+=hbTrId("txt_mail_editor_reply_importance"); 
        ret+=" ";    
        if (env.priority()==NmMessagePriorityLow){
            ret+=hbTrId("txt_mail_editor_reply_importance_low");         
        }
        else {
            ret+=hbTrId("txt_mail_editor_reply_importance_high"); 
        }
    }    
    ret+="<br></body></html>";
    return ret;
}