emailuis/nmhswidget/src/nmhswidget.cpp
author hgs
Thu, 24 Jun 2010 14:32:18 +0300
changeset 47 f83bd4ae1fe3
parent 43 99bcbff212ad
child 49 00c7ae862740
permissions -rw-r--r--
201025

/*
 * Copyright (c) 2010 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: 
 *
 */
#include <QtGui>
#include <QGraphicsLinearLayout>
#include <hbcolorscheme.h>
#include <QTranslator>
#include <hbframedrawer.h>
#include <hbframeitem.h>
#include <hblabel.h>
#include "nmcommon.h"
#include "nmhswidget.h"
#include "nmhswidgetemailengine.h"
#include "nmmessageenvelope.h"
#include "nmhswidgettitlerow.h"
#include "nmhswidgetemailrow.h"
#include "nmhswidgetconsts.h"
#include "nmhswidgetdatetimeobserver.h"
#include "emailtrace.h"

NmHsWidget::NmHsWidget(QGraphicsItem *parent, Qt::WindowFlags flags)
    : HbWidget(parent, flags), 
      mEngine(0),
      mRowLayout(0),
      mTitleRow(0),
      mAccountId(0),
      mAccountIconName(),
      mTranslator(0),
      mBackgroundFrameDrawer(0),
      mIsExpanded(false),
      mDateObserver(0),
      mNoMailsLabel(0)
{
    NM_FUNCTION;
}

/*!
 Destructor
 */
NmHsWidget::~NmHsWidget()
{
    NM_FUNCTION;

    delete mTranslator;
    mTranslator = NULL;

    delete mEngine;
    mEngine = NULL;

    delete mBackgroundFrameDrawer;
    mBackgroundFrameDrawer = NULL;

    delete mDateObserver;
    mDateObserver = NULL;
}

/*!
 \fn QPainterPath NmHsWidget::shape()

 Called by home screen fw to check widget boundaries, needed to draw
 outside widget boundingRect.
 /return QPainterPath path describing actual boundaries of widget 
  including child items
 */
QPainterPath NmHsWidget::shape() const
{
    NM_FUNCTION;
    
    QPainterPath path;
    path.setFillRule(Qt::WindingFill);
    
    path.addRect(this->rect());
    if (mTitleRow){
        path.addPath(mTitleRow->shape());
    }
    return path.simplified();
}

/*!
 \fn void NmHsWidget::onShow()

 called by home screen fw when widget gets visible
 */
void NmHsWidget::onShow()
{
    NM_FUNCTION;
    if (mEngine) {
        mEngine->activate();
    }
}

/*!
 \fn void NmHsWidget::onHide()

 called by home screen fw when widget gets hidden
 */
void NmHsWidget::onHide()
{
    NM_FUNCTION;
    if (mEngine) {
        mEngine->suspend();
    }
}

/*!
 Initializes Localization.
 /post mTranslator constructed & localization file loaded
 */
void NmHsWidget::setupLocalization()
{
    NM_FUNCTION;

    //Use correct localisation
    mTranslator = new QTranslator();
    QString lang = QLocale::system().name();
    mTranslator->load(KNmHsWidgetLocFileName + lang, KNmHsWidgetLocLocation);
    QCoreApplication::installTranslator(mTranslator);
}

/*!
 Initializes UI. Everything that is not done in docml files should be here.
 return true if ok, in error false.
 */
