Changeset 561 for trunk/src/gui/itemviews/qlistview.cpp
- Timestamp:
- Feb 11, 2010, 11:19:06 PM (16 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
src/gui/itemviews/qlistview.cpp (modified) (89 diffs)
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/qlistview.cpp
r2 r561 1 /*************************************************************************** 1 /*************************************************************************** 2 2 ** 3 3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). 4 ** Contact: Qt Software Information ([email protected]) 4 ** All rights reserved. 5 ** Contact: Nokia Corporation ([email protected]) 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 37 ** @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 QListView presents items stored in a model, either as a simple … … 358 358 /*! 359 359 \property QListView::spacing 360 \brief the space betweenitems in the layout360 \brief the space items in the layout 361 361 362 362 This property is the size of the empty space that is padded around … … 459 459 { 460 460 Q_D(QListView); 461 462 461 463 d->viewMode = mode; 462 464 465 463 466 if (mode == ListMode) { 464 delete d->dynamicListView; 465 d->dynamicListView = 0; 466 if (!d->staticListView) 467 d->staticListView = new QStaticListViewBase(this, d); 467 d->commonListView = new QListModeViewBase(this, d); 468 468 if (!(d->modeProperties & QListViewPrivate::Wrap)) 469 469 d->setWrapping(false); … … 481 481 d->showElasticBand = false; 482 482 } else { 483 delete d->staticListView; 484 d->staticListView = 0; 485 if (!d->dynamicListView) 486 d->dynamicListView = new QDynamicListViewBase(this, d); 483 d->commonListView = new QIconModeViewBase(this, d); 487 484 if (!(d->modeProperties & QListViewPrivate::Wrap)) 488 485 d->setWrapping(true); … … 548 545 Q_D(QListView); 549 546 const bool hidden = d->isHidden(row); 550 if (d->viewMode == ListMode) { 551 if (hide && !hidden) 552 d->hiddenRows.append(d->model->index(row, 0)); 553 else if (!hide && hidden) 554 d->hiddenRows.remove(d->hiddenRows.indexOf(d->model->index(row, 0))); 555 d->doDelayedItemsLayout(); 556 } else { 557 if (hide && !hidden) { 558 d->dynamicListView->removeItem(row); 559 d->hiddenRows.append(d->model->index(row, 0)); 560 } else if (!hide && hidden) { 561 d->hiddenRows.remove(d->hiddenRows.indexOf(d->model->index(row, 0))); 562 d->dynamicListView->insertItem(row); 563 } 564 if (d->resizeMode == Adjust) 565 d->doDelayedItemsLayout(); 566 d->viewport->update(); 567 } 547 if (hide && !hidden) 548 d->commonListView->appendHiddenRow(row); 549 else if (!hide && hidden) 550 d->commonListView->removeHiddenRow(row); 551 d->doDelayedItemsLayout(); 552 d->viewport->update(); 568 553 } 569 554 … … 574 559 { 575 560 Q_D(const QListView); 576 return d->mapToViewport(rectForIndex(index) , d->viewMode == QListView::ListMode);561 return d->mapToViewport(rectForIndex(index)); 577 562 } 578 563 … … 589 574 const QRect rect = visualRect(index); 590 575 if (hint == EnsureVisible && d->viewport->rect().contains(rect)) { 591 d-> setDirtyRegion(rect);576 d->(rect); 592 577 return; 593 578 } … … 611 596 ? rect.right() > area.right() 612 597 : (rect.right() > area.right()) && (rect.left() > area.left()); 613 int horizontalValue = q->horizontalScrollBar()->value(); 614 615 // ScrollPerItem 616 if (q->horizontalScrollMode() == QAbstractItemView::ScrollPerItem && viewMode == QListView::ListMode) { 617 const QListViewItem item = indexToListViewItem(index); 618 const QRect rect = q->visualRect(index); 619 horizontalValue = staticListView->horizontalPerItemValue(itemIndex(item), 620 horizontalValue, area.width(), 621 leftOf, rightOf, isWrapping(), hint, rect.width()); 622 } else { // ScrollPerPixel 623 if (q->isRightToLeft()) { 624 if (hint == QListView::PositionAtCenter) { 625 horizontalValue += ((area.width() - rect.width()) / 2) - rect.left(); 626 } else { 627 if (leftOf) 628 horizontalValue -= rect.left(); 629 else if (rightOf) 630 horizontalValue += qMin(rect.left(), area.width() - rect.right()); 631 } 632 } else { 633 if (hint == QListView::PositionAtCenter) { 634 horizontalValue += rect.left() - ((area.width()- rect.width()) / 2); 635 } else { 636 if (leftOf) 637 horizontalValue += rect.left(); 638 else if (rightOf) 639 horizontalValue += qMin(rect.left(), rect.right() - area.width()); 640 } 641 } 642 } 643 return horizontalValue; 598 return commonListView->horizontalScrollToValue(q->visualIndex(index), hint, leftOf, rightOf, area, rect); 644 599 } 645 600 … … 648 603 { 649 604 Q_Q(const QListView); 650 651 605 const QRect area = viewport->rect(); 652 606 const bool above = (hint == QListView::EnsureVisible && rect.top() < area.top()); 653 607 const bool below = (hint == QListView::EnsureVisible && rect.bottom() > area.bottom()); 654 655 int verticalValue = q->verticalScrollBar()->value(); 656 657 // ScrollPerItem 658 if (q->verticalScrollMode() == QAbstractItemView::ScrollPerItem && viewMode == QListView::ListMode) { 659 const QListViewItem item = indexToListViewItem(index); 660 const QRect rect = q->visualRect(index); 661 verticalValue = staticListView->verticalPerItemValue(itemIndex(item), 662 verticalValue, area.height(), 663 above, below, isWrapping(), hint, rect.height()); 664 665 } else { // ScrollPerPixel 666 QRect adjusted = rect.adjusted(-spacing(), -spacing(), spacing(), spacing()); 667 if (hint == QListView::PositionAtTop || above) 668 verticalValue += adjusted.top(); 669 else if (hint == QListView::PositionAtBottom || below) 670 verticalValue += qMin(adjusted.top(), adjusted.bottom() - area.height() + 1); 671 else if (hint == QListView::PositionAtCenter) 672 verticalValue += adjusted.top() - ((area.height() - adjusted.height()) / 2); 673 } 674 675 return verticalValue; 608 return commonListView->verticalScrollToValue(q->visualIndex(index), hint, above, below, area, rect); 676 609 } 677 610 … … 710 643 } 711 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 712 670 713 671 /*! … … 740 698 Scroll the view contents by \a dx and \a dy. 741 699 */ 700 742 701 void QListView::scrollContentsBy(int dx, int dy) 743 702 { 744 703 Q_D(QListView); 745 746 704 d->delayedAutoScroll.stop(); // auto scroll was canceled by the user scrolling 747 748 if (d->viewMode == ListMode) 749 d->staticListView->scrollContentsBy(dx, dy); 750 else if (state() == DragSelectingState) 751 d->scrollElasticBandBy(isRightToLeft() ? -dx : dx, dy); 752 753 d->scrollContentsBy(isRightToLeft() ? -dx : dx, dy); 754 755 // update the dragged items 756 if (d->viewMode == IconMode) // ### move to dynamic class 757 if (!d->dynamicListView->draggedItems.isEmpty()) 758 d->setDirtyRegion(d->dynamicListView->draggedItemsRect().translated(dx, dy)); 705 d->commonListView->scrollContentsBy(dx, dy, d->state == QListView::DragSelectingState); 759 706 } 760 707 … … 785 732 void QListView::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) 786 733 { 787 Q_D(QListView); 788 if (d->viewMode == IconMode) 789 d->dynamicListView->dataChanged(topLeft, bottomRight); 734 d_func()->commonListView->dataChanged(topLeft, bottomRight); 790 735 QAbstractItemView::dataChanged(topLeft, bottomRight); 791 736 } … … 828 773 void QListView::mouseMoveEvent(QMouseEvent *e) 829 774 { 775 776 830 777 Q_D(QListView); 831 778 QAbstractItemView::mouseMoveEvent(e); … … 836 783 QRect rect(d->pressedPosition, e->pos() + QPoint(horizontalOffset(), verticalOffset())); 837 784 rect = rect.normalized(); 838 d-> setDirtyRegion(d->mapToViewport(rect.united(d->elasticBand), d->viewMode == QListView::ListMode));785 d->)); 839 786 d->elasticBand = rect; 840 787 } … … 850 797 // #### move this implementation into a dynamic class 851 798 if (d->showElasticBand && d->elasticBand.isValid()) { 852 d-> setDirtyRegion(d->mapToViewport(d->elasticBand, d->viewMode == QListView::ListMode));799 d->)); 853 800 d->elasticBand = QRect(); 854 801 } … … 886 833 887 834 bool listWrap = (d->viewMode == ListMode) && d->wrapItemText; 888 bool flowDimensionChanged = (d->flow == LeftToRight && delta.width() != 0) 889 || (d->flow == TopToBottom && delta.height() != 0);835 bool flowDimensionChanged = (d->flow == LeftToRight && delta.width() != 0) 836 || (d->flow == TopToBottom && delta.height() != 0); 890 837 891 838 // We post a delayed relayout in the following cases : 892 839 // - we're wrapping 893 840 // - the state is NoState, we're adjusting and the size has changed in the flowing direction 894 if (listWrap 841 if (listWrap 895 842 || (state() == NoState && d->resizeMode == Adjust && flowDimensionChanged)) { 896 d->doDelayedItemsLayout(100); // wait 1/10 sec before starting the layout897 } else { 843 d->doDelayedItemsLayout(100); // wait 1/10 sec before starting the layout 844 } else { 898 845 QAbstractItemView::resizeEvent(e); 899 846 } … … 907 854 void QListView::dragMoveEvent(QDragMoveEvent *e) 908 855 { 909 // ### move implementation to dynamic 910 Q_D(QListView); 911 if (e->source() == this && d->viewMode == IconMode) { 912 // the ignore by default 913 e->ignore(); 914 if (d->canDecode(e)) { 915 // get old dragged items rect 916 QRect itemsRect = d->dynamicListView->itemsRect(d->dynamicListView->draggedItems); 917 d->setDirtyRegion(itemsRect.translated(d->dynamicListView->draggedItemsDelta())); 918 // update position 919 d->dynamicListView->draggedItemsPos = e->pos(); 920 // get new items rect 921 d->setDirtyRegion(itemsRect.translated(d->dynamicListView->draggedItemsDelta())); 922 // set the item under the cursor to current 923 QModelIndex index; 924 if (d->movement == Snap) { 925 QRect rect(d->dynamicListView->snapToGrid(e->pos() + d->offset()), d->gridSize()); 926 d->intersectingSet(rect); 927 index = d->intersectVector.count() > 0 928 ? d->intersectVector.last() : QModelIndex(); 929 } else { 930 index = indexAt(e->pos()); 931 } 932 // check if we allow drops here 933 if (e->source() == this && d->dynamicListView->draggedItems.contains(index)) 934 e->accept(); // allow changing item position 935 else if (d->model->flags(index) & Qt::ItemIsDropEnabled) 936 e->accept(); // allow dropping on dropenabled items 937 else if (!index.isValid()) 938 e->accept(); // allow dropping in empty areas 939 } 940 // do autoscrolling 941 if (d->shouldAutoScroll(e->pos())) 942 startAutoScroll(); 943 } else { // not internal 944 QAbstractItemView::dragMoveEvent(e); 945 } 946 } 856 Q_D(QListView); 857 if (!d->commonListView->filterDragMoveEvent(e)) { 858 if (viewMode() == QListView::ListMode && flow() == QListView::LeftToRight) 859 static_cast<QListModeViewBase *>(d->commonListView)->dragMoveEvent(e); 860 else 861 QAbstractItemView::dragMoveEvent(e); 862 } 863 } 864 947 865 948 866 /*! … … 951 869 void QListView::dragLeaveEvent(QDragLeaveEvent *e) 952 870 { 953 // ### move implementation to dynamic 954 Q_D(QListView); 955 if (d->viewMode == IconMode) { 956 d->viewport->update(d->dynamicListView->draggedItemsRect()); // erase the area 957 d->dynamicListView->draggedItemsPos = QPoint(-1, -1); // don't draw the dragged items 958 } 959 QAbstractItemView::dragLeaveEvent(e); 871 if (!d_func()->commonListView->filterDragLeaveEvent(e)) 872 QAbstractItemView::dragLeaveEvent(e); 960 873 } 961 874 … … 963 876 \reimp 964 877 */ 965 void QListView::dropEvent(QDropEvent *event) 966 { 967 Q_D(QListView); 968 if (event->source() == this && d->viewMode == IconMode) 969 internalDrop(event); // ### move to dynamic 970 else 971 QAbstractItemView::dropEvent(event); 878 void QListView::dropEvent(QDropEvent *e) 879 { 880 if (!d_func()->commonListView->filterDropEvent(e)) 881 QAbstractItemView::dropEvent(e); 972 882 } 973 883 … … 977 887 void QListView::startDrag(Qt::DropActions supportedActions) 978 888 { 979 Q_D(QListView); 980 if (d->viewMode == IconMode) // ### move to dynamic 981 internalDrag(supportedActions); 982 else 889 if (!d_func()->commonListView->filterStartDrag(supportedActions)) 983 890 QAbstractItemView::startDrag(supportedActions); 984 891 } … … 992 899 void QListView::internalDrop(QDropEvent *event) 993 900 { 994 Q_D(QListView); 995 if (d->viewMode == QListView::ListMode) 996 return; 997 998 // ### move to dynamic class 999 QPoint offset(horizontalOffset(), verticalOffset()); 1000 QPoint end = event->pos() + offset; 1001 QPoint start = d->pressedPosition; 1002 QPoint delta = (d->movement == Snap ? 1003 d->dynamicListView->snapToGrid(end) 1004 - d->dynamicListView->snapToGrid(start) : end - start); 1005 QSize contents = d->contentsSize(); 1006 QList<QModelIndex> indexes = d->selectionModel->selectedIndexes(); 1007 for (int i = 0; i < indexes.count(); ++i) { 1008 QModelIndex index = indexes.at(i); 1009 QRect rect = rectForIndex(index); 1010 d->setDirtyRegion(d->mapToViewport(rect, d->viewMode == QListView::ListMode)); 1011 QPoint dest = rect.topLeft() + delta; 1012 if (isRightToLeft()) 1013 dest.setX(d->flipX(dest.x()) - rect.width()); 1014 d->dynamicListView->moveItem(index.row(), dest); 1015 d->setDirtyRegion(visualRect(index)); 1016 } 1017 stopAutoScroll(); 1018 d->dynamicListView->draggedItems.clear(); 1019 emit indexesMoved(indexes); 1020 event->accept(); // we have handled the event 1021 // if the size has not grown, we need to check if it has shrinked 1022 if (d->dynamicListView 1023 && (d->contentsSize().width() <= contents.width() 1024 || d->contentsSize().height() <= contents.height())) { 1025 d->dynamicListView->updateContentsSize(); 1026 } 1027 if (d->contentsSize() != contents) 1028 updateGeometries(); 901 // ### Qt5: remove that function 902 Q_UNUSED(event); 1029 903 } 1030 904 … … 1037 911 void QListView::internalDrag(Qt::DropActions supportedActions) 1038 912 { 1039 Q_D(QListView); 1040 if (d->viewMode == QListView::ListMode) 1041 return; 1042 1043 // #### move to dynamic class 1044 1045 // This function does the same thing as in QAbstractItemView::startDrag(), 1046 // plus adding viewitems to the draggedItems list. 1047 // We need these items to draw the drag items 1048 QModelIndexList indexes = d->selectionModel->selectedIndexes(); 1049 if (indexes.count() > 0 ) { 1050 if (d->viewport->acceptDrops()) { 1051 QModelIndexList::ConstIterator it = indexes.constBegin(); 1052 for (; it != indexes.constEnd(); ++it) 1053 if (d->model->flags(*it) & Qt::ItemIsDragEnabled 1054 && (*it).column() == d->column) 1055 d->dynamicListView->draggedItems.push_back(*it); 1056 } 1057 QDrag *drag = new QDrag(this); 1058 drag->setMimeData(d->model->mimeData(indexes)); 1059 Qt::DropAction action = drag->exec(supportedActions, Qt::CopyAction); 1060 d->dynamicListView->draggedItems.clear(); 1061 if (action == Qt::MoveAction) 1062 d->clearOrRemove(); 1063 } 913 // ### Qt5: remove that function 914 Q_UNUSED(supportedActions); 1064 915 } 1065 916 … … 1089 940 } 1090 941 942 1091 943 /*! 1092 944 \reimp … … 1099 951 QStyleOptionViewItemV4 option = d->viewOptionsV4(); 1100 952 QPainter painter(d->viewport); 1101 QRect area = e->rect(); 1102 1103 QVector<QModelIndex> toBeRendered; 1104 // QVector<QRect> rects = e->region().rects(); 1105 // for (int i = 0; i < rects.size(); ++i) { 1106 // d->intersectingSet(rects.at(i).translated(horizontalOffset(), verticalOffset())); 1107 // toBeRendered += d->intersectVector; 1108 // } 1109 d->intersectingSet(e->rect().translated(horizontalOffset(), verticalOffset()), false); 1110 toBeRendered = d->intersectVector; 953 954 const QVector<QModelIndex> toBeRendered = d->intersectingSet(e->rect().translated(horizontalOffset(), verticalOffset()), false); 1111 955 1112 956 const QModelIndex current = currentIndex(); … … 1123 967 int previousRow = -2; // trigger the alternateBase adjustment on first pass 1124 968 969 970 971 972 1125 973 QVector<QModelIndex>::const_iterator end = toBeRendered.constEnd(); 1126 974 for (QVector<QModelIndex>::const_iterator it = toBeRendered.constBegin(); it != end; ++it) { 1127 975 Q_ASSERT((*it).isValid()); 1128 976 option.rect = visualRect(*it); 977 978 979 980 981 982 1129 983 option.state = state; 1130 984 if (selections && selections->isSelected(*it)) … … 1193 1047 1194 1048 #ifndef QT_NO_DRAGANDDROP 1195 // #### move this implementation into a dynamic class 1196 if (d->viewMode == IconMode) 1197 if (!d->dynamicListView->draggedItems.isEmpty() 1198 && d->viewport->rect().contains(d->dynamicListView->draggedItemsPos)) { 1199 QPoint delta = d->dynamicListView->draggedItemsDelta(); 1200 painter.translate(delta.x(), delta.y()); 1201 d->dynamicListView->drawItems(&painter, d->dynamicListView->draggedItems); 1202 } 1203 // FIXME: Until the we can provide a proper drop indicator 1204 // in IconMode, it makes no sense to show it 1205 if (d->viewMode == ListMode) 1206 d->paintDropIndicator(&painter); 1049 d->commonListView->paintDragDrop(&painter); 1207 1050 #endif 1208 1051 … … 1230 1073 Q_D(const QListView); 1231 1074 QRect rect(p.x() + horizontalOffset(), p.y() + verticalOffset(), 1, 1); 1232 d->intersectingSet(rect);1233 QModelIndex index = d->intersectVector.count() > 01234 ? d->intersectVector.last() : QModelIndex();1075 d->intersectingSet(rect); 1076 QModelIndex index = intersectVector.count() > 0 1077 ? intersectVector.last() : QModelIndex(); 1235 1078 if (index.isValid() && visualRect(index).contains(p)) 1236 1079 return index; … … 1243 1086 int QListView::horizontalOffset() const 1244 1087 { 1245 Q_D(const QListView); 1246 // ### split into static and dynamic 1247 if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem && d->viewMode == ListMode) { 1248 if (d->isWrapping()) { 1249 if (d->flow == TopToBottom && !d->staticListView->segmentPositions.isEmpty()) { 1250 const int max = d->staticListView->segmentPositions.count() - 1; 1251 int currentValue = qBound(0, horizontalScrollBar()->value(), max); 1252 int position = d->staticListView->segmentPositions.at(currentValue); 1253 int maximumValue = qBound(0, horizontalScrollBar()->maximum(), max); 1254 int maximum = d->staticListView->segmentPositions.at(maximumValue); 1255 return (isRightToLeft() ? maximum - position : position); 1256 } 1257 //return 0; 1258 } else { 1259 if (d->flow == LeftToRight && !d->staticListView->flowPositions.isEmpty()) { 1260 int position = d->staticListView->flowPositions.at(horizontalScrollBar()->value()); 1261 int maximum = d->staticListView->flowPositions.at(horizontalScrollBar()->maximum()); 1262 return (isRightToLeft() ? maximum - position : position); 1263 } 1264 //return 0; 1265 } 1266 } 1267 return (isRightToLeft() 1268 ? horizontalScrollBar()->maximum() - horizontalScrollBar()->value() 1269 : horizontalScrollBar()->value()); 1088 return d_func()->commonListView->horizontalOffset(); 1270 1089 } 1271 1090 … … 1275 1094 int QListView::verticalOffset() const 1276 1095 { 1277 // ## split into static and dynamic 1278 Q_D(const QListView); 1279 if (verticalScrollMode() == QAbstractItemView::ScrollPerItem && d->viewMode == ListMode) { 1280 if (d->isWrapping()) { 1281 if (d->flow == LeftToRight && !d->staticListView->segmentPositions.isEmpty()) { 1282 int value = verticalScrollBar()->value(); 1283 if (value >= d->staticListView->segmentPositions.count()) { 1284 //qWarning("QListView: Vertical scroll bar is out of bounds"); 1285 return 0; 1286 } 1287 return d->staticListView->segmentPositions.at(value); 1288 } 1289 } else { 1290 if (d->flow == TopToBottom && !d->staticListView->flowPositions.isEmpty()) { 1291 int value = verticalScrollBar()->value(); 1292 if (value > d->staticListView->flowPositions.count()) { 1293 //qWarning("QListView: Vertical scroll bar is out of bounds"); 1294 return 0; 1295 } 1296 return d->staticListView->flowPositions.at(value) - d->spacing(); 1297 } 1298 } 1299 } 1300 return verticalScrollBar()->value(); 1096 return d_func()->commonListView->verticalOffset(); 1301 1097 } 1302 1098 … … 1319 1115 if (row >= rowCount) 1320 1116 return QModelIndex(); 1321 return d->model->index(row, 0, d->root);1117 return d->model->index(row, , d->root); 1322 1118 } 1323 1119 … … 1325 1121 QRect rect = initialRect; 1326 1122 if (rect.isEmpty()) { 1327 return d->model->index(0, 0, d->root);1123 return d->model->index(0, , d->root); 1328 1124 } 1329 1125 if (d->gridSize().isValid()) rect.setSize(d->gridSize()); 1330 1126 1331 1127 QSize contents = d->contentsSize(); 1332 d->intersectVector.clear();1128 ; 1333 1129 1334 1130 switch (cursorAction) { 1335 1131 case MoveLeft: 1336 while ( d->intersectVector.isEmpty()) {1132 while (intersectVector.isEmpty()) { 1337 1133 rect.translate(-rect.width(), 0); 1338 1134 if (rect.right() <= 0) … … 1340 1136 if (rect.left() < 0) 1341 1137 rect.setLeft(0); 1342 d->intersectingSet(rect);1343 d->removeCurrentAndDisabled(& d->intersectVector, current);1344 } 1345 return d->closestIndex(initialRect, d->intersectVector);1138 d->intersectingSet(rect); 1139 d->removeCurrentAndDisabled(&intersectVector, current); 1140 } 1141 return d->closestIndex(initialRect, intersectVector); 1346 1142 case MoveRight: 1347 while ( d->intersectVector.isEmpty()) {1143 while (intersectVector.isEmpty()) { 1348 1144 rect.translate(rect.width(), 0); 1349 1145 if (rect.left() >= contents.width()) … … 1351 1147 if (rect.right() > contents.width()) 1352 1148 rect.setRight(contents.width()); 1353 d->intersectingSet(rect);1354 d->removeCurrentAndDisabled(& d->intersectVector, current);1355 } 1356 return d->closestIndex(initialRect, d->intersectVector);1149 d->intersectingSet(rect); 1150 d->removeCurrentAndDisabled(&intersectVector, current); 1151 } 1152 return d->closestIndex(initialRect, intersectVector); 1357 1153 case MovePageUp: 1358 rect.moveTop(rect.top() - d->viewport->height()); 1154 // move current by (visibileRowCount - 1) items. 1155 // rect.translate(0, -rect.height()); will happen in the switch fallthrough for MoveUp. 1156 rect.moveTop(rect.top() - d->viewport->height() + 2 * rect.height()); 1359 1157 if (rect.top() < rect.height()) 1360 1158 rect.moveTop(rect.height()); 1361 1159 case MovePrevious: 1362 1160 case MoveUp: 1363 while ( d->intersectVector.isEmpty()) {1161 while (intersectVector.isEmpty()) { 1364 1162 rect.translate(0, -rect.height()); 1365 1163 if (rect.bottom() <= 0) { … … 1377 1175 if (rect.top() < 0) 1378 1176 rect.setTop(0); 1379 d->intersectingSet(rect);1380 d->removeCurrentAndDisabled(& d->intersectVector, current);1381 } 1382 return d->closestIndex(initialRect, d->intersectVector);1177 d->intersectingSet(rect); 1178 d->removeCurrentAndDisabled(&intersectVector, current); 1179 } 1180 return d->closestIndex(initialRect, intersectVector); 1383 1181 case MovePageDown: 1384 rect.moveTop(rect.top() + d->viewport->height()); 1182 // move current by (visibileRowCount - 1) items. 1183 // rect.translate(0, rect.height()); will happen in the switch fallthrough for MoveDown. 1184 rect.moveTop(rect.top() + d->viewport->height() - 2 * rect.height()); 1385 1185 if (rect.bottom() > contents.height() - rect.height()) 1386 1186 rect.moveBottom(contents.height() - rect.height()); 1387 1187 case MoveNext: 1388 1188 case MoveDown: 1389 while ( d->intersectVector.isEmpty()) {1189 while (intersectVector.isEmpty()) { 1390 1190 rect.translate(0, rect.height()); 1391 1191 if (rect.top() >= contents.height()) { … … 1404 1204 if (rect.bottom() > contents.height()) 1405 1205 rect.setBottom(contents.height()); 1406 d->intersectingSet(rect);1407 d->removeCurrentAndDisabled(& d->intersectVector, current);1408 } 1409 return d->closestIndex(initialRect, d->intersectVector);1206 d->intersectingSet(rect); 1207 d->removeCurrentAndDisabled(&intersectVector, current); 1208 } 1209 return d->closestIndex(initialRect, intersectVector); 1410 1210 case MoveHome: 1411 1211 return d->model->index(0, d->column, d->root); … … 1424 1224 QRect QListView::rectForIndex(const QModelIndex &index) const 1425 1225 { 1426 Q_D(const QListView); 1427 if (!d->isIndexValid(index) 1428 || index.parent() != d->root 1429 || index.column() != d->column 1430 || isIndexHidden(index)) 1431 return QRect(); 1432 d->executePostedLayout(); 1433 QListViewItem item = d->indexToListViewItem(index); 1434 return d->viewItemRect(item); 1226 return d_func()->rectForIndex(index); 1435 1227 } 1436 1228 … … 1440 1232 Sets the contents position of the item at \a index in the model to the given 1441 1233 \a position. 1442 If the list view's movement mode is Static , this function will have no1443 effect.1234 If the list view's movement mode is Static 1235 effect. 1444 1236 */ 1445 1237 void QListView::setPositionForIndex(const QPoint &position, const QModelIndex &index) … … 1453 1245 1454 1246 d->executePostedLayout(); 1455 if (index.row() >= d->dynamicListView->items.count()) 1456 return; 1457 const QSize oldContents = d->contentsSize(); 1458 d->setDirtyRegion(visualRect(index)); // update old position 1459 d->dynamicListView->moveItem(index.row(), position); 1460 d->setDirtyRegion(visualRect(index)); // update new position 1461 1462 if (d->contentsSize() != oldContents) 1463 updateGeometries(); // update the scroll bars 1247 d->commonListView->setPositionForIndex(position, index); 1464 1248 } 1465 1249 … … 1482 1266 1483 1267 if (rect.width() == 1 && rect.height() == 1) { 1484 d->intersectingSet(rect.translated(horizontalOffset(), verticalOffset()));1268 d->intersectingSet(rect.translated(horizontalOffset(), verticalOffset())); 1485 1269 QModelIndex tl; 1486 if (! d->intersectVector.isEmpty())1487 tl = d->intersectVector.last(); // special case for mouse press; only select the top item1270 if (!intersectVector.isEmpty()) 1271 tl = intersectVector.last(); // special case for mouse press; only select the top item 1488 1272 if (tl.isValid() && d->isIndexEnabled(tl)) 1489 1273 selection.select(tl, tl); … … 1495 1279 // get the first item 1496 1280 const QRect topLeft(rect.left() + horizontalOffset(), rect.top() + verticalOffset(), 1, 1); 1497 d->intersectingSet(topLeft);1498 if (! d->intersectVector.isEmpty())1499 tl = d->intersectVector.last();1281 d->intersectingSet(topLeft); 1282 if (!intersectVector.isEmpty()) 1283 tl = intersectVector.last(); 1500 1284 // get the last item 1501 1285 const QRect bottomRight(rect.right() + horizontalOffset(), rect.bottom() + verticalOffset(), 1, 1); 1502 d->intersectingSet(bottomRight);1503 if (! d->intersectVector.isEmpty())1504 br = d->intersectVector.last();1286 d->intersectingSet(bottomRight); 1287 if (!intersectVector.isEmpty()) 1288 br = intersectVector.last(); 1505 1289 1506 1290 // get the ranges … … 1545 1329 // middle rectangle 1546 1330 if (top.bottom() < bottom.top()) { 1547 middle.setTop(top.bottom() + 1); 1331 if (gridSize().isValid() && !gridSize().isNull()) 1332 middle.setTop(top.top() + gridSize().height()); 1333 else 1334 middle.setTop(top.bottom() + 1); 1548 1335 middle.setLeft(qMin(top.left(), bottom.left())); 1549 1336 middle.setBottom(bottom.top() - 1); … … 1572 1359 middle.setTop(0); 1573 1360 middle.setBottom(ch); 1574 middle.setLeft(left.right() + 1); 1361 if (gridSize().isValid() && !gridSize().isNull()) 1362 middle.setLeft(left.left() + gridSize().width()); 1363 else 1364 middle.setLeft(left.right() + 1); 1575 1365 middle.setRight(right.left() - 1); 1576 1366 } else if (left.bottom() < right.top()) { … … 1609 1399 continue; 1610 1400 QModelIndex parent = selection.at(i).topLeft().parent(); 1401 1402 1403 1404 1611 1405 int t = selection.at(i).topLeft().row(); 1612 1406 int b = selection.at(i).bottomRight().row(); … … 1617 1411 while (t <= b && d->isHidden(t)) ++t; 1618 1412 while (b >= t && d->isHidden(b)) --b; 1619 const QModelIndex top = d->model->index(t, c, d->root);1620 const QModelIndex bottom = d->model->index(b, c, d->root);1413 const QModelIndex top = d->model->index(t, c, t); 1414 const QModelIndex bottom = d->model->index(b, c, t); 1621 1415 QRect rect(visualRect(top).topLeft(), 1622 1416 visualRect(bottom).bottomRight()); … … 1634 1428 { 1635 1429 Q_D(const QListView); 1636 QModelIndexList viewSelected;1637 QModelIndexList modelSelected;1638 if (d->selectionModel) 1639 modelSelected = d->selectionModel->selectedIndexes();1640 for (int i = 0; i < modelSelected.count(); ++i) {1641 QModelIndex index = modelSelected.at(i);1430 1431 ; 1432 1433 Selected = d->selectionModel->selectedIndexes(); 1434 for (int i = 0; i < Selected.count(); ++i) { 1435 Selected.at(i); 1642 1436 if (!isIndexHidden(index) && index.parent() == d->root && index.column() == d->column) 1643 viewSelected.append(index); 1437 ++i; 1438 else 1439 viewSelected.removeAt(i); 1644 1440 } 1645 1441 return viewSelected; … … 1658 1454 // triggering another layout 1659 1455 QAbstractItemView::State oldState = state(); 1660 setState(ExpandingState); 1456 setState(ExpandingState); 1661 1457 if (d->model->columnCount(d->root) > 0) { // no columns means no contents 1662 1458 d->resetBatchStartRow(); … … 1685 1481 QStyleOptionViewItemV4 option = d->viewOptionsV4(); 1686 1482 QSize step = d->itemSize(option, index); 1687 1688 QSize csize = d->contentsSize(); 1689 QSize vsize = d->viewport->size(); 1690 QSize max = maximumViewportSize(); 1691 if (max.width() >= d->contentsSize().width() && max.height() >= d->contentsSize().height()) 1692 vsize = max; 1693 1694 // ### reorder the logic 1695 1696 // ### split into static and dynamic 1697 1698 const bool vertical = verticalScrollMode() == QAbstractItemView::ScrollPerItem; 1699 const bool horizontal = horizontalScrollMode() == QAbstractItemView::ScrollPerItem; 1700 1701 if (d->flow == TopToBottom) { 1702 if (horizontal && d->isWrapping() && d->viewMode == ListMode) { 1703 const QVector<int> segmentPositions = d->staticListView->segmentPositions; 1704 const int steps = segmentPositions.count() - 1; 1705 if (steps > 0) { 1706 int pageSteps = d->staticListView->perItemScrollingPageSteps(vsize.width(), 1707 csize.width(), 1708 isWrapping()); 1709 horizontalScrollBar()->setSingleStep(1); 1710 horizontalScrollBar()->setPageStep(pageSteps); 1711 horizontalScrollBar()->setRange(0, steps - pageSteps); 1712 } else { 1713 horizontalScrollBar()->setRange(0, 0); 1714 } 1715 } else { 1716 horizontalScrollBar()->setSingleStep(step.width() + d->spacing()); 1717 horizontalScrollBar()->setPageStep(vsize.width()); 1718 horizontalScrollBar()->setRange(0, d->contentsSize().width() - vsize.width()); 1719 } 1720 if (vertical && !d->isWrapping() && d->viewMode == ListMode) { 1721 const QVector<int> flowPositions = d->staticListView->flowPositions; 1722 const int steps = flowPositions.count() - 1; 1723 if (steps > 0) { 1724 int pageSteps = d->staticListView->perItemScrollingPageSteps(vsize.height(), 1725 csize.height(), 1726 isWrapping()); 1727 verticalScrollBar()->setSingleStep(1); 1728 verticalScrollBar()->setPageStep(pageSteps); 1729 verticalScrollBar()->setRange(0, steps - pageSteps); 1730 } else { 1731 verticalScrollBar()->setRange(0, 0); 1732 } 1733 // } else if (vertical && d->isWrapping() && d->movement == Static) { 1734 // ### wrapped scrolling in flow direction 1735 } else { 1736 verticalScrollBar()->setSingleStep(step.height() + d->spacing()); 1737 verticalScrollBar()->setPageStep(vsize.height()); 1738 verticalScrollBar()->setRange(0, d->contentsSize().height() - vsize.height()); 1739 } 1740 } else { // LeftToRight 1741 if (horizontal && !d->isWrapping() && d->viewMode == ListMode) { 1742 const QVector<int> flowPositions = d->staticListView->flowPositions; 1743 int steps = flowPositions.count() - 1; 1744 if (steps > 0) { 1745 int pageSteps = d->staticListView->perItemScrollingPageSteps(vsize.width(), 1746 csize.width(), 1747 isWrapping()); 1748 horizontalScrollBar()->setSingleStep(1); 1749 horizontalScrollBar()->setPageStep(pageSteps); 1750 horizontalScrollBar()->setRange(0, steps - pageSteps); 1751 } else { 1752 horizontalScrollBar()->setRange(0, 0); 1753 } 1754 // } else if (horizontal && d->isWrapping() && d->movement == Static) { 1755 // ### wrapped scrolling in flow direction 1756 } else { 1757 horizontalScrollBar()->setSingleStep(step.width() + d->spacing()); 1758 horizontalScrollBar()->setPageStep(vsize.width()); 1759 horizontalScrollBar()->setRange(0, d->contentsSize().width() - vsize.width()); 1760 } 1761 if (vertical && d->isWrapping() && d->viewMode == ListMode) { 1762 const QVector<int> segmentPositions = d->staticListView->segmentPositions; 1763 int steps = segmentPositions.count() - 1; 1764 if (steps > 0) { 1765 int pageSteps = d->staticListView->perItemScrollingPageSteps(vsize.height(), 1766 csize.height(), 1767 isWrapping()); 1768 verticalScrollBar()->setSingleStep(1); 1769 verticalScrollBar()->setPageStep(pageSteps); 1770 verticalScrollBar()->setRange(0, steps - pageSteps); 1771 } else { 1772 verticalScrollBar()->setRange(0, 0); 1773 } 1774 } else { 1775 verticalScrollBar()->setSingleStep(step.height() + d->spacing()); 1776 verticalScrollBar()->setPageStep(vsize.height()); 1777 verticalScrollBar()->setRange(0, d->contentsSize().height() - vsize.height()); 1778 } 1779 } 1483 d->commonListView->updateHorizontalScrollBar(step); 1484 d->commonListView->updateVerticalScrollBar(step); 1780 1485 } 1781 1486 … … 1926 1631 QListViewPrivate::QListViewPrivate() 1927 1632 : QAbstractItemViewPrivate(), 1928 dynamicListView(0), 1929 staticListView(0), 1633 commonListView(0), 1930 1634 wrap(false), 1931 1635 space(0), … … 1938 1642 column(0), 1939 1643 uniformItemSizes(false), 1940 batchSize(100) 1644 batchSize(100), 1645 showElasticBand(false) 1941 1646 { 1942 1647 } … … 1944 1649 QListViewPrivate::~QListViewPrivate() 1945 1650 { 1946 delete staticListView; 1947 delete dynamicListView; 1651 delete commonListView; 1948 1652 } 1949 1653 1950 1654 void QListViewPrivate::clear() 1951 1655 { 1952 // ### split into dynamic and static1953 1656 // initialization of data structs 1954 1657 cachedItemSize = QSize(); 1955 if (viewMode == QListView::ListMode) 1956 staticListView->clear(); 1957 else 1958 dynamicListView->clear(); 1658 commonListView->clear(); 1959 1659 } 1960 1660 … … 1965 1665 1966 1666 //take the size as if there were scrollbar in order to prevent scrollbar to blink 1967 layoutBounds = QRect(QPoint( 0,0), q->maximumViewportSize());1667 layoutBounds = QRect(QPoint(), q->maximumViewportSize()); 1968 1668 1969 1669 int frameAroundContents = 0; 1970 1670 if (q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents)) 1971 1671 frameAroundContents = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth) * 2; 1972 int verticalMargin = vbarpolicy==Qt::ScrollBarAlwaysOff ? 0 : 1973 q->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, q->verticalScrollBar()) + frameAroundContents; 1974 int horizontalMargin = hbarpolicy==Qt::ScrollBarAlwaysOff ? 0 : 1975 q->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, q->horizontalScrollBar()) + frameAroundContents; 1672 1673 // maximumViewportSize() already takes scrollbar into account if policy is 1674 // Qt::ScrollBarAlwaysOn but scrollbar extent must be deduced if policy 1675 // is Qt::ScrollBarAsNeeded 1676 int verticalMargin = vbarpolicy==Qt::ScrollBarAsNeeded 1677 ? q->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, vbar) + frameAroundContents 1678 : 0; 1679 int horizontalMargin = hbarpolicy==Qt::ScrollBarAsNeeded 1680 ? q->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, hbar) + frameAroundContents 1681 : 0; 1976 1682 1977 1683 layoutBounds.adjust(0, 0, -verticalMargin, -horizontalMargin); 1978 1684 1979 int rowCount = model->rowCount(root); 1980 int colCount = model->columnCount(root); 1981 if (colCount <= 0) 1982 rowCount = 0; // no contents 1983 if (viewMode == QListView::ListMode) { 1984 staticListView->flowPositions.resize(rowCount); 1985 } else { 1986 dynamicListView->tree.create(qMax(rowCount - hiddenRows.count(), 0)); 1987 } 1685 int rowCount = model->columnCount(root) <= 0 ? 0 : model->rowCount(root); 1686 commonListView->setRowCount(rowCount); 1988 1687 } 1989 1688 … … 1993 1692 bool QListViewPrivate::doItemsLayout(int delta) 1994 1693 { 1995 // ### split into static and dynamic1996 1694 int max = model->rowCount(root) - 1; 1997 1695 int first = batchStartRow(); 1998 1696 int last = qMin(first + delta - 1, max); 1999 1697 2000 if (max < 0 || last < first)2001 return true; // nothing to do2002 2003 1698 if (first == 0) { 2004 1699 layoutChildren(); // make sure the viewport has the right size 2005 1700 prepareItemsLayout(); 1701 1702 1703 1704 2006 1705 } 2007 1706 … … 2016 1715 info.max = max; 2017 1716 2018 if (viewMode == QListView::ListMode) 2019 return staticListView->doBatchedItemLayout(info, max); 2020 return dynamicListView->doBatchedItemLayout(info, max); 1717 return commonListView->doBatchedItemLayout(info, max); 2021 1718 } 2022 1719 … … 2026 1723 return QListViewItem(); 2027 1724 2028 if (viewMode == QListView::ListMode) 2029 return staticListView->indexToListViewItem(index); 2030 return dynamicListView->indexToListViewItem(index); 2031 } 2032 2033 2034 int QListViewPrivate::itemIndex(const QListViewItem &item) const 2035 { 2036 if (viewMode == QListView::ListMode) 2037 return staticListView->itemIndex(item); 2038 return dynamicListView->itemIndex(item); 2039 } 2040 2041 QRect QListViewPrivate::mapToViewport(const QRect &rect, bool greedy) const 1725 return commonListView->indexToListViewItem(index); 1726 } 1727 1728 QRect QListViewPrivate::mapToViewport(const QRect &rect, bool extend) const 2042 1729 { 2043 1730 Q_Q(const QListView); … … 2045 1732 return rect; 2046 1733 2047 QRect result = rect; 2048 if (greedy) 2049 result = staticListView->mapToViewport(rect); 2050 1734 QRect result = extend ? commonListView->mapToViewport(rect) : rect; 2051 1735 int dx = -q->horizontalOffset(); 2052 1736 int dy = -q->verticalOffset(); 2053 result.adjust(dx, dy, dx, dy); 2054 return result; 1737 return result.adjusted(dx, dy, dx, dy); 2055 1738 } 2056 1739 … … 2110 1793 QItemSelection selection; 2111 1794 QModelIndex tl, br; 2112 intersectingSet(rect);2113 QVector<QModelIndex>:: iterator it = intersectVector.begin();1795 intersectingSet(rect); 1796 QVector<QModelIndex>::iterator it = intersectVector.begin(); 2114 1797 for (; it != intersectVector.end(); ++it) { 2115 1798 if (!tl.isValid() && !br.isValid()) { … … 2135 1818 } 2136 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 2137 1830 /* 2138 * Static ListView Implementation 2139 */ 2140 2141 int QStaticListViewBase::verticalPerItemValue(int itemIndex, int verticalValue, int areaHeight, 2142 bool above, bool below, bool wrap, 2143 QListView::ScrollHint hint, int itemHeight) const 2144 { 2145 int value = qBound(0, verticalValue, flowPositions.count() - 1); 2146 if (above) 2147 return perItemScrollToValue(itemIndex, value, areaHeight, QListView::PositionAtTop, 2148 Qt::Vertical,wrap, itemHeight); 2149 else if (below) 2150 return perItemScrollToValue(itemIndex, value, areaHeight, QListView::PositionAtBottom, 2151 Qt::Vertical, wrap, itemHeight); 2152 else if (hint != QListView::EnsureVisible) 2153 return perItemScrollToValue(itemIndex, value, areaHeight, hint, Qt::Vertical, wrap, itemHeight); 2154 return value; 2155 } 2156 2157 int QStaticListViewBase::horizontalPerItemValue(int itemIndex, int horizontalValue, int areaWidth, 2158 bool leftOf, bool rightOf, bool wrap, 2159 QListView::ScrollHint hint, int itemWidth) const 2160 { 2161 int value = qBound(0, horizontalValue, flowPositions.count() - 1); 1831 * Common ListView Implementation 1832 */ 1833 1834 void QCommonListViewBase::appendHiddenRow(int row) 1835 { 1836 dd->hiddenRows.append(dd->model->index(row, 0, qq->rootIndex())); 1837 } 1838 1839 void QCommonListViewBase::removeHiddenRow(int row) 1840 { 1841 dd->hiddenRows.remove(dd->hiddenRows.indexOf(dd->model->index(row, 0, qq->rootIndex()))); 1842 } 1843 1844 void QCommonListViewBase::updateHorizontalScrollBar(const QSize &step) 1845 { 1846 horizontalScrollBar()->setSingleStep(step.width() + spacing()); 1847 horizontalScrollBar()->setPageStep(viewport()->width()); 1848 horizontalScrollBar()->setRange(0, contentsSize.width() - viewport()->width() - 2 * spacing()); 1849 } 1850 1851 void QCommonListViewBase::updateVerticalScrollBar(const QSize &step) 1852 { 1853 verticalScrollBar()->setSingleStep(step.height() + spacing()); 1854 verticalScrollBar()->setPageStep(viewport()->height()); 1855 verticalScrollBar()->setRange(0, contentsSize.height() - viewport()->height() - 2 * spacing()); 1856 } 1857 1858 void QCommonListViewBase::scrollContentsBy(int dx, int dy, bool /*scrollElasticBand*/) 1859 { 1860 dd->scrollContentsBy(isRightToLeft() ? -dx : dx, dy); 1861 } 1862 1863 int QCommonListViewBase::verticalScrollToValue(int /*index*/, QListView::ScrollHint hint, 1864 bool above, bool below, const QRect &area, const QRect &rect) const 1865 { 1866 int verticalValue = verticalScrollBar()->value(); 1867 QRect adjusted = rect.adjusted(-spacing(), -spacing(), spacing(), spacing()); 1868 if (hint == QListView::PositionAtTop || above) 1869 verticalValue += adjusted.top(); 1870 else if (hint == QListView::PositionAtBottom || below) 1871 verticalValue += qMin(adjusted.top(), adjusted.bottom() - area.height() + 1); 1872 else if (hint == QListView::PositionAtCenter) 1873 verticalValue += adjusted.top() - ((area.height() - adjusted.height()) / 2); 1874 return verticalValue; 1875 } 1876 1877 int QCommonListViewBase::horizontalOffset() const 1878 { 1879 return (isRightToLeft() ? horizontalScrollBar()->maximum() - horizontalScrollBar()->value() : horizontalScrollBar()->value()); 1880 } 1881 1882 int QCommonListViewBase::horizontalScrollToValue(const int /*index*/, QListView::ScrollHint hint, 1883 bool leftOf, bool rightOf, const QRect &area, const QRect &rect) const 1884 { 1885 int horizontalValue = horizontalScrollBar()->value(); 1886 if (isRightToLeft()) { 1887 if (hint == QListView::PositionAtCenter) { 1888 horizontalValue += ((area.width() - rect.width()) / 2) - rect.left(); 1889 } else { 1890 if (leftOf) 1891 horizontalValue -= rect.left(); 1892 else if (rightOf) 1893 horizontalValue += qMin(rect.left(), area.width() - rect.right()); 1894 } 1895 } else { 1896 if (hint == QListView::PositionAtCenter) { 1897 horizontalValue += rect.left() - ((area.width()- rect.width()) / 2); 1898 } else { 1899 if (leftOf) 1900 horizontalValue += rect.left(); 1901 else if (rightOf) 1902 horizontalValue += qMin(rect.left(), rect.right() - area.width()); 1903 } 1904 } 1905 return horizontalValue; 1906 } 1907 1908 /* 1909 * ListMode ListView Implementation 1910 */ 1911 1912 #ifndef QT_NO_DRAGANDDROP 1913 void QListModeViewBase::paintDragDrop(QPainter *painter) 1914 { 1915 // FIXME: Until the we can provide a proper drop indicator 1916 // in IconMode, it makes no sense to show it 1917 dd->paintDropIndicator(painter); 1918 } 1919 1920 QAbstractItemView::DropIndicatorPosition QListModeViewBase::position(const QPoint &pos, const QRect &rect, const QModelIndex &index) const 1921 { 1922 QAbstractItemView::DropIndicatorPosition r = QAbstractItemView::OnViewport; 1923 if (!dd->overwrite) { 1924 const int margin = 2; 1925 if (pos.x() - rect.left() < margin) { 1926 r = QAbstractItemView::AboveItem; // Visually, on the left 1927 } else if (rect.right() - pos.x() < margin) { 1928 r = QAbstractItemView::BelowItem; // Visually, on the right 1929 } else if (rect.contains(pos, true)) { 1930 r = QAbstractItemView::OnItem; 1931 } 1932 } else { 1933 QRect touchingRect = rect; 1934 touchingRect.adjust(-1, -1, 1, 1); 1935 if (touchingRect.contains(pos, false)) { 1936 r = QAbstractItemView::OnItem; 1937 } 1938 } 1939 1940 if (r == QAbstractItemView::OnItem && (!(dd->model->flags(index) & Qt::ItemIsDropEnabled))) 1941 r = pos.x() < rect.center().x() ? QAbstractItemView::AboveItem : QAbstractItemView::BelowItem; 1942 1943 return r; 1944 } 1945 1946 void QListModeViewBase::dragMoveEvent(QDragMoveEvent *event) 1947 { 1948 if (qq->dragDropMode() == QAbstractItemView::InternalMove 1949 && (event->source() != qq || !(event->possibleActions() & Qt::MoveAction))) 1950 return; 1951 1952 // ignore by default 1953 event->ignore(); 1954 1955 QModelIndex index = qq->indexAt(event->pos()); 1956 dd->hover = index; 1957 if (!dd->droppingOnItself(event, index) 1958 && dd->canDecode(event)) { 1959 1960 if (index.isValid() && dd->showDropIndicator) { 1961 QRect rect = qq->visualRect(index); 1962 dd->dropIndicatorPosition = position(event->pos(), rect, index); 1963 switch (dd->dropIndicatorPosition) { 1964 case QAbstractItemView::AboveItem: 1965 if (dd->isIndexDropEnabled(index.parent())) { 1966 dd->dropIndicatorRect = QRect(rect.left(), rect.top(), 0, rect.height()); 1967 event->accept(); 1968 } else { 1969 dd->dropIndicatorRect = QRect(); 1970 } 1971 break; 1972 case QAbstractItemView::BelowItem: 1973 if (dd->isIndexDropEnabled(index.parent())) { 1974 dd->dropIndicatorRect = QRect(rect.right(), rect.top(), 0, rect.height()); 1975 event->accept(); 1976 } else { 1977 dd->dropIndicatorRect = QRect(); 1978 } 1979 break; 1980 case QAbstractItemView::OnItem: 1981 if (dd->isIndexDropEnabled(index)) { 1982 dd->dropIndicatorRect = rect; 1983 event->accept(); 1984 } else { 1985 dd->dropIndicatorRect = QRect(); 1986 } 1987 break; 1988 case QAbstractItemView::OnViewport: 1989 dd->dropIndicatorRect = QRect(); 1990 if (dd->isIndexDropEnabled(qq->rootIndex())) { 1991 event->accept(); // allow dropping in empty areas 1992 } 1993 break; 1994 } 1995 } else { 1996 dd->dropIndicatorRect = QRect(); 1997 dd->dropIndicatorPosition = QAbstractItemView::OnViewport; 1998 if (dd->isIndexDropEnabled(qq->rootIndex())) { 1999 event->accept(); // allow dropping in empty areas 2000 } 2001 } 2002 dd->viewport->update(); 2003 } // can decode 2004 2005 if (dd->shouldAutoScroll(event->pos())) 2006 qq->startAutoScroll(); 2007 } 2008 2009 #endif //QT_NO_DRAGANDDROP 2010 2011 void QListModeViewBase::updateVerticalScrollBar(const QSize &step) 2012 { 2013 if (verticalScrollMode() == QAbstractItemView::ScrollPerItem 2014 && ((flow() == QListView::TopToBottom && !isWrapping()) 2015 || (flow() == QListView::LeftToRight && isWrapping()))) { 2016 const int steps = (flow() == QListView::TopToBottom ? scrollValueMap : segmentPositions).count() - 1; 2017 if (steps > 0) { 2018 const int pageSteps = perItemScrollingPageSteps(viewport()->height(), contentsSize.height(), isWrapping()); 2019 verticalScrollBar()->setSingleStep(1); 2020 verticalScrollBar()->setPageStep(pageSteps); 2021 verticalScrollBar()->setRange(0, steps - pageSteps); 2022 } else { 2023 verticalScrollBar()->setRange(0, 0); 2024 } 2025 // } else if (vertical && d->isWrapping() && d->movement == Static) { 2026 // ### wrapped scrolling in flow direction 2027 } else { 2028 QCommonListViewBase::updateVerticalScrollBar(step); 2029 } 2030 } 2031 2032 void QListModeViewBase::updateHorizontalScrollBar(const QSize &step) 2033 { 2034 if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem 2035 && ((flow() == QListView::TopToBottom && isWrapping()) 2036 || (flow() == QListView::LeftToRight && !isWrapping()))) { 2037 int steps = (flow() == QListView::TopToBottom ? segmentPositions : scrollValueMap).count() - 1; 2038 if (steps > 0) { 2039 const int pageSteps = perItemScrollingPageSteps(viewport()->width(), contentsSize.width(), isWrapping()); 2040 horizontalScrollBar()->setSingleStep(1); 2041 horizontalScrollBar()->setPageStep(pageSteps); 2042 horizontalScrollBar()->setRange(0, steps - pageSteps); 2043 } else { 2044 horizontalScrollBar()->setRange(0, 0); 2045 } 2046 } else { 2047 QCommonListViewBase::updateHorizontalScrollBar(step); 2048 } 2049 } 2050 2051 int QListModeViewBase::verticalScrollToValue(int index, QListView::ScrollHint hint, 2052 bool above, bool below, const QRect &area, const QRect &rect) const 2053 { 2054 if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) { 2055 int value; 2056 if (scrollValueMap.isEmpty()) 2057 value = 0; 2058 else 2059 value = qBound(0, scrollValueMap.at(verticalScrollBar()->value()), flowPositions.count() - 1); 2060 if (above) 2061 hint = QListView::PositionAtTop; 2062 else if (below) 2063 hint = QListView::PositionAtBottom; 2064 if (hint == QListView::EnsureVisible) 2065 return value; 2066 2067 return perItemScrollToValue(index, value, area.height(), hint, Qt::Vertical, isWrapping(), rect.height()); 2068 } 2069 2070 return QCommonListViewBase::verticalScrollToValue(index, hint, above, below, area, rect); 2071 } 2072 2073 int QListModeViewBase::horizontalOffset() const 2074 { 2075 if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) { 2076 if (isWrapping()) { 2077 if (flow() == QListView::TopToBottom && !segmentPositions.isEmpty()) { 2078 const int max = segmentPositions.count() - 1; 2079 int currentValue = qBound(0, horizontalScrollBar()->value(), max); 2080 int position = segmentPositions.at(currentValue); 2081 int maximumValue = qBound(0, horizontalScrollBar()->maximum(), max); 2082 int maximum = segmentPositions.at(maximumValue); 2083 return (isRightToLeft() ? maximum - position : position); 2084 } 2085 } else if (flow() == QListView::LeftToRight && !flowPositions.isEmpty()) { 2086 int position = flowPositions.at(scrollValueMap.at(horizontalScrollBar()->value())); 2087 int maximum = flowPositions.at(scrollValueMap.at(horizontalScrollBar()->maximum())); 2088 return (isRightToLeft() ? maximum - position : position); 2089 } 2090 } 2091 return QCommonListViewBase::horizontalOffset(); 2092 } 2093 2094 int QListModeViewBase::verticalOffset() const 2095 { 2096 if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) { 2097 if (isWrapping()) { 2098 if (flow() == QListView::LeftToRight && !segmentPositions.isEmpty()) { 2099 int value = verticalScrollBar()->value(); 2100 if (value >= segmentPositions.count()) 2101 return 0; 2102 return segmentPositions.at(value); 2103 } 2104 } else if (flow() == QListView::TopToBottom && !flowPositions.isEmpty()) { 2105 int value = verticalScrollBar()->value(); 2106 if (value > scrollValueMap.count()) 2107 return 0; 2108 return flowPositions.at(scrollValueMap.at(value)) - spacing(); 2109 } 2110 } 2111 return QCommonListViewBase::verticalOffset(); 2112 } 2113 2114 int QListModeViewBase::horizontalScrollToValue(int index, QListView::ScrollHint hint, 2115 bool leftOf, bool rightOf, const QRect &area, const QRect &rect) const 2116 { 2117 if (horizontalScrollMode() != QAbstractItemView::ScrollPerItem) 2118 return QCommonListViewBase::horizontalScrollToValue(index, hint, leftOf, rightOf, area, rect); 2119 2120 int value; 2121 if (scrollValueMap.isEmpty()) 2122 value = 0; 2123 else 2124 value = qBound(0, scrollValueMap.at(horizontalScrollBar()->value()), flowPositions.count() - 1); 2162 2125 if (leftOf) 2163 return perItemScrollToValue(itemIndex, value, areaWidth, QListView::PositionAtTop, 2164 Qt::Horizontal, wrap, itemWidth); 2126 hint = QListView::PositionAtTop; 2165 2127 else if (rightOf) 2166 return perItemScrollToValue(itemIndex, value, areaWidth, QListView::PositionAtBottom,2167 Qt::Horizontal, wrap, itemWidth);2168 else if (hint != QListView::EnsureVisible)2169 return perItemScrollToValue(itemIndex, value, areaWidth, hint, Qt::Horizontal, wrap, itemWidth); 2170 return value;2171 } 2172 2173 void Q StaticListViewBase::scrollContentsBy(int &dx, int &dy)2128 2129 2130 2131 2132 return ; 2133 } 2134 2135 void Q) 2174 2136 { 2175 2137 // ### reorder this logic 2176 const int verticalValue = verticalScrollBar Value();2177 const int horizontalValue = horizontalScrollBar Value();2138 const int verticalValue = verticalScrollBaralue(); 2139 const int horizontalValue = horizontalScrollBaralue(); 2178 2140 const bool vertical = (verticalScrollMode() == QAbstractItemView::ScrollPerItem); 2179 2141 const bool horizontal = (horizontalScrollMode() == QAbstractItemView::ScrollPerItem); … … 2203 2165 int currentValue = qBound(0, verticalValue, max); 2204 2166 int previousValue = qBound(0, currentValue + dy, max); 2205 int currentCoordinate = flowPositions.at( currentValue);2206 int previousCoordinate = flowPositions.at( previousValue);2167 int currentCoordinate = flowPositions.at(); 2168 int previousCoordinate = flowPositions.at(); 2207 2169 dy = previousCoordinate - currentCoordinate; 2208 2170 } else if (horizontal && flow() == QListView::LeftToRight && dx != 0) { 2209 2171 int currentValue = qBound(0, horizontalValue, max); 2210 2172 int previousValue = qBound(0, currentValue + dx, max); 2211 int currentCoordinate = flowPositions.at( currentValue);2212 int previousCoordinate = flowPositions.at( previousValue);2173 int currentCoordinate = flowPositions.at(); 2174 int previousCoordinate = flowPositions.at(); 2213 2175 dx = previousCoordinate - currentCoordinate; 2214 2176 } 2215 2177 } 2216 } 2217 2218 bool QStaticListViewBase::doBatchedItemLayout(const QListViewLayoutInfo &info, int max) 2178 QCommonListViewBase::scrollContentsBy(dx, dy, scrollElasticBand); 2179 } 2180 2181 bool QListModeViewBase::doBatchedItemLayout(const QListViewLayoutInfo &info, int max) 2219 2182 { 2220 2183 doStaticLayout(info); … … 2228 2191 } 2229 2192 2230 QListViewItem Q StaticListViewBase::indexToListViewItem(const QModelIndex &index) const2193 QListViewItem QViewBase::indexToListViewItem(const QModelIndex &index) const 2231 2194 { 2232 2195 if (flowPositions.isEmpty() 2233 2196 || segmentPositions.isEmpty() 2234 || index.row() > flowPositions.count())2197 || index.row() > flowPositions.count()) 2235 2198 return QListViewItem(); 2236 2199 … … 2264 2227 } 2265 2228 2266 QPoint Q StaticListViewBase::initStaticLayout(const QListViewLayoutInfo &info)2229 QPoint QViewBase::initStaticLayout(const QListViewLayoutInfo &info) 2267 2230 { 2268 2231 int x, y; … … 2272 2235 segmentStartRows.clear(); 2273 2236 segmentExtents.clear(); 2237 2274 2238 x = info.bounds.left() + info.spacing; 2275 2239 y = info.bounds.top() + info.spacing; … … 2299 2263 \internal 2300 2264 */ 2301 void Q StaticListViewBase::doStaticLayout(const QListViewLayoutInfo &info)2265 void QViewBase::doStaticLayout(const QListViewLayoutInfo &info) 2302 2266 { 2303 2267 const bool useItemSize = !info.grid.isValid(); … … 2363 2327 } 2364 2328 // save the flow position of this item 2329 2365 2330 flowPositions.append(flowPosition); 2366 2331 // prepare for the next item … … 2388 2353 if (info.last == info.max) { 2389 2354 segmentExtents.append(flowPosition); 2355 2390 2356 flowPositions.append(flowPosition); 2391 2357 segmentPositions.append(info.wrap ? segPosition + deltaSegPosition : INT_MAX); … … 2402 2368 In this function, itemsize is counted from topleft to the start of the next item. 2403 2369 */ 2404 void QStaticListViewBase::intersectingStaticSet(const QRect &area) const2405 { 2406 clearIntersections();2370 Set(const QRect &area) const 2371 { 2372 ; 2407 2373 int segStartPosition; 2408 2374 int segEndPosition; … … 2421 2387 } 2422 2388 if (segmentPositions.count() < 2 || flowPositions.isEmpty()) 2423 return ;2389 return; 2424 2390 // the last segment position is actually the edge of the last segment 2425 2391 const int segLast = segmentPositions.count() - 2; … … 2436 2402 QModelIndex index = modelIndex(row); 2437 2403 if (index.isValid()) 2438 appendToIntersections(index);2404 ; 2439 2405 #if 0 // for debugging 2440 2406 else 2441 qWarning("intersectingS taticSet: row %d was invalid", row);2407 qWarning("intersectingSet: row %d was invalid", row); 2442 2408 #endif 2443 2409 } 2444 2410 } 2445 } 2446 2447 int QStaticListViewBase::itemIndex(const QListViewItem &item) const 2448 { 2449 return item.indexHint; 2450 } 2451 2452 QRect QStaticListViewBase::mapToViewport(const QRect &rect) const 2411 return ret; 2412 } 2413 2414 void QListModeViewBase::dataChanged(const QModelIndex &, const QModelIndex &) 2415 { 2416 dd->doDelayedItemsLayout(); 2417 } 2418 2419 2420 QRect QListModeViewBase::mapToViewport(const QRect &rect) const 2453 2421 { 2454 2422 if (isWrapping()) 2455 2423 return rect; 2456 2424 // If the listview is in "listbox-mode", the items are as wide as the view. 2425 2457 2426 QRect result = rect; 2458 QSize vsize = viewport()->size();2459 QSize csize = contentsSize;2460 2427 if (flow() == QListView::TopToBottom) { 2461 2428 result.setLeft(spacing()); 2462 result.setWidth(qMax( csize.width(), vsize.width()) - 2 * spacing());2429 result.setWidth(qMax()); 2463 2430 } else { // LeftToRight 2464 2431 result.setTop(spacing()); 2465 result.setHeight(qMax( csize.height(), vsize.height()) - 2 * spacing());2432 result.setHeight(qMax()); 2466 2433 } 2467 2434 return result; 2468 2435 } 2469 2436 2470 int QStaticListViewBase::perItemScrollingPageSteps(int length, int bounds, bool wrap) const 2471 { 2472 const QVector<int> positions = (wrap ? segmentPositions : flowPositions); 2437 int QListModeViewBase::perItemScrollingPageSteps(int length, int bounds, bool wrap) const 2438 { 2439 QVector<int> positions; 2440 if (wrap) 2441 positions = segmentPositions; 2442 else if (!flowPositions.isEmpty()) { 2443 positions.reserve(scrollValueMap.size()); 2444 foreach (int itemShown, scrollValueMap) 2445 positions.append(flowPositions.at(itemShown)); 2446 } 2473 2447 if (positions.isEmpty() || bounds <= length) 2474 2448 return positions.count(); … … 2496 2470 } 2497 2471 2498 int Q StaticListViewBase::perItemScrollToValue(int index, int scrollValue, int viewportSize,2472 int QViewBase::perItemScrollToValue(int index, int scrollValue, int viewportSize, 2499 2473 QAbstractItemView::ScrollHint hint, 2500 2474 Qt::Orientation orientation, bool wrap, int itemExtent) const … … 2556 2530 } 2557 2531 2558 void Q StaticListViewBase::clear()2532 void QViewBase::clear() 2559 2533 { 2560 2534 flowPositions.clear(); … … 2568 2542 2569 2543 /* 2570 * Dynamic ListView Implementation 2571 */ 2572 2573 void QDynamicListViewBase::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) 2544 * IconMode ListView Implementation 2545 */ 2546 2547 void QIconModeViewBase::setPositionForIndex(const QPoint &position, const QModelIndex &index) 2548 { 2549 if (index.row() >= items.count()) 2550 return; 2551 const QSize oldContents = contentsSize; 2552 qq->update(index); // update old position 2553 moveItem(index.row(), position); 2554 qq->update(index); // update new position 2555 2556 if (contentsSize != oldContents) 2557 dd->viewUpdateGeometries(); // update the scroll bars 2558 } 2559 2560 void QIconModeViewBase::appendHiddenRow(int row) 2561 { 2562 if (row >= 0 && row < items.count()) //remove item 2563 tree.removeLeaf(items.at(row).rect(), row); 2564 QCommonListViewBase::appendHiddenRow(row); 2565 } 2566 2567 void QIconModeViewBase::removeHiddenRow(int row) 2568 { 2569 QCommonListViewBase::removeHiddenRow(row); 2570 if (row >= 0 && row < items.count()) //insert item 2571 tree.insertLeaf(items.at(row).rect(), row); 2572 } 2573 2574 #ifndef QT_NO_DRAGANDDROP 2575 void QIconModeViewBase::paintDragDrop(QPainter *painter) 2576 { 2577 if (!draggedItems.isEmpty() && viewport()->rect().contains(draggedItemsPos)) { 2578 //we need to draw the items that arre dragged 2579 painter->translate(draggedItemsDelta()); 2580 QStyleOptionViewItemV4 option = viewOptions(); 2581 option.state &= ~QStyle::State_MouseOver; 2582 QVector<QModelIndex>::const_iterator it = draggedItems.begin(); 2583 QListViewItem item = indexToListViewItem(*it); 2584 for (; it != draggedItems.end(); ++it) { 2585 item = indexToListViewItem(*it); 2586 option.rect = viewItemRect(item); 2587 delegate(*it)->paint(painter, option, *it); 2588 } 2589 } 2590 } 2591 2592 bool QIconModeViewBase::filterStartDrag(Qt::DropActions supportedActions) 2593 { 2594 // This function does the same thing as in QAbstractItemView::startDrag(), 2595 // plus adding viewitems to the draggedItems list. 2596 // We need these items to draw the drag items 2597 QModelIndexList indexes = dd->selectionModel->selectedIndexes(); 2598 if (indexes.count() > 0 ) { 2599 if (viewport()->acceptDrops()) { 2600 QModelIndexList::ConstIterator it = indexes.constBegin(); 2601 for (; it != indexes.constEnd(); ++it) 2602 if (dd->model->flags(*it) & Qt::ItemIsDragEnabled 2603 && (*it).column() == dd->column) 2604 draggedItems.push_back(*it); 2605 } 2606 QDrag *drag = new QDrag(qq); 2607 drag->setMimeData(dd->model->mimeData(indexes)); 2608 Qt::DropAction action = drag->exec(supportedActions, Qt::CopyAction); 2609 draggedItems.clear(); 2610 if (action == Qt::MoveAction) 2611 dd->clearOrRemove(); 2612 } 2613 return true; 2614 } 2615 2616 bool QIconModeViewBase::filterDropEvent(QDropEvent *e) 2617 { 2618 if (e->source() != qq) 2619 return false; 2620 2621 const QSize contents = contentsSize; 2622 QPoint offset(horizontalOffset(), verticalOffset()); 2623 QPoint end = e->pos() + offset; 2624 QPoint start = dd->pressedPosition; 2625 QPoint delta = (dd->movement == QListView::Snap ? snapToGrid(end) - snapToGrid(start) : end - start); 2626 QList<QModelIndex> indexes = dd->selectionModel->selectedIndexes(); 2627 for (int i = 0; i < indexes.count(); ++i) { 2628 QModelIndex index = indexes.at(i); 2629 QRect rect = dd->rectForIndex(index); 2630 viewport()->update(dd->mapToViewport(rect, false)); 2631 QPoint dest = rect.topLeft() + delta; 2632 if (qq->isRightToLeft()) 2633 dest.setX(dd->flipX(dest.x()) - rect.width()); 2634 moveItem(index.row(), dest); 2635 qq->update(index); 2636 } 2637 dd->stopAutoScroll(); 2638 draggedItems.clear(); 2639 dd->emitIndexesMoved(indexes); 2640 e->accept(); // we have handled the event 2641 // if the size has not grown, we need to check if it has shrinked 2642 if (contentsSize != contents) { 2643 if ((contentsSize.width() <= contents.width() 2644 || contentsSize.height() <= contents.height())) { 2645 updateContentsSize(); 2646 } 2647 dd->viewUpdateGeometries(); 2648 } 2649 return true; 2650 } 2651 2652 bool QIconModeViewBase::filterDragLeaveEvent(QDragLeaveEvent *e) 2653 { 2654 viewport()->update(draggedItemsRect()); // erase the area 2655 draggedItemsPos = QPoint(-1, -1); // don't draw the dragged items 2656 return QCommonListViewBase::filterDragLeaveEvent(e); 2657 } 2658 2659 bool QIconModeViewBase::filterDragMoveEvent(QDragMoveEvent *e) 2660 { 2661 if (e->source() != qq || !dd->canDecode(e)) 2662 return false; 2663 2664 // ignore by default 2665 e->ignore(); 2666 // get old dragged items rect 2667 QRect itemsRect = this->itemsRect(draggedItems); 2668 viewport()->update(itemsRect.translated(draggedItemsDelta())); 2669 // update position 2670 draggedItemsPos = e->pos(); 2671 // get new items rect 2672 viewport()->update(itemsRect.translated(draggedItemsDelta())); 2673 // set the item under the cursor to current 2674 QModelIndex index; 2675 if (movement() == QListView::Snap) { 2676 QRect rect(snapToGrid(e->pos() + offset()), gridSize()); 2677 const QVector<QModelIndex> intersectVector = intersectingSet(rect); 2678 index = intersectVector.count() > 0 ? intersectVector.last() : QModelIndex(); 2679 } else { 2680 index = qq->indexAt(e->pos()); 2681 } 2682 // check if we allow drops here 2683 if (draggedItems.contains(index)) 2684 e->accept(); // allow changing item position 2685 else if (dd->model->flags(index) & Qt::ItemIsDropEnabled) 2686 e->accept(); // allow dropping on dropenabled items 2687 else if (!index.isValid()) 2688 e->accept(); // allow dropping in empty areas 2689 2690 // the event was treated. do autoscrolling 2691 if (dd->shouldAutoScroll(e->pos())) 2692 dd->startAutoScroll(); 2693 return true; 2694 } 2695 #endif // QT_NO_DRAGANDDROP 2696 2697 void QIconModeViewBase::setRowCount(int rowCount) 2698 { 2699 tree.create(qMax(rowCount - hiddenCount(), 0)); 2700 } 2701 2702 void QIconModeViewBase::scrollContentsBy(int dx, int dy, bool scrollElasticBand) 2703 { 2704 if (scrollElasticBand) 2705 dd->scrollElasticBandBy(isRightToLeft() ? -dx : dx, dy); 2706 2707 QCommonListViewBase::scrollContentsBy(dx, dy, scrollElasticBand); 2708 if (!draggedItems.isEmpty()) 2709 viewport()->update(draggedItemsRect().translated(dx, dy)); 2710 } 2711 2712 void QIconModeViewBase::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) 2574 2713 { 2575 2714 if (column() >= topLeft.column() && column() <= bottomRight.column()) { … … 2581 2720 } 2582 2721 2583 bool Q DynamicListViewBase::doBatchedItemLayout(const QListViewLayoutInfo &info, int max)2722 bool QViewBase::doBatchedItemLayout(const QListViewLayoutInfo &info, int max) 2584 2723 { 2585 2724 if (info.last >= items.count()) { 2586 createItems(info.last + 1); 2725 //first we create the items 2726 QStyleOptionViewItemV4 option = viewOptions(); 2727 for (int row = items.count(); row <= info.last; ++row) { 2728 QSize size = itemSize(option, modelIndex(row)); 2729 QListViewItem item(QRect(0, 0, size.width(), size.height()), row); // default pos 2730 items.append(item); 2731 } 2587 2732 doDynamicLayout(info); 2588 2733 } … … 2590 2735 } 2591 2736 2592 QListViewItem Q DynamicListViewBase::indexToListViewItem(const QModelIndex &index) const2737 QListViewItem QViewBase::indexToListViewItem(const QModelIndex &index) const 2593 2738 { 2594 2739 if (index.isValid() && index.row() < items.count()) … … 2597 2742 } 2598 2743 2599 void Q DynamicListViewBase::initBspTree(const QSize &contents)2744 void QViewBase::initBspTree(const QSize &contents) 2600 2745 { 2601 2746 // remove all items from the tree … … 2614 2759 } 2615 2760 2616 QPoint Q DynamicListViewBase::initDynamicLayout(const QListViewLayoutInfo &info)2761 QPoint QViewBase::initDynamicLayout(const QListViewLayoutInfo &info) 2617 2762 { 2618 2763 int x, y; … … 2636 2781 \internal 2637 2782 */ 2638 void Q DynamicListViewBase::doDynamicLayout(const QListViewLayoutInfo &info)2783 void QViewBase::doDynamicLayout(const QListViewLayoutInfo &info) 2639 2784 { 2640 2785 const bool useItemSize = !info.grid.isValid(); … … 2670 2815 moved.resize(items.count()); 2671 2816 2672 QRect rect(QPoint( 0, 0), topLeft);2817 QRect rect(QPoint(), topLeft); 2673 2818 QListViewItem *item = 0; 2674 2819 for (int row = info.first; row <= info.last; ++row) { … … 2763 2908 } 2764 2909 2765 void QDynamicListViewBase::intersectingDynamicSet(const QRect &area) const 2766 { 2767 clearIntersections(); 2768 QListViewPrivate *that = const_cast<QListViewPrivate*>(dd); 2910 QVector<QModelIndex> QIconModeViewBase::intersectingSet(const QRect &area) const 2911 { 2912 QIconModeViewBase *that = const_cast<QIconModeViewBase*>(this); 2769 2913 QBspTree::Data data(static_cast<void*>(that)); 2770 that->dynamicListView->tree.climbTree(area, &QDynamicListViewBase::addLeaf, data); 2771 } 2772 2773 void QDynamicListViewBase::createItems(int to) 2774 { 2775 int count = items.count(); 2776 QSize size; 2777 QStyleOptionViewItemV4 option = viewOptions(); 2778 for (int row = count; row < to; ++row) { 2779 size = itemSize(option, modelIndex(row)); 2780 QListViewItem item(QRect(0, 0, size.width(), size.height()), row); // default pos 2781 items.append(item); 2782 } 2783 } 2784 2785 void QDynamicListViewBase::drawItems(QPainter *painter, const QVector<QModelIndex> &indexes) const 2786 { 2787 QStyleOptionViewItemV4 option = viewOptions(); 2788 option.state &= ~QStyle::State_MouseOver; 2789 QVector<QModelIndex>::const_iterator it = indexes.begin(); 2790 QListViewItem item = indexToListViewItem(*it); 2791 for (; it != indexes.end(); ++it) { 2792 item = indexToListViewItem(*it); 2793 option.rect = viewItemRect(item); 2794 delegate(*it)->paint(painter, option, *it); 2795 } 2796 } 2797 2798 QRect QDynamicListViewBase::itemsRect(const QVector<QModelIndex> &indexes) const 2914 QVector<QModelIndex> res; 2915 that->interSectingVector = &res; 2916 that->tree.climbTree(area, &QIconModeViewBase::addLeaf, data); 2917 that->interSectingVector = 0; 2918 return res; 2919 } 2920 2921 QRect QIconModeViewBase::itemsRect(const QVector<QModelIndex> &indexes) const 2799 2922 { 2800 2923 QVector<QModelIndex>::const_iterator it = indexes.begin(); … … 2808 2931 } 2809 2932 2810 int Q DynamicListViewBase::itemIndex(const QListViewItem &item) const2933 int QViewBase::itemIndex(const QListViewItem &item) const 2811 2934 { 2812 2935 if (!item.isValid()) … … 2844 2967 } 2845 2968 2846 void Q DynamicListViewBase::addLeaf(QVector<int> &leaf, const QRect &area,2847 uint visited, QBspTree::Data data)2969 void QViewBase::addLeaf(QVector<int> &leaf, const QRect &area, 2970 uint visited, QBspTree::Data data) 2848 2971 { 2849 2972 QListViewItem *vi; 2850 Q ListViewPrivate *_this = static_cast<QListViewPrivate *>(data.ptr);2973 Qe *>(data.ptr); 2851 2974 for (int i = 0; i < leaf.count(); ++i) { 2852 2975 int idx = leaf.at(i); 2853 if (idx < 0 || idx >= _this-> dynamicListView->items.count())2976 if (idx < 0 || idx >= _this->items.count()) 2854 2977 continue; 2855 vi = &_this-> dynamicListView->items[idx];2978 vi = &_this->items[idx]; 2856 2979 Q_ASSERT(vi); 2857 2980 if (vi->isValid() && vi->rect().intersects(area) && vi->visited != visited) { 2858 QModelIndex index = _this->listViewItemToIndex(*vi);2981 QModelIndex index ->listViewItemToIndex(*vi); 2859 2982 Q_ASSERT(index.isValid()); 2860 _this->inter sectVector.append(index);2983 _this->interappend(index); 2861 2984 vi->visited = visited; 2862 2985 } … … 2864 2987 } 2865 2988 2866 void QDynamicListViewBase::insertItem(int index) 2867 { 2868 if (index >= 0 && index < items.count()) 2869 tree.insertLeaf(items.at(index).rect(), index); 2870 } 2871 2872 void QDynamicListViewBase::removeItem(int index) 2873 { 2874 if (index >= 0 && index < items.count()) 2875 tree.removeLeaf(items.at(index).rect(), index); 2876 } 2877 2878 void QDynamicListViewBase::moveItem(int index, const QPoint &dest) 2989 void QIconModeViewBase::moveItem(int index, const QPoint &dest) 2879 2990 { 2880 2991 // does not impact on the bintree itself or the contents rect … … 2896 3007 } 2897 3008 2898 QPoint Q DynamicListViewBase::snapToGrid(const QPoint &pos) const3009 QPoint QViewBase::snapToGrid(const QPoint &pos) const 2899 3010 { 2900 3011 int x = pos.x() - (pos.x() % gridSize().width()); … … 2903 3014 } 2904 3015 2905 QPoint Q DynamicListViewBase::draggedItemsDelta() const3016 QPoint QViewBase::draggedItemsDelta() const 2906 3017 { 2907 3018 if (movement() == QListView::Snap) { … … 2913 3024 } 2914 3025 2915 QRect Q DynamicListViewBase::draggedItemsRect() const3026 QRect QViewBase::draggedItemsRect() const 2916 3027 { 2917 3028 QRect rect = itemsRect(draggedItems); … … 2932 3043 } 2933 3044 2934 void Q DynamicListViewBase::clear()3045 void QViewBase::clear() 2935 3046 { 2936 3047 tree.destroy(); … … 2941 3052 } 2942 3053 2943 void Q DynamicListViewBase::updateContentsSize()3054 void QViewBase::updateContentsSize() 2944 3055 { 2945 3056 QRect bounding; … … 2994 3105 d->executePostedLayout(); 2995 3106 QListViewItem itm = d->indexToListViewItem(index); 2996 return d-> itemIndex(itm);3107 return d->itemIndex(itm); 2997 3108 } 2998 3109
Note:
See TracChangeset
for help on using the changeset viewer.
