Changeset 561 for trunk/src/gui/itemviews/qtreeview.cpp
- Timestamp:
- Feb 11, 2010, 11:19:06 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk
-
Property svn:mergeinfo
set to (toggle deleted branches)
/branches/vendor/nokia/qt/4.6.1 merged eligible /branches/vendor/nokia/qt/current merged eligible /branches/vendor/trolltech/qt/current 3-149
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
trunk/src/gui/itemviews/qtreeview.cpp
r2 r561 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information (qt-info@nokia.com) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation (qt-info@nokia.com) 5 6 ** 6 7 ** This file is part of the QtGui module of the Qt Toolkit. … … 21 22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. 22 23 ** 23 ** In addition, as a special exception, Nokia gives you certain 24 ** additional rights. These rights are described in the Nokia Qt LGPL 25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this 26 ** package. 24 ** In addition, as a special exception, Nokia gives you certain additional 25 ** rights. These rights are described in the Nokia Qt LGPL Exception 26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. 27 27 ** 28 28 ** GNU General Public License Usage … … 34 34 ** met: http://www.gnu.org/copyleft/gpl.html. 35 35 ** 36 ** If you are unsure which license is appropriate for your use, please37 ** contact the sales department at qt-sales@nokia.com.36 ** If you have questions regarding the use of this file, please contact 37 ** Nokia at qt-info@nokia.com. 38 38 ** $QT_END_LICENSE$ 39 39 ** … … 67 67 \ingroup model-view 68 68 \ingroup advanced 69 \mainclass 69 70 70 71 71 A QTreeView implements a tree representation of items from a … … 216 216 if (model == d->model) 217 217 return; 218 if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) { 219 disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)), 220 this, SLOT(rowsRemoved(QModelIndex,int,int))); 221 222 disconnect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_modelAboutToBeReset())); 223 } 224 218 225 if (d->selectionModel) { // support row editing 219 226 disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)), … … 239 246 this, SLOT(rowsRemoved(QModelIndex,int,int))); 240 247 241 connect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),242 this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int)));243 connect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),244 this, SLOT(_q_columnsRemoved(QModelIndex,int,int)));245 246 248 connect(d->model, SIGNAL(modelAboutToBeReset()), SLOT(_q_modelAboutToBeReset())); 247 249 248 250 if (d->sortingEnabled) 249 sortByColumn(header()->sortIndicatorSection(), header()->sortIndicatorOrder());251 d->_q_sortIndicatorChanged(header()->sortIndicatorSection(), header()->sortIndicatorOrder()); 250 252 } 251 253 … … 268 270 Q_ASSERT(selectionModel); 269 271 if (d->selectionModel) { 270 if (d->allColumnsShowFocus) {271 QObject::disconnect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),272 this, SLOT(_q_currentChanged(QModelIndex,QModelIndex)));273 }274 272 // support row editing 275 273 disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)), … … 281 279 282 280 if (d->selectionModel) { 283 if (d->allColumnsShowFocus) {284 QObject::connect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),285 this, SLOT(_q_currentChanged(QModelIndex,QModelIndex)));286 }287 281 // support row editing 288 282 connect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)), … … 681 675 // since QAbstractItemView::dataChanged() will get the visualRect for the items anyway 682 676 683 QModelIndex top = topLeft.sibling(topLeft.row(), 0); 684 int topViewIndex = d->viewIndex(top); 677 int topViewIndex = d->viewIndex(topLeft); 685 678 if (topViewIndex == 0) 686 d->defaultItemHeight = indexRowSizeHint(top );679 d->defaultItemHeight = indexRowSizeHint(topLeft); 687 680 bool sizeChanged = false; 688 681 if (topViewIndex != -1) { … … 692 685 sizeChanged = (oldHeight != d->itemHeight(topViewIndex)); 693 686 } else { 694 QModelIndex bottom = bottomRight.sibling(bottomRight.row(), 0); 695 int bottomViewIndex = d->viewIndex(bottom); 687 int bottomViewIndex = d->viewIndex(bottomRight); 696 688 for (int i = topViewIndex; i <= bottomViewIndex; ++i) { 697 689 int oldHeight = d->itemHeight(i); … … 847 839 { 848 840 Q_D(QTreeView); 849 d->sortingEnabled = enable;850 841 header()->setSortIndicatorShown(enable); 851 842 header()->setClickable(enable); 852 843 if (enable) { 844 //sortByColumn has to be called before we connect or set the sortingEnabled flag 845 // because otherwise it will not call sort on the model. 846 sortByColumn(header()->sortIndicatorSection(), header()->sortIndicatorOrder()); 853 847 connect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), 854 this, SLOT(_q_sortIndicatorChanged(int, Qt::SortOrder))); 855 sortByColumn(header()->sortIndicatorSection(), header()->sortIndicatorOrder()); 848 this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)), Qt::UniqueConnection); 856 849 } else { 857 850 disconnect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), 858 this, SLOT(_q_sortIndicatorChanged(int, Qt::SortOrder))); 859 } 851 this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder))); 852 } 853 d->sortingEnabled = enable; 860 854 } 861 855 … … 907 901 if (d->allColumnsShowFocus == enable) 908 902 return; 909 if (d->selectionModel) {910 if (enable) {911 QObject::connect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),912 this, SLOT(_q_currentChanged(QModelIndex,QModelIndex)));913 } else {914 QObject::disconnect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),915 this, SLOT(_q_currentChanged(QModelIndex,QModelIndex)));916 }917 }918 903 d->allColumnsShowFocus = enable; 919 904 d->viewport->update(); … … 1118 1103 verticalScrollBar()->setValue(item); 1119 1104 } else { // PositionAtBottom or PositionAtCenter 1120 int itemLocation = item;1105 const int currentItemHeight = d->itemHeight(item); 1121 1106 int y = (hint == PositionAtCenter 1122 ? area.height() / 2 1107 //we center on the current item with a preference to the top item (ie. -1) 1108 ? area.height() / 2 + currentItemHeight - 1 1109 //otherwise we simply take the whole space 1123 1110 : area.height()); 1124 while (y > 0 && item > 0) 1125 y -= d->itemHeight(item--); 1126 // end up half over the top of the area 1127 if (y < 0 && item < itemLocation) 1128 ++item; 1129 // end up half over the bottom of the area 1130 if (item >= 0 && item < itemLocation) 1131 ++item; 1111 if (y > currentItemHeight) { 1112 while (item >= 0) { 1113 y -= d->itemHeight(item); 1114 if (y < 0) { //there is no more space left 1115 item++; 1116 break; 1117 } 1118 item--; 1119 } 1120 } 1132 1121 verticalScrollBar()->setValue(item); 1133 1122 } … … 1141 1130 // nothing to do 1142 1131 } else if (hint == EnsureVisible && area.contains(rect)) { 1143 d-> setDirtyRegion(rect);1132 d->viewport->update(rect); 1144 1133 // nothing to do 1145 1134 } else { … … 1245 1234 QRect oldRect = visualRect(oldIndex); 1246 1235 QRect newRect = visualRect(newIndex); 1247 viewport()->update(oldRect.left() - d->indent, oldRect.top(), d->indent, oldRect.height()); 1248 viewport()->update(newRect.left() - d->indent, newRect.top(), d->indent, newRect.height()); 1236 oldRect.setLeft(oldRect.left() - d->indent); 1237 newRect.setLeft(newRect.left() - d->indent); 1238 //we need to paint the whole items (including the decoration) so that when the user 1239 //moves the mouse over those elements they are updated 1240 viewport()->update(oldRect); 1241 viewport()->update(newRect); 1249 1242 } 1250 1243 } … … 1273 1266 d->executePostedLayout(); 1274 1267 QPainter painter(viewport()); 1268 #ifndef QT_NO_ANIMATION 1275 1269 if (d->isAnimating()) { 1276 drawTree(&painter, event->region() - d->animat ionRect());1270 drawTree(&painter, event->region() - d->animatedOperation.rect()); 1277 1271 d->drawAnimatedOperation(&painter); 1278 } else { 1272 } else 1273 #endif //QT_NO_ANIMATION 1274 { 1279 1275 drawTree(&painter, event->region()); 1280 1276 #ifndef QT_NO_DRAGANDDROP … … 1312 1308 Q_Q(QTreeView); 1313 1309 // we want to handle mousePress in EditingState (persistent editors) 1314 if (( q->state()!= QAbstractItemView::NoState1315 && q->state()!= QAbstractItemView::EditingState)1310 if ((state != QAbstractItemView::NoState 1311 && state != QAbstractItemView::EditingState) 1316 1312 || !viewport->rect().contains(pos)) 1317 1313 return true; 1318 1314 1319 1315 int i = itemDecorationAt(pos); 1320 if ((i != -1) && q->itemsExpandable()&& hasVisibleChildren(viewItems.at(i).index)) {1316 if ((i != -1) && itemsExpandable && hasVisibleChildren(viewItems.at(i).index)) { 1321 1317 if (viewItems.at(i).expanded) 1322 1318 collapse(i, true); … … 1325 1321 if (!isAnimating()) { 1326 1322 q->updateGeometries(); 1327 q->viewport()->update();1323 viewport->update(); 1328 1324 } 1329 1325 return true; … … 1339 1335 QAbstractItemViewPrivate::_q_modelDestroyed(); 1340 1336 } 1337 1338 /*! 1339 \reimp 1340 1341 We have a QTreeView way of knowing what elements are on the viewport 1342 */ 1343 QItemViewPaintPairs QTreeViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const 1344 { 1345 Q_ASSERT(r); 1346 return QAbstractItemViewPrivate::draggablePaintPairs(indexes, r); 1347 Q_Q(const QTreeView); 1348 QRect &rect = *r; 1349 const QRect viewportRect = viewport->rect(); 1350 int itemOffset = 0; 1351 int row = firstVisibleItem(&itemOffset); 1352 QPair<int, int> startEnd = startAndEndColumns(viewportRect); 1353 QVector<int> columns; 1354 for (int i = startEnd.first; i <= startEnd.second; ++i) { 1355 int logical = header->logicalIndex(i); 1356 if (!header->isSectionHidden(logical)) 1357 columns += logical; 1358 } 1359 QSet<QModelIndex> visibleIndexes; 1360 for (; itemOffset < viewportRect.bottom() && row < viewItems.count(); ++row) { 1361 const QModelIndex &index = viewItems.at(row).index; 1362 for (int colIndex = 0; colIndex < columns.count(); ++colIndex) 1363 visibleIndexes += index.sibling(index.row(), columns.at(colIndex)); 1364 itemOffset += itemHeight(row); 1365 } 1366 1367 //now that we have the visible indexes, we can try to find those which are selected 1368 QItemViewPaintPairs ret; 1369 for (int i = 0; i < indexes.count(); ++i) { 1370 const QModelIndex &index = indexes.at(i); 1371 if (visibleIndexes.contains(index)) { 1372 const QRect current = q->visualRect(index); 1373 ret += qMakePair(current, index); 1374 rect |= current; 1375 } 1376 } 1377 rect &= viewportRect; 1378 return ret; 1379 } 1380 1341 1381 1342 1382 /*! … … 1394 1434 const int itemHeight = d->itemHeight(i); 1395 1435 option.rect.setRect(0, y, viewportWidth, itemHeight); 1396 option.state = state | (viewItems.at(i).expanded 1397 ? QStyle::State_Open : QStyle::State_None); 1436 option.state = state | (viewItems.at(i).expanded ? QStyle::State_Open : QStyle::State_None) 1437 | (viewItems.at(i).hasChildren ? QStyle::State_Children : QStyle::State_None) 1438 | (viewItems.at(i).hasMoreSiblings ? QStyle::State_Sibling : QStyle::State_None); 1398 1439 d->current = i; 1399 1440 d->spanning = viewItems.at(i).spanning; … … 1547 1588 : logicalIndices.at(currentLogicalSection - 1); 1548 1589 if (columnCount == 1 || (nextLogicalSection == 0 && prevLogicalSection == -1) 1549 || (headerSection == 0 && nextLogicalSection == -1) )1590 || (headerSection == 0 && nextLogicalSection == -1) || spanning) 1550 1591 opt.viewItemPosition = QStyleOptionViewItemV4::OnlyOne; 1551 1592 else if (headerSection == 0 || (nextLogicalSection != 0 && prevLogicalSection == -1)) … … 1720 1761 1721 1762 const bool expanded = viewItem.expanded; 1722 const bool children = (((expanded && viewItem.total > 0)) // already laid out and has children 1723 || d->hasVisibleChildren(index)); // not laid out yet, so we don't know 1724 bool moreSiblings = false; 1725 if (d->hiddenIndexes.isEmpty()) 1726 moreSiblings = (d->model->rowCount(parent) - 1 > index.row()); 1727 else 1728 moreSiblings = ((d->viewItems.size() > item +1) 1729 && (d->viewItems.at(item + 1).index.parent() == parent)); 1763 const bool children = viewItem.hasChildren; 1764 bool moreSiblings = viewItem.hasMoreSiblings; 1730 1765 1731 1766 opt.state = QStyle::State_Item | extraFlags … … 1816 1851 return; // user clicked outside the items 1817 1852 1818 const QModelIndex &index = d->viewItems.at(i).index; 1819 1820 int column = d->header->logicalIndexAt(event->x()); 1821 QPersistentModelIndex persistent = index.sibling(index.row(), column); 1853 const QPersistentModelIndex firstColumnIndex = d->viewItems.at(i).index; 1854 const QPersistentModelIndex persistent = indexAt(event->pos()); 1822 1855 1823 1856 if (d->pressedIndex != persistent) { … … 1842 1875 && d->expandsOnDoubleClick 1843 1876 && d->hasVisibleChildren(persistent)) { 1844 if (!((i < d->viewItems.count()) && (d->viewItems.at(i).index == persistent))) {1877 if (!((i < d->viewItems.count()) && (d->viewItems.at(i).index == firstColumnIndex))) { 1845 1878 // find the new index of the item 1846 1879 for (i = 0; i < d->viewItems.count(); ++i) { 1847 if (d->viewItems.at(i).index == persistent)1880 if (d->viewItems.at(i).index == firstColumnIndex) 1848 1881 break; 1849 1882 } … … 2073 2106 int index = useTopIndex ? INT_MAX : INT_MIN; 2074 2107 const QItemSelection selection = d->selectionModel->selection(); 2075 foreach (const QItemSelectionRange &range, selection) { 2108 for (int i = 0; i < selection.count(); ++i) { 2109 const QItemSelectionRange &range = selection.at(i); 2076 2110 int candidate = d->viewIndex(useTopIndex ? range.topLeft() : range.bottomRight()); 2077 2111 if (candidate >= 0) … … 2087 2121 vi = qMax(0, d->viewIndex(current)); 2088 2122 2123 if (isRightToLeft()) { 2124 if (cursorAction == MoveRight) 2125 cursorAction = MoveLeft; 2126 else if (cursorAction == MoveLeft) 2127 cursorAction = MoveRight; 2128 } 2089 2129 switch (cursorAction) { 2090 2130 case MoveNext: … … 2408 2448 } 2409 2449 2410 if (parent != d->root && !d->isIndexExpanded(parent) && d->model->rowCount(parent) > (end - start) + 1) { 2450 const int parentRowCount = d->model->rowCount(parent); 2451 const int delta = end - start + 1; 2452 if (parent != d->root && !d->isIndexExpanded(parent) && parentRowCount > delta) { 2411 2453 QAbstractItemView::rowsInserted(parent, start, end); 2412 2454 return; … … 2423 2465 : d->viewItems.at(parentItem).total) - 1; 2424 2466 2425 int firstColumn = 0; 2426 while (isColumnHidden(firstColumn) && firstColumn < header()->count() - 1) 2427 ++firstColumn; 2428 2429 const int delta = end - start + 1; 2467 if (parentRowCount == end + 1 && start > 0) { 2468 //need to Update hasMoreSiblings 2469 int previousRow = start - 1; 2470 QModelIndex previousSibilingModelIndex = d->model->index(previousRow, 0, parent); 2471 bool isHidden = d->isRowHidden(previousSibilingModelIndex); 2472 while (isHidden && previousRow > 0) { 2473 previousRow--; 2474 previousSibilingModelIndex = d->model->index(previousRow, 0, parent); 2475 isHidden = d->isRowHidden(previousSibilingModelIndex); 2476 } 2477 if (!isHidden) { 2478 const int previousSibilling = d->viewIndex(previousSibilingModelIndex); 2479 if(previousSibilling != -1) 2480 d->viewItems[previousSibilling].hasMoreSiblings = true; 2481 } 2482 } 2483 2430 2484 QVector<QTreeViewItem> insertedItems(delta); 2431 2485 for (int i = 0; i < delta; ++i) { 2432 insertedItems[i].index = d->model->index(i + start, firstColumn, parent);2486 insertedItems[i].index = d->model->index(i + start, 0, parent); 2433 2487 insertedItems[i].level = childLevel; 2488 insertedItems[i].hasChildren = d->hasVisibleChildren(insertedItems[i].index); 2489 insertedItems[i].hasMoreSiblings = !((i == delta - 1) && (parentRowCount == end +1)); 2434 2490 } 2435 2491 if (d->viewItems.isEmpty()) … … 2473 2529 } 2474 2530 2531 if (parentItem != -1) 2532 d->viewItems[parentItem].hasChildren = true; 2475 2533 d->updateChildCount(parentItem, delta); 2534 2476 2535 updateGeometries(); 2477 2536 viewport()->update(); … … 2479 2538 d->doDelayedItemsLayout(); 2480 2539 } else if (parentItem != -1 && (d->model->rowCount(parent) == end - start + 1)) { 2481 // the parent just went from 0 children to having some update to re-paint the decoration 2540 // the parent just went from 0 children to more. update to re-paint the decoration 2541 d->viewItems[parentItem].hasChildren = true; 2482 2542 viewport()->update(); 2483 2543 } … … 2613 2673 d->layout(i); 2614 2674 QModelIndex idx = d->viewItems.at(i).index; 2615 d->expandedIndexes.insert(idx .sibling(idx.row(), 0));2675 d->expandedIndexes.insert(idx); 2616 2676 } 2617 2677 updateGeometries(); … … 2715 2775 if (d->viewItems.isEmpty()) 2716 2776 return -1; 2777 ensurePolished(); 2717 2778 int w = 0; 2718 2779 QStyleOptionViewItemV4 option = d->viewOptionsV4(); … … 2772 2833 if (isRightToLeft()) { 2773 2834 start = (start == -1 ? count - 1 : start); 2774 end = (end == -1 ? 0 : end);2835 end = 0; 2775 2836 } else { 2776 2837 start = (start == -1 ? 0 : start); 2777 end = (end == -1 ? count - 1 : end); 2778 } 2779 2780 int tmp = start; 2781 start = qMin(start, end); 2782 end = qMax(tmp, end); 2838 end = count - 1; 2839 } 2840 2841 if (end < start) 2842 qSwap(end, start); 2783 2843 2784 2844 int height = -1; … … 2828 2888 2829 2889 /*! 2830 \ reimp2890 \internal 2831 2891 */ 2832 2892 void QTreeView::horizontalScrollbarAction(int action) … … 2860 2920 header->setDefaultAlignment(Qt::AlignLeft|Qt::AlignVCenter); 2861 2921 q->setHeader(header); 2862 2863 // animation 2864 QObject::connect(&timeline, SIGNAL(frameChanged(int)), q, SLOT(_q_animate())); 2865 QObject::connect(&timeline, SIGNAL(finished()), q, SLOT(_q_endAnimatedOperation()), Qt::QueuedConnection); 2922 #ifndef QT_NO_ANIMATION 2923 QObject::connect(&animatedOperation, SIGNAL(finished()), q, SLOT(_q_endAnimatedOperation())); 2924 #endif //QT_NO_ANIMATION 2866 2925 } 2867 2926 … … 2873 2932 return; 2874 2933 2934 #ifndef QT_NO_ANIMATION 2875 2935 if (emitSignal && animationsEnabled) 2876 prepareAnimatedOperation(item, AnimatedOperation::Expand);2877 2878 QAbstractItemView::State oldState = q->state();2936 prepareAnimatedOperation(item, QVariantAnimation::Forward); 2937 #endif //QT_NO_ANIMATION 2938 QAbstractItemView::State oldState = state; 2879 2939 q->setState(QAbstractItemView::ExpandingState); 2880 2940 const QModelIndex index = viewItems.at(item).index; … … 2884 2944 q->setState(oldState); 2885 2945 2946 if (model->canFetchMore(index)) 2947 model->fetchMore(index); 2886 2948 if (emitSignal) { 2887 2949 emit q->expanded(index); 2950 #ifndef QT_NO_ANIMATION 2888 2951 if (animationsEnabled) 2889 2952 beginAnimatedOperation(); 2890 } 2891 if (model->canFetchMore(index)) 2892 model->fetchMore(index); 2953 #endif //QT_NO_ANIMATION 2954 } 2893 2955 } 2894 2956 … … 2911 2973 return; // nothing to do 2912 2974 2975 #ifndef QT_NO_ANIMATION 2913 2976 if (emitSignal && animationsEnabled) 2914 prepareAnimatedOperation(item, AnimatedOperation::Collapse); 2915 2916 QAbstractItemView::State oldState = q->state(); 2977 prepareAnimatedOperation(item, QVariantAnimation::Backward); 2978 #endif //QT_NO_ANIMATION 2979 2980 QAbstractItemView::State oldState = state; 2917 2981 q->setState(QAbstractItemView::CollapsingState); 2918 2982 expandedIndexes.erase(it); … … 2931 2995 if (emitSignal) { 2932 2996 emit q->collapsed(modelIndex); 2997 #ifndef QT_NO_ANIMATION 2933 2998 if (animationsEnabled) 2934 2999 beginAnimatedOperation(); 2935 } 2936 } 2937 2938 void QTreeViewPrivate::prepareAnimatedOperation(int item, AnimatedOperation::Type type) 3000 #endif //QT_NO_ANIMATION 3001 } 3002 } 3003 3004 #ifndef QT_NO_ANIMATION 3005 void QTreeViewPrivate::prepareAnimatedOperation(int item, QVariantAnimation::Direction direction) 2939 3006 { 2940 3007 animatedOperation.item = item; 2941 animatedOperation.type = type; 3008 animatedOperation.viewport = viewport; 3009 animatedOperation.setDirection(direction); 2942 3010 2943 3011 int top = coordinateForItem(item) + itemHeight(item); 2944 3012 QRect rect = viewport->rect(); 2945 3013 rect.setTop(top); 2946 if ( type == AnimatedOperation::Collapse) {3014 if (direction == QVariantAnimation::Backward) { 2947 3015 const int limit = rect.height() * 2; 2948 3016 int h = 0; … … 2951 3019 h += itemHeight(i); 2952 3020 rect.setHeight(h); 2953 animatedOperation. duration = h;2954 } 2955 animatedOperation. top = top;3021 animatedOperation.setEndValue(top + h); 3022 } 3023 animatedOperation.setStartValue(top); 2956 3024 animatedOperation.before = renderTreeToPixmapForAnimation(rect); 2957 3025 } … … 2962 3030 2963 3031 QRect rect = viewport->rect(); 2964 rect.setTop(animatedOperation.top );2965 if (animatedOperation. type == AnimatedOperation::Expand) {3032 rect.setTop(animatedOperation.top()); 3033 if (animatedOperation.direction() == QVariantAnimation::Forward) { 2966 3034 const int limit = rect.height() * 2; 2967 3035 int h = 0; … … 2970 3038 h += itemHeight(i); 2971 3039 rect.setHeight(h); 2972 animatedOperation.duration = h; 2973 } 2974 2975 animatedOperation.after = renderTreeToPixmapForAnimation(rect); 2976 2977 q->setState(QAbstractItemView::AnimatingState); 2978 2979 timeline.stop(); 2980 timeline.setDuration(250); 2981 timeline.setFrameRange(animatedOperation.top, animatedOperation.top + animatedOperation.duration); 2982 timeline.start(); 2983 } 2984 2985 void QTreeViewPrivate::_q_endAnimatedOperation() 2986 { 2987 Q_Q(QTreeView); 2988 animatedOperation.before = QPixmap(); 2989 animatedOperation.after = QPixmap(); 2990 q->setState(QAbstractItemView::NoState); 2991 q->updateGeometries(); 2992 viewport->update(); 2993 } 2994 2995 void QTreeViewPrivate::_q_animate() 2996 { 2997 QRect rect = viewport->rect(); 2998 rect.moveTop(animatedOperation.top); 2999 viewport->repaint(rect); 3040 animatedOperation.setEndValue(animatedOperation.top() + h); 3041 } 3042 3043 if (!rect.isEmpty()) { 3044 animatedOperation.after = renderTreeToPixmapForAnimation(rect); 3045 3046 q->setState(QAbstractItemView::AnimatingState); 3047 animatedOperation.start(); //let's start the animation 3048 } 3000 3049 } 3001 3050 3002 3051 void QTreeViewPrivate::drawAnimatedOperation(QPainter *painter) const 3003 3052 { 3004 int start = timeline.startFrame();3005 int end = timeline.endFrame();3006 bool collapsing = animatedOperation.type == AnimatedOperation::Collapse;3007 int current = collapsing ? end - timeline.currentFrame() + start : timeline.currentFrame();3053 const int start = animatedOperation.startValue().toInt(), 3054 end = animatedOperation.endValue().toInt(), 3055 current = animatedOperation.currentValue().toInt(); 3056 bool collapsing = animatedOperation.direction() == QVariantAnimation::Backward; 3008 3057 const QPixmap top = collapsing ? animatedOperation.before : animatedOperation.after; 3009 3058 painter->drawPixmap(0, start, top, 0, end - current - 1, top.width(), top.height()); … … 3048 3097 } 3049 3098 3050 void QTreeViewPrivate::_q_ currentChanged(const QModelIndex ¤t, const QModelIndex &previous)3099 void QTreeViewPrivate::_q_endAnimatedOperation() 3051 3100 { 3052 3101 Q_Q(QTreeView); 3053 if (previous.isValid()) { 3054 QRect previousRect = q->visualRect(previous); 3055 if (allColumnsShowFocus) { 3056 previousRect.setX(0); 3057 previousRect.setWidth(viewport->width()); 3058 } 3059 viewport->update(previousRect); 3060 } 3061 if (current.isValid()) { 3062 QRect currentRect = q->visualRect(current); 3063 if (allColumnsShowFocus) { 3064 currentRect.setX(0); 3065 currentRect.setWidth(viewport->width()); 3066 } 3067 viewport->update(currentRect); 3068 } 3069 } 3102 q->setState(QAbstractItemView::NoState); 3103 q->updateGeometries(); 3104 viewport->update(); 3105 } 3106 #endif //QT_NO_ANIMATION 3070 3107 3071 3108 void QTreeViewPrivate::_q_modelAboutToBeReset() … … 3076 3113 void QTreeViewPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end) 3077 3114 { 3078 Q_UNUSED(parent);3079 3115 if (start <= 0 && 0 <= end) 3080 3116 viewItems.clear(); 3117 QAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(parent, start, end); 3081 3118 } 3082 3119 3083 3120 void QTreeViewPrivate::_q_columnsRemoved(const QModelIndex &parent, int start, int end) 3084 3121 { 3085 Q_UNUSED(parent);3086 3122 if (start <= 0 && 0 <= end) 3087 3123 doDelayedItemsLayout(); 3124 QAbstractItemViewPrivate::_q_columnsRemoved(parent, start, end); 3088 3125 } 3089 3126 … … 3093 3130 QModelIndex current; 3094 3131 QModelIndex parent = (i < 0) ? (QModelIndex)root : modelIndex(i); 3095 // modelIndex() will return an index that don't have a parent if column 0 is hidden,3096 // so we must make sure that parent points to the actual parent that has children.3097 if (parent != root)3098 parent = model->index(parent.row(), 0, parent.parent());3099 3132 3100 3133 if (i>=0 && !parent.isValid()) { … … 3130 3163 int last = 0; 3131 3164 int children = 0; 3132 3133 int firstColumn = 0; 3134 while (header->isSectionHidden(firstColumn) && firstColumn < header->count()) 3135 ++firstColumn; 3136 3165 QTreeViewItem *item = 0; 3137 3166 for (int j = first; j < first + count; ++j) { 3138 current = model->index(j - first, firstColumn, parent);3139 if (isRowHidden(current .sibling(current.row(), 0))) {3167 current = model->index(j - first, 0, parent); 3168 if (isRowHidden(current)) { 3140 3169 ++hidden; 3141 3170 last = j - hidden + children; 3142 3171 } else { 3143 3172 last = j - hidden + children; 3144 viewItems[last].index = current; 3145 viewItems[last].level = level; 3146 viewItems[last].height = 0; 3147 viewItems[last].spanning = q->isFirstColumnSpanned(current.row(), parent); 3148 viewItems[last].expanded = false; 3149 viewItems[last].total = 0; 3173 if (item) 3174 item->hasMoreSiblings = true; 3175 item = &viewItems[last]; 3176 item->index = current; 3177 item->level = level; 3178 item->height = 0; 3179 item->spanning = q->isFirstColumnSpanned(current.row(), parent); 3180 item->expanded = false; 3181 item->total = 0; 3182 item->hasMoreSiblings = false; 3150 3183 if (isIndexExpanded(current)) { 3151 viewItems[last].expanded = true;3184 item->expanded = true; 3152 3185 layout(last); 3153 children += viewItems[last].total; 3186 item = &viewItems[last]; 3187 children += item->total; 3188 item->hasChildren = item->total > 0; 3154 3189 last = j - hidden + children; 3190 } else { 3191 item->hasChildren = hasVisibleChildren(current); 3155 3192 } 3156 3193 } … … 3218 3255 int QTreeViewPrivate::coordinateForItem(int item) const 3219 3256 { 3220 Q_Q(const QTreeView);3221 3257 if (verticalScrollMode == QAbstractItemView::ScrollPerPixel) { 3222 3258 if (uniformRowHeights) 3223 return (item * defaultItemHeight) - q->verticalScrollBar()->value();3259 return (item * defaultItemHeight) - vbar->value(); 3224 3260 // ### optimize (spans or caching) 3225 3261 int y = 0; 3226 3262 for (int i = 0; i < viewItems.count(); ++i) { 3227 3263 if (i == item) 3228 return y - q->verticalScrollBar()->value();3264 return y - vbar->value(); 3229 3265 y += itemHeight(i); 3230 3266 } 3231 3267 } else { // ScrollPerItem 3232 int topViewItemIndex = q->verticalScrollBar()->value();3268 int topViewItemIndex = vbar->value(); 3233 3269 if (uniformRowHeights) 3234 3270 return defaultItemHeight * (item - topViewItemIndex); … … 3270 3306 int QTreeViewPrivate::itemAtCoordinate(int coordinate) const 3271 3307 { 3272 Q_Q(const QTreeView);3273 3308 const int itemCount = viewItems.count(); 3274 3309 if (itemCount == 0) … … 3278 3313 if (verticalScrollMode == QAbstractItemView::ScrollPerPixel) { 3279 3314 if (uniformRowHeights) { 3280 const int viewItemIndex = (coordinate + q->verticalScrollBar()->value()) / defaultItemHeight;3315 const int viewItemIndex = (coordinate + vbar->value()) / defaultItemHeight; 3281 3316 return ((viewItemIndex >= itemCount || viewItemIndex < 0) ? -1 : viewItemIndex); 3282 3317 } 3283 3318 // ### optimize 3284 3319 int viewItemCoordinate = 0; 3285 const int contentsCoordinate = coordinate + q->verticalScrollBar()->value();3320 const int contentsCoordinate = coordinate + vbar->value(); 3286 3321 for (int viewItemIndex = 0; viewItemIndex < viewItems.count(); ++viewItemIndex) { 3287 3322 viewItemCoordinate += itemHeight(viewItemIndex); … … 3290 3325 } 3291 3326 } else { // ScrollPerItem 3292 int topViewItemIndex = q->verticalScrollBar()->value();3327 int topViewItemIndex = vbar->value(); 3293 3328 if (uniformRowHeights) { 3294 3329 if (coordinate < 0) … … 3320 3355 int QTreeViewPrivate::viewIndex(const QModelIndex &_index) const 3321 3356 { 3322 Q_Q(const QTreeView);3323 3357 if (!_index.isValid() || viewItems.isEmpty()) 3324 3358 return -1; 3325 3359 3326 3360 const int totalCount = viewItems.count(); 3327 int firstColumn = 0; 3328 while (q->isColumnHidden(firstColumn) && firstColumn < header->count()) 3329 ++firstColumn; 3330 const QModelIndex index = _index.sibling(_index.row(), firstColumn); 3361 const QModelIndex index = _index.sibling(_index.row(), 0); 3331 3362 3332 3363 … … 3386 3417 int QTreeViewPrivate::firstVisibleItem(int *offset) const 3387 3418 { 3388 Q_Q(const QTreeView); 3389 const int value = q->verticalScrollBar()->value(); 3419 const int value = vbar->value(); 3390 3420 if (verticalScrollMode == QAbstractItemView::ScrollPerItem) { 3391 3421 if (offset) … … 3464 3494 if (!viewItems.isEmpty()) 3465 3495 itemsInViewport = qMax(1, itemsInViewport); 3466 q->verticalScrollBar()->setRange(0, viewItems.count() - itemsInViewport);3467 q->verticalScrollBar()->setPageStep(itemsInViewport);3468 q->verticalScrollBar()->setSingleStep(1);3496 vbar->setRange(0, viewItems.count() - itemsInViewport); 3497 vbar->setPageStep(itemsInViewport); 3498 vbar->setSingleStep(1); 3469 3499 } else { // scroll per pixel 3470 3500 int contentsHeight = 0; … … 3475 3505 contentsHeight += itemHeight(i); 3476 3506 } 3477 q->verticalScrollBar()->setRange(0, contentsHeight - viewportSize.height());3478 q->verticalScrollBar()->setPageStep(viewportSize.height());3479 q->verticalScrollBar()->setSingleStep(qMax(viewportSize.height() / (itemsInViewport + 1), 2));3507 vbar->setRange(0, contentsHeight - viewportSize.height()); 3508 vbar->setPageStep(viewportSize.height()); 3509 vbar->setSingleStep(qMax(viewportSize.height() / (itemsInViewport + 1), 2)); 3480 3510 } 3481 3511 … … 3493 3523 columnsInViewport = qMax(1, columnsInViewport); 3494 3524 if (horizontalScrollMode == QAbstractItemView::ScrollPerItem) { 3495 q->horizontalScrollBar()->setRange(0, columnCount - columnsInViewport);3496 q->horizontalScrollBar()->setPageStep(columnsInViewport);3497 q->horizontalScrollBar()->setSingleStep(1);3525 hbar->setRange(0, columnCount - columnsInViewport); 3526 hbar->setPageStep(columnsInViewport); 3527 hbar->setSingleStep(1); 3498 3528 } else { // scroll per pixel 3499 3529 const int horizontalLength = header->length(); 3500 3530 const QSize maxSize = q->maximumViewportSize(); 3501 if (maxSize.width() >= horizontalLength && q->verticalScrollBar()->maximum() <= 0)3531 if (maxSize.width() >= horizontalLength && vbar->maximum() <= 0) 3502 3532 viewportSize = maxSize; 3503 q->horizontalScrollBar()->setPageStep(viewportSize.width());3504 q->horizontalScrollBar()->setRange(0, qMax(horizontalLength - viewportSize.width(), 0));3505 q->horizontalScrollBar()->setSingleStep(qMax(viewportSize.width() / (columnsInViewport + 1), 2));3533 hbar->setPageStep(viewportSize.width()); 3534 hbar->setRange(0, qMax(horizontalLength - viewportSize.width(), 0)); 3535 hbar->setSingleStep(qMax(viewportSize.width() / (columnsInViewport + 1), 2)); 3506 3536 } 3507 3537 } … … 3509 3539 int QTreeViewPrivate::itemDecorationAt(const QPoint &pos) const 3510 3540 { 3511 const_cast<QTreeView *>(q_func())->executeDelayedItemsLayout();3541 executePostedLayout(); 3512 3542 int x = pos.x(); 3513 3543 int column = header->logicalIndexAt(x); … … 3575 3605 current.first = -2; // -1 is not enough because -1+1 = 0 3576 3606 current.second = -2; 3577 foreach (int logicalColumn, logicalIndexes) { 3607 for(int i = 0; i < logicalIndexes.count(); ++i) { 3608 const int logicalColumn = logicalIndexes.at(i); 3578 3609 if (current.second + 1 != logicalColumn) { 3579 3610 if (current.first != -2) { … … 3714 3745 const int delta = end - start + 1; 3715 3746 3747 int previousSibiling = -1; 3716 3748 int removedCount = 0; 3717 3749 for (int item = firstChildItem; item <= lastChildItem; ) { … … 3721 3753 const int count = viewItems.at(item).total + 1; 3722 3754 if (modelIndex.row() < start) { 3755 previousSibiling = item; 3723 3756 // not affected by the removal 3724 3757 item += count; … … 3738 3771 } 3739 3772 3773 if (previousSibiling != -1 && after && model->rowCount(parent) == start) 3774 viewItems[previousSibiling].hasMoreSiblings = false; 3775 3776 3740 3777 updateChildCount(parentItem, -removedCount); 3778 if (parentItem != -1 && viewItems.at(parentItem).total == 0) 3779 viewItems[parentItem].hasChildren = false; //every children have been removed; 3741 3780 if (after) { 3742 3781 q->updateGeometries(); … … 3810 3849 #endif 3811 3850 QAbstractItemView::currentChanged(current, previous); 3851 3852 if (allColumnsShowFocus()) { 3853 if (previous.isValid()) { 3854 QRect previousRect = visualRect(previous); 3855 previousRect.setX(0); 3856 previousRect.setWidth(viewport()->width()); 3857 viewport()->update(previousRect); 3858 } 3859 if (current.isValid()) { 3860 QRect currentRect = visualRect(current); 3861 currentRect.setX(0); 3862 currentRect.setWidth(viewport()->width()); 3863 viewport()->update(currentRect); 3864 } 3865 } 3812 3866 } 3813 3867
Note:
See TracChangeset
for help on using the changeset viewer.