void NmHsWidget::setupUi()
{
    NM_FUNCTION;

    setContentsMargins(KNmHsWidgetContentsMargin, KNmHsWidgetContentsMargin,
        KNmHsWidgetContentsMargin, KNmHsWidgetContentsMargin);

    //Setup layout
    mRowLayout = new QGraphicsLinearLayout(Qt::Vertical);

    mRowLayout->setContentsMargins(KNmHsWidgetContentsMargin, KNmHsWidgetContentsMargin,
        KNmHsWidgetContentsMargin, KNmHsWidgetContentsMargin);
    mRowLayout->setSpacing(KNmHsWidgetContentsMargin);
    setLayout(mRowLayout);

    //background
    mBackgroundFrameDrawer = new HbFrameDrawer(KNmHsWidgetBackgroundImage,
        HbFrameDrawer::NinePieces);
    HbFrameItem* backgroundLayoutItem = new HbFrameItem(mBackgroundFrameDrawer);
    //set to NULL to indicate that ownership transferred
    mBackgroundFrameDrawer = NULL;
    setBackgroundItem(backgroundLayoutItem);
    
    //Create NoMails Label.
    mNoMailsLabel = new HbLabel(this);
    mNoMailsLabel->setPlainText(hbTrId("txt_mail_widget_info_no_messages"));
    HbFontSpec fontSpec(HbFontSpec::Secondary);
    HbStyle style;
    qreal size;
    bool found = style.parameter(QString("hb-param-text-height-tiny"), size);
    if (found) {
        fontSpec.setTextHeight(size);
    }
    mNoMailsLabel->setFontSpec(fontSpec);
    QColor newFontColor;
    newFontColor = HbColorScheme::color("qtc_hs_list_item_content_normal");
    mNoMailsLabel->setTextColor(newFontColor);
    mNoMailsLabel->setAlignment(Qt::AlignCenter);
    mNoMailsLabel->setVisible(false);

}

/*!
 Initializes the widget.
 
 called by home screen fw when widget is added to home screen
 */
void NmHsWidget::onInitialize()
{
    NM_FUNCTION;

    QT_TRY {
        setupUi();
        setupLocalization();

        //Engine construction is 2 phased. 
        mEngine = new NmHsWidgetEmailEngine(mAccountId);
        //Client must connect to exception signals before calling the initialize function
        //because we don't want to miss any signals.
        connect(mEngine, SIGNAL( exceptionOccured(const int&) ), this,
            SLOT( onEngineException(const int&) ));
        if (!mEngine->initialize()) {
            //engine construction failed. Give up.
            emit error();
            return;
        }

        //construct and load docml for title row
        mTitleRow = new NmHsWidgetTitleRow(this);
        if (!mTitleRow->setupUI()) {
            //if docml loading fails no point to proceed
            emit error();
            return;
        }
        mRowLayout->addItem(mTitleRow);
        mTitleRow->updateAccountName(mEngine->accountName());

        //create observer for date/time change events
        mDateObserver = new NmHsWidgetDateTimeObserver();

        //Crete MailRows and associated connections
        createMailRowsList();

        updateMailData();
        mTitleRow->updateUnreadCount(mEngine->unreadCount());
        mTitleRow->setAccountIcon(mAccountIconName);
        mTitleRow->setExpandCollapseIcon(mIsExpanded);

        //Get signals about changes in mail data
        connect(mEngine, SIGNAL( mailDataChanged() ), this, SLOT( updateMailData() ));

        //Get Signals about changes in unread count
        connect(mEngine, SIGNAL( unreadCountChanged(const int&) )
                ,mTitleRow, SLOT( updateUnreadCount(const int&) ) );
        
        //Get signals about account name changes
        connect(mEngine, SIGNAL( accountNameChanged(const QString&) )
                ,mTitleRow, SLOT( updateAccountName(const QString&) ) );

	    //Get signals about user actions
	    connect(mTitleRow, SIGNAL( mailboxLaunchTriggered() )
	            ,mEngine, SLOT( launchMailAppInboxView() ) );
	    connect(mTitleRow, SIGNAL( expandCollapseButtonPressed() )
	            ,this, SLOT( handleExpandCollapseEvent() ) );

    }
    QT_CATCH(...) {
        emit error();
    }

}


/*!
 updateMailData slot
 */
