emailuis/nmailui/src/nmeditorheader.cpp
changeset 18 578830873419
child 20 ecc8def7944a
equal deleted inserted replaced
4:e7aa27f58ae1 18:578830873419
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: Message editor header widget
       
    15 *
       
    16 */
       
    17 
       
    18 #include "nmuiheaders.h"
       
    19 
       
    20 // Layout
       
    21 static const char *NMUI_EDITOR_TO_LABEL = "EditorHeaderToLabel";
       
    22 static const char *NMUI_EDITOR_TO_EDIT = "EditorHeaderToEdit";
       
    23 static const char *NMUI_EDITOR_TO_BUTTON = "EditorHeaderToButton";
       
    24 static const char *NMUI_EDITOR_RECIPIENT_GB = "EditorHeaderRecipientGB";
       
    25 static const char *NMUI_EDITOR_SUBJECT_LABEL = "EditorHeaderSubjectLabel";
       
    26 static const char *NMUI_EDITOR_SUBJECT_EDIT = "EditorHeaderSubjectEdit";
       
    27 static const char *NMUI_EDITOR_PRIORITY_ICON = "labelPriorityIcon";
       
    28 static const char *NMUI_EDITOR_ATTACHMENT_LIST = "attachmentListWidget";
       
    29 
       
    30 // Following constants are removed when header fields will offer these
       
    31 static const double Un = 6.66;
       
    32 static const double FieldHeightWhenSecondaryFont = 5 * Un;
       
    33 static const int GroupBoxTitleHeight = 42;
       
    34 static const double Margin = 2 * Un;
       
    35 static const double HeaderAreaMarginsTotal = 3 * Un;
       
    36 static const double IconFieldWidth = 5 * Un;
       
    37 
       
    38 static const int nmLayoutSystemWaitTimer = 10;
       
    39 
       
    40 /*!
       
    41     Constructor
       
    42 */
       
    43 NmEditorHeader::NmEditorHeader(HbDocumentLoader *documentLoader, QGraphicsItem *parent) :
       
    44     HbWidget(parent),
       
    45     mDocumentLoader(documentLoader),
       
    46     mHeaderHeight(0),
       
    47     mSubjectLabel(NULL),
       
    48     mIconVisible(false),
       
    49     mSubjectEdit(NULL),
       
    50     mRecipientFieldsEmpty(true),
       
    51     mGroupBoxRecipient(NULL),
       
    52     mAttachmentList(NULL)
       
    53 {
       
    54     loadWidgets();
       
    55     rescaleHeader();
       
    56     createConnections();
       
    57 }
       
    58 
       
    59 /*!
       
    60     Destructor
       
    61 */
       
    62 NmEditorHeader::~NmEditorHeader()
       
    63 {
       
    64     if (mAttachmentList) {
       
    65         mAttachmentList->clearList();
       
    66         delete mAttachmentList;
       
    67     }
       
    68 }
       
    69 
       
    70 /*!
       
    71     Load widgets from XML for the header.
       
    72 */
       
    73 void NmEditorHeader::loadWidgets()
       
    74 {
       
    75     // To: field objects
       
    76     HbLabel *toLabel = qobject_cast<HbLabel *>
       
    77         (mDocumentLoader->findWidget(NMUI_EDITOR_TO_LABEL));
       
    78     toLabel->setPlainText(hbTrId("txt_mail_editor_to"));
       
    79     NmRecipientLineEdit *toEdit = qobject_cast<NmRecipientLineEdit *>
       
    80         (mDocumentLoader->findWidget(NMUI_EDITOR_TO_EDIT));
       
    81     HbPushButton *toButton = qobject_cast<HbPushButton *>
       
    82         (mDocumentLoader->findWidget(NMUI_EDITOR_TO_BUTTON));
       
    83     mToField = new NmRecipientField(toLabel, toEdit, toButton);
       
    84 
       
    85     // Create recipient group box which includes cc and bcc fields
       
    86     mGroupBoxRecipient = qobject_cast<HbGroupBox *>
       
    87         (mDocumentLoader->findWidget(NMUI_EDITOR_RECIPIENT_GB));
       
    88     // Ownership is transfered
       
    89     mGroupBoxRecipient->setContentWidget(createRecipientGroupBoxContentWidget());
       
    90     mGroupBoxRecipient->setHeading(hbTrId("txt_mail_subhead_ccbcc"));
       
    91     mGroupBoxRecipient->setCollapsable(true);
       
    92     mGroupBoxRecipient->setCollapsed(true);
       
    93 
       
    94     // Add Subject: field
       
    95     mSubjectLabel = qobject_cast<HbLabel *>
       
    96         (mDocumentLoader->findWidget(NMUI_EDITOR_SUBJECT_LABEL));
       
    97     mSubjectLabel->setPlainText(hbTrId("txt_mail_editor_subject"));
       
    98     mSubjectEdit = qobject_cast<NmHtmlLineEdit *>
       
    99         (mDocumentLoader->findWidget(NMUI_EDITOR_SUBJECT_EDIT));
       
   100 
       
   101     // Add attachment list
       
   102     NmAttachmentListWidget *attachmentList = qobject_cast<NmAttachmentListWidget *>
       
   103         (mDocumentLoader->findWidget(NMUI_EDITOR_ATTACHMENT_LIST));
       
   104     // Create attachment list handling object
       
   105     mAttachmentList = new NmAttachmentList(attachmentList);
       
   106 
       
   107     mPriorityIconLabel = qobject_cast<HbLabel *>
       
   108         (mDocumentLoader->findWidget(NMUI_EDITOR_PRIORITY_ICON));
       
   109 }
       
   110 
       
   111 /*!
       
   112     Create signal - slot connections.
       
   113 */
       
   114 void NmEditorHeader::createConnections()
       
   115 {
       
   116     // Signals for checking if the recipient fields have text.
       
   117     connect(mToField, SIGNAL(textChanged(const QString &)),
       
   118             this, SLOT(editorContentChanged()));
       
   119     connect(mCcField, SIGNAL(textChanged(const QString &)),
       
   120             this, SLOT(editorContentChanged()));
       
   121     connect(mBccField, SIGNAL(textChanged(const QString &)),
       
   122             this, SLOT(editorContentChanged()));
       
   123 
       
   124     // Signals for handling the recipient field expanding
       
   125     connect(mToField, SIGNAL(textChanged(const QString &)),
       
   126             this, SLOT(sendHeaderHeightChanged()));
       
   127     connect(mCcField, SIGNAL(textChanged(const QString &)),
       
   128             this, SLOT(sendHeaderHeightChanged()));
       
   129     connect(mBccField, SIGNAL(textChanged(const QString &)),
       
   130             this, SLOT(sendHeaderHeightChanged()));
       
   131     connect(mSubjectEdit, SIGNAL(contentsChanged()), this, SLOT(sendHeaderHeightChanged()));
       
   132 
       
   133     // Signal for handling the recipient group box expanding/collapsing
       
   134     connect(mGroupBoxRecipient, SIGNAL(toggled(bool)),
       
   135             this, SLOT(groupBoxExpandCollapse()));
       
   136 
       
   137     // Signals for handling the attachment list
       
   138     connect(mAttachmentList->listWidget(), SIGNAL(longPressed(int, QPointF)),
       
   139             this, SLOT(attachmentSelected(int, QPointF)));
       
   140     connect(mAttachmentList ,SIGNAL(attachmentListLayoutChanged()),
       
   141             this, SLOT(sendHeaderHeightChanged()));
       
   142 }
       
   143 
       
   144 /*!
       
   145     Function can be used to rescale the header area.
       
   146 */
       
   147 void NmEditorHeader::rescaleHeader()
       
   148 {
       
   149 }
       
   150 
       
   151 /*!
       
   152     Return the height of the whole header widget.
       
   153     (Should find beter way to get the height of the header area.)
       
   154  */
       
   155 int NmEditorHeader::headerHeight() const
       
   156 {
       
   157     qreal toHeight = mToField->height();
       
   158     qreal subjectHeight = mSubjectEdit->geometry().height() + Margin;
       
   159 
       
   160     // When called first time, height is wrongly 'Margin'
       
   161     if (toHeight == Margin) {
       
   162         toHeight = FieldHeightWhenSecondaryFont;
       
   163         subjectHeight = FieldHeightWhenSecondaryFont;
       
   164     }
       
   165 
       
   166     // Recipient GroupBox
       
   167     qreal recipientGroupBoxHeight = GroupBoxTitleHeight;
       
   168     if (!mGroupBoxRecipient->isCollapsed()) {
       
   169         recipientGroupBoxHeight +=
       
   170             mGroupBoxRecipientContent->geometry().height() + HeaderAreaMarginsTotal;
       
   171     }
       
   172 
       
   173     qreal attHeight = 0;
       
   174     if (mAttachmentList && mAttachmentList->count() > 0) {
       
   175         attHeight = mAttachmentList->listWidget()->geometry().height();
       
   176     }
       
   177 
       
   178     return (int)(toHeight + recipientGroupBoxHeight + subjectHeight + attHeight);
       
   179 }
       
   180 
       
   181 /*!
       
   182     Send signal to inform that one of the recipient fields height has been changed.
       
   183  */
       
   184 void NmEditorHeader::sendHeaderHeightChanged()
       
   185 {
       
   186     // Adjust field heights
       
   187     mToField->editor()->setPreferredHeight(
       
   188         mToField->editor()->document()->size().height() + Margin);
       
   189     mCcField->editor()->setPreferredHeight(
       
   190         mCcField->editor()->document()->size().height() + Margin);
       
   191     mBccField->editor()->setPreferredHeight(
       
   192         mBccField->editor()->document()->size().height() + Margin);
       
   193     mSubjectEdit->setPreferredHeight(
       
   194         mSubjectEdit->document()->size().height() + Margin);
       
   195 
       
   196     int hHeight = headerHeight();
       
   197     if (mHeaderHeight != hHeight) {
       
   198         mHeaderHeight = hHeight;
       
   199         emit headerHeightChanged(mHeaderHeight);
       
   200     }
       
   201 }
       
   202 
       
   203 /*!
       
   204     This slot is called when group box state is changed. Timer is used to give some time
       
   205     for layout system so that header hight can be recalculated correctly
       
   206  */
       
   207 void NmEditorHeader::groupBoxExpandCollapse()
       
   208 {
       
   209     QTimer::singleShot(nmLayoutSystemWaitTimer, this, SLOT(sendHeaderHeightChanged()));
       
   210 }
       
   211 
       
   212 /*!
       
   213     Return pointer to to field
       
   214  */
       
   215 NmRecipientLineEdit* NmEditorHeader::toField() const
       
   216 {
       
   217     return mToField->editor();
       
   218 }
       
   219 
       
   220 /*!
       
   221     Return pointer to cc field
       
   222  */
       
   223 NmRecipientLineEdit* NmEditorHeader::ccField() const
       
   224 {
       
   225     return mCcField->editor();
       
   226 }
       
   227 
       
   228 /*!
       
   229     Return pointer to bcc field
       
   230  */
       
   231 NmRecipientLineEdit* NmEditorHeader::bccField() const
       
   232 {
       
   233     return mBccField->editor();
       
   234 }
       
   235 
       
   236 /*!
       
   237     Return pointer to subject field
       
   238  */
       
   239 NmHtmlLineEdit* NmEditorHeader::subjectField() const
       
   240 {
       
   241     return mSubjectEdit;
       
   242 }
       
   243 
       
   244 /*!
       
   245     Checks if recipient editors are empty and emits a signal if
       
   246     the state is changed.
       
   247 */
       
   248 void NmEditorHeader::editorContentChanged()
       
   249 {
       
   250     bool recipientsFieldsEmpty = true;
       
   251     if (mToField->text().length()) {
       
   252         recipientsFieldsEmpty = false;
       
   253     }
       
   254     else if (mCcField->text().length()) {
       
   255         recipientsFieldsEmpty = false;
       
   256     }
       
   257     else if (mBccField->text().length()) {
       
   258         recipientsFieldsEmpty = false;
       
   259     }
       
   260     if (mRecipientFieldsEmpty != recipientsFieldsEmpty) {
       
   261         mRecipientFieldsEmpty = recipientsFieldsEmpty;
       
   262         emit recipientFieldsHaveContent(!mRecipientFieldsEmpty);
       
   263     }
       
   264 }
       
   265 
       
   266 /*!
       
   267     This function create content widget for recipient group box.
       
   268     When AD offers groupBox content widget handling. This function
       
   269     need to be changed to use AD/docml
       
   270  */
       
   271 HbWidget* NmEditorHeader::createRecipientGroupBoxContentWidget()
       
   272 {
       
   273     mGroupBoxRecipientContent = new HbWidget();
       
   274 
       
   275     // Create layout for the widget
       
   276     mGbVerticalLayout = new QGraphicsLinearLayout(Qt::Vertical,mGroupBoxRecipientContent);
       
   277     mCcFieldLayout = new QGraphicsLinearLayout(Qt::Horizontal, mGbVerticalLayout);
       
   278     mBccFieldLayout = new QGraphicsLinearLayout(Qt::Horizontal, mGbVerticalLayout);
       
   279 
       
   280     // Add Cc: field into widget
       
   281     mCcField = new NmRecipientField(hbTrId("txt_mail_editor_cc"));
       
   282     if (mCcField) {
       
   283         mCcField->setObjectName("lineEditCcField");
       
   284         mGbVerticalLayout->insertItem(EEditorCcLine, mCcField );
       
   285     }
       
   286 
       
   287     // Add Bcc: field into widget
       
   288     mBccField = new NmRecipientField(hbTrId("txt_mail_editor_bcc"));
       
   289     if (mBccField){
       
   290         mBccField->setObjectName("lineEditBccField");
       
   291         mGbVerticalLayout->insertItem(EEditorBccLine, mBccField);
       
   292     }
       
   293     mGbVerticalLayout->setContentsMargins(0,0,0,0);
       
   294 
       
   295     mGroupBoxRecipientContent->setLayout(mGbVerticalLayout);
       
   296     return mGroupBoxRecipientContent;
       
   297 }
       
   298 
       
   299 /*!
       
   300     Sets the icon for priority
       
   301  */
       
   302 void NmEditorHeader::setPriority(NmMessagePriority priority)
       
   303 {
       
   304     switch (priority) {
       
   305     case NmMessagePriorityHigh:
       
   306         setPriority(NmActionResponseCommandPriorityHigh);
       
   307         break;
       
   308     case NmMessagePriorityLow:
       
   309         setPriority(NmActionResponseCommandPriorityLow);
       
   310         break;
       
   311     default:
       
   312         setPriority(NmActionResponseCommandNone);
       
   313         break;
       
   314     }
       
   315 }
       
   316 
       
   317 /*!
       
   318     Sets the icon for priority
       
   319  */
       
   320 void NmEditorHeader::setPriority(NmActionResponseCommand prio)
       
   321 {
       
   322     switch(prio) {
       
   323     case NmActionResponseCommandPriorityHigh:
       
   324         if (!mIconVisible) {
       
   325             mIconVisible = true;
       
   326             mPriorityIconLabel->setMaximumWidth(IconFieldWidth);
       
   327             mSubjectEdit->setMaximumWidth(mSubjectEdit->geometry().width() - IconFieldWidth);
       
   328         }
       
   329         mPriorityIconLabel->setIcon(
       
   330             NmIcons::getIcon(NmIcons::NmIconPriorityHigh));
       
   331         break;
       
   332     case NmActionResponseCommandPriorityLow:
       
   333         if (!mIconVisible) {
       
   334             mIconVisible = true;
       
   335             mPriorityIconLabel->setMaximumWidth(IconFieldWidth);
       
   336             mSubjectEdit->setMaximumWidth(mSubjectEdit->geometry().width() - IconFieldWidth);
       
   337         }
       
   338         mPriorityIconLabel->setIcon(
       
   339             NmIcons::getIcon(NmIcons::NmIconPriorityLow));
       
   340         break;
       
   341     default:
       
   342         if (mIconVisible) {
       
   343             mIconVisible = false;
       
   344             HbIcon emptyIcon;
       
   345             mPriorityIconLabel->setIcon(emptyIcon);
       
   346             mPriorityIconLabel->setMaximumWidth(0);
       
   347             mSubjectEdit->setMaximumWidth(mSubjectEdit->geometry().width() + IconFieldWidth);
       
   348         }
       
   349         break;
       
   350     }
       
   351     // Update subject field height because row amount might have been changed.
       
   352     // Done with delayed timer so that layout system has finished before.
       
   353     QTimer::singleShot(nmLayoutSystemWaitTimer, this, SLOT(sendHeaderHeightChanged()));
       
   354     // This second call will set new position for body if subject field height has been changed.
       
   355     QTimer::singleShot(nmLayoutSystemWaitTimer * 2, this, SLOT(sendHeaderHeightChanged()));
       
   356 }
       
   357 
       
   358 /*!
       
   359  * \brief Sets the groupbox to be expanded or collapsed. 
       
   360  */
       
   361 void NmEditorHeader::setGroupBoxCollapsed( bool collapsed )
       
   362 {
       
   363     mGroupBoxRecipient->setCollapsed( collapsed );
       
   364 }
       
   365 
       
   366 /*!
       
   367    Adds an attachment to attachment list for mail.
       
   368  */
       
   369 void NmEditorHeader::addAttachment(
       
   370     const QString &fileName, const QString &fileSize, const NmId &nmid)
       
   371 {
       
   372     mAttachmentList->insertAttachment(fileName, fileSize, nmid);
       
   373     sendHeaderHeightChanged();
       
   374 }
       
   375 
       
   376 /*!
       
   377    Remove attachment from the list. This function is used when attachment adding has failed
       
   378    and attachment id is not known.
       
   379  */
       
   380 void NmEditorHeader::removeAttachment(const QString &fileName)
       
   381 {
       
   382     mAttachmentList->removeAttachment(fileName);
       
   383     sendHeaderHeightChanged();
       
   384 }
       
   385 
       
   386 /*!
       
   387     This function set messagePartId and fileSize for attachment.
       
   388  */
       
   389 void NmEditorHeader::setAttachmentParameters(
       
   390     const QString &fileName,
       
   391     const NmId &msgPartId,
       
   392     const QString &fileSize,
       
   393     int result)
       
   394 {
       
   395     if (result == NmNoError) {
       
   396         // Attachment adding succesful, set message part id and size for attachment
       
   397         mAttachmentList->setAttachmentPartId(fileName, msgPartId);
       
   398         mAttachmentList->setAttachmentSize(msgPartId, fileSize);
       
   399     }
       
   400 }
       
   401 
       
   402 /*!
       
   403    Slot attachment selected from attachment list by longtap.
       
   404  */
       
   405 void NmEditorHeader::attachmentSelected(int arrayIndex, QPointF point)
       
   406 {
       
   407     Q_UNUSED(point);
       
   408     // Remove selected attachment
       
   409     emit attachmentRemoved(mAttachmentList->nmIdByIndex(arrayIndex));
       
   410     mAttachmentList->removeAttachment(arrayIndex);
       
   411 }
       
   412