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; |