Revision: 201031
authorDremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 18 Aug 2010 10:52:49 +0300
changeset 13 8bf920201dea
parent 9 dde80bf4a8c7
child 16 0e550c9259fd
Revision: 201031 Kit: 201033
ganeswidgets/data/hgmediawall.widgetml
ganeswidgets/ganeswidgets.pro
ganeswidgets/inc/HgContainer.h
ganeswidgets/inc/hgmediawall_p.h
ganeswidgets/inc/hgmediawalldataprovider.h
ganeswidgets/inc/hgspring.h
ganeswidgets/inc/hgwidgets_p.h
ganeswidgets/src/HgContainer.cpp
ganeswidgets/src/hgmediawall_p.cpp
ganeswidgets/src/hgmediawallrenderer.cpp
ganeswidgets/src/hgspring.cpp
ganeswidgets/src/hgwidgets.cpp
ganeswidgets/src/hgwidgets_p.cpp
ganeswidgets/tsrc/fute/HgWidgetTest/src/hgwidgetoptionsview.cpp
ganeswidgets/tsrc/fute/HgWidgetTest/src/hgwidgettestview.cpp
hgcacheproxymodel/src/hgbuffermanager.cpp
hgcacheproxymodel/tsrc/unit/test_hgcacheproxydatamodel.cpp
hgcacheproxymodel/tsrc/unit/unittest_hgcacheproxymodel.pro
hgwidgets_plat/ganeswidgets_api/inc/hgmediawall.h
hgwidgets_plat/ganeswidgets_api/inc/hgwidgets.h
layers.sysdef.xml
--- a/ganeswidgets/data/hgmediawall.widgetml	Tue Jul 06 15:29:26 2010 +0300
+++ b/ganeswidgets/data/hgmediawall.widgetml	Wed Aug 18 10:52:49 2010 +0300
@@ -8,9 +8,11 @@
 	<meshitem src="scrollbar-horizontal" srcEdge="RIGHT" dst="content" dstEdge="RIGHT" />
     <meshitem src="scrollbar-horizontal" srcEdge="LEFT" dst="content" dstEdge="LEFT" />
     <meshitem src="description" srcEdge="BOTTOM" dst="scrollbar-horizontal" dstEdge="TOP" />
-    <meshitem src="description" srcEdge="CENTERH" dst="content" dstEdge="CENTERH" />
+    <meshitem src="description" srcEdge="LEFT" dst="content" dstEdge="LEFT" />
+    <meshitem src="description" srcEdge="RIGHT" dst="content" dstEdge="RIGHT" />
     <meshitem src="title" srcEdge="BOTTOM" dst="description" dstEdge="TOP" />
-    <meshitem src="title" srcEdge="CENTERH" dst="content" dstEdge="CENTERH" />
+    <meshitem src="title" srcEdge="LEFT" dst="content" dstEdge="LEFT" />
+    <meshitem src="title" srcEdge="RIGHT" dst="content" dstEdge="RIGHT" />
     <meshitem src="centeritem" srcEdge="BOTTOM" dst="title" dstEdge="TOP" />
     <meshitem src="centeritem" srcEdge="TOP" dst="content" dstEdge="TOP" />
 	<meshitem src="centeritem" srcEdge="RIGHT" dst="content" dstEdge="RIGHT" />
@@ -22,9 +24,11 @@
 	<meshitem src="content" srcEdge="RIGHT" dst="" dstEdge="RIGHT" />
     <meshitem src="content" srcEdge="LEFT" dst="" dstEdge="LEFT" />
     <meshitem src="description" srcEdge="BOTTOM" dst="content" dstEdge="BOTTOM" />
-    <meshitem src="description" srcEdge="CENTERH" dst="content" dstEdge="CENTERH" />
+    <meshitem src="description" srcEdge="LEFT" dst="content" dstEdge="LEFT" />
+    <meshitem src="description" srcEdge="RIGHT" dst="content" dstEdge="RIGHT" />
     <meshitem src="title" srcEdge="BOTTOM" dst="description" dstEdge="TOP" />
-    <meshitem src="title" srcEdge="CENTERH" dst="content" dstEdge="CENTERH" />
+    <meshitem src="title" srcEdge="LEFT" dst="content" dstEdge="LEFT" />
+    <meshitem src="title" srcEdge="RIGHT" dst="content" dstEdge="RIGHT" />
     <meshitem src="centeritem" srcEdge="BOTTOM" dst="title" dstEdge="TOP" />
     <meshitem src="centeritem" srcEdge="TOP" dst="content" dstEdge="TOP" />
 	<meshitem src="centeritem" srcEdge="RIGHT" dst="content" dstEdge="RIGHT" />
--- a/ganeswidgets/ganeswidgets.pro	Tue Jul 06 15:29:26 2010 +0300
+++ b/ganeswidgets/ganeswidgets.pro	Wed Aug 18 10:52:49 2010 +0300
@@ -19,8 +19,7 @@
 DEPENDPATH += .
 INCLUDEPATH += . \
     inc \
-    $$MW_LAYER_SYSTEMINCLUDE \
-    /sf/mw/hb/src/hbcore/gui
+    $$MW_LAYER_SYSTEMINCLUDE
 LIBS += -lestor.dll \
     -lhbcore \
     -lhbwidgets \
--- a/ganeswidgets/inc/HgContainer.h	Tue Jul 06 15:29:26 2010 +0300
+++ b/ganeswidgets/inc/HgContainer.h	Wed Aug 18 10:52:49 2010 +0300
@@ -93,6 +93,8 @@
     Qt::Orientation scrollDirection() const;
     qreal scrollPosition() const;
 
