emailuis/nmailui/src/nmeditorheader.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Fri, 11 Jun 2010 13:27:14 +0300
changeset 30 759dc5235cdb
parent 27 9ba4404ef423
child 44 c2d07d913565
permissions -rw-r--r--
Revision: 201021 Kit: 2010123

/*
* 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 container class. Collects the header widgets.
*
*/

#include "nmuiheaders.h"

// Layout
// These match to the defintions in nmeditorview.docml
static const char *NMUI_EDITOR_CONTAINER = "containerContents";
static const char *NMUI_EDITOR_SUBJECT_FIELD = "editorSubjectField";
static const char *NMUI_EDITOR_SUBJECT_EDIT = "editorSubjectEdit";
static const char *NMUI_EDITOR_CC_FIELD = "editorCcField";
static const char *NMUI_EDITOR_BCC_FIELD = "editorBccField";
static const char *NMUI_EDITOR_PRIORITY_ICON = "editPriorityIcon";
static const char *NMUI_EDITOR_FOLLOWUP_ICON = "editFollowUpIcon";
static const char *NMUI_EDITOR_ATTACHMENT_LIST = "attachmentListWidget";
static const char *NMUI_EDITOR_PREFIX_TO = "editorTo";
static const char *NMUI_EDITOR_PREFIX_CC = "editorCc";
static const char *NMUI_EDITOR_PREFIX_BCC = "editorBcc";

static const int MaxRows = 10000;

static const int nmLayoutSystemWaitTimer = 10;

/*!
    Constructor
*/
NmEditorHeader::NmEditorHeader(HbDocumentLoader *documentLoader) :
    mDocumentLoader(documentLoader),
    mHeaderHeight(0),
    mIconVisible(false),
    mSubjectEdit(NULL),
    mRecipientFieldsEmpty(true),
    mAttachmentList(NULL),
    mToField(NULL),
    mCcField(NULL),
    mBccField(NULL),
    mCcBccFieldVisible(false)
{
    NM_FUNCTION;
    
    loadWidgets();
    createConnections();
}

/*!
    Destructor
*/
NmEditorHeader::~NmEditorHeader()
{
    NM_FUNCTION;
}

/*!
    Load widgets from XML for the header.
*/
void NmEditorHeader::loadWidgets()
{
    NM_FUNCTION;
	
    // Load widgets from docml and construct handlers. Those widgets that are not shown by default
    // are hidden and removed from the layout at this phase.    
    HbWidget *contentWidget =
        qobject_cast<HbWidget *>(mDocumentLoader->findWidget(NMUI_EDITOR_CONTAINER));
    mLayout = static_cast<QGraphicsLinearLayout *>(contentWidget->layout());

    // base class QObject takes the deleting responsibility
    mToField = new NmRecipientField(this, *mDocumentLoader, NMUI_EDITOR_PREFIX_TO);
    mCcField = new NmRecipientField(this, *mDocumentLoader, NMUI_EDITOR_PREFIX_CC);
    mBccField = new NmRecipientField(this, *mDocumentLoader, NMUI_EDITOR_PREFIX_BCC);

    // Cc field is not shown by default. It needs to be both hidden and removed from the layout.
	mCcWidget = qobject_cast<HbWidget *>(mDocumentLoader->findWidget(NMUI_EDITOR_CC_FIELD));
    mCcWidget->hide();
    mLayout->removeItem(mCcWidget);
    
    // Bcc field is not shown by default. It needs to be both hidden and removed from the layout.
    mBccWidget = qobject_cast<HbWidget *>(mDocumentLoader->findWidget(NMUI_EDITOR_BCC_FIELD));
    mBccWidget->hide();
    mLayout->removeItem(mBccWidget);

    mSubjectWidget =
        qobject_cast<HbWidget *>(mDocumentLoader->findWidget(NMUI_EDITOR_SUBJECT_FIELD));
    mSubjectLayout = static_cast<QGraphicsLinearLayout *>(mSubjectWidget->layout());
    
    // Add Subject: field
    mSubjectEdit = qobject_cast<NmHtmlLineEdit *>
        (mDocumentLoader->findWidget(NMUI_EDITOR_SUBJECT_EDIT));
    mSubjectEdit->setMaxRows(MaxRows);

    // Add attachment list
    NmAttachmentListWidget *attachmentList = qobject_cast<NmAttachmentListWidget *>
        (mDocumentLoader->findWidget(NMUI_EDITOR_ATTACHMENT_LIST));
    // Create attachment list handling object
    mAttachmentList = new NmAttachmentList(*attachmentList);
    mAttachmentList->setParent(this); // ownership changes
    attachmentList->hide();
    mLayout->removeItem(attachmentList);

    // Add priority icon
    mPriorityIcon = qobject_cast<HbLabel *>
        (mDocumentLoader->findWidget(NMUI_EDITOR_PRIORITY_ICON));
    mPriorityIcon->hide();
    mSubjectLayout->removeItem(mPriorityIcon);

    // follow-up icon is not yet supported
    HbLabel *followUpIcon = qobject_cast<HbLabel *>
        (mDocumentLoader->findWidget(NMUI_EDITOR_FOLLOWUP_ICON));
    followUpIcon->hide();
    mSubjectLayout->removeItem(followUpIcon);
}

