src/hbwidgets/itemviews/hbdatepickerview_p.cpp
changeset 21 4633027730f5
child 23 e6ad4ef83b23
equal deleted inserted replaced
7:923ff622b8b9 21:4633027730f5
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (developer.feedback@nokia.com)
       
     6 **
       
     7 ** This file is part of the HbWidgets module of the UI Extensions for Mobile.
       
     8 **
       
     9 ** GNU Lesser General Public License Usage
       
    10 ** This file may be used under the terms of the GNU Lesser General Public
       
    11 ** License version 2.1 as published by the Free Software Foundation and
       
    12 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
       
    13 ** Please review the following information to ensure the GNU Lesser General
       
    14 ** Public License version 2.1 requirements will be met:
       
    15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    16 **
       
    17 ** In addition, as a special exception, Nokia gives you certain additional
       
    18 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    20 **
       
    21 ** If you have questions regarding the use of this file, please contact
       
    22 ** Nokia at developer.feedback@nokia.com.
       
    23 **
       
    24 ****************************************************************************/
       
    25 #include "hbdatepickerview_p.h"
       
    26 #include "hbabstractitemview_p.h"
       
    27 #include "hbabstractitemcontainer_p.h"
       
    28 #include "hbabstractitemcontainer_p_p.h"
       
    29 #include "hblistlayout_p.h"
       
    30 #include "hbstyleoption_p.h"
       
    31 
       
    32 #include <hbmodeliterator.h>
       
    33 #include <hbdatepickerviewitem_p.h>
       
    34 #include <hbtapgesture.h>
       
    35 
       
    36 #include <qmath.h>
       
    37 #include <QTimeLine>
       
    38 #include <QGraphicsItemAnimation>
       
    39 #include <QGestureEvent>
       
    40 #include <QGesture>
       
    41 #include <QStringListModel>
       
    42 #include <QCoreApplication>
       
    43 
       
    44 #define HB_DATEPICKERVIEW_PREFERRED_ITEMS 3
       
    45 
       
    46 class HbDatePickerViewPrivate : public HbAbstractItemViewPrivate
       
    47 {
       
    48 public:
       
    49     HbDatePickerViewPrivate();
       
    50     ~HbDatePickerViewPrivate();
       
    51 
       
    52     void _q_scrollingStarted();
       
    53     void _q_scrollingEnded();
       
    54     void _q_itemSelected(QPointF point);
       
    55 
       
    56     void createPrimitives();
       
    57     void updateScrollMetrics(){ mAbleToScrollY = true; }
       
    58 
       
    59     qreal topBoundary();
       
    60     qreal bottomBoundary();
       
    61 
       
    62     HbAbstractViewItem* getCenterItem();
       
    63     void slectItemAt(const QPointF& point,QGraphicsItem* itemToMap);
       
    64 
       
    65 
       
    66     QTimeLine *animationtimer;
       
    67     QGraphicsItemAnimation *animation;
       
    68     Q_DECLARE_PUBLIC(HbDatePickerView);
       
    69     QGraphicsItem   *mBackground;
       
    70     QGraphicsItem   *mFrame;//overlay
       
    71     QGraphicsItem   *mHighlight;
       
    72     QGraphicsItem   *mDivider;
       
    73    // bool tapActive;
       
    74 
       
    75     enum ViewState
       
    76     {
       
    77         NoState = 0,
       
    78         TapStarted = 1,
       
    79         ScrollStarted = 2
       
    80     };
       
    81     Q_DECLARE_FLAGS(ViewStates, ViewState);
       
    82     ViewStates viewStates;
       
    83 
       
    84 };
       
    85 class HbDatePickerContainerPrivate;
       
    86 
       
    87 
       
    88 class HbDatePickerContainer:public HbAbstractItemContainer
       
    89 {
       
    90 public:
       
    91     HbDatePickerContainer(QGraphicsItem* parent = 0);
       
    92 
       
    93     void setModelIndexes(const QModelIndex &startIndex = QModelIndex());
       
    94     void resizeContainer();
       
    95     void itemAdded(int index, HbAbstractViewItem *item, bool animate);
       
    96     void itemRemoved(HbAbstractViewItem *item, bool animate);
       
    97 
       
    98     bool isLoopingEnabled(){return true;}
       
    99     bool isLoopingNeeded();
       
   100     int maxItemPossible()const;
       
   101 
       
   102 protected:
       
   103     QPointF recycleItems(const QPointF &delta);
       
   104     int maxItemCount() const;
       
   105     HbAbstractViewItem *createDefaultPrototype() const;
       
   106     void viewResized(const QSizeF &size);
       
   107 
       
   108 private:
       
   109     Q_DECLARE_PRIVATE(HbDatePickerContainer);
       
   110     friend class HbDatePickerView;
       
   111     friend class HbDatePickerViewPrivate;
       
   112 };
       
   113 
       
   114 class HbDatePickerContainerPrivate:public HbAbstractItemContainerPrivate
       
   115 {
       
   116 public:
       
   117     HbDatePickerContainerPrivate();
       
   118     HbAbstractViewItem *shiftDownItem(QPointF& delta);
       
   119     HbAbstractViewItem *shiftUpItem(QPointF& delta);
       
   120     qreal getSmallestItemHeight() const;
       
   121     void init();
       
   122     HbAbstractViewItem *item(const QModelIndex &index) const;
       
   123 
       
   124     HbListLayout *mLayout;
       
   125     Q_DECLARE_PUBLIC(HbDatePickerContainer);
       
   126 };
       
   127 
       
   128 HbDatePickerContainerPrivate::HbDatePickerContainerPrivate()
       
   129     :mLayout(0)
       
   130 {
       
   131 
       
   132 }
       
   133 
       
   134 
       
   135 void HbDatePickerContainerPrivate::init()
       
   136 {
       
   137     Q_Q(HbDatePickerContainer);
       
   138     mLayout = new HbListLayout();
       
   139     mLayout->setContentsMargins(0, 0, 0, 0);
       
   140     //mLayout->setPreferredWidth(q->size().width());
       
   141 
       
   142     q->setLayout(mLayout);
       
   143 }
       
   144 
       
   145 bool HbDatePickerContainer::isLoopingNeeded()
       
   146 {
       
   147     Q_D(HbDatePickerContainer);
       
   148     return (isLoopingEnabled() && !(d->mItems.count() < maxItemPossible()));
       
   149 }
       
   150 
       
   151 void HbDatePickerContainer::setModelIndexes(const QModelIndex &startIndex)
       
   152 {
       
   153     Q_D(HbDatePickerContainer);
       
   154 
       
   155     if (!d->mItemView || !d->mItemView->model()) {
       
   156         return;
       
   157     }
       
   158 
       
   159     QModelIndex index = startIndex;
       
   160     if (!index.isValid()) {
       
   161         if (!d->mItems.isEmpty()) {
       
   162             index = d->mItems.first()->modelIndex();
       
   163         }
       
   164 
       
   165         if (!index.isValid()) {
       
   166             index = d->mItemView->modelIterator()->nextIndex(index);
       
   167         }
       
   168     }
       
   169 
       
   170     QModelIndexList indexList;
       
   171 
       
   172     int itemCount(d->mItems.count());
       
   173 
       
   174     if (itemCount != 0 && index.isValid()) {
       
   175         indexList.append(index);
       
   176     }
       
   177 
       
   178     for (int i = indexList.count(); i < itemCount; ++i) {
       
   179         index = d->mItemView->modelIterator()->nextIndex(indexList.last());
       
   180 
       
   181         if (index.isValid()) {
       
   182             indexList.append(index);
       
   183         } else {
       
   184             break;
       
   185         }
       
   186     }
       
   187     if(isLoopingEnabled() && indexList.count()<itemCount){
       
   188         QModelIndex firstModelIndex =  d->mItemView->modelIterator()->index(0,QModelIndex());
       
   189         indexList.append(firstModelIndex);
       
   190         for (int i = indexList.count(); i < itemCount; ++i) {
       
   191             index = d->mItemView->modelIterator()->nextIndex(indexList.last());
       
   192 
       
   193             if (index.isValid()) {
       
   194                 indexList.append(index);
       
   195             } else {
       
   196                 break;
       
   197             }
       
   198         }
       
   199     }
       
   200 
       
   201     int indexCount(indexList.count());
       
   202     for (int i = 0; i < itemCount; ++i) {
       
   203         HbAbstractViewItem *item = d->mItems.at(i);
       
   204         HbAbstractViewItem *prototype = 0;
       
   205         // setItemModelIndex() is considered recycling. It is called only, if recycling is permitted
       
   206         if (i < indexCount) {
       
   207             prototype = d->itemPrototype(indexList.at(i));
       
   208         }
       
   209         if (prototype) {
       
   210             if (    prototype == item->prototype()
       
   211                 &&  d->mItemRecycling) {
       
   212                 setItemModelIndex(item, indexList.at(i));
       
   213             } else if (     d->mItemRecycling
       
   214                        ||   (   !d->mItemRecycling
       
   215                             &&  item->modelIndex() != indexList.at(i))) {
       
   216                 d->deleteItem(item);
       
   217                 insertItem(i, indexList.at(i));
       
   218             } // else: !d->mItemRecycling && item->modelIndex().isValid() == indexList.at(i))
       
   219         } else {
       
   220             d->deleteItem(item);
       
   221             itemCount--;
       
   222             i--;
       
   223         }
       
   224     }
       
   225 }
       
   226 
       
   227 void HbDatePickerContainer::resizeContainer()
       
   228 {
       
   229     Q_D(HbAbstractItemContainer);
       
   230 
       
   231     if (d->mItemView) {
       
   232         resize(d->mItemView->size().width(), layout()->preferredHeight());
       
   233     } else {
       
   234         resize(0, layout()->preferredHeight());
       
   235     }
       
   236 }
       
   237 
       
   238 void HbDatePickerContainer::itemAdded(int index, HbAbstractViewItem *item, bool animate)
       
   239 {
       
   240     Q_D(HbDatePickerContainer);
       
   241     d->mLayout->insertItem(index,item, animate);
       
   242 }
       
   243 
       
   244 void HbDatePickerContainer::itemRemoved(HbAbstractViewItem *item, bool animate)
       
   245 {
       
   246     Q_D(HbDatePickerContainer);
       
   247     d->mLayout->removeItem(item, animate);
       
   248 }
       
   249 
       
   250 void HbDatePickerContainer::viewResized(const QSizeF &viewSize)
       
   251 {
       
   252     QSizeF newSize = this->size();
       
   253     newSize.setWidth( viewSize.width() );
       
   254     resize( newSize );
       
   255 }
       
   256 
       
   257 QPointF HbDatePickerContainer::recycleItems(const QPointF &delta)
       
   258 {
       
   259     Q_D(HbDatePickerContainer);
       
   260 
       
   261     if( itemView()->size().height() < size().height()){
       
   262           const qreal diff = d->getDiffWithoutScrollareaCompensation(delta);
       
   263           if(diff !=0.0){
       
   264                 QPointF newDelta(0.0, 0.0);
       
   265                 qreal result = 0.0;
       
   266             HbAbstractViewItem *item = 0;
       
   267             if (diff < 0.0) {
       
   268                 while (-newDelta.y() > diff) {
       
   269                     item = d->shiftUpItem(newDelta);
       
   270                     if (!item) {
       
   271                         break;
       
   272                     }
       
   273                 }
       
   274             }
       
   275             else {
       
   276                 while (-newDelta.y() < diff) {
       
   277                     item = d->shiftDownItem(newDelta);
       
   278                     if (!item) {
       
   279                         break;
       
   280                     }
       
   281                 }
       
   282             }
       
   283                 result = newDelta.y();
       
   284                 return QPointF(delta.x(),delta.y()+result);
       
   285 
       
   286           }
       
   287       }
       
   288       return delta;
       
   289 
       
   290 }
       
   291 
       
   292 HbAbstractViewItem *HbDatePickerContainerPrivate::item(const QModelIndex &index) const
       
   293 {
       
   294     int itemCount = mItems.count();
       
   295     for(int i=0;i<itemCount;++i) {
       
   296         if(mItems.at(i)->modelIndex() == index) {
       
   297             return mItems.at(i);
       
   298         }
       
   299     }
       
   300     return 0;
       
   301 }
       
   302 HbAbstractViewItem *HbDatePickerContainerPrivate::shiftDownItem(QPointF& delta)
       
   303 {
       
   304     Q_Q(HbDatePickerContainer);
       
   305 
       
   306     HbAbstractViewItem *item = 0;
       
   307     HbAbstractViewItem *lastItem = mItems.last();
       
   308 
       
   309     QModelIndex nextIndex = mItemView->modelIterator()->nextIndex(lastItem->modelIndex());
       
   310     if(q->isLoopingEnabled() && (!nextIndex.isValid())){
       
   311        nextIndex = mItemView->model()->index(0,0);
       
   312     }
       
   313     if (nextIndex.isValid()) {
       
   314         item = mItems.takeFirst();
       
   315 
       
   316         q->itemRemoved(item,false);
       
   317 
       
   318         delta.setY(delta.y() - item->size().height());
       
   319 
       
   320         mItems.append(item);
       
   321 
       
   322         q->setItemModelIndex(item, nextIndex);
       
   323 
       
   324         q->itemAdded(mItems.count() - 1, item,false);
       
   325     }
       
   326     mBufferSize=4;
       
   327     return item;
       
   328 }
       
   329 
       
   330 HbAbstractViewItem *HbDatePickerContainerPrivate::shiftUpItem(QPointF& delta)
       
   331 {
       
   332     Q_Q(HbDatePickerContainer);
       
   333 
       
   334     HbAbstractViewItem *item = 0;
       
   335     HbAbstractViewItem *firstItem = mItems.first();
       
   336 
       
   337     QModelIndex previousIndex = mItemView->modelIterator()->previousIndex(firstItem->modelIndex());
       
   338     if(q->isLoopingEnabled() && !previousIndex.isValid()){
       
   339         previousIndex = mItemView->model()->index(mItemView->model()->rowCount()-1,0);
       
   340     }
       
   341     if (previousIndex.isValid()) {
       
   342         item = mItems.takeLast();
       
   343 
       
   344         q->itemRemoved(item,false);
       
   345 
       
   346         mItems.insert(0, item);
       
   347 
       
   348         q->setItemModelIndex(item, previousIndex);
       
   349 
       
   350         qreal itemHeight=0;
       
   351         if (q->uniformItemSizes()) {
       
   352             itemHeight = mItems.last()->preferredHeight();
       
   353         } else {
       
   354             //This is time consuming and causes backwards srolling to be slower than forwards.
       
   355             //The sizehint of the item is dirty.
       
   356             itemHeight = item->preferredHeight();
       
   357         }
       
   358 
       
   359         delta.setY(delta.y() + itemHeight);
       
   360 
       
   361         q->itemAdded(0, item,false);
       
   362     }
       
   363     return item;
       
   364 }
       
   365 qreal HbDatePickerContainerPrivate::getSmallestItemHeight() const
       
   366 {
       
   367     Q_Q(const HbDatePickerContainer);
       
   368     qreal minHeight = 0.0;
       
   369     if (mItems.count() > 0) {
       
   370         minHeight = mLayout->smallestItemHeight();
       
   371     }
       
   372     if (minHeight == 0.0) {
       
   373         QModelIndex index;
       
   374         while (mItems.isEmpty()) {
       
   375             // in practise following conditions must apply: itemview is empty and scrollTo() has been called.
       
   376             // Starts populating items from given mFirstItemIndex
       
   377             if ( mFirstItemIndex.isValid()) {
       
   378                 index = mFirstItemIndex;
       
   379                 const_cast<QPersistentModelIndex&>(mFirstItemIndex) = QModelIndex();
       
   380             } else {
       
   381                 index = mItemView->modelIterator()->nextIndex(index);
       
   382             }
       
   383             if (!index.isValid()) {
       
   384                 break;
       
   385             }
       
   386             const_cast<HbDatePickerContainer *>(q)->insertItem(0, index);
       
   387         }
       
   388 
       
   389         if (!mItems.isEmpty()) {
       
   390             minHeight = mItems.first()->preferredHeight();
       
   391         }
       
   392     }
       
   393     return minHeight;
       
   394 }
       
   395 int HbDatePickerContainer::maxItemPossible()const
       
   396 {
       
   397     Q_D(const HbDatePickerContainer);
       
   398     qreal minHeight = d->getSmallestItemHeight();
       
   399     if (minHeight > 0) {
       
   400         int countEstimate = qCeil(d->mItemView->boundingRect().height() / minHeight)
       
   401             + d->mBufferSize;
       
   402         return countEstimate;
       
   403     }
       
   404     return 0;
       
   405 }
       
   406 int HbDatePickerContainer::maxItemCount() const
       
   407 {
       
   408     Q_D(const HbDatePickerContainer);
       
   409     int targetCount = HbAbstractItemContainer::maxItemCount();
       
   410     if (targetCount > 0
       
   411         && d->mItemRecycling
       
   412         && d->mPrototypes.count() <= 1) {
       
   413 
       
   414         qreal minHeight = d->getSmallestItemHeight();
       
   415 
       
   416         if (minHeight > 0) {
       
   417             int countEstimate = qCeil(d->mItemView->boundingRect().height() / minHeight)
       
   418                 + d->mBufferSize;
       
   419 
       
   420             // This limits the targetCount not to be larger
       
   421             // than row count inside model.
       
   422             targetCount = qMin(targetCount, countEstimate);
       
   423         } else {
       
   424             targetCount = 0;
       
   425         }
       
   426     }
       
   427     return targetCount;
       
   428 }
       
   429 HbAbstractViewItem *HbDatePickerContainer::createDefaultPrototype()const
       
   430 {
       
   431     return new HbDatePickerViewItem();
       
   432 }
       
   433 
       
   434 HbDatePickerContainer::HbDatePickerContainer(QGraphicsItem* parent)
       
   435     :HbAbstractItemContainer(*(new HbDatePickerContainerPrivate),parent )
       
   436 {
       
   437     Q_D(HbDatePickerContainer);
       
   438     d->init();
       
   439 }
       
   440 
       
   441 HbDatePickerViewPrivate::HbDatePickerViewPrivate()
       
   442     :animationtimer(0),animation(0),
       
   443     mBackground(0),mFrame(0),mHighlight(0),mDivider(0),
       
   444     viewStates(NoState)
       
   445 {
       
   446 
       
   447 }
       
   448 HbDatePickerViewPrivate::~HbDatePickerViewPrivate()
       
   449 {
       
   450     if(animationtimer){
       
   451         if(animationtimer->state() != QTimeLine::NotRunning) {
       
   452             animationtimer->stop();
       
   453         }
       
   454         delete animationtimer;
       
   455         delete animation;
       
   456     }
       
   457 }
       
   458 
       
   459 
       
   460 HbDatePickerView::HbDatePickerView(QGraphicsItem *parent)
       
   461     :HbAbstractItemView(*(new HbDatePickerViewPrivate),new HbDatePickerContainer,new HbModelIterator(),parent)
       
   462 {
       
   463     Q_D(HbDatePickerView);
       
   464     d->mAbleToScrollY = true;
       
   465     setSelectionMode(HbAbstractItemView::SingleSelection);
       
   466     setLongPressEnabled(false);
       
   467     setUniformItemSizes(true);
       
   468     setEnabledAnimations(HbAbstractItemView::TouchDown);
       
   469     setItemRecycling(true);
       
   470     //scroll area settings
       
   471     setClampingStyle(HbScrollArea::BounceBackClamping);
       
   472     setVerticalScrollBarPolicy(HbScrollArea::ScrollBarAlwaysOff);
       
   473     setHorizontalScrollBarPolicy(HbScrollArea::ScrollBarAlwaysOff);
       
   474     setFrictionEnabled(true);
       
   475 
       
   476     //dont want this to occupy entire screen. preferred is few items.
       
   477     setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred);
       
   478 
       
   479 
       
   480     bool b = connect(this,SIGNAL(scrollingStarted()),this,SLOT(_q_scrollingStarted()));
       
   481     Q_ASSERT(b);
       
   482     b = connect(this,SIGNAL(scrollingEnded()),this,SLOT(_q_scrollingEnded()));
       
   483     Q_ASSERT(b);
       
   484     d->createPrimitives();
       
   485     updatePrimitives();
       
   486     setModel(new QStringListModel());
       
   487 
       
   488 }
       
   489 
       
   490 HbDatePickerView::~HbDatePickerView()
       
   491 {
       
   492 
       
   493 }
       
   494 
       
   495 void HbDatePickerView::rowsRemoved(const QModelIndex &parent, int start, int end)
       
   496 {
       
   497     Q_D(HbDatePickerView);
       
   498 
       
   499     HbAbstractItemView::rowsRemoved(parent,start,end);
       
   500     HbDatePickerContainer* container = static_cast<HbDatePickerContainer*>(d->mContainer);
       
   501 
       
   502     container->d_func()->updateItemBuffer();
       
   503     //d->mContainer->layout()->activate();
       
   504 
       
   505     d->mPostponedScrollIndex = currentIndex();
       
   506     d->mPostponedScrollHint = PositionAtCenter;
       
   507     QCoreApplication::postEvent(this, new QEvent(QEvent::LayoutRequest));
       
   508 }
       
   509 void HbDatePickerView::rowsAboutToBeInserted(const QModelIndex &index, int start, int end)
       
   510 {
       
   511     Q_D(HbDatePickerView);
       
   512     QPointF containerPos =  d->mContainer->pos();
       
   513     if(containerPos.y()>0){
       
   514         containerPos.setY(0);
       
   515         d->mContainer->setPos(containerPos);
       
   516     }
       
   517     HbAbstractItemView::rowsAboutToBeInserted(index,start,end);
       
   518 }
       
   519 
       
   520 void HbDatePickerView::rowsInserted(const QModelIndex &parent, int start, int end)
       
   521 {
       
   522     Q_D(HbDatePickerView);
       
   523     HbAbstractItemView::rowsInserted(parent,start,end);
       
   524     //d->mContainer->layout()->activate();
       
   525    // scrollTo(currentIndex(),PositionAtCenter);
       
   526     d->mPostponedScrollIndex = currentIndex();
       
   527     d->mPostponedScrollHint = PositionAtCenter;
       
   528 }
       
   529 
       
   530 void HbDatePickerView::scrollTo(const QModelIndex &index, ScrollHint hint)
       
   531 {
       
   532     Q_D(HbDatePickerView);
       
   533     hint = PositionAtCenter;
       
   534     if (!d->mModelIterator->model()
       
   535         ||  index.model() != d->mModelIterator->model()) {
       
   536         return;
       
   537     }
       
   538     //If item is in the buffer, just reveal it.
       
   539     //This is always the case if recycling is off
       
   540     //and sometimes the case when recycling is on
       
   541     if (itemRecycling()) {
       
   542         if (    !d->mContainer->itemByIndex(index)
       
   543             ||  hint != EnsureVisible) {
       
   544             //Now the item is not in the buffer.
       
   545             //We must first set the item to be in the buffer
       
   546             //If the item is above let's put it first and if it is below put it last
       
   547             int newIndex = -1;
       
   548             switch (hint) {
       
   549             case PositionAtCenter: {
       
   550                     int containerCount = d->mContainer->items().count();
       
   551                     newIndex = index.row() - containerCount / 2 ;
       
   552                     if(newIndex < 0){
       
   553                         if(((HbDatePickerContainer*)(d->mContainer))->isLoopingNeeded()){
       
   554                             newIndex = d->mModelIterator->indexCount()+newIndex;
       
   555                         }
       
   556                         else{
       
   557                             newIndex = 0;
       
   558                         }
       
   559                     }
       
   560                     break;
       
   561                 }
       
   562             case EnsureVisible:
       
   563             case PositionAtTop:
       
   564             case PositionAtBottom:
       
   565             default: {
       
   566                      }
       
   567             }
       
   568             d->mContainer->setModelIndexes(d->mModelIterator->index(newIndex));
       
   569         }
       
   570     }
       
   571     //HbAbstractItemView::scrollTo(index, hint);
       
   572     if (    index.isValid()
       
   573         &&  d->mModelIterator->model() == index.model()) {
       
   574         d->mPostponedScrollIndex = QPersistentModelIndex();
       
   575         d->scrollTo(index, hint);
       
   576         d->mPostponedScrollIndex = index;
       
   577         d->mPostponedScrollHint = hint;
       
   578         if (    d->mContainer->itemRecycling()
       
   579             &&  !d->mContainer->items().count()) {
       
   580             // settings index from which loading viewitems start when itemview is
       
   581             // empty or reset by setModel()
       
   582             ((HbDatePickerContainer*)d->mContainer)->d_func()->mFirstItemIndex = index;
       
   583         }
       
   584        // QCoreApplication::postEvent(this, new QEvent(QEvent::LayoutRequest));
       
   585     }
       
   586 }
       
   587 
       
   588 void HbDatePickerViewPrivate::_q_scrollingStarted()
       
   589 {
       
   590     viewStates |= ScrollStarted;
       
   591 }
       
   592 
       
   593 void HbDatePickerViewPrivate::slectItemAt(const QPointF& point,QGraphicsItem* itemTomap)
       
   594 {
       
   595     Q_Q(HbDatePickerView);
       
   596     QPointF mappedPoint = itemTomap->mapToScene(point);
       
   597     HbDatePickerContainer* container = static_cast<HbDatePickerContainer*>(mContainer);
       
   598     HbDatePickerContainerPrivate* containerPriv = container->d_func();
       
   599     
       
   600     HbAbstractViewItem* item = qobject_cast<HbAbstractViewItem*>(itemAt(mappedPoint)); //(q->sender());    
       
   601     if(item){
       
   602         QPointF centerPt = q->mapToScene(q->boundingRect().center());
       
   603         qreal itemHeight = containerPriv->getSmallestItemHeight();
       
   604         centerPt.setY(centerPt.y()- itemHeight/2);
       
   605         QPointF itemPos = q->mapToScene(containerPriv->itemBoundingRect(item).topLeft());
       
   606         QPointF delta = itemPos-centerPt;
       
   607 
       
   608         if(qCeil(delta.y())!=0){
       
   609             QPointF contPos = container->pos();
       
   610             QPointF newPos =  contPos-QPointF(0,qCeil(delta.y()));
       
   611             //need to remove already posted request to avoid multiple scrolling
       
   612             QCoreApplication::removePostedEvents(q,QEvent::LayoutRequest);
       
   613           q->scrollContentsTo(-newPos,200);
       
   614         }
       
   615         else {
       
   616             q->setCurrentIndex(item->modelIndex());
       
   617             emit q->itemSelected(item->modelIndex().row());
       
   618         }
       
   619 
       
   620     }
       
   621 
       
   622 }
       
   623 
       
   624 void HbDatePickerViewPrivate::_q_scrollingEnded()
       
   625 {
       
   626     if(mOptions & PanningActive){
       
   627         return;
       
   628     }
       
   629     if(viewStates.testFlag(TapStarted)){
       
   630         viewStates &= ~TapStarted;
       
   631         return;
       
   632     }
       
   633     Q_Q(HbDatePickerView);
       
   634 	mContainer->layout()->activate();//call this to get proper item;
       
   635     slectItemAt(q->boundingRect().center(),q);
       
   636 }
       
   637 
       
   638 void HbDatePickerViewPrivate::_q_itemSelected(QPointF point)
       
   639 {
       
   640     Q_Q(HbDatePickerView);
       
   641     if(!mIsScrolling && !mIsAnimating){
       
   642         slectItemAt(point,qobject_cast<HbAbstractViewItem*>(q->sender()));
       
   643     }
       
   644 
       
   645 }
       
   646 
       
   647 HbAbstractViewItem* HbDatePickerViewPrivate::getCenterItem()
       
   648 {
       
   649     Q_Q(HbDatePickerView);
       
   650 
       
   651     if(!q->scene()) {
       
   652         return 0;
       
   653     }
       
   654     QPointF centerPt = q->mapToScene(q->boundingRect().center());
       
   655     return itemAt(centerPt);
       
   656 }
       
   657 qreal HbDatePickerViewPrivate::topBoundary()
       
   658 {
       
   659     //top boundary and bottom boundary is different for tumble view
       
   660     //it is half item less than the middle of the view
       
   661     Q_Q( HbDatePickerView );
       
   662     qreal itemheight = (static_cast<HbDatePickerContainer*>(mContainer))->d_func()->getSmallestItemHeight();
       
   663     return (-(q->boundingRect().height()-itemheight)/2);
       
   664 }
       
   665 
       
   666 qreal HbDatePickerViewPrivate::bottomBoundary()
       
   667 {
       
   668     Q_Q ( HbDatePickerView);
       
   669     qreal itemheight = (static_cast<HbDatePickerContainer*>(mContainer))->d_func()->getSmallestItemHeight();   
       
   670     return mContents->boundingRect().height()-((q->boundingRect().height()+itemheight)/2);   
       
   671 }
       
   672 
       
   673 QSizeF HbDatePickerView::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
       
   674 {
       
   675     Q_UNUSED(constraint);
       
   676     Q_D(const HbDatePickerView);
       
   677     QSizeF sh=HbAbstractItemView::sizeHint(which,constraint);
       
   678     qreal mheight =(static_cast<HbDatePickerContainer*>(d->mContainer))->d_func()->getSmallestItemHeight();
       
   679     switch(which) {
       
   680         case Qt::MinimumSize:
       
   681             sh = QSizeF(sh.width(),HB_DATEPICKERVIEW_PREFERRED_ITEMS*mheight);
       
   682             break;
       
   683         case Qt::PreferredSize:
       
   684             sh = QSizeF(sh.width(),HB_DATEPICKERVIEW_PREFERRED_ITEMS*mheight);
       
   685             sh.setWidth(HbWidget::sizeHint(which, constraint).width());
       
   686             break;
       
   687         case Qt::MaximumSize:
       
   688             break;
       
   689         default:
       
   690             qWarning("HbTumbleView::sizeHint(): unknown 'which'");
       
   691             break;
       
   692     }
       
   693     return sh;
       
   694 }
       
   695 void HbDatePickerView::setSelected(int row)
       
   696 {
       
   697     Q_D(HbDatePickerView);
       
   698     if(model()){
       
   699         setCurrentIndex(model()->index(row,0));
       
   700         d->viewStates &= ~HbDatePickerViewPrivate::ScrollStarted;
       
   701         scrollTo(model()->index(row,0),PositionAtCenter);
       
   702         //scrolling will not be started all the time so we need to emit signal
       
   703         //here in those cases.
       
   704         if(!d->viewStates.testFlag(HbDatePickerViewPrivate::ScrollStarted)){
       
   705             emit itemSelected(row);
       
   706         }
       
   707     }
       
   708 }
       
   709 
       
   710 int HbDatePickerView::selected() const
       
   711 {
       
   712     return currentIndex().row();
       
   713 }
       
   714 
       
   715 void HbDatePickerView::setLoopingEnabled(bool looping)
       
   716 {
       
   717     Q_UNUSED(looping)
       
   718 }
       
   719 bool HbDatePickerView::isLoopinEnabled()const
       
   720 {
       
   721     return true;
       
   722 }
       
   723 void HbDatePickerViewPrivate::createPrimitives()
       
   724 {
       
   725     Q_Q(HbDatePickerView);
       
   726 
       
   727     //this is the highlight which is placed at center
       
   728     if(!mHighlight) {
       
   729         mHighlight = HbStylePrivate::createPrimitive(HbStylePrivate::P_TumbleView_highlight,q);
       
   730         HbStyle::setItemName(mHighlight,"highlight");
       
   731     }
       
   732     if(!mDivider){
       
   733         mDivider = HbStylePrivate::createPrimitive(HbStylePrivate::P_DateTimePicker_separator,q);
       
   734         HbStyle::setItemName(mDivider,"separator");
       
   735         mDivider->hide();
       
   736     }
       
   737 
       
   738 }
       
   739 void HbDatePickerView::updatePrimitives()
       
   740 {
       
   741     Q_D(HbDatePickerView);
       
   742 
       
   743     HbStyleOption opt;
       
   744     initStyleOption(&opt);
       
   745 
       
   746     if(d->mBackground) {
       
   747         HbStylePrivate::updatePrimitive(d->mBackground,HbStylePrivate::P_TumbleView_background,&opt);
       
   748     }
       
   749     if(d->mFrame) {
       
   750         HbStylePrivate::updatePrimitive(d->mFrame,HbStylePrivate::P_TumbleView_frame,&opt);
       
   751     } 
       
   752     if(d->mHighlight) {
       
   753         HbStylePrivate::updatePrimitive(d->mHighlight,HbStylePrivate::P_TumbleView_highlight,&opt);
       
   754     }
       
   755     if(d->mDivider){
       
   756         HbStylePrivate::updatePrimitive(d->mDivider, HbStylePrivate::P_DateTimePicker_separator, &opt);
       
   757     }
       
   758     HbAbstractItemView::updatePrimitives();
       
   759 
       
   760 }
       
   761 
       
   762 
       
   763 void HbDatePickerView::gestureEvent(QGestureEvent *event)
       
   764 {
       
   765     Q_D(HbDatePickerView);
       
   766     if(QTapGesture *gesture = static_cast<QTapGesture*>(event->gesture(Qt::TapGesture))){
       
   767         switch(gesture->state()){
       
   768             case Qt::GestureStarted:
       
   769             d->viewStates |= HbDatePickerViewPrivate::TapStarted;
       
   770                 break;
       
   771             case Qt::GestureCanceled:
       
   772 
       
   773                 break;
       
   774             case Qt::GestureFinished:
       
   775                 d->slectItemAt(boundingRect().center(),this);
       
   776                 break;
       
   777             default:
       
   778                 break;
       
   779 
       
   780         }
       
   781     }
       
   782     HbAbstractItemView::gestureEvent(event);
       
   783 }
       
   784 
       
   785 void HbDatePickerView::currentIndexChanged(const QModelIndex &current, const QModelIndex &previous)
       
   786 {
       
   787     HbAbstractItemView::currentIndexChanged(current,previous);
       
   788 }
       
   789 
       
   790 void HbDatePickerView::orientationAboutToBeChanged()
       
   791 {
       
   792     Q_D(HbDatePickerView);
       
   793     d->mVisibleIndex = currentIndex();
       
   794 }
       
   795 
       
   796 
       
   797 #include "moc_hbdatepickerview_p.cpp"