emailuis/nmhswidget/src/nmhswidget.cpp
changeset 23 2dc6caa42ec3
parent 20 ecc8def7944a
child 30 759dc5235cdb
--- a/emailuis/nmhswidget/src/nmhswidget.cpp	Mon May 03 12:23:15 2010 +0300
+++ b/emailuis/nmhswidget/src/nmhswidget.cpp	Fri May 14 15:41:10 2010 +0300
@@ -18,6 +18,9 @@
 #include <QtGui>
 #include <QGraphicsLinearLayout>
 #include <hbcolorscheme.h>
+#include <QTranslator>
+#include <hbframedrawer.h>
+#include <hbframeitem.h>
 #include "nmcommon.h"
 #include "nmhswidget.h"
 #include "nmhswidgetemailengine.h"
@@ -25,26 +28,23 @@
 #include "nmhswidgettitlerow.h"
 #include "nmhswidgetemailrow.h"
 #include "nmhswidgetconsts.h"
+#include "nmhswidgetdatetimeobserver.h"
 
 NmHsWidget::NmHsWidget(QGraphicsItem *parent, Qt::WindowFlags flags)
     : HbWidget(parent, flags), 
       mEngine(0),
       mRowLayout(0),
-      mTitleRow( new NmHsWidgetTitleRow() ),
-      mAccountId(0)
+      mTitleRow(0),
+      mAccountId(0),
+      mAccountIconName(0),
+      mTranslator(0),
+      mBackgroundFrameDrawer(0),
+      mIsExpanded(true),
+      mStaticWidget(true),
+      mDateObserver(0)
 {
     qDebug() << "NmHsWidget::NmHsWidget IN -->>";
-
-    this->setContentsMargins( KNmHsWidgetContentsMargin, KNmHsWidgetContentsMargin,
-            KNmHsWidgetContentsMargin, KNmHsWidgetContentsMargin);
-    //Setup layout
-    mRowLayout = new QGraphicsLinearLayout(Qt::Vertical);
-    mRowLayout->setContentsMargins(KNmHsWidgetContentsMargin, KNmHsWidgetContentsMargin,
-            KNmHsWidgetContentsMargin, KNmHsWidgetContentsMargin);
-    mRowLayout->setSpacing(KNmHsWidgetContentsMargin);
-    mRowLayout->addItem(mTitleRow);
-    setLayout(mRowLayout);
-    
+       
     qDebug() << "NmHsWidget::NmHsWidget OUT <<--";
 }
 
