15 * |
15 * |
16 */ |
16 */ |
17 #include <QtGui> |
17 #include <QtGui> |
18 #include <QTranslator> |
18 #include <QTranslator> |
19 #include <QGraphicsLinearLayout> |
19 #include <QGraphicsLinearLayout> |
|
20 #include <QTimer> |
20 #include <hbcolorscheme.h> |
21 #include <hbcolorscheme.h> |
21 #include <hbdocumentloader.h> |
22 #include <hbdocumentloader.h> |
22 #include <hbframedrawer.h> |
23 #include <hbframedrawer.h> |
23 #include <hbframeitem.h> |
24 #include <hbframeitem.h> |
24 #include <hblabel.h> |
25 #include <hblabel.h> |
25 #include <hbstyleloader.h> |
26 #include <hbstyleloader.h> |
26 #include <hblistview.h> |
27 #include <hblistview.h> |
27 #include <hbdeviceprofile.h> |
28 #include <hbdeviceprofile.h> |
|
29 #include <hbevent.h> |
|
30 |
28 #include "nmcommon.h" |
31 #include "nmcommon.h" |
29 #include "nmmessageenvelope.h" |
32 #include "nmmessageenvelope.h" |
30 #include "nmhswidget.h" |
33 #include "nmhswidget.h" |
31 #include "nmhswidgetemailengine.h" |
34 #include "nmhswidgetemailengine.h" |
32 #include "nmhswidgettitlerow.h" |
35 #include "nmhswidgettitlerow.h" |
221 mBackgroundFrameDrawer = new HbFrameDrawer(KNmHsWidgetBackgroundImage, |
231 mBackgroundFrameDrawer = new HbFrameDrawer(KNmHsWidgetBackgroundImage, |
222 HbFrameDrawer::NinePieces); |
232 HbFrameDrawer::NinePieces); |
223 HbFrameItem* backgroundLayoutItem = new HbFrameItem(mBackgroundFrameDrawer); |
233 HbFrameItem* backgroundLayoutItem = new HbFrameItem(mBackgroundFrameDrawer); |
224 //set to NULL to indicate that ownership transferred |
234 //set to NULL to indicate that ownership transferred |
225 mBackgroundFrameDrawer = NULL; |
235 mBackgroundFrameDrawer = NULL; |
226 mWidgetContainer->setBackgroundItem(backgroundLayoutItem); |
236 mContentContainer->setBackgroundItem(backgroundLayoutItem); |
|
237 |
|
238 HbEffect::add(mContentContainer, "combo_disappear_up", "collapse"); |
|
239 HbEffect::add(mContentContainer, "combo_appear_down", "expand"); |
|
240 |
227 } |
241 } |
228 |
242 |
229 /*! |
243 /*! |
230 Sets correct properties and mail item proto type for mail list view |
244 Sets correct properties and mail item proto type for mail list view |
231 */ |
245 */ |
232 void NmHsWidget::createMailRowsList() |
246 void NmHsWidget::createMailRowsList() |
233 { |
247 { |
234 NM_FUNCTION; |
248 NM_FUNCTION; |
235 connect(mListView, SIGNAL(activated(const QModelIndex&)), this, |
249 |
|
250 //construct list model |
|
251 mListModel = new NmHsWidgetListModel(); |
|
252 |
|
253 //Connect item activation (click) to message view launching |
|
254 connect(mListView, SIGNAL(activated(const QModelIndex&)), this, |
236 SLOT(openMessage(const QModelIndex&))); |
255 SLOT(openMessage(const QModelIndex&))); |
237 |
256 |
|
257 //When new mails arrive, scroll list to the start |
|
258 connect(mListModel, SIGNAL( messagesAddedToModel() ), |
|
259 this, SLOT( handleMessagesAddedToModel() )); |
|
260 |
|
261 //connect item removal signal to update layout, so that nomailslabel & listview visibility |
|
262 //can be determined |
|
263 connect(mListModel, SIGNAL( modelIsEmpty(bool) ), |
|
264 this, SLOT( updateLayout() )); |
|
265 |
238 // Set the list widget properties. |
266 // Set the list widget properties. |
|
267 mListView->setItemRecycling(false); //This should be changed in future |
239 NmHsWidgetListViewItem *prototype = new NmHsWidgetListViewItem(mListView); |
268 NmHsWidgetListViewItem *prototype = new NmHsWidgetListViewItem(mListView); |
240 mListView->setItemPrototype(prototype); |
269 mListView->setItemPrototype(prototype); |
241 mListModel = new NmHsWidgetListModel(); |
|
242 mListView->setModel(mListModel); |
270 mListView->setModel(mListModel); |
243 } |
271 } |
244 |
272 |
245 /*! |
273 /*! |
246 Initializes the widget. |
274 Initializes the widget. |
277 return; |
304 return; |
278 } |
305 } |
279 |
306 |
280 setupUi(); |
307 setupUi(); |
281 |
308 |
|
309 //Crete list for mail items |
|
310 createMailRowsList(); |
|
311 |
282 //Engine construction is 2 phased. |
312 //Engine construction is 2 phased. |
283 mEngine = new NmHsWidgetEmailEngine(mAccountId); |
313 mEngine = new NmHsWidgetEmailEngine(mAccountId); |
|
314 connect(mEngine, SIGNAL( mailDataRefreshed(const QList<NmMessageEnvelope*>&) ), |
|
315 mListModel, SLOT ( refresh (const QList<NmMessageEnvelope*>&) )); |
|
316 connect(mEngine, SIGNAL( mailDataCleared() ), |
|
317 mListModel, SLOT ( removeAllMessages() )); |
|
318 connect(mEngine, SIGNAL( mailsReceived (const QList<NmMessageEnvelope*>&) ), |
|
319 mListModel, SLOT ( addMessages (const QList<NmMessageEnvelope*>&) )); |
|
320 connect(mEngine, SIGNAL( mailsUpdated (const QList<NmMessageEnvelope*>&) ), |
|
321 mListModel, SLOT ( updateMessages(const QList<NmMessageEnvelope*>&) )); |
|
322 connect(mEngine, SIGNAL( mailsDeleted (const QList<NmId>&)), |
|
323 mListModel, SLOT ( removeMessages(const QList<NmId>&) )); |
284 //Client must connect to exception signals before calling the initialize function |
324 //Client must connect to exception signals before calling the initialize function |
285 //because we don't want to miss any signals. |
325 //because we don't want to miss any signals. |
286 connect(mEngine, SIGNAL( exceptionOccured(const int&) ), this, |
326 connect(mEngine, SIGNAL( exceptionOccured(const int&) ), this, |
287 SLOT( onEngineException(const int&) )); |
327 SLOT( onEngineException(const int&) )); |
288 if (!mEngine->initialize()) { |
328 if (!mEngine->initialize()) { |
296 mTitleRow->updateAccountName(mEngine->accountName()); |
336 mTitleRow->updateAccountName(mEngine->accountName()); |
297 |
337 |
298 //create observer for date/time change events |
338 //create observer for date/time change events |
299 mDateObserver = new NmHsWidgetDateTimeObserver(); |
339 mDateObserver = new NmHsWidgetDateTimeObserver(); |
300 |
340 |
301 //Crete list for mail items |
341 //Create timer for delaying events after list scrolling is ended |
302 createMailRowsList(); |
342 mListActivityTimer = new QTimer(this); |
303 |
343 mListActivityTimer->setInterval(KNmHsWidgetDelayAfterScrollingEnded); |
304 updateMailData(); |
344 connect(mListActivityTimer, SIGNAL(timeout()), this, SLOT(scrollListToStart()) ); |
|
345 //Connect scrolling ended to scrolling timer activation |
|
346 //so that after timeout the list will be scrolled to first item |
|
347 connect(mListView, SIGNAL( scrollingEnded() ), |
|
348 mListActivityTimer, SLOT( start() )); |
|
349 |
|
350 //if timer is running, stop it right away when new activity happens |
|
351 connect(mListView, SIGNAL( scrollingStarted() ), |
|
352 mListActivityTimer, SLOT( stop() )); |
|
353 |
305 mTitleRow->updateUnreadCount(mEngine->unreadCount()); |
354 mTitleRow->updateUnreadCount(mEngine->unreadCount()); |
306 mTitleRow->setAccountIcon(mAccountIconName); |
355 mTitleRow->setAccountIcon(mAccountIconName); |
307 mTitleRow->setExpandCollapseIcon(mIsExpanded); |
356 mTitleRow->setExpandCollapseIcon(mIsExpanded); |
308 |
357 |
309 //Get signals about changes in mail data |
|
310 connect(mEngine, SIGNAL( mailDataChanged() ), this, SLOT( updateMailData() )); |
|
311 |
|
312 //Get Signals about changes in unread count |
358 //Get Signals about changes in unread count |
313 connect(mEngine, SIGNAL( unreadCountChanged(const int&) ) |
359 connect(mEngine, SIGNAL( unreadCountChanged(const int&) ) |
314 ,mTitleRow, SLOT( updateUnreadCount(const int&) ) ); |
360 ,mTitleRow, SLOT( updateUnreadCount(const int&) ) ); |
315 |
361 |
316 //Get signals about account name changes |
362 //Get signals about account name changes |
325 connect(mTitleRow, SIGNAL( expandCollapseButtonPressed() ) |
371 connect(mTitleRow, SIGNAL( expandCollapseButtonPressed() ) |
326 ,this, SLOT( handleExpandCollapseEvent() ) ); |
372 ,this, SLOT( handleExpandCollapseEvent() ) ); |
327 |
373 |
328 //Get date/time events from date observer |
374 //Get date/time events from date observer |
329 connect(mDateObserver, SIGNAL(dateTimeChanged()) |
375 connect(mDateObserver, SIGNAL(dateTimeChanged()) |
330 , this, SLOT(updateMailData())); |
376 , mEngine, SLOT(forceUpdate())); |
|
377 |
331 setMinimumSize(mTitleRow->minimumWidth(), |
378 setMinimumSize(mTitleRow->minimumWidth(), |
332 mEmptySpaceContainer->minimumHeight() + mTitleRow->minimumHeight()); |
379 mEmptySpaceContainer->minimumHeight() + mTitleRow->minimumHeight()); |
333 } |
380 } |
334 QT_CATCH(...) { |
381 QT_CATCH(...) { |
335 NM_ERROR(1,"NmHsWidget::onInitialize fail @ catch"); |
382 NM_ERROR(1,"NmHsWidget::onInitialize fail @ catch"); |
347 NM_FUNCTION; |
394 NM_FUNCTION; |
348 HbStyleLoader::unregisterFilePath(":/layout/nmhswidgetlistviewitem.widgetml"); |
395 HbStyleLoader::unregisterFilePath(":/layout/nmhswidgetlistviewitem.widgetml"); |
349 HbStyleLoader::unregisterFilePath(":/layout/nmhswidgetlistviewitem.css"); |
396 HbStyleLoader::unregisterFilePath(":/layout/nmhswidgetlistviewitem.css"); |
350 } |
397 } |
351 |
398 |
352 /*! |
|
353 updateMailData slot |
|
354 */ |
|
355 void NmHsWidget::updateMailData() |
|
356 { |
|
357 NM_FUNCTION; |
|
358 QT_TRY { |
|
359 QList<NmMessageEnvelope*> envelopes; |
|
360 int count = 0; |
|
361 if (mIsExpanded) { |
|
362 count = mEngine->getEnvelopes(envelopes, KMaxNumberOfMailsShown); |
|
363 } |
|
364 mListModel->refresh( envelopes ); |
|
365 updateLayout(count); |
|
366 }QT_CATCH(...) { |
|
367 NM_ERROR(1,"NmHsWidget::updateMailData fail @ catch"); |
|
368 emit error(); |
|
369 } |
|
370 } |
|
371 |
399 |
372 /*! |
400 /*! |
373 Sets monitored account id from given string |
401 Sets monitored account id from given string |
374 Needed for home screen framework which supports only QString type properties |
402 Needed for home screen framework which supports only QString type properties |
375 */ |
403 */ |
421 Slot to handle expand/collapse trigger event |
449 Slot to handle expand/collapse trigger event |
422 */ |
450 */ |
423 void NmHsWidget::handleExpandCollapseEvent() |
451 void NmHsWidget::handleExpandCollapseEvent() |
424 { |
452 { |
425 NM_FUNCTION; |
453 NM_FUNCTION; |
426 toggleExpansionState(); |
454 if(mIsExpanded){ |
|
455 HbEffect::start( mContentContainer, "collapse", this, "toggleExpansion"); |
|
456 } |
|
457 else{ |
|
458 toggleExpansionState(); |
|
459 HbEffect::start( mContentContainer, "expand"); |
|
460 } |
427 } |
461 } |
428 |
462 |
429 /*! |
463 /*! |
430 Sets widget expand/collapse state |
464 Sets widget expand/collapse state |
431 /post widget expansion state is changed |
465 /post widget expansion state is changed |
484 titlerow & noMailsLabel. |
518 titlerow & noMailsLabel. |
485 If widget is expanded and mailCount is greter |
519 If widget is expanded and mailCount is greter |
486 than zero, layout will contain titlerow and KMaxNumberOfMailsShown times |
520 than zero, layout will contain titlerow and KMaxNumberOfMailsShown times |
487 emailrow(s) |
521 emailrow(s) |
488 */ |
522 */ |
489 void NmHsWidget::updateLayout(const int mailCount) |
523 void NmHsWidget::updateLayout() |
490 { |
524 { |
491 NM_FUNCTION; |
525 NM_FUNCTION; |
492 |
526 int mailCount = mListModel->rowCount(); |
493 //collapsed size |
527 //collapsed size |
494 qreal totalHeight = mEmptySpaceContainer->preferredHeight() + mTitleRow->containerHeight(); |
528 qreal totalHeight = mEmptySpaceContainer->preferredHeight() + mTitleRow->containerHeight(); |
495 |
529 |
496 if (mIsExpanded) { |
530 if (mIsExpanded) { |
497 //when expanded, grow as big as possible |
531 //when expanded, grow as big as possible |
581 /*! |
615 /*! |
582 openMessage slot |
616 openMessage slot |
583 */ |
617 */ |
584 void NmHsWidget::openMessage(const QModelIndex& index) |
618 void NmHsWidget::openMessage(const QModelIndex& index) |
585 { |
619 { |
586 QVariant var = mListModel->data(index,Qt::DisplayRole); |
620 NM_FUNCTION; |
587 if(!var.isNull()){ |
621 QVariant var = mListModel->data(index,Qt::DisplayRole); |
588 NmMessageEnvelope *envelope = var.value<NmMessageEnvelope*>(); |
622 if(!var.isNull()){ |
589 mEngine->launchMailAppMailViewer(envelope->messageId()); |
623 NmMessageEnvelope *envelope = var.value<NmMessageEnvelope*>(); |
590 } |
624 mEngine->launchMailAppMailViewer(envelope->messageId()); |
591 |
625 } |
|
626 } |
|
627 |
|
628 /*! |
|
629 handleMessagesAddedToModel slo |
|
630 Slot is called when new messages is added to model. This function should scroll |
|
631 the list right away to the first item, unless there is user activity ongoing or |
|
632 the scrolling timer is active |
|
633 */ |
|
634 void NmHsWidget::handleMessagesAddedToModel() |
|
635 { |
|
636 NM_FUNCTION; |
|
637 if(mListActivityTimer->isActive() || mListView->isScrolling()){ |
|
638 //No need to scroll right away as user is active and we don't want to interupt it |
|
639 //or the scrolling event will occur within KNmHsWidgetDelayAfterScrollingEnded msecs. |
|
640 return; |
|
641 }else{ |
|
642 //if the list is idle, scroll to the first item |
|
643 scrollListToStart(); |
|
644 } |
|
645 } |
|
646 |
|
647 /*! |
|
648 scrollListToStart slot - Scrolls the mListView to the beginning of the list with |
|
649 KListScrollUpTime as a time to do it. |
|
650 */ |
|
651 void NmHsWidget::scrollListToStart() |
|
652 { |
|
653 NM_FUNCTION; |
|
654 QModelIndex index = (mListModel->item(0,0))->index(); |
|
655 //next line will fail if item recycling is enabled!! |
|
656 QPointF pos = (mListView->itemByIndex(index))->pos(); |
|
657 if(mListView->contentWidget()->pos() != pos){ |
|
658 //dont move if already there. Otherwise new scrolling events are emitted |
|
659 mListView->scrollContentsTo(pos, KListScrollUpTime); |
|
660 } |
|
661 mListActivityTimer->stop(); //stop the timer |
592 } |
662 } |
593 |
663 |
594 /*! |
664 /*! |
595 onEngineException (NmHsWidgetEmailEngineExceptionCode exc) |
665 onEngineException (NmHsWidgetEmailEngineExceptionCode exc) |
596 signals widget to be finalized |
666 signals widget to be finalized |