void NmHsWidget::updateMailData()
{
    NM_FUNCTION;

    QList<NmMessageEnvelope> envelopes;
    int count = 0;
    if (mIsExpanded) {
        count = mEngine->getEnvelopes(envelopes, KMaxNumberOfMailsShown);
    }

    updateLayout(count);
    //count is safe for envelopes and mMailRows
    for (int i = 0; i < count; i++) {
        mMailRows.at(i)->updateMailData(envelopes.at(i));
    }
}

/*!
 Sets monitored account id from given string
 Needed for home screen framework which supports only QString type properties
 */
void NmHsWidget::setAccountId(const QString &text)
{
    NM_FUNCTION;

    bool ok;
    quint64 id = text.toULongLong(&ok);
    if (!ok) {
        NM_ERROR(1, "NmHsWidget::setAccountId: invalid account ID data, signal finished()!!!");
        //No valid account id so give up
        emit finished();
        return;
    }

    mAccountId.setId(id);
}

/*!
 Returns monitored account id as a string
 Needed for home screen framework which supports only QString type properties
 */
QString NmHsWidget::accountId() const
{
    NM_FUNCTION;
    return QString::number(mAccountId.id());
}

/*!
 Sets monitored account icon name from given string
 */
void NmHsWidget::setAccountIconName(const QString &text)
{
    NM_FUNCTION;
    mAccountIconName = text;
}

/*!
 Returns monitored account icon name
 */
QString NmHsWidget::accountIconName() const
{
    NM_FUNCTION;
    return mAccountIconName;
}

/*!
 Slot to handle expand/collapse trigger event
 */
void NmHsWidget::handleExpandCollapseEvent()
{
    NM_FUNCTION;
    toggleExpansionState();
}

/*!
 Sets widget expand/collapse state
 /post widget expansion state is changed
 */
void NmHsWidget::toggleExpansionState()
{
    NM_FUNCTION;

    mIsExpanded = !mIsExpanded;

    //save new state to home screen
    QStringList propertiesList;
    propertiesList.append("widgetState");
    emit setPreferences(propertiesList);

    //handle state change drawing
    updateMailData();

    mTitleRow->setExpandCollapseIcon(mIsExpanded);
}

/*!
 Sets expand/collapse state from given string (needed by homescreen)
 */
void NmHsWidget::setWidgetStateProperty(QString value)
{
    NM_FUNCTION;
    if (value == KNmHsWidgetStateCollapsed) {
        mIsExpanded = false;
    }
    else {
        mIsExpanded = true;
    }
}

/*!
 Returns widget expand/collapse state as string (needed by homescreen) 
 */
QString NmHsWidget::widgetStateProperty()
{
    NM_FUNCTION;
    if (mIsExpanded) {
        return KNmHsWidgetStateExpanded;
    }
    else {
        return KNmHsWidgetStateCollapsed;
    }
}

/*!
 Updates mMailRows list to include KMaxNumberOfMailsShown mail row widgets
 /post mMailRows contains KMaxNumberOfMailsShown mailRows 
 */
void NmHsWidget::createMailRowsList()
{
    NM_FUNCTION;

    //make sure that there are as many email rows as needed
    while (mMailRows.count() < KMaxNumberOfMailsShown) {
        NmHsWidgetEmailRow *row = new NmHsWidgetEmailRow(this);
        if (!row->setupUI()) {
            NM_ERROR(1, "NmHsWidget::createMailRowsList row->setUpUI() fails");
            //if setupUI fails no point to proceed
            emit error();
            return;
        }
        connect(row, SIGNAL(mailViewerLaunchTriggered(const NmId&)), mEngine,
            SLOT(launchMailAppMailViewer(const NmId&)));
        connect(mDateObserver, SIGNAL(dateTimeChanged()), row, SLOT(updateDateTime()));
        mMailRows.append(row);
    }

}

/*!
 Updates the Layout to contain the right items
 /param mailCount defines how many emails is to be shown
 /post If widget is collapsed, the layout contains only titleRow widget.
 If widget is expanded and mailCount is 0 layout will contain
 titlerow & noMailsLabel. 
 If widget is expanded and mailCount is greter
 than zero, layout will contain titlerow and KMaxNumberOfMailsShown times
 emailrow(s)
 */
