--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emailuis/nmhswidget/src/nmhswidget.cpp Tue Aug 31 15:04:17 2010 +0300
@@ -0,0 +1,596 @@
+/*
+ * 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 <hbdocumentloader.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),
+ mMainContainer(0),
+ mEmptySpaceContainer(0),
+ mWidgetContainer(0),
+ mTitleRow(0),
+ mContentContainer(0),
+ mNoMailsLabel(0),
+ mContentLayout(0),
+ mBackgroundFrameDrawer(0),
+ mTranslator(0),
+ mEngine(0),
+ mAccountId(0),
+ mAccountIconName(),
+ mDateObserver(0),
+ mIsExpanded(false)
+{
+ 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);
+ if (mWidgetContainer){
+ //add mWidgetContainer using geometry to get
+ //correct point for top-left-corner
+ QRectF widgetRect = mWidgetContainer->geometry();
+ path.addRect(widgetRect);
+
+ //then fetch shape from title row
+ QPainterPath titlepath;
+ titlepath.addPath(mTitleRow->shape());
+ //translate it's location to be inside mWidgetContainer
+ titlepath.translate(widgetRect.topLeft());
+ //and finally add it to path
+ path.addPath(titlepath);
+ }
+ //simplified path, i.e. only outlines
+ 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();
+ }
+}
+
+/*!
+ \fn bool NmHsWidget::loadDocML(HbDocumentLoader &loader)
+
+ loads layout data and child items from docml file. Must be called after constructor.
+ /return true if loading succeeded, otherwise false. False indicates that object is unusable
+ */
+bool NmHsWidget::loadDocML(HbDocumentLoader &loader)
+{
+ NM_FUNCTION;
+
+ bool ok(false);
+ loader.load(KNmHsWidgetDocML, &ok);
+
+ if(ok) {
+ mMainContainer = static_cast<HbWidget*> (loader.findWidget(KNmHsWidgetMainContainer));
+ mWidgetContainer = static_cast<HbWidget*> (loader.findWidget(KNmHsWidgetContainer));
+ mContentContainer = static_cast<HbWidget*> (loader.findWidget(KNmHsWidgetContentContainer));
+ mEmptySpaceContainer = static_cast<HbWidget*> (loader.findWidget(KNmHsWidgetEmptySpaceContainer));
+ mNoMailsLabel = static_cast<HbLabel*> (loader.findWidget(KNmHsWidgetNoMailsLabel));
+ if (!mMainContainer || !mWidgetContainer || !mContentContainer
+ || !mEmptySpaceContainer || !mNoMailsLabel ) {
+ //something failed in documentloader, no point to continue
+ NM_ERROR(1,"NmHsWidget::loadDocML fail @ containers or label");
+ ok = false;
+ }
+ }
+ return ok;
+}
+
+/*!
+ 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;
+
+ //main level layout needed to control docml objects
+ QGraphicsLinearLayout *widgetLayout = new QGraphicsLinearLayout(Qt::Vertical);
+ widgetLayout->setContentsMargins(KNmHsWidgetContentsMargin, KNmHsWidgetContentsMargin,
+ KNmHsWidgetContentsMargin, KNmHsWidgetContentsMargin);
+ widgetLayout->setSpacing(KNmHsWidgetContentsMargin);
+ widgetLayout->addItem(mMainContainer);
+ this->setLayout(widgetLayout);
+
+ //fetch pointer to content container layout
+ //to be able to add/remove email rows and no mails label
+ mContentLayout = (QGraphicsLinearLayout*) mContentContainer->layout();
+
+ //set noMailsLabel properties not supported by doc loader
+ QColor newFontColor;
+ newFontColor = HbColorScheme::color("qtc_hs_list_item_content_normal");
+ mNoMailsLabel->setTextColor(newFontColor);
+ mNoMailsLabel->setVisible(true);
+
+ mContentLayout->removeItem(mNoMailsLabel);
+
+ //widget background
+ mBackgroundFrameDrawer = new HbFrameDrawer(KNmHsWidgetBackgroundImage,
+ HbFrameDrawer::NinePieces);
+ HbFrameItem* backgroundLayoutItem = new HbFrameItem(mBackgroundFrameDrawer);
+ //set to NULL to indicate that ownership transferred
+ mBackgroundFrameDrawer = NULL;
+ mWidgetContainer->setBackgroundItem(backgroundLayoutItem);
+}
+
+/*!
+ Initializes the widget.
+
+ called by home screen fw when widget is added to home screen
+ */
+void NmHsWidget::onInitialize()
+{
+ NM_FUNCTION;
+
+ QT_TRY {
+ // Use document loader to load the contents
+ HbDocumentLoader loader;
+ //setup localization before docml loading
+ setupLocalization();
+
+ //load containers and mNoMailsLabel
+ if (!loadDocML(loader)) {
+ NM_ERROR(1,"NmHsWidget::onInitialize Fail @ loader");
+ emit error(); //failure, no point to continue
+ return;
+ }
+
+ //construct title row
+ mTitleRow = new NmHsWidgetTitleRow(this);
+ if (!mTitleRow->setupUI(loader)) {
+ //title row creation failed
+ NM_ERROR(1,"NmHsWidget::onInitialize fail @ titlerow");
+ emit error(); //failure, no point to continue
+ return;
+ }
+
+ setupUi();
+
+ //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.
+ NM_ERROR(1,"NmHsWidget::onInitialize fail @ engine");
+ emit error();
+ return;
+ }
+
+ 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() ) );
+
+ setMinimumSize(mTitleRow->minimumWidth(),
+ mEmptySpaceContainer->minimumHeight() + mTitleRow->minimumHeight());
+ }
+ QT_CATCH(...) {
+ NM_ERROR(1,"NmHsWidget::onInitialize fail @ 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) {
+ //set container height to content height
+ qreal contentHeight = KMaxNumberOfMailsShown
+ * mMailRows.first()->maximumHeight();
+ mContentContainer->setMaximumHeight(contentHeight);
+ mContentContainer->setVisible(true);
+ if (mailCount == 0) {
+ addNoMailsLabelToLayout();
+ removeEmailRowsFromLayout();
+ }
+ else {
+ removeNoMailsLabelFromLayout();
+ addEmailRowsToLayout();
+ }
+ }
+ else {
+ removeNoMailsLabelFromLayout();
+ removeEmailRowsFromLayout();
+ mContentContainer->setVisible(false);
+ mContentContainer->setMaximumHeight(0);
+ }
+
+ //resize the widget to new layout size
+ qreal totalHeight = mEmptySpaceContainer->preferredHeight() + mTitleRow->containerHeight() + mContentContainer->maximumHeight();
+ //set maximum sizes, otherwise widget will stay huge also when collapsed
+ setMaximumHeight(totalHeight);
+ mMainContainer->setMaximumHeight(totalHeight);
+ mWidgetContainer->setMaximumHeight(totalHeight - mEmptySpaceContainer->preferredHeight());
+ //resize here or widget cannot draw mail rows when expanding
+ resize(mTitleRow->maximumWidth(), totalHeight);
+ mMainContainer->resize(mTitleRow->maximumWidth(), totalHeight);
+ mWidgetContainer->resize(mTitleRow->maximumWidth(), totalHeight - mEmptySpaceContainer->preferredHeight());
+
+ 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 mContentLayout.
+ */
+void NmHsWidget::addNoMailsLabelToLayout()
+{
+ NM_FUNCTION;
+
+ if (mNoMailsLabel->isVisible() || mMailRows.isEmpty()) {
+ return;
+ }
+ //Add mNoMailsLabel to layout if not yet there and show it
+ mContentLayout->addItem(mNoMailsLabel);
+ //resize the widget to new layout size
+ mNoMailsLabel->show();
+}
+
+/*!
+ removeNoMailsLabelFromLayout removes mNoMailsLabel from the layout
+ /post mNoMailsLabel is not in mContentLayout
+ */
+void NmHsWidget::removeNoMailsLabelFromLayout()
+{
+ NM_FUNCTION;
+ //remove mNoMailsLabel from Layout and hide it
+ mContentLayout->removeItem(mNoMailsLabel);
+ mNoMailsLabel->hide();
+}
+
+/*!
+ addEmailRowsToLayout adds every emailrow to the layout
+ /post all elements in mMailRows are added to mContentLayout
+ */
+void NmHsWidget::addEmailRowsToLayout()
+{
+ NM_FUNCTION;
+ foreach(NmHsWidgetEmailRow *row, mMailRows)
+ {
+ mContentLayout->addItem(row);
+ }
+}
+
+/*!
+ removeEmailRowsFromLayout removes every emailrow from the layout
+ /post none of the elements in mMailRows are in mContentLayout
+ */
+void NmHsWidget::removeEmailRowsFromLayout()
+{
+ NM_FUNCTION;
+ foreach(NmHsWidgetEmailRow *row, mMailRows)
+ {
+ mContentLayout->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;
+ }
+}