homescreenapp/stateplugins/hshomescreenstateplugin/src/hsidlestate.cpp
branchRCL_3
changeset 82 5f0182e07bfb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/homescreenapp/stateplugins/hshomescreenstateplugin/src/hsidlestate.cpp	Tue Aug 31 15:06:34 2010 +0300
@@ -0,0 +1,1431 @@
+/*
+* 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:
+*
+*/
+
+#include <QStateMachine>
+#include <QGraphicsSceneMouseEvent>
+#include <QPropertyAnimation>
+#include <QApplication>
+#include <QVariantHash>
+
+#include <HbMainWindow>
+#include <HbView>
+#include <HbMenu>
+#include <HbAction>
+#include <HbMessageBox>
+#include <HbLabel>
+#include <HbInstantFeedback>
+#include <HbContinuousFeedback>
+#include <HbPanGesture>
+#include <HbTapAndHoldGesture>
+
+#ifdef Q_OS_SYMBIAN
+#include <XQSettingsManager>
+#include <startupdomainpskeys.h>
+#endif
+
+#include "hsidlestate.h"
+#include "hsidlewidget.h"
+#include "hsdomainmodeldatastructures.h"
+#include "hsscene.h"
+#include "hspage.h"
+#include "hspagevisual.h"
+#include "hswidgethost.h"
+#include "hswidgethostvisual.h"
+#include "hswallpaper.h"
+#include "hswallpaperselectionstate.h"
+#include "hstrashbinwidget.h"
+#include "hspageindicator.h"
+#include "hsmenueventfactory.h"
+#include "hshomescreenstatecommon.h"
+#include "hstitleresolver.h"
+#include "hsmenuservice.h"
+#include "hsconfiguration.h"
+#include "hsmessageboxwrapper.h"
+#include "hspropertyanimationwrapper.h"
+#include "hsgui.h"
+
+
+namespace
+{
+  
+    //User adds a new page to home screen
+    const char hsLocTextId_OptionsMenu_AddPage[] = "txt_homescreen_opt_add_page";
+
+    //User removes page from home screen
+    const char hsLocTextId_OptionsMenu_RemovePage[] = "txt_homescreen_opt_remove_page";
+
+    //Sends request to all widgets to enable data connections
+    const char hsLocTextId_OptionsMenu_HsToOnline[] = "txt_homescreen_opt_home_screen_to_online";
+
+    //Sends request to all widgets to disable data connections
+    const char hsLocTextId_OptionsMenu_HsToOffline[] = "txt_homescreen_opt_home_screen_to_offline";
+
+    //Home screen canvas menu item for opening picture gallery
+    const char hsLocTextId_ContextMenu_ChangeWallpaper[] = "txt_homescreen_list_change_wallpaper";
+
+    //Home screen canvas menu item for opening Application library
+    const char hsLocTextId_ContextMenu_AddContent[] = "txt_homescreen_list_add_content";
+
+    //Home screen options menu item for opening Task switcher
+    const char hsLocTextId_OptionsMenu_TaskSwitcher[] = "txt_homescreen_opt_task_switcher";
+
+    //Heading text in confirmation dialog while removing page with content
+    const char hsLocTextId_Title_RemovePage[] = "txt_homescreen_title_remove_page";
+
+    //Text in confirmation dialog while removing page with content
+    const char hsLocTextId_Confirmation_RemovePage[] = "txt_homescreen_info_page_and_content_will_be_remov";
+}
+
+// Helper macros for connecting state entry and exit actions.
+#define ENTRY_ACTION(state, action) \
+    connect(state, SIGNAL(entered()), SLOT(action()));
+#define EXIT_ACTION(state, action) \
+    connect(state, SIGNAL(exited()), SLOT(action()));
+
+
+
+/*!
+    \class HsIdleState
+    \ingroup group_hshomescreenstateplugin
+    \brief Controller part of the home screen idle state.
+
+    Controls the home screen idle state execution. See the
+    state chart below for the state structure.
+
+    \imageDEPRECATED html hsidlestate_statechart.png
+*/
+
+/*!
+    Constructs a new idle state with the given \a parent.
+*/
+HsIdleState::HsIdleState(QState *parent)
+  : QState(parent),
+    mNavigationAction(0), 
+    mTitleResolver(0),
+    mAllowZoneAnimation(false),
+    mContinuousFeedback(0),
+    mTrashBinFeedbackAlreadyPlayed(false),
+    mDeltaX(0),
+    mSceneMenu(0)
+#ifdef Q_OS_SYMBIAN
+    ,mSettingsMgr(0)
+#endif
+    ,mMessageBoxWrapper(0)
+    
+{
+    setupStates();
+    mTitleResolver = new HsTitleResolver(this);
+     
+    // TODO: Uncomment when updated API available
+    //mContinuousFeedback = new HbContinuousFeedback;
+    //mContinuousFeedback->setContinuousEffect(HbFeedback::ContinuousSmooth);
+    //mContinuousFeedback->setIntensity(HbFeedback::IntensityFull );
+
+    mVerticalSnapLineTimer.setSingleShot(true);
+    mHorizontalSnapLineTimer.setSingleShot(true);
+}
+
+/*!
+    Destroys this idle state.
+*/
+HsIdleState::~HsIdleState()
+{
+    // TODO: Uncomment when updated API available
+    //delete mContinuousFeedback;
+}
+
+/*!
+    \copydoc QObject::eventFilter(QObject *watched, QEvent *event)
+*/
+bool HsIdleState::eventFilter(QObject *watched, QEvent *event)
+{
+    switch (event->type()) {
+        case QEvent::ApplicationActivate:
+            action_idle_layoutNewWidgets();
+            break;
+        case QEvent::ApplicationDeactivate:
+            emit event_waitInput();
+            break;
+        default:
+            break;
+    }
+    return QState::eventFilter(watched, event);
+}
+
+/*!
+    \fn HsIdleState::event_applicationLibrary()
+
+    This signal initiates a transition to application library.
+*/
+
+/*!
+    \fn HsIdleState::event_waitInput()
+
+    This signal initiates a transition to the waitInput state.
+*/
+
+/*!
+    \fn HsIdleState::event_moveWidget()
+
+    This signal initiates a transition to the moveWidget state.
+*/
+
+/*!
+    \fn HsIdleState::event_moveScene()
+
+    This signal initiates a transition to the moveScene state.
+*/
+
+/*!
+    \fn HsIdleState::event_selectWallpaper()
+
+    This signal initiates a transition to the selectSceneWallpaper state.
+*/
+
+/*!
+    \fn HsIdleState::event_addPage()
+
+    This signal initiates a transition to the addPage state.
+*/
+
+/*!
+    \fn HsIdleState::event_removePage()
+
+    This signal initiates a transition to the removePage state.
+*/
+
+/*!
+    \fn HsIdleState::event_toggleConnection()
+
+    This signal initiates a transition to the toggleConnection state.
+*/
+
+/*!
+    Creates the internal state structure and connects
+    state entry and exit actions.
+*/
+void HsIdleState::setupStates()
+{
+    // States
+
+    QState *state_waitInput = new QState(this);
+    setInitialState(state_waitInput);
+    QState *state_moveWidget = new QState(this);
+    QState *state_moveScene = new QState(this);
+    HsWallpaperSelectionState *state_wallpaperSelectionState =
+        new HsWallpaperSelectionState(this);
+    QState *state_addPage = new QState(this);
+    QState *state_preRemovePage = new QState(this);
+    QState *state_removePage = new QState(this);
+    QState *state_toggleConnection = new QState(this);
+
+    // Transitions
+
+    state_waitInput->addTransition(
+        this, SIGNAL(event_addPage()), state_addPage);
+    state_waitInput->addTransition(
+        this, SIGNAL(event_preRemovePage()), state_preRemovePage);
+    state_waitInput->addTransition(
+        this, SIGNAL(event_toggleConnection()), state_toggleConnection);
+    state_waitInput->addTransition(
+        this, SIGNAL(event_selectWallpaper()), state_wallpaperSelectionState);
+    state_waitInput->addTransition(
+        this, SIGNAL(event_moveScene()), state_moveScene);
+    state_waitInput->addTransition(
+        this, SIGNAL(event_moveWidget()), state_moveWidget);
+
+    state_moveWidget->addTransition(
+        this, SIGNAL(event_waitInput()), state_waitInput);
+
+    state_moveScene->addTransition(
+        this, SIGNAL(event_waitInput()), state_waitInput);
+
+    state_wallpaperSelectionState->addTransition(
+        state_wallpaperSelectionState, SIGNAL(event_waitInput()), state_waitInput);
+
+    state_addPage->addTransition(state_waitInput);
+    
+    state_preRemovePage->addTransition(
+        this,SIGNAL(event_removePage()),state_removePage);
+    
+    state_preRemovePage->addTransition(
+        this,SIGNAL(event_waitInput()),state_waitInput);
+
+    state_removePage->addTransition(
+        this,SIGNAL(event_waitInput()),state_waitInput);
+
+    state_toggleConnection->addTransition(state_waitInput);
+
+    // Actions
+
+    ENTRY_ACTION(this, action_idle_setupView)
+    ENTRY_ACTION(this, action_idle_layoutNewWidgets)
+    ENTRY_ACTION(this, action_idle_showActivePage)
+    ENTRY_ACTION(this, action_idle_connectOrientationChangeEventHandler)
+    ENTRY_ACTION(this, action_idle_setupTitle)
+    ENTRY_ACTION(this, action_idle_installEventFilter)
+    EXIT_ACTION(this, action_idle_cleanupTitle)
+    EXIT_ACTION(this, action_idle_cleanupView)
+    EXIT_ACTION(this, action_idle_disconnectOrientationChangeEventHandler)
+    EXIT_ACTION(this, action_idle_uninstallEventFilter)
+
+    ENTRY_ACTION(state_waitInput, action_waitInput_updateOptionsMenu)
+    ENTRY_ACTION(state_waitInput, action_waitInput_connectGestureHandlers)
+    ENTRY_ACTION(state_waitInput, action_waitInput_publishIdleKey)
+    EXIT_ACTION(state_waitInput, action_waitInput_disconnectGestureHandlers)
+    EXIT_ACTION(state_waitInput, action_waitInput_resetNewWidgets)
+
+    ENTRY_ACTION(state_moveWidget, action_moveWidget_reparentToControlLayer)
+    ENTRY_ACTION(state_moveWidget, action_moveWidget_startWidgetDragEffect)
+    ENTRY_ACTION(state_moveWidget, action_moveWidget_connectGestureHandlers)
+    ENTRY_ACTION(state_moveWidget, action_moveWidget_setWidgetSnap)
+
+    EXIT_ACTION(state_moveWidget, action_moveWidget_reparentToPage)
+    EXIT_ACTION(state_moveWidget, action_moveWidget_startWidgetDropEffect)
+    EXIT_ACTION(state_moveWidget, action_moveWidget_disconnectGestureHandlers)
+    EXIT_ACTION(state_moveWidget, action_moveWidget_preventZoneAnimation)
+    EXIT_ACTION(state_moveWidget, action_moveWidget_deleteWidgetSnap)
+
+    ENTRY_ACTION(state_moveScene, action_moveScene_connectGestureHandlers)
+    EXIT_ACTION(state_moveScene, action_moveScene_moveToNearestPage)
+    EXIT_ACTION(state_moveScene, action_moveScene_disconnectGestureHandlers)
+    
+    ENTRY_ACTION(state_addPage, action_addPage_addPage)
+    
+    ENTRY_ACTION(state_preRemovePage, action_preRemovePage_showQuery)
+    EXIT_ACTION(state_preRemovePage, action_preRemovePage_exit);
+
+    ENTRY_ACTION(state_removePage, action_removePage_startRemovePageAnimation)
+    EXIT_ACTION(state_removePage, action_removePage_removePage)
+
+    ENTRY_ACTION(state_toggleConnection, action_toggleConnection_toggleConnection)
+}
+
+/*!
+    Computes the page layer x position based on the given \a pageIndex.
+*/
+qreal HsIdleState::pageLayerXPos(int pageIndex) const
+{
+    return -pageIndex * HsGui::instance()->layoutRect().width();
+}
+
+/*!
+    Starts the page change animation based on the given \a targetPageIndex
+    and \a duration.
+*/
+void HsIdleState::startPageChangeAnimation(int targetPageIndex, int duration)
+{
+    HsPropertyAnimationWrapper *animation = HsGui::instance()->pageChangeAnimation();
+    if (animation->isRunning()) {
+        animation->stop();
+    }        
+    animation->disconnect(this);
+    animation->setEndValue(pageLayerXPos(targetPageIndex));
+    animation->setDuration(duration);
+    
+    if (abs(mDeltaX) < HSCONFIGURATION_GET(pageChangePanDistance)) {
+        animation->setEasingCurve(HSCONFIGURATION_GET(bounceAnimationEasingCurve)); 
+    }
+    else {
+        animation->setEasingCurve(HSCONFIGURATION_GET(pageChangeAnimationEasingCurve));
+    }
+
+    connect(animation,
+            SIGNAL(finished()),
+            SLOT(pageChangeAnimationFinished()), 
+            Qt::UniqueConnection);
+    animation->start();
+    
+    HbInstantFeedback::play(HSCONFIGURATION_GET(pageChangeFeedbackEffect));
+    
+    HsGui::instance()->idleWidget()->showPageIndicator();
+    HsGui::instance()->idleWidget()->setActivePage(targetPageIndex);
+}
+
+/*!
+    Starts the page change zone animation (crawling) based on the given a\ duration
+*/
+void HsIdleState::startPageChangeZoneAnimation(int duration)
+{
+    HsScene *scene = HsScene::instance();
+
+    int targetPageIndex = scene->activePageIndex();
+
+    if (isInLeftPageChangeZone() && 0 < targetPageIndex) {
+        --targetPageIndex;
+    } else if (isInRightPageChangeZone() &&
+        targetPageIndex < HSCONFIGURATION_GET(maximumPageCount) - 1) {
+        ++targetPageIndex;
+    } else {
+        return;
+    }
+
+    int bounceEffect = HSCONFIGURATION_GET(bounceEffect);
+    
+    HsPropertyAnimationWrapper *pageCrawlingAnimation =
+        HsGui::instance()->pageCrawlingAnimation();
+
+    if (isInLeftPageChangeZone()) {
+        pageCrawlingAnimation->setEndValue(pageLayerXPos(scene->activePageIndex()) + bounceEffect);
+    } else {
+        pageCrawlingAnimation->setEndValue(pageLayerXPos(scene->activePageIndex()) - bounceEffect);
+    }
+    pageCrawlingAnimation->setDuration(duration);
+    pageCrawlingAnimation->setForward();
+
+    connect(pageCrawlingAnimation,
+            SIGNAL(finished()),
+            SLOT(zoneAnimationFinished()),
+            Qt::UniqueConnection);
+    
+    pageCrawlingAnimation->start();
+}
+
+/*!
+    Checks if the active widget is located inside the left or right
+    page change zone.
+*/
+bool HsIdleState::isInPageChangeZone()
+{
+    return isInLeftPageChangeZone() ||
+           isInRightPageChangeZone();
+}
+
+/*!
+    Checks if touch point in the active widget is located inside the left
+    page change zone.
+*/
+bool HsIdleState::isInLeftPageChangeZone()
+{
+    return mWidgetHotSpot.x() < HSCONFIGURATION_GET(pageChangeZoneWidth);
+}
+
+/*!
+    Checks if touch point in the active widget is located inside the right
+    page change zone.
+*/
+bool HsIdleState::isInRightPageChangeZone()
+{
+    qreal pageWidth = HsGui::instance()->layoutRect().width();
+    return mWidgetHotSpot.x() > pageWidth - HSCONFIGURATION_GET(pageChangeZoneWidth);
+}
+
+/*!
+    Inserts new page at index position \a pageIndex in the scene.
+*/
+void HsIdleState::addPageToScene(int pageIndex)
+{
+    HsPageData data;
+    data.indexPosition = pageIndex;
+    HsPage *page = HsPage::createInstance(data);
+    page->load();
+    HsScene::instance()->addPage(page);
+    HsGui::instance()->idleWidget()->insertPage(pageIndex, page);
+}
+
+/*!
+    Checks if page change zone animation needs to be started or stopped
+*/
+void HsIdleState::updateZoneAnimation()
+{
+    HsPropertyAnimationWrapper *pageCrawlingAnimation = 
+        HsGui::instance()->pageCrawlingAnimation();
+
+    if (!mAllowZoneAnimation) {
+        pageCrawlingAnimation->stop();
+    } else if (isInPageChangeZone()) {
+        // should we start it
+        if (!pageCrawlingAnimation->isRunning() &&
+            !HsGui::instance()->pageChangeAnimation()->isRunning()) {
+            startPageChangeZoneAnimation(HSCONFIGURATION_GET(pageChangeZoneAnimationDuration));
+        } 
+    } else if (pageCrawlingAnimation->isRunning()) {
+        // Not in zone, but still running     
+        if (pageCrawlingAnimation->isForward()){
+            // reverse
+            pageCrawlingAnimation->setDuration(HSCONFIGURATION_GET(pageChangeZoneReverseAnimationDuration));
+            pageCrawlingAnimation->setBackward();
+        } 
+    } 
+}
+
+/*!
+    Selects which trash bin icon is shown or not shown at all
+*/
+void HsIdleState::showTrashBin()
+{
+    if (HsGui::instance()->idleWidget()->trashBin()->isUnderMouse()) {
+        if (!mTrashBinFeedbackAlreadyPlayed) {
+            HbInstantFeedback::play(HSCONFIGURATION_GET(widgetOverTrashbinFeedbackEffect));
+            mTrashBinFeedbackAlreadyPlayed = true;
+        }
+        HsGui::instance()->idleWidget()->trashBin()->activate();
+    } else {
+        HsGui::instance()->idleWidget()->trashBin()->deactivate();
+        mTrashBinFeedbackAlreadyPlayed = false;
+    }
+
+    if (!HsGui::instance()->idleWidget()->pageIndicator()->isAnimationRunning()) {
+        HsGui::instance()->idleWidget()->showTrashBin();
+    }
+}
+
+/*!
+    If called for the first time, setups the idle view.
+    Updates the soft key action and sets the idle view
+    as the current view to the main window.
+*/
+void HsIdleState::action_idle_setupView()
+{
+    HsGui::instance()->setupIdleUi();
+    connect(HsGui::instance(),SIGNAL(navigateToApplibrary()),SIGNAL(event_applicationLibrary()),Qt::UniqueConnection);
+
+}
+
+/*!
+    Sets the idle view's title.
+*/
+void HsIdleState::action_idle_setupTitle()
+{    
+    onTitleChanged(mTitleResolver->title());
+    connect(mTitleResolver, 
+        SIGNAL(titleChanged(QString)), 
+        SLOT(onTitleChanged(QString)));
+}
+
+/*!
+    Updates the idle view's title.
+*/
+void HsIdleState::onTitleChanged(QString title)
+{
+    qDebug() << "HsIdleState::onTitleChanged() to title: " << title;
+    HsGui::instance()->idleView()->setTitle(title);
+}
+
+/*!
+
+*/
+void HsIdleState::onAddContentFromContextMenuActionTriggered()
+{
+    /* include position information in homescreen data,
+       which passed around in applib and returned when adding content
+    */
+    QVariant homescreenData(mPageHotSpot);
+    machine()->postEvent(
+        HsMenuEventFactory::createOpenAppLibraryEvent(Hs::AddHsMenuMode, homescreenData));
+    mPageHotSpot = QPointF();
+}
+
+/*!
+
+*/
+void HsIdleState::onAddContentFromOptionsMenuActionTriggered()
+{
+    machine()->postEvent(
+         HsMenuEventFactory::createOpenAppLibraryEvent(Hs::AddHsMenuMode));
+}
+
+/*!
+    Disconnects the idle view's title.
+*/
+void HsIdleState::action_idle_cleanupTitle()
+{
+    mTitleResolver->disconnect(this);
+}
+
+/*!
+
+*/
+void HsIdleState::onPageTapAndHoldFinished(QGestureEvent *event)
+{
+    mPageHotSpot = qobject_cast<HbTapAndHoldGesture *>(
+        event->gesture(Qt::TapAndHoldGesture))->scenePosition();
+
+    mSceneMenu = new HbMenu();
+    mSceneMenu->setObjectName("hs_ctx_menu");
+    mSceneMenu->setAttribute(Qt::WA_DeleteOnClose);
+
+    HbAction *action = mSceneMenu->addAction(hbTrId(hsLocTextId_ContextMenu_AddContent), this,
+	                      SLOT(onAddContentFromContextMenuActionTriggered()));
+    action->setObjectName("action_add_content_ctx_menu");
+
+    HsScene *scene = HsScene::instance();
+    if (scene->pages().count() < HSCONFIGURATION_GET(maximumPageCount)) {
+        action = mSceneMenu->addAction(hbTrId(hsLocTextId_OptionsMenu_AddPage), this, SIGNAL(event_addPage()));
+        action->setObjectName("action_add_page_ctx_menu");
+    }
+
+    action = mSceneMenu->addAction(hbTrId(hsLocTextId_ContextMenu_ChangeWallpaper), this, SIGNAL(event_selectWallpaper()));
+    action->setObjectName("action_change_wallpaper_ctx_menu");
+    mSceneMenu->setPreferredPos(mPageHotSpot);
+    mSceneMenu->open();
+}
+
+void HsIdleState::onPagePanStarted(QGestureEvent *event)
+{
+    Q_UNUSED(event)
+    emit event_moveScene();
+}
+ 
+void HsIdleState::onPagePanUpdated(QGestureEvent *event)
+{
+    HbPanGesture *gesture = qobject_cast<HbPanGesture *>(
+        event->gesture(Qt::PanGesture));
+
+    mDeltaX = gesture->sceneOffset().x();
+
+    HsScene *scene = HsScene::instance();
+    int bounceEffect = HSCONFIGURATION_GET(bounceEffect);
+    qreal x = qBound(pageLayerXPos(scene->pages().count() - 1) - bounceEffect / 2 / HsGui::instance()->idleWidget()->parallaxFactor(),
+                     pageLayerXPos(scene->activePageIndex()) + mDeltaX,
+                     pageLayerXPos(0) + (bounceEffect / 2 / HsGui::instance()->idleWidget()->parallaxFactor()));
+
+    HsGui::instance()->idleWidget()->setSceneX(x);
+}
+ 
+void HsIdleState::onPagePanFinished(QGestureEvent *event)
+{
+    HbPanGesture *gesture = qobject_cast<HbPanGesture *>(
+        event->gesture(Qt::PanGesture));
+    mDeltaX = gesture->sceneOffset().x();
+    emit event_waitInput();
+}
+
+void HsIdleState::onWidgetTapStarted(HsWidgetHost *widget)
+{
+    HsScene *scene = HsScene::instance();
+    scene->setActiveWidget(widget);
+    HsPage *page = scene->activePage();
+    QMetaObject::invokeMethod(page, "updateZValues", Qt::QueuedConnection);
+}
+ 
+void HsIdleState::onWidgetTapAndHoldFinished(QGestureEvent *event, HsWidgetHost *widget)
+{
+    HsScene *scene = HsScene::instance();
+    scene->setActiveWidget(widget);
+    
+    mWidgetHotSpot = qobject_cast<HbTapAndHoldGesture *>(
+        event->gesture(Qt::TapAndHoldGesture))->scenePosition();
+    mWidgetHotSpotOffset = mWidgetHotSpot - widget->visual()->pos();
+    
+    emit event_moveWidget();
+}
+ 
+void HsIdleState::onWidgetMoveUpdated(const QPointF &scenePos, HsWidgetHost *widget)
+{
+    QRectF widgetRect = widget->visual()->geometry();
+
+    // Move widget to updated position.
+    mWidgetHotSpot = scenePos;
+    widgetRect.moveTopLeft(mWidgetHotSpot - mWidgetHotSpotOffset);
+
+    // When moving widget can go over the pages left border.
+    qreal lowerBoundX = -widgetRect.width();
+
+    // When moving widget can go over the pages right border.
+    QRectF pageRect = HsGui::instance()->idleView()->rect();
+    qreal upperBoundX = pageRect.width();
+
+    // When moving widget can go under the chrome at the pages upper border.
+    // Notice that chrome height is 64 pixels.
+    qreal lowerBoundY = qreal(64) - widgetRect.height();
+
+    // When moving widget can go over the pages down border.
+    qreal upperBoundY = pageRect.height();
+
+    qreal widgetX = qBound(lowerBoundX, widgetRect.x(), upperBoundX);
+    qreal widgetY = qBound(lowerBoundY, widgetRect.y(), upperBoundY);
+
+    // If using ItemClipsChildrenToShape-flag in widgethost then
+    // setPos does not update position here, however setGeometry does it, QT bug?
+    widget->visual()->setGeometry(widgetX, widgetY, widgetRect.width(), widgetRect.height());
+    
+    if (HSCONFIGURATION_GET(isSnapEnabled)) {
+        mSnapResult = HsWidgetPositioningOnWidgetMove::instance()->run(widget->visual()->sceneBoundingRect());
+
+        bool isTrashbinOpen = HsGui::instance()->idleWidget()->trashBin()->isUnderMouse();
+
+        if (HSCONFIGURATION_GET(isSnapEffectsEnabled)) {
+            if (mSnapResult.hasHorizontalSnap && !isTrashbinOpen) {
+                showVerticalLine();
+            } else {
+                hideVerticalLine();
+            }
+            if (mSnapResult.hasVerticalSnap && !isTrashbinOpen) {
+                showHorizontalLine();
+            } else {
+                hideHorizontalLine();
+            }
+        }
+
+        mPreviousSnapResult = mSnapResult;
+    }
+
+    // Handle effects:
+    // User is indicated by a tactile feedback if he/she is trying to move
+    // widget over the first or the last page.
+    HsScene *scene = HsScene::instance();
+    HsPage *page = scene->activePage();
+    int bounceFeedbackEffectDistance = HSCONFIGURATION_GET(bounceFeedbackEffectDistance);
+    if( (page == scene->pages().first() && mWidgetHotSpot.x() < bounceFeedbackEffectDistance ) ||
+        (page == scene->pages().last() && scene->pages().count() == HSCONFIGURATION_GET(maximumPageCount)
+         && mWidgetHotSpot.x() > pageRect.width() - bounceFeedbackEffectDistance)) {
+             HbInstantFeedback::play(HSCONFIGURATION_GET(widgetMoveBlockedFeedbackEffect));
+            // TODO: use code below when Orbit has updated ContinuousFeedback API
+            //if (!mContinuousFeedback->isPlaying()) {
+            //    mContinuousFeedback->play();
+            //}
+        } else /*if (mContinuousFeedback->isPlaying())*/ {
+            //mContinuousFeedback->stop();
+        }
+
+    updateZoneAnimation();
+    showTrashBin();
+}
+ 
+void HsIdleState::onWidgetMoveFinished(const QPointF &scenePos, HsWidgetHost *widget)
+{
+    Q_UNUSED(scenePos)
+    Q_UNUSED(widget)
+    emit event_waitInput();
+}
+
+/*!
+    Lays out the active page's new widgets that were added
+    from the application library.
+*/
+void HsIdleState::action_idle_layoutNewWidgets()
+{
+    HsPage *page = HsScene::instance()->activePage();
+    if (!page) {
+        return;
+    }
+
+    QList<HsWidgetHost *> widgets = page->newWidgets();
+    if (widgets.isEmpty()) {
+        return;
+    }
+
+    foreach (HsWidgetHost *widget, widgets) {
+        widget->startWidget();
+    }
+
+    page->layoutNewWidgets();
+
+}
+
+/*!
+    Moves the scene and page layers so that the active
+    page is shown.
+*/
+void HsIdleState::action_idle_showActivePage()
+{   
+    HsScene *scene = HsScene::instance();
+    QApplication::instance()->installEventFilter(scene);
+    scene->activePage()->showWidgets();
+    qreal x = pageLayerXPos(scene->activePageIndex());
+    HsGui::instance()->idleWidget()->setSceneX(x);
+}
+
+/*!
+    Connects the orientation change event handler.
+*/
+void HsIdleState::action_idle_connectOrientationChangeEventHandler()
+{
+    connect(HsGui::instance(),
+        SIGNAL(orientationChanged(Qt::Orientation)),
+        SLOT(action_idle_orientationChanged()));
+}
+
+void HsIdleState::action_idle_orientationChanged()
+{
+    HsScene::instance()->activePage()->resetNewWidgets();
+    action_idle_showActivePage();
+}
+
+/*!
+    Installs the event filter.
+*/
+void HsIdleState::action_idle_installEventFilter()
+{
+    QCoreApplication::instance()->installEventFilter(this);
+}
+
+/*!
+    Publishes the idle key
+*/
+void HsIdleState::action_waitInput_publishIdleKey()
+{
+#ifdef Q_OS_SYMBIAN
+    qDebug() << "HsIdleState::action_waitInput_publishIdleKey";
+    if (!mSettingsMgr){
+        // All done, let others know it too
+        qDebug() << "Setting the idle key";
+        mSettingsMgr = new XQSettingsManager(this);
+        XQPublishAndSubscribeSettingsKey key(KPSUidStartup.iUid, KPSIdlePhase1Ok);
+        mSettingsMgr->writeItemValue(key, EIdlePhase1Ok);
+
+        // Done, we can disconnect this signal.
+        disconnect(sender(), SIGNAL(entered()), this, SLOT(action_waitInput_publishIdleKey()));
+    }
+#endif
+}
+
+/*!
+    Cleans up the idle view.
+*/
+void HsIdleState::action_idle_cleanupView()
+{
+    HsScene *scene = HsScene::instance();
+    QApplication::instance()->removeEventFilter(scene);
+    scene->activePage()->hideWidgets();
+    
+    HsGui::instance()->disconnect(this,SIGNAL(event_applicationLibrary()));
+    //Close options menu on view change
+    HsGui::instance()->idleView()->setMenu(NULL);
+
+    //Close context menu on view change
+    if (mSceneMenu) {
+        mSceneMenu->close();
+    }
+}
+
+/*!
+    Disconnects the orientation change event handler.
+*/
+void HsIdleState::action_idle_disconnectOrientationChangeEventHandler()
+{
+    disconnect(HsGui::instance(),
+        SIGNAL(orientationChanged(Qt::Orientation)),
+        this, SLOT(action_idle_orientationChanged()));
+}
+
+/*!
+    Disconnects the event filter.
+*/
+void HsIdleState::action_idle_uninstallEventFilter()
+{
+    QCoreApplication::instance()->removeEventFilter(this);
+}
+
+/*!
+    Updates the options menu content.
+*/
+void HsIdleState::action_waitInput_updateOptionsMenu()
+{
+    HsScene *scene = HsScene::instance();
+
+    HbMenu *menu = new HbMenu();
+    menu->setObjectName("hs_menu");
+    // Task switcher
+    menu->addAction(hbTrId(hsLocTextId_OptionsMenu_TaskSwitcher),
+        this, SLOT(openTaskSwitcher()));
+    
+    // Add content
+    menu->addAction(hbTrId(hsLocTextId_ContextMenu_AddContent),
+        this, SLOT(onAddContentFromOptionsMenuActionTriggered()));
+    // Add page
+    if (scene->pages().count() < HSCONFIGURATION_GET(maximumPageCount)) {
+        menu->addAction(hbTrId(hsLocTextId_OptionsMenu_AddPage),
+            this, SIGNAL(event_addPage()));
+    
+    }
+
+    // Change wallpaper
+    menu->addAction(hbTrId(hsLocTextId_ContextMenu_ChangeWallpaper),
+        this, SIGNAL(event_selectWallpaper()));
+    
+    // Remove page
+    if (scene->activePage()->isRemovable()) {
+        menu->addAction(hbTrId(hsLocTextId_OptionsMenu_RemovePage),
+            this, SIGNAL(event_preRemovePage()));
+    }
+
+    // Online / Offline
+    if (scene->isOnline()) {
+        menu->addAction(hbTrId(hsLocTextId_OptionsMenu_HsToOffline),
+            this, SIGNAL(event_toggleConnection()));
+    } else {
+        menu->addAction(hbTrId(hsLocTextId_OptionsMenu_HsToOnline),
+            this, SIGNAL(event_toggleConnection()));
+    }
+
+    HsGui::instance()->idleView()->setMenu(menu);
+}
+
+void HsIdleState::action_waitInput_connectGestureHandlers()
+{
+    HsScene *scene = HsScene::instance();
+
+    connect(scene, 
+        SIGNAL(pageTapAndHoldFinished(QGestureEvent*)), 
+        SLOT(onPageTapAndHoldFinished(QGestureEvent*)),
+        Qt::UniqueConnection);
+
+    connect(scene,
+        SIGNAL(pagePanStarted(QGestureEvent*)),
+        SLOT(onPagePanStarted(QGestureEvent*)),
+        Qt::UniqueConnection);
+
+    connect(scene, 
+        SIGNAL(widgetTapStarted(HsWidgetHost*)), 
+        SLOT(onWidgetTapStarted(HsWidgetHost*)),
+        Qt::UniqueConnection);
+    
+    connect(scene, 
+        SIGNAL(widgetTapAndHoldFinished(QGestureEvent*,HsWidgetHost*)), 
+        SLOT(onWidgetTapAndHoldFinished(QGestureEvent*,HsWidgetHost*)),
+        Qt::UniqueConnection);
+}
+
+void HsIdleState::action_waitInput_disconnectGestureHandlers()
+{
+    HsScene *scene = HsScene::instance();
+    scene->disconnect(this);
+}
+
+/*!
+    Resets new widget layout.
+*/
+void HsIdleState::action_waitInput_resetNewWidgets()
+{
+    HsScene::instance()->activePage()->resetNewWidgets();
+}
+
+/*!
+    Reparents the active widget to the control layer.
+*/
+void HsIdleState::action_moveWidget_reparentToControlLayer()
+{
+    HsWidgetHost *widget = HsScene::instance()->activeWidget();
+    Q_ASSERT(widget);
+    widget->visual()->setParentItem(HsGui::instance()->idleWidget()->controlLayer());
+
+    HsGui::instance()->idleWidget()->showTrashBin();
+}
+
+/*!
+    Starts the widget drag effect.
+*/
+void HsIdleState::action_moveWidget_startWidgetDragEffect()
+{
+    HsWidgetHost *widget = HsScene::instance()->activeWidget();
+    Q_ASSERT(widget);
+    widget->startDragEffect();
+    mAllowZoneAnimation = true;
+}
+
+void HsIdleState::action_moveWidget_connectGestureHandlers()
+{
+    HsScene *scene = HsScene::instance();
+        
+    connect(scene, 
+        SIGNAL(widgetMoveUpdated(const QPointF&,HsWidgetHost*)), 
+        SLOT(onWidgetMoveUpdated(const QPointF&,HsWidgetHost*)),
+        Qt::UniqueConnection);
+    
+    connect(scene, 
+        SIGNAL(widgetMoveFinished(const QPointF&,HsWidgetHost*)), 
+        SLOT(onWidgetMoveFinished(const QPointF&,HsWidgetHost*)),
+        Qt::UniqueConnection);
+}
+
+/*!
+    Initializes the presentation to the snapping algorithm
+    Connects the SIGNAL for changing the presentation on active page changed
+    Connects the timer for showing the snap lines
+*/
+void HsIdleState::action_moveWidget_setWidgetSnap()
+{
+    if (HSCONFIGURATION_GET(isSnapEnabled)) {
+
+        QVariantHash snapConfiguration;
+        snapConfiguration[Hs::snapEnabled] = QString::number(HSCONFIGURATION_GET(isSnapEnabled));
+        snapConfiguration[Hs::snapForce] = QString::number(HSCONFIGURATION_GET(snapForce));
+        snapConfiguration[Hs::snapGap] = QString::number(HSCONFIGURATION_GET(snapGap));
+        HsWidgetPositioningOnWidgetMove::instance()->setConfiguration(snapConfiguration);
+
+        updatePagePresentationToWidgetSnap();
+
+        connect(HsScene::instance(), SIGNAL(activePageChanged()),
+            SLOT(onActivePageChanged()));
+
+        if (HSCONFIGURATION_GET(isSnapEffectsEnabled)) {
+            mVerticalSnapLineTimer.setInterval(HSCONFIGURATION_GET(snapTimeout));
+            mHorizontalSnapLineTimer.setInterval(HSCONFIGURATION_GET(snapTimeout));
+
+            connect(&mVerticalSnapLineTimer, SIGNAL(timeout()),
+                SLOT(onVerticalSnapLineTimerTimeout()));
+            connect(&mHorizontalSnapLineTimer, SIGNAL(timeout()),
+                SLOT(onHorizontalSnapLineTimerTimeout()));
+
+        }
+    }
+}
+
+/*!
+    Create the list of inactive rectangles on the page.
+*/
+QList<QRectF> HsIdleState::createInactiveWidgetRects()
+{
+    HsScene *scene = HsScene::instance();
+    HsPage *activePage = scene->activePage();
+    HsWidgetHost *activeWidget = scene->activeWidget();
+
+    QList<QRectF> incativeWidgetRects;
+
+    foreach (HsWidgetHost* widget, activePage->widgets()) {
+        //If the above function returns the active widget, skip over it as widget and mMovingRect represent same widget.
+        if (widget == activeWidget) {
+           continue;
+        }
+        QRectF widgetRect = widget->visual()->geometry();
+        incativeWidgetRects.append(widgetRect);
+    }
+    return incativeWidgetRects;
+}
+
+/*!
+    Reparents the active widget to the active page.
+*/
+void HsIdleState::action_moveWidget_reparentToPage()
+{
+    HsPropertyAnimationWrapper *pageCrawlingAnimation =
+        HsGui::instance()->pageCrawlingAnimation();
+    if (pageCrawlingAnimation->isRunning()&& 
+        pageCrawlingAnimation->isForward()) {
+
+        pageCrawlingAnimation->setDuration(HSCONFIGURATION_GET(pageChangeZoneReverseAnimationDuration));
+        pageCrawlingAnimation->setBackward();
+    }
+
+    HsScene *scene = HsScene::instance();
+    HsPage *page = scene->activePage();
+    HsWidgetHost *widget = scene->activeWidget();
+
+    if (HsGui::instance()->idleWidget()->trashBin()->isUnderMouse()) {
+        HbInstantFeedback::play(HSCONFIGURATION_GET(widgetDropToTrashbinFeedbackEffect));
+        widget->page()->removeWidget(widget);
+        widget->remove();
+        scene->setActiveWidget(0);
+    } else {
+        if (widget->page() != page) {
+            widget->page()->removeWidget(widget);
+            page->addExistingWidget(widget);
+            if (HsGui::instance()->orientation() == Qt::Horizontal) {
+                widget->removePresentation(Qt::Vertical);
+            } else {
+                widget->removePresentation(Qt::Horizontal);
+            }
+        }
+
+        //Set the snap position of the widget and save the position
+        QRectF widgetRect = widget->visual()->geometry();
+        if (mSnapResult.hasHorizontalSnap) {
+            widgetRect.moveLeft(mSnapResult.horizontalSnapPosition);
+        }
+        if (mSnapResult.hasVerticalSnap) {
+            widgetRect.moveTop(mSnapResult.verticalSnapPosition);
+        }
+
+        QPointF adjustedWidgetPosition = page->adjustedWidgetPosition(widgetRect);
+        widget->visual()->setPos(adjustedWidgetPosition);
+
+        widget->savePresentation();
+        page->updateZValues();
+    }
+
+    widget->visual()->setParentItem(HsScene::instance()->activePage()->visual());
+
+    HsGui::instance()->idleWidget()->showPageIndicator();
+}
+
+/*!
+    Starts the widget drop effect.
+*/
+void HsIdleState::action_moveWidget_startWidgetDropEffect()
+{
+    HsWidgetHost *widget = HsScene::instance()->activeWidget();
+    if (widget) {
+        widget->startDropEffect();
+    }
+}
+
+void HsIdleState::action_moveWidget_disconnectGestureHandlers()
+{
+    HsScene *scene = HsScene::instance();
+    scene->disconnect(this);
+}
+
+/*!
+    Resets the snap position
+    Disconnect the Active Page Changed SIGNAL
+    Disconnects the timers to show snap lines
+*/
+void HsIdleState::action_moveWidget_deleteWidgetSnap()
+{
+    if (HSCONFIGURATION_GET(isSnapEnabled)) {
+        resetSnapPosition();
+
+        disconnect(HsScene::instance(), SIGNAL(activePageChanged()),
+                    this, SLOT(onActivePageChanged()));
+
+        if (HSCONFIGURATION_GET(isSnapEffectsEnabled)) {
+            disconnect(&mVerticalSnapLineTimer, SIGNAL(timeout()),
+                this, SLOT(onVerticalSnapLineTimerTimeout()));
+            disconnect(&mHorizontalSnapLineTimer, SIGNAL(timeout()),
+                this, SLOT(onHorizontalSnapLineTimerTimeout()));
+        }
+    }
+}
+
+/*!
+    Prevents page change zone animation.
+*/
+void HsIdleState::action_moveWidget_preventZoneAnimation()
+{
+    mAllowZoneAnimation = false;
+}
+
+void HsIdleState::action_moveScene_connectGestureHandlers()
+{
+    HsScene *scene = HsScene::instance();
+
+    connect(scene,
+        SIGNAL(pagePanUpdated(QGestureEvent*)),
+        SLOT(onPagePanUpdated(QGestureEvent*)),
+        Qt::UniqueConnection);
+
+    connect(scene,
+        SIGNAL(pagePanFinished(QGestureEvent*)),
+        SLOT(onPagePanFinished(QGestureEvent*)),
+        Qt::UniqueConnection);
+}
+
+/*!
+    Moves to the nearest page.
+*/
+void HsIdleState::action_moveScene_moveToNearestPage()
+{
+    QList<HsPage *> pages = HsScene::instance()->pages();
+    QSizeF pageSize = pages.first()->visual()->size();
+
+    int pageIndex = HsScene::instance()->activePageIndex();
+
+    if (mDeltaX < -HSCONFIGURATION_GET(pageChangePanDistance)) {
+        pageIndex = qMin(pageIndex + 1, pages.count() - 1);
+    } else if (HSCONFIGURATION_GET(pageChangePanDistance) < mDeltaX) {
+        pageIndex = qMax(pageIndex - 1, 0);
+    }
+
+    HsScene::instance()->setActivePageIndex(pageIndex);
+
+    HsPage *page = HsScene::instance()->activePage();
+    if (page) {
+        QList<HsWidgetHost *> widgets = page->newWidgets();
+        if (!widgets.isEmpty()) {
+            foreach (HsWidgetHost *widget, widgets) {
+                widget->startWidget();
+            }
+        }
+    page->layoutNewWidgets();
+    }
+
+    startPageChangeAnimation(pageIndex, HSCONFIGURATION_GET(pageChangeAnimationDuration));
+}
+
+void HsIdleState::action_moveScene_disconnectGestureHandlers()
+{
+    HsScene *scene = HsScene::instance();
+    scene->disconnect(this);
+}
+
+/*!
+    Adds a new page to the scene.
+*/
+void HsIdleState::action_addPage_addPage()
+{
+    HsScene *scene = HsScene::instance();
+	int pageIndex = scene->activePageIndex() + 1;
+    addPageToScene(pageIndex);
+    scene->setActivePageIndex(pageIndex);
+    startPageChangeAnimation(pageIndex, HSCONFIGURATION_GET(newPageAddedAnimationDuration));
+    HsGui::instance()->idleWidget()->pageIndicator()->addItem(pageIndex);
+    HsGui::instance()->idleWidget()->showPageIndicator();
+}
+
+/*!
+    Displays a confirmation query before page is removed if there are widgets on page 
+*/
+void HsIdleState::action_preRemovePage_showQuery()
+{
+    HsScene *scene = HsScene::instance();
+    HsPage *page = scene->activePage();
+
+    if (!page->widgets().isEmpty()) {
+        if (!mMessageBoxWrapper) {
+            mMessageBoxWrapper = new HsMessageBoxWrapper(this);
+            mMessageBoxWrapper->setHeader(hbTrId(hsLocTextId_Title_RemovePage));
+            mMessageBoxWrapper->setQueryText(hbTrId(hsLocTextId_Confirmation_RemovePage));
+            connect(mMessageBoxWrapper,SIGNAL(accepted()),SIGNAL(event_removePage())); 
+            connect(mMessageBoxWrapper,SIGNAL(rejected()),SIGNAL(event_waitInput())); 
+        }
+        mMessageBoxWrapper->show();
+    } else {
+        // Empty page can be removed without confirmation
+        emit event_removePage();
+    }
+}
+
+/*!
+    Make sure confirmation query gets closed if user exits preRemovePage state e.g. by pressing application key
+*/
+void HsIdleState::action_preRemovePage_exit()
+{
+    if (mMessageBoxWrapper) {
+        mMessageBoxWrapper->close();
+    }
+}
+
+/*!
+    Start remove page animation.
+*/
+void HsIdleState::action_removePage_startRemovePageAnimation()
+{
+    HsScene *scene = HsScene::instance();
+   
+    int pageToRemoveIndex = scene->activePageIndex();
+    bool isLastPage(scene->activePage() == scene->pages().last());
+    
+    int nextPageIndex(pageToRemoveIndex);
+   
+    if (isLastPage) {
+        nextPageIndex--; 
+    } else {
+        nextPageIndex++;
+    }
+
+    HsPropertyAnimationWrapper *animation = HsGui::instance()->pageChangeAnimation();
+    if (animation->isRunning()) {
+        animation->stop();
+    }
+    animation->disconnect(this);
+    connect(animation,
+            SIGNAL(finished()),
+            SIGNAL(event_waitInput()), 
+            Qt::UniqueConnection);
+    animation->setEndValue(pageLayerXPos(nextPageIndex));
+    animation->setDuration(HSCONFIGURATION_GET(pageRemovedAnimationDuration));
+   
+    animation->start();
+    
+    HbInstantFeedback::play(HSCONFIGURATION_GET(pageChangeFeedbackEffect));
+    
+}
+
+/*!
+    Removes an existing page from the scene.
+*/
+void HsIdleState::action_removePage_removePage()
+{
+    HsIdleWidget *idleWidget = HsGui::instance()->idleWidget();
+    HsPropertyAnimationWrapper *animation = HsGui::instance()->pageChangeAnimation();
+    HsScene *scene = HsScene::instance();
+    HsPage *pageToRemove = scene->activePage();
+
+    if (animation->isRunning()) {
+        animation->stop();
+    }
+    // remove from ui
+    idleWidget->removePage(pageToRemove->pageIndex());
+    idleWidget->showPageIndicator();
+    // update data model
+    scene->removePage(pageToRemove);
+    // Take new active page (previous was removed) and move scene to right position
+    qreal x = pageLayerXPos(scene->activePageIndex());
+    idleWidget->setSceneX(x);
+    // delete it   
+    pageToRemove->deleteLater();
+   
+}
+/*!
+    Toggles the homescreen online/offline state.
+*/
+void HsIdleState::action_toggleConnection_toggleConnection()
+{
+    HsScene *scene = HsScene::instance();
+    scene->setOnline(!scene->isOnline());
+}
+
+#ifdef COVERAGE_MEASUREMENT
+#pragma CTC SKIP
+#endif //COVERAGE_MEASUREMENT
+
+/*!
+ Open task switcher.
+ \retval true if operation is successful.
+ */
+bool HsIdleState::openTaskSwitcher()
+{
+    return HsMenuService::launchTaskSwitcher();
+}
+#ifdef COVERAGE_MEASUREMENT
+#pragma CTC ENDSKIP
+#endif //COVERAGE_MEASUREMENT
+
+/*!
+    Page change zone animation has been finished.
+ */
+void HsIdleState::zoneAnimationFinished()
+{
+    HsScene *scene = HsScene::instance();
+    int pageIndex = scene->activePageIndex();
+    HsGui *gui(HsGui::instance());
+    if (gui->pageCrawlingAnimation()->isForward()) {
+        if (isInLeftPageChangeZone() &&
+            0 < pageIndex) {
+            --pageIndex;
+        } else if (isInRightPageChangeZone() &&
+                   pageIndex < scene->pages().count()) {
+            ++pageIndex;
+        }
+        if (pageIndex == scene->pages().count()) {
+            if (pageIndex < HSCONFIGURATION_GET(maximumPageCount)) {
+                addPageToScene(pageIndex);
+                gui->idleWidget()->showPageIndicator();
+                gui->idleWidget()->pageIndicator()->addItem(pageIndex);
+            }
+        }
+        scene->setActivePageIndex(pageIndex);
+        startPageChangeAnimation(pageIndex, HSCONFIGURATION_GET(pageChangeAnimationDuration));
+    } else {
+        scene->setActivePageIndex(pageIndex);
+        gui->idleWidget()->setActivePage(pageIndex);
+    }
+}
+
+/*!
+    Page change animation has been finished.
+ */
+void HsIdleState::pageChangeAnimationFinished()
+{
+    updateZoneAnimation();
+}
+
+
+/*!
+    Provides the page presentation to the Widget Snap algorithm
+*/
+void HsIdleState::updatePagePresentationToWidgetSnap()
+{
+    QRectF containerRect = HsScene::instance()->activePage()->contentGeometry();
+    HsWidgetHost *activeWidget = HsScene::instance()->activeWidget();
+    HsWidgetPositioningOnWidgetMove::instance()->setPagePresentation(
+        containerRect, createInactiveWidgetRects(), activeWidget->visual()->geometry());
+}
+
+/*!
+    Reset Snap position, hide the snap lines
+*/
+void HsIdleState::resetSnapPosition()
+{
+    mSnapResult = HsWidgetPositioningOnWidgetMove::Result();
+    mPreviousSnapResult = HsWidgetPositioningOnWidgetMove::Result();
+    hideVerticalLine();
+    hideHorizontalLine();
+}
+
+/*!
+    Show the Vertical line for Snap guidance
+*/
+void HsIdleState::showVerticalLine()
+{
+    if (mPreviousSnapResult.verticalSnapLine.x1() != mSnapResult.verticalSnapLine.x1()) {
+        hideVerticalLine();
+        mVerticalSnapLineTimer.start();
+    }
+    else {
+        //As the Vertical Line position is at the same place,
+        //the timer was started when vertical line positions were at different locations
+        //the line will be shown when the timer expires.
+        //If timer has already expired, just show the line, which is redrawn to new geometry.
+        if (!mVerticalSnapLineTimer.isActive()) {
+            HsGui::instance()->idleWidget()->showVerticalSnapLine(mSnapResult.verticalSnapLine);
+        }
+    }
+}
+
+/*!
+    Timer for showing the Vertical line expires
+*/
+void HsIdleState::onVerticalSnapLineTimerTimeout()
+{
+    HsGui::instance()->idleWidget()->showVerticalSnapLine(mSnapResult.verticalSnapLine);
+}
+
+/*!
+    Hide the Vertical line for Snap guidance
+*/
+void HsIdleState::hideVerticalLine()
+{
+    HsGui::instance()->idleWidget()->hideVerticalSnapLine();
+    mVerticalSnapLineTimer.stop();
+}
+
+/*!
+    Show the Horizontal line for Snap guidance
+*/
+void HsIdleState::showHorizontalLine()
+{
+    if (mPreviousSnapResult.horizontalSnapLine.y1() != mSnapResult.horizontalSnapLine.y1()) {
+        hideHorizontalLine();
+        mHorizontalSnapLineTimer.start();
+    }
+    else {
+        if (!mHorizontalSnapLineTimer.isActive()) {
+            HsGui::instance()->idleWidget()->showHorizontalSnapLine(mSnapResult.horizontalSnapLine);
+        }
+    }
+}
+
+/*!
+    Timer for showing the Horizontal line expires
+*/
+void HsIdleState::onHorizontalSnapLineTimerTimeout()
+{
+    HsGui::instance()->idleWidget()->showHorizontalSnapLine(mSnapResult.horizontalSnapLine);
+}
+
+/*!
+    Hide the Horizontal line for Snap guidance
+*/
+void HsIdleState::hideHorizontalLine()
+{
+    HsGui::instance()->idleWidget()->hideHorizontalSnapLine();
+    mHorizontalSnapLineTimer.stop();
+}
+
+/*!
+    Handles updating the Snap algorithm with page presentation on page change
+*/
+void HsIdleState::onActivePageChanged()
+{
+    updatePagePresentationToWidgetSnap();
+    resetSnapPosition();
+}
+
+