/*!
    Create signal - slot connections.
*/
void NmEditorHeader::createConnections()
{
    NM_FUNCTION;
    
    // 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(sendDelayedHeaderHeightChanged()));
    connect(mCcField, SIGNAL(textChanged(const QString &)),
            this, SLOT(sendDelayedHeaderHeightChanged()));
    connect(mBccField, SIGNAL(textChanged(const QString &)),
            this, SLOT(sendDelayedHeaderHeightChanged()));
    connect(mSubjectEdit, SIGNAL(contentsChanged()), this, SLOT(sendDelayedHeaderHeightChanged()));

    // Signals for handling the attachment list
    connect(&mAttachmentList->listWidget(), SIGNAL(itemActivated(int)),
            this, SLOT(attachmentActivated(int)));
    connect(&mAttachmentList->listWidget(), SIGNAL(longPressed(int, QPointF)),
            this, SLOT(attachmentLongPressed(int, QPointF)));
    connect(mAttachmentList ,SIGNAL(attachmentListLayoutChanged()),
            this, SLOT(sendHeaderHeightChanged()));
}

/*!
   Show or hide recipient field
*/
void NmEditorHeader::setFieldVisibility(bool isVisible)
{
	if ( mCcBccFieldVisible != isVisible ) {
		mCcBccFieldVisible = isVisible;
		if (mCcBccFieldVisible) {
            mLayout->insertItem(1, mBccWidget);
			mLayout->insertItem(1, mCcWidget);
			mCcWidget->show();
            mBccWidget->show();
		}
		else {
            mCcWidget->hide();
            mBccWidget->hide();
			mLayout->removeItem(mCcWidget);
			mLayout->removeItem(mBccWidget);
		}

		QTimer::singleShot(
		    nmLayoutSystemWaitTimer * 2, this, SLOT(sendDelayedHeaderHeightChanged()));
	}
}

/*!
    Return the height of the whole header widget.
 */
qreal NmEditorHeader::headerHeight() const
{
    NM_FUNCTION;

    // get the layout's vertical spacing
    qreal spacing = 0;
    HbStyle().parameter("hb-param-margin-gene-middle-vertical", spacing);

    // calculate the height
    qreal height = 0;
    
    height += mToField->height(); // returns widget's geometry height
    height += spacing;
    
    if (mCcBccFieldVisible) {
        height += mCcField->height(); // returns widget's geometry height
        height += spacing;
        
        height += mBccField->height(); // returns widget's geometry height
        height += spacing;
    }

    height += mSubjectWidget->geometry().height();
    height += spacing;

    if (mAttachmentList->listWidget().isVisible()) {
        height += mAttachmentList->listWidget().geometry().height();
        height += spacing;
    }

    return height;
}

/*!
    Send signal to inform that one of the recipient fields height has been changed.
 */
void NmEditorHeader::sendDelayedHeaderHeightChanged()
{
    NM_FUNCTION;
	QTimer::singleShot(nmLayoutSystemWaitTimer * 5, this, SLOT(sendHeaderHeightChanged()));
}

/*!
    Send signal to inform that one of the recipient fields height has been changed.
 */
void NmEditorHeader::sendHeaderHeightChanged()
{
    qreal hHeight = headerHeight();
    if (mHeaderHeight != hHeight) {
        mHeaderHeight = hHeight;
        emit headerHeightChanged(mHeaderHeight);
    }
}

/*!
    Return pointer to to edit
 */
NmRecipientLineEdit* NmEditorHeader::toEdit() const
{
    NM_FUNCTION;
    
    return mToField->editor();
}

/*!
    Return pointer to cc edit
 */
NmRecipientLineEdit* NmEditorHeader::ccEdit() const
{
    NM_FUNCTION;
    
    return mCcField->editor();
}

/*!
    Return pointer to bcc edit
 */
NmRecipientLineEdit* NmEditorHeader::bccEdit() const
{
    NM_FUNCTION;
    
    return mBccField->editor();
}