+    void setHandleLongPress(bool handleLongPress);
+        
 signals:
 
     // emit this signal when scrolling. for example scrollbar can be connected to this signal.
@@ -119,7 +121,7 @@
     int imageCount() const;
     const HgImage *image(int index) const;
     int flags(int index) const;
-    const HgImage *indicator(int flags) const;
+    const HgImage *indicator(int flags);
 
 protected: // events
 
@@ -139,7 +141,8 @@
     virtual void handleTapAction(const QPointF& pos, HgWidgetItem* hitItem, int hitItemIndex);
     virtual void handleLongTapAction(const QPointF& pos, HgWidgetItem* hitItem, int hitItemIndex);
     virtual void onScrollPositionChanged(qreal pos);
-
+    virtual void loadIndicatorGraphics(bool loadIfExists = false);
+    
 protected:
 
     enum ItemActionType
@@ -222,6 +225,7 @@
     Qt::Orientation mOrientation;
     QModelIndex mDelayedScrollToIndex;
     bool mIgnoreGestureAction;
+    bool mHandleLongPress;
 };
 
 #endif
--- a/ganeswidgets/inc/hgmediawall_p.h	Tue Jul 06 15:29:26 2010 +0300
+++ b/ganeswidgets/inc/hgmediawall_p.h	Wed Aug 18 10:52:49 2010 +0300
@@ -23,7 +23,6 @@
 
 class HgCoverflowContainer;
 class HgCenterItemArea;
-class HbIconItem;
 class HbTextItem;
 
 class HgMediawallPrivate : public HgWidgetPrivate
@@ -47,7 +46,8 @@
 
 private: // From HgWidgetPrivate
     void updateCurrentItem(const QModelIndex &currentItem);
-
+    void handleThemeChanged();
+    
 private:
     HbTextItem *mTitleItem;
     HbTextItem *mDescriptionItem;
--- a/ganeswidgets/inc/hgmediawalldataprovider.h	Tue Jul 06 15:29:26 2010 +0300
+++ b/ganeswidgets/inc/hgmediawalldataprovider.h	Wed Aug 18 10:52:49 2010 +0300
@@ -49,7 +49,7 @@
      * @param flags.
      * @return pointer HgImage-object.
      */
-    virtual const HgImage* indicator(int flags) const=0;
+    virtual const HgImage* indicator(int flags)=0;
 };
 
 #endif
--- a/ganeswidgets/inc/hgspring.h	Tue Jul 06 15:29:26 2010 +0300
+++ b/ganeswidgets/inc/hgspring.h	Wed Aug 18 10:52:49 2010 +0300
@@ -30,15 +30,21 @@
 class HgSpring : public QObject
 {
     Q_OBJECT
+    Q_PROPERTY(qreal mDamping READ damping WRITE setDamping)
+    Q_PROPERTY(qreal mK READ k WRITE setK)
+    
 public:
 
     explicit HgSpring();    
     virtual ~HgSpring();
     
+    qreal k() const;
+    qreal damping() const;
     void setK(qreal K);
     void setDamping(qreal damping);
     
     void animateToPos(const QPointF& pos);
+    void animateToPosAfterPanning(const QPointF& pos, qreal worldWidth);
     void gotoPos(const QPointF& pos);
     void cancel();
     bool isActive() const;
@@ -63,6 +69,7 @@
     QPointF mStartPos;
     QPointF mPos;
     QPointF mEndPos;
+    QPointF mEndPosOverListBoundary;
     QPointF mVelocity;
     qreal mK;
     qreal mDamping;
@@ -70,6 +77,9 @@
     QTimer* mTimer;
     QTime mPrevTime;
     bool mDoNotUpdate;
+    
+    bool mEndPosOverListEdge;
+    qreal mWorldWidth;
 };
 
 #endif
--- a/ganeswidgets/inc/hgwidgets_p.h	Tue Jul 06 15:29:26 2010 +0300
+++ b/ganeswidgets/inc/hgwidgets_p.h	Wed Aug 18 10:52:49 2010 +0300
@@ -75,6 +75,11 @@
     void setItemSpacing(const QSizeF& size);
     QSizeF itemSpacing() const;
 
+    void setHandleLongPress(bool handleLongPress);
+    bool handleLongPress() const;
+    
+    virtual void handleThemeChanged();
+    
     HgWidget *q_ptr;
 
 private:
@@ -114,11 +119,12 @@
     void _q_modelReset();
     void _q_groovePressed(qreal value, Qt::Orientation orientation);
     void _q_updateCurrentItem(const QModelIndex &current, const QModelIndex &previous);
-
+    void _q_themeChanged();
+    
     void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
 
     void initBufferManager(int itemCount);
-
+    
 protected:
 
     HgContainer *mContainer;
--- a/ganeswidgets/src/HgContainer.cpp	Tue Jul 06 15:29:26 2010 +0300
+++ b/ganeswidgets/src/HgContainer.cpp	Wed Aug 18 10:52:49 2010 +0300
@@ -63,7 +63,8 @@
     mItemSizePolicy(HgWidget::ItemSizeAutomatic),
     mOrientation(Qt::Vertical),
     mDelayedScrollToIndex(),
-    mIgnoreGestureAction(false)
+    mIgnoreGestureAction(false),
+    mHandleLongPress(false)
 {
     FUNC_LOG;
 
@@ -96,6 +97,7 @@
     }
 }
 
+// TODO: This does exactly the same as HgContainer::imageCount(), should this be thus removed?
 int HgContainer::itemCount() const
 {
     return mItems.count();
@@ -393,6 +395,7 @@
     scrollTo(mSelectionModel->currentIndex());
 }
 
