emailuis/nmhswidget/src/nmhswidget.cpp
changeset 47 f83bd4ae1fe3
parent 43 99bcbff212ad
child 49 00c7ae862740
--- a/emailuis/nmhswidget/src/nmhswidget.cpp	Fri Jun 11 16:42:02 2010 +0300
+++ b/emailuis/nmhswidget/src/nmhswidget.cpp	Thu Jun 24 14:32:18 2010 +0300
@@ -20,6 +20,7 @@
 #include <QTranslator>
 #include <hbframedrawer.h>
 #include <hbframeitem.h>
+#include <hblabel.h>
 #include "nmcommon.h"
 #include "nmhswidget.h"
 #include "nmhswidgetemailengine.h"
@@ -40,15 +41,15 @@
       mTranslator(0),
       mBackgroundFrameDrawer(0),
       mIsExpanded(false),
-      mStaticWidget(true),
-      mDateObserver(0)
+      mDateObserver(0),
+      mNoMailsLabel(0)
 {
     NM_FUNCTION;
 }
 
 /*!
-    Destructor
-*/
+ Destructor
+ */
 NmHsWidget::~NmHsWidget()
 {
     NM_FUNCTION;
@@ -67,134 +68,163 @@
 }
 
 /*!
-    \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()
-
-    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
-    returns false in failure, otherwise true
-*/
-bool NmHsWidget::setupLocalization()
+ \fn void NmHsWidget::onHide()
+
+ called by home screen fw when widget gets hidden
+ */
+void NmHsWidget::onHide()
 {
     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;
+    if (mEngine) {
+        mEngine->suspend();
+    }
 }
 
 /*!
-    Initializes UI. Everything that is not done in docml files should be here.
-    return true if ok, in error false.
-*/
+ 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);
-    
+
+    setContentsMargins(KNmHsWidgetContentsMargin, KNmHsWidgetContentsMargin,
+        KNmHsWidgetContentsMargin, KNmHsWidgetContentsMargin);
+
     //Setup layout
     mRowLayout = new QGraphicsLinearLayout(Qt::Vertical);
 
     mRowLayout->setContentsMargins(KNmHsWidgetContentsMargin, KNmHsWidgetContentsMargin,
-            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 );
+
+    //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
-*/
+ Initializes the widget.
+ 
+ called by home screen fw when widget is added to home screen
+ */
 void NmHsWidget::onInitialize()
 {
     NM_FUNCTION;
-    
-    QT_TRY{       
+
+    QT_TRY {
         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.
             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;
-            }
 
         //construct and load docml for title row
-        mTitleRow = new NmHsWidgetTitleRow(); 
-        if( !mTitleRow->loadDocML()){
+        mTitleRow = new NmHsWidgetTitleRow(this);
+        if (!mTitleRow->setupUI()) {
             //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&) ) );
@@ -209,76 +239,58 @@
 	    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()); 
-		}
     }
-    QT_CATCH(...){
+    QT_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 +298,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 +307,8 @@
 }
 
 /*!
-    Returns monitored account icon name
-*/
+ Returns monitored account icon name
+ */
 QString NmHsWidget::accountIconName() const
 {
     NM_FUNCTION;
@@ -304,8 +316,8 @@
 }
 
 /*!
-    Slot to handle expand/collapse trigger event
-*/
+ Slot to handle expand/collapse trigger event
+ */
 void NmHsWidget::handleExpandCollapseEvent()
 {
     NM_FUNCTION;
@@ -313,153 +325,212 @@
 }
 
 /*!
-    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) {
+        if (mailCount == 0) {
+            addNoMailsLabelToLayout();
+            removeEmailRowsFromLayout();
+        }
+        else {
+            removeNoMailsLabelFromLayout();
+            addEmailRowsToLayout();
         }
-    else
+    }
+    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)
         {
-        return KNmHsWidgetStateCollapsed;
+            mRowLayout->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 mRowLayout
+ */
+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);
+            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
-*/
+ 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;
     }
+}