emailuis/nmailui/src/nmeditorheader.cpp
changeset 18 578830873419
child 20 ecc8def7944a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emailuis/nmailui/src/nmeditorheader.cpp	Fri Apr 16 14:51:52 2010 +0300
@@ -0,0 +1,412 @@
+/*
+* 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 editor header widget
+*
+*/
+
+#include "nmuiheaders.h"
+
+// Layout
+static const char *NMUI_EDITOR_TO_LABEL = "EditorHeaderToLabel";
+static const char *NMUI_EDITOR_TO_EDIT = "EditorHeaderToEdit";
+static const char *NMUI_EDITOR_TO_BUTTON = "EditorHeaderToButton";
+static const char *NMUI_EDITOR_RECIPIENT_GB = "EditorHeaderRecipientGB";
+static const char *NMUI_EDITOR_SUBJECT_LABEL = "EditorHeaderSubjectLabel";
+static const char *NMUI_EDITOR_SUBJECT_EDIT = "EditorHeaderSubjectEdit";
+static const char *NMUI_EDITOR_PRIORITY_ICON = "labelPriorityIcon";
+static const char *NMUI_EDITOR_ATTACHMENT_LIST = "attachmentListWidget";
+
+// Following constants are removed when header fields will offer these
+static const double Un = 6.66;
+static const double FieldHeightWhenSecondaryFont = 5 * Un;
+static const int GroupBoxTitleHeight = 42;
+static const double Margin = 2 * Un;
+static const double HeaderAreaMarginsTotal = 3 * Un;
+static const double IconFieldWidth = 5 * Un;
+
+static const int nmLayoutSystemWaitTimer = 10;
+
+/*!
+    Constructor
+*/
+NmEditorHeader::NmEditorHeader(HbDocumentLoader *documentLoader, QGraphicsItem *parent) :
+    HbWidget(parent),
+    mDocumentLoader(documentLoader),
+    mHeaderHeight(0),
+    mSubjectLabel(NULL),
+    mIconVisible(false),
+    mSubjectEdit(NULL),
+    mRecipientFieldsEmpty(true),
+    mGroupBoxRecipient(NULL),
+    mAttachmentList(NULL)
+{
+    loadWidgets();
+    rescaleHeader();
+    createConnections();
+}
+
+/*!
+    Destructor
+*/
+NmEditorHeader::~NmEditorHeader()
+{
+    if (mAttachmentList) {
+        mAttachmentList->clearList();
+        delete mAttachmentList;
+    }
+}
+
+/*!
+    Load widgets from XML for the header.
+*/
+void NmEditorHeader::loadWidgets()
+{
+    // To: field objects
+    HbLabel *toLabel = qobject_cast<HbLabel *>
+        (mDocumentLoader->findWidget(NMUI_EDITOR_TO_LABEL));
+    toLabel->setPlainText(hbTrId("txt_mail_editor_to"));
+    NmRecipientLineEdit *toEdit = qobject_cast<NmRecipientLineEdit *>
+        (mDocumentLoader->findWidget(NMUI_EDITOR_TO_EDIT));
+    HbPushButton *toButton = qobject_cast<HbPushButton *>
+        (mDocumentLoader->findWidget(NMUI_EDITOR_TO_BUTTON));
+    mToField = new NmRecipientField(toLabel, toEdit, toButton);
+
+    // Create recipient group box which includes cc and bcc fields
+    mGroupBoxRecipient = qobject_cast<HbGroupBox *>
+        (mDocumentLoader->findWidget(NMUI_EDITOR_RECIPIENT_GB));
+    // Ownership is transfered
+    mGroupBoxRecipient->setContentWidget(createRecipientGroupBoxContentWidget());
+    mGroupBoxRecipient->setHeading(hbTrId("txt_mail_subhead_ccbcc"));
+    mGroupBoxRecipient->setCollapsable(true);
+    mGroupBoxRecipient->setCollapsed(true);
+
+    // Add Subject: field
+    mSubjectLabel = qobject_cast<HbLabel *>
+        (mDocumentLoader->findWidget(NMUI_EDITOR_SUBJECT_LABEL));
+    mSubjectLabel->setPlainText(hbTrId("txt_mail_editor_subject"));
+    mSubjectEdit = qobject_cast<NmHtmlLineEdit *>
+        (mDocumentLoader->findWidget(NMUI_EDITOR_SUBJECT_EDIT));
+
+    // Add attachment list
+    NmAttachmentListWidget *attachmentList = qobject_cast<NmAttachmentListWidget *>
+        (mDocumentLoader->findWidget(NMUI_EDITOR_ATTACHMENT_LIST));
+    // Create attachment list handling object
+    mAttachmentList = new NmAttachmentList(attachmentList);
+
+    mPriorityIconLabel = qobject_cast<HbLabel *>
+        (mDocumentLoader->findWidget(NMUI_EDITOR_PRIORITY_ICON));
+}
+
+/*!
+    Create signal - slot connections.
+*/
+void NmEditorHeader::createConnections()
+{
+    // Signals for checking if the recipient fields have text.
+    connect(mToField, SIGNAL(textChanged(const QString &)),
+            this, SLOT(editorContentChanged()));
+    connect(mCcField, SIGNAL(textChanged(const QString &)),
+            this, SLOT(editorContentChanged()));
+    connect(mBccField, SIGNAL(textChanged(const QString &)),
+            this, SLOT(editorContentChanged()));
+
+    // Signals for handling the recipient field expanding
+    connect(mToField, SIGNAL(textChanged(const QString &)),
+            this, SLOT(sendHeaderHeightChanged()));
+    connect(mCcField, SIGNAL(textChanged(const QString &)),
+            this, SLOT(sendHeaderHeightChanged()));
+    connect(mBccField, SIGNAL(textChanged(const QString &)),
+            this, SLOT(sendHeaderHeightChanged()));
+    connect(mSubjectEdit, SIGNAL(contentsChanged()), this, SLOT(sendHeaderHeightChanged()));
+
+    // Signal for handling the recipient group box expanding/collapsing
+    connect(mGroupBoxRecipient, SIGNAL(toggled(bool)),
+            this, SLOT(groupBoxExpandCollapse()));
+
+    // Signals for handling the attachment list
+    connect(mAttachmentList->listWidget(), SIGNAL(longPressed(int, QPointF)),
+            this, SLOT(attachmentSelected(int, QPointF)));
+    connect(mAttachmentList ,SIGNAL(attachmentListLayoutChanged()),
+            this, SLOT(sendHeaderHeightChanged()));
+}
+
+/*!
+    Function can be used to rescale the header area.
+*/
+void NmEditorHeader::rescaleHeader()
+{
+}
+
+/*!
+    Return the height of the whole header widget.
+    (Should find beter way to get the height of the header area.)
+ */
+int NmEditorHeader::headerHeight() const
+{
+    qreal toHeight = mToField->height();
+    qreal subjectHeight = mSubjectEdit->geometry().height() + Margin;
+
+    // When called first time, height is wrongly 'Margin'
+    if (toHeight == Margin) {
+        toHeight = FieldHeightWhenSecondaryFont;
+        subjectHeight = FieldHeightWhenSecondaryFont;
+    }
+
+    // Recipient GroupBox
+    qreal recipientGroupBoxHeight = GroupBoxTitleHeight;
+    if (!mGroupBoxRecipient->isCollapsed()) {
+        recipientGroupBoxHeight +=
+            mGroupBoxRecipientContent->geometry().height() + HeaderAreaMarginsTotal;
+    }
+
+    qreal attHeight = 0;
+    if (mAttachmentList && mAttachmentList->count() > 0) {
+        attHeight = mAttachmentList->listWidget()->geometry().height();
+    }
+
+    return (int)(toHeight + recipientGroupBoxHeight + subjectHeight + attHeight);
+}
+
+/*!
+    Send signal to inform that one of the recipient fields height has been changed.
+ */
+void NmEditorHeader::sendHeaderHeightChanged()
+{
+    // Adjust field heights
+    mToField->editor()->setPreferredHeight(
+        mToField->editor()->document()->size().height() + Margin);
+    mCcField->editor()->setPreferredHeight(
+        mCcField->editor()->document()->size().height() + Margin);
+    mBccField->editor()->setPreferredHeight(
+        mBccField->editor()->document()->size().height() + Margin);
+    mSubjectEdit->setPreferredHeight(
+        mSubjectEdit->document()->size().height() + Margin);
+
+    int hHeight = headerHeight();
+    if (mHeaderHeight != hHeight) {
+        mHeaderHeight = hHeight;
+        emit headerHeightChanged(mHeaderHeight);
+    }
+}
+
+/*!
+    This slot is called when group box state is changed. Timer is used to give some time
+    for layout system so that header hight can be recalculated correctly
+ */
+void NmEditorHeader::groupBoxExpandCollapse()
+{
+    QTimer::singleShot(nmLayoutSystemWaitTimer, this, SLOT(sendHeaderHeightChanged()));
+}
+
+/*!
+    Return pointer to to field
+ */
+NmRecipientLineEdit* NmEditorHeader::toField() const
+{
+    return mToField->editor();
+}
+
+/*!
+    Return pointer to cc field
+ */
+NmRecipientLineEdit* NmEditorHeader::ccField() const
+{
+    return mCcField->editor();
+}
+
+/*!
+    Return pointer to bcc field
+ */
+NmRecipientLineEdit* NmEditorHeader::bccField() const
+{
+    return mBccField->editor();
+}
+
+/*!
+    Return pointer to subject field
+ */
+NmHtmlLineEdit* NmEditorHeader::subjectField() const
+{
+    return mSubjectEdit;
+}
+
+/*!
+    Checks if recipient editors are empty and emits a signal if
+    the state is changed.
+*/
+void NmEditorHeader::editorContentChanged()
+{
+    bool recipientsFieldsEmpty = true;
+    if (mToField->text().length()) {
+        recipientsFieldsEmpty = false;
+    }
+    else if (mCcField->text().length()) {
+        recipientsFieldsEmpty = false;
+    }
+    else if (mBccField->text().length()) {
+        recipientsFieldsEmpty = false;
+    }
+    if (mRecipientFieldsEmpty != recipientsFieldsEmpty) {
+        mRecipientFieldsEmpty = recipientsFieldsEmpty;
+        emit recipientFieldsHaveContent(!mRecipientFieldsEmpty);
+    }
+}
+
+/*!
+    This function create content widget for recipient group box.
+    When AD offers groupBox content widget handling. This function
+    need to be changed to use AD/docml
+ */
+HbWidget* NmEditorHeader::createRecipientGroupBoxContentWidget()
+{
+    mGroupBoxRecipientContent = new HbWidget();
+
+    // Create layout for the widget
+    mGbVerticalLayout = new QGraphicsLinearLayout(Qt::Vertical,mGroupBoxRecipientContent);
+    mCcFieldLayout = new QGraphicsLinearLayout(Qt::Horizontal, mGbVerticalLayout);
+    mBccFieldLayout = new QGraphicsLinearLayout(Qt::Horizontal, mGbVerticalLayout);
+
+    // Add Cc: field into widget
+    mCcField = new NmRecipientField(hbTrId("txt_mail_editor_cc"));
+    if (mCcField) {
+        mCcField->setObjectName("lineEditCcField");
+        mGbVerticalLayout->insertItem(EEditorCcLine, mCcField );
+    }
+
+    // Add Bcc: field into widget
+    mBccField = new NmRecipientField(hbTrId("txt_mail_editor_bcc"));
+    if (mBccField){
+        mBccField->setObjectName("lineEditBccField");
+        mGbVerticalLayout->insertItem(EEditorBccLine, mBccField);
+    }
+    mGbVerticalLayout->setContentsMargins(0,0,0,0);
+
+    mGroupBoxRecipientContent->setLayout(mGbVerticalLayout);
+    return mGroupBoxRecipientContent;
+}
+
+/*!
+    Sets the icon for priority
+ */
+void NmEditorHeader::setPriority(NmMessagePriority priority)
+{
+    switch (priority) {
+    case NmMessagePriorityHigh:
+        setPriority(NmActionResponseCommandPriorityHigh);
+        break;
+    case NmMessagePriorityLow:
+        setPriority(NmActionResponseCommandPriorityLow);
+        break;
+    default:
+        setPriority(NmActionResponseCommandNone);
+        break;
+    }
+}
+
+/*!
+    Sets the icon for priority
+ */
+void NmEditorHeader::setPriority(NmActionResponseCommand prio)
+{
+    switch(prio) {
+    case NmActionResponseCommandPriorityHigh:
+        if (!mIconVisible) {
+            mIconVisible = true;
+            mPriorityIconLabel->setMaximumWidth(IconFieldWidth);
+            mSubjectEdit->setMaximumWidth(mSubjectEdit->geometry().width() - IconFieldWidth);
+        }
+        mPriorityIconLabel->setIcon(
+            NmIcons::getIcon(NmIcons::NmIconPriorityHigh));
+        break;
+    case NmActionResponseCommandPriorityLow:
+        if (!mIconVisible) {
+            mIconVisible = true;
+            mPriorityIconLabel->setMaximumWidth(IconFieldWidth);
+            mSubjectEdit->setMaximumWidth(mSubjectEdit->geometry().width() - IconFieldWidth);
+        }
+        mPriorityIconLabel->setIcon(
+            NmIcons::getIcon(NmIcons::NmIconPriorityLow));
+        break;
+    default:
+        if (mIconVisible) {
+            mIconVisible = false;
+            HbIcon emptyIcon;
+            mPriorityIconLabel->setIcon(emptyIcon);
+            mPriorityIconLabel->setMaximumWidth(0);
+            mSubjectEdit->setMaximumWidth(mSubjectEdit->geometry().width() + IconFieldWidth);
+        }
+        break;
+    }
+    // Update subject field height because row amount might have been changed.
+    // Done with delayed timer so that layout system has finished before.
+    QTimer::singleShot(nmLayoutSystemWaitTimer, this, SLOT(sendHeaderHeightChanged()));
+    // This second call will set new position for body if subject field height has been changed.
+    QTimer::singleShot(nmLayoutSystemWaitTimer * 2, this, SLOT(sendHeaderHeightChanged()));
+}
+
+/*!
+ * \brief Sets the groupbox to be expanded or collapsed. 
+ */
+void NmEditorHeader::setGroupBoxCollapsed( bool collapsed )
+{
+    mGroupBoxRecipient->setCollapsed( collapsed );
+}
+
+/*!
+   Adds an attachment to attachment list for mail.
+ */
+void NmEditorHeader::addAttachment(
+    const QString &fileName, const QString &fileSize, const NmId &nmid)
+{
+    mAttachmentList->insertAttachment(fileName, fileSize, nmid);
+    sendHeaderHeightChanged();
+}
+
+/*!
+   Remove attachment from the list. This function is used when attachment adding has failed
+   and attachment id is not known.
+ */
+void NmEditorHeader::removeAttachment(const QString &fileName)
+{
+    mAttachmentList->removeAttachment(fileName);
+    sendHeaderHeightChanged();
+}
+
+/*!
+    This function set messagePartId and fileSize for attachment.
+ */
+void NmEditorHeader::setAttachmentParameters(
+    const QString &fileName,
+    const NmId &msgPartId,
+    const QString &fileSize,
+    int result)
+{
+    if (result == NmNoError) {
+        // Attachment adding succesful, set message part id and size for attachment
+        mAttachmentList->setAttachmentPartId(fileName, msgPartId);
+        mAttachmentList->setAttachmentSize(msgPartId, fileSize);
+    }
+}
+
+/*!
+   Slot attachment selected from attachment list by longtap.
+ */
+void NmEditorHeader::attachmentSelected(int arrayIndex, QPointF point)
+{
+    Q_UNUSED(point);
+    // Remove selected attachment
+    emit attachmentRemoved(mAttachmentList->nmIdByIndex(arrayIndex));
+    mAttachmentList->removeAttachment(arrayIndex);
+}
+