+// TODO: This does exactly the same as HgContainer::itemCount(), should this be thus removed?
 int HgContainer::imageCount() const
 {
     return mItems.count();
@@ -416,8 +419,13 @@
     return 0;
 }
 
-const HgImage *HgContainer::indicator(int flags) const
+const HgImage *HgContainer::indicator(int flags)
 {
+    if (flags != 0 && (!mMarkImageOff || !mMarkImageOn)) {
+        // indicators haven't been loaded yet.
+        loadIndicatorGraphics();
+    }
+    
     if (flags & 1) {
         return mMarkImageOn;
     }
@@ -493,6 +501,10 @@
         // set scrollto index to invalid value.
         mDelayedScrollToIndex = QModelIndex();
     }
+    // Indicator size depends from the item size so
+    // indicators need to be updated. Indicators are created
+    // in runtime only for need so if they dont exists they aren't created.
+    loadIndicatorGraphics(true);
 }
 
 // this needs to be implemented for gesture framework to work
@@ -516,7 +528,7 @@
     HbTapGesture *tap = 0;
     if (QGesture *gesture = event->gesture(Qt::TapGesture)) {
         tap = static_cast<HbTapGesture *>(event->gesture(Qt::TapGesture));
-        if (tap->tapStyleHint() == HbTapGesture::TapAndHold) {
+        if (mHandleLongPress && tap->tapStyleHint() == HbTapGesture::TapAndHold) {
             eventHandled = handleLongTap(tap->state(),
                     mapFromScene(event->mapToGraphicsScene(tap->hotSpot())));
         
@@ -547,35 +559,6 @@
 
     mQuadRenderer = mRenderer->getRenderer();
 
-    // Fetch icons for marking mode (on and off states).
-
-    mMarkImageOn = mQuadRenderer->createNativeImage();
-    HANDLE_ERROR_NULL(mMarkImageOn);
-    mMarkImageOff = mQuadRenderer->createNativeImage();
-    HANDLE_ERROR_NULL(mMarkImageOff);
-
-    // Since there is no way to create the icons directly currently
-    // lets create HbCheckBox and ask primitives from it.
-    HbCheckBox* checkBox = new HbCheckBox();
-    checkBox->setCheckState(Qt::Checked);
-    QGraphicsItem *icon = checkBox->HbWidget::primitive("icon");
-    HbIconItem *iconItem = 0;
-    if (icon) {
-        iconItem = static_cast<HbIconItem*>(icon);    
-        if (mMarkImageOn) {
-            mMarkImageOn->setPixmap(iconItem->icon().pixmap());
-        }
-    }
-    checkBox->setCheckState(Qt::Unchecked);
-    icon = checkBox->HbWidget::primitive("icon");    
-    if (icon) {
-        iconItem = static_cast<HbIconItem*>(icon);
-        if (mMarkImageOff) {
-            mMarkImageOff->setPixmap(iconItem->icon().pixmap());
-        }
-    }    
-    delete checkBox;
-
     connect(&mSpring, SIGNAL(updated()), SLOT(updateBySpringPosition()));
     connect(&mSpring, SIGNAL(started()), SIGNAL(scrollingStarted()));
     connect(&mSpring, SIGNAL(started()), SLOT(onScrollingStarted()));
@@ -611,14 +594,12 @@
     FUNC_LOG;
 
     qreal x = mSpring.endPos().x();
-    x = qBound(qreal(0), x, worldWidth());
     if (mRenderer->coverflowModeEnabled()) {
         qreal i = floorf(x);
         x = (x - i > 0.5f) ? ceilf(x) : i;
-        mSpring.animateToPos(QPointF(x, 0));
     }
 
-    mSpring.animateToPos(QPointF(x, 0));
+    mSpring.animateToPosAfterPanning(QPointF(x, 0), worldWidth());
 
 }
 
@@ -679,7 +660,9 @@
         mDragged = false;
         qreal newPos(0);
         if (mDrag.finish(pos, mRenderer->coverflowModeEnabled(), newPos)) {
-            mSpring.animateToPos(QPointF(qBound(qreal(0), newPos, worldWidth()), 0));
+            
+            mSpring.animateToPosAfterPanning(QPointF(newPos, 0), worldWidth());
+            
             HgWidgetItem* item = itemByIndex(newPos);
             if (item && item->modelIndex() != mSelectionModel->currentIndex()) {
             //    mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current);
@@ -707,7 +690,7 @@
     FUNC_LOG;
     
     bool handleGesture = false;
-
+    
     if (hasItemAt(pos)) {
         switch (state) 
             {
@@ -715,9 +698,44 @@
                 {
                 if (mRenderer->coverflowModeEnabled() || !mSpring.isActive()) {
                     mIgnoreGestureAction = false;
-                    startLongPressWatcher(pos);
+
+                    if (mHandleLongPress) {
+                        if (mRenderer->coverflowModeEnabled()) {
+                            // in coverflow mode we react to longtap only if animation is not on and
+                            // center item is tapped.
+                            int temp = 0;
+                            if (getItemAt(pos,temp)->modelIndex() == mSelectionModel->currentIndex() &&
+                                    !mSpring.isActive()) {
+                                startLongPressWatcher(pos);
+                            }
+                        } else {
+                            startLongPressWatcher(pos);
+                        }
+                    }
                 } else if(mSpring.isActive()) {
-                    mSpring.cancel();
+                    
+                    int rowCount = mRenderer->getRowCount();
+                    if(rowCount != 0)   //just in case, should not be zero 
+                    {
+                        qreal springPos = mSpring.pos().x();
+                        int gridTotalHeightInImages = ceilf( mItems.count() / rowCount );
+                        qreal currentViewHeightInImages;
+                        if (scrollDirection() == Qt::Horizontal ) {
+                            int rowHeight = mRenderer->getImageSize().width() + mRenderer->getSpacing().width();
+                            currentViewHeightInImages = rect().width() / rowHeight;
+                        } else {
+                            int rowHeight = mRenderer->getImageSize().height() + mRenderer->getSpacing().height();
+                            currentViewHeightInImages = rect().height() / rowHeight;
+                        }
+                        
+                        // If list does not currently fill the whole screen (some theme background behind the list
+                        // is visible), and list is moving, then do not react to tapping.
+                        if( springPos >= 0 
+                            && springPos <= (gridTotalHeightInImages - currentViewHeightInImages) )
+                        {
+                            mSpring.cancel();
+                        }
+                    }
                     mIgnoreGestureAction = true;
                 }
                 break;
@@ -733,7 +751,7 @@
         
         handleGesture = true;
     } else {
-       mIgnoreGestureAction = true;
+        mIgnoreGestureAction = true;
     }    
     return handleGesture;
 }
@@ -786,15 +804,24 @@
         if (item && action != DoubleTap) {
             if (action == LongTap) {
                 INFO("Long tap:" << item->modelIndex().row());
+
+                bool currentPressed = item->modelIndex() == mSelectionModel->currentIndex();
                 
                 if (!mRenderer->coverflowModeEnabled()) {
                     selectItem(index);
                 } else {
                     mSelectionModel->setCurrentIndex(item->modelIndex(), QItemSelectionModel::Current);
+                    mSpring.animateToPos(QPointF(index, 0));
                 }
 
                 if (!mIgnoreGestureAction) {
-                    emit longPressed(item->modelIndex(), pos);
+                    if (mRenderer->coverflowModeEnabled() && mHandleLongPress) {
+                        if( currentPressed && !mSpring.isActive()) {
+                            emit longPressed(item->modelIndex(), pos);
+                        }
+                    } else if (mHandleLongPress){
+                        emit longPressed(item->modelIndex(), pos);
+                    }
                 } else {
                     mSpring.resetVelocity();
                     update();
@@ -1153,6 +1180,10 @@
         mRenderer->setImageSize(mUserItemSize);
         mRenderer->setSpacing(mUserItemSpacing);
     }
+    // Indicator size depends from the item size so
+    // indicators need to be updated. Indicators are created
+    // in runtime only for need so if they dont exists they aren't created.
+    loadIndicatorGraphics(true);
 }
 
 QSizeF HgContainer::getAutoItemSize() const
@@ -1175,4 +1206,47 @@
     return mSpring.pos().x();
 }
 
+void HgContainer::loadIndicatorGraphics(bool loadIfExists)
+{
+    if (loadIfExists && !mMarkImageOn && !mMarkImageOff) return;
+    
+    if (!mMarkImageOn) {
+        mMarkImageOn = mQuadRenderer->createNativeImage();
+    }        
+    HANDLE_ERROR_NULL(mMarkImageOn);
+    if (!mMarkImageOff) {
+        mMarkImageOff = mQuadRenderer->createNativeImage();
+    }
+    
+    const QSizeF newIndicatorSize = itemSize()/2;
+    
+    // Validate if loading marking icons is really needed by comparing the sizes.
+    // Both marking icons have the same size so its enough to check one.
+    if (mMarkImageOn && mMarkImageOn->width() == newIndicatorSize.width() &&
+            mMarkImageOn->height() == newIndicatorSize.height() ) return;
+    
+    HANDLE_ERROR_NULL(mMarkImageOff);    
+    HbIcon selectedIcon(QLatin1String("qtg_small_selected"));
+    HbIcon unselectedIcon(QLatin1String("qtg_small_unselected"));
+    selectedIcon.setSize(newIndicatorSize);
+    unselectedIcon.setSize(newIndicatorSize);
+
+    QPixmap selectedPixmap = selectedIcon.pixmap();
+    QPixmap unselectedPixmap = unselectedIcon.pixmap();
+
+    if (!selectedPixmap.isNull() && !unselectedPixmap.isNull()) {
+        if (mMarkImageOn) {
+            mMarkImageOn->setPixmap(selectedPixmap);
+        }
+        if (mMarkImageOff) {
+            mMarkImageOff->setPixmap(unselectedPixmap);
+        }
+    }    
+}
+
+void HgContainer::setHandleLongPress(bool handheLongPress)
+{
+    // this is just a flag that is used in gesturehandling logic.
+    mHandleLongPress = handheLongPress;
+}
 // EOF
--- a/ganeswidgets/src/hgmediawall_p.cpp	Tue Jul 06 15:29:26 2010 +0300
+++ b/ganeswidgets/src/hgmediawall_p.cpp	Wed Aug 18 10:52:49 2010 +0300
@@ -16,6 +16,8 @@
 */
 
 #include <HbTextItem>
+#include <HbEvent>
+#include <QApplication>
 #include "hgmediawall_p.h"
 #include "hgwidgetitem.h"
 #include "hgcoverflowcontainer.h"
@@ -41,10 +43,12 @@
 
     mTitleItem = new HbTextItem("", q);
     q->style()->setItemName(mTitleItem, "title");
+    mTitleItem->setElideMode(Qt::ElideRight);
 
     mDescriptionItem = new HbTextItem("", q);
     q->style()->setItemName(mDescriptionItem, "description");
-
+    mDescriptionItem->setElideMode(Qt::ElideRight);
+    
     mCenterItemArea = new HgCenterItemArea(q);
     q->style()->setItemName(mCenterItemArea, "centeritem");
 
@@ -127,4 +131,17 @@
     }
 }
 
+void HgMediawallPrivate::handleThemeChanged()
+{
+    HgWidgetPrivate::handleThemeChanged();
+    
+    if (mTitleItem || mDescriptionItem) {
+        Q_Q(HgMediawall);
+    
+        // this is needed to enforce color fetch from CSS
+        HbEvent themeEvent(HbEvent::ThemeChanged);
+        QApplication::sendEvent(q, &themeEvent);    
+    }
+}
+
 // EOF
--- a/ganeswidgets/src/hgmediawallrenderer.cpp	Tue Jul 06 15:29:26 2010 +0300
+++ b/ganeswidgets/src/hgmediawallrenderer.cpp	Wed Aug 18 10:52:49 2010 +0300
@@ -436,7 +436,7 @@
         mNextScrollDirection = mScrollDirection;
         return;
     }
-    
+        
     if (mScrollDirection != scrollDirection)
     {
         mStateMachine->setAnimated(animate);
@@ -449,7 +449,7 @@
         {
             //emit renderingNeeded();            
         }
-    } else if (!animate) {
+    } else {
         // reset next scrolldirection just to be sure. In some cases
         // when orientation changes couple of times and container visibility changes
         // we might otherwise end up in wrong state.
@@ -661,23 +661,42 @@
 }
     
 qreal HgMediaWallRenderer::getWorldWidth() const
-{   
-    qreal width = ceil((qreal)mDataProvider->imageCount() / (qreal)mRowCount - 1.0f);
-    
+{
+    qreal worldWidth = ceil((qreal)mDataProvider->imageCount() / (qreal)mRowCount);
+    qreal worldWidthAsIndex = worldWidth - 1.0f;
+
     // if we are in vertical orientation we want last and first item
     // to place at the top and bottom of the screen instead of center
     if (mScrollDirection == Qt::Vertical)
     {
-        qreal step = mSpacing2D.height() + mImageSize2D.height(); 
-        width -= (mRect.height() / step - 1.0f);
+        qreal step = mSpacing2D.height() + mImageSize2D.height();
+        qreal screenWidth = mRect.height() / step;
+        if(worldWidth > screenWidth) //do the items take over one screenful?
+        {
+            worldWidthAsIndex -= (screenWidth - 1.0f);
+        }
+        else
+        {
+            // all items fit to one screenful
+            return 0;
+        }
     }
     else if (mScrollDirection == Qt::Horizontal && !mCoverflowMode)
     {
         qreal step = mSpacing2D.width() + mImageSize2D.width();
-        width -= (mRect.width() / step - 1.0f);
+        qreal screenWidth = mRect.width() / step;
+        if(worldWidth > screenWidth) //do the items take over one screenful?
+        {
+            worldWidthAsIndex -= (screenWidth - 1.0f);
+        }
+        else
+        {
+            // all items fit to one screenful
+            return 0;
+        }
     }
-       
-    return width;
+    
+    return worldWidthAsIndex;
 }
 
 
--- a/ganeswidgets/src/hgspring.cpp	Tue Jul 06 15:29:26 2010 +0300
+++ b/ganeswidgets/src/hgspring.cpp	Wed Aug 18 10:52:49 2010 +0300
@@ -21,7 +21,7 @@
 
 const int KTimeDelta(10);
 const qreal KTimeDeltaF(0.01f);
-//const qreal KVelocitySnap(0.05f);
+const qreal KVelocitySnap(0.06f);
 const qreal KPositionSnap(0.01f);
 const int KTimerInterval(10);
 
@@ -29,11 +29,13 @@
 mStartPos(QPointF(0,0)),
 mPos(QPointF(0,0)),
 mEndPos(QPointF(0,0)),
+mEndPosOverListBoundary(QPointF(0,0)),
 mVelocity(QPointF(0,0)),
 mK(30.1),
 mDamping(10.1),
 mAccumulator(0.0),
-mDoNotUpdate(false)
+mDoNotUpdate(false),
+mEndPosOverListEdge(false)
 {
     mTimer = new QTimer(this);
 
@@ -56,8 +58,24 @@
     mDamping = damping;
 }
 
+qreal HgSpring::k() const
+{
+    return mK;
+}
+
+qreal HgSpring::damping() const
+{
+    return mDamping;
+}
+
+// TODO: Remove this function and use only the animateToPosAfterPanning version?
 void HgSpring::animateToPos(const QPointF& pos)
-{
+{    
+    if (mPos == pos) {
+        // No need to animate, we are already in correct position.
+        return;
+    }
+            
     mStartPos = mPos;
     mEndPos = pos;
 
@@ -70,6 +88,39 @@
     }
 }
 
+void HgSpring::animateToPosAfterPanning(const QPointF& pos, qreal worldWidth)
+{    
+    mWorldWidth = worldWidth;
+    mStartPos = mPos;
+    
+    qreal xPos = pos.x();
+    if( xPos < 0.0 )
+    {
+        mEndPosOverListEdge = true;
+        mEndPosOverListBoundary = pos;
+        mEndPos = QPointF(0, 0);
+    }
+    else if( xPos > worldWidth )
+    {
+        mEndPosOverListEdge = true;
+        mEndPosOverListBoundary = pos;
+        mEndPos = QPointF(worldWidth, 0);
+    }
+    else
+    {
+        mEndPosOverListEdge = false;
+        mEndPos = pos;
+    }
+
+    emit started();
+
+    if (!mTimer->isActive())
+    {
+        mTimer->start(KTimerInterval);
+        mPrevTime.start();
+    }
+}
+
 void HgSpring::gotoPos(const QPointF& pos)
 {
     if (mTimer->isActive())
@@ -122,12 +173,36 @@
     bool stopped = false;
     while (mAccumulator >= KTimeDelta)
     {
-        QPointF delta = mEndPos - mPos;
+        QPointF delta;
+        if(mEndPosOverListEdge)
+        {
+            delta = mEndPosOverListBoundary - mPos;
+            
+            if( mPos.x() < KPositionSnap || mPos.x() > mWorldWidth )
+            {
+                // When list's position goes past the world boundary
+                // we reset our mEndPosOverListEdge boolean flag
+                // -> the passed boundary will be used as end point,
+                // and the K value of this spring will be modified.
+                mEndPosOverListEdge = false; //reset
+                mEndPosOverListBoundary = QPointF(0,0); //reset
+                mWorldWidth = 0.0; //reset
+                mK = 60.0;
+            }
+            
+        }
+        else
+        {
+            delta = mEndPos - mPos;
+        }
+        
         QPointF force = delta * mK - mVelocity * mDamping;
         mVelocity += force * KTimeDeltaF;
         mPos += mVelocity * KTimeDeltaF;
+        
         if ( (qAbs(mPos.x() - mEndPos.x()) < KPositionSnap &&
-              qAbs(mPos.y() - mEndPos.y()) < KPositionSnap) )
+                  qAbs(mPos.y() - mEndPos.y()) < KPositionSnap)
+             && qAbs(mVelocity.x()) < KVelocitySnap )
         {
             mPos = mEndPos;
             mAccumulator = 0;
@@ -139,7 +214,7 @@
 
         mAccumulator -= KTimeDelta;
     }
-
+    
     if (!mDoNotUpdate)
         emit updated();
     
--- a/ganeswidgets/src/hgwidgets.cpp	Tue Jul 06 15:29:26 2010 +0300
+++ b/ganeswidgets/src/hgwidgets.cpp	Wed Aug 18 10:52:49 2010 +0300
@@ -25,7 +25,7 @@
 #include "hgwidgets_p.h"
 #include "hgcontainer.h"
 #include "hgwidgetitem.h"
-#include "hgscrollBufferManager.h"
+#include "hgscrollbuffermanager.h"
 #include "hggridcontainer.h"
 #include "trace.h"
 
@@ -148,13 +148,11 @@
  * Returns true if the scroll area handles
  * long press gestures, false otherwise
  *
- * \sa HbScrollArea::setHandleLongPress()
  */
 bool HgWidget::longPressEnabled() const
 {
     Q_D( const HgWidget );
-
-    return d->mHandleLongPress;
+    return d->handleLongPress();
 }
 
 /*!
@@ -163,22 +161,11 @@
  *
  * The default value is false.
  *
- * \sa HbScrollArea::handleLongPress()
  */
 void HgWidget::setLongPressEnabled (bool value)
 {
     Q_D( HgWidget );
-
-    if (d->mHandleLongPress != value)
-    {
-        d->mHandleLongPress = value;
-    }
-
-    // TODO, should we do something like this?????
-//    if (isChanged) {
-//        d->updateGestures();
-//        emit gestureSceneFilterChanged( d->mGestureFilter );
-//    }
+    d->setHandleLongPress(value);
 }
 
 HgWidget::ScrollBarPolicy HgWidget::scrollBarPolicy() const
--- a/ganeswidgets/src/hgwidgets_p.cpp	Tue Jul 06 15:29:26 2010 +0300
+++ b/ganeswidgets/src/hgwidgets_p.cpp	Wed Aug 18 10:52:49 2010 +0300
@@ -16,7 +16,8 @@
 */
 
 #include <QApplication>
-#include <hbscrollbar_p.h>
+#include <HbScrollbar>
+#include <HbTheme>
 #include <hgwidgets/hgwidgets.h>
 
 #include "hgwidgets_p.h"
@@ -82,7 +83,10 @@
     q->connect(mContainer, SIGNAL(scrollingStarted()), q, SIGNAL(scrollingStarted()));
     q->connect(mContainer, SIGNAL(scrollingEnded()), q, SIGNAL(scrollingEnded()));
     q->connect(mScrollBarHideTimer, SIGNAL(timeout()), q, SLOT(_q_hideScrollBars()));
-
+    q->connect( HbTheme::instance(), SIGNAL(changed()), q, SLOT(_q_themeChanged()));
+    
+    mContainer->setHandleLongPress(mHandleLongPress);
+    
 //    mIndexFeedback = new HgIndexFeedback(q);
 //    mIndexFeedback->setWidget(q);
 
@@ -676,27 +680,12 @@
 
 void HgWidgetPrivate::lostForeground()
 {
-    if( !mForeground ) return;
-
     mForeground = false;
-    QList<HgWidgetItem*> list = mContainer->items();
-    foreach(HgWidgetItem* item, list){
-        item->releaseItemData();
-    }
 }
 
 void HgWidgetPrivate::gainedForeground()
 {
-    if( mForeground ) return;
-
     mForeground = true;
-    QList<HgWidgetItem*> list = mContainer->items();
-    int bufferStart = 0;
-    int bufferEnd = 0;
-    mBufferManager->currentBuffer(bufferStart,bufferEnd);
-    for(;bufferStart<=bufferEnd;bufferStart++){
-        list.at(bufferStart)->updateItemData();
-    }
 }
 
 void HgWidgetPrivate::updateCurrentItem(const QModelIndex &currentItem)
@@ -719,8 +708,8 @@
 void HgWidgetPrivate::orientationChanged(Qt::Orientation orientation)
 {
     Q_Q(HgWidget);
-    if (mContainer->orientation() != orientation) {
-        mContainer->setOrientation(orientation, q->isVisible());
+    if (mContainer->orientation() != orientation) {    
+        mContainer->setOrientation(orientation, q->isVisible() && q->isActive());
         if (!mStaticScrollDirection) {
             createScrollBar(orientation);
         }
@@ -864,4 +853,28 @@
     mBufferManager->resetBuffer(0, itemCount);
 }
 
+void HgWidgetPrivate::setHandleLongPress(bool handleLongPress)
+{
+    if (mHandleLongPress != handleLongPress) {
+        mHandleLongPress = handleLongPress;
+        mContainer->setHandleLongPress(mHandleLongPress);
+    }
+}
+
+bool HgWidgetPrivate::handleLongPress() const
+{
+    return mHandleLongPress;
+}
+
+void HgWidgetPrivate::_q_themeChanged()
+{
+    handleThemeChanged();
+}
+
+void HgWidgetPrivate::handleThemeChanged()
+{
+    // TODO, add graphics updates here if required.    
+}
+
+
 #include "moc_hgwidgets.cpp"
--- a/ganeswidgets/tsrc/fute/HgWidgetTest/src/hgwidgetoptionsview.cpp	Tue Jul 06 15:29:26 2010 +0300
+++ b/ganeswidgets/tsrc/fute/HgWidgetTest/src/hgwidgetoptionsview.cpp	Wed Aug 18 10:52:49 2010 +0300
@@ -143,6 +143,8 @@
     QSettings settings(SETT_ORGANIZATION, SETT_APPLICATION);
 
     HbDataFormModelItem *item = mModel->itemFromIndex(startIn);
+    if( !item ) return;
+    
     if (item->data(HbDataFormModelItem::LabelRole).toString() == WIDGET_TYPE) {
         int index = item->contentWidgetData(QString("currentIndex")).toInt();
         HgTestWidgetType type = HgWidgetNone;
@@ -510,7 +512,7 @@
 
     if (mUpdateWidgetSize) {
         mContentReady = false;
-        HbDataFormModelItem *item = item = mModel->itemFromIndex(mModel->index(ItemWidgetHeight, 0));
+        HbDataFormModelItem *item = mModel->itemFromIndex(mModel->index(ItemWidgetHeight, 0));
         if (item) {
             item->setContentWidgetData(QString("text"), event->newSize().height());
         }
--- a/ganeswidgets/tsrc/fute/HgWidgetTest/src/hgwidgettestview.cpp	Tue Jul 06 15:29:26 2010 +0300
+++ b/ganeswidgets/tsrc/fute/HgWidgetTest/src/hgwidgettestview.cpp	Wed Aug 18 10:52:49 2010 +0300
@@ -668,12 +668,8 @@
             connect(view, SIGNAL(lowResImageUseChanged(bool)), SLOT(changeLowResImageUse(bool)));
             connect(view, SIGNAL(widgetHeightChanged(int)), SLOT(changeWidgetHeight(int)));
             connect(view, SIGNAL(widgetWidthChanged(int)), SLOT(changeWidgetWidth(int)));
-            connect(view, SIGNAL(titlePositionChanged(HgMediawall::LabelPosition)),
-                SLOT(changeTitlePosition(HgMediawall::LabelPosition)));
             connect(view, SIGNAL(titleFontChanged(HbFontSpec)),
                 SLOT(changeTitleFont(HbFontSpec)));
-            connect(view, SIGNAL(descriptionPositionChanged(HgMediawall::LabelPosition)),
-                SLOT(changeDescriptionPosition(HgMediawall::LabelPosition)));
             connect(view, SIGNAL(descriptionFontChanged(HbFontSpec)),
                 SLOT(changeDescriptionFont(HbFontSpec)));
             connect(view, SIGNAL(reflectionsEnabledChanged(bool)), 
@@ -948,20 +944,22 @@
     if (orientation == Qt::Horizontal && mWidgetType == HgWidgetCoverflow) {
         setItemVisible(Hb::AllItems, false);
     }
-    else if (orientation == Qt::Horizontal && mWidgetType == HgWidgetGrid && mainWindow()->currentView() == this ) {
+    else if (orientation == Qt::Horizontal
+                && mWidgetType == HgWidgetGrid
+                && mainWindow()->currentView() == this ) {
         setItemVisible(Hb::AllItems, false);
-    }        
+    }
     else if (orientation == Qt::Horizontal && mWidgetType == HgWidgetTBone) {
         initWidget(HgWidgetCoverflow);
         setItemVisible(Hb::AllItems, false);
-    }            
+    }
     else if (orientation == Qt::Vertical && mWidgetType == HgWidgetCoverflow) {
         initWidget(HgWidgetTBone);
         setItemVisible(Hb::AllItems, true);
     }
     else if (orientation == Qt::Vertical && mWidgetType == HgWidgetGrid) {
         setItemVisible(Hb::AllItems, true);
-    }    
+    }
 }
 void HgWidgetTestView::resizeEvent(QGraphicsSceneResizeEvent *event)
 {
--- a/hgcacheproxymodel/src/hgbuffermanager.cpp	Tue Jul 06 15:29:26 2010 +0300
+++ b/hgcacheproxymodel/src/hgbuffermanager.cpp	Wed Aug 18 10:52:49 2010 +0300
@@ -13,7 +13,7 @@
 *
 * Description:
 *
-*  Version     : %version: 6 %
+*  Version     : %version: 7 %
 */
 #include "hgbuffermanager.h"
 #include <hgwidgets/hgcacheproxymodel.h>
@@ -30,7 +30,13 @@
 mBufferSize( aBufferSize ),
 mBufferTreshold( aBufferTreshold ),
 mBufferPosition( aInitialPosition ),
-mTotalCount( aTotalCount )
+mDiff(0),
+mTotalCount( aTotalCount ),
+mResetOrdered(false),
+mRequestStart(0),
+mRequestCount(0),
+mReleaseStart(0),
+mReleaseCount(0)
 {
     ASSERT( mObserver != 0 );
     mBufferPosition -= (mBufferSize / 2);
--- a/hgcacheproxymodel/tsrc/unit/test_hgcacheproxydatamodel.cpp	Tue Jul 06 15:29:26 2010 +0300
+++ b/hgcacheproxymodel/tsrc/unit/test_hgcacheproxydatamodel.cpp	Wed Aug 18 10:52:49 2010 +0300
@@ -13,7 +13,7 @@
 *
 * Description:
 *
-*  Version     : %version: 10 %
+*  Version     : %version: 11 %
 */
 #include <QtTest/QtTest>
 #include <hgwidgets/hgcacheproxymodel.h>
@@ -1425,5 +1425,23 @@
         return QTest::qExec(&tc, c, v);
     }
 #else
-    QTEST_MAIN(TestCacheProxy)
+    int main (int argc, char* argv[]) 
+    {
+        for ( int i=0;i<argc; i++){
+            if (strcmp(argv[i], "-o")==0 && i+1 <argc ){
+                //let's make sure that folder specified after -o exists
+                QDir file( QString::fromLatin1( argv[i+1] ));
+                QString s = file.absolutePath ();
+                s = s.left( s.lastIndexOf(file.dirName()) );
+                if ( !file.exists(s) ){
+                    file.mkpath(s);
+                }
+            }
+        }
+        
+        QApplication app(argc, argv);
+        QTEST_DISABLE_KEYPAD_NAVIGATION
+        TestCacheProxy tc;
+        return QTest::qExec(&tc, argc, argv);
+    }
 #endif
--- a/hgcacheproxymodel/tsrc/unit/unittest_hgcacheproxymodel.pro	Tue Jul 06 15:29:26 2010 +0300
+++ b/hgcacheproxymodel/tsrc/unit/unittest_hgcacheproxymodel.pro	Wed Aug 18 10:52:49 2010 +0300
@@ -12,9 +12,7 @@
 TEMPLATE = app
 TARGET = unittest_hgcacheproxymodel
 
-#fix that later
-#CONFIG += symbian_test
-
+CONFIG += symbian_test
 CONFIG += hb
 INCLUDEPATH += $$MW_LAYER_SYSTEMINCLUDE $$APP_LAYER_SYSTEMINCLUDE
 
@@ -23,7 +21,7 @@
 
 TARGET.CAPABILITY = ALL -TCB
 
-DEFINES += _CACHEPROXYDATAMODEL_UNITTEST_LOG_TO_C
+#DEFINES += _CACHEPROXYDATAMODEL_UNITTEST_LOG_TO_C
 
 # Input
 LIBS +=     -lhgcacheproxymodel \
--- a/hgwidgets_plat/ganeswidgets_api/inc/hgmediawall.h	Tue Jul 06 15:29:26 2010 +0300
+++ b/hgwidgets_plat/ganeswidgets_api/inc/hgmediawall.h	Wed Aug 18 10:52:49 2010 +0300
@@ -29,7 +29,6 @@
     Q_PROPERTY(HbFontSpec descriptionFontSpec READ descriptionFontSpec WRITE setDescriptionFontSpec)
     Q_PROPERTY(QPointF frontItemPositionDelta READ frontItemPositionDelta WRITE setFrontItemPositionDelta)
     Q_PROPERTY(bool reflectionsEnabled READ reflectionsEnabled WRITE enableReflections)
-    Q_ENUMS(LabelPosition)
 
 public:
 
--- a/hgwidgets_plat/ganeswidgets_api/inc/hgwidgets.h	Tue Jul 06 15:29:26 2010 +0300
+++ b/hgwidgets_plat/ganeswidgets_api/inc/hgwidgets.h	Wed Aug 18 10:52:49 2010 +0300
@@ -165,6 +165,7 @@
     Q_PRIVATE_SLOT(d_func(), void _q_groovePressed(qreal, Qt::Orientation))
     Q_PRIVATE_SLOT(d_func(), void _q_modelReset())
     Q_PRIVATE_SLOT(d_func(), void _q_updateCurrentItem(const QModelIndex &current, const QModelIndex &previous))
+    Q_PRIVATE_SLOT(d_func(), void _q_themeChanged())
 };
 
 #endif  //HGWIDGET_H
--- a/layers.sysdef.xml	Tue Jul 06 15:29:26 2010 +0300
+++ b/layers.sysdef.xml	Wed Aug 18 10:52:49 2010 +0300
@@ -16,7 +16,8 @@
     </layer>
 
     <layer name="unit_test_layer">
-      <module name="hgwidgets_unit_tests">
+      <module name="hgcacheproxy_unit_test">
+        <unit unitID="imm.hgwidgets.hgcacheproxy_unit_test" name="hgcacheproxy_unit_test" bldFile="&layer_real_source_path;/hgcacheproxymodel/tsrc/unit/" proFile="unittest_hgcacheproxymodel.pro" mrp="" />
       </module>
     </layer>