emailuis/nmailui/src/nmeditorheader.cpp
author hgs
Fri, 14 May 2010 04:41:45 +0300
changeset 40 2c62ef3caffd
parent 23 2dc6caa42ec3
child 30 759dc5235cdb
permissions -rw-r--r--
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: Message editor header widget
*
*/

#include "nmuiheaders.h"

// Layout
static const char *NMUI_EDITOR_RECIPIENT_FIELDS = "RecipientFields";
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 double Margin = 2 * 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),
    mAttachmentList(NULL),
    mToField(NULL),
    mCcField(NULL),
    mBccField(NULL),
    mCcBccFieldVisible(false)
{
    loadWidgets();
    rescaleHeader();
    createConnections();
}

/*!
    Destructor
*/
NmEditorHeader::~NmEditorHeader()
{
    if (mAttachmentList) {
        mAttachmentList->clearList();
        delete mAttachmentList;
    }
}

/*!
    Load widgets from XML for the header.
*/
void NmEditorHeader::loadWidgets()
{
	// Add "To:", "CC:" and "BCC:" fields
	mHeader = qobject_cast<HbWidget *>
	        (mDocumentLoader->findWidget(NMUI_EDITOR_RECIPIENT_FIELDS));

	mLayout = new QGraphicsLinearLayout(Qt::Vertical);
	mLayout->setContentsMargins(0,Un,0,0);

	mToField = new NmRecipientField(QString("To:"), mHeader);
	mCcField = new NmRecipientField(QString("Cc:"), mHeader);
	mBccField = new NmRecipientField(QString("Bcc:"), mHeader);

    // Only 'To:' field is visible at startup
	mLayout->addItem(mToField);
	mCcField->hide();
	mBccField->hide();

	mHeader->setLayout(mLayout);
	mHeader->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding);

    // Add Subject: field
    mSubjectLabel = qobject_cast<HbLabel *>
        (mDocumentLoader->findWidget(NMUI_EDITOR_SUBJECT_LABEL));
    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(fixHeaderFieldHeights()));
    connect(mCcField, SIGNAL(textChanged(const QString &)),
            this, SLOT(fixHeaderFieldHeights()));
    connect(mBccField, SIGNAL(textChanged(const QString &)),
            this, SLOT(fixHeaderFieldHeights()));
    connect(mSubjectEdit, SIGNAL(contentsChanged()), this, SLOT(fixHeaderFieldHeights()));

    // 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) {
			mCcField->show();
			mBccField->show();
			mLayout->addItem(mCcField);
			mLayout->addItem(mBccField);
		}
		else {
			mCcField->hide();
			mBccField->hide();
			mLayout->removeItem(mCcField);
			mLayout->removeItem(mBccField);
		}

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

/*!
    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 ccHeight = 0;
    qreal bccHeight = 0;
    if (mCcBccFieldVisible) {
		ccHeight = mCcField->height();
		bccHeight = mBccField->height();
    }
    qreal subjectHeight = mSubjectEdit->geometry().height() + Margin;

    // When called first time, height is wrongly 'Margin'
    if (toHeight == Margin) {
        toHeight = FieldHeightWhenSecondaryFont;
    	ccHeight = FieldHeightWhenSecondaryFont;
    	bccHeight = FieldHeightWhenSecondaryFont;
        subjectHeight = FieldHeightWhenSecondaryFont;
    }

    qreal attHeight = 0;
    if (mAttachmentList && mAttachmentList->count() > 0) {
        attHeight = mAttachmentList->listWidget().geometry().height();
    }

    return (int)(toHeight + ccHeight + bccHeight + subjectHeight + attHeight);
}

/*!
    Send signal to inform that one of the recipient fields height has been changed.
 */
void NmEditorHeader::fixHeaderFieldHeights()
{
    // Adjust height of recipient fields 
	adjustFieldSizeValues(mToField->editor(), mToField->editor()->document()->size().height());
	adjustFieldSizeValues(mCcField->editor(), mCcField->editor()->document()->size().height());
	adjustFieldSizeValues(mBccField->editor(), mBccField->editor()->document()->size().height());

    // Adjust height of the subject field 
	if (mSubjectEdit->document()->size().height() > FieldHeightWhenSecondaryFont) {
	mSubjectEdit->setPreferredHeight(
			mSubjectEdit->document()->size().height() + Margin );
	}
	else {
		mSubjectEdit->setPreferredHeight( FieldHeightWhenSecondaryFont );
	}

	QTimer::singleShot(nmLayoutSystemWaitTimer*5, this, SLOT(sendHeaderHeightChanged()));	
}


/*!
    Private routine to adjust heights of the recipient fields
 */
void NmEditorHeader::adjustFieldSizeValues( NmRecipientLineEdit *widget, qreal height )
{
	if (height > FieldHeightWhenSecondaryFont) {
		widget->setMaximumHeight( height + Margin );
		widget->setMinimumHeight( height + Margin );
	}
	else {
		widget->setMaximumHeight( FieldHeightWhenSecondaryFont );	
		widget->setMinimumHeight( FieldHeightWhenSecondaryFont );	
	}	
}

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

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

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

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

/*!
    Return pointer to subject field
 */
NmHtmlLineEdit* NmEditorHeader::subjectEdit() 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);
    }
}

/*!
    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.
    QTimer::singleShot(nmLayoutSystemWaitTimer * 3, this, SLOT(fixHeaderFieldHeights()));
}

/*!
   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();
}

/*!
   Remove attachment from the list. This function is used when
   attachment has been selected for remove.
 */
void NmEditorHeader::removeAttachment(const NmId &nmid)
{
    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)
{
    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)
{
    attachmentActivated(mAttachmentList->indexByNmId(itemId));
}

/*!
   Slot attachment activated from attachment list by short tap.
 */
void NmEditorHeader::attachmentActivated(int arrayIndex)
{
    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)
{
    // Remove selected attachment
    emit attachmentLongPressed(mAttachmentList->nmIdByIndex(arrayIndex), point);
}