--- a/emailuis/nmhswidget/src/nmhswidget.cpp Wed Jun 23 18:00:21 2010 +0300
+++ b/emailuis/nmhswidget/src/nmhswidget.cpp Tue Jul 06 14:04:34 2010 +0300
@@ -17,9 +17,11 @@
#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"
@@ -33,22 +35,24 @@
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),
- mStaticWidget(true),
- mDateObserver(0)
+ mDateObserver(0),
+ mNoMailsLabel(0),
+ mWidgetContainer(0),
+ mContentContainer(0),
+ mContentLayout(0)
{
NM_FUNCTION;
}
/*!
- Destructor
-*/
+ Destructor
+ */
NmHsWidget::~NmHsWidget()
{
NM_FUNCTION;
@@ -67,134 +71,195 @@
}
/*!
- \fn void NmHsWidget::onShow()
+ \fn QPainterPath NmHsWidget::shape()
- called by home screen fw when widget gets visible
-*/
+ 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)
- {
+ if (mEngine) {
mEngine->activate();
- }
+ }
}
/*!
- \fn void NmHsWidget::onHide()
+ \fn void NmHsWidget::onHide()
- called by home screen fw when widget gets hidden
-*/
+ called by home screen fw when widget gets hidden
+ */
void NmHsWidget::onHide()
{
NM_FUNCTION;
- if (mEngine)
- {
+ if (mEngine) {
mEngine->suspend();
- }
+ }
}
/*!
- Initializes Localization.
- /post mTranslator constructed & localization file loaded
- returns false in failure, otherwise true
-*/
-bool NmHsWidget::setupLocalization()
-{
- NM_FUNCTION;
-
- //Use correct localisation
- bool ret(false);
- mTranslator = new QTranslator();
- QString lang = QLocale::system().name();
- ret = mTranslator->load(KNmHsWidgetLocFileName + lang, KNmHsWidgetLocLocation);
- QCoreApplication::installTranslator(mTranslator);
-
- return ret;
-}
-
-/*!
- Initializes UI. Everything that is not done in docml files should be here.
- return true if ok, in error false.
-*/
-void NmHsWidget::setupUi()
+ \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;
- setContentsMargins( KNmHsWidgetContentsMargin, KNmHsWidgetContentsMargin,
- KNmHsWidgetContentsMargin, KNmHsWidgetContentsMargin);
+ bool ok(false);
+ loader.load(KNmHsWidgetDocML, &ok);
- //Setup layout
- mRowLayout = new QGraphicsLinearLayout(Qt::Vertical);
+ if(ok) {
+ mWidgetContainer = static_cast<HbWidget*> (loader.findWidget(KNmHsWidgetContainer));
+ mContentContainer = static_cast<HbWidget*> (loader.findWidget(KNmHsWidgetContentContainer));
+ mNoMailsLabel = static_cast<HbLabel*> (loader.findWidget(KNmHsWidgetNoMailsLabel));
+ if (!mWidgetContainer || !mContentContainer || !mNoMailsLabel) {
+ //something failed in documentloader, no point to continue
+ NM_ERROR(1,"NmHsWidget::loadDocML fail @ containers or label");
+ ok = false;
+ }
+ }
+ return ok;
+}
- 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 );
+/*!
+ 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 the widget.
+ 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(mWidgetContainer);
+ 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();
- called by home screen fw when widget is added to home screen
-*/
+ //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;
+ setBackgroundItem(backgroundLayoutItem);
+}
+
+
+/*!
+ Initializes the widget.
+
+ called by home screen fw when widget is added to home screen
+ */
void NmHsWidget::onInitialize()
{
NM_FUNCTION;
-
- QT_TRY{
+
+ QT_TRY {
+
+ // Use document loader to load the contents
+ HbDocumentLoader loader;
+
+ //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();
- //emit error if localization fails
- if(!setupLocalization()){
+ 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.
+ NM_ERROR(1,"NmHsWidget::onInitialize fail @ engine");
emit error();
return;
}
-
- //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;
- }
+
+
+ mTitleRow->updateAccountName(mEngine->accountName());
- //construct and load docml for title row
- mTitleRow = new NmHsWidgetTitleRow();
- if( !mTitleRow->loadDocML()){
- //if docml loading fails no point to proceed
- //but memoryleak must be prevented
- delete mTitleRow;
- mTitleRow = NULL;
- emit error();
- return;
- }
- mRowLayout->addItem(mTitleRow);
- mTitleRow->updateAccountName(mEngine->accountName());
-
- //create observer for date/time change events
- mDateObserver = new NmHsWidgetDateTimeObserver();
-
+ //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() ) );
-
+ 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&) ) );
@@ -208,77 +273,60 @@
,mEngine, SLOT( launchMailAppInboxView() ) );
connect(mTitleRow, SIGNAL( expandCollapseButtonPressed() )
,this, SLOT( handleExpandCollapseEvent() ) );
-
- //resize here so homescreen will place widget correctly on screen
- setPreferredSize( mRowLayout->preferredSize() );
- if (parentWidget()) {
- //to place widget properly after adding to homescreen
- parentWidget()->resize(preferredSize());
- }
+
+ setMinimumSize(mTitleRow->minimumSize());
}
- QT_CATCH(...){
+ QT_CATCH(...) {
+ NM_ERROR(1,"NmHsWidget::onInitialize fail @ catch");
emit error();
}
-
}
-/*!
- Uninitializes the widget.
-
- called by home screen fw when widget is removed from home screen
-*/
-void NmHsWidget::onUninitialize()
-{
- NM_FUNCTION;
-}
/*!
- updateMailData slot
-*/
+ updateMailData slot
+ */
void NmHsWidget::updateMailData()
{
NM_FUNCTION;
-
+
QList<NmMessageEnvelope> envelopes;
int count = 0;
if (mIsExpanded) {
count = mEngine->getEnvelopes(envelopes, KMaxNumberOfMailsShown);
- }
+ }
- updateMailRowsList(count);
-
- for(int i=0; i<envelopes.count(); i++)
- {
- mMailRows[i]->updateMailData( envelopes[i] );
- }
+ 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
-*/
+ 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()!!!");
+ if (!ok) {
+ NM_ERROR(1, "NmHsWidget::setAccountId: invalid account ID data, signal finished()!!!");
//No valid account id so give up
emit finished();
- }
- else
- {
- mAccountId.setId(id);
- }
+ return;
+ }
+
+ mAccountId.setId(id);
}
/*!
- Returns monitored account id as a string
- Needed for home screen framework which supports only QString type properties
-*/
+ Returns monitored account id as a string
+ Needed for home screen framework which supports only QString type properties
+ */
QString NmHsWidget::accountId() const
{
NM_FUNCTION;
@@ -286,8 +334,8 @@
}
/*!
- Sets monitored account icon name from given string
-*/
+ Sets monitored account icon name from given string
+ */
void NmHsWidget::setAccountIconName(const QString &text)
{
NM_FUNCTION;
@@ -295,8 +343,8 @@
}
/*!
- Returns monitored account icon name
-*/
+ Returns monitored account icon name
+ */
QString NmHsWidget::accountIconName() const
{
NM_FUNCTION;
@@ -304,8 +352,8 @@
}
/*!
- Slot to handle expand/collapse trigger event
-*/
+ Slot to handle expand/collapse trigger event
+ */
void NmHsWidget::handleExpandCollapseEvent()
{
NM_FUNCTION;
@@ -313,153 +361,219 @@
}
/*!
- Sets widget expand/collapse state
- /post widget expansion state is changed
-*/
+ 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)
-*/
+ Sets expand/collapse state from given string (needed by homescreen)
+ */
void NmHsWidget::setWidgetStateProperty(QString value)
{
NM_FUNCTION;
- if (value == KNmHsWidgetStateCollapsed)
- {
+ 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;
}
- else
- {
- mIsExpanded = true;
- }
+ connect(row, SIGNAL(mailViewerLaunchTriggered(const NmId&)), mEngine,
+ SLOT(launchMailAppMailViewer(const NmId&)));
+ connect(mDateObserver, SIGNAL(dateTimeChanged()), row, SLOT(updateDateTime()));
+ mMailRows.append(row);
+ }
+
}
/*!
- Returns widget expand/collapse state as string (needed by homescreen)
-*/
-QString NmHsWidget::widgetStateProperty()
+ 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)
- {
- return KNmHsWidgetStateExpanded;
+
+ 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
+ }
+ else {
+ removeNoMailsLabelFromLayout();
+ removeEmailRowsFromLayout();
+ mContentContainer->setVisible(false);
+ mContentContainer->setMaximumHeight(0);
+ }
+
+ //resize the widget to new layout size
+ qreal totalHeight = mTitleRow->preferredHeight() + mContentContainer->maximumHeight();
+ //set maximum size, otherwise widget will stay huge also when collapsed
+ this->setMaximumHeight(totalHeight);
+ //resize here or widget cannot draw mail rows when expanding
+ this->resize(mTitleRow->preferredWidth(), totalHeight);
+
+ 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)
{
- return KNmHsWidgetStateCollapsed;
+ mContentLayout->addItem(row);
}
}
/*!
- Updates mMailRows list to include correct amount of mail row widgets
- /param mailCount defines how many mail rows is needed
- /post mMailRows list includes NmHsWidgetEmailRow for each mail item
-*/
-void NmHsWidget::updateMailRowsList(const int mailCount)
+ removeEmailRowsFromLayout removes every emailrow from the layout
+ /post none of the elements in mMailRows are in mContentLayout
+ */
+void NmHsWidget::removeEmailRowsFromLayout()
{
NM_FUNCTION;
-
- int neededRowsCount = mailCount;
- //force size when static and expanded
- if (mStaticWidget && mIsExpanded)
- {
- neededRowsCount = KMaxNumberOfMailsShown;
- }
-
- while (mMailRows.count() != neededRowsCount)
+ foreach(NmHsWidgetEmailRow *row, mMailRows)
{
- //more mails to show than rows
- if (mMailRows.count() < neededRowsCount)
- {
- NmHsWidgetEmailRow *row = new NmHsWidgetEmailRow();
- if( !row->loadDocML()){
- NM_ERROR(1,"NmHsWidget::updateMailRowsList row->loadDocML() fails");
- //if docml loading fails no point to proceed
- //but memoryleak must be prevented
- delete row;
- row = NULL;
- emit error();
- return;
- }
- connect(row, SIGNAL(mailViewerLaunchTriggered(const NmId&))
- ,mEngine, SLOT(launchMailAppMailViewer(const NmId&)));
- connect( mDateObserver, SIGNAL(dateTimeChanged())
- ,row, SLOT(updateDateTime()) );
- mMailRows.append(row);
- mRowLayout->addItem(row);
- }
- //too many rows
- else if (mMailRows.count() > neededRowsCount)
- {
- mRowLayout->removeItem(mMailRows.last());
- delete mMailRows.takeLast();
- }
- }
- __ASSERT_ALWAYS( mMailRows.count() == neededRowsCount, User::Panic(_L("Invalid"), 500) );
-
- //resize the widget to new layout size
- setPreferredSize( mRowLayout->preferredSize() );
-
- if (mStaticWidget)
- {
- this->updateMailRowsVisibility(mailCount);
+ 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
-*/
+ 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++)
- {
+
+ for (int i = 0; i < mMailRows.count(); i++) {
isVisible = false;
- if ((mIsExpanded) && (i < visibleCount))
- {
+ if ((mIsExpanded) && (i < visibleCount)) {
isVisible = true;
- }
+ }
mMailRows.at(i)->setVisible(isVisible);
- }
+ }
}
/*!
- onEngineException (NmHsWidgetEmailEngineExceptionCode exc)
- signals widget to be finalized
- /param exc exception type
-*/
+ onEngineException (NmHsWidgetEmailEngineExceptionCode exc)
+ signals widget to be finalized
+ /param exc exception type
+ */
void NmHsWidget::onEngineException(const int& exc)
- {
+{
NM_FUNCTION;
- switch (exc)
- {
+ switch (exc) {
case (NmEngineExcAccountDeleted):
- emit finished(); //succesful ending
- break;
+ emit finished(); //succesful ending
+ break;
case (NmEngineExcFailure):
- emit error(); //failure
- break;
- default:
- break;
- }
+ emit error(); //failure
+ break;
+ default:
+ break;
}
+}