/*!
    Return pointer to subject field
 */
NmHtmlLineEdit* NmEditorHeader::subjectEdit() const
{
    NM_FUNCTION;
    
    return mSubjectEdit;
}

/*!
    Checks if recipient editors are empty and emits a signal if
    the state is changed.
*/
void NmEditorHeader::editorContentChanged()
{
    NM_FUNCTION;
    
    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);
    }
}

/*!
    Sets the icon for priority
 */
void NmEditorHeader::setPriority(NmMessagePriority priority)
{
    NM_FUNCTION;
    
    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)
{
    NM_FUNCTION;
    
    switch(prio) {
    case NmActionResponseCommandPriorityHigh:
        if (!mIconVisible) {
            mIconVisible = true;
            // icon widget is just after the subject line edit (see docml)
            mSubjectLayout->insertItem(2, mPriorityIcon);
            mPriorityIcon->show();
        }
        mPriorityIcon->setIcon(
            NmIcons::getIcon(NmIcons::NmIconPriorityHigh));
        break;
    case NmActionResponseCommandPriorityLow:
        if (!mIconVisible) {
            mIconVisible = true;
            // icon widget is just after the subject line edit (see docml)
            mSubjectLayout->insertItem(2, mPriorityIcon);
            mPriorityIcon->show();
        }
        mPriorityIcon->setIcon(
            NmIcons::getIcon(NmIcons::NmIconPriorityLow));
        break;
    default:
        if (mIconVisible) {
            mIconVisible = false;
            HbIcon emptyIcon;
            mPriorityIcon->setIcon(emptyIcon);
            mSubjectLayout->removeItem(mPriorityIcon);
            mPriorityIcon->hide();
        }
        break;
    }
    // Update subject field height because row amount might have been changed.
    QTimer::singleShot(nmLayoutSystemWaitTimer * 3, this, SLOT(sendDelayedHeaderHeightChanged()));
}

/*!
   Adds an attachment to attachment list for mail.
 */
void NmEditorHeader::addAttachment(
    const QString &fileName, const QString &fileSize, const NmId &nmid)
{
    NM_FUNCTION;
    
    mAttachmentList->insertAttachment(fileName, fileSize, nmid);
    if (!mAttachmentList->listWidget().isVisible()) {
        // attachment list is inserted just before the body widget (see docml).
        mLayout->insertItem(mLayout->count() - 1, &mAttachmentList->listWidget());
        mAttachmentList->listWidget().show();
    }
    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)
{
    NM_FUNCTION;
    
    mAttachmentList->removeAttachment(fileName);
    if (mAttachmentList->count() == 0) {
        mAttachmentList->listWidget().hide();
        mLayout->removeItem(&mAttachmentList->listWidget());
    }
    sendHeaderHeightChanged();
}

/*!
   Remove attachment from the list. This function is used when
   attachment has been selected for remove.
 */
void NmEditorHeader::removeAttachment(const NmId &nmid)
{
    NM_FUNCTION;
    
    mAttachmentList->removeAttachment(nmid);
    sendHeaderHeightChanged();
}

/*!
    This function set messagePartId and fileSize for attachment.
 */
void NmEditorHeader::setAttachmentParameters(
    const QString &fileName,
    const NmId &msgPartId,
    const QString &fileSize,
    int result)
{
    NM_FUNCTION;
    
    if (result == NmNoError) {
        // Attachment adding succesful, set message part id and size for attachment
        mAttachmentList->setAttachmentPartId(fileName, msgPartId);
        mAttachmentList->setAttachmentSize(msgPartId, fileSize);
    }
}

/*!
   Attachment launched from attachment list by "open" menu item.
 */
void NmEditorHeader::launchAttachment(const NmId &itemId)
{
    NM_FUNCTION;
    
    attachmentActivated(mAttachmentList->indexByNmId(itemId));
}

/*!
   Slot attachment activated from attachment list by short tap.
 */
void NmEditorHeader::attachmentActivated(int arrayIndex)
{
    NM_FUNCTION;
    
    QFile launchFile(mAttachmentList->getFullFileNameByIndex(arrayIndex));
    if (NmUtilities::openFile( launchFile ) == NmNotFoundError) {
        NmUtilities::displayErrorNote(hbTrId("txt_mail_dialog_unable_to_open_attachment_file_ty")); 
    }
}

/*!
   Slot attachment selected from attachment list by longtap.
 */
void NmEditorHeader::attachmentLongPressed(int arrayIndex, QPointF point)
{
    NM_FUNCTION;
    
    // Remove selected attachment
    emit attachmentLongPressed(mAttachmentList->nmIdByIndex(arrayIndex), point);
}