|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Menu collection state. |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <QStateMachine> |
|
19 #include <HbAction> |
|
20 #include <HbView> |
|
21 #include <HbGroupBox> |
|
22 #include <HbListView> |
|
23 #include <HbPushButton> |
|
24 #include <HbAbstractViewItem> |
|
25 #include <HbMenu> |
|
26 |
|
27 #include <cadefs.h> |
|
28 #include <caentry.h> |
|
29 #include <caitemmodel.h> |
|
30 |
|
31 #include "hsapp_defs.h" |
|
32 #include "hsmenuevent.h" |
|
33 #include "hsmenueventfactory.h" |
|
34 #include "hsmenuservice.h" |
|
35 #include "hsmenumodewrapper.h" |
|
36 #include "hsmenuitemmodel.h" |
|
37 #include "hscollectionstate.h" |
|
38 #include "hsaddappstocollectionstate.h" |
|
39 #include "hsapplibstateutils.h" |
|
40 |
|
41 /*! |
|
42 \class HsCollectionState |
|
43 \ingroup group_hsmenustateplugin |
|
44 \brief Collection State. |
|
45 Displays a concrete collection. |
|
46 \lib ?library |
|
47 \see StateMachine |
|
48 */ |
|
49 |
|
50 /*! |
|
51 \var HsCollectionState::mSortAttribute |
|
52 Sort order. |
|
53 */ |
|
54 |
|
55 /*! |
|
56 \var HsCollectionState::mCollectionId |
|
57 The id of the current collection. |
|
58 */ |
|
59 |
|
60 /*! |
|
61 \var HsCollectionState::mCollectionType |
|
62 The type of the current collection. |
|
63 */ |
|
64 |
|
65 |
|
66 /*! |
|
67 \fn void HsCollectionState::sortOrderChanged(SHsSortAttribute sortOrder); |
|
68 This signal is emitted when sort order is changed to \a sortOrder. |
|
69 \param sortAttribute sort attribute |
|
70 */ |
|
71 |
|
72 /*! |
|
73 \fn void HsCollectionState::constructMenu(bool isDynamic); |
|
74 Set up Menu. |
|
75 \param isDynamic Decides which options should be added to menu. |
|
76 */ |
|
77 |
|
78 /*! |
|
79 Constructor. |
|
80 \param menuViewBuilder Menu view builder. |
|
81 \param menuMode menu mode object (add mode on/add mode off). |
|
82 \param mainWindow main window wrapper. |
|
83 \param parent Owner. |
|
84 */ |
|
85 HsCollectionState::HsCollectionState(HsMenuViewBuilder &menuViewBuilder, |
|
86 HsMenuModeWrapper &menuMode, |
|
87 HsMainWindow &mainWindow, |
|
88 QState *parent) : |
|
89 HsBaseViewState(mainWindow, menuMode, parent), |
|
90 mSortAttribute(Hs::LatestOnTopHsSortAttribute), |
|
91 mCollectionId(-1) |
|
92 { |
|
93 initialize(menuViewBuilder, HsCollectionContext); |
|
94 construct(); |
|
95 } |
|
96 |
|
97 /*! |
|
98 Constructs contained objects. |
|
99 */ |
|
100 void HsCollectionState::construct() |
|
101 { |
|
102 HSMENUTEST_FUNC_ENTRY("HsCollectionState::construct"); |
|
103 |
|
104 const QString parentName = |
|
105 parent() != 0 ? parent()->objectName() : QString(""); |
|
106 setObjectName(parentName + "/collectionstate"); |
|
107 |
|
108 HSMENUTEST_FUNC_EXIT("HsCollectionState::construct"); |
|
109 } |
|
110 |
|
111 /*! |
|
112 Destructor. |
|
113 */ |
|
114 HsCollectionState::~HsCollectionState() |
|
115 { |
|
116 mMenuView->inactivate(); |
|
117 mMenuView->view()->setNavigationAction(NULL); |
|
118 } |
|
119 |
|
120 |
|
121 /*! |
|
122 Sets entry event. |
|
123 \param event entry event. |
|
124 */ |
|
125 void HsCollectionState::onEntry(QEvent *event) |
|
126 { |
|
127 qDebug("HsCollectionState::onEntry()"); |
|
128 HSMENUTEST_FUNC_ENTRY("HsCollectionState::onEntry"); |
|
129 QState::onEntry(event); |
|
130 |
|
131 if (event->type() == HsMenuEvent::eventType()) { |
|
132 HsMenuEvent *menuEvent = static_cast<HsMenuEvent *>(event); |
|
133 QVariantMap data = menuEvent->data(); |
|
134 mCollectionId = data.value(Hs::itemIdKey).toInt(); |
|
135 mCollectionType = data.value(Hs::entryTypeNameKey).toString(); |
|
136 } |
|
137 |
|
138 HSMENUTEST_FUNC_EXIT("HsCollectionState::onEntry"); |
|
139 } |
|
140 |
|
141 /*! |
|
142 Slot invoked when a state is entered. |
|
143 */ |
|
144 void HsCollectionState::stateEntered() |
|
145 { |
|
146 HSMENUTEST_FUNC_ENTRY("HsCollectionState::stateEntered"); |
|
147 if (!mModel) { |
|
148 mModel = |
|
149 HsMenuService::getCollectionModel( |
|
150 mCollectionId, mSortAttribute, mCollectionType); |
|
151 } |
|
152 |
|
153 handleEmptyChange(mModel->rowCount() == 0); |
|
154 |
|
155 makeConnect(); |
|
156 |
|
157 mMenuView->viewLabel()->setHeading( |
|
158 mModel->root().data(CaItemModel::CollectionTitleRole).toString()); |
|
159 |
|
160 HsBaseViewState::stateEntered(); |
|
161 HSMENUTEST_FUNC_EXIT("HsCollectionState::stateEntered"); |
|
162 } |
|
163 |
|
164 /*! |
|
165 Creates and installs menu options for the view |
|
166 */ |
|
167 void HsCollectionState::setMenuOptions() |
|
168 { |
|
169 HSMENUTEST_FUNC_ENTRY("HsAllCollectionsState::setMenuOptions"); |
|
170 |
|
171 EntryFlags flags = |
|
172 mModel->root().data(CaItemModel::FlagsRole).value<EntryFlags> (); |
|
173 |
|
174 mViewOptions->clearActions(); |
|
175 |
|
176 mViewOptions->addAction(hbTrId("txt_applib_opt_task_switcher"), |
|
177 static_cast<HsBaseViewState*>(this), |
|
178 SLOT(openTaskSwitcher())); |
|
179 |
|
180 if (flags & RemovableEntryFlag) { |
|
181 mViewOptions->addAction(hbTrId("txt_applib_opt_add_content"), this, |
|
182 SLOT(addAppsAction())); |
|
183 } |
|
184 |
|
185 mViewOptions->addAction(hbTrId("txt_applib_opt_add_to_home_screen"), |
|
186 this, SLOT(addCollectionShortcutToHomeScreenAction())); |
|
187 |
|
188 if (flags & RemovableEntryFlag) { |
|
189 if (mModel->rowCount() > 0) { |
|
190 mViewOptions->addAction( |
|
191 hbTrId("txt_applib_opt_arrange"), |
|
192 this, |
|
193 SLOT(createArrangeCollection())); |
|
194 } |
|
195 mViewOptions->addAction( |
|
196 hbTrId("txt_common_opt_rename_item"), |
|
197 this, |
|
198 SLOT(renameAction())); |
|
199 mViewOptions->addAction( |
|
200 hbTrId("txt_common_opt_delete"), |
|
201 this, |
|
202 SLOT(deleteAction())); |
|
203 } |
|
204 if (mCollectionType == Hs::collectionDownloadedTypeName && |
|
205 mModel->rowCount() > 0) { |
|
206 HbMenu *sortMenu = mViewOptions->addMenu( |
|
207 hbTrId("txt_applib_opt_sort_by")); |
|
208 //Grouped options are exclusive by default. |
|
209 QActionGroup *sortGroup = new QActionGroup(this); |
|
210 sortGroup->addAction( |
|
211 sortMenu->addAction( |
|
212 hbTrId("txt_applib_opt_sub_latest_on_top"), |
|
213 this, |
|
214 SLOT(latestOnTopMenuAction()))); |
|
215 sortGroup->addAction( |
|
216 sortMenu->addAction( |
|
217 hbTrId("txt_applib_opt_sub_oldest_on_top"), |
|
218 this, |
|
219 SLOT(oldestOnTopMenuAction()))); |
|
220 foreach(QAction *action, sortMenu->actions()) { |
|
221 action->setCheckable(true); |
|
222 } |
|
223 static const int defaultSortingPosition = 0; |
|
224 sortGroup->actions().at(defaultSortingPosition)->setChecked(true); |
|
225 } |
|
226 mMenuView->view()->setMenu(mViewOptions); |
|
227 HSMENUTEST_FUNC_EXIT("HsAllCollectionsState::setMenuOptions"); |
|
228 } |
|
229 |
|
230 /*! |
|
231 Slot invoked when a state is exited. |
|
232 */ |
|
233 void HsCollectionState::stateExited() |
|
234 { |
|
235 HSMENUTEST_FUNC_ENTRY("HsCollectionState::stateExited"); |
|
236 mMenuView->disableSearch(false); |
|
237 makeDisconnect(); |
|
238 |
|
239 delete mModel; |
|
240 mModel = NULL; |
|
241 this->mSortAttribute = Hs::NoHsSortAttribute; |
|
242 |
|
243 HsBaseViewState::stateExited(); |
|
244 |
|
245 HSMENUTEST_FUNC_EXIT("HsCollectionState::stateExited"); |
|
246 qDebug("CollectionState::stateExited()"); |
|
247 } |
|
248 |
|
249 /*! |
|
250 Perform all signal connections. |
|
251 */ |
|
252 void HsCollectionState::makeConnect() |
|
253 { |
|
254 connect(mBackKeyAction, SIGNAL(triggered()), |
|
255 static_cast<HsBaseViewState*>(this), SLOT(openAppLibrary())); |
|
256 connect(mMenuView.data(), |
|
257 SIGNAL(activated(QModelIndex)), |
|
258 static_cast<HsBaseViewState*>(this), |
|
259 SLOT(launchItem(QModelIndex))); |
|
260 connect(mMenuView.data(), |
|
261 SIGNAL(longPressed(HbAbstractViewItem *, QPointF)), |
|
262 static_cast<HsBaseViewState*>(this), |
|
263 SLOT(showContextMenu(HbAbstractViewItem *, QPointF))); |
|
264 connect(mModel, SIGNAL(modelReset()), SLOT(updateLabel())); |
|
265 connect(mModel, SIGNAL(empty(bool)),this, |
|
266 SLOT(handleEmptyChange(bool))); |
|
267 connect(mModel, SIGNAL(empty(bool)),this, |
|
268 SLOT(lockSearchButton(bool))); |
|
269 } |
|
270 |
|
271 /*! |
|
272 Perform all signal disconnections. |
|
273 */ |
|
274 void HsCollectionState::makeDisconnect() |
|
275 { |
|
276 disconnect(mBackKeyAction, SIGNAL(triggered()), |
|
277 static_cast<HsBaseViewState*>(this), SLOT(openAppLibrary())); |
|
278 |
|
279 disconnect(mMenuView.data(), |
|
280 SIGNAL(activated(QModelIndex)), |
|
281 static_cast<HsBaseViewState*>(this), |
|
282 SLOT(launchItem(QModelIndex))); |
|
283 disconnect(mMenuView.data(), |
|
284 SIGNAL(longPressed(HbAbstractViewItem *, QPointF)), |
|
285 static_cast<HsBaseViewState*>(this), |
|
286 SLOT(showContextMenu(HbAbstractViewItem *, QPointF))); |
|
287 disconnect(mModel, SIGNAL(empty(bool)),this, |
|
288 SLOT(handleEmptyChange(bool))); |
|
289 |
|
290 disconnect(mModel, SIGNAL(empty(bool)),this, |
|
291 SLOT(lockSearchButton(bool))); |
|
292 |
|
293 disconnect(mModel, SIGNAL(modelReset()), |
|
294 this, SLOT(updateLabel())); |
|
295 } |
|
296 |
|
297 /*! |
|
298 Handles context menu actions |
|
299 \param action action taken in context menu |
|
300 */ |
|
301 void HsCollectionState::contextMenuAction(HbAction *action) |
|
302 { |
|
303 HsBaseViewState::contextMenuAction(action); |
|
304 Hs::HsContextAction command = |
|
305 static_cast<Hs::HsContextAction>(action->data().toInt()); |
|
306 if (command == Hs::RemoveFromCollectionContextAction ) { |
|
307 const int itemId = mContextModelIndex.data(CaItemModel::IdRole).toInt(); |
|
308 machine()->postEvent( |
|
309 HsMenuEventFactory::createRemoveAppFromCollectionEvent( |
|
310 itemId, mCollectionId)); |
|
311 } |
|
312 } |
|
313 |
|
314 /*! |
|
315 Handler to be called when model becomes not empty or model becomes empty. |
|
316 \param empty \a true when model becomes empty \a false otherwise. |
|
317 */ |
|
318 void HsCollectionState::handleEmptyChange(bool empty) |
|
319 { |
|
320 |
|
321 EntryFlags flags = |
|
322 mModel->root().data(CaItemModel::FlagsRole).value< |
|
323 EntryFlags> (); |
|
324 |
|
325 if (empty){ |
|
326 if (flags & RemovableEntryFlag){ |
|
327 mMenuView->reset(HsButtonContext); |
|
328 connect(mMenuView->contentButton(), |
|
329 SIGNAL(clicked()), this, SLOT(addAppsAction()), |
|
330 Qt::UniqueConnection); |
|
331 } else { |
|
332 mMenuView->reset(HsEmptyLabelContext); |
|
333 } |
|
334 |
|
335 } else { |
|
336 mMenuView->reset(HsItemViewContext); |
|
337 mMenuView->setModel(mModel); |
|
338 mMenuView->listView()->scrollTo( |
|
339 mModel->index(0), HbAbstractItemView::PositionAtTop); |
|
340 } |
|
341 |
|
342 mMenuView->disableSearch(empty); |
|
343 |
|
344 mMenuView->activate(); |
|
345 |
|
346 setMenuOptions(); |
|
347 } |
|
348 |
|
349 |
|
350 /*! |
|
351 Handles lock search button |
|
352 \param lock if true lock search button. |
|
353 */ |
|
354 void HsCollectionState::lockSearchButton(bool lock) |
|
355 { |
|
356 mMenuView->disableSearch(lock); |
|
357 } |
|
358 |
|
359 |
|
360 /*! |
|
361 Menu add applications action slot |
|
362 \param addApps if true create event for add enties to collection. |
|
363 Parametr use by toggled from HbPushButton |
|
364 */ |
|
365 void HsCollectionState::addAppsAction() |
|
366 { |
|
367 // Add applications |
|
368 machine()->postEvent( |
|
369 HsMenuEventFactory::createAddAppsFromCollectionViewEvent( |
|
370 mCollectionId)); |
|
371 } |
|
372 |
|
373 /*! |
|
374 Menu add shortcut action slot |
|
375 */ |
|
376 void HsCollectionState::addCollectionShortcutToHomeScreenAction() |
|
377 { |
|
378 addToHomeScreen(mCollectionId); |
|
379 } |
|
380 |
|
381 /*! |
|
382 Menu rename action slot |
|
383 */ |
|
384 void HsCollectionState::renameAction() |
|
385 { |
|
386 machine()->postEvent(HsMenuEventFactory::createRenameCollectionEvent( |
|
387 mCollectionId)); |
|
388 } |
|
389 |
|
390 /*! |
|
391 Menu delete action slot |
|
392 */ |
|
393 void HsCollectionState::deleteAction() |
|
394 { |
|
395 machine()->postEvent(HsMenuEventFactory::createDeleteCollectionEvent( |
|
396 mCollectionId)); |
|
397 } |
|
398 |
|
399 /*! |
|
400 Updates label |
|
401 */ |
|
402 void HsCollectionState::updateLabel() |
|
403 { |
|
404 HSMENUTEST_FUNC_ENTRY("HsCollectionState::updateLabel"); |
|
405 if (mModel) { |
|
406 mMenuView->viewLabel()->setHeading( |
|
407 mModel->root().data(Qt::DisplayRole).toString()); |
|
408 } |
|
409 HSMENUTEST_FUNC_EXIT("HsCollectionState::updateLabel"); |
|
410 } |
|
411 |
|
412 /*! |
|
413 Method setting context menu options. |
|
414 */ |
|
415 void HsCollectionState::setContextMenuOptions(HbAbstractViewItem *item, EntryFlags flags) |
|
416 { |
|
417 HbAction *openAction = mContextMenu->addAction(hbTrId( |
|
418 "txt_common_menu_open")); |
|
419 openAction->setData(Hs::OpenAppContextAction); |
|
420 HbAction *addToHomeScreenAction = mContextMenu->addAction(hbTrId( |
|
421 "txt_applib_menu_add_to_home_screen")); |
|
422 addToHomeScreenAction->setData(Hs::AddToHomeScreenContextAction); |
|
423 HbAction *addToCollection = mContextMenu->addAction(hbTrId( |
|
424 "txt_applib_menu_add_to_collection")); |
|
425 addToCollection->setData(Hs::AddToCollectionFromCollectionViewContextAction); |
|
426 HbAction *removeAction(NULL); |
|
427 HbAction *uninstallAction(NULL); |
|
428 HbAction *appSettingsAction(NULL); |
|
429 HbAction *appDetailsAction(NULL); |
|
430 // we do not add remove option in locked collection |
|
431 // check conditions and hide irrelevant menu items |
|
432 EntryFlags rootFlags = |
|
433 mModel->root().data(CaItemModel::FlagsRole).value< |
|
434 EntryFlags> (); |
|
435 |
|
436 if (rootFlags & RemovableEntryFlag) { |
|
437 removeAction = mContextMenu->addAction( |
|
438 hbTrId("txt_applib_menu_remove_from_collection")); |
|
439 removeAction->setData(Hs::RemoveFromCollectionContextAction); |
|
440 } |
|
441 |
|
442 if ((flags & RemovableEntryFlag)) { |
|
443 uninstallAction = mContextMenu->addAction(hbTrId("txt_common_menu_delete")); |
|
444 uninstallAction->setData(Hs::UninstallContextAction); |
|
445 } |
|
446 QSharedPointer<const CaEntry> entry = mModel->entry(item->modelIndex()); |
|
447 |
|
448 if (!(entry->attribute(Hs::appSettingsPlugin).isEmpty())) { |
|
449 appSettingsAction = mContextMenu->addAction(hbTrId( |
|
450 "txt_common_menu_settings")); |
|
451 appSettingsAction->setData(Hs::AppSettingContextAction); |
|
452 } |
|
453 |
|
454 if (!(entry->attribute(Hs::componentIdAttributeName).isEmpty()) && |
|
455 (flags & RemovableEntryFlag) ) { |
|
456 appDetailsAction = mContextMenu->addAction(hbTrId( |
|
457 "txt_common_menu_details")); |
|
458 appDetailsAction->setData(Hs::AppDetailsContextAction); |
|
459 } |
|
460 |
|
461 addToHomeScreenAction->setVisible( |
|
462 !HsAppLibStateUtils::isCWRTWidgetOnHomeScreen(entry.data())); |
|
463 } |
|
464 |
|
465 /*! |
|
466 A Slot called when an action for sorting (latest |
|
467 on top) is invoked for Downloaded collection. |
|
468 */ |
|
469 void HsCollectionState::latestOnTopMenuAction() |
|
470 { |
|
471 mSortAttribute = Hs::LatestOnTopHsSortAttribute; |
|
472 mModel->setSort(mSortAttribute); |
|
473 emit sortOrderChanged(mSortAttribute); |
|
474 } |
|
475 |
|
476 /*! |
|
477 A Slot called when an action for sorting (oldest |
|
478 on top) is invoked for Downloaded collection. |
|
479 */ |
|
480 void HsCollectionState::oldestOnTopMenuAction() |
|
481 { |
|
482 mSortAttribute = Hs::OldestOnTopHsSortAttribute; |
|
483 mModel->setSort(mSortAttribute); |
|
484 emit sortOrderChanged(mSortAttribute); |
|
485 } |
|
486 |
|
487 /*! |
|
488 A Slot called when an arrange operation |
|
489 is invoked for a static collection. |
|
490 */ |
|
491 void HsCollectionState::createArrangeCollection() |
|
492 { |
|
493 // Arrange collection via the Arrange view |
|
494 int topItemId(0); |
|
495 |
|
496 if (mMenuView->listView() != NULL) { |
|
497 const QList<HbAbstractViewItem *> array = |
|
498 mMenuView->listView()->visibleItems(); |
|
499 |
|
500 if (array.count() >= 1) { |
|
501 QModelIndex idx = array[0]->modelIndex(); |
|
502 topItemId = idx.data(CaItemModel::IdRole).toInt(); |
|
503 } |
|
504 } |
|
505 |
|
506 machine()->postEvent( |
|
507 HsMenuEventFactory::createArrangeCollectionEvent( |
|
508 topItemId, |
|
509 mCollectionId)); |
|
510 } |