@@ -54,18 +54,32 @@
 NmHsWidget::~NmHsWidget()
 {
     qDebug() << "NmHsWidget::~NmHsWidget IN -->>";
-    if(mEngine)
-        {
+    if(mTranslator){
+        delete mTranslator;
+        mTranslator = NULL;
+    }
+    
+    if(mEngine){
         delete mEngine;
         mEngine = NULL;
         }
+    
+    if(mBackgroundFrameDrawer){
+        delete mBackgroundFrameDrawer;
+        mBackgroundFrameDrawer = NULL;
+        }
+		
+	if(mDateObserver){
+        delete mDateObserver;
+        mDateObserver = NULL;
+        }
     qDebug() << "NmHsWidget::~NmHsWidget OUT <<--";
 }
 
 /*!
     \fn void NmHsWidget::onShow()
 
-    Shows the widget
+    called by home screen fw when widget gets visible
 */
 void NmHsWidget::onShow()
 {
@@ -77,11 +91,10 @@
     qDebug() << "NmHsWidget::onShow OUT <<--";
 }
 
-
 /*!
     \fn void NmHsWidget::onHide()
 
-    Hides the widget
+    called by home screen fw when widget gets hidden
 */
 void NmHsWidget::onHide()
 {
@@ -93,36 +106,141 @@
     qDebug() << "NmHsWidget::onHide OUT <<--";
 }
 
+/*!
+    Initializes Localization.
+    /post mTranslator constructed & localization file loaded
+    returns false in failure, otherwise true
+*/
+bool NmHsWidget::setupLocalization()
+{
+    qDebug() << "NmHsWidget::setupLocalization IN -->>";
+    
+    //Use correct localisation
+    bool ret(false); 
+    mTranslator = new QTranslator();
+    QString lang = QLocale::system().name();
+    ret = mTranslator->load(KNmHsWidgetLocFileName + lang, KNmHsWidgetLocLocation);
+    qDebug() << "NmHsWidget::setupLocalization mTranslator->load loadSucceed:"<<ret;
+    QCoreApplication::installTranslator(mTranslator);
+
+    qDebug() << "NmHsWidget::setupLocalization OUT <<--";
+    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()
+{
+    qDebug() << "NmHsWidget::setupUi IN -->>";
+    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 );
+   
+   qDebug() << "NmHsWidget::setupUi OUT -->>";
+}
 
 /*!
     Initializes the widget.
+    
+    called by home screen fw when widget is added to home screen
 */
 void NmHsWidget::onInitialize()
 {
-    qDebug() << "NmHsWidget::onInitialize IN -->>";
+    QT_TRY{
+        qDebug() << "NmHsWidget::onInitialize IN -->>";
+        
+        setupUi();
+        //emit error if localization fails
+        if(!setupLocalization()){
+            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;
+            }
 
-    mEngine = new NmHsWidgetEmailEngine( mAccountId ); 
-    mTitleRow->updateAccountName(mEngine->accountName());
-    updateMailData();
-    mTitleRow->updateUnreadCount(mEngine->unreadCount());
+        //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());
     
-    //Get signals about changes in mail data
-    connect(mEngine, SIGNAL( mailDataChanged() )
-            ,this, SLOT( updateMailData() ) );
+	    //create observer for date/time change events
+	    mDateObserver = new NmHsWidgetDateTimeObserver();
     
-    //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&) ) );
+        updateMailData();
+        mTitleRow->updateUnreadCount(mEngine->unreadCount());
+        mTitleRow->setAccountIcon(mAccountIconName);
+        
+        //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&) ) );
 
-    qDebug() << "NmHsWidget::onInitialize OUT <<--";  
+	    //Get signals about user actions
+	    connect(mTitleRow, SIGNAL( mailboxLaunchTriggered() )
+	            ,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()); 
+		}
+        qDebug() << "NmHsWidget::onInitialize OUT <<--";  
+    }
+    QT_CATCH(...){
+        emit error();
+    }
+
 }
 
 /*!
     Uninitializes the widget.
+    
+    called by home screen fw when widget is removed from home screen
 */
 void NmHsWidget::onUninitialize()
 {
@@ -132,45 +250,21 @@
 }
 
 /*!
-    Paints widget
-*/
-void NmHsWidget::paint(QPainter *painter, 
-                          const QStyleOptionGraphicsItem *option, 
-                          QWidget *widget)
-{
-    Q_UNUSED(option);
-    Q_UNUSED(widget);
-    //----- backgroud ----------------
-    painter->setOpacity(KNmHsWidgetBackgroundOpacity);
-    QColor backgroundColor(HbColorScheme::color(KBackgroundColorAttribute));
-    // frame is not wanted to be drawn, thus pen color is same as backround color
-    painter->setPen(QPen(backgroundColor, 0));
-    painter->setBrush(backgroundColor);
-    painter->drawRoundedRect(rect(), KNmHsWidgetShoulderRadius, 
-            KNmHsWidgetShoulderRadius);
-    painter->setOpacity(1); //set opacity back to default
-}
-
-/*!
     updateMailData slot
 */
 void NmHsWidget::updateMailData()
 {
     qDebug() << "NmHsWidget::updateData IN -->>";
     QList<NmMessageEnvelope> envelopes;
-    int count = mEngine->getEnvelopes(envelopes, 2);
-    //TODO: needs error check for -1 ?
+    int count = 0;
+    if (mIsExpanded) {
+        count = mEngine->getEnvelopes(envelopes, KMaxNumberOfMailsShown);
+        }
+
     updateMailRowsList(count);
     
     for(int i=0; i<envelopes.count(); i++)
         {
-        qDebug() << "env:" << QString::number(i) << "dispName: " << envelopes[i].sender().displayName();
-        qDebug() << "env:" << QString::number(i) << "dispName: " << envelopes[i].sender().address();
-        qDebug() << "env:" << QString::number(i) << "subject:" << envelopes[i].subject();
-        qDebug() << "env:" << QString::number(i) << "isRead: " << envelopes[i].isRead();
-        qDebug() << "env:" << QString::number(i) << "date: " << envelopes[i].sentTime();
-        qDebug() << "env:" << QString::number(i) << "priority: " << envelopes[i].priority();
-        qDebug() << "env:" << QString::number(i) << "attachments: " << envelopes[i].hasAttachments();
         mMailRows[i]->updateMailData( envelopes[i] );
         }
     qDebug() << "NmHsWidget::updateData OUT <<--"; 
@@ -178,7 +272,7 @@
 
 /*!
     Sets monitored account id from given string
-    Needed for home screen framework thich supports only QString type properties
+    Needed for home screen framework which supports only QString type properties
 */
 void NmHsWidget::setAccountId(const QString &text)
 {
@@ -187,9 +281,9 @@
     quint64 id = text.toULongLong(&ok);
     if (!ok)
         {
-        // TODO: assert here if conversion failed?
-        qDebug() << "NmHsWidget::setAccountId: invalid account ID data!!!"; 
-        mAccountId.setId(0);
+        qDebug() << "NmHsWidget::setAccountId: invalid account ID data, signal finished()!!!"; 
+        //No valid account id so give up
+        emit finished();
         }
     else
         {
@@ -209,57 +303,190 @@
 }
 
 /*!
-    Updates list to include correct amount of mail row widgets
+    Sets monitored account icon name from given string
+*/
+void NmHsWidget::setAccountIconName(const QString &text)
+{
+    qDebug() << "NmHsWidget::setAccountIconName IN -->>"; 
+    mAccountIconName = text;
+    qDebug() << "NmHsWidget::setAccountIconName OUT <<--"; 
+}
+
+/*!
+    Returns monitored account icon name
+*/
+QString NmHsWidget::accountIconName() const
+{
+    qDebug() << "NmHsWidget::accountIconName()"; 
+    return mAccountIconName;
+}
+
+/*!
+    Slot to handle expand/collapse trigger event
+*/
+void NmHsWidget::handleExpandCollapseEvent()
+{
+    qDebug() << "NmHsWidget::handleExpandCollapseEvent IN -->>";
+    toggleExpansionState();
+    qDebug() << "NmHsWidget::handleExpandCollapseEvent OUT <<--"; 
+}
+
+/*!
+    Sets widget expand/collapse state
+    /post widget expansion state is changed
 */
-void NmHsWidget::updateMailRowsList(int mailCount)
+void NmHsWidget::toggleExpansionState()
+{
+    qDebug() << "NmHsWidget::setExpanded IN -->>"; 
+
+    mIsExpanded = !mIsExpanded;
+    
+    //save new state to home screen
+    QStringList propertiesList;
+    propertiesList.append("widgetState");
+    emit setPreferences(propertiesList);
+    
+    //handle state change drawing
+    updateMailData();
+    
+    qDebug() << "NmHsWidget::setExpanded OUT <<--"; 
+}
+
+/*!
+    Sets expand/collapse state from given string (needed by homescreen)
+*/
+void NmHsWidget::setWidgetStateProperty(QString value)
+{
+    qDebug() << "NmHsWidget::setWidgetStateProperty IN -->>"; 
+    if (value == KNmHsWidgetStateCollapsed)
+        {
+        mIsExpanded = false;
+        }
+    else
+        {
+        mIsExpanded = true;
+        }
+    qDebug() << "NmHsWidget::setWidgetStateProperty OUT <<--"; 
+}
+
+/*!
+    Returns widget expand/collapse state as string (needed by homescreen) 
+*/
+QString NmHsWidget::widgetStateProperty()
+{
+    qDebug() << "NmHsWidget::widgetStateProperty()";
+    if (mIsExpanded)
+        {
+        return KNmHsWidgetStateExpanded;
+        }
+    else
+        {
+        return KNmHsWidgetStateCollapsed;
+        }
+}
+
+/*!
+    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)
 {
     qDebug() << "NmHsWidget::updateMailRowsList IN -->>";
     qDebug() << "NmHsWidget - mMailRows.count() == " <<  mMailRows.count();
     qDebug() << "NmHsWidget - ordered count == " <<  mailCount;
-    while (mMailRows.count() != mailCount)
+    
+    int neededRowsCount = mailCount;
+    //force size when static and expanded
+    if (mStaticWidget && mIsExpanded)
+        {
+        neededRowsCount = KMaxNumberOfMailsShown;
+        }
+    
+    while (mMailRows.count() != neededRowsCount)
         {
         //more mails to show than rows
-        if (mMailRows.count() < mailCount)
+        if (mMailRows.count() < neededRowsCount)
             {
             qDebug() << "NmHsWidget - add new mail row";
             NmHsWidgetEmailRow *row = new NmHsWidgetEmailRow();
+            if( !row->loadDocML()){
+                qDebug() << "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() > mailCount)
+        else if (mMailRows.count() > neededRowsCount)
             {
             qDebug() << "NmHsWidget - remove mail row";
             mRowLayout->removeItem(mMailRows.last());
             delete mMailRows.takeLast();
             }
         }
-    __ASSERT_ALWAYS( mMailRows.count() == mailCount, User::Panic(_L("Invalid"), 500) );
+    __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);
+        }
     qDebug() << "NmHsWidget::updateMailRowsList OUT <<--";
 }
 
 /*!
-    mousePressEvent(QGraphicsSceneMouseEvent *event)
+    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::mousePressEvent(QGraphicsSceneMouseEvent *event)
+void NmHsWidget::updateMailRowsVisibility(const int visibleCount)
 {
-    qDebug() << "NmHsWidget::mousePressEvent IN -->>";
-
-    if (mTitleRow->rect().contains(event->pos()))
-        {
-        mEngine->launchMailAppInboxView();
-        }
-    else
+    qDebug() << "NmHsWidget::updateMailRowsVisibility IN -->>";
+  
+    // 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)) 
             {
-            QRectF tmpRect = mMailRows.at(i)->geometry(); // rect();
-            if (tmpRect.contains(event->pos()))
-                {
-                mEngine->launchMailAppMailViewer(mMailRows.at(i)->messageId());
-                break;
-                }
+            isVisible = true;
             }
+        mMailRows.at(i)->setVisible(isVisible);
         }
-    qDebug() << "NmHsWidget::mousePressEvent OUT <<--";
+    
+    qDebug() << "NmHsWidget::updateMailRowsVisibility OUT <<--";
 }
+
+/*!
+    onEngineException (NmHsWidgetEmailEngineExceptionCode exc)
+    signals widget to be finalized
+    /param exc exception type
+*/
+void NmHsWidget::onEngineException(const int& exc)
+    {
+    qDebug() << "NmHsWidget:onEngineException IN -->>";
+    switch (exc)
+        {
+        case (NmEngineExcAccountDeleted):
+             emit finished(); //succesful ending
+             break;
+        case (NmEngineExcFailure):
+             emit error(); //failure
+             break;
+        default: 
+            break; 
+        }
+    }