void NmHsWidget::updateLayout(const int mailCount)
{
    NM_FUNCTION;
    if (mIsExpanded) {
        if (mailCount == 0) {
            addNoMailsLabelToLayout();
            removeEmailRowsFromLayout();
        }
        else {
            removeNoMailsLabelFromLayout();
            addEmailRowsToLayout();
        }
    }
    else {
        removeNoMailsLabelFromLayout();
        removeEmailRowsFromLayout();
    }

    //resize the widget to new layout size
    setPreferredSize(mRowLayout->preferredSize());

    updateMailRowsVisibility(mailCount);
}

/*!
 Updates mNoMailsLabel visibility based on widget state
 /param mailCount defines how many mail rows is needed
 /post if mail count is 0 and mIsExpanded equals true, then
 the mNoMailLabel is added to the mRowLayout. 
 */
void NmHsWidget::addNoMailsLabelToLayout()
{
    NM_FUNCTION;
    //Use sizes defined for titlerow and mailrow docml to indentify the correct size
    //for the mNoMailslabel
    if (mNoMailsLabel->isVisible() || mMailRows.isEmpty()) {
        return;
    }
    QSizeF mailLabelSize(mTitleRow->maximumWidth(), KMaxNumberOfMailsShown
        * mMailRows.first()->maximumHeight());
    mNoMailsLabel->setPreferredSize(mailLabelSize);
    mNoMailsLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    //Add mNoMailsLabel to layout if not yet there and show it
    mRowLayout->addItem(mNoMailsLabel);
    //resize the widget to new layout size
    mNoMailsLabel->show();
}

/*!
 removeNoMailsLabelFromLayout removes mNoMailsLabel from the layout
 /post mNoMailsLabel is not in mRowLayout
 */
void NmHsWidget::removeNoMailsLabelFromLayout()
{
    NM_FUNCTION;
    //remove mNoMailsLabel from Layout and hide it
    mRowLayout->removeItem(mNoMailsLabel);
    mNoMailsLabel->hide();
}

/*!
 addEmailRowsToLayout adds every emailrow to the layout
 /post all elements in mMailRows are added to mRowLayout
 */
void NmHsWidget::addEmailRowsToLayout()
{
    NM_FUNCTION;
    foreach(NmHsWidgetEmailRow *row, mMailRows)
        {
            mRowLayout->addItem(row);
        }
}

/*!
 removeEmailRowsFromLayout removes every emailrow from the layout
 /post none of the elements in mMailRows are in mRowLayout
 */
void NmHsWidget::removeEmailRowsFromLayout()
{
    NM_FUNCTION;
    foreach(NmHsWidgetEmailRow *row, mMailRows)
        {
            mRowLayout->removeItem(row);
        }
}

/*!
 Updates mail row visibilities in static widget
 /param visibleCount defines how many items do have mail data
 /post all row items having mail data are visible, other rows are hidden
 */
void NmHsWidget::updateMailRowsVisibility(const int visibleCount)
{
    NM_FUNCTION;

    // set visible as many rows as requested by visibleCount param
    bool isVisible;

    for (int i = 0; i < mMailRows.count(); i++) {
        isVisible = false;
        if ((mIsExpanded) && (i < visibleCount)) {
            isVisible = true;
        }
        mMailRows.at(i)->setVisible(isVisible);
    }
}

/*!
 onEngineException (NmHsWidgetEmailEngineExceptionCode exc)
 signals widget to be finalized
 /param exc exception type
 */
void NmHsWidget::onEngineException(const int& exc)
{
    NM_FUNCTION;
    switch (exc) {
        case (NmEngineExcAccountDeleted):
            emit finished(); //succesful ending
            break;
        case (NmEngineExcFailure):
            emit error(); //failure
            break;
        default:
            break;
    }
}