homescreenapp/stateplugins/hsapplibrarystateplugin/src/hssearchview.cpp
changeset 71 1db7cc813a4e
parent 69 87476091b3f5
child 81 7dd137878ff8
equal deleted inserted replaced
69:87476091b3f5 71:1db7cc813a4e
    13  *
    13  *
    14  * Description: hssearchview.cpp
    14  * Description: hssearchview.cpp
    15  *
    15  *
    16  */
    16  */
    17 
    17 
       
    18 #include <QApplication>
       
    19 #include <QInputContext>
    18 #include <QSortFilterProxyModel>
    20 #include <QSortFilterProxyModel>
    19 
    21 
    20 #include <HbGroupBox>
    22 #include <HbGroupBox>
    21 #include <HbLineEdit>
    23 #include <HbLineEdit>
    22 #include <HbListView>
    24 #include <HbListView>
    23 #include <HbAbstractViewItem>
    25 #include <HbAbstractViewItem>
    24 #include <HbView>
    26 #include <HbView>
    25 #include <HbSearchPanel>
    27 #include <HbSearchPanel>
    26 #include <QApplication>
       
    27 #include <QInputContext>
       
    28 
    28 
    29 #include <caitemmodel.h>
    29 #include <caitemmodel.h>
    30 
    30 
    31 #include "hslistviewitem.h"
    31 #include "hslistviewitem.h"
    32 #include "hsmainwindow.h"
    32 #include "hsmainwindow.h"
    38   \param stateContext Identifies the state where search starts from.
    38   \param stateContext Identifies the state where search starts from.
    39   \param mainWindow Enables switching between originating and search view.
    39   \param mainWindow Enables switching between originating and search view.
    40  */
    40  */
    41 HsSearchView::HsSearchView(HsMenuViewBuilder &builder,
    41 HsSearchView::HsSearchView(HsMenuViewBuilder &builder,
    42         HsStateContext stateContext, HsMainWindow &mainWindow) :
    42         HsStateContext stateContext, HsMainWindow &mainWindow) :
    43     mProxyModel(new QSortFilterProxyModel(this)),
    43     mProxyModel(new QSortFilterProxyModel(this)), mSearchView(NULL),
    44     mSearchView(NULL),
       
    45     mSearchListView(NULL), mSearchPanel(NULL), mStateContext(stateContext),
    44     mSearchListView(NULL), mSearchPanel(NULL), mStateContext(stateContext),
    46     mBuilder(builder), mMainWindow(mainWindow), mListView(NULL),
    45     mBuilder(builder), mMainWindow(mainWindow), mListView(NULL),
    47     mVkbHost(NULL)
    46     mVkbHost(NULL), mSearchViewBuilder(), mEmptyResultText(true)
    48 {
    47 {
    49     mProxyModel->setFilterRole(CaItemModel::TextRole);
    48     mProxyModel->setFilterRole(CaItemModel::TextRole);
    50     mProxyModel->setFilterKeyColumn(1);
    49     mProxyModel->setFilterKeyColumn(1);
    51     mProxyModel->setSortRole(CaItemModel::TextRole);
    50     mProxyModel->setSortRole(CaItemModel::TextRole);
    52 }
    51 }
    68 void HsSearchView::setSearchPanelVisible(bool visible)
    67 void HsSearchView::setSearchPanelVisible(bool visible)
    69 {
    68 {
    70     HSMENUTEST_FUNC_ENTRY("HsMenuView::setSearchPanelVisible");
    69     HSMENUTEST_FUNC_ENTRY("HsMenuView::setSearchPanelVisible");
    71 
    70 
    72     if (visible && !isActive()) {
    71     if (visible && !isActive()) {
    73 
       
    74         searchBegins();
    72         searchBegins();
    75 
       
    76         connectSearchItemViewsSignals();
    73         connectSearchItemViewsSignals();
    77         connectSearchPanelSignals();
    74         connectSearchPanelSignals();
    78 
       
    79     } else if (isActive()) {
    75     } else if (isActive()) {
    80 
       
    81         disconnectSearchPanelSignals();
    76         disconnectSearchPanelSignals();
    82         disconnectSearchItemViewsSignals();
    77         disconnectSearchItemViewsSignals();
    83 
       
    84         searchFinished();
    78         searchFinished();
    85     }
    79     }
    86     HSMENUTEST_FUNC_EXIT("HsMenuView::setSearchPanelVisible");
    80     HSMENUTEST_FUNC_EXIT("HsMenuView::setSearchPanelVisible");
    87 }
    81 }
    88 
    82 
    89 /*!
    83 /*!
    90     \param view List view to operate on.
    84     \param view List view to operate on.
    91     \return Index of F=first visible item of \a view if any 
    85     \return Index of F=first visible item of \a view if any
    92     or default QModelIndex otherwise.
    86     or default QModelIndex otherwise.
    93  */
    87  */
    94 QModelIndex HsSearchView::firstVisibleItemIndex(const HbListView *view) const
    88 QModelIndex HsSearchView::firstVisibleItemIndex(const HbListView *view) const
    95 {
    89 {
    96     QModelIndex result;
    90     const QList<HbAbstractViewItem *> array = view->visibleItems();
    97 
    91     if (array.count()) {
    98     const QList<HbAbstractViewItem *> array =
    92         return array[0]->modelIndex();
    99         view->visibleItems();
    93     }
   100 
    94     return QModelIndex();
   101     if (array.count() >= 1) {
       
   102         result = array[0]->modelIndex();
       
   103     }
       
   104     return result;
       
   105 }
    95 }
   106 
    96 
   107 /*!
    97 /*!
   108  Displays search panel with view representing search results.
    98  Displays search panel with view representing search results.
   109  */
    99  */
   119     mProxyModel->invalidate();
   109     mProxyModel->invalidate();
   120     mProxyModel->setSourceModel(mListView->model());
   110     mProxyModel->setSourceModel(mListView->model());
   121     mProxyModel->setFilterRegExp(
   111     mProxyModel->setFilterRegExp(
   122             QRegExp(QString(".*"), Qt::CaseInsensitive, QRegExp::RegExp));
   112             QRegExp(QString(".*"), Qt::CaseInsensitive, QRegExp::RegExp));
   123 
   113 
   124     QString viewLabelHeading;
   114     mSearchView = mSearchViewBuilder.searchView();
   125 
   115     mSearchListView = mSearchViewBuilder.searchListView();
   126     if (mBuilder.currentViewLabel() != 0) {
   116     mSearchPanel = mSearchViewBuilder.searchPanel();
   127         viewLabelHeading = mBuilder.currentViewLabel()->heading();
       
   128     }
       
   129 
       
   130     setSearchContext();
       
   131 
       
   132     mSearchView = mBuilder.currentView();
       
   133     mSearchListView = mBuilder.currentListView();
       
   134     mSearchPanel = mBuilder.currentSearchPanel();
       
   135     initSearchPanel(*mSearchPanel);
   117     initSearchPanel(*mSearchPanel);
   136     mVkbHost.reset(new HbShrinkingVkbHost(mSearchView));
   118     mVkbHost.reset(new HbShrinkingVkbHost(mSearchView));
   137 
   119 
   138     if (mBuilder.currentViewLabel() != 0) {
   120     if (mBuilder.currentViewLabel()) {
   139         mBuilder.currentViewLabel()->setHeading(viewLabelHeading);
   121         mSearchViewBuilder.searchViewLabel()->setHeading(
   140     }
   122                 mBuilder.currentViewLabel()->heading());
   141 
   123         mSearchViewBuilder.setSearchLabledContext();
       
   124     }
   142 
   125 
   143     mSearchView->hideItems(Hb::AllItems);
   126     mSearchView->hideItems(Hb::AllItems);
   144     mSearchListView->setModel(mProxyModel);
   127     mSearchListView->setModel(mProxyModel, new HsListViewItem());
   145     mSearchListView->setItemPrototype(new HsListViewItem());
       
   146 
   128 
   147     mMainWindow.setCurrentView(mSearchView);
   129     mMainWindow.setCurrentView(mSearchView);
   148 
   130 
   149     mSearchListView->scrollTo(
   131     mSearchListView->scrollTo(
   150         mProxyModel->mapFromSource(mSearchViewInitialIndex),
   132         mProxyModel->mapFromSource(mSearchViewInitialIndex),
   151         HbAbstractItemView::PositionAtTop);
   133         HbAbstractItemView::PositionAtTop);
       
   134 
       
   135     setNoResultsVisibility();
   152     HSMENUTEST_FUNC_EXIT("HsSearchView::searchBegins");
   136     HSMENUTEST_FUNC_EXIT("HsSearchView::searchBegins");
   153 }
   137 }
   154 
   138 
       
   139 /*!
       
   140  Handles button visibility.
       
   141  \param visibility indicates whether show or not to show 'empty' label.
       
   142  */
       
   143 void HsSearchView::setNoResultsVisibility()
       
   144 {
       
   145     if (mProxyModel->rowCount() && mEmptyResultText) {
       
   146         mSearchViewBuilder.loadViewListSection();
       
   147         mEmptyResultText = false;
       
   148     } else if (!mProxyModel->rowCount() && !mEmptyResultText) {
       
   149         mSearchViewBuilder.loadViewEmptySection();
       
   150         mEmptyResultText = true;
       
   151     }
       
   152 }
   155 
   153 
   156 /*
   154 /*
   157  Connects \a activated and \a longPressed signals coming from search list
   155  Connects \a activated and \a longPressed signals coming from search list
   158  view to emit corresponding signal of this object with translated model index.
   156  view to emit corresponding signal of this object with translated model index.
   159 */
   157 */
   195  Connects signals \a exitClicked and \a criteriaChanged emitted
   193  Connects signals \a exitClicked and \a criteriaChanged emitted
   196  by search panel with handling slots of the object or its members.
   194  by search panel with handling slots of the object or its members.
   197 */
   195 */
   198 void HsSearchView::connectSearchPanelSignals()
   196 void HsSearchView::connectSearchPanelSignals()
   199 {
   197 {
       
   198     connect(mProxyModel, SIGNAL(rowsInserted(QModelIndex, int, int)),
       
   199             this, SLOT(setNoResultsVisibility()));
       
   200     connect(mProxyModel, SIGNAL(rowsRemoved(QModelIndex, int, int)),
       
   201             this, SLOT(setNoResultsVisibility()));
   200     connect(mSearchPanel, SIGNAL(exitClicked()),
   202     connect(mSearchPanel, SIGNAL(exitClicked()),
   201             this, SLOT(hideSearchPanel()));
   203             this, SLOT(hideSearchPanel()));
   202     connect(mSearchPanel, SIGNAL(criteriaChanged(QString)),
   204     connect(mSearchPanel, SIGNAL(criteriaChanged(QString)),
   203             this, SLOT(findItem(QString)));
   205             this, SLOT(findItem(QString)));
   204 }
   206 }
   208  by search panel from handling slots of the object or its members
   210  by search panel from handling slots of the object or its members
   209  Scrolls view to state before connections.
   211  Scrolls view to state before connections.
   210 */
   212 */
   211 void HsSearchView::disconnectSearchPanelSignals()
   213 void HsSearchView::disconnectSearchPanelSignals()
   212 {
   214 {
   213     disconnect(mSearchPanel, SIGNAL(exitClicked()),
   215     mProxyModel->disconnect(this);
   214            this, SLOT(hideSearchPanel()));
   216     mSearchPanel->disconnect(this);
   215     disconnect(mSearchPanel, SIGNAL(criteriaChanged(QString)),
       
   216            this, SLOT(findItem(QString)));
       
   217 }
   217 }
   218 
   218 
   219 /*!
   219 /*!
   220   Scrolls originating view to first item matching search criteria.
   220   Scrolls originating view to first item matching search criteria.
   221  */
   221  */
   222 void HsSearchView::searchFinished()
   222 void HsSearchView::searchFinished()
   223 {
   223 {
   224     HSMENUTEST_FUNC_ENTRY("HsSearchView::searchFinished");
   224     HSMENUTEST_FUNC_ENTRY("HsSearchView::searchFinished");
   225 
   225 
   226     mIndexToScrollAfterSearchDone =
   226     mIndexToScrollAfterSearchDone = firstVisibleItemIndex(mSearchListView);
   227             firstVisibleItemIndex(mSearchListView);
       
   228 
   227 
   229     setOriginatingContext();
   228     setOriginatingContext();
   230 
   229 
   231     mMainWindow.setCurrentView(mBuilder.currentView());
   230     mMainWindow.setCurrentView(mBuilder.currentView());
   232 
   231 
   233     mListView->scrollTo(mProxyModel->mapToSource(mIndexToScrollAfterSearchDone),
   232     mListView->scrollTo(mProxyModel->mapToSource(
       
   233             mIndexToScrollAfterSearchDone),
   234             HbAbstractItemView::PositionAtTop);
   234             HbAbstractItemView::PositionAtTop);
   235 
   235 
   236     HbVkbHost::detachHost(mSearchView);
   236     HbVkbHost::detachHost(mSearchView);
   237     mVkbHost.reset(NULL);
   237     mVkbHost.reset(NULL);
   238     mSearchListView = NULL;
   238     mSearchListView = NULL;
   239     mSearchPanel = NULL;
   239     mSearchPanel = NULL;
       
   240     mProxyModel->setSourceModel(NULL);
   240     HSMENUTEST_FUNC_EXIT("HsSearchView::searchFinished");
   241     HSMENUTEST_FUNC_EXIT("HsSearchView::searchFinished");
   241 }
   242 }
   242 
   243 
   243 /*!
   244 /*!
   244  Looks up for item and if found scrolls to it.
   245  Looks up for item and if found scrolls to it.
   247 void HsSearchView::findItem(QString criteriaStr)
   248 void HsSearchView::findItem(QString criteriaStr)
   248 {
   249 {
   249     qDebug() << "HsSearchView::findItem: " + criteriaStr;
   250     qDebug() << "HsSearchView::findItem: " + criteriaStr;
   250     HSMENUTEST_FUNC_ENTRY("HsSearchView::findItem");
   251     HSMENUTEST_FUNC_ENTRY("HsSearchView::findItem");
   251 
   252 
   252     mProxyModel->invalidate();
       
   253     mProxyModel->setSourceModel(mListView->model());
       
   254     mProxyModel->setFilterRegExp(
   253     mProxyModel->setFilterRegExp(
   255             QRegExp("(^|\\b)" + criteriaStr, Qt::CaseInsensitive));
   254             QRegExp("(^|\\b)" + criteriaStr, Qt::CaseInsensitive));
   256 
   255 
   257     mSearchListView->scrollTo(
   256     mSearchListView->scrollTo(
   258             mProxyModel->index(0,0), HbAbstractItemView::PositionAtTop);
   257             mProxyModel->index(0,0), HbAbstractItemView::PositionAtTop);
   273  Slot used to forward 'long pressed' signal with item description transladed
   272  Slot used to forward 'long pressed' signal with item description transladed
   274  from search view context to context of the view search was requested from.
   273  from search view context to context of the view search was requested from.
   275   \param item Long pressed item.
   274   \param item Long pressed item.
   276   \param coords Coordinates of the long press action.
   275   \param coords Coordinates of the long press action.
   277  */
   276  */
   278 void HsSearchView::longPressedProxySlot(HbAbstractViewItem *item,
   277 void HsSearchView::longPressedProxySlot(
   279                                       const QPointF &coords)
   278         HbAbstractViewItem *item, const QPointF &coords)
   280 {
   279 {
   281     /*
   280     /*
   282     this is a kind of hack, introduced for reasons:
   281     this is a kind of hack, introduced for reasons:
   283     item object should be reusable later, but orbit (or qt) prevents setting
   282     item object should be reusable later, but orbit (or qt) prevents setting
   284     its index model to previous state
   283     its index model to previous state
   285     */
   284     */
   286     mSearchViewLongPressedIndex =
   285     mSearchViewLongPressedIndex = mProxyModel->mapToSource(
   287         mProxyModel->mapToSource(item->modelIndex());
   286             item->modelIndex());
   288     QScopedPointer<HbAbstractViewItem> itemNew(item->createItem());
   287     QScopedPointer<HbAbstractViewItem> itemNew(item->createItem());
   289     itemNew->setModelIndex(mSearchViewLongPressedIndex);
   288     itemNew->setModelIndex(mSearchViewLongPressedIndex);
   290     emit longPressed(itemNew.data(), coords);
   289     emit longPressed(itemNew.data(), coords);
   291 }
   290 }
   292 
   291 
   299 {
   298 {
   300     HbLineEdit *const lineEdit(searchPanelLineEdit(searchPanel));
   299     HbLineEdit *const lineEdit(searchPanelLineEdit(searchPanel));
   301 
   300 
   302     lineEdit->setText("");
   301     lineEdit->setText("");
   303     lineEdit->setFocus();
   302     lineEdit->setFocus();
   304     lineEdit->setInputMethodHints(Qt::ImhNoPredictiveText |
   303     lineEdit->setInputMethodHints(
   305         Qt::ImhNoAutoUppercase);
   304             Qt::ImhNoPredictiveText | Qt::ImhNoAutoUppercase);
   306 }
   305 }
   307 
   306 
   308 /*!
   307 /*!
   309  \param searchPanel Search panel to operate on.
   308  \param searchPanel Search panel to operate on.
   310  \return Line edit of the searchPanel on success, NULL otherwise.
   309  \return Line edit of the searchPanel on success, NULL otherwise.
   313         HbSearchPanel &searchPanel) const
   312         HbSearchPanel &searchPanel) const
   314 {
   313 {
   315     HSMENUTEST_FUNC_ENTRY("HsSearchView::searchPanelLineEdit");
   314     HSMENUTEST_FUNC_ENTRY("HsSearchView::searchPanelLineEdit");
   316 
   315 
   317     HbLineEdit *result(0);
   316     HbLineEdit *result(0);
   318 
       
   319     foreach(QGraphicsItem *obj, searchPanel.childItems()) {
   317     foreach(QGraphicsItem *obj, searchPanel.childItems()) {
   320 
       
   321         QGraphicsWidget *const widget = static_cast<QGraphicsWidget *>(obj);
   318         QGraphicsWidget *const widget = static_cast<QGraphicsWidget *>(obj);
   322 
       
   323         if (widget != NULL) {
   319         if (widget != NULL) {
   324 
       
   325             HbLineEdit *const lineEdit = qobject_cast<HbLineEdit *>(widget);
   320             HbLineEdit *const lineEdit = qobject_cast<HbLineEdit *>(widget);
   326 
       
   327             if (lineEdit != NULL) {
   321             if (lineEdit != NULL) {
   328                 result = lineEdit;
   322                 result = lineEdit;
   329                 break;
   323                 break;
   330             }
   324             }
   331         }
   325         }
   344     mBuilder.setStateContext(mStateContext);
   338     mBuilder.setStateContext(mStateContext);
   345     mBuilder.setOperationalContext(HsItemViewContext);
   339     mBuilder.setOperationalContext(HsItemViewContext);
   346 }
   340 }
   347 
   341 
   348 /*!
   342 /*!
   349   Sets the builder context to the one determined by \a mStateContext and
       
   350   \a HsSearchContext.
       
   351  */
       
   352 void HsSearchView::setSearchContext()
       
   353 {
       
   354     mBuilder.setStateContext(mStateContext);
       
   355     mBuilder.setOperationalContext(HsSearchContext);
       
   356 }
       
   357 /*!
       
   358   \retval true when search view is already invoked, \a false otherwise.
   343   \retval true when search view is already invoked, \a false otherwise.
   359  */
   344  */
   360 bool HsSearchView::isActive() const
   345 bool HsSearchView::isActive() const
   361 {
   346 {
   362     return mSearchListView != NULL;
   347     return mSearchListView != NULL;