emailuis/nmailui/src/nmmessagesearchlistview.cpp
changeset 72 64e38f08e49c
parent 65 478bc57ad291
child 75 47d84de1c893
equal deleted inserted replaced
65:478bc57ad291 72:64e38f08e49c
    13 *
    13 *
    14 * Description:
    14 * Description:
    15 *
    15 *
    16 */
    16 */
    17 
    17 
    18 static const char *NMUI_MESSAGE_SEARCH_LIST_VIEW_XML = ":/docml/nmmessagesearchlistview.docml";
       
    19 static const char *NMUI_MESSAGE_SEARCH_LIST_VIEW = "NmMessageSearchListView";
       
    20 static const char *NMUI_MESSAGE_SEARCH_LIST_TREE_LIST = "MessageTreeList";
       
    21 static const char *NMUI_MESSAGE_SEARCH_LIST_NO_MESSAGES = "MessageListNoMessages";
       
    22 static const char *NMUI_MESSAGE_SEARCH_LIST_INFO_LABEL = "LabelGroupBox";
       
    23 static const char *NMUI_MESSAGE_SEARCH_LIST_LINE_EDIT = "LineEdit";
       
    24 static const char *NMUI_MESSAGE_SEARCH_LIST_PUSH_BUTTON = "PushButton";
       
    25 
       
    26 
       
    27 #include "nmuiheaders.h"
    18 #include "nmuiheaders.h"
       
    19 
       
    20 static const char *NMUI_MESSAGE_SEARCH_VIEW_XML = ":/docml/nmmessagesearchlistview.docml";
       
    21 static const char *NMUI_MESSAGE_SEARCH_VIEW = "NmMessageSearchView";
       
    22 static const char *NMUI_MESSAGE_SEARCH_MESSAGE_TREE_LIST= "MessageTreeList";
       
    23 static const char *NMUI_MESSAGE_SEARCH_PANEL = "SearchPanel";
       
    24 static const char *NMUI_MESSAGE_SEARCH_NO_MESSAGES = "MessageNoMessages";
       
    25 
       
    26 static const QString NmSearchListViewProgressButton("progressbutton");
       
    27 static const QString NmSearchListViewLineEdit("lineedit");
       
    28 
       
    29 static const QString NmSearchListViewSpinnerAnimation("qtg_anim_mono_loading");
       
    30 static const QString NmSearchListViewSpinnerImage("qtg_anim_mono_loading_1");
    28 
    31 
    29 
    32 
    30 /*!
    33 /*!
    31     \class NmMessageSearchListView
    34     \class NmMessageSearchListView
    32     \brief The view for searching messages.
    35     \brief The view for searching messages.
    47   mApplication(application),
    50   mApplication(application),
    48   mUiEngine(uiEngine),
    51   mUiEngine(uiEngine),
    49   mMsgListModel(msgListModel),
    52   mMsgListModel(msgListModel),
    50   mDocumentLoader(documentLoader),
    53   mDocumentLoader(documentLoader),
    51   mItemContextMenu(NULL),
    54   mItemContextMenu(NULL),
    52   mMessageListWidget(NULL),
    55   mMessageList(NULL),
    53   mInfoLabel(NULL),
       
    54   mNoMessagesLabel(NULL),
    56   mNoMessagesLabel(NULL),
       
    57   mSearchPanel(NULL),
       
    58   mLongPressedItem(NULL),
       
    59   mProgressButton(NULL),
    55   mLineEdit(NULL),
    60   mLineEdit(NULL),
    56   mPushButton(NULL),
       
    57   mLongPressedItem(NULL),
       
    58   mViewReady(false),
    61   mViewReady(false),
    59   mSearchInProgress(false)
    62   mSearchInProgress(false),
       
    63   mSpinnerIcon(NULL),
       
    64   mAnimationAddedToManger(false),
       
    65   mSelectTextAfterOrientationChange(false),
       
    66   mVkbHost(NULL)
    60 {
    67 {
    61     NM_FUNCTION;
    68     NM_FUNCTION;
    62     
    69     
    63     loadViewLayout();
    70     loadViewLayout();
    64     initTreeView();
    71     initTreeView();
       
    72 
       
    73     // Add spinner animation axml to animation manager.
       
    74     HbIconAnimationManager *animationManager = HbIconAnimationManager::global();
       
    75     if (animationManager) {
       
    76         mAnimationAddedToManger =
       
    77             animationManager->addDefinitionFile(NmSearchListViewSpinnerAnimation);
       
    78     }
       
    79 
       
    80     HbMainWindow *mainWindow = mApplication.mainWindow();
       
    81     connect(mainWindow, SIGNAL(aboutToChangeOrientation()),
       
    82             this, SLOT(orientationAboutToChange()));
       
    83     connect(mainWindow, SIGNAL(orientationChanged(Qt::Orientation)),
       
    84             this, SLOT(orientationChanged()));
       
    85 
       
    86     mVkbHost = new HbShrinkingVkbHost(this);
       
    87     connect(mVkbHost, SIGNAL(keypadOpened()), this, SLOT(vkbOpened()));
       
    88     connect(mVkbHost, SIGNAL(keypadClosed()), this, SLOT(vkbClosed()));
    65 }
    89 }
    66 
    90 
    67 
    91 
    68 /*!
    92 /*!
    69     Class destructor.
    93     Class destructor.
    70 */
    94 */
    71 NmMessageSearchListView::~NmMessageSearchListView()
    95 NmMessageSearchListView::~NmMessageSearchListView()
    72 {
    96 {
    73     NM_FUNCTION;
    97     NM_FUNCTION;
    74     
    98     delete mSpinnerIcon;
    75     delete mDocumentLoader;
    99     delete mDocumentLoader;
    76 
   100 
    77     mWidgetList.clear();
   101     mWidgetList.clear();
    78 
   102 
    79     if (mItemContextMenu){
   103     if (mItemContextMenu){
    80         mItemContextMenu->clearActions();
   104         mItemContextMenu->clearActions();
    81     }
   105     }
    82 
   106 
    83     delete mItemContextMenu;
   107     delete mItemContextMenu;
       
   108     delete mVkbHost;
    84 }
   109 }
    85 
   110 
    86 
   111 
    87 /*!
   112 /*!
    88     From NmBaseView.
   113     From NmBaseView.
    96     NM_FUNCTION;
   121     NM_FUNCTION;
    97     
   122     
    98     return NmUiViewMessageSearchList;
   123     return NmUiViewMessageSearchList;
    99 }
   124 }
   100 
   125 
       
   126 
       
   127 /*!
       
   128     From NmBaseView.
       
   129 
       
   130     Makes necessary activities before view can exit.
       
   131 */
       
   132 void NmMessageSearchListView::aboutToExitView()
       
   133 {
       
   134     NM_FUNCTION;
       
   135     if (mSearchInProgress) {
       
   136        // Search is in progress - do cancel.
       
   137        mUiEngine.cancelSearch(mStartParam->mailboxId());
       
   138        mSearchInProgress = false;
       
   139     }
       
   140 }
   101 
   141 
   102 /*!
   142 /*!
   103     From NmBaseView.
   143     From NmBaseView.
   104 
   144 
   105     Does the lazy loading after the view layout has been loaded.
   145     Does the lazy loading after the view layout has been loaded.
   113         setViewTitle();
   153         setViewTitle();
   114 
   154 
   115         // Refresh the list.
   155         // Refresh the list.
   116         QMetaObject::invokeMethod(this, "refreshList", Qt::QueuedConnection);
   156         QMetaObject::invokeMethod(this, "refreshList", Qt::QueuedConnection);
   117 
   157 
   118         // Highlight the search input.
   158         // Undim search field.
   119         setSearchInputMode(NmHighlightedMode);
   159         setSearchInputMode(NmNormalMode);
       
   160 
       
   161         // Open VKB
       
   162         QMetaObject::invokeMethod(this, "sendSoftwareInputPanelRequest", Qt::QueuedConnection);
   120 
   163 
   121         mViewReady = true;
   164         mViewReady = true;
   122     }
   165     }
   123 }
   166 }
   124 
   167 
   152         }
   195         }
   153     }
   196     }
   154     // Handle context menu commands here.
   197     // Handle context menu commands here.
   155     if (actionResponse.menuType() == NmActionContextMenu) {
   198     if (actionResponse.menuType() == NmActionContextMenu) {
   156         if (mLongPressedItem){
   199         if (mLongPressedItem){
       
   200 
       
   201             // Hide VKB
       
   202             vkbClosed();
       
   203             sendSoftwareInputPanelRequest(QEvent::CloseSoftwareInputPanel);
       
   204 
   157             NmUiStartParam *startParam = new NmUiStartParam(NmUiViewMessageViewer,
   205             NmUiStartParam *startParam = new NmUiStartParam(NmUiViewMessageViewer,
   158                 mStartParam->mailboxId(), mLongPressedItem->envelope().folderId(),
   206                 mStartParam->mailboxId(), mLongPressedItem->envelope().folderId(),
   159                 mLongPressedItem->envelope().messageId());
   207                 mLongPressedItem->envelope().messageId());
   160 
   208 
   161             mApplication.enterNmUiView(startParam);
   209             mApplication.enterNmUiView(startParam);
   174 {
   222 {
   175     NM_FUNCTION;
   223     NM_FUNCTION;
   176     
   224     
   177     // Use the document loader to load the view layout.
   225     // Use the document loader to load the view layout.
   178     bool ok(false);
   226     bool ok(false);
   179     setObjectName(QString(NMUI_MESSAGE_SEARCH_LIST_VIEW));
   227     setObjectName(QString(NMUI_MESSAGE_SEARCH_VIEW));
   180     QObjectList objectList;
   228     QObjectList objectList;
   181     objectList.append(this);
   229     objectList.append(this);
   182 
   230 
   183     // Pass the view to the document loader. Instead of creating a new view, the
   231     // Pass the view to the document loader. Instead of creating a new view, the
   184     // document loader uses this view when the docml file is parsed.
   232     // document loader uses this view when the docml file is parsed.
   185     if (mDocumentLoader) {
   233     if (mDocumentLoader) {
   186         mDocumentLoader->setObjectTree(objectList);
   234         mDocumentLoader->setObjectTree(objectList);
   187         mWidgetList = mDocumentLoader->load(NMUI_MESSAGE_SEARCH_LIST_VIEW_XML, &ok);
   235         mWidgetList = mDocumentLoader->load(NMUI_MESSAGE_SEARCH_VIEW_XML, &ok);
   188     }
   236     }
   189 
   237 
   190     if (ok) {
   238     if (ok) {
   191         // Load the search panel (contains the line edit and the push button
   239         // Load the search panel
   192         // widgets.
   240         mSearchPanel = qobject_cast<HbSearchPanel *>(
   193         mLineEdit = qobject_cast<HbLineEdit *>(
   241             mDocumentLoader->findWidget(NMUI_MESSAGE_SEARCH_PANEL));
   194             mDocumentLoader->findWidget(NMUI_MESSAGE_SEARCH_LIST_LINE_EDIT));
   242 
   195 
   243         if (mSearchPanel) {
   196         if (mLineEdit) {
   244             mSearchPanel->setProgressive(false);
   197             connect(mLineEdit, SIGNAL(textChanged(QString)), 
   245             mSearchPanel->setCancelEnabled(true);
   198                     this, SLOT(criteriaChanged(QString)));
   246 
   199         }
   247             foreach(QGraphicsItem *obj, mSearchPanel->childItems()) {
   200     
   248                 QGraphicsWidget *const widget = static_cast<QGraphicsWidget *>(obj);
   201         mPushButton = qobject_cast<HbPushButton *>(
   249                 if (widget) {
   202         mDocumentLoader->findWidget(NMUI_MESSAGE_SEARCH_LIST_PUSH_BUTTON));
   250                     QString objectName(widget->objectName());
   203 
   251                     if (objectName == NmSearchListViewProgressButton) {
   204         if (mPushButton) {
   252                         mProgressButton = qobject_cast<HbPushButton *>(widget);
   205             // button is disabled when line edit is empty
   253                         mProgressButton->setIcon(HbIcon("qtg_mono_search"));
   206             mPushButton->setEnabled(false);
   254                         mProgressButton->setEnabled(false);
   207 
   255                     }
   208             // The push button both starts and stops the search.
   256                     else if(objectName == NmSearchListViewLineEdit) {
   209             connect(mPushButton, SIGNAL(clicked()), this, SLOT(toggleSearch()));
   257                         mLineEdit = qobject_cast<HbLineEdit *>(widget);
   210             mPushButton->setIcon(HbIcon("qtg_mono_search"));
   258                         mLineEdit->setInputMethodHints(Qt::ImhNoPredictiveText);
   211         }
   259                         connect(mLineEdit, SIGNAL(textChanged(const QString &)),
   212 
   260                                 this, SLOT(textChanged(const QString &)));
   213         // Load the info label.
   261                     }
   214         mInfoLabel = qobject_cast<HbGroupBox *>(
   262                 }
   215             mDocumentLoader->findWidget(NMUI_MESSAGE_SEARCH_LIST_INFO_LABEL));
   263             }
   216 
   264 
   217         if (mInfoLabel) {
   265             connect(mSearchPanel, SIGNAL(criteriaChanged(const QString &)),
   218             NM_COMMENT("NmMessageSearchListView: info label loaded");
   266                     this, SLOT(toggleSearch()));
   219 
   267 
   220             // If the heading is empty, the widget will not be shown which in
   268             connect(mSearchPanel, SIGNAL(exitClicked()),
   221             // turn would ruin the layout.
   269                     this, SLOT(exitClicked()), Qt::QueuedConnection);
   222             mInfoLabel->setHeading(" ");
   270 
   223         }
   271         }
   224 
   272 
   225         // Get the message list widget.
   273         // Get the message list widget.
   226         mMessageListWidget = qobject_cast<HbTreeView *>(
   274         mMessageList = qobject_cast<HbTreeView *>(
   227             mDocumentLoader->findWidget(NMUI_MESSAGE_SEARCH_LIST_TREE_LIST));
   275             mDocumentLoader->findWidget(NMUI_MESSAGE_SEARCH_MESSAGE_TREE_LIST));
   228 
   276 
   229         if (mMessageListWidget) {
   277         if (mMessageList) {
   230             NM_COMMENT("NmMessageSearchListView: message list widget loaded");
   278             NM_COMMENT("NmMessageSearchListView: message list widget loaded");
   231 
   279 
   232             // Set the item prototype.
   280             // Set the item prototype.
   233             mMessageListWidget->setItemPrototype(new NmMessageListViewItem());
   281             mMessageList->setItemPrototype(new NmMessageListViewItem());
   234 
   282 
   235             // Set the list widget properties.
   283             // Set the list widget properties.
   236             mMessageListWidget->setItemRecycling(true);
   284             mMessageList->setItemRecycling(true);
   237             mMessageListWidget->contentWidget()->setProperty("indentation", 0);
   285             mMessageList->contentWidget()->setProperty("indentation", 0);
   238             mMessageListWidget->setScrollDirections(Qt::Vertical);
   286             mMessageList->setScrollDirections(Qt::Vertical);
   239             mMessageListWidget->setClampingStyle(HbScrollArea::BounceBackClamping);
   287             mMessageList->setClampingStyle(HbScrollArea::BounceBackClamping);
   240             mMessageListWidget->setFrictionEnabled(true);
   288             mMessageList->setFrictionEnabled(true);
   241             mMessageListWidget->setItemPixmapCacheEnabled(true);
   289             mMessageList->setItemPixmapCacheEnabled(true);
   242             
   290             
   243             // We want the search results to appear one by one.
   291             // We want the search results to appear one by one.
   244             mMessageListWidget->setEnabledAnimations(HbAbstractItemView::Appear &
   292             mMessageList->setEnabledAnimations(HbAbstractItemView::Appear &
   245                                                      HbAbstractItemView::Expand);
   293                 HbAbstractItemView::Expand);
   246         }
   294         }
   247 
   295 
   248         // Load the no messages label.
   296         // Load the no messages label.
   249         mNoMessagesLabel = qobject_cast<HbLabel *>(
   297         mNoMessagesLabel = qobject_cast<HbLabel *>(
   250             mDocumentLoader->findWidget(NMUI_MESSAGE_SEARCH_LIST_NO_MESSAGES));
   298             mDocumentLoader->findWidget(NMUI_MESSAGE_SEARCH_NO_MESSAGES));
   251 
   299 
   252         if (mNoMessagesLabel) {
   300         if (mNoMessagesLabel) {
   253             NMLOG("NmMessageSearchListView: No messages label loaded.");
   301             NMLOG("NmMessageSearchListView: No messages label loaded.");
   254             mNoMessagesLabel->hide();
   302             mNoMessagesLabel->setMaximumHeight(0);
   255         }
   303         }
   256     }
   304     }
   257     else {
   305     else {
   258         NM_ERROR(1, "NmMessageSearchListView: failed to load widgets from XML");
   306         NM_ERROR(1, "NmMessageSearchListView: failed to load widgets from XML");
   259     }
   307     }
   266 void NmMessageSearchListView::initTreeView()
   314 void NmMessageSearchListView::initTreeView()
   267 {
   315 {
   268     NM_FUNCTION;
   316     NM_FUNCTION;
   269     
   317     
   270     // Get the mailbox widget pointer and set the parameters.
   318     // Get the mailbox widget pointer and set the parameters.
   271     if (mMessageListWidget) {
   319     if (mMessageList) {
   272         connect(mMessageListWidget, SIGNAL(activated(const QModelIndex &)),
   320         connect(mMessageList, SIGNAL(activated(const QModelIndex &)),
   273                 this, SLOT(itemActivated(const QModelIndex &)));
   321                 this, SLOT(itemActivated(const QModelIndex &)));
   274 
   322 
   275         connect(mMessageListWidget, SIGNAL(longPressed(HbAbstractViewItem*, QPointF)),
   323         connect(mMessageList, SIGNAL(longPressed(HbAbstractViewItem*, QPointF)),
   276                 this, SLOT(showItemContextMenu(HbAbstractViewItem*, QPointF)));
   324                 this, SLOT(showItemContextMenu(HbAbstractViewItem*, QPointF)));
   277 
   325 
   278         mMessageListWidget->setFocus();
   326         mMessageList->setFocus();
   279         mItemContextMenu = new HbMenu();
   327         mItemContextMenu = new HbMenu();
   280     }
   328     }
   281 
   329 
   282     // Clear the previous content if any.
   330     // Clear the previous content if any.
   283     mMsgListModel.clear();
   331     mMsgListModel.clear();
   312 {
   360 {
   313     NM_FUNCTION;
   361     NM_FUNCTION;
   314     
   362     
   315     if (visible) {
   363     if (visible) {
   316         // Hide the message list widget and display the "no messages" label.
   364         // Hide the message list widget and display the "no messages" label.
   317         if (mMessageListWidget) {
   365         if (mMessageList) {
   318             mMessageListWidget->hide();
   366             mMessageList->setMaximumHeight(0);
       
   367             mMessageList->hide();
   319         }
   368         }
   320 
   369 
   321         if (mNoMessagesLabel && !mNoMessagesLabel->isVisible()) {
   370         if (mNoMessagesLabel && !mNoMessagesLabel->isVisible()) {
       
   371             mNoMessagesLabel->setMaximumHeight(QWIDGETSIZE_MAX);
   322             mNoMessagesLabel->show();
   372             mNoMessagesLabel->show();
   323         }
   373         }
   324     }
   374     }
   325     else {
   375     else {
   326         // Hide the "no messages" label and display the message list widget.
   376         // Hide the "no messages" label and display the message list widget.
   327         if (mNoMessagesLabel && mNoMessagesLabel->isVisible()) {
   377         if (mNoMessagesLabel && mNoMessagesLabel->isVisible()) {
       
   378             mNoMessagesLabel->setMaximumHeight(0);
   328             mNoMessagesLabel->hide();
   379             mNoMessagesLabel->hide();
   329         }
   380         }
   330 
   381 
   331         if (mMessageListWidget) {
   382         if (mMessageList) {
   332             mMessageListWidget->show();
   383             mMessageList->setMaximumHeight(QWIDGETSIZE_MAX);
   333         }
   384             mMessageList->show();
   334     }
   385         }
   335 }
   386     }
   336 
   387 }
   337 
   388 
   338 /*!
   389 
   339     Updates the search result count information. If the message list does not
   390 /*!
   340     contain any items, a "no messages" label is displayed. Otherwise the result
   391     Shows no messages label if no matching messages were found.
   341     count in the information label is updated according to the number of
   392 */
   342     messages in the list.
   393 void NmMessageSearchListView::updateResultView()
   343 */
   394 {
   344 void NmMessageSearchListView::updateSearchResultCountInfo()
   395     NM_FUNCTION;
   345 {
   396 
   346     NM_FUNCTION;
   397     if (mMsgListModel.rowCount() < 1) {
   347 
   398         // Display the "no messages".
   348     const int resultCount = mMsgListModel.rowCount();
       
   349 
       
   350     if (resultCount) {
       
   351         if (mInfoLabel) {
       
   352             // Display the result count on the info label.
       
   353             QString resultsString(hbTrId("txt_mail_list_search_results",resultCount));
       
   354             mInfoLabel->setHeading(resultsString);
       
   355 
       
   356             if (!mInfoLabel->isVisible()) {
       
   357                 mInfoLabel->show();
       
   358             }
       
   359         }
       
   360     }
       
   361     else {
       
   362         // No search results!
       
   363         if (mInfoLabel && mInfoLabel->isVisible()) {
       
   364             mInfoLabel->hide();
       
   365         }
       
   366 
       
   367         // Display the "no messages" label and highlight the search term.
       
   368         noMessagesLabelVisibility(true);
   399         noMessagesLabelVisibility(true);
   369     }
   400     }
   370     
       
   371 }
   401 }
   372 
   402 
   373 
   403 
   374 /*!
   404 /*!
   375     Sets the mode for the search input.
   405     Sets the mode for the search input.
   377     \param mode The mode to set.
   407     \param mode The mode to set.
   378 */
   408 */
   379 void NmMessageSearchListView::setSearchInputMode(NmSearchInputMode mode)
   409 void NmMessageSearchListView::setSearchInputMode(NmSearchInputMode mode)
   380 {
   410 {
   381     NM_FUNCTION;
   411     NM_FUNCTION;
   382     
   412 
   383     if (!mLineEdit) {
   413     if (!mLineEdit) {
   384         // No line edit widget!
   414         // No line edit widget!
   385         return;
   415         return;
   386     }
   416     }
   387 
   417 
   388     switch (mode) {
   418     if (mode == NmNormalMode) {
   389         case NmNormalMode: {
   419         mLineEdit->setEnabled(true);
   390             mLineEdit->setEnabled(true);
   420         mLineEdit->setFocus();
   391             break;
   421     }
   392         }
   422     else {
   393         case NmHighlightedMode: {
   423         mLineEdit->setEnabled(false);
   394             mLineEdit->setEnabled(true);
   424         mLineEdit->deselect();
   395             mLineEdit->setFocus();
   425     }
   396             break;
   426 }
   397         }
       
   398         case NmDimmedMode: {
       
   399             mLineEdit->setEnabled(false);
       
   400             break;
       
   401         }
       
   402     }
       
   403 }
       
   404 
       
   405 
   427 
   406 /*!
   428 /*!
   407     From NmBaseView.
   429     From NmBaseView.
   408 
   430 
   409     Reloads the view contents with new start parameters. This method is
   431     Reloads the view contents with new start parameters. This method is
   435         NM_ERROR(1, "NmMessageSearchListView: invalid message list start parameter");
   457         NM_ERROR(1, "NmMessageSearchListView: invalid message list start parameter");
   436         delete startParam;
   458         delete startParam;
   437     }
   459     }
   438 }
   460 }
   439 
   461 
   440 
       
   441 /*!
       
   442     Called when text is changed in the edit field. If there is no search term
       
   443     in the edit field, the search button is dimmed and disabled. If the field
       
   444     contains text, the button can be clicked.
       
   445     
       
   446     \param text The text in the field after the modification.
       
   447 */
       
   448 void NmMessageSearchListView::criteriaChanged(QString text) 
       
   449 {
       
   450     NM_FUNCTION;
       
   451     NM_COMMENT(QString("NmMessageSearchListView::criteriaChanged %1").arg(text));
       
   452     
       
   453     // Check if the button should be disabled/enabled.
       
   454     bool enabled = mPushButton->isEnabled();
       
   455 
       
   456     if (!enabled && !text.isEmpty()) {
       
   457         mPushButton->setEnabled(true);
       
   458     }
       
   459     else if (enabled && text.isEmpty()) {
       
   460         mPushButton->setEnabled(false);
       
   461     }
       
   462 }
       
   463 
       
   464 
       
   465 /*!
   462 /*!
   466     Displays the item context menu. This method gets called if an item on the
   463     Displays the item context menu. This method gets called if an item on the
   467     list is long pressed.
   464     list is long pressed.
   468 */
   465 */
   469 void NmMessageSearchListView::showItemContextMenu(
   466 void NmMessageSearchListView::showItemContextMenu(
   470     HbAbstractViewItem *listViewItem, const QPointF &coords)
   467     HbAbstractViewItem *listViewItem, const QPointF &coords)
   471 {
   468 {
   472     NM_FUNCTION;
   469     NM_FUNCTION;
   473     
   470     
       
   471     // Stop search.
       
   472     if (mSearchInProgress) {
       
   473         toggleSearch();
       
   474     }
       
   475 
   474     // Store long press item for later use with response.
   476     // Store long press item for later use with response.
   475     mLongPressedItem = 
   477     mLongPressedItem = 
   476         mMsgListModel.data(listViewItem->modelIndex(),
   478         mMsgListModel.data(listViewItem->modelIndex(),
   477                            Qt::DisplayRole).value<NmMessageListModelItem*>();
   479                            Qt::DisplayRole).value<NmMessageListModelItem*>();
   478 
   480 
   542         // Open the message.
   544         // Open the message.
   543         NmUiStartParam *startParam = new NmUiStartParam(NmUiViewMessageViewer,
   545         NmUiStartParam *startParam = new NmUiStartParam(NmUiViewMessageViewer,
   544             mStartParam->mailboxId(), modelItem->envelope().folderId(),
   546             mStartParam->mailboxId(), modelItem->envelope().folderId(),
   545             modelItem->envelope().messageId());
   547             modelItem->envelope().messageId());
   546 
   548 
       
   549         // Hide VKB
       
   550         vkbClosed();
       
   551         sendSoftwareInputPanelRequest(QEvent::CloseSoftwareInputPanel);
       
   552 
   547         mApplication.enterNmUiView(startParam);
   553         mApplication.enterNmUiView(startParam);
   548     }
   554     }
   549 }
   555 }
   550 
   556 
   551 
   557 
   561     Q_UNUSED(end);
   567     Q_UNUSED(end);
   562 
   568 
   563     // The search is an asynchronous operation. If a user stops the search, it
   569     // The search is an asynchronous operation. If a user stops the search, it
   564     // might take a short while before the search is actually stopped and during
   570     // might take a short while before the search is actually stopped and during
   565     // this time it is possible that messages matching the search are added.
   571     // this time it is possible that messages matching the search are added.
   566     // Therefore, update the result count info if items are added after the
   572     // Therefore, update is needed if items are added after the
   567     // search has been stopped by the user.
   573     // search has been stopped by the user.
   568     if (!mSearchInProgress) {
   574     if (!mSearchInProgress) {
   569         updateSearchResultCountInfo();
   575         updateResultView();
   570     }
   576     }
   571 
   577 
   572     if (!start && mMessageListWidget) {
   578     if (!start && mMessageList) {
   573         QList<HbAbstractViewItem*> items = mMessageListWidget->visibleItems();
   579         QList<HbAbstractViewItem*> items = mMessageList->visibleItems();
   574 
   580 
   575         if (items.count()) {
   581         if (items.count()) {
   576             QModelIndex index = items.at(0)->modelIndex();
   582             QModelIndex index = items.at(0)->modelIndex();
   577 
   583 
   578             while (index.row() > 0) {
   584             while (index.row() > 0) {
   579                 QModelIndex previous =
   585                 QModelIndex previous =
   580                     mMessageListWidget->modelIterator()->previousIndex(index);
   586                     mMessageList->modelIterator()->previousIndex(index);
   581 
   587 
   582                 if (previous.isValid()) {
   588                 if (previous.isValid()) {
   583                     mMessageListWidget->scrollTo(previous);
   589                     mMessageList->scrollTo(previous);
   584                 }
   590                 }
   585 
   591 
   586                 index = previous;
   592                 index = previous;
   587             }
   593             }
   588         }
   594         }
   590 }
   596 }
   591 
   597 
   592 
   598 
   593 /*!
   599 /*!
   594     This method gets called when an item is removed from the list. If the
   600     This method gets called when an item is removed from the list. If the
   595     search has completed (or stopped), the search result count information is
   601     search has completed (or stopped), the search results needs to be updated.
   596     updated according to the number of messages in the list.
       
   597 */
   602 */
   598 void NmMessageSearchListView::itemsRemoved()
   603 void NmMessageSearchListView::itemsRemoved()
   599 {
   604 {
   600     NM_FUNCTION;
   605     NM_FUNCTION;
   601     
   606     
   602     if (!mSearchInProgress) {
   607     if (!mSearchInProgress) {
   603         updateSearchResultCountInfo();
   608         updateResultView();
   604     }
   609     }
   605 }
   610 }
   606 
   611 
   607 
   612 
   608 /*!
   613 /*!
   610 */
   615 */
   611 void NmMessageSearchListView::refreshList()
   616 void NmMessageSearchListView::refreshList()
   612 {
   617 {
   613     NM_FUNCTION;
   618     NM_FUNCTION;
   614     
   619     
   615     if (mMessageListWidget) {
   620     if (mMessageList) {
   616         // Set the model.
   621         // Set the model.
   617         mMessageListWidget->setModel(
   622         mMessageList->setModel(static_cast<QStandardItemModel*>(&mMsgListModel));
   618             static_cast<QStandardItemModel*>(&mMsgListModel));
       
   619 
   623 
   620         // Connect the signals.
   624         // Connect the signals.
   621         connect(&mMsgListModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)),
   625         connect(&mMsgListModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)),
   622                 this, SLOT(itemsAdded(const QModelIndex&, int, int)), Qt::UniqueConnection);
   626                 this, SLOT(itemsAdded(const QModelIndex&, int, int)), Qt::UniqueConnection);
   623 
   627 
   625                 this, SLOT(itemsRemoved()), Qt::UniqueConnection);
   629                 this, SLOT(itemsRemoved()), Qt::UniqueConnection);
   626 
   630 
   627         connect(&mMsgListModel, SIGNAL(setNewParam(NmUiStartParam*)),
   631         connect(&mMsgListModel, SIGNAL(setNewParam(NmUiStartParam*)),
   628                 this, SLOT(reloadViewContents(NmUiStartParam*)), Qt::UniqueConnection);
   632                 this, SLOT(reloadViewContents(NmUiStartParam*)), Qt::UniqueConnection);
   629     }
   633     }
   630 
       
   631     // The info label cannot be hidden when constructed because doing so would
       
   632     // ruin the layout (for example the line edit widget's width would be too
       
   633     // short in lanscape).
       
   634     if (mInfoLabel) {
       
   635         mInfoLabel->hide();
       
   636     }
       
   637 }
   634 }
   638 
   635 
   639 
   636 
   640 /*!
   637 /*!
   641     Starts and stops the search according to the current status.
   638     Starts and stops the search according to the current status.
   642 
   639 
   643     Starts search: Uses the input given by the user as a search string and
   640     Starts search: Uses the input given by the user as a search string and
   644     starts an asynchronous search. Any previous search results are removed from
   641     starts an asynchronous search. Any previous search results are removed from
   645     the search list.
   642     the search list.
   646 
   643 
   647     Stops search: Sets the number of search results into the info label.
   644     Stops search: shows no messages label if no matching messages were found.
   648 */
   645 */
   649 void NmMessageSearchListView::toggleSearch()
   646 void NmMessageSearchListView::toggleSearch()
   650 {
   647 {
   651     NM_FUNCTION;
   648     NM_FUNCTION;
   652     
   649     
   666                 this, SLOT(handleSearchComplete()), Qt::UniqueConnection);
   663                 this, SLOT(handleSearchComplete()), Qt::UniqueConnection);
   667     
   664     
   668         // Get the search input and start the search.
   665         // Get the search input and start the search.
   669         QStringList searchStrings;
   666         QStringList searchStrings;
   670 
   667 
   671         if (mLineEdit) {
   668         if (mSearchPanel) {
   672             searchStrings.append(mLineEdit->text());
   669             searchStrings.append(mSearchPanel->criteria());
   673         }
   670         }
   674 
       
   675         mUiEngine.search(mStartParam->mailboxId(), searchStrings);
       
   676 
   671 
   677         // Hide the virtual keyboard
   672         // Hide the virtual keyboard
   678         QInputContext *ic = qApp->inputContext();
   673         sendSoftwareInputPanelRequest(QEvent::CloseSoftwareInputPanel);
   679         if (ic) {
   674 
   680             QEvent *closeEvent = new QEvent(QEvent::CloseSoftwareInputPanel);
       
   681             ic->filterEvent(closeEvent);
       
   682             delete closeEvent;
       
   683         }
       
   684         
       
   685         // Hide the "no messages" label if visible and dim the search input.
   675         // Hide the "no messages" label if visible and dim the search input.
   686         noMessagesLabelVisibility(false);
   676         noMessagesLabelVisibility(false);
   687         setSearchInputMode(NmDimmedMode);
   677         setSearchInputMode(NmDimmedMode);
   688 
   678 
   689         // Display the info label.
   679         // Change "Go" button icon to spinner.
   690         if (mInfoLabel) {
   680         if (mProgressButton) {
   691             mInfoLabel->setHeading(hbTrId("txt_mail_list_searching"));
   681             // Create icon if not created yet.
   692             mInfoLabel->show();
   682             if (!mSpinnerIcon) {
   693         }
   683                 // Select one picture if animation loading has failed.
   694 
   684                 QString iconName = NmSearchListViewSpinnerImage;
   695         // Change the push button text.
   685                 if (mAnimationAddedToManger) {
   696         if (mPushButton) {
   686                     iconName = NmSearchListViewSpinnerAnimation;
   697             mPushButton->setIcon(HbIcon("qtg_mono_search_stop"));
   687                 }
   698         }
   688                 mSpinnerIcon = new HbIcon(iconName);
       
   689                 mSpinnerIcon->setFlags(HbIcon::Colorized);
       
   690             }
       
   691             mProgressButton->setIcon(*mSpinnerIcon);
       
   692         }
       
   693 
       
   694         // Start search
       
   695         mUiEngine.search(mStartParam->mailboxId(), searchStrings);
   699     }
   696     }
   700 }
   697 }
   701 
   698 
   702 
   699 
   703 /*!
   700 /*!
   709 {
   706 {
   710     NM_FUNCTION;
   707     NM_FUNCTION;
   711     
   708     
   712     mSearchInProgress = false;
   709     mSearchInProgress = false;
   713     
   710     
   714     // Change the push button text.
   711     // Change search button icon to magnifying glass.
   715     if (mPushButton) {
   712     if (mProgressButton) {
   716         mPushButton->setIcon(HbIcon("qtg_mono_search"));
   713         mProgressButton->setIcon(HbIcon("qtg_mono_search"));
   717     }
   714     }
   718 
   715 
   719     // Display the search result count.
   716     // Update result view. Shows no message label if no matching messages were found.
   720     updateSearchResultCountInfo();
   717     updateResultView();
   721 
   718 
   722     const int resultCount = mMsgListModel.rowCount();
   719     // Undim the search input.
   723 
   720     setSearchInputMode(NmNormalMode);
   724     if (resultCount) {
   721 
   725         // Undim the search input.
   722     // In no matching messages were found. Show no messages label and open VKB.
   726         setSearchInputMode(NmNormalMode);
   723     if (mMsgListModel.rowCount() < 1) {
       
   724         noMessagesLabelVisibility(true);
       
   725 
       
   726         sendSoftwareInputPanelRequest(QEvent::RequestSoftwareInputPanel);
       
   727 
       
   728         // Select text
       
   729         mLineEdit->selectAll();
       
   730     }
       
   731 }
       
   732 
       
   733 /*!
       
   734     By default search button is disabled but when some text is
       
   735     written to search field, the search button is enabled. When search field is
       
   736     erased, button is disabled.
       
   737 
       
   738     \param text chaged text.
       
   739 */
       
   740 void NmMessageSearchListView::textChanged(const QString &text)
       
   741 {
       
   742     NM_FUNCTION;
       
   743 
       
   744     if (!text.isEmpty()) {
       
   745         if (!mProgressButton->isEnabled()) {
       
   746             mProgressButton->setEnabled(true);
       
   747         }
   727     }
   748     }
   728     else {
   749     else {
   729         // Highlight the search field.
   750         if (mProgressButton->isEnabled()) {
   730         noMessagesLabelVisibility(true);
   751             mProgressButton->setEnabled(false);
   731         setSearchInputMode(NmHighlightedMode);
   752         }
   732     }
   753     }
   733 }
   754 }
   734 
   755 
       
   756 /*!
       
   757     When exit button is clicked, trigger back navigation action
       
   758     which closes the search view.
       
   759 */
       
   760 void NmMessageSearchListView::exitClicked()
       
   761 {
       
   762     NM_FUNCTION;
       
   763 
       
   764     navigationAction()->activate(QAction::Trigger);
       
   765 }
       
   766 
       
   767 /*!
       
   768     Called before orientation chages. Checks if search criteria text
       
   769     needs to be selected after the orientation has changed.
       
   770 */
       
   771 void NmMessageSearchListView::orientationAboutToChange()
       
   772 {
       
   773     NM_FUNCTION;
       
   774 
       
   775     HbVkbHostBridge *instance = HbVkbHostBridge::instance();
       
   776     if (instance &&
       
   777         instance->keypadStatus() == HbVkbHost::HbVkbStatusOpened &&
       
   778         mLineEdit &&
       
   779         mLineEdit->hasSelectedText()) {
       
   780         mSelectTextAfterOrientationChange = true;
       
   781     }
       
   782 }
       
   783 
       
   784 /*!
       
   785     Called when orientation has changed. Selects search criteria text if needed.
       
   786     \sa  NmMessageSearchListView::orientationAboutToChange()
       
   787 */
       
   788 void NmMessageSearchListView::orientationChanged()
       
   789 {
       
   790     NM_FUNCTION;
       
   791     if (mSelectTextAfterOrientationChange) {
       
   792         mLineEdit->selectAll();
       
   793         mSelectTextAfterOrientationChange = false;
       
   794     }
       
   795 
       
   796 }
       
   797 
       
   798 /*!
       
   799     Sends event to software input panel (VKB).
       
   800 
       
   801     Used event types:
       
   802     QEvent::RequestSoftwareInputPanel(opens VKB)
       
   803     QEvent::CloseSoftwareInputPanel(closes VKB)
       
   804 */
       
   805 void NmMessageSearchListView::sendSoftwareInputPanelRequest(QEvent::Type eventType)
       
   806 {
       
   807     NM_FUNCTION;
       
   808 
       
   809     QInputContext *ic = qApp->inputContext();
       
   810     if (ic) {
       
   811         QScopedPointer<QEvent> event(new QEvent(eventType));
       
   812         ic->filterEvent(event.data());
       
   813     }
       
   814 }
       
   815 
       
   816 /*!
       
   817     Called when virtual keyboard is about to open.
       
   818 */
       
   819 void NmMessageSearchListView::vkbOpened()
       
   820 {
       
   821     NM_FUNCTION;
       
   822 
       
   823     setContentFullScreen(true);
       
   824     hideItems(Hb::ToolBarItem);
       
   825 }
       
   826 
       
   827 /*!
       
   828     Called when virtual keyboard is about to close.
       
   829 */
       
   830 void NmMessageSearchListView::vkbClosed()
       
   831 {
       
   832     NM_FUNCTION;
       
   833 
       
   834     setContentFullScreen(false);
       
   835     showItems(Hb::ToolBarItem);
       
   836 }
   735 
   837 
   736 // End of file.
   838 // End of file.