src/hbwidgets/itemviews/hbtreeview.cpp
changeset 1 f7ac710697a9
parent 0 16d8024aca5e
child 2 06ff229162e9
equal deleted inserted replaced
0:16d8024aca5e 1:f7ac710697a9
    32 #include "hbtreemodeliterator_p.h"
    32 #include "hbtreemodeliterator_p.h"
    33 
    33 
    34 #include <QItemSelection>
    34 #include <QItemSelection>
    35 #include <QGraphicsSceneMouseEvent>
    35 #include <QGraphicsSceneMouseEvent>
    36 
    36 
       
    37 // for QMAP_INT__ITEM_STATE_DEPRECATED's sake
       
    38 #include <hbabstractviewitem.h>
       
    39 
    37 /*!
    40 /*!
    38     @alpha
    41     @alpha
    39     @hbwidgets
    42     @hbwidgets
    40     \class HbTreeView
    43     \class HbTreeView
    41     \brief HbTreeView represents a hierarchical list
    44     \brief HbTreeView represents a hierarchical list
   124             }
   127             }
   125         }
   128         }
   126     }
   129     }
   127 
   130 
   128     if ( itemRecycling()) {
   131     if ( itemRecycling()) {
   129         bool itemBuffered = d->mContainer->itemByIndex(newIndex);
   132         if (    !d->mContainer->itemByIndex(newIndex)
   130         if (! (     itemBuffered
   133             ||  hint != EnsureVisible) {
   131                 &&  hint == PositionAtTop)) {
       
   132             if ( hint != PositionAtTop ) {
   134             if ( hint != PositionAtTop ) {
   133                 // Following two variable applies only for hint EnsureVisible.
   135                 // Following two variable applies only for hint EnsureVisible.
   134                 // It is position relative to the view
   136                 // It is position relative to the view
   135                 bool belowBottom = false;
   137                 bool belowBottom = false;
   136                 bool aboveTop = false;
   138                 bool aboveTop = false;
   246         return;
   248         return;
   247     }
   249     }
   248 
   250 
   249     if (d->isParentValid(parent)) {
   251     if (d->isParentValid(parent)) {
   250         if (isExpanded(parent) || parent == d->mModelIterator->rootIndex()) {
   252         if (isExpanded(parent) || parent == d->mModelIterator->rootIndex()) {
   251             HbAbstractItemView::rowsInserted(parent, start, end);
   253             int lastStartPoint = 0;
       
   254             for (int i = start; i <= end; ++i) {
       
   255                 QModelIndex newParent = d->treeModelIterator()->index(i, parent);
       
   256                 int childCount = d->treeModelIterator()->childCount(newParent);
       
   257                 if (childCount > 0 && isExpanded(newParent)) {
       
   258                     HbAbstractItemView::rowsInserted(parent, lastStartPoint, i);
       
   259                     lastStartPoint = i;
       
   260                     rowsInserted(newParent, 0, childCount - 1);
       
   261                 }
       
   262             }
       
   263 
       
   264             HbAbstractItemView::rowsInserted(parent, lastStartPoint, end);
       
   265 
       
   266             if (d->animationEnabled(true)) {
       
   267                 if (d->mInSetExpanded) {
       
   268                     d->startAppearEffect("treeviewitem", "expand", parent, start, end);
       
   269                 } else {
       
   270                     d->startAppearEffect("viewitem", "appear", parent, start, end);
       
   271                 }
       
   272             }
   252         }
   273         }
   253 
   274 
   254         HbAbstractViewItem *parentItem = d->mContainer->itemByIndex(parent);
   275         HbAbstractViewItem *parentItem = d->mContainer->itemByIndex(parent);
   255         if (parentItem) {
   276         if (parentItem) {
   256             parentItem->updateChildItems();
   277             parentItem->updateChildItems();
   257         }            
   278         }
   258     }
   279     }
   259 }
   280 }
   260 
   281 
   261 /*!
   282 /*!
   262     \reimp
   283     \reimp
   280             if (d->mSelectionModel) {
   301             if (d->mSelectionModel) {
   281                 d->mSelectionModel->setCurrentIndex(newCurrentIndex, QItemSelectionModel::NoUpdate);
   302                 d->mSelectionModel->setCurrentIndex(newCurrentIndex, QItemSelectionModel::NoUpdate);
   282             } 
   303             } 
   283         }  
   304         }  
   284 
   305 
   285         if (isExpanded(parent) || parent == d->mModelIterator->rootIndex()) {
   306         if (isExpanded(parent) || parent == d->mModelIterator->rootIndex() || d->mInSetExpanded) {
       
   307             bool animate = d->animationEnabled(false);
       
   308 
       
   309             QList<HbAbstractViewItem *> items = d->mContainer->items();
   286             for (int i = d->mItemsToBeDeleted.count() - 1; i >= 0; --i) {
   310             for (int i = d->mItemsToBeDeleted.count() - 1; i >= 0; --i) {
   287                 int pos = d->mItemsToBeDeleted.at(i);
   311                 int pos = d->mItemsToBeDeleted.at(i);
   288                 d->mContainer->removeItem(pos);
   312                 
       
   313                 HbAbstractViewItem *item = items.at(pos);
       
   314                 if (item) {
       
   315                     if (animate) {
       
   316                         HbEffect::cancel(item, "appear");
       
   317                         HbEffect::cancel(item, "expand");
       
   318                         
       
   319                         QString effectType;
       
   320                         QString itemType;
       
   321                         if (d->mInSetExpanded) {
       
   322                             effectType = "collapse";
       
   323                             itemType = "treeviewitem";
       
   324                         } else {
       
   325                             effectType = "disappear";
       
   326                             itemType = "viewitem";
       
   327                         }
       
   328 
       
   329                         item->setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
       
   330                         HbEffect::start(item,
       
   331                                 itemType,
       
   332                                 effectType,
       
   333                                 d->mContainer,
       
   334                                 "animationFinished");
       
   335                         
       
   336                         if (HbEffect::effectRunning(item, effectType)) {
       
   337                             d->mContainer->removeItem(pos, animate);
       
   338                         }
       
   339                     } else {
       
   340                         d->mContainer->removeItem(pos, animate);
       
   341                     }
       
   342                 }
   289             }
   343             }
   290         }
   344         }
   291 
   345 
   292         HbAbstractViewItem *parentItem = d->mContainer->itemByIndex(parent);
   346         HbAbstractViewItem *parentItem = d->mContainer->itemByIndex(parent);
   293         if (parentItem) {
   347         if (parentItem) {
   294             parentItem->updateChildItems();
   348             parentItem->updateChildItems();
   295         }
   349         }
   296     }
   350     }
   297 
       
   298     d->mItemsToBeDeleted.clear();
       
   299 }
   351 }
   300 
   352 
   301 /*!
   353 /*!
   302     \reimp
   354     \reimp
   303 */
   355 */
   304 void HbTreeView::rowsAboutToBeRemoved(const QModelIndex &index, int start, int end)
   356 void HbTreeView::rowsAboutToBeRemoved(const QModelIndex &index, int start, int end)
   305 {
   357 {
   306     Q_D(HbTreeView);
   358     Q_D(HbTreeView);
   307 
   359 
   308     d->mItemsToBeDeleted.clear();
   360     if (d->isParentValid(index)) {
       
   361         d->mItemsToBeDeleted.clear();
   309         
   362         
   310     QList <HbAbstractViewItem *> items = d->mContainer->items();
   363         QList <HbAbstractViewItem *> items = d->mContainer->items();
   311     int itemCount = items.count();
   364         int itemCount = items.count();
   312 
   365 
   313     // Add the view items given as parameters and all their child items to a list for deletion.    
   366         // Add the view items given as parameters and all their child items to a list for deletion.
   314     for (int i = start; i <= end; ++i) {
   367         for (int i = start; i <= end; ++i) {
   315         QModelIndex parent = model()->index(i, 0, index);
   368             QModelIndex parent = model()->index(i, 0, index);
   316         
   369 
   317         for (int j = 0; j < itemCount; ++j) {
   370             for (int j = 0; j < itemCount; ++j) {
   318             QModelIndex itemIndex = items.at(j)->modelIndex();
   371                 QModelIndex itemIndex = items.at(j)->modelIndex();
   319             if (itemIndex == parent || d->isChild(itemIndex, parent)) {
   372                 if (itemIndex == parent || d->isChild(itemIndex, parent)) {
   320                 d->mItemsToBeDeleted.append(j);
   373                     d->mItemsToBeDeleted.append(j);
       
   374                 }
   321             }
   375             }
   322         }
   376         }
   323     }
   377     }
   324 }
   378 }
   325 
   379 
   440                             // Initially node1 is selected, then leaf1 is selected.
   494                             // Initially node1 is selected, then leaf1 is selected.
   441                             // Node2 may have been set Unchecked into map before node1.
   495                             // Node2 may have been set Unchecked into map before node1.
   442                             // When node1 will be handled, node2 is unchecked in the map but not yet in the view item
   496                             // When node1 will be handled, node2 is unchecked in the map but not yet in the view item
   443                             childCheckState = parentItems.value(childIndex);
   497                             childCheckState = parentItems.value(childIndex);
   444                         } else {
   498                         } else {
   445                             QVariant value = d->mContainer->itemState(childIndex).value(HbTreeViewItem::CheckStateKey);
   499                             QVariant value = d->mContainer->itemTransientState(childIndex).value("checkState");
   446                             if (value.isValid()) {
   500                             if (value.isValid()) {
   447                                 childCheckState = (Qt::CheckState)value.toInt();
   501                                 childCheckState = (Qt::CheckState)value.toInt();
   448                             }
   502                             }
   449                         }
   503                         }
   450                         if (childCheckState != Qt::Unchecked) {
   504                         if (childCheckState != Qt::Unchecked) {
   476             HbAbstractViewItem *item = d->mContainer->itemByIndex(iterator.key());
   530             HbAbstractViewItem *item = d->mContainer->itemByIndex(iterator.key());
   477             if (item) {
   531             if (item) {
   478                 item->setCheckState(iterator.value());
   532                 item->setCheckState(iterator.value());
   479             } 
   533             } 
   480 
   534 
       
   535 #ifndef QMAP_INT__ITEM_STATE_DEPRECATED
   481             d->mContainer->setItemStateValue(iterator.key(), HbAbstractViewItem::CheckStateKey, iterator.value());
   536             d->mContainer->setItemStateValue(iterator.key(), HbAbstractViewItem::CheckStateKey, iterator.value());
       
   537 #endif
       
   538             d->mContainer->setItemTransientStateValue(iterator.key(), "checkState", iterator.value());
   482             iterator++;
   539             iterator++;
   483         }
   540         }
   484 
   541 
   485         d->mSelectionStarted = false;
   542         d->mSelectionStarted = false;
   486     }
   543     }
   494 void HbTreeView::setExpanded(const QModelIndex &index, bool expanded)
   551 void HbTreeView::setExpanded(const QModelIndex &index, bool expanded)
   495 {
   552 {
   496     Q_D(HbTreeView);
   553     Q_D(HbTreeView);
   497 
   554 
   498     if (isExpanded(index) != expanded) {
   555     if (isExpanded(index) != expanded) {
   499         d->treeModelIterator()->itemStateChanged(index, HbTreeViewItem::ExpansionKey);
   556         d->mInSetExpanded = true;
   500         HbTreeItemContainer *container = qobject_cast<HbTreeItemContainer *>(d->mContainer);
   557         d->treeModelIterator()->itemExpansionChanged(index);
   501         container->setExpanded(index, expanded);
   558 
       
   559 #ifndef QMAP_INT__ITEM_STATE_DEPRECATED
       
   560         d->mContainer->setItemStateValue(index, HbTreeViewItem::ExpansionKey, expanded);
       
   561 #endif
       
   562         d->mContainer->setItemTransientStateValue(index, "expanded", expanded);
       
   563 
       
   564         int childCount = d->treeModelIterator()->childCount(index) - 1;
       
   565 
       
   566         if (expanded) {
       
   567             rowsAboutToBeInserted(index, 0, childCount);
       
   568             rowsInserted(index, 0, childCount);
       
   569         } else {
       
   570             rowsAboutToBeRemoved(index, 0, childCount);
       
   571             rowsRemoved(index, 0, childCount);
       
   572         }
       
   573 
       
   574         HbTreeViewItem *item = qobject_cast<HbTreeViewItem *>(itemByIndex(index));
       
   575         if (item) {
       
   576             item->setExpanded(expanded);
       
   577         } 
       
   578 
       
   579         d->mInSetExpanded = false;
   502     }
   580     }
   503 }
   581 }
   504 
   582 
   505 /*!
   583 /*!
   506     Returns true if the model item \a index is expanded; otherwise returns false.
   584     Returns true if the model item \a index is expanded; otherwise returns false.
   509 */
   587 */
   510 bool HbTreeView::isExpanded(const QModelIndex &index) const
   588 bool HbTreeView::isExpanded(const QModelIndex &index) const
   511 {
   589 {
   512     Q_D(const HbTreeView);
   590     Q_D(const HbTreeView);
   513 
   591 
   514     HbTreeItemContainer *container = qobject_cast<HbTreeItemContainer *>(d->mContainer);
   592     QVariant flags = d->mContainer->itemTransientState(index).value("expanded");
   515     return container->isExpanded(index);
   593     if (flags.isValid() && flags.toBool() == true) {
       
   594         return true;
       
   595     } else {
       
   596         return false;
       
   597     }
   516 }
   598 }
   517 /*!
   599 /*!
   518     Overrides default indentation of tree view items defined in style sheet.
   600     Overrides default indentation of tree view items defined in style sheet.
   519     Items, which are not immediate children of root item are indented by
   601     Items, which are not immediate children of root item are indented by
   520     indentation * level pixels. 
   602     indentation * level pixels. 
   562     HbAbstractItemView::setRootIndex(index);
   644     HbAbstractItemView::setRootIndex(index);
   563     setExpanded(index, true); 
   645     setExpanded(index, true); 
   564 }
   646 }
   565 
   647 
   566 /*!
   648 /*!
   567     This function handles expanding and collapsing parent items in tree view. 
       
   568     Parent item expands and collapses, when pressed down is released
       
   569     exluding following use cases:
       
   570     \li HbTreeViewItem::selectionAreaContains() has returned true for pressed down
       
   571     \li view is panned or scrolled 
       
   572 
       
   573     \sa HbTreeViewItem::selectionAreaContains() 
       
   574 */
       
   575 void HbTreeView::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
       
   576 {
       
   577     Q_D(HbTreeView);
       
   578 
       
   579     HbTreeViewItem* hitItem = qobject_cast<HbTreeViewItem*>(d->itemAt(event->scenePos()));
       
   580 
       
   581     // check whether expansion collapsion can be done
       
   582     if (    d->mHitItem
       
   583         &&  d->mHitItem == hitItem
       
   584         &&  hitItem->primitive(HbStyle::P_TreeViewItem_expandicon)
       
   585         &&  hitItem->flags().testFlag(QGraphicsItem::ItemIsFocusable)
       
   586         &&  !d->mWasScrolling
       
   587         &&  (   d->mSelectionMode == SingleSelection
       
   588             || !d->mSelectionSettings.testFlag(HbAbstractItemViewPrivate::Selection))) {
       
   589         Hb::InteractionModifiers modifiers = 0;
       
   590         if (hitItem->isExpanded()) {
       
   591             d->mInstantClickedModifiers |= Hb::ModifierExpandedItem;
       
   592         } else {
       
   593             d->mInstantClickedModifiers |= Hb::ModifierCollapsedItem;
       
   594         }
       
   595         hitItem->setExpanded(!hitItem->isExpanded());
       
   596     }
       
   597 
       
   598     HbAbstractItemView::mouseReleaseEvent(event);
       
   599 }
       
   600 
       
   601 /*!
       
   602     \reimp
   649     \reimp
   603     Tree view has its internal selection model. Implementation of this virtual function is needed
   650     Tree view has its internal selection model. Implementation of this virtual function is needed
   604     to take it into use with new model..
   651     to take it into use with new model..
   605 */
   652 */
   606 void HbTreeView::setModel(QAbstractItemModel *model, HbAbstractViewItem *prototype)
   653 void HbTreeView::setModel(QAbstractItemModel *model, HbAbstractViewItem *prototype)