--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/homescreenapp/stateplugins/hsapplibrarystateplugin/src/hscollectionstate.cpp Tue Aug 31 15:06:34 2010 +0300
@@ -0,0 +1,510 @@
+/*
+ * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Nokia Corporation - initial contribution.
+ *
+ * Contributors:
+ *
+ * Description: Menu collection state.
+ *
+ */
+
+#include <QStateMachine>
+#include <HbAction>
+#include <HbView>
+#include <HbGroupBox>
+#include <HbListView>
+#include <HbPushButton>
+#include <HbAbstractViewItem>
+#include <HbMenu>
+
+#include <cadefs.h>
+#include <caentry.h>
+#include <caitemmodel.h>
+
+#include "hsapp_defs.h"
+#include "hsmenuevent.h"
+#include "hsmenueventfactory.h"
+#include "hsmenuservice.h"
+#include "hsmenumodewrapper.h"
+#include "hsmenuitemmodel.h"
+#include "hscollectionstate.h"
+#include "hsaddappstocollectionstate.h"
+#include "hsapplibstateutils.h"
+
+/*!
+ \class HsCollectionState
+ \ingroup group_hsmenustateplugin
+ \brief Collection State.
+ Displays a concrete collection.
+ \lib ?library
+ \see StateMachine
+ */
+
+/*!
+ \var HsCollectionState::mSortAttribute
+ Sort order.
+ */
+
+/*!
+ \var HsCollectionState::mCollectionId
+ The id of the current collection.
+ */
+
+/*!
+ \var HsCollectionState::mCollectionType
+ The type of the current collection.
+ */
+
+
+/*!
+ \fn void HsCollectionState::sortOrderChanged(SHsSortAttribute sortOrder);
+ This signal is emitted when sort order is changed to \a sortOrder.
+ \param sortAttribute sort attribute
+ */
+
+/*!
+ \fn void HsCollectionState::constructMenu(bool isDynamic);
+ Set up Menu.
+ \param isDynamic Decides which options should be added to menu.
+ */
+
+/*!
+ Constructor.
+ \param menuViewBuilder Menu view builder.
+ \param menuMode menu mode object (add mode on/add mode off).
+ \param mainWindow main window wrapper.
+ \param parent Owner.
+*/
+HsCollectionState::HsCollectionState(HsMenuViewBuilder &menuViewBuilder,
+ HsMenuModeWrapper &menuMode,
+ HsMainWindow &mainWindow,
+ QState *parent) :
+ HsBaseViewState(mainWindow, menuMode, parent),
+ mSortAttribute(Hs::LatestOnTopHsSortAttribute),
+ mCollectionId(-1)
+{
+ initialize(menuViewBuilder, HsCollectionContext);
+ construct();
+}
+
+/*!
+ Constructs contained objects.
+ */
+void HsCollectionState::construct()
+{
+ HSMENUTEST_FUNC_ENTRY("HsCollectionState::construct");
+
+ const QString parentName =
+ parent() != 0 ? parent()->objectName() : QString("");
+ setObjectName(parentName + "/collectionstate");
+
+ HSMENUTEST_FUNC_EXIT("HsCollectionState::construct");
+}
+
+/*!
+ Destructor.
+ */
+HsCollectionState::~HsCollectionState()
+{
+ mMenuView->inactivate();
+ mMenuView->view()->setNavigationAction(NULL);
+}
+
+
+/*!
+ Sets entry event.
+ \param event entry event.
+ */
+void HsCollectionState::onEntry(QEvent *event)
+{
+ qDebug("HsCollectionState::onEntry()");
+ HSMENUTEST_FUNC_ENTRY("HsCollectionState::onEntry");
+ QState::onEntry(event);
+
+ if (event->type() == HsMenuEvent::eventType()) {
+ HsMenuEvent *menuEvent = static_cast<HsMenuEvent *>(event);
+ QVariantMap data = menuEvent->data();
+ mCollectionId = data.value(Hs::itemIdKey).toInt();
+ mCollectionType = data.value(Hs::entryTypeNameKey).toString();
+ }
+
+ HSMENUTEST_FUNC_EXIT("HsCollectionState::onEntry");
+}
+
+/*!
+ Slot invoked when a state is entered.
+ */
+void HsCollectionState::stateEntered()
+{
+ HSMENUTEST_FUNC_ENTRY("HsCollectionState::stateEntered");
+ if (!mModel) {
+ mModel =
+ HsMenuService::getCollectionModel(
+ mCollectionId, mSortAttribute, mCollectionType);
+ }
+
+ handleEmptyChange(mModel->rowCount() == 0);
+
+ makeConnect();
+
+ mMenuView->viewLabel()->setHeading(
+ mModel->root().data(CaItemModel::CollectionTitleRole).toString());
+
+ HsBaseViewState::stateEntered();
+ HSMENUTEST_FUNC_EXIT("HsCollectionState::stateEntered");
+}
+
+/*!
+ Creates and installs menu options for the view
+ */
+void HsCollectionState::setMenuOptions()
+{
+ HSMENUTEST_FUNC_ENTRY("HsAllCollectionsState::setMenuOptions");
+
+ EntryFlags flags =
+ mModel->root().data(CaItemModel::FlagsRole).value<EntryFlags> ();
+
+ mViewOptions->clearActions();
+
+ mViewOptions->addAction(hbTrId("txt_applib_opt_task_switcher"),
+ static_cast<HsBaseViewState*>(this),
+ SLOT(openTaskSwitcher()));
+
+ if (flags & RemovableEntryFlag) {
+ mViewOptions->addAction(hbTrId("txt_applib_opt_add_content"), this,
+ SLOT(addAppsAction()));
+ }
+
+ mViewOptions->addAction(hbTrId("txt_applib_opt_add_to_home_screen"),
+ this, SLOT(addCollectionShortcutToHomeScreenAction()));
+
+ if (flags & RemovableEntryFlag) {
+ if (mModel->rowCount() > 0) {
+ mViewOptions->addAction(
+ hbTrId("txt_applib_opt_arrange"),
+ this,
+ SLOT(createArrangeCollection()));
+ }
+ mViewOptions->addAction(
+ hbTrId("txt_common_opt_rename_item"),
+ this,
+ SLOT(renameAction()));
+ mViewOptions->addAction(
+ hbTrId("txt_common_opt_delete"),
+ this,
+ SLOT(deleteAction()));
+ }
+ if (mCollectionType == Hs::collectionDownloadedTypeName &&
+ mModel->rowCount() > 0) {
+ HbMenu *sortMenu = mViewOptions->addMenu(
+ hbTrId("txt_applib_opt_sort_by"));
+ //Grouped options are exclusive by default.
+ QActionGroup *sortGroup = new QActionGroup(this);
+ sortGroup->addAction(
+ sortMenu->addAction(
+ hbTrId("txt_applib_opt_sub_latest_on_top"),
+ this,
+ SLOT(latestOnTopMenuAction())));
+ sortGroup->addAction(
+ sortMenu->addAction(
+ hbTrId("txt_applib_opt_sub_oldest_on_top"),
+ this,
+ SLOT(oldestOnTopMenuAction())));
+ foreach(QAction *action, sortMenu->actions()) {
+ action->setCheckable(true);
+ }
+ static const int defaultSortingPosition = 0;
+ sortGroup->actions().at(defaultSortingPosition)->setChecked(true);
+ }
+ mMenuView->view()->setMenu(mViewOptions);
+ HSMENUTEST_FUNC_EXIT("HsAllCollectionsState::setMenuOptions");
+}
+
+/*!
+ Slot invoked when a state is exited.
+ */
+void HsCollectionState::stateExited()
+{
+ HSMENUTEST_FUNC_ENTRY("HsCollectionState::stateExited");
+ mMenuView->disableSearch(false);
+ makeDisconnect();
+
+ delete mModel;
+ mModel = NULL;
+ this->mSortAttribute = Hs::NoHsSortAttribute;
+
+ HsBaseViewState::stateExited();
+
+ HSMENUTEST_FUNC_EXIT("HsCollectionState::stateExited");
+ qDebug("CollectionState::stateExited()");
+}
+
+/*!
+ Perform all signal connections.
+ */
+void HsCollectionState::makeConnect()
+{
+ connect(mBackKeyAction, SIGNAL(triggered()),
+ static_cast<HsBaseViewState*>(this), SLOT(openAppLibrary()));
+ connect(mMenuView.data(),
+ SIGNAL(activated(QModelIndex)),
+ static_cast<HsBaseViewState*>(this),
+ SLOT(launchItem(QModelIndex)));
+ connect(mMenuView.data(),
+ SIGNAL(longPressed(HbAbstractViewItem *, QPointF)),
+ static_cast<HsBaseViewState*>(this),
+ SLOT(showContextMenu(HbAbstractViewItem *, QPointF)));
+ connect(mModel, SIGNAL(modelReset()), SLOT(updateLabel()));
+ connect(mModel, SIGNAL(empty(bool)),this,
+ SLOT(handleEmptyChange(bool)));
+ connect(mModel, SIGNAL(empty(bool)),this,
+ SLOT(lockSearchButton(bool)));
+}
+
+/*!
+ Perform all signal disconnections.
+ */
+void HsCollectionState::makeDisconnect()
+{
+ disconnect(mBackKeyAction, SIGNAL(triggered()),
+ static_cast<HsBaseViewState*>(this), SLOT(openAppLibrary()));
+
+ disconnect(mMenuView.data(),
+ SIGNAL(activated(QModelIndex)),
+ static_cast<HsBaseViewState*>(this),
+ SLOT(launchItem(QModelIndex)));
+ disconnect(mMenuView.data(),
+ SIGNAL(longPressed(HbAbstractViewItem *, QPointF)),
+ static_cast<HsBaseViewState*>(this),
+ SLOT(showContextMenu(HbAbstractViewItem *, QPointF)));
+ disconnect(mModel, SIGNAL(empty(bool)),this,
+ SLOT(handleEmptyChange(bool)));
+
+ disconnect(mModel, SIGNAL(empty(bool)),this,
+ SLOT(lockSearchButton(bool)));
+
+ disconnect(mModel, SIGNAL(modelReset()),
+ this, SLOT(updateLabel()));
+}
+
+/*!
+ Handles context menu actions
+ \param action action taken in context menu
+ */
+void HsCollectionState::contextMenuAction(HbAction *action)
+{
+ HsBaseViewState::contextMenuAction(action);
+ Hs::HsContextAction command =
+ static_cast<Hs::HsContextAction>(action->data().toInt());
+ if (command == Hs::RemoveFromCollectionContextAction ) {
+ const int itemId = mContextModelIndex.data(CaItemModel::IdRole).toInt();
+ machine()->postEvent(
+ HsMenuEventFactory::createRemoveAppFromCollectionEvent(
+ itemId, mCollectionId));
+ }
+}
+
+/*!
+ Handler to be called when model becomes not empty or model becomes empty.
+ \param empty \a true when model becomes empty \a false otherwise.
+ */
+void HsCollectionState::handleEmptyChange(bool empty)
+{
+
+ EntryFlags flags =
+ mModel->root().data(CaItemModel::FlagsRole).value<
+ EntryFlags> ();
+
+ if (empty){
+ if (flags & RemovableEntryFlag){
+ mMenuView->reset(HsButtonContext);
+ connect(mMenuView->contentButton(),
+ SIGNAL(clicked()), this, SLOT(addAppsAction()),
+ Qt::UniqueConnection);
+ } else {
+ mMenuView->reset(HsEmptyLabelContext);
+ }
+
+ } else {
+ mMenuView->reset(HsItemViewContext);
+ mMenuView->setModel(mModel);
+ mMenuView->listView()->scrollTo(
+ mModel->index(0), HbAbstractItemView::PositionAtTop);
+ }
+
+ mMenuView->disableSearch(empty);
+
+ mMenuView->activate();
+
+ setMenuOptions();
+}
+
+
+/*!
+ Handles lock search button
+ \param lock if true lock search button.
+ */
+void HsCollectionState::lockSearchButton(bool lock)
+{
+ mMenuView->disableSearch(lock);
+}
+
+
+/*!
+ Menu add applications action slot
+ \param addApps if true create event for add enties to collection.
+ Parametr use by toggled from HbPushButton
+ */
+void HsCollectionState::addAppsAction()
+{
+ // Add applications
+ machine()->postEvent(
+ HsMenuEventFactory::createAddAppsFromCollectionViewEvent(
+ mCollectionId));
+}
+
+/*!
+ Menu add shortcut action slot
+ */
+void HsCollectionState::addCollectionShortcutToHomeScreenAction()
+{
+ addToHomeScreen(mCollectionId);
+}
+
+/*!
+ Menu rename action slot
+ */
+void HsCollectionState::renameAction()
+{
+ machine()->postEvent(HsMenuEventFactory::createRenameCollectionEvent(
+ mCollectionId));
+}
+
+/*!
+ Menu delete action slot
+ */
+void HsCollectionState::deleteAction()
+{
+ machine()->postEvent(HsMenuEventFactory::createDeleteCollectionEvent(
+ mCollectionId));
+}
+
+/*!
+ Updates label
+ */
+void HsCollectionState::updateLabel()
+{
+ HSMENUTEST_FUNC_ENTRY("HsCollectionState::updateLabel");
+ if (mModel) {
+ mMenuView->viewLabel()->setHeading(
+ mModel->root().data(Qt::DisplayRole).toString());
+ }
+ HSMENUTEST_FUNC_EXIT("HsCollectionState::updateLabel");
+}
+
+/*!
+ Method setting context menu options.
+ */
+void HsCollectionState::setContextMenuOptions(HbAbstractViewItem *item, EntryFlags flags)
+{
+ HbAction *openAction = mContextMenu->addAction(hbTrId(
+ "txt_common_menu_open"));
+ openAction->setData(Hs::OpenAppContextAction);
+ HbAction *addToHomeScreenAction = mContextMenu->addAction(hbTrId(
+ "txt_applib_menu_add_to_home_screen"));
+ addToHomeScreenAction->setData(Hs::AddToHomeScreenContextAction);
+ HbAction *addToCollection = mContextMenu->addAction(hbTrId(
+ "txt_applib_menu_add_to_collection"));
+ addToCollection->setData(Hs::AddToCollectionFromCollectionViewContextAction);
+ HbAction *removeAction(NULL);
+ HbAction *uninstallAction(NULL);
+ HbAction *appSettingsAction(NULL);
+ HbAction *appDetailsAction(NULL);
+ // we do not add remove option in locked collection
+ // check conditions and hide irrelevant menu items
+ EntryFlags rootFlags =
+ mModel->root().data(CaItemModel::FlagsRole).value<
+ EntryFlags> ();
+
+ if (rootFlags & RemovableEntryFlag) {
+ removeAction = mContextMenu->addAction(
+ hbTrId("txt_applib_menu_remove_from_collection"));
+ removeAction->setData(Hs::RemoveFromCollectionContextAction);
+ }
+
+ if ((flags & RemovableEntryFlag)) {
+ uninstallAction = mContextMenu->addAction(hbTrId("txt_common_menu_delete"));
+ uninstallAction->setData(Hs::UninstallContextAction);
+ }
+ QSharedPointer<const CaEntry> entry = mModel->entry(item->modelIndex());
+
+ if (!(entry->attribute(Hs::appSettingsPlugin).isEmpty())) {
+ appSettingsAction = mContextMenu->addAction(hbTrId(
+ "txt_common_menu_settings"));
+ appSettingsAction->setData(Hs::AppSettingContextAction);
+ }
+
+ if (!(entry->attribute(Hs::componentIdAttributeName).isEmpty()) &&
+ (flags & RemovableEntryFlag) ) {
+ appDetailsAction = mContextMenu->addAction(hbTrId(
+ "txt_common_menu_details"));
+ appDetailsAction->setData(Hs::AppDetailsContextAction);
+ }
+
+ addToHomeScreenAction->setVisible(
+ !HsAppLibStateUtils::isCWRTWidgetOnHomeScreen(entry.data()));
+}
+
+/*!
+ A Slot called when an action for sorting (latest
+ on top) is invoked for Downloaded collection.
+ */
+void HsCollectionState::latestOnTopMenuAction()
+{
+ mSortAttribute = Hs::LatestOnTopHsSortAttribute;
+ mModel->setSort(mSortAttribute);
+ emit sortOrderChanged(mSortAttribute);
+}
+
+/*!
+ A Slot called when an action for sorting (oldest
+ on top) is invoked for Downloaded collection.
+ */
+void HsCollectionState::oldestOnTopMenuAction()
+{
+ mSortAttribute = Hs::OldestOnTopHsSortAttribute;
+ mModel->setSort(mSortAttribute);
+ emit sortOrderChanged(mSortAttribute);
+}
+
+/*!
+ A Slot called when an arrange operation
+ is invoked for a static collection.
+ */
+void HsCollectionState::createArrangeCollection()
+{
+ // Arrange collection via the Arrange view
+ int topItemId(0);
+
+ if (mMenuView->listView() != NULL) {
+ const QList<HbAbstractViewItem *> array =
+ mMenuView->listView()->visibleItems();
+
+ if (array.count() >= 1) {
+ QModelIndex idx = array[0]->modelIndex();
+ topItemId = idx.data(CaItemModel::IdRole).toInt();
+ }
+ }
+
+ machine()->postEvent(
+ HsMenuEventFactory::createArrangeCollectionEvent(
+ topItemId,
+ mCollectionId));
+}