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) |