src/hbwidgets/itemviews/hbabstractviewitem.cpp
changeset 0 16d8024aca5e
child 1 f7ac710697a9
equal deleted inserted replaced
-1:000000000000 0:16d8024aca5e
       
     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 
       
    26 #include "hbabstractviewitem_p.h"
       
    27 
       
    28 #include <hbabstractviewitem.h>
       
    29 #include <hbabstractitemview.h>
       
    30 #include <hbnamespace.h>
       
    31 #include <hbstyleoptionabstractviewitem.h>
       
    32 #include <hbstyle.h>
       
    33 #include <hbiconitem.h>
       
    34 #include <hbframebackground.h>
       
    35 #include <hbtextitem.h>
       
    36 
       
    37 #include <QPersistentModelIndex>
       
    38 #include <QGraphicsSceneMouseEvent>
       
    39 #include <QGraphicsLinearLayout>
       
    40 #include <QVariant>
       
    41 #include <QCoreApplication>
       
    42 #include <QEvent>
       
    43 #include <QDebug>
       
    44 
       
    45 const QString KDefaultLayoutOption = "default";
       
    46 const int HbAbstractViewItemShared::ViewItemDeferredDeleteEvent = QEvent::registerEventType();
       
    47 
       
    48 /*!
       
    49     @alpha
       
    50     @hbwidgets
       
    51     \class HbAbstractViewItem
       
    52     \brief The HbAbstractViewItem class represents a single item in a AbstractItemView.  
       
    53 
       
    54     The HbAbstractViewItem class provides an item that is used by HbAbstractItemView class to
       
    55     visualize content within single model index. By default HbAbstractViewItem supports QString
       
    56     that is stored into Qt::DisplayRole role and QIcon or HbIcon that is stored into
       
    57     Qt::DecoratorRole role within the index. 
       
    58 
       
    59     This class is provided mainly for customization purposes but it also acts as a default
       
    60     item prototype inside HbAbstractItemView. See HbAbstractItemView how to set customized class as a item prototype.
       
    61 
       
    62     \b Subclassing
       
    63 
       
    64     When subclassing HbAbstractViewItem, childclass must provide implementations of createItem() and updateChildItems() functions.
       
    65     
       
    66     To support multiple Abstractview items within single AbstractItemview, you must also provide an implementation of canSetModelIndex().
       
    67 
       
    68     If derived abstract view item has transient state information that is not meaningful to store within model index (child item cursor 
       
    69     position selection areas etc.) view item can use abstract views internal state model to store this information. This feature can
       
    70     be taken into use by implementing state() and setState() functions in derived class.
       
    71 */
       
    72 
       
    73 /*!
       
    74     \enum HbAbstractViewItem::StateKey
       
    75 
       
    76     HbAbstractViewItem's predefined set of state keys.
       
    77 
       
    78     This enum describes state keys for HbAbstractViewItem state values. State value can be accessed using this key.
       
    79 */
       
    80 
       
    81 /*!
       
    82     \var HbAbstractViewItem::FocusKey
       
    83          Predefined key for focus state value.
       
    84 */
       
    85 
       
    86 /*!
       
    87     \var HbAbstractViewItem::UserKey
       
    88          First key that can be used by the derived class for it's own purposes.
       
    89 */
       
    90 
       
    91 /*!
       
    92     \fn HbAbstractViewItem::createItem 
       
    93 
       
    94     Creates a new item. 
       
    95 
       
    96     In most subclasses, createItem should be implemented like this:
       
    97 
       
    98     \snippet{ultimatecodesnippet/customlistviewitem.cpp,1}
       
    99 */
       
   100 
       
   101 
       
   102 void HbAbstractViewItemPrivate::init()
       
   103 {
       
   104     Q_Q(HbAbstractViewItem);
       
   105 
       
   106     q->setProperty("state", "normal");
       
   107 
       
   108     if (isPrototype()) {
       
   109         q->setFocusPolicy(Qt::ClickFocus);
       
   110     } else {
       
   111         QGraphicsItem::GraphicsItemFlags itemFlags = q->flags();
       
   112         itemFlags |= QGraphicsItem::ItemIsFocusable;
       
   113         q->setFlags(itemFlags);
       
   114 
       
   115         q->setFocusPolicy(mSharedData->mPrototype->focusPolicy());
       
   116 
       
   117         mSharedData->mCloneItems.append(q);
       
   118     }
       
   119 }
       
   120 
       
   121 int HbAbstractViewItemPrivate::modelItemType() const
       
   122 {
       
   123     return mIndex.data(Hb::ItemTypeRole).toInt();
       
   124 }
       
   125 
       
   126 void HbAbstractViewItemPrivate::_q_animationFinished(const HbEffect::EffectStatus &status)
       
   127 {
       
   128     Q_UNUSED(status);
       
   129     Q_Q(HbAbstractViewItem);
       
   130 
       
   131     if (mFocusItem) {
       
   132         QCoreApplication::postEvent(q, new QEvent((QEvent::Type)HbAbstractViewItemShared::ViewItemDeferredDeleteEvent));
       
   133     }
       
   134 }
       
   135 
       
   136 void HbAbstractViewItemPrivate::repolishCloneItems()
       
   137 {
       
   138     int count(mSharedData->mCloneItems.count());
       
   139     for (int i = 0; i < count; ++i) {
       
   140         mSharedData->mCloneItems.at(i)->repolish();
       
   141     }
       
   142 }
       
   143 
       
   144 void HbAbstractViewItemPrivate::updateCloneItems()
       
   145 {
       
   146     int count(mSharedData->mCloneItems.count());
       
   147     for (int i = 0; i < count; ++i) {
       
   148         mSharedData->mCloneItems.at(i)->updatePrimitives();
       
   149     }
       
   150 }
       
   151 
       
   152 void HbAbstractViewItemPrivate::setInsidePopup(bool insidePopup)
       
   153 {
       
   154     Q_Q(HbAbstractViewItem);
       
   155 
       
   156     HbWidgetPrivate::setInsidePopup(insidePopup);
       
   157     if (q) {
       
   158         themingPending = true;
       
   159         q->updatePrimitives();
       
   160         q->repolish();
       
   161     }
       
   162 }
       
   163 
       
   164 /*!
       
   165     Constructs an abstract view item with the given parent.
       
   166 */
       
   167 HbAbstractViewItem::HbAbstractViewItem(QGraphicsItem *parent) : 
       
   168     HbWidget( *new HbAbstractViewItemPrivate( this ), parent )
       
   169 {
       
   170     Q_D( HbAbstractViewItem );
       
   171     d->q_ptr = this;
       
   172 
       
   173     d->init();
       
   174 }
       
   175 
       
   176 /*!
       
   177     Creates a separate graphics widget with same Abstract view item state as \a source.
       
   178 */
       
   179 HbAbstractViewItem::HbAbstractViewItem( HbAbstractViewItemPrivate &dd, QGraphicsItem *parent):
       
   180                     HbWidget( dd, parent )
       
   181 {
       
   182     Q_D( HbAbstractViewItem );
       
   183     d->q_ptr = this;
       
   184 
       
   185     d->init();
       
   186 }
       
   187 
       
   188 /*!
       
   189     Creates a separate graphics widget with same abstract view item state as \a source.
       
   190 */
       
   191 HbAbstractViewItem::HbAbstractViewItem(const HbAbstractViewItem &source) :
       
   192     HbWidget(*new HbAbstractViewItemPrivate(*source.d_func()), 0)
       
   193 {
       
   194     Q_D( HbAbstractViewItem );
       
   195     d->q_ptr = this;
       
   196 
       
   197     d->init();
       
   198 }
       
   199 
       
   200 /*!
       
   201     Assigns the \a source abstract view item to this abstract view item and returns a reference to this item.
       
   202 */
       
   203 HbAbstractViewItem &HbAbstractViewItem::operator=(const HbAbstractViewItem &source)
       
   204 {
       
   205     Q_D( HbAbstractViewItem );
       
   206     *d = *source.d_func();
       
   207     return *this;
       
   208 }
       
   209 
       
   210 
       
   211 /*!
       
   212     Destructor.
       
   213 */
       
   214 HbAbstractViewItem::~HbAbstractViewItem()
       
   215 {
       
   216     HB_SDD(HbAbstractViewItem);
       
   217     if (d && !d->isPrototype()) {
       
   218         sd->mCloneItems.removeOne(this);
       
   219     }
       
   220 }
       
   221 
       
   222 /*!
       
   223     Returns true if \a model index is supported by Abstract view item, otherwise returns false.
       
   224     This function is called for every item on the prototype list (, if several prototypes exist)
       
   225     until item is found, which can create item for \a index. The prototype list is gone 
       
   226     through from end to the beginning. 
       
   227     
       
   228     Thus specialized prototypes should be in the end of the list and 
       
   229     'default' prototype first one. The specialized prototypes usually can create only
       
   230     certain types of list view items. The default prototype usually return always true,
       
   231     meaning that it can create any type of list view item. 
       
   232 
       
   233     \sa HbAbstractItemView::setItemPrototype(HbAbstractViewItem *prototype), HbAbstractItemView::setItemPrototype(const QList<HbAbstractViewItem *> &prototypes)
       
   234 */
       
   235 bool HbAbstractViewItem::canSetModelIndex(const QModelIndex &index) const
       
   236 {
       
   237     Q_UNUSED(index);
       
   238     return true;
       
   239 }
       
   240 
       
   241 /*!
       
   242     Returns model index tied into this Abstract view item.
       
   243 */
       
   244 QModelIndex HbAbstractViewItem::modelIndex() const
       
   245 {
       
   246     Q_D( const HbAbstractViewItem );
       
   247     return d->mIndex;
       
   248 }
       
   249 
       
   250 /*!
       
   251     \deprecated HbAbstractViewItem::type() const
       
   252         is deprecated.
       
   253 
       
   254     \reimp
       
   255 */
       
   256 int HbAbstractViewItem::type() const
       
   257 {
       
   258     qWarning("HbAbstractViewItem::type() const is deprecated");
       
   259 
       
   260     return Hb::ItemType_AbstractViewItem;
       
   261 }
       
   262 
       
   263 
       
   264 /*!
       
   265     Sets model \a index where this Abstract view item should retrieve it's content.
       
   266 */
       
   267 void HbAbstractViewItem::setModelIndex(const QModelIndex &index)
       
   268 {
       
   269     Q_D( HbAbstractViewItem );
       
   270     if (d->mIndex != index) {
       
   271         d->mIndex = index;
       
   272         updateChildItems();
       
   273     }
       
   274 }
       
   275 
       
   276 /*!
       
   277     \deprecated HbAbstractViewItem::receivedFocus()
       
   278         is deprecated.
       
   279 
       
   280     Called when item has received focus.
       
   281 */
       
   282 void HbAbstractViewItem::receivedFocus()
       
   283 {
       
   284     qWarning("HbAbstractViewItem::receivedFocus() is deprecated!");
       
   285 
       
   286     Q_D( HbAbstractViewItem );
       
   287     d->mFocused = true;
       
   288 }
       
   289 
       
   290 /*!
       
   291     \deprecated HbAbstractViewItem::lostFocus()
       
   292         is deprecated.
       
   293 
       
   294     Called when item has lost focus.
       
   295 */
       
   296 void HbAbstractViewItem::lostFocus()
       
   297 {
       
   298     qWarning("HbAbstractViewItem::lostFocus() is deprecated!");
       
   299 
       
   300     Q_D( HbAbstractViewItem );
       
   301     d->mFocused = false;
       
   302 }
       
   303 
       
   304 /*!
       
   305     \deprecated HbAbstractViewItem::isFocused() const
       
   306         is deprecated.
       
   307 
       
   308     Retuns true if item is currently focused, otherwise return false.
       
   309 */
       
   310 bool HbAbstractViewItem::isFocused() const
       
   311 {
       
   312     qWarning("HbAbstractViewItem::isFocused() is deprecated!");
       
   313 
       
   314     Q_D( const HbAbstractViewItem );
       
   315     return d->mFocused;
       
   316 }
       
   317 
       
   318 /*!
       
   319     Returns the saved item's transient state. Transient state can be seen as a state data that is 
       
   320     wanted to be preserved but it not meaningful to be stored inside model index because of it's
       
   321     momentary nature. States will be saved inside AbstractItemview and restored when current model index is
       
   322     assigned to certain Abstract view item.
       
   323 */
       
   324 QMap<int,QVariant> HbAbstractViewItem::state() const
       
   325 {
       
   326     Q_D( const HbAbstractViewItem );
       
   327     QMap<int,QVariant> state;
       
   328 
       
   329     state.insert(FocusKey, d->mFocused);
       
   330     state.insert(CheckStateKey, d->mCheckState);
       
   331 
       
   332     return state;
       
   333 }
       
   334 
       
   335 /*!
       
   336     Restores the item's transient state using given \a state data.
       
   337 */
       
   338 void HbAbstractViewItem::setState(const QMap<int,QVariant> &state)
       
   339 {
       
   340     Q_D( HbAbstractViewItem );
       
   341     if (state.contains(FocusKey)) {
       
   342         d->mFocused = state.value(FocusKey).toBool();
       
   343     } else {
       
   344         d->mFocused = false; 
       
   345     }
       
   346 
       
   347     if (state.contains(CheckStateKey)) {
       
   348         d->mCheckState = (Qt::CheckState)state.value(CheckStateKey).toInt();
       
   349     } else {
       
   350         d->mCheckState = Qt::Unchecked;
       
   351     }
       
   352 }
       
   353 
       
   354 /*!
       
   355     Returns a pointer to HbAbstractViewItem prototype that was used to create this
       
   356     view item.
       
   357 */
       
   358 HbAbstractViewItem *HbAbstractViewItem::prototype() const
       
   359 {
       
   360     HB_SDD( const HbAbstractViewItem );
       
   361     return sd->mPrototype;
       
   362 }
       
   363 
       
   364 /*!
       
   365     Sets \a AbstractItemView that contains the Abstract view item.
       
   366 */
       
   367 void HbAbstractViewItem::setItemView( HbAbstractItemView *itemView )
       
   368 {
       
   369     HB_SDD( HbAbstractViewItem );
       
   370     sd->mItemView = itemView;
       
   371 }
       
   372 
       
   373 /*!
       
   374     Returns item view that contains the item view item.
       
   375 */
       
   376 HbAbstractItemView *HbAbstractViewItem::itemView() const
       
   377 {
       
   378     HB_SDD( const HbAbstractViewItem );
       
   379     return sd->mItemView;
       
   380 }
       
   381 
       
   382 /*!
       
   383     Populates a style option object for this widget based on its current state, and stores the output in \a option.
       
   384 */
       
   385 void HbAbstractViewItem::initStyleOption(HbStyleOptionAbstractViewItem *option) const
       
   386 {
       
   387     HB_SDD( const HbAbstractViewItem );
       
   388 
       
   389     HbWidget::initStyleOption(option);
       
   390 
       
   391     option->modelItemType = d->mModelItemType;
       
   392     option->index = d->mIndex;
       
   393 
       
   394     option->viewItemType = type();
       
   395     option->checkState = d->mCheckState;
       
   396     option->background = d->mBackground;
       
   397     if (!option->background.isValid()) {
       
   398         if (option->modelItemType == Hb::StandardItem 
       
   399             && !sd->mDefaultFrame.isNull()) {
       
   400             option->background = sd->mDefaultFrame;
       
   401         }
       
   402     }
       
   403 
       
   404     if (d->mPressed) {
       
   405         option->state |= QStyle::State_Sunken;
       
   406     }
       
   407     if (    sd->mItemView
       
   408         &&  sd->mItemView->selectionMode() == HbAbstractItemView::SingleSelection){
       
   409         option->singleSelectionMode = true;
       
   410     }
       
   411 
       
   412     option->insidePopup = testAttribute(Hb::InsidePopup);
       
   413 }
       
   414 
       
   415 /*!
       
   416     Check whether \a scenePosition of pressed down is inside selection area of view item in current selection mode.
       
   417 
       
   418     Default selection areas are for
       
   419     \li HbAbstractItemView::SingleSelection mode: whole item
       
   420     \li HbAbstractItemView::MultiSelection mode: touch area of selection icon. 
       
   421         Touch are is represented by primitive HbStyle::P_ItemViewItem_touchmultiselection.
       
   422     \li HbAbstractItemView::ContiguousSelection mode: touch area of selection icon. 
       
   423         Touch are is represented by primitive HbStyle::P_ItemViewItem_touchmultiselection.
       
   424     \li HbAbstractItemView::NoSelection mode: none
       
   425 */
       
   426 bool HbAbstractViewItem::selectionAreaContains(const QPointF &scenePosition) const
       
   427 {
       
   428     HB_SDD(const HbAbstractViewItem);
       
   429     bool contains = false;
       
   430     if (sd->mItemView) {
       
   431         switch (sd->mItemView->selectionMode()) {
       
   432             case HbAbstractItemView::SingleSelection: 
       
   433                 contains = true;
       
   434                 break;
       
   435             case HbAbstractItemView::MultiSelection: 
       
   436                 // fall through
       
   437             case HbAbstractItemView::ContiguousSelection: {
       
   438                 // TODO: put assert back in action, when official layouts in use
       
   439                 /*Q_ASSERT_X(     d->mMultiSelectionTouchArea 
       
   440                             &&  d->mMultiSelectionTouchArea->boundingRect().size().width() > 0 
       
   441                             &&  d->mMultiSelectionTouchArea->boundingRect().size().height() > 0, "", "HbAbstractViewItem::selectionAreaContains(): d->mMultiSelectionTouchArea should exist");
       
   442                 */
       
   443                 if(     d->mMultiSelectionTouchArea 
       
   444                     &&  d->mMultiSelectionTouchArea->boundingRect().size().width() > 0 
       
   445                     &&  d->mMultiSelectionTouchArea->boundingRect().size().height() > 0) {
       
   446                     contains = d->mMultiSelectionTouchArea->boundingRect().contains(
       
   447                                     d->mMultiSelectionTouchArea->mapFromScene(scenePosition));
       
   448                 } else {
       
   449                     contains = d->mSelectionItem->boundingRect().contains(
       
   450                                     d->mSelectionItem->mapFromScene(scenePosition));
       
   451                 }
       
   452                 break;
       
   453             }
       
   454             default:
       
   455                 break;
       
   456         }
       
   457     }
       
   458     return contains;
       
   459 }
       
   460 
       
   461 
       
   462 /*!
       
   463     \reimp
       
   464 */
       
   465 bool HbAbstractViewItem::event(QEvent *e)
       
   466 {
       
   467     if (e) {
       
   468         switch (e->type()) {
       
   469             case QEvent::GraphicsSceneResize: {
       
   470                 Q_D(HbAbstractViewItem );
       
   471                 if (d->mBackgroundItem || d->mFrame || d->mFocusItem) {
       
   472                     HbStyleOptionAbstractViewItem styleOption;
       
   473                     initStyleOption(&styleOption);
       
   474                     if (d->mFocusItem) {
       
   475                         style()->updatePrimitive(d->mFocusItem, HbStyle::P_ItemViewItem_focus, &styleOption);
       
   476                     }
       
   477                 }
       
   478                 break;
       
   479             }
       
   480             case QEvent::LayoutDirectionChange: {
       
   481                 repolish();
       
   482                 break;
       
   483             }
       
   484             default: {
       
   485                 if (e->type() == HbAbstractViewItemShared::ViewItemDeferredDeleteEvent) {
       
   486                     // cannot handle ViewItemDeferredDeleteEvent in the case statement!
       
   487                     Q_D(HbAbstractViewItem);
       
   488                     delete d->mFocusItem;
       
   489                     d->mFocusItem = 0;
       
   490                }
       
   491                 break;
       
   492             }
       
   493         }
       
   494 
       
   495         return HbWidget::event(e);
       
   496     }
       
   497 
       
   498     return false;
       
   499 }
       
   500 
       
   501 /*!
       
   502   Provides access to primitives of HbAbstractViewItem.
       
   503   \param primitive is the type of the requested primitive. The available primitives are 
       
   504   \c P_ItemViewItem_background
       
   505   \c P_ItemViewItem_frame
       
   506   \c P_ItemViewItem_selection
       
   507   \c P_ItemViewItem_focus
       
   508   \c P_ItemViewItem_touchmultiselection.
       
   509  */
       
   510 QGraphicsItem *HbAbstractViewItem::primitive(HbStyle::Primitive primitive) const
       
   511 {
       
   512     Q_D(const HbAbstractViewItem);
       
   513 
       
   514     if (primitive == HbStyle::P_ItemViewItem_background) {
       
   515         return d->mBackgroundItem;
       
   516     } else if (primitive == HbStyle::P_ItemViewItem_frame) {
       
   517         return d->mFrame;
       
   518     } else if (primitive == HbStyle::P_ItemViewItem_selection) {
       
   519         return d->mSelectionItem;
       
   520     } else if (primitive == HbStyle::P_ItemViewItem_focus) {
       
   521         return d->mFocusItem;
       
   522     } else if (primitive == HbStyle::P_ItemViewItem_touchmultiselection) {
       
   523         return d->mMultiSelectionTouchArea;
       
   524     }
       
   525 
       
   526     return HbWidget::primitive(primitive);
       
   527 }
       
   528 
       
   529 /*!
       
   530     \reimp
       
   531 
       
   532     To optimise loading css/xml definitions to take place only once, this function should be
       
   533     called only after other primitives (child items) has been created.
       
   534 
       
   535 */
       
   536 void HbAbstractViewItem::updatePrimitives()
       
   537 {
       
   538     Q_D( HbAbstractViewItem);
       
   539     HbWidget::updatePrimitives();
       
   540 
       
   541     // For debugging primitives
       
   542 #if 0
       
   543     {
       
   544         QStringList listClasses;
       
   545         listClasses << "HbTreeViewItem";
       
   546         const QMetaObject *meta = metaObject();
       
   547         int count = listClasses.count();
       
   548         for (int i=0; i< count; i++) {
       
   549             if ( meta->className() == listClasses.at(i)) {
       
   550                 qDebug() << "HbAbstractViewItem::updatePrimitives(): widget, row, item count, check state" 
       
   551                     << listClasses.at(i) << modelIndex().row() << childItems().count() << d->mCheckState;;
       
   552                 int count = childItems().count();
       
   553                 for (int i=0; i< count; i++) {
       
   554                     if (childItems().at(i)) {
       
   555                         HbTextItem *textItem = 0;
       
   556                         if (childItems().at(i)->isWidget()) {
       
   557                             textItem = qobject_cast<HbTextItem*>(static_cast<QGraphicsWidget*>(childItems().at(i)));
       
   558                         }
       
   559                         if (textItem) {
       
   560                             qDebug() << "  item #, item name, id: " << i << childItems().at(i)->data(0xfffe).toString() << textItem->text();
       
   561                         } else {
       
   562                             qDebug() << "  item #, item name: " << i << childItems().at(i)->data(0xfffe).toString();
       
   563                         }
       
   564                     }
       
   565                 }
       
   566             }
       
   567         }
       
   568     }
       
   569 #endif
       
   570 
       
   571 
       
   572     HbStyleOptionAbstractViewItem styleOption;
       
   573     initStyleOption(&styleOption);
       
   574 
       
   575     if (d->mBackgroundItem) {
       
   576         style()->updatePrimitive(d->mBackgroundItem, HbStyle::P_ItemViewItem_background, &styleOption);
       
   577     }
       
   578 
       
   579     if (d->mFrame) {
       
   580         style()->updatePrimitive(d->mFrame, HbStyle::P_ItemViewItem_frame, &styleOption);
       
   581     }
       
   582 
       
   583     if (d->mSelectionItem) {
       
   584         style()->updatePrimitive(d->mSelectionItem, HbStyle::P_ItemViewItem_selection, &styleOption);
       
   585     }
       
   586 
       
   587     if (d->mMultiSelectionTouchArea) {
       
   588         style()->updatePrimitive(d->mMultiSelectionTouchArea, HbStyle::P_ItemViewItem_touchmultiselection, &styleOption);
       
   589     }
       
   590 
       
   591     if (d->mFocusItem) {
       
   592         style()->updatePrimitive(d->mFocusItem, HbStyle::P_ItemViewItem_focus, &styleOption);
       
   593     }
       
   594 }
       
   595 
       
   596 
       
   597 /*!
       
   598     Updates child graphics items to represent current state and content. 
       
   599 
       
   600     \note It is a good habit to reuse child items as much as possible as this improves
       
   601     performance, especially when item recycling is used. 
       
   602 
       
   603     Most of the HbAbstractViewItem derived classes inside Hb library are optimised for performance.
       
   604     Layout files are loaded only if child items are created or deleted. Loading layout
       
   605     files is triggered by calling HbWidget::repolish(). 
       
   606     Classes deriving from HbAbstractViewItem outside Hb, should either always call explicitly
       
   607     repolish() or if they are also optimised for performance only when child items are created or deleted
       
   608     in the custom view item.
       
   609 
       
   610     Here is an example of custom view item that reuses its child items. The custom view item does not
       
   611     create or delete child items.
       
   612 
       
   613     \snippet{ultimatecodesnippet/customlistviewitem.cpp,2}
       
   614 
       
   615     \sa HbWidget::polish()
       
   616 */
       
   617 void HbAbstractViewItem::updateChildItems()
       
   618 {
       
   619     HB_SDD(HbAbstractViewItem);
       
   620 
       
   621     int itemType = d->modelItemType();
       
   622     if (itemType != d->mModelItemType) {
       
   623         d->mModelItemType = itemType;
       
   624         d->mItemsChanged = true;
       
   625         d->themingPending = true;
       
   626     }
       
   627 
       
   628     // background
       
   629     QVariant currentBackground = d->mIndex.data(Qt::BackgroundRole);
       
   630     if (currentBackground != d->mBackground) {
       
   631         d->mBackground = currentBackground;
       
   632         if (currentBackground.canConvert<HbIcon>() 
       
   633             || currentBackground.canConvert<QBrush>()) {
       
   634             if (!d->mBackgroundItem) {  
       
   635                 d->mItemsChanged = true;
       
   636                 d->mBackgroundItem = style()->createPrimitive(HbStyle::P_ItemViewItem_background, this);
       
   637             }
       
   638         } 
       
   639         else if (currentBackground.canConvert<HbFrameBackground>()) {
       
   640             if (!d->mFrame) {
       
   641                 d->mItemsChanged = true;
       
   642                 d->mFrame = style()->createPrimitive(HbStyle::P_ItemViewItem_frame, this);
       
   643             }
       
   644             if (d->mBackgroundItem) {
       
   645                 d->mItemsChanged = true;
       
   646                 delete d->mBackgroundItem;
       
   647                 d->mBackgroundItem = 0;
       
   648             }
       
   649         }
       
   650         else {
       
   651             if (d->mBackgroundItem) {
       
   652                 d->mItemsChanged = true;
       
   653                 delete d->mBackgroundItem;
       
   654                 d->mBackgroundItem = 0;
       
   655             }
       
   656         }
       
   657     }
       
   658     
       
   659     if (!d->mFrame) { // frame should always exists
       
   660         d->mItemsChanged = true;
       
   661         d->mFrame = style()->createPrimitive(HbStyle::P_ItemViewItem_frame, this);
       
   662     }
       
   663 
       
   664     GraphicsItemFlags itemFlags = flags();
       
   665     Qt::ItemFlags indexFlags = d->mIndex.flags();
       
   666 
       
   667     if (indexFlags & Qt::ItemIsEnabled) {
       
   668         if (!(itemFlags & QGraphicsItem::ItemIsFocusable)) {
       
   669             itemFlags |= QGraphicsItem::ItemIsFocusable;
       
   670             setFocusPolicy(sd->mPrototype->focusPolicy());
       
   671             setProperty("state", "normal");
       
   672         }
       
   673     } else {
       
   674         if (itemFlags & QGraphicsItem::ItemIsFocusable) {
       
   675             itemFlags &= ~QGraphicsItem::ItemIsFocusable;
       
   676             setFocusPolicy(Qt::NoFocus);
       
   677             setProperty("state", "disabled");
       
   678         }
       
   679     }
       
   680 
       
   681     // selection
       
   682     HbAbstractItemView::SelectionMode selectionMode = HbAbstractItemView::NoSelection;
       
   683     if (sd->mItemView) {
       
   684         selectionMode = sd->mItemView->selectionMode();
       
   685     }
       
   686 
       
   687     bool previousSelectable = itemFlags & QGraphicsItem::ItemIsSelectable;
       
   688     bool itemSelectable = false;
       
   689 
       
   690     if (indexFlags & Qt::ItemIsSelectable 
       
   691         && selectionMode != HbAbstractItemView::NoSelection
       
   692         && indexFlags & Qt::ItemIsEnabled) {
       
   693         itemFlags |= QGraphicsItem::ItemIsSelectable;
       
   694         itemSelectable = true;
       
   695     } else {
       
   696         itemFlags &= ~QGraphicsItem::ItemIsSelectable;
       
   697     }
       
   698 
       
   699     if (previousSelectable != itemSelectable) {
       
   700         if (itemSelectable) {
       
   701             if (!d->mSelectionItem) {
       
   702                 d->mItemsChanged = true;
       
   703                 d->mSelectionItem = style()->createPrimitive(HbStyle::P_ItemViewItem_selection, this);
       
   704             }
       
   705         } else {
       
   706             d->mItemsChanged = true;
       
   707             delete d->mSelectionItem;
       
   708             d->mSelectionItem = 0;
       
   709         }
       
   710     }
       
   711 
       
   712     setFlags(itemFlags);
       
   713 
       
   714     // multiselection area
       
   715     if (    itemSelectable 
       
   716         &&  (   selectionMode == HbAbstractItemView::MultiSelection
       
   717             ||  selectionMode == HbAbstractItemView::ContiguousSelection)) {
       
   718         if (!d->mMultiSelectionTouchArea) {
       
   719             d->mItemsChanged = true;
       
   720             d->mMultiSelectionTouchArea = style()->createPrimitive(HbStyle::P_ItemViewItem_touchmultiselection, this);
       
   721         }
       
   722     } else if (d->mMultiSelectionTouchArea) {
       
   723         d->mItemsChanged = true;
       
   724         delete d->mMultiSelectionTouchArea;
       
   725         d->mMultiSelectionTouchArea = 0;
       
   726     }
       
   727 
       
   728     // items visibility or items content has really changed
       
   729     d->mSizeHintPolish = false;
       
   730     updatePrimitives();
       
   731     if (!d->mContentChangedSupported
       
   732         || d->mItemsChanged) {
       
   733         updateGeometry();   // ensures that sizehint is calculated again in case items have been created or deleted
       
   734         d->mRepolishRequested = true;
       
   735         repolish();
       
   736     }
       
   737     d->mItemsChanged = false;
       
   738 }
       
   739 
       
   740 /*!
       
   741     Sets the check state of the view item to state.
       
   742 
       
   743     \sa checkState().
       
   744 */
       
   745 void HbAbstractViewItem::setCheckState(Qt::CheckState state)
       
   746 {
       
   747     Q_D(HbAbstractViewItem);
       
   748     if (state != d->mCheckState) {
       
   749         d->mCheckState = state;
       
   750         updatePrimitives();
       
   751     }
       
   752 }
       
   753 
       
   754 /*!
       
   755     Returns the checked state of the view item (see Qt::CheckState).
       
   756 
       
   757     \sa setCheckState().
       
   758 */
       
   759 Qt::CheckState HbAbstractViewItem::checkState() const
       
   760 {
       
   761     Q_D(const HbAbstractViewItem);
       
   762     return d->mCheckState;
       
   763 }
       
   764 
       
   765 /*!
       
   766     \deprecated HbAbstractViewItem::setPressed(bool, bool)
       
   767         is deprecated.
       
   768 
       
   769     Sets the item press state to \a pressed. Animation is allowed
       
   770     if \a animate is set as true; otherwise animation should not
       
   771     be triggered.
       
   772 
       
   773     \sa isPressed, pressStateChanged
       
   774 */
       
   775 void HbAbstractViewItem::setPressed(bool pressed, bool animate)
       
   776 {
       
   777     qWarning("HbAbstractViewItem::setPressed(bool pressed, bool animate) is deprecated!");
       
   778 
       
   779     Q_D(HbAbstractViewItem);
       
   780 
       
   781     if (pressed != d->mPressed) {
       
   782         d->mPressed = pressed;
       
   783         pressStateChanged(d->mPressed, animate);
       
   784         if (d->mPressed) {
       
   785             setProperty("state", "pressed");
       
   786         } else {
       
   787             setProperty("state", "normal");
       
   788         }
       
   789     }
       
   790 }
       
   791 
       
   792 /*!
       
   793     This function is called whenever item press state changes. \a pressed is new state.
       
   794 
       
   795     Animation is allowed if \a animate is set as true; otherwise animation should not
       
   796     be triggered.
       
   797 
       
   798     Default implementation creates focus frame if item is currently pressed 
       
   799     and deletes the focus frame if item is not anymore pressed. It also triggers
       
   800     default animations.
       
   801 
       
   802     \sa setPressed
       
   803 */
       
   804 void HbAbstractViewItem::pressStateChanged(bool pressed, bool animate)
       
   805 {
       
   806     HB_SDD(HbAbstractViewItem);
       
   807 
       
   808     bool doAnimate = animate;
       
   809     if (sd->mItemView && !(sd->mItemView->enabledAnimations() & HbAbstractItemView::TouchDown)) {
       
   810         doAnimate = false;
       
   811     }
       
   812     if (pressed) {
       
   813         if (!d->mFocusItem) {
       
   814             d->mFocusItem = style()->createPrimitive(HbStyle::P_ItemViewItem_focus, this);
       
   815         }
       
   816             
       
   817         HbStyleOptionAbstractViewItem styleOption;
       
   818         initStyleOption(&styleOption);
       
   819 
       
   820         style()->updatePrimitive(d->mFocusItem, HbStyle::P_ItemViewItem_focus, &styleOption);
       
   821 
       
   822         if (doAnimate) {
       
   823             HbEffect::cancel(this, "released");
       
   824             HbEffect::cancel(d->mFocusItem, "released");
       
   825 
       
   826             HbEffect::start(this, sd->mItemType, "pressed");
       
   827             HbEffect::start(d->mFocusItem, sd->mItemType + QString("-focus"), "pressed");
       
   828         }
       
   829     } else {
       
   830         if (doAnimate) {
       
   831             HbEffect::cancel(this, "pressed");
       
   832             HbEffect::cancel(d->mFocusItem, "pressed");
       
   833 
       
   834             HbEffect::start(this, sd->mItemType, "released");
       
   835             HbEffect::start(d->mFocusItem, sd->mItemType + QString("-focus"), "released", this, "_q_animationFinished");
       
   836         } else {
       
   837             QCoreApplication::postEvent(this, new QEvent((QEvent::Type)HbAbstractViewItemShared::ViewItemDeferredDeleteEvent));
       
   838         }
       
   839     }
       
   840 }
       
   841 
       
   842 /*!
       
   843     \deprecated HbAbstractViewItem::isPressed() const
       
   844         is deprecated.
       
   845 
       
   846     Returns true if the item is pressed; otherwise returns false
       
   847 
       
   848     \sa setPressed
       
   849 */
       
   850 bool HbAbstractViewItem::isPressed() const
       
   851 {
       
   852     qWarning("HbAbstractViewItem::isPressed() const is deprecated!");
       
   853 
       
   854     Q_D(const HbAbstractViewItem);
       
   855     return d->mPressed;
       
   856 }
       
   857 
       
   858 /*!
       
   859     Returns the model item type that is retrieved from model index.
       
   860 */
       
   861 Hb::ModelItemType HbAbstractViewItem::modelItemType() const
       
   862 {
       
   863     Q_D(const HbAbstractViewItem);
       
   864     return (Hb::ModelItemType)d->mModelItemType;
       
   865 }
       
   866 
       
   867 /*!
       
   868     \reimp
       
   869 */
       
   870 void HbAbstractViewItem::polish(HbStyleParameters& params)
       
   871 {
       
   872     HB_SDD(HbAbstractViewItem);
       
   873 
       
   874 	if (!d->polished && layout()) {
       
   875 		return;
       
   876 	}
       
   877 	
       
   878     if (d->mSizeHintPolish) {
       
   879         d->mSizeHintPolish = false;
       
   880         return;
       
   881     }
       
   882 
       
   883     if (sd->mItemView) {
       
   884         setProperty("layoutName", sd->mItemView->layoutName());
       
   885     }
       
   886 
       
   887     d->mRepolishRequested = false;
       
   888     HbWidget::polish(params);
       
   889 
       
   890     // TODO Brush background is overridden by css system even if bursh would not be set
       
   891     // explicitly by css/xml. This is feature, which will change
       
   892     // later in css system. Workaround for it. This overrides the background brush set by css. 
       
   893     {
       
   894         if (d->mBackground.isValid() 
       
   895             && d->mBackground.canConvert<QBrush>() 
       
   896             && d->mBackgroundItem
       
   897             && d->mBackgroundItem->isWidget()) {
       
   898             qgraphicsitem_cast<HbIconItem *>(static_cast<QGraphicsWidget*>(d->mBackgroundItem))->setBrush(d->mBackground.value<QBrush>());
       
   899         } 
       
   900     }
       
   901 }
       
   902 
       
   903 
       
   904 /*!
       
   905     \reimp
       
   906 
       
   907     The default implementation ignores all mouse press events.
       
   908 */
       
   909 void HbAbstractViewItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
       
   910 {
       
   911     event->ignore();
       
   912 }
       
   913 
       
   914 /*!
       
   915     \reimp
       
   916 
       
   917     The default implementation ignores all mouse move events.
       
   918 */
       
   919 void HbAbstractViewItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
       
   920 {
       
   921     event->ignore();
       
   922 }
       
   923 
       
   924 /*!
       
   925     \reimp
       
   926 
       
   927     The default implementation ignores all mouse release events.
       
   928 */
       
   929 void HbAbstractViewItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
       
   930 {
       
   931     event->ignore();
       
   932 }
       
   933 
       
   934 /*!
       
   935     \reimp
       
   936 */
       
   937 QSizeF HbAbstractViewItem::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
       
   938 {
       
   939     Q_D(const HbAbstractViewItem);
       
   940     if (d->mRepolishRequested) {
       
   941         // force the polish event in order to get the real size
       
   942         const_cast<HbAbstractViewItemPrivate *>(d)->mRepolishRequested = false;
       
   943         QEvent polishEvent(QEvent::Polish);
       
   944         QCoreApplication::sendEvent(const_cast<HbAbstractViewItem *>(this), &polishEvent);
       
   945         // HbAbstractItemView::scrollByAmount() [recycleItems()]
       
   946         // causes updateChildItems() to be called, which posts Polish to be posted via repolish().
       
   947         // Next statement in the scrollByAmount() [refreshContainerGeometry()]
       
   948         // causes synchronous call of this method. This is a quick way to disable another
       
   949         // ::polish() to be called.
       
   950         d->mSizeHintPolish = true;
       
   951     }
       
   952     return HbWidget::sizeHint(which, constraint);
       
   953 }
       
   954 
       
   955 /*!
       
   956     Sets the default frame for standard view items as \a frame.  
       
   957     
       
   958     This method will change the used frame for
       
   959     all view items that represent model index with Hb::StandardItem type.
       
   960 
       
   961     Input parameter with empty graphicsName string will remove the frame.
       
   962     Input parameter with null graphicsName string will restore the default frame.
       
   963 
       
   964     \sa defaultFrame
       
   965 */
       
   966 void HbAbstractViewItem::setDefaultFrame(const HbFrameBackground &frame)
       
   967 {
       
   968     HB_SDD(HbAbstractViewItem);
       
   969     if (sd->mDefaultFrame != frame) {
       
   970         sd->mDefaultFrame = frame;
       
   971         
       
   972         int count(sd->mCloneItems.count());
       
   973         for (int i = 0; i < count; ++i) {
       
   974             sd->mCloneItems.at(i)->updatePrimitives();
       
   975         }
       
   976     }
       
   977 }
       
   978 
       
   979 /*!
       
   980     Returns the current default frame.
       
   981 
       
   982     \sa setDefaultFrame
       
   983 */
       
   984 HbFrameBackground HbAbstractViewItem::defaultFrame() const
       
   985 {
       
   986     HB_SDD(const HbAbstractViewItem);
       
   987     return sd->mDefaultFrame;
       
   988 }
       
   989 
       
   990 
       
   991 #include "moc_hbabstractviewitem.cpp"
       
   992