Changeset 561 for trunk/src/gui/itemviews
- Timestamp:
- Feb 11, 2010, 11:19:06 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 67 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/qabstractitemdelegate.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 ** … … 62 62 63 63 \ingroup model-view 64 \mainclass 64 65 65 66 66 A QAbstractItemDelegate provides the interface and common functionality -
trunk/src/gui/itemviews/qabstractitemdelegate.h
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 ** -
trunk/src/gui/itemviews/qabstractitemview.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 ** … … 62 62 #include <qaccessible.h> 63 63 #endif 64 #include <private/qsoftkeymanager_p.h> 64 65 65 66 QT_BEGIN_NAMESPACE … … 69 70 itemDelegate(0), 70 71 selectionModel(0), 72 ctrlDragSelectionFlag(QItemSelectionModel::NoUpdate), 73 noSelectionOnMousePress(false), 71 74 selectionMode(QAbstractItemView::ExtendedSelection), 72 75 selectionBehavior(QAbstractItemView::SelectItems), … … 74 77 pressedModifiers(Qt::NoModifier), 75 78 pressedPosition(QPoint(-1, -1)), 79 pressedAlreadySelected(false), 76 80 viewportEnteredNeeded(false), 77 81 state(QAbstractItemView::NoState), … … 85 89 overwrite(false), 86 90 dropIndicatorPosition(QAbstractItemView::OnItem), 91 defaultDropAction(Qt::IgnoreAction), 92 #endif 93 #ifdef QT_SOFTKEYS_ENABLED 94 doneSoftKey(0), 87 95 #endif 88 96 autoScroll(true), 89 97 autoScrollMargin(16), 90 98 autoScrollCount(0), 99 shouldScrollToCurrentOnShow(false), 100 shouldClearStatusTip(false), 91 101 alternatingColors(false), 92 102 textElideMode(Qt::ElideRight), … … 108 118 q->setItemDelegate(new QStyledItemDelegate(q)); 109 119 110 q->verticalScrollBar()->setRange(0, 0);111 q->horizontalScrollBar()->setRange(0, 0);112 113 QObject::connect( q->verticalScrollBar(), SIGNAL(actionTriggered(int)),120 vbar->setRange(0, 0); 121 hbar->setRange(0, 0); 122 123 QObject::connect(vbar, SIGNAL(actionTriggered(int)), 114 124 q, SLOT(verticalScrollbarAction(int))); 115 QObject::connect( q->horizontalScrollBar(), SIGNAL(actionTriggered(int)),125 QObject::connect(hbar, SIGNAL(actionTriggered(int)), 116 126 q, SLOT(horizontalScrollbarAction(int))); 117 QObject::connect( q->verticalScrollBar(), SIGNAL(valueChanged(int)),127 QObject::connect(vbar, SIGNAL(valueChanged(int)), 118 128 q, SLOT(verticalScrollbarValueChanged(int))); 119 QObject::connect( q->horizontalScrollBar(), SIGNAL(valueChanged(int)),129 QObject::connect(hbar, SIGNAL(valueChanged(int)), 120 130 q, SLOT(horizontalScrollbarValueChanged(int))); 121 131 … … 125 135 126 136 q->setAttribute(Qt::WA_InputMethodEnabled); 127 } 137 138 #ifdef QT_SOFTKEYS_ENABLED 139 doneSoftKey = QSoftKeyManager::createKeyedAction(QSoftKeyManager::DoneSoftKey, Qt::Key_Back, q); 140 #endif 141 } 142 143 void QAbstractItemViewPrivate::setHoverIndex(const QPersistentModelIndex &index) 144 { 145 Q_Q(QAbstractItemView); 146 if (hover == index) 147 return; 148 149 q->update(hover); //update the old one 150 hover = index; 151 q->update(hover); //update the new one 152 } 153 154 void QAbstractItemViewPrivate::checkMouseMove(const QPersistentModelIndex &index) 155 { 156 //we take a persistent model index because the model might change by emitting signals 157 Q_Q(QAbstractItemView); 158 setHoverIndex(index); 159 if (viewportEnteredNeeded || enteredIndex != index) { 160 viewportEnteredNeeded = false; 161 162 if (index.isValid()) { 163 emit q->entered(index); 164 #ifndef QT_NO_STATUSTIP 165 QString statustip = model->data(index, Qt::StatusTipRole).toString(); 166 if (parent && (shouldClearStatusTip || !statustip.isEmpty())) { 167 QStatusTipEvent tip(statustip); 168 QApplication::sendEvent(parent, &tip); 169 shouldClearStatusTip = !statustip.isEmpty(); 170 } 171 #endif 172 } else { 173 #ifndef QT_NO_STATUSTIP 174 if (parent && shouldClearStatusTip) { 175 QString emptyString; 176 QStatusTipEvent tip( emptyString ); 177 QApplication::sendEvent(parent, &tip); 178 } 179 #endif 180 emit q->viewportEntered(); 181 } 182 enteredIndex = index; 183 } 184 } 185 128 186 129 187 /*! … … 134 192 135 193 \ingroup model-view 136 \mainclass 194 137 195 138 196 QAbstractItemView class is the base class for every standard view … … 143 201 changes to their models. This class provides standard support for 144 202 keyboard and mouse navigation, viewport scrolling, item editing, 145 and selections. 203 and selections. The keyboard navigation implements this 204 functionality: 205 206 \table 207 \header 208 \o Keys 209 \o Functionality 210 \row 211 \o Arrow keys 212 \o Changes the current item and selects it. 213 \row 214 \o Ctrl+Arrow keys 215 \o Changes the current item but does not select it. 216 \row 217 \o Shift+Arrow keys 218 \o Changes the current item and selects it. The previously 219 selected item(s) is not deselected. 220 \row 221 \o Ctr+Space 222 \o Toggles selection of the current item. 223 \row 224 \o Tab/Backtab 225 \o Changes the current item to the next/previous item. 226 \row 227 \o Home/End 228 \o Selects the first/last item in the model. 229 \row 230 \o Page up/Page down 231 \o Scrolls the rows shown up/down by the number of 232 visible rows in the view. 233 \row 234 \o Ctrl+A 235 \o Selects all items in the model. 236 \endtable 237 238 Note that the above table assumes that the 239 \l{selectionMode}{selection mode} allows the operations. For 240 instance, you cannot select items if the selection mode is 241 QAbstractItemView::NoSelection. 146 242 147 243 The QAbstractItemView class is one of the \l{Model/View Classes} … … 525 621 disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), 526 622 this, SLOT(dataChanged(QModelIndex,QModelIndex))); 623 disconnect(d->model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), 624 this, SLOT(_q_headerDataChanged())); 527 625 disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)), 528 626 this, SLOT(rowsInserted(QModelIndex,int,int))); … … 552 650 "The parent of a top level index should be invalid"); 553 651 554 if (d->model && d->model!= QAbstractItemModelPrivate::staticEmptyModel()) {652 if (d->model != QAbstractItemModelPrivate::staticEmptyModel()) { 555 653 connect(d->model, SIGNAL(destroyed()), 556 654 this, SLOT(_q_modelDestroyed())); 557 655 connect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), 558 656 this, SLOT(dataChanged(QModelIndex,QModelIndex))); 657 connect(d->model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), 658 this, SLOT(_q_headerDataChanged())); 559 659 connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)), 560 660 this, SLOT(rowsInserted(QModelIndex,int,int))); … … 671 771 } 672 772 673 674 773 if (delegate) { 675 774 if (d->delegateRefCount(delegate) == 0) { … … 682 781 } 683 782 d->itemDelegate = delegate; 783 viewport()->update(); 684 784 } 685 785 … … 746 846 d->rowDelegates.insert(row, delegate); 747 847 } 848 viewport()->update(); 748 849 } 749 850 … … 802 903 d->columnDelegates.insert(column, delegate); 803 904 } 905 viewport()->update(); 804 906 } 805 907 … … 820 922 821 923 /*! 822 Returns the item delegate used by this view and model for823 the given \a index.924 Returns the item delegate used by this view and model for 925 the given \a index. 824 926 */ 825 927 QAbstractItemDelegate *QAbstractItemView::itemDelegate(const QModelIndex &index) const … … 830 932 831 933 /*! 832 \property QAbstractItemView::selectionMode833 \brief which selection mode the view operates in834 835 This property controls whether the user can select one or many items836 and, in many-item selections, whether the selection must be a837 continuous range of items.838 839 \sa SelectionMode SelectionBehavior934 \property QAbstractItemView::selectionMode 935 \brief which selection mode the view operates in 936 937 This property controls whether the user can select one or many items 938 and, in many-item selections, whether the selection must be a 939 continuous range of items. 940 941 \sa SelectionMode SelectionBehavior 840 942 */ 841 943 void QAbstractItemView::setSelectionMode(SelectionMode mode) … … 852 954 853 955 /*! 854 \property QAbstractItemView::selectionBehavior855 \brief which selection behavior the view uses856 857 This property holds whether selections are done858 in terms of single items, rows or columns.859 860 \sa SelectionMode SelectionBehavior956 \property QAbstractItemView::selectionBehavior 957 \brief which selection behavior the view uses 958 959 This property holds whether selections are done 960 in terms of single items, rows or columns. 961 962 \sa SelectionMode SelectionBehavior 861 963 */ 862 964 … … 875 977 /*! 876 978 Sets the current item to be the item at \a index. 877 Depending on the current selection mode, the item may also be selected. 979 980 Unless the current selection mode is 981 \l{QAbstractItemView::}{NoSelection}, the item is also be selected. 878 982 Note that this function also updates the starting position for any 879 983 new selections the user performs. … … 921 1025 { 922 1026 Q_D(QAbstractItemView); 1027 d->delayedReset.stop(); //make sure we stop the timer 923 1028 QList<QEditorInfo>::const_iterator it = d->editors.constBegin(); 924 1029 for (; it != d->editors.constEnd(); ++it) … … 929 1034 setState(NoState); 930 1035 setRootIndex(QModelIndex()); 1036 if (d->selectionModel) 1037 d->selectionModel->reset(); 931 1038 } 932 1039 … … 959 1066 960 1067 /*! 961 Selects all itemin the view.962 This function wil use the selectionselection behavior963 set on the view when selecting.964 965 \sa setSelection(), selectedIndexes(), clearSelection()1068 Selects all items in the view. 1069 This function will use the selection behavior 1070 set on the view when selecting. 1071 1072 \sa setSelection(), selectedIndexes(), clearSelection() 966 1073 */ 967 1074 void QAbstractItemView::selectAll() … … 1192 1299 #ifndef QT_NO_DRAGANDDROP 1193 1300 /*! 1194 \property QAbstractItemView::showDropIndicator1195 \brief whether the drop indicator is shown when dragging items and dropping.1196 1197 \sa dragEnabled DragDropMode dragDropOverwriteMode acceptDrops1301 \property QAbstractItemView::showDropIndicator 1302 \brief whether the drop indicator is shown when dragging items and dropping. 1303 1304 \sa dragEnabled DragDropMode dragDropOverwriteMode acceptDrops 1198 1305 */ 1199 1306 … … 1211 1318 1212 1319 /*! 1213 \property QAbstractItemView::dragEnabled1214 \brief whether the view supports dragging of its own items1215 1216 \sa showDropIndicator DragDropMode dragDropOverwriteMode acceptDrops1320 \property QAbstractItemView::dragEnabled 1321 \brief whether the view supports dragging of its own items 1322 1323 \sa showDropIndicator DragDropMode dragDropOverwriteMode acceptDrops 1217 1324 */ 1218 1325 … … 1250 1357 1251 1358 /*! 1252 \property QAbstractItemView::dragDropMode1253 \brief the drag and drop event the view will act upon1254 1255 \since 4.21256 \sa showDropIndicator dragDropOverwriteMode1359 \property QAbstractItemView::dragDropMode 1360 \brief the drag and drop event the view will act upon 1361 1362 \since 4.2 1363 \sa showDropIndicator dragDropOverwriteMode 1257 1364 */ 1258 1365 void QAbstractItemView::setDragDropMode(DragDropMode behavior) … … 1287 1394 } 1288 1395 1396 /*! 1397 \property QAbstractItemView::defaultDropAction 1398 \brief the drop action that will be used by default in QAbstractItemView::drag() 1399 1400 If the property is not set, the drop action is CopyAction when the supported 1401 actions support CopyAction. 1402 1403 \since 4.6 1404 \sa showDropIndicator dragDropOverwriteMode 1405 */ 1406 void QAbstractItemView::setDefaultDropAction(Qt::DropAction dropAction) 1407 { 1408 Q_D(QAbstractItemView); 1409 d->defaultDropAction = dropAction; 1410 } 1411 1412 Qt::DropAction QAbstractItemView::defaultDropAction() const 1413 { 1414 Q_D(const QAbstractItemView); 1415 return d->defaultDropAction; 1416 } 1417 1289 1418 #endif // QT_NO_DRAGANDDROP 1290 1419 1291 1420 /*! 1292 \property QAbstractItemView::alternatingRowColors1293 \brief whether to draw the background using alternating colors1294 1295 If this property is true, the item background will be drawn using1296 QPalette::Base and QPalette::AlternateBase; otherwise the background1297 will be drawn using the QPalette::Base color.1298 1299 By default, this property is false.1421 \property QAbstractItemView::alternatingRowColors 1422 \brief whether to draw the background using alternating colors 1423 1424 If this property is true, the item background will be drawn using 1425 QPalette::Base and QPalette::AlternateBase; otherwise the background 1426 will be drawn using the QPalette::Base color. 1427 1428 By default, this property is false. 1300 1429 */ 1301 1430 void QAbstractItemView::setAlternatingRowColors(bool enable) … … 1338 1467 \property QAbstractItemView::textElideMode 1339 1468 1340 \brief the theposition of the "..." in elided text.1469 \brief the position of the "..." in elided text. 1341 1470 1342 1471 The default value for all item views is Qt::ElideRight. … … 1381 1510 break; 1382 1511 case QEvent::Show: 1383 { 1384 d->executePostedLayout(); //make sure we set the layout properly 1512 d->executePostedLayout(); //make sure we set the layout properly 1513 if (d->shouldScrollToCurrentOnShow) { 1514 d->shouldScrollToCurrentOnShow = false; 1385 1515 const QModelIndex current = currentIndex(); 1386 1516 if (current.isValid() && (d->state == QAbstractItemView::EditingState || d->autoScroll)) … … 1401 1531 d->checkPersistentEditorFocus(); 1402 1532 break; 1533 case QEvent::FontChange: 1534 d->doDelayedItemsLayout(); // the size of the items will change 1535 break; 1403 1536 default: 1404 1537 break; … … 1419 1552 Q_D(QAbstractItemView); 1420 1553 switch (event->type()) { 1421 case QEvent::HoverEnter: { 1422 QHoverEvent *he = static_cast<QHoverEvent*>(event); 1423 d->hover = indexAt(he->pos()); 1424 d->viewport->update(visualRect(d->hover)); 1425 break; } 1426 case QEvent::HoverLeave: { 1427 d->viewport->update(visualRect(d->hover)); // update old 1428 d->hover = QModelIndex(); 1429 break; } 1430 case QEvent::HoverMove: { 1431 QHoverEvent *he = static_cast<QHoverEvent*>(event); 1432 QModelIndex old = d->hover; 1433 d->hover = indexAt(he->pos()); 1434 if (d->hover != old) 1435 d->viewport->update(visualRect(old)|visualRect(d->hover)); 1436 break; } 1554 case QEvent::HoverMove: 1555 case QEvent::HoverEnter: 1556 d->setHoverIndex(indexAt(static_cast<QHoverEvent*>(event)->pos())); 1557 break; 1558 case QEvent::HoverLeave: 1559 d->setHoverIndex(QModelIndex()); 1560 break; 1437 1561 case QEvent::Enter: 1438 1562 d->viewportEnteredNeeded = true; 1439 1563 break; 1440 1564 case QEvent::Leave: 1565 #ifndef QT_NO_STATUSTIP 1566 if (d->shouldClearStatusTip && d->parent) { 1567 QString empty; 1568 QStatusTipEvent tip(empty); 1569 QApplication::sendEvent(d->parent, &tip); 1570 d->shouldClearStatusTip = false; 1571 } 1572 #endif 1441 1573 d->enteredIndex = QModelIndex(); 1442 1574 break; … … 1492 1624 d->pressedModifiers = event->modifiers(); 1493 1625 QItemSelectionModel::SelectionFlags command = selectionCommand(index, event); 1626 d->noSelectionOnMousePress = command == QItemSelectionModel::NoUpdate || !index.isValid(); 1494 1627 QPoint offset = d->offset(); 1495 1628 if ((command & QItemSelectionModel::Current) == 0) 1496 1629 d->pressedPosition = pos + offset; 1497 1498 if (d->pressedPosition == QPoint(-1, -1)) 1630 else if (!indexAt(d->pressedPosition - offset).isValid()) 1499 1631 d->pressedPosition = visualRect(currentIndex()).center() + offset; 1500 1632 … … 1510 1642 d->autoScroll = autoScroll; 1511 1643 QRect rect(d->pressedPosition - offset, pos); 1644 if (command.testFlag(QItemSelectionModel::Toggle)) { 1645 command &= ~QItemSelectionModel::Toggle; 1646 d->ctrlDragSelectionFlag = d->selectionModel->isSelected(index) ? QItemSelectionModel::Deselect : QItemSelectionModel::Select; 1647 command |= d->ctrlDragSelectionFlag; 1648 } 1512 1649 setSelection(rect, command); 1513 1650 … … 1553 1690 #endif // QT_NO_DRAGANDDROP 1554 1691 1555 Q ModelIndex index = indexAt(bottomRight);1692 QPersistentModelIndex index = indexAt(bottomRight); 1556 1693 QModelIndex buddy = d->model->buddy(d->pressedIndex); 1557 1694 if ((state() == EditingState && d->hasEditor(buddy)) … … 1564 1701 topLeft = bottomRight; 1565 1702 1566 if (d->viewportEnteredNeeded || d->enteredIndex != index) { 1567 d->viewportEnteredNeeded = false; 1568 1569 // signal handlers may change the model 1570 QPersistentModelIndex persistent = index; 1571 if (persistent.isValid()) { 1572 emit entered(persistent); 1573 #ifndef QT_NO_STATUSTIP 1574 QString statustip = d->model->data(persistent, Qt::StatusTipRole).toString(); 1575 if (parent() && !statustip.isEmpty()) { 1576 QStatusTipEvent tip(statustip); 1577 QApplication::sendEvent(parent(), &tip); 1578 } 1579 #endif 1580 } else { 1581 #ifndef QT_NO_STATUSTIP 1582 if (parent()) { 1583 QString emptyString; 1584 QStatusTipEvent tip(emptyString); 1585 QApplication::sendEvent(parent(), &tip); 1586 } 1587 #endif 1588 emit viewportEntered(); 1589 } 1590 d->enteredIndex = persistent; 1591 index = persistent; 1592 } 1703 d->checkMouseMove(index); 1593 1704 1594 1705 #ifndef QT_NO_DRAGANDDROP 1595 if ( index.isValid()1706 if (d->pressedIndex.isValid() 1596 1707 && d->dragEnabled 1597 1708 && (state() != DragSelectingState) … … 1606 1717 setState(DragSelectingState); 1607 1718 QItemSelectionModel::SelectionFlags command = selectionCommand(index, event); 1719 if (d->ctrlDragSelectionFlag != QItemSelectionModel::NoUpdate && command.testFlag(QItemSelectionModel::Toggle)) { 1720 command &= ~QItemSelectionModel::Toggle; 1721 command |= d->ctrlDragSelectionFlag; 1722 } 1608 1723 1609 1724 // Do the normalize ourselves, since QRect::normalized() is flawed 1610 1725 QRect selectionRect = QRect(topLeft, bottomRight); 1611 QPersistentModelIndex persistent = index;1612 1726 setSelection(selectionRect, command); 1613 1727 1614 1728 // set at the end because it might scroll the view 1615 if ( persistent.isValid()1616 && ( persistent!= d->selectionModel->currentIndex())1617 && d->isIndexEnabled( persistent))1618 d->selectionModel->setCurrentIndex( persistent, QItemSelectionModel::NoUpdate);1729 if (index.isValid() 1730 && (index != d->selectionModel->currentIndex()) 1731 && d->isIndexEnabled(index)) 1732 d->selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate); 1619 1733 } 1620 1734 } … … 1638 1752 && d->isIndexEnabled(index) 1639 1753 && d->sendDelegateEvent(index, event)) 1640 d->viewport->update(visualRect(index));1754 update(index); 1641 1755 return; 1642 1756 } … … 1647 1761 bool edited = edit(index, trigger, event); 1648 1762 1649 if (d->selectionModel) 1763 d->ctrlDragSelectionFlag = QItemSelectionModel::NoUpdate; 1764 1765 if (d->selectionModel && d->noSelectionOnMousePress) { 1766 d->noSelectionOnMousePress = false; 1650 1767 d->selectionModel->select(index, selectionCommand(index, event)); 1768 } 1651 1769 1652 1770 setState(NoState); … … 1951 2069 Q_D(QAbstractItemView); 1952 2070 QAbstractScrollArea::focusInEvent(event); 1953 if (selectionModel() 2071 2072 const QItemSelectionModel* model = selectionModel(); 2073 const bool currentIndexValid = currentIndex().isValid(); 2074 2075 if (model 1954 2076 && !d->currentIndexSet 1955 && !currentIndex ().isValid()) {2077 && !currentIndexValid) { 1956 2078 bool autoScroll = d->autoScroll; 1957 2079 d->autoScroll = false; … … 1961 2083 d->autoScroll = autoScroll; 1962 2084 } 2085 2086 if (model && currentIndexValid) { 2087 if (currentIndex().flags() != Qt::ItemIsEditable) 2088 setAttribute(Qt::WA_InputMethodEnabled, false); 2089 else 2090 setAttribute(Qt::WA_InputMethodEnabled); 2091 } 2092 2093 if (!currentIndexValid) 2094 setAttribute(Qt::WA_InputMethodEnabled, false); 2095 1963 2096 d->viewport->update(); 1964 2097 } … … 1999 2132 if (!hasEditFocus()) { 2000 2133 setEditFocus(true); 2134 #ifdef QT_SOFTKEYS_ENABLED 2135 addAction(d->doneSoftKey); 2136 #endif 2001 2137 return; 2002 2138 } … … 2004 2140 break; 2005 2141 case Qt::Key_Back: 2006 if (QApplication::keypadNavigationEnabled() && hasEditFocus()) 2142 if (QApplication::keypadNavigationEnabled() && hasEditFocus()) { 2143 #ifdef QT_SOFTKEYS_ENABLED 2144 removeAction(d->doneSoftKey); 2145 #endif 2007 2146 setEditFocus(false); 2008 else2147 } else { 2009 2148 event->ignore(); 2149 } 2010 2150 return; 2011 2151 default: … … 2074 2214 if (command & QItemSelectionModel::Current) { 2075 2215 d->selectionModel->setCurrentIndex(newCurrent, QItemSelectionModel::NoUpdate); 2076 if ( d->pressedPosition == QPoint(-1, -1))2077 d->pressedPosition = visualRect(oldCurrent).center() ;2216 if (!indexAt(d->pressedPosition - d->offset()).isValid()) 2217 d->pressedPosition = visualRect(oldCurrent).center() + d->offset(); 2078 2218 QRect rect(d->pressedPosition - d->offset(), visualRect(newCurrent).center()); 2079 2219 setSelection(rect, command); … … 2081 2221 d->selectionModel->setCurrentIndex(newCurrent, command); 2082 2222 d->pressedPosition = visualRect(newCurrent).center() + d->offset(); 2223 // We copy the same behaviour as for mousePressEvent(). 2224 QRect rect(d->pressedPosition - d->offset(), QSize(1, 1)); 2225 setSelection(rect, command); 2083 2226 } 2084 2227 return; … … 2098 2241 case Qt::Key_Left: 2099 2242 case Qt::Key_Right: 2243 #ifdef QT_KEYPAD_NAVIGATION 2244 if (QApplication::navigationMode() == Qt::NavigationModeKeypadDirectional) { 2245 event->accept(); // don't change horizontal focus in directional mode 2246 break; 2247 } 2248 #endif // QT_KEYPAD_NAVIGATION 2100 2249 case Qt::Key_Home: 2101 2250 case Qt::Key_End: … … 2161 2310 #endif 2162 2311 bool modified = (event->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier)); 2163 if (!event->text().isEmpty() && !modified) { 2164 if (!edit(currentIndex(), AnyKeyPressed, event)) 2165 keyboardSearch(event->text()); 2166 } 2167 event->ignore(); 2312 if (!event->text().isEmpty() && !modified && !edit(currentIndex(), AnyKeyPressed, event)) { 2313 keyboardSearch(event->text()); 2314 event->accept(); 2315 } else { 2316 event->ignore(); 2317 } 2168 2318 break; } 2169 2319 } … … 2191 2341 { 2192 2342 Q_D(QAbstractItemView); 2193 if (event->timerId() == d->autoScrollTimer.timerId()) 2343 if (event->timerId() == d->fetchMoreTimer.timerId()) 2344 d->fetchMore(); 2345 else if (event->timerId() == d->delayedReset.timerId()) 2346 reset(); 2347 else if (event->timerId() == d->autoScrollTimer.timerId()) 2194 2348 doAutoScroll(); 2195 2349 else if (event->timerId() == d->updateTimer.timerId()) … … 2246 2400 2247 2401 \value OnViewport The item will be dropped onto a region of the viewport with 2248 no items. The way each view handles items dropped onto the viewport depends on2249 the behavior of the underlying model in use.2402 no items. The way each view handles items dropped onto the viewport depends on 2403 the behavior of the underlying model in use. 2250 2404 */ 2251 2405 … … 2264 2418 2265 2419 /*! 2266 This convenience function returns a list of all selected and2267 non-hidden item indexes in the view. The list contains no2268 duplicates, and is not sorted.2269 2270 \sa QItemSelectionModel::selectedIndexes()2420 This convenience function returns a list of all selected and 2421 non-hidden item indexes in the view. The list contains no 2422 duplicates, and is not sorted. 2423 2424 \sa QItemSelectionModel::selectedIndexes() 2271 2425 */ 2272 2426 QModelIndexList QAbstractItemView::selectedIndexes() const … … 2321 2475 2322 2476 if (d->sendDelegateEvent(index, event)) { 2323 d->viewport->update(visualRect(index));2477 update(index); 2324 2478 return true; 2325 2479 } … … 2350 2504 2351 2505 /*! 2352 \internal2353 Updates the data shown in the open editor widgets in the view.2506 \internal 2507 Updates the data shown in the open editor widgets in the view. 2354 2508 */ 2355 2509 void QAbstractItemView::updateEditorData() … … 2360 2514 2361 2515 /*! 2362 \internal2363 Updates the geometry of the open editor widgets in the view.2516 \internal 2517 Updates the geometry of the open editor widgets in the view. 2364 2518 */ 2365 2519 void QAbstractItemView::updateEditorGeometries() … … 2393 2547 //we release the editor outside of the loop because it might change the focus and try 2394 2548 //to change the d->editors list. 2395 for each(QWidget *editor, editorsToRelease) {2396 d->releaseEditor(editor );2549 for (int i = 0; i < editorsToRelease.count(); ++i) { 2550 d->releaseEditor(editorsToRelease.at(i)); 2397 2551 } 2398 2552 } … … 2406 2560 { 2407 2561 updateEditorGeometries(); 2408 QMetaObject::invokeMethod(this, "_q_fetchMore", Qt::QueuedConnection);2409 } 2410 2411 /*! 2412 \internal2562 d_func()->fetchMoreTimer.start(0, this); //fetch more later 2563 } 2564 2565 /*! 2566 \internal 2413 2567 */ 2414 2568 void QAbstractItemView::verticalScrollbarValueChanged(int value) … … 2417 2571 if (verticalScrollBar()->maximum() == value && d->model->canFetchMore(d->root)) 2418 2572 d->model->fetchMore(d->root); 2419 } 2420 2421 /*! 2422 \internal 2573 QPoint posInVp = viewport()->mapFromGlobal(QCursor::pos()); 2574 if (viewport()->rect().contains(posInVp)) 2575 d->checkMouseMove(posInVp); 2576 } 2577 2578 /*! 2579 \internal 2423 2580 */ 2424 2581 void QAbstractItemView::horizontalScrollbarValueChanged(int value) … … 2427 2584 if (horizontalScrollBar()->maximum() == value && d->model->canFetchMore(d->root)) 2428 2585 d->model->fetchMore(d->root); 2586 QPoint posInVp = viewport()->mapFromGlobal(QCursor::pos()); 2587 if (viewport()->rect().contains(posInVp)) 2588 d->checkMouseMove(posInVp); 2429 2589 } 2430 2590 … … 2521 2681 2522 2682 /*! 2523 Commit the data in the \a editor to the model.2524 2525 \sa closeEditor()2683 Commit the data in the \a editor to the model. 2684 2685 \sa closeEditor() 2526 2686 */ 2527 2687 void QAbstractItemView::commitData(QWidget *editor) … … 2542 2702 2543 2703 /*! 2544 This function is called when the given \a editor has been destroyed.2545 2546 \sa closeEditor()2704 This function is called when the given \a editor has been destroyed. 2705 2706 \sa closeEditor() 2547 2707 */ 2548 2708 void QAbstractItemView::editorDestroyed(QObject *editor) … … 2615 2775 2616 2776 /*! 2617 Moves to and selects the item best matching the string \a search.2618 If no item is found nothing happens.2619 2620 In the default implementation, the search is reset if \a search is empty, or2621 the time interval since the last search has exceeded2622 QApplication::keyboardInputInterval().2777 Moves to and selects the item best matching the string \a search. 2778 If no item is found nothing happens. 2779 2780 In the default implementation, the search is reset if \a search is empty, or 2781 the time interval since the last search has exceeded 2782 QApplication::keyboardInputInterval(). 2623 2783 */ 2624 2784 void QAbstractItemView::keyboardSearch(const QString &search) … … 2635 2795 || (d->keyboardInputTime.msecsTo(now) > QApplication::keyboardInputInterval())) { 2636 2796 d->keyboardInput = search; 2637 skipRow = true;2797 skipRow = currentIndex().isValid(); //if it is not valid we should really start at QModelIndex(0,0) 2638 2798 } else { 2639 2799 d->keyboardInput += search; … … 2662 2822 QModelIndexList match; 2663 2823 QModelIndex firstMatch; 2824 QModelIndex startMatch; 2664 2825 QModelIndexList previous; 2665 2826 do { … … 2674 2835 break; 2675 2836 } 2676 2677 2678 2837 int row = firstMatch.row() + 1; 2838 if (row >= d->model->rowCount(firstMatch.parent())) 2839 row = 0; 2679 2840 current = firstMatch.sibling(row, firstMatch.column()); 2841 2842 //avoid infinite loop if all the matching items are disabled. 2843 if (!startMatch.isValid()) 2844 startMatch = firstMatch; 2845 else if (startMatch == firstMatch) 2846 break; 2680 2847 } 2681 2848 } while (current != start && firstMatch.isValid()); … … 2718 2885 if (row < 0 || row >= d->model->rowCount() || !model()) 2719 2886 return -1; 2887 2888 ensurePolished(); 2720 2889 2721 2890 QStyleOptionViewItemV4 option = d->viewOptionsV4(); … … 2748 2917 return -1; 2749 2918 2919 ensurePolished(); 2920 2750 2921 QStyleOptionViewItemV4 option = d->viewOptionsV4(); 2751 2922 int width = 0; … … 2783 2954 2784 2955 /*! 2785 Closes the persistent editor for the item at the given \a index.2786 2787 \sa openPersistentEditor()2956 Closes the persistent editor for the item at the given \a index. 2957 2958 \sa openPersistentEditor() 2788 2959 */ 2789 2960 void QAbstractItemView::closePersistentEditor(const QModelIndex &index) … … 2840 3011 d->addEditor(index, widget, true); 2841 3012 widget->show(); 3013 dataChanged(index, index); // update the geometry 2842 3014 if (!d->delayedPendingLayout) 2843 3015 widget->setGeometry(visualRect(index)); 2844 dataChanged(index, index); // update the geometry2845 3016 } 2846 3017 } … … 2897 3068 { 2898 3069 Q_D(QAbstractItemView); 2899 if (index.isValid()) 2900 d->viewport->update(visualRect(index)); 3070 if (index.isValid()) { 3071 const QRect rect = visualRect(index); 3072 //this test is important for peformance reason 3073 //For example in dataChanged we simply update all the cells without checking 3074 //it can be a major bottleneck to update rects that aren't even part of the viewport 3075 if (d->viewport->rect().intersects(rect)) 3076 d->viewport->update(rect); 3077 } 2901 3078 } 2902 3079 … … 2922 3099 if (isVisible() && !d->delayedPendingLayout) { 2923 3100 // otherwise the items will be update later anyway 2924 d->viewport->update(visualRect(topLeft));3101 update(topLeft); 2925 3102 } 2926 3103 return; … … 2943 3120 { 2944 3121 if (!isVisible()) 2945 QMetaObject::invokeMethod(this, "_q_fetchMore", Qt::QueuedConnection);3122 d_func()->fetchMoreTimer.start(0, this); //fetch more later 2946 3123 else 2947 3124 updateEditorGeometries(); … … 3100 3277 void QAbstractItemViewPrivate::_q_modelDestroyed() 3101 3278 { 3102 Q_Q(QAbstractItemView);3103 3279 model = QAbstractItemModelPrivate::staticEmptyModel(); 3104 QMetaObject::invokeMethod(q, "reset", Qt::QueuedConnection);3280 doDelayedReset(); 3105 3281 } 3106 3282 … … 3127 3303 Q_D(QAbstractItemView); 3128 3304 if (isVisible() && updatesEnabled()) { 3129 d->setDirtyRegion(visualRegionForSelection(deselected)); 3130 d->setDirtyRegion(visualRegionForSelection(selected)); 3131 d->updateDirtyRegion(); 3305 d->viewport->update(visualRegionForSelection(deselected) | visualRegionForSelection(selected)); 3132 3306 } 3133 3307 } … … 3157 3331 } 3158 3332 if (isVisible()) { 3159 d->setDirtyRegion(visualRect(previous)); 3160 d->updateDirtyRegion(); 3161 } 3162 } 3163 if (isVisible() && current.isValid() && !d->autoScrollTimer.isActive()) { 3164 if (d->autoScroll) 3165 scrollTo(current); 3166 d->setDirtyRegion(visualRect(current)); 3167 d->updateDirtyRegion(); 3168 edit(current, CurrentChanged, 0); 3169 if (current.row() == (d->model->rowCount(d->root) - 1)) 3170 d->_q_fetchMore(); 3333 update(previous); 3334 } 3335 } 3336 3337 if (current.isValid() && !d->autoScrollTimer.isActive()) { 3338 if (isVisible()) { 3339 if (d->autoScroll) 3340 scrollTo(current); 3341 update(current); 3342 edit(current, CurrentChanged, 0); 3343 if (current.row() == (d->model->rowCount(d->root) - 1)) 3344 d->fetchMore(); 3345 } else { 3346 d->shouldScrollToCurrentOnShow = d->autoScroll; 3347 } 3171 3348 } 3172 3349 } … … 3192 3369 drag->setHotSpot(d->pressedPosition - rect.topLeft()); 3193 3370 Qt::DropAction defaultDropAction = Qt::IgnoreAction; 3194 if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove) 3371 if (d->defaultDropAction != Qt::IgnoreAction && (supportedActions & d->defaultDropAction)) 3372 defaultDropAction = d->defaultDropAction; 3373 else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove) 3195 3374 defaultDropAction = Qt::CopyAction; 3196 3375 if (drag->exec(supportedActions, defaultDropAction) == Qt::MoveAction) … … 3212 3391 option.font = font(); 3213 3392 3214 #if def Q_WS_WIN3215 // Note this is currently required on Windows3216 // do give non-focused item views inactive appearance3393 #ifndef Q_WS_MAC 3394 // On mac the focus appearance follows window activation 3395 // not widget activation 3217 3396 if (!hasFocus()) 3218 3397 option.state &= ~QStyle::State_Active; … … 3313 3492 3314 3493 /*! 3315 Prepares the view for scrolling by (\a{dx},\a{dy}) pixels by moving the dirty regions in the3316 opposite direction. You only need to call this function if you are implementing a scrolling3317 viewport in your view subclass.3318 3319 If you implement scrollContentsBy() in a subclass of QAbstractItemView, call this function3320 before you call QWidget::scroll() on the viewport. Alternatively, just call update().3321 3322 \sa scrollContentsBy(), dirtyRegionOffset(), setDirtyRegion()3494 Prepares the view for scrolling by (\a{dx},\a{dy}) pixels by moving the dirty regions in the 3495 opposite direction. You only need to call this function if you are implementing a scrolling 3496 viewport in your view subclass. 3497 3498 If you implement scrollContentsBy() in a subclass of QAbstractItemView, call this function 3499 before you call QWidget::scroll() on the viewport. Alternatively, just call update(). 3500 3501 \sa scrollContentsBy(), dirtyRegionOffset(), setDirtyRegion() 3323 3502 */ 3324 3503 void QAbstractItemView::scrollDirtyRegion(int dx, int dy) … … 3329 3508 3330 3509 /*! 3331 Returns the offset of the dirty regions in the view.3332 3333 If you use scrollDirtyRegion() and implement a paintEvent() in a subclass of3334 QAbstractItemView, you should translate the area given by the paint event with3335 the offset returned from this function.3336 3337 \sa scrollDirtyRegion(), setDirtyRegion()3510 Returns the offset of the dirty regions in the view. 3511 3512 If you use scrollDirtyRegion() and implement a paintEvent() in a subclass of 3513 QAbstractItemView, you should translate the area given by the paint event with 3514 the offset returned from this function. 3515 3516 \sa scrollDirtyRegion(), setDirtyRegion() 3338 3517 */ 3339 3518 QPoint QAbstractItemView::dirtyRegionOffset() const … … 3348 3527 void QAbstractItemView::startAutoScroll() 3349 3528 { 3350 Q_D(QAbstractItemView); 3351 // ### it would be nice to make this into a style hint one day 3352 int scrollInterval = (verticalScrollMode() == QAbstractItemView::ScrollPerItem) ? 150 : 50; 3353 d->autoScrollTimer.start(scrollInterval, this); 3354 d->autoScrollCount = 0; 3529 d_func()->startAutoScroll(); 3355 3530 } 3356 3531 … … 3360 3535 void QAbstractItemView::stopAutoScroll() 3361 3536 { 3362 Q_D(QAbstractItemView); 3363 d->autoScrollTimer.stop(); 3364 d->autoScrollCount = 0; 3537 d_func()->stopAutoScroll(); 3365 3538 } 3366 3539 … … 3507 3680 const bool controlKeyPressed = modifiers & Qt::ControlModifier; 3508 3681 if (((index == pressedIndex && selectionModel->isSelected(index)) 3509 3510 && !shiftKeyPressed && !controlKeyPressed && !rightButtonPressed)3682 || !index.isValid()) && state != QAbstractItemView::DragSelectingState 3683 && !shiftKeyPressed && !controlKeyPressed && (!rightButtonPressed || !index.isValid())) 3511 3684 return QItemSelectionModel::ClearAndSelect|selectionBehaviorFlags(); 3512 3685 return QItemSelectionModel::NoUpdate; … … 3527 3700 case Qt::Key_PageDown: 3528 3701 case Qt::Key_Tab: 3702 if (modifiers & Qt::ControlModifier 3529 3703 #ifdef QT_KEYPAD_NAVIGATION 3530 return QItemSelectionModel::NoUpdate; 3531 #else 3532 if (modifiers & Qt::ControlModifier) 3704 // Preserve historical tab order navigation behavior 3705 || QApplication::navigationMode() == Qt::NavigationModeKeypadTabOrder 3706 #endif 3707 ) 3533 3708 return QItemSelectionModel::NoUpdate; 3534 #endif3535 3709 break; 3536 3710 case Qt::Key_Select: … … 3586 3760 } 3587 3761 3588 void QAbstractItemViewPrivate::_q_fetchMore() 3589 { 3762 void QAbstractItemViewPrivate::fetchMore() 3763 { 3764 fetchMoreTimer.stop(); 3590 3765 if (!model->canFetchMore(root)) 3591 3766 return; … … 3738 3913 3739 3914 Either remove the selected rows or clear them 3740 3915 */ 3741 3916 void QAbstractItemViewPrivate::clearOrRemove() 3742 3917 { … … 3774 3949 When persistent aeditor gets/loses focus, we need to check 3775 3950 and setcorrectly the current index. 3776 3951 */ 3777 3952 void QAbstractItemViewPrivate::checkPersistentEditorFocus() 3778 3953 { 3779 3954 Q_Q(QAbstractItemView); 3780 if (QWidget *widget = qApp->focusWidget()) {3955 if (QWidget *widget = QApplication::focusWidget()) { 3781 3956 if (persistent.contains(widget)) { 3782 3957 //a persistent editor has gained the focus … … 3860 4035 } 3861 4036 4037 /* 4038 \internal 4039 4040 returns the pair QRect/QModelIndex that should be painted on the viewports's rect 4041 */ 4042 4043 QItemViewPaintPairs QAbstractItemViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const 4044 { 4045 Q_ASSERT(r); 4046 Q_Q(const QAbstractItemView); 4047 QRect &rect = *r; 4048 const QRect viewportRect = viewport->rect(); 4049 QItemViewPaintPairs ret; 4050 for (int i = 0; i < indexes.count(); ++i) { 4051 const QModelIndex &index = indexes.at(i); 4052 const QRect current = q->visualRect(index); 4053 if (current.intersects(viewportRect)) { 4054 ret += qMakePair(current, index); 4055 rect |= current; 4056 } 4057 } 4058 rect &= viewportRect; 4059 return ret; 4060 } 4061 3862 4062 QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes, QRect *r) const 3863 4063 { 3864 Q_Q(const QAbstractItemView); 3865 QRect rect = q->visualRect(indexes.at(0)); 3866 QList<QRect> rects; 3867 for (int i = 0; i < indexes.count(); ++i) { 3868 rects.append(q->visualRect(indexes.at(i))); 3869 rect |= rects.at(i); 3870 } 3871 rect = rect.intersected(viewport->rect()); 3872 if (rect.width() <= 0 || rect.height() <= 0) 4064 Q_ASSERT(r); 4065 QItemViewPaintPairs paintPairs = draggablePaintPairs(indexes, r); 4066 if (paintPairs.isEmpty()) 3873 4067 return QPixmap(); 3874 Q Image image(rect.size(), QImage::Format_ARGB32_Premultiplied);3875 image.fill(0);3876 QPainter painter(& image);4068 QPixmap pixmap(r->size()); 4069 pixmap.fill(Qt::transparent); 4070 QPainter painter(&pixmap); 3877 4071 QStyleOptionViewItemV4 option = viewOptionsV4(); 3878 4072 option.state |= QStyle::State_Selected; 3879 for (int j = 0; j < indexes.count(); ++j) { 3880 option.rect = QRect(rects.at(j).topLeft() - rect.topLeft(), rects.at(j).size()); 3881 delegateForIndex(indexes.at(j))->paint(&painter, option, indexes.at(j)); 3882 } 3883 painter.end(); 3884 if (r) *r = rect; 3885 return QPixmap::fromImage(image); 4073 for (int j = 0; j < paintPairs.count(); ++j) { 4074 option.rect = paintPairs.at(j).first.translated(-r->topLeft()); 4075 const QModelIndex ¤t = paintPairs.at(j).second; 4076 delegateForIndex(current)->paint(&painter, option, current); 4077 } 4078 return pixmap; 3886 4079 } 3887 4080 -
trunk/src/gui/itemviews/qabstractitemview.h
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 ** … … 75 75 Q_PROPERTY(bool dragDropOverwriteMode READ dragDropOverwriteMode WRITE setDragDropOverwriteMode) 76 76 Q_PROPERTY(DragDropMode dragDropMode READ dragDropMode WRITE setDragDropMode) 77 Q_PROPERTY(Qt::DropAction defaultDropAction READ defaultDropAction WRITE setDefaultDropAction) 77 78 #endif 78 79 Q_PROPERTY(bool alternatingRowColors READ alternatingRowColors WRITE setAlternatingRowColors) … … 182 183 void setDragDropMode(DragDropMode behavior); 183 184 DragDropMode dragDropMode() const; 184 #endif 185 186 void setDefaultDropAction(Qt::DropAction dropAction); 187 Qt::DropAction defaultDropAction() const; 188 #endif 189 185 190 void setAlternatingRowColors(bool enable); 186 191 bool alternatingRowColors() const; … … 354 359 Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed()) 355 360 Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged()) 356 Q_PRIVATE_SLOT(d_func(), void _q_ fetchMore())361 Q_PRIVATE_SLOT(d_func(), void _q_headerDataChanged()) 357 362 358 363 friend class QTreeViewPrivate; // needed to compile with MSVC 359 364 friend class QAccessibleItemRow; 365 friend class QListModeViewBase; 366 friend class QListViewPrivate; // needed to compile for Symbian emulator 360 367 }; 361 368 -
trunk/src/gui/itemviews/qabstractitemview_p.h
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 ** … … 62 62 #include "QtGui/qpainter.h" 63 63 #include "QtCore/qpair.h" 64 #include "QtCore/qtimer.h"65 #include "QtCore/qtimeline.h"66 64 #include "QtGui/qregion.h" 67 65 #include "QtCore/qdebug.h" 68 66 #include "QtGui/qpainter.h" 67 #include "QtCore/qbasictimer.h" 69 68 70 69 #ifndef QT_NO_ITEMVIEWS … … 87 86 88 87 }; 88 89 typedef QPair<QRect, QModelIndex> QItemViewPaintPair; 90 typedef QList<QItemViewPaintPair> QItemViewPaintPairs; 89 91 90 92 class QEmptyModel : public QAbstractItemModel … … 100 102 }; 101 103 102 class Q_ GUI_EXPORT QAbstractItemViewPrivate : public QAbstractScrollAreaPrivate104 class Q_AUTOTEST_EXPORT QAbstractItemViewPrivate : public QAbstractScrollAreaPrivate 103 105 { 104 106 Q_DECLARE_PUBLIC(QAbstractItemView) … … 110 112 void init(); 111 113 112 void _q_rowsRemoved(const QModelIndex &parent, int start, int end); 113 void _q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end); 114 void _q_columnsRemoved(const QModelIndex &parent, int start, int end); 115 void _q_columnsInserted(const QModelIndex &parent, int start, int end); 116 void _q_modelDestroyed(); 117 void _q_layoutChanged(); 118 void _q_fetchMore(); 114 virtual void _q_rowsRemoved(const QModelIndex &parent, int start, int end); 115 virtual void _q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end); 116 virtual void _q_columnsRemoved(const QModelIndex &parent, int start, int end); 117 virtual void _q_columnsInserted(const QModelIndex &parent, int start, int end); 118 virtual void _q_modelDestroyed(); 119 virtual void _q_layoutChanged(); 120 void _q_headerDataChanged() { doDelayedItemsLayout(); } 121 122 void fetchMore(); 119 123 120 124 bool shouldEdit(QAbstractItemView::EditTrigger trigger, const QModelIndex &index) const; … … 123 127 void doDelayedItemsLayout(int delay = 0); 124 128 void interruptDelayedItemsLayout() const; 129 130 void startAutoScroll() 131 { // ### it would be nice to make this into a style hint one day 132 int scrollInterval = (verticalScrollMode == QAbstractItemView::ScrollPerItem) ? 150 : 50; 133 autoScrollTimer.start(scrollInterval, q_func()); 134 autoScrollCount = 0; 135 } 136 void stopAutoScroll() { autoScrollTimer.stop(); autoScrollCount = 0;} 137 125 138 126 139 bool dropOn(QDropEvent *event, int *row, int *col, QModelIndex *index); … … 140 153 virtual void selectAll(QItemSelectionModel::SelectionFlags command); 141 154 155 void setHoverIndex(const QPersistentModelIndex &index); 156 157 void checkMouseMove(const QPersistentModelIndex &index); 158 inline void checkMouseMove(const QPoint &pos) { checkMouseMove(q_func()->indexAt(pos)); } 159 142 160 inline QItemSelectionModel::SelectionFlags selectionBehaviorFlags() const 143 161 { … … 150 168 151 169 #ifndef QT_NO_DRAGANDDROP 152 QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const; 170 virtual QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const; 171 153 172 inline bool canDecode(QDropEvent *e) const { 154 173 QStringList modelTypes = model->mimeTypes(); … … 174 193 } 175 194 } 195 176 196 #endif 197 virtual QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const; 177 198 178 199 inline void releaseEditor(QWidget *editor) const { … … 219 240 void checkPersistentEditorFocus(); 220 241 221 QPixmap renderToPixmap(const QModelIndexList &indexes, QRect *r = 0) const;242 QPixmap renderToPixmap(const QModelIndexList &indexes, QRect *r) const; 222 243 223 244 inline QPoint offset() const { … … 299 320 return ref; 300 321 } 301 322 302 323 /** 303 324 * return true if the index is registered as a QPersistentModelIndex … … 305 326 inline bool isPersistent(const QModelIndex &index) const 306 327 { 307 return static_cast<QAbstractItemModelPrivate *>(model->d_ptr )->persistent.indexes.contains(index);328 return static_cast<QAbstractItemModelPrivate *>(model->d_ptr.data())->persistent.indexes.contains(index); 308 329 } 309 330 … … 311 332 312 333 QStyleOptionViewItemV4 viewOptionsV4() const; 334 335 void doDelayedReset() 336 { 337 //we delay the reset of the timer because some views (QTableView) 338 //with headers can't handle the fact that the model has been destroyed 339 //all _q_modelDestroyed slots must have been called 340 if (!delayedReset.isActive()) 341 delayedReset.start(0, q_func()); 342 } 313 343 314 344 QAbstractItemModel *model; … … 317 347 QMap<int, QPointer<QAbstractItemDelegate> > columnDelegates; 318 348 QPointer<QItemSelectionModel> selectionModel; 349 QItemSelectionModel::SelectionFlag ctrlDragSelectionFlag; 350 bool noSelectionOnMousePress; 319 351 320 352 QAbstractItemView::SelectionMode selectionMode; … … 330 362 QPoint pressedPosition; 331 363 bool pressedAlreadySelected; 332 333 //forces the next mouseMoveEvent to send the viewportEntered signal 364 365 //forces the next mouseMoveEvent to send the viewportEntered signal 334 366 //if the mouse is over the viewport and not over an item 335 367 bool viewportEnteredNeeded; … … 351 383 bool overwrite; 352 384 QAbstractItemView::DropIndicatorPosition dropIndicatorPosition; 385 Qt::DropAction defaultDropAction; 386 #endif 387 388 #ifdef QT_SOFTKEYS_ENABLED 389 QAction *doneSoftKey; 353 390 #endif 354 391 … … 360 397 int autoScrollMargin; 361 398 int autoScrollCount; 399 bool shouldScrollToCurrentOnShow; //used to know if we should scroll to current on show event 400 bool shouldClearStatusTip; //if there is a statustip currently shown that need to be cleared when leaving. 362 401 363 402 bool alternatingColors; … … 372 411 QBasicTimer delayedEditing; 373 412 QBasicTimer delayedAutoScroll; //used when an item is clicked 374 Q TimeLine timeline;413 QBasicTimer delayedReset; 375 414 376 415 QAbstractItemView::ScrollMode verticalScrollMode; … … 384 423 private: 385 424 mutable QBasicTimer delayedLayout; 425 mutable QBasicTimer fetchMoreTimer; 386 426 }; 387 427 -
trunk/src/gui/itemviews/qabstractproxymodel.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 ** -
trunk/src/gui/itemviews/qabstractproxymodel.h
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 ** -
trunk/src/gui/itemviews/qabstractproxymodel_p.h
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 ** -
trunk/src/gui/itemviews/qbsptree.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 ** -
trunk/src/gui/itemviews/qbsptree_p.h
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 ** -
trunk/src/gui/itemviews/qcolumnview.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 ** … … 53 53 #include <qpainter.h> 54 54 #include <qdebug.h> 55 #include <qpainterpath.h>56 55 57 56 QT_BEGIN_NAMESPACE … … 65 64 \ingroup model-view 66 65 \ingroup advanced 67 \mainclass 66 68 67 69 68 QColumnView displays a model in a number of QListViews, one for each … … 109 108 Q_Q(QColumnView); 110 109 q->setTextElideMode(Qt::ElideMiddle); 111 q->connect(¤tAnimation, SIGNAL(frameChanged(int)), 112 q->horizontalScrollBar(), SLOT(setValue(int))); 113 q->connect(¤tAnimation, SIGNAL(finished()), q, SLOT(_q_changeCurrentColumn())); 110 #ifndef QT_NO_ANIMATION 111 QObject::connect(¤tAnimation, SIGNAL(finished()), q, SLOT(_q_changeCurrentColumn())); 112 currentAnimation.setDuration(ANIMATION_DURATION_MSEC); 113 currentAnimation.setTargetObject(hbar); 114 currentAnimation.setPropertyName("value"); 115 currentAnimation.setEasingCurve(QEasingCurve::InOutQuad); 116 #endif //QT_NO_ANIMATION 114 117 delete itemDelegate; 115 118 q->setItemDelegate(new QColumnViewDelegate(q)); … … 261 264 return; 262 265 263 if (d->currentAnimation.state() == QTimeLine::Running) 266 #ifndef QT_NO_ANIMATION 267 if (d->currentAnimation.state() == QPropertyAnimation::Running) 264 268 return; 265 269 266 270 d->currentAnimation.stop(); 271 #endif //QT_NO_ANIMATION 267 272 268 273 // Fill up what is needed to get to index … … 327 332 } 328 333 329 //horizontalScrollBar()->setValue(newScrollbarValue); 330 //d->_q_changeCurrentColumn(); 331 //return; 332 // or do the following currentAnimation 333 334 int oldValue = horizontalScrollBar()->value(); 335 336 if (oldValue < newScrollbarValue) { 337 d->currentAnimation.setFrameRange(oldValue, newScrollbarValue); 338 d->currentAnimation.setDirection(QTimeLine::Forward); 339 d->currentAnimation.setCurrentTime(0); 340 } else { 341 d->currentAnimation.setFrameRange(newScrollbarValue, oldValue); 342 d->currentAnimation.setDirection(QTimeLine::Backward); 343 } 334 #ifndef QT_NO_ANIMATION 335 d->currentAnimation.setEndValue(newScrollbarValue); 344 336 d->currentAnimation.start(); 337 #else 338 horizontalScrollBar()->setValue(newScrollbarValue); 339 #endif //QT_NO_ANIMATION 345 340 } 346 341 … … 411 406 { 412 407 Q_Q(QColumnView); 413 if (currentAnimation.state() == QTimeLine::Running) 414 return; 408 #ifndef QT_NO_ANIMATION 409 if (currentAnimation.state() == QPropertyAnimation::Running) 410 return; 411 #endif //QT_NO_ANIMATION 415 412 416 413 // find the total horizontal length of the laid out columns … … 422 419 } 423 420 424 QSize viewportSize = q->viewport()->size();425 if (horizontalLength < viewportSize.width() && q->horizontalScrollBar()->value() == 0) {426 q->horizontalScrollBar()->setRange(0, 0);421 QSize viewportSize = viewport->size(); 422 if (horizontalLength < viewportSize.width() && hbar->value() == 0) { 423 hbar->setRange(0, 0); 427 424 } else { 428 425 int visibleLength = qMin(horizontalLength + q->horizontalOffset(), viewportSize.width()); 429 426 int hiddenLength = horizontalLength - visibleLength; 430 if (hiddenLength != q->horizontalScrollBar()->maximum())431 q->horizontalScrollBar()->setRange(0, hiddenLength);427 if (hiddenLength != hbar->maximum()) 428 hbar->setRange(0, hiddenLength); 432 429 } 433 430 if (!columns.isEmpty()) { 434 431 int pageStepSize = columns.at(0)->width(); 435 if (pageStepSize != q->horizontalScrollBar()->pageStep())436 q->horizontalScrollBar()->setPageStep(pageStepSize);437 } 438 bool visible = ( q->horizontalScrollBar()->maximum() > 0);439 if (visible != q->horizontalScrollBar()->isVisible())440 q->horizontalScrollBar()->setVisible(visible);432 if (pageStepSize != hbar->pageStep()) 433 hbar->setPageStep(pageStepSize); 434 } 435 bool visible = (hbar->maximum() > 0); 436 if (visible != hbar->isVisible()) 437 hbar->setVisible(visible); 441 438 } 442 439 … … 676 673 if (model->hasChildren(index)) { 677 674 view = q->createColumn(index); 678 q->connect(view, SIGNAL(clicked( const QModelIndex &)),679 q, SLOT(_q_clicked( const QModelIndex &)));675 q->connect(view, SIGNAL(clicked(QModelIndex)), 676 q, SLOT(_q_clicked(QModelIndex))); 680 677 } else { 681 678 if (!previewColumn) … … 685 682 } 686 683 687 q->connect(view, SIGNAL(activated( const QModelIndex &)),688 q, SIGNAL(activated( const QModelIndex &)));689 q->connect(view, SIGNAL(clicked( const QModelIndex &)),690 q, SIGNAL(clicked( const QModelIndex &)));691 q->connect(view, SIGNAL(doubleClicked( const QModelIndex &)),692 q, SIGNAL(doubleClicked( const QModelIndex &)));693 q->connect(view, SIGNAL(entered( const QModelIndex &)),694 q, SIGNAL(entered( const QModelIndex &)));695 q->connect(view, SIGNAL(pressed( const QModelIndex &)),696 q, SIGNAL(pressed( const QModelIndex &)));684 q->connect(view, SIGNAL(activated(QModelIndex)), 685 q, SIGNAL(activated(QModelIndex))); 686 q->connect(view, SIGNAL(clicked(QModelIndex)), 687 q, SIGNAL(clicked(QModelIndex))); 688 q->connect(view, SIGNAL(doubleClicked(QModelIndex)), 689 q, SIGNAL(doubleClicked(QModelIndex))); 690 q->connect(view, SIGNAL(entered(QModelIndex)), 691 q, SIGNAL(entered(QModelIndex))); 692 q->connect(view, SIGNAL(pressed(QModelIndex)), 693 q, SIGNAL(pressed(QModelIndex))); 697 694 698 695 view->setFocusPolicy(Qt::NoFocus); 699 view->setParent( q->viewport());696 view->setParent(viewport); 700 697 Q_ASSERT(view); 701 698 … … 708 705 709 706 if (columnSizes.count() > columns.count()) { 710 view->setGeometry(0, 0, columnSizes.at(columns.count()), q->viewport()->height());707 view->setGeometry(0, 0, columnSizes.at(columns.count()), viewport->height()); 711 708 } else { 712 709 int initialWidth = view->sizeHint().width(); 713 710 if (q->isRightToLeft()) 714 view->setGeometry( q->viewport()->width() - initialWidth, 0, initialWidth, q->viewport()->height());711 view->setGeometry(viewport->width() - initialWidth, 0, initialWidth, viewport->height()); 715 712 else 716 view->setGeometry(0, 0, initialWidth, q->viewport()->height());713 view->setGeometry(0, 0, initialWidth, viewport->height()); 717 714 columnSizes.resize(qMax(columnSizes.count(), columns.count() + 1)); 718 715 columnSizes[columns.count()] = initialWidth; … … 897 894 \reimp 898 895 */ 896 void QColumnView::rowsInserted(const QModelIndex &parent, int start, int end) 897 { 898 QAbstractItemView::rowsInserted(parent, start, end); 899 d_func()->checkColumnCreation(parent); 900 } 901 902 /*! 903 \reimp 904 */ 899 905 void QColumnView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) 900 906 { … … 1037 1043 ,showResizeGrips(true) 1038 1044 ,offset(0) 1039 ,currentAnimation(ANIMATION_DURATION_MSEC)1040 1045 ,previewWidget(0) 1041 1046 ,previewColumn(0) … … 1049 1054 /*! 1050 1055 \internal 1056 1057 */ 1058 void QColumnViewPrivate::_q_columnsInserted(const QModelIndex &parent, int start, int end) 1059 { 1060 QAbstractItemViewPrivate::_q_columnsInserted(parent, start, end); 1061 checkColumnCreation(parent); 1062 } 1063 1064 /*! 1065 \internal 1066 1067 Makes sure we create a corresponding column as a result of changing the model. 1068 1069 */ 1070 void QColumnViewPrivate::checkColumnCreation(const QModelIndex &parent) 1071 { 1072 if (parent == q_func()->currentIndex() && model->hasChildren(parent)) { 1073 //the parent has children and is the current 1074 //let's try to find out if there is already a mapping that is good 1075 for (int i = 0; i < columns.count(); ++i) { 1076 QAbstractItemView *view = columns.at(i); 1077 if (view->rootIndex() == parent) { 1078 if (view == previewColumn) { 1079 //let's recreate the parent 1080 closeColumns(parent, false); 1081 createColumn(parent, true /*show*/); 1082 } 1083 break; 1084 } 1085 } 1086 } 1087 } 1088 1089 /*! 1090 \internal 1051 1091 Place all of the columns where they belong inside of the viewport, resize as necessary. 1052 1092 */ … … 1057 1097 return; 1058 1098 1059 int viewportHeight = q->viewport()->height();1099 int viewportHeight = viewport->height(); 1060 1100 int x = columns.at(0)->x(); 1061 1101 1062 1102 if (q->isRightToLeft()) { 1063 x = q->viewport()->width() + q->horizontalOffset();1103 x = viewport->width() + q->horizontalOffset(); 1064 1104 for (int i = 0; i < columns.size(); ++i) { 1065 1105 QAbstractItemView *view = columns.at(i); … … 1117 1157 if (index.model()->hasChildren(index)) { 1118 1158 const QWidget *view = opt.widget; 1119 QStyle *style = view ? view->style() : qApp->style();1159 QStyle *style = view ? view->style() : QApplication::style(); 1120 1160 style->drawPrimitive(QStyle::PE_IndicatorColumnViewArrow, &opt, painter, view); 1121 1161 } -
trunk/src/gui/itemviews/qcolumnview.h
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 ** … … 98 98 int horizontalOffset() const; 99 99 int verticalOffset() const; 100 void scrollContentsBy(int dx, int dy); 100 void rowsInserted(const QModelIndex &parent, int start, int end); 101 void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); 101 102 102 103 // QColumnView functions 104 void scrollContentsBy(int dx, int dy); 103 105 virtual QAbstractItemView* createColumn(const QModelIndex &rootIndex); 104 106 void initializeColumn(QAbstractItemView *column) const; 105 106 protected Q_SLOTS:107 // QAbstractItemView overloads108 void currentChanged(const QModelIndex ¤t, const QModelIndex &previous);109 107 110 108 private: -
trunk/src/gui/itemviews/qcolumnview_p.h
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 ** … … 56 56 #include "qcolumnview.h" 57 57 58 #ifndef QT_NO_QCO lUMNVIEW58 #ifndef QT_NO_QCOLUMNVIEW 59 59 60 60 #include <private/qabstractitemview_p.h> 61 61 62 62 #include <QtCore/qabstractitemmodel.h> 63 #include <QtCore/q timeline.h>63 #include <QtCore/qpropertyanimation.h> 64 64 #include <QtGui/qabstractitemdelegate.h> 65 65 #include <QtGui/qabstractitemview.h> … … 149 149 void doLayout(); 150 150 void setPreviewWidget(QWidget *widget); 151 void checkColumnCreation(const QModelIndex &parent); 152 151 153 152 154 void _q_gripMoved(int offset); 153 155 void _q_changeCurrentColumn(); 154 156 void _q_clicked(const QModelIndex &index); 157 void _q_columnsInserted(const QModelIndex &parent, int start, int end); 155 158 156 159 QList<QAbstractItemView*> columns; … … 158 161 bool showResizeGrips; 159 162 int offset; 160 QTimeLine currentAnimation; 163 #ifndef QT_NO_ANIMATION 164 QPropertyAnimation currentAnimation; 165 #endif 161 166 QWidget *previewWidget; 162 167 QAbstractItemView *previewColumn; … … 170 175 171 176 public: 172 explicit QColumnViewDelegate(QObject *parent = 0) : QItemDelegate(parent) {} ;173 ~QColumnViewDelegate() {} ;177 explicit QColumnViewDelegate(QObject *parent = 0) : QItemDelegate(parent) {} 178 ~QColumnViewDelegate() {} 174 179 175 180 void paint(QPainter *painter, -
trunk/src/gui/itemviews/qcolumnviewgrip.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 ** -
trunk/src/gui/itemviews/qcolumnviewgrip_p.h
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 ** -
trunk/src/gui/itemviews/qdatawidgetmapper.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 ** … … 279 279 280 280 \table 281 \row \o 1 \o Nokia Corporation and/or its subsidiary(-ies)\o Oslo282 \row \o 2 \o Trolltech Pty\o Brisbane283 \row \o 3 \o Trolltech Inc\o Palo Alto284 \row \o 4 \o Trolltech China\o Beijing285 \row \o 5 \o Trolltech GmbH\o Berlin281 \row \o 1 \o Qt Norway \o Oslo 282 \row \o 2 \o Qt Australia \o Brisbane 283 \row \o 3 \o Qt USA \o Palo Alto 284 \row \o 4 \o Qt China \o Beijing 285 \row \o 5 \o Qt Germany \o Berlin 286 286 \endtable 287 287 … … 781 781 782 782 \table 783 \row \o 1 \o Nokia Corporation and/or its subsidiary(-ies)\o Oslo784 \row \o 2 \o Trolltech Pty\o Brisbane785 \row \o 3 \o Trolltech Inc\o Silicon Valley786 \row \o 4 \o Trolltech China\o Beijing787 \row \o 5 \o Trolltech GmbH\o Berlin783 \row \o 1 \o Qt Norway \o Oslo 784 \row \o 2 \o Qt Australia \o Brisbane 785 \row \o 3 \o Qt USA \o Silicon Valley 786 \row \o 4 \o Qt China \o Beijing 787 \row \o 5 \o Qt Germany \o Berlin 788 788 \endtable 789 789 … … 797 797 \table 798 798 \row \o 1 \o 2 \o 3 \o 4 \o 5 799 \row \o Nokia Corporation and/or its subsidiary(-ies) \o Trolltech Pty \o Trolltech Inc \o Trolltech China \o Trolltech GmbH799 \row \o Qt Norway \o Qt Australia \o Qt USA \o Qt China \o Qt Germany 800 800 \row \o Oslo \o Brisbane \o Silicon Valley \o Beijing \i Berlin 801 801 \endtable -
trunk/src/gui/itemviews/qdatawidgetmapper.h
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 ** -
trunk/src/gui/itemviews/qdirmodel.cpp
r376 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 ** … … 45 45 #include <qstack.h> 46 46 #include <qfile.h> 47 #include <qfilesystemmodel.h> 47 48 #include <qurl.h> 48 49 #include <qmime.h> … … 190 191 \ingroup model-view 191 192 193 \note The usage of QDirModel is not recommended anymore. The 194 QFileSystemModel class is a more performant alternative. 195 192 196 This class provides access to the local filesystem, providing functions 193 197 for renaming and removing files and directories, and for creating new … … 228 232 \note QDirModel requires an instance of a GUI application. 229 233 230 \sa nameFilters(), setFilter(), filter(), QListView, QTreeView, 234 \sa nameFilters(), setFilter(), filter(), QListView, QTreeView, QFileSystemModel, 231 235 {Dir View Example}, {Model Classes} 232 236 */ … … 869 873 870 874 QString absolutePath = QDir(path).absolutePath(); 875 #if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN) || defined(Q_OS_OS2) 876 absolutePath = absolutePath.toLower(); 877 #endif 871 878 #if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_OS2) 872 absolutePath = absolutePath.toLower();873 879 // On Windows, "filename......." and "filename" are equivalent 874 880 if (absolutePath.endsWith(QLatin1Char('.'))) { … … 910 916 if (childAppended) 911 917 emit const_cast<QDirModel*>(this)->layoutChanged(); 912 } else if (pathElements.at(0).endsWith(QLatin1Char(':'))) { 918 } else 919 #endif 920 #if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN) || defined(Q_OS_OS2) 921 if (pathElements.at(0).endsWith(QLatin1Char(':'))) { 913 922 pathElements[0] += QLatin1Char('/'); 914 923 } … … 932 941 const QFileInfo& fi = parent->children.at(j).info; 933 942 QString childFileName; 934 #if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_OS2)935 943 childFileName = idx.isValid() ? fi.fileName() : fi.absoluteFilePath(); 944 #if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN) || defined(Q_OS_OS2) 936 945 childFileName = childFileName.toLower(); 937 #else938 childFileName = idx.isValid() ? fi.fileName() : fi.absoluteFilePath();939 946 #endif 940 947 if (childFileName == element) { … … 953 960 newPath = parent->info.absoluteFilePath() + element; 954 961 else 955 newPath = parent->info.absoluteFilePath() + QLatin1Char('/') + element;962 newPath = parent->info.absoluteFilePath() + QLatin1Char('/') + element; 956 963 #else 957 964 QString newPath = parent->info.absoluteFilePath() + QLatin1Char('/') + element; … … 1305 1312 if (name.startsWith(QLatin1Char('/'))) // UNC host 1306 1313 return info.fileName(); 1314 #endif 1315 #if (defined(Q_OS_WIN) && !defined(Q_OS_WINCE)) || defined(Q_OS_SYMBIAN) || defined(Q_OS_OS2) 1307 1316 if (name.endsWith(QLatin1Char('/'))) 1308 1317 name.chop(1); … … 1336 1345 quint64 bytes = n->info.size(); 1337 1346 if (bytes >= tb) 1338 return Q Locale().toString(bytes / tb) + QString::fromLatin1(" TB");1347 return QFileSystemModel::tr("%1 TB").arg(QLocale().toString(qreal(bytes) / tb, 'f', 3)); 1339 1348 if (bytes >= gb) 1340 return Q Locale().toString(bytes / gb) + QString::fromLatin1(" GB");1349 return QFileSystemModel::tr("%1 GB").arg(QLocale().toString(qreal(bytes) / gb, 'f', 2)); 1341 1350 if (bytes >= mb) 1342 return Q Locale().toString(bytes / mb) + QString::fromLatin1(" MB");1351 return QFileSystemModel::tr("%1 MB").arg(QLocale().toString(qreal(bytes) / mb, 'f', 1)); 1343 1352 if (bytes >= kb) 1344 return Q Locale().toString(bytes / kb) + QString::fromLatin1(" KB");1345 return Q Locale().toString(bytes) + QString::fromLatin1(" bytes");1353 return QFileSystemModel::tr("%1 KB").arg(QLocale().toString(bytes / kb)); 1354 return QFileSystemModel::tr("%1 byte(s)").arg(QLocale().toString(bytes)); 1346 1355 } 1347 1356 -
trunk/src/gui/itemviews/qdirmodel.h
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 ** -
trunk/src/gui/itemviews/qfileiconprovider.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 ** … … 46 46 #include <qapplication.h> 47 47 #include <qdir.h> 48 #include <qpixmapcache.h> 48 49 #if defined(Q_WS_WIN) 49 # define _WIN32_IE 0x050050 # include <objbase.h>51 # include <private/qpixmapdata_p.h>52 # include <qpixmapcache.h>50 # define _WIN32_IE 0x0500 51 # include <qt_windows.h> 52 # include <commctrl.h> 53 # include <objbase.h> 53 54 #elif defined(Q_WS_MAC) 54 #include <private/qt_mac_p.h> 55 #endif 55 # include <private/qt_cocoa_helpers_mac_p.h> 56 #endif 57 56 58 #include <private/qfunctions_p.h> 57 #ifdef Q_OS_WINCE 58 #include <Commctrl.h> 59 #include <private/qguiplatformplugin_p.h> 60 61 #if defined(Q_WS_X11) && !defined(Q_NO_STYLE_GTK) 62 # include <private/qgtkstyle_p.h> 63 # include <private/qt_x11_p.h> 59 64 #endif 60 65 61 66 #ifndef SHGFI_ADDOVERLAYS 62 # define SHGFI_ADDOVERLAYS 0x00000002067 # define SHGFI_ADDOVERLAYS 0x000000020 63 68 #endif 64 69 … … 181 186 QFileIconProvider::~QFileIconProvider() 182 187 { 183 delete d_ptr;184 188 } 185 189 … … 216 220 { 217 221 QIcon retIcon; 218 QString fileExtension = fileInfo.suffix().toUpper(); 219 fileExtension.prepend( QLatin1String(".") ); 222 const QString fileExtension = QLatin1Char('.') + fileInfo.suffix().toUpper(); 220 223 221 224 QString key; … … 245 248 //Get the small icon 246 249 #ifndef Q_OS_WINCE 247 val = SHGetFileInfo((const WCHAR*)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,250 val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, 248 251 sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_SMALLICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS); 249 252 #else 250 val = SHGetFileInfo((const WCHAR*)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,253 val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, 251 254 sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_SYSICONINDEX); 252 255 #endif … … 266 269 if (pixmap.isNull()) { 267 270 #ifndef Q_OS_WINCE 268 pixmap = convertHIconToPixmap(info.hIcon);269 #else 270 pixmap = convertHIconToPixmap(ImageList_GetIcon((HIMAGELIST) val, info.iIcon, ILD_NORMAL));271 pixmap = QPixmap::fromWinHICON(info.hIcon); 272 #else 273 pixmap = QPixmap::fromWinHICON(ImageList_GetIcon((HIMAGELIST) val, info.iIcon, ILD_NORMAL)); 271 274 #endif 272 275 if (!pixmap.isNull()) { … … 284 287 //Get the big icon 285 288 #ifndef Q_OS_WINCE 286 val = SHGetFileInfo((const WCHAR*)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,289 val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, 287 290 sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_LARGEICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS); 288 291 #else 289 val = SHGetFileInfo((const WCHAR*)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info,292 val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, 290 293 sizeof(SHFILEINFO), SHGFI_LARGEICON|SHGFI_SYSICONINDEX); 291 294 #endif … … 296 299 } 297 300 #ifndef Q_OS_WINCE 298 pixmap = convertHIconToPixmap(info.hIcon);299 #else 300 pixmap = convertHIconToPixmap(ImageList_GetIcon((HIMAGELIST) val, info.iIcon, ILD_NORMAL), true);301 pixmap = QPixmap::fromWinHICON(info.hIcon); 302 #else 303 pixmap = QPixmap::fromWinHICON(ImageList_GetIcon((HIMAGELIST) val, info.iIcon, ILD_NORMAL)); 301 304 #endif 302 305 if (!pixmap.isNull()) { … … 317 320 { 318 321 QIcon retIcon; 322 QString fileExtension = fi.suffix().toUpper(); 323 fileExtension.prepend(QLatin1String(".")); 324 325 const QString keyBase = QLatin1String("qt_") + fileExtension; 326 327 QPixmap pixmap; 328 if (fi.isFile() && !fi.isExecutable() && !fi.isSymLink()) { 329 QPixmapCache::find(keyBase + QLatin1String("16"), pixmap); 330 } 331 332 if (!pixmap.isNull()) { 333 retIcon.addPixmap(pixmap); 334 if (QPixmapCache::find(keyBase + QLatin1String("32"), pixmap)) { 335 retIcon.addPixmap(pixmap); 336 if (QPixmapCache::find(keyBase + QLatin1String("64"), pixmap)) { 337 retIcon.addPixmap(pixmap); 338 if (QPixmapCache::find(keyBase + QLatin1String("128"), pixmap)) { 339 retIcon.addPixmap(pixmap); 340 return retIcon; 341 } 342 } 343 } 344 } 345 346 319 347 FSRef macRef; 320 348 OSStatus status = FSPathMakeRef(reinterpret_cast<const UInt8*>(fi.canonicalFilePath().toUtf8().constData()), … … 329 357 IconRef iconRef; 330 358 SInt16 iconLabel; 331 status = GetIconRefFromFileInfo(&macRef, macName.length, macName.unicode, kIconServicesCatalogInfoMask, &info, kIconServicesNormalUsageFlag, &iconRef, &iconLabel); 359 status = GetIconRefFromFileInfo(&macRef, macName.length, macName.unicode, 360 kIconServicesCatalogInfoMask, &info, kIconServicesNormalUsageFlag, 361 &iconRef, &iconLabel); 332 362 if (status != noErr) 333 363 return retIcon; 334 extern void qt_mac_constructQIconFromIconRef(const IconRef, const IconRef, QIcon*, QStyle::StandardPixmap = QStyle::SP_CustomBase); // qmacstyle_mac.cpp335 364 qt_mac_constructQIconFromIconRef(iconRef, 0, &retIcon); 336 365 ReleaseIconRef(iconRef); 366 367 pixmap = retIcon.pixmap(16); 368 QPixmapCache::insert(keyBase + QLatin1String("16"), pixmap); 369 pixmap = retIcon.pixmap(32); 370 QPixmapCache::insert(keyBase + QLatin1String("32"), pixmap); 371 pixmap = retIcon.pixmap(64); 372 QPixmapCache::insert(keyBase + QLatin1String("64"), pixmap); 373 pixmap = retIcon.pixmap(128); 374 QPixmapCache::insert(keyBase + QLatin1String("128"), pixmap); 375 337 376 return retIcon; 338 377 } … … 347 386 { 348 387 Q_D(const QFileIconProvider); 388 389 QIcon platformIcon = qt_guiPlatformPlugin()->fileSystemIcon(info); 390 if (!platformIcon.isNull()) 391 return platformIcon; 392 393 #if defined(Q_WS_X11) && !defined(QT_NO_STYLE_GTK) 394 if (X11->desktopEnvironment == DE_GNOME) { 395 QIcon gtkIcon = QGtkStylePrivate::getFilesystemIcon(info); 396 if (!gtkIcon.isNull()) 397 return gtkIcon; 398 } 399 #endif 400 349 401 #ifdef Q_WS_MAC 350 402 QIcon retIcon = d->getMacIcon(info); … … 357 409 #endif 358 410 if (info.isRoot()) 359 #if defined (Q_WS_WIN) && !defined(Q_ OS_WINCE)411 #if defined (Q_WS_WIN) && !defined(Q_WS_WINCE) 360 412 { 361 uint type = DRIVE_UNKNOWN; 362 QT_WA({ type = GetDriveTypeW((wchar_t *)info.absoluteFilePath().utf16()); }, 363 { type = GetDriveTypeA(info.absoluteFilePath().toLocal8Bit()); }); 413 UINT type = GetDriveType((wchar_t *)info.absoluteFilePath().utf16()); 364 414 365 415 switch (type) { … … 417 467 418 468 if (info.isDir()) 419 return QApplication::translate("QFileDialog",420 469 #ifdef Q_WS_WIN 421 "File Folder", "Match Windows Explorer" 422 #else 423 "Folder", "All other platforms" 424 #endif 425 ); 470 return QApplication::translate("QFileDialog", "File Folder", "Match Windows Explorer"); 471 #else 472 return QApplication::translate("QFileDialog", "Folder", "All other platforms"); 473 #endif 426 474 // Windows - "File Folder" 427 475 // OS X - "Folder" … … 430 478 431 479 if (info.isSymLink()) 432 return QApplication::translate("QFileDialog",433 480 #ifdef Q_OS_MAC 434 "Alias", "Mac OS X Finder" 435 #else 436 "Shortcut", "All other platforms" 437 #endif 438 ); 481 return QApplication::translate("QFileDialog", "Alias", "Mac OS X Finder"); 482 #else 483 return QApplication::translate("QFileDialog", "Shortcut", "All other platforms"); 484 #endif 439 485 // OS X - "Alias" 440 486 // Windows - "Shortcut" -
trunk/src/gui/itemviews/qfileiconprovider.h
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 ** … … 43 43 #define QFILEICONPROVIDER_H 44 44 45 #include <QtCore/qfileinfo.h> 46 #include <QtCore/qscopedpointer.h> 45 47 #include <QtGui/qicon.h> 46 #include <QtCore/qfileinfo.h>47 48 48 49 QT_BEGIN_HEADER … … 68 69 private: 69 70 Q_DECLARE_PRIVATE(QFileIconProvider) 70 Q FileIconProviderPrivate *d_ptr;71 QScopedPointer<QFileIconProviderPrivate> d_ptr; 71 72 Q_DISABLE_COPY(QFileIconProvider) 72 73 }; -
trunk/src/gui/itemviews/qheaderview.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 ** … … 63 63 #ifndef QT_NO_DATASTREAM 64 64 #include <qdatastream.h> 65 #endif 65 66 66 67 QT_BEGIN_NAMESPACE 67 68 69 #ifndef QT_NO_DATASTREAM 68 70 QDataStream &operator<<(QDataStream &out, const QHeaderViewPrivate::SectionSpan &span) 69 71 { … … 77 79 return in; 78 80 } 79 #endif 81 #endif // QT_NO_DATASTREAM 80 82 81 83 … … 87 89 88 90 \ingroup model-view 89 \mainclass 91 90 92 91 93 A QHeaderView displays the headers used in item views such as the … … 521 523 { 522 524 Q_D(const QHeaderView); 523 if (count() < 1)524 return QSize(0, 0);525 525 if (d->cachedSizeHint.isValid()) 526 526 return d->cachedSizeHint; 527 int width = 0; 528 int height = 0; 527 d->cachedSizeHint = QSize(0, 0); //reinitialize the cached size hint 528 const int sectionCount = count(); 529 529 530 // get size hint for the first n sections 530 int c = qMin(count(), 100);531 for (int i = 0; i < c; ++i) {531 int i = 0; 532 for (int checked = 0; checked < 100 && i < sectionCount; ++i) { 532 533 if (isSectionHidden(i)) 533 534 continue; 535 checked++; 534 536 QSize hint = sectionSizeFromContents(i); 535 width = qMax(hint.width(), width); 536 height = qMax(hint.height(), height); 537 d->cachedSizeHint = d->cachedSizeHint.expandedTo(hint); 537 538 } 538 539 // get size hint for the last n sections 539 c = qMax(count() - 100, c);540 for (int j = count() - 1; j >= c; --j) {540 i = qMax(i, sectionCount - 100 ); 541 for (int j = sectionCount - 1, checked = 0; j >= i && checked < 100; --j) { 541 542 if (isSectionHidden(j)) 542 543 continue; 544 checked++; 543 545 QSize hint = sectionSizeFromContents(j); 544 width = qMax(hint.width(), width); 545 height = qMax(hint.height(), height); 546 } 547 d->cachedSizeHint = QSize(width, height); 546 d->cachedSizeHint = d->cachedSizeHint.expandedTo(hint); 547 } 548 548 return d->cachedSizeHint; 549 549 } … … 1048 1048 /*! 1049 1049 Returns the logicalIndex for the section at the given \a visualIndex 1050 position, or -1 otherwise. 1050 position, or -1 if visualIndex < 0 or visualIndex >= QHeaderView::count(). 1051 1052 Note that the visualIndex is not affected by hidden sections. 1051 1053 1052 1054 \sa visualIndex(), sectionPosition() … … 1152 1154 1153 1155 Sets the constraints on how the section specified by \a logicalIndex in 1154 the header can be resized to those described by the given \a mode. 1156 the header can be resized to those described by the given \a mode. The logical 1157 index should exist at the time this function is called. 1155 1158 1156 1159 \note This setting will be ignored for the last section if the stretchLastSection … … 1195 1198 Q_D(const QHeaderView); 1196 1199 int visual = visualIndex(logicalIndex); 1197 Q_ASSERT(visual != -1); 1198 return d->visualIndexResizeMode(visual); 1200 if (visual == -1) 1201 return Fixed; //the default value 1202 return d->headerSectionResizeMode(visual); 1199 1203 } 1200 1204 … … 1235 1239 return; 1236 1240 1237 if (d-> visualIndexResizeMode(sortIndicatorSection()) == ResizeToContents)1241 if (d->headerSectionResizeMode(sortIndicatorSection()) == ResizeToContents) 1238 1242 resizeSections(); 1239 1243 … … 1268 1272 d->sortIndicatorOrder = order; 1269 1273 1270 if (logicalIndex >= d->sectionCount) 1274 if (logicalIndex >= d->sectionCount) { 1275 emit sortIndicatorChanged(logicalIndex, order); 1271 1276 return; // nothing to do 1277 } 1272 1278 1273 1279 if (old != logicalIndex … … 1389 1395 { 1390 1396 Q_D(QHeaderView); 1391 d->defaultSectionSize = size; 1392 d->forceInitializing = true; 1397 d->setDefaultSectionSize(size); 1393 1398 } 1394 1399 … … 1415 1420 if (d->orientation == Qt::Horizontal) 1416 1421 return qMax(strut.width(), (fontMetrics().maxWidth() + margin)); 1417 return qMax(strut.height(), (fontMetrics(). lineSpacing() + margin));1422 return qMax(strut.height(), (fontMetrics().height() + margin)); 1418 1423 } 1419 1424 return d->minimumSectionSize; … … 1535 1540 return false; 1536 1541 } 1537 #endif 1542 #endif // QT_NO_DATASTREAM 1538 1543 1539 1544 /*! … … 1895 1900 if (newCount < oldCount) 1896 1901 d->updateHiddenSections(0, newCount-1); 1897 } else if (d->forceInitializing) {1898 initializeSections(0, newCount - 1);1899 d->forceInitializing = false;1900 1902 } 1901 1903 } … … 1912 1914 Q_ASSERT(end >= 0); 1913 1915 1914 d->executePostedLayout();1915 1916 d->invalidateCachedSizeHint(); 1916 1917 … … 1938 1939 1939 1940 if (!d->logicalIndices.isEmpty()) { 1940 d->logicalIndices.resize(d->sectionCount); 1941 d->visualIndices.resize(d->sectionCount); 1942 for (int i = start; i < d->sectionCount; ++i){ 1943 d->logicalIndices[i] = i; 1944 d->visualIndices[i] = i; 1941 if (oldCount <= d->sectionCount) { 1942 d->logicalIndices.resize(d->sectionCount); 1943 d->visualIndices.resize(d->sectionCount); 1944 for (int i = oldCount; i < d->sectionCount; ++i) { 1945 d->logicalIndices[i] = i; 1946 d->visualIndices[i] = i; 1947 } 1948 } else { 1949 int j = 0; 1950 for (int i = 0; i < oldCount; ++i) { 1951 int v = d->logicalIndices.at(i); 1952 if (v < d->sectionCount) { 1953 d->logicalIndices[j] = v; 1954 d->visualIndices[v] = j; 1955 j++; 1956 } 1957 } 1958 d->logicalIndices.resize(d->sectionCount); 1959 d->visualIndices.resize(d->sectionCount); 1945 1960 } 1946 1961 } … … 1953 1968 d->sectionHidden.resize(d->sectionCount); 1954 1969 1955 if (d->sectionCount > oldCount || d->forceInitializing)1970 if (d->sectionCount > oldCount) 1956 1971 d->createSectionSpan(start, end, (end - start + 1) * d->defaultSectionSize, d->globalResizeMode); 1957 1972 //Q_ASSERT(d->headerLength() == d->length); … … 1972 1987 if (d->orientation == Qt::Horizontal && current.column() != old.column()) { 1973 1988 if (old.isValid() && old.parent() == d->root) 1974 d-> setDirtyRegion(QRect(sectionViewportPosition(old.column()), 0,1989 d->viewport->update(QRect(sectionViewportPosition(old.column()), 0, 1975 1990 sectionSize(old.column()), d->viewport->height())); 1976 1991 if (current.isValid() && current.parent() == d->root) 1977 d-> setDirtyRegion(QRect(sectionViewportPosition(current.column()), 0,1992 d->viewport->update(QRect(sectionViewportPosition(current.column()), 0, 1978 1993 sectionSize(current.column()), d->viewport->height())); 1979 1994 } else if (d->orientation == Qt::Vertical && current.row() != old.row()) { 1980 1995 if (old.isValid() && old.parent() == d->root) 1981 d-> setDirtyRegion(QRect(0, sectionViewportPosition(old.row()),1996 d->viewport->update(QRect(0, sectionViewportPosition(old.row()), 1982 1997 d->viewport->width(), sectionSize(old.row()))); 1983 1998 if (current.isValid() && current.parent() == d->root) 1984 d-> setDirtyRegion(QRect(0, sectionViewportPosition(current.row()),1999 d->viewport->update(QRect(0, sectionViewportPosition(current.row()), 1985 2000 d->viewport->width(), sectionSize(current.row()))); 1986 2001 } 1987 d->updateDirtyRegion();1988 2002 } 1989 2003 … … 2396 2410 d->pressed = d->section = d->target = -1; 2397 2411 d->updateSectionIndicator(d->section, -1); 2398 } 2412 break; } 2413 case QEvent::Wheel: { 2414 QAbstractScrollArea *asa = qobject_cast<QAbstractScrollArea *>(parentWidget()); 2415 if (asa) 2416 return QApplication::sendEvent(asa->viewport(), e); 2417 break; } 2399 2418 default: 2400 2419 break; … … 2516 2535 Q_ASSERT(logicalIndex >= 0); 2517 2536 2537 ensurePolished(); 2538 2518 2539 // use SizeHintRole 2519 2540 QVariant variant = d->model->headerData(logicalIndex, d->orientation, Qt::SizeHintRole); … … 2541 2562 opt.icon = qvariant_cast<QPixmap>(variant); 2542 2563 QSize size = style()->sizeFromContents(QStyle::CT_HeaderSection, &opt, QSize(), this); 2543 if (isSortIndicatorShown() && sortIndicatorSection() == logicalIndex) {2564 if (isSortIndicatorShown()) { 2544 2565 int margin = style()->pixelMetric(QStyle::PM_HeaderMargin, &opt, this); 2545 2566 if (d->orientation == Qt::Horizontal) … … 2618 2639 int last = orientation() == Qt::Horizontal ? bottomRight.column() : bottomRight.row(); 2619 2640 for (int i = first; i <= last && !resizeRequired; ++i) 2620 resizeRequired = (resize Required && resizeMode(i));2641 resizeRequired = (resizeMode(i) == ResizeToContents); 2621 2642 if (resizeRequired) 2622 2643 d->doDelayedResizeSections(); … … 2824 2845 } 2825 2846 2826 int x, y,w, h;2847 int w, h; 2827 2848 int p = q->sectionViewportPosition(section); 2828 2849 if (orientation == Qt::Horizontal) { 2829 x = p;2830 y = 0;2831 2850 w = q->sectionSize(section); 2832 2851 h = viewport->height(); 2833 2852 } else { 2834 x = 0;2835 y = p;2836 2853 w = viewport->width(); 2837 2854 h = q->sectionSize(section); … … 2939 2956 { 2940 2957 Q_Q(QHeaderView); 2958 //stop the timer in case it is delayed 2959 delayedResize.stop(); 2941 2960 2942 2961 executePostedLayout(); 2943 2962 if (sectionCount == 0) 2944 2963 return; 2964 2965 if (resizeRecursionBlock) 2966 return; 2967 resizeRecursionBlock = true; 2968 2945 2969 invalidateCachedSizeHint(); 2970 2971 const int lastVisibleSection = lastVisibleVisualIndex(); 2946 2972 2947 2973 // find stretchLastSection if we have it 2948 2974 int stretchSection = -1; 2949 if (stretchLastSection && !useGlobalMode) { 2950 for (int i = sectionCount - 1; i >= 0; --i) { 2951 if (!isVisualIndexHidden(i)) { 2952 stretchSection = i; 2953 break; 2954 } 2955 } 2956 } 2975 if (stretchLastSection && !useGlobalMode) 2976 stretchSection = lastVisibleVisualIndex(); 2957 2977 2958 2978 // count up the number of strected sections and how much space left for them … … 2968 2988 resizeMode = globalMode; 2969 2989 else 2970 resizeMode = (i == stretchSection ? QHeaderView::Stretch : visualIndexResizeMode(i));2990 resizeMode = (i == stretchSection ? QHeaderView::Stretch : headerSectionResizeMode(i)); 2971 2991 2972 2992 if (resizeMode == QHeaderView::Stretch) { … … 3000 3020 int spanStartSection = 0; 3001 3021 int previousSectionLength = 0; 3002 const int lastVisibleSection = lastVisibleVisualIndex();3003 3022 3004 3023 QHeaderView::ResizeMode previousSectionResizeMode = QHeaderView::Interactive; … … 3019 3038 resizeMode = (i == stretchSection 3020 3039 ? QHeaderView::Stretch 3021 : visualIndexResizeMode(i));3040 : newSectionResizeMode); 3022 3041 if (resizeMode == QHeaderView::Stretch && stretchSectionLength != -1) { 3023 3042 if (i == lastVisibleSection) … … 3056 3075 previousSectionResizeMode); 3057 3076 //Q_ASSERT(headerLength() == length); 3058 3077 resizeRecursionBlock = false; 3059 3078 viewport->update(); 3060 3079 } … … 3365 3384 } 3366 3385 3386 void QHeaderViewPrivate::setDefaultSectionSize(int size) 3387 { 3388 Q_Q(QHeaderView); 3389 defaultSectionSize = size; 3390 int currentVisualIndex = 0; 3391 for (int i = 0; i < sectionSpans.count(); ++i) { 3392 QHeaderViewPrivate::SectionSpan &span = sectionSpans[i]; 3393 if (span.size > 0) { 3394 //we resize it if it is not hidden (ie size > 0) 3395 const int newSize = span.count * size; 3396 if (newSize != span.size) { 3397 length += newSize - span.size; //the whole length is changed 3398 const int oldSectionSize = span.sectionSize(); 3399 span.size = span.count * size; 3400 for (int i = currentVisualIndex; i < currentVisualIndex + span.count; ++i) { 3401 emit q->sectionResized(logicalIndex(i), oldSectionSize, size); 3402 } 3403 } 3404 } 3405 currentVisualIndex += span.count; 3406 } 3407 } 3408 3367 3409 void QHeaderViewPrivate::resizeSectionSpan(int visualIndex, int oldSize, int newSize) 3368 3410 { … … 3450 3492 int QHeaderViewPrivate::viewSectionSizeHint(int logical) const 3451 3493 { 3452 Q_Q(const QHeaderView); 3453 if (QAbstractItemView *parent = qobject_cast<QAbstractItemView*>(q->parent())) { 3494 if (QAbstractItemView *view = qobject_cast<QAbstractItemView*>(parent)) { 3454 3495 return (orientation == Qt::Horizontal 3455 ? parent->sizeHintForColumn(logical)3456 : parent->sizeHintForRow(logical));3496 ? view->sizeHintForColumn(logical) 3497 : view->sizeHintForRow(logical)); 3457 3498 } 3458 3499 return 0; … … 3540 3581 3541 3582 in >> align; 3542 defaultAlignment = (Qt::Alignment)align;3583 defaultAlignment = Qt::Alignment(align); 3543 3584 3544 3585 in >> global; … … 3550 3591 } 3551 3592 3593 #endif // QT_NO_DATASTREAM 3594 3552 3595 QT_END_NAMESPACE 3553 3596 3554 #endif // QT_NO_DATASTREAEM3555 3556 3597 #endif // QT_NO_ITEMVIEWS 3557 3598 -
trunk/src/gui/itemviews/qheaderview.h
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 ** … … 222 222 223 223 QModelIndex moveCursor(CursorAction, Qt::KeyboardModifiers); 224 void setSelection(const QRect& , QItemSelectionModel::SelectionFlags);224 void setSelection(const QRect& rect, QItemSelectionModel::SelectionFlags flags); 225 225 QRegion visualRegionForSelection(const QItemSelection &selection) const; 226 226 void initStyleOption(QStyleOptionHeader *option) const; … … 229 229 Q_PRIVATE_SLOT(d_func(), void _q_sectionsRemoved(const QModelIndex &parent, int logicalFirst, int logicalLast)) 230 230 Q_PRIVATE_SLOT(d_func(), void _q_layoutAboutToBeChanged()) 231 Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged())232 231 Q_DECLARE_PRIVATE(QHeaderView) 233 232 Q_DISABLE_COPY(QHeaderView) -
trunk/src/gui/itemviews/qheaderview_p.h
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 ** … … 91 91 stretchLastSection(false), 92 92 cascadingResizing(false), 93 forceInitializing(false),93 resizeRecursionBlock(false), 94 94 stretchSections(0), 95 95 contentsSections(0), … … 171 171 } 172 172 173 inline QHeaderView::ResizeMode visualIndexResizeMode(int visual) const {174 return headerSectionResizeMode(visual);175 }176 177 173 inline bool hasAutoResizeSections() const { 178 174 return stretchSections || stretchLastSection || contentsSections; … … 212 208 213 209 inline bool sectionIsCascadable(int visual) const { 214 return visualIndexResizeMode(visual) == QHeaderView::Interactive;210 return headerSectionResizeMode(visual) == QHeaderView::Interactive; 215 211 } 216 212 … … 232 228 inline void executePostedResize() const { 233 229 if (delayedResize.isActive() && state == NoState) { 234 delayedResize.stop();235 230 const_cast<QHeaderView*>(q_func())->resizeSections(); 236 231 } … … 276 271 bool stretchLastSection; 277 272 bool cascadingResizing; 278 bool forceInitializing;273 bool resizeRecursionBlock; 279 274 int stretchSections; 280 275 int contentsSections; … … 311 306 void removeSectionsFromSpans(int start, int end); 312 307 void resizeSectionSpan(int visualIndex, int oldSize, int newSize); 308 void setDefaultSectionSize(int size); 313 309 314 310 inline int headerSectionCount() const { // for debugging -
trunk/src/gui/itemviews/qitemdelegate.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 ** … … 48 48 #include <qlineedit.h> 49 49 #include <qtextedit.h> 50 #include <qplaintextedit.h> 50 51 #include <qpainter.h> 51 52 #include <qpalette.h> … … 185 186 186 187 \ingroup model-view 187 \mainclass 188 188 189 189 190 QItemDelegate can be used to provide custom display features and editor … … 219 220 while editing takes place. Editors are created with a 220 221 QItemEditorFactory; a default static instance provided by 221 QItemEditorFactory is installed on all item del agates. You can set222 QItemEditorFactory is installed on all item delegates. You can set 222 223 a custom factory using setItemEditorFactory() or set a new default 223 224 factory with QItemEditorFactory::setDefaultFactory(). It is the … … 255 256 \row \o \l Qt::BackgroundColorRole \o QColor (obsolete; use Qt::BackgroundRole instead) 256 257 \row \o \l Qt::CheckStateRole \o Qt::CheckState 257 \row \o \l Qt::DecorationRole \o QIcon and QColor258 \row \o \l Qt::DecorationRole \o QIcon, QPixmap and QColor 258 259 \row \o \l Qt::DisplayRole \o QString and types with a string representation 259 260 \row \o \l Qt::EditRole \o See QItemEditorFactory for details … … 352 353 { 353 354 QString text; 354 switch (value.type()) { 355 switch (value.userType()) { 356 case QMetaType::Float: 357 text = option.locale.toString(value.toFloat(), 'g'); 358 break; 355 359 case QVariant::Double: 356 360 text = option.locale.toString(value.toDouble(), 'g', DBL_DIG); … … 574 578 575 579 /*! 576 Gets data drom the \a editor widget and stores it in the specified580 Gets data from the \a editor widget and stores it in the specified 577 581 \a model at the item \a index. 578 582 … … 719 723 elided += option.fontMetrics.elidedText(text.mid(start), 720 724 option.textElideMode, textRect.width()); 721 if (end != -1)722 elided += QChar::LineSeparator;723 725 } 724 726 d->textLayout.setText(elided); … … 861 863 /*! 862 864 \internal 865 866 Code duplicated in QCommonStylePrivate::viewItemLayout 863 867 */ 864 868 … … 882 886 883 887 textRect->adjust(-textMargin, 0, textMargin, 0); // add width padding 884 if (textRect->height() == 0 && !hasPixmap) 888 if (textRect->height() == 0 && (!hasPixmap || !hint)) { 889 //if there is no text, we still want to have a decent height for the item sizeHint and the editor size 885 890 textRect->setHeight(option.fontMetrics.height()); 891 } 886 892 887 893 QSize pm(0, 0); … … 1054 1060 1055 1061 QPixmap selected = QPixmap(QPixmap::fromImage(img)); 1056 int n = (img. numBytes() >> 10) + 1;1062 int n = (img.byteCount() >> 10) + 1; 1057 1063 if (QPixmapCache::cacheLimit() < n) 1058 1064 QPixmapCache::setCacheLimit(n); … … 1195 1201 case Qt::Key_Return: 1196 1202 #ifndef QT_NO_TEXTEDIT 1197 if (qobject_cast<QTextEdit *>(editor))1203 if (qobject_cast<QTextEdit *>(editor) || qobject_cast<QPlainTextEdit *>(editor)) 1198 1204 return false; // don't filter enter key events for QTextEdit 1199 1205 // We want the editor to be able to process the key press … … 1219 1225 editor->parentWidget()->setFocus(); 1220 1226 return true; 1221 } else if (event->type() == QEvent::FocusOut || event->type() == QEvent::Hide) {1227 } else if (event->type() == QEvent::FocusOut || (event->type() == QEvent::Hide && editor->isWindow())) { 1222 1228 //the Hide event will take care of he editors that are in fact complete dialogs 1223 1229 if (!editor->isActiveWindow() || (QApplication::focusWidget() != editor)) { … … 1234 1240 return false; 1235 1241 #endif 1236 // Opening a modal dialog will start a new eventloop 1237 // that will process the deleteLater event. 1238 if (QApplication::activeModalWidget() 1239 && !QApplication::activeModalWidget()->isAncestorOf(editor) 1240 && qobject_cast<QDialog*>(QApplication::activeModalWidget())) 1241 return false; 1242 1242 1243 emit commitData(editor); 1243 1244 emit closeEditor(editor, NoHint); … … 1297 1298 } 1298 1299 1299 Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked 1300 Qt::CheckState state; 1301 if ( flags & Qt::ItemIsTristate ) { 1302 state = static_cast<Qt::CheckState>( (value.toInt() + 1) % 3 ); 1303 } else { 1304 state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked 1300 1305 ? Qt::Unchecked : Qt::Checked); 1306 } 1307 1301 1308 return model->setData(index, state, Qt::CheckStateRole); 1302 1309 } … … 1321 1328 value = index.data(Qt::TextAlignmentRole); 1322 1329 if (value.isValid()) 1323 opt.displayAlignment = (Qt::Alignment)value.toInt();1330 opt.displayAlignment = Qt::Alignment(value.toInt()); 1324 1331 1325 1332 // set foreground brush -
trunk/src/gui/itemviews/qitemdelegate.h
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 ** -
trunk/src/gui/itemviews/qitemeditorfactory.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 ** … … 159 159 QItemEditorFactory::~QItemEditorFactory() 160 160 { 161 //we make sure we delete all the QItemEditorCreatorBase 162 //this has to be done only once, hence the QSet 163 QSet<QItemEditorCreatorBase*> set = creatorMap.values().toSet(); 164 qDeleteAll(set); 161 165 } 162 166 … … 171 175 void QItemEditorFactory::registerEditor(QVariant::Type type, QItemEditorCreatorBase *creator) 172 176 { 173 delete creatorMap.value(type, 0); 174 creatorMap[type] = creator; 177 QHash<QVariant::Type, QItemEditorCreatorBase *>::iterator it = creatorMap.find(type); 178 if (it != creatorMap.end()) { 179 QItemEditorCreatorBase *oldCreator = it.value(); 180 Q_ASSERT(oldCreator); 181 creatorMap.erase(it); 182 if (!creatorMap.values().contains(oldCreator)) 183 delete oldCreator; // if it is no more in use we can delete it 184 } 185 186 creatorMap[type] = creator; 175 187 } 176 188 -
trunk/src/gui/itemviews/qitemeditorfactory.h
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 ** -
trunk/src/gui/itemviews/qitemeditorfactory_p.h
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 ** -
trunk/src/gui/itemviews/qitemselectionmodel.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 ** … … 271 271 */ 272 272 273 /*! 274 Returns the list of model index items stored in the selection. 275 */ 276 277 QModelIndexList QItemSelectionRange::indexes() const 278 { 279 QModelIndex index; 280 QModelIndexList result; 281 if (isValid() && model()) { 282 for (int column = left(); column <= right(); ++column) { 283 for (int row = top(); row <= bottom(); ++row) { 284 index = model()->index(row, column, parent()); 285 Qt::ItemFlags flags = model()->flags(index); 273 /* 274 \internal 275 276 utility function for getting the indexes from a range 277 it avoid concatenating list and works on one 278 */ 279 280 static void indexesFromRange(const QItemSelectionRange &range, QModelIndexList &result) 281 { 282 if (range.isValid() && range.model()) { 283 for (int column = range.left(); column <= range.right(); ++column) { 284 for (int row = range.top(); row <= range.bottom(); ++row) { 285 QModelIndex index = range.model()->index(row, column, range.parent()); 286 Qt::ItemFlags flags = range.model()->flags(index); 286 287 if ((flags & Qt::ItemIsSelectable) && (flags & Qt::ItemIsEnabled)) 287 288 result.append(index); … … 289 290 } 290 291 } 292 } 293 294 /*! 295 Returns the list of model index items stored in the selection. 296 */ 297 298 QModelIndexList QItemSelectionRange::indexes() const 299 { 300 QModelIndexList result; 301 indexesFromRange(*this, result); 291 302 return result; 292 303 } 293 304 294 305 /*! 295 \class QItemSelection 296 297 \brief The QItemSelection class manages information about selected items in a model. 298 299 \ingroup model-view 300 301 A QItemSelection describes the items in a model that have been 302 selected by the user. A QItemSelection is basically a list of 303 selection ranges, see QItemSelectionRange. It provides functions for 304 creating and manipulating selections, and selecting a range of items 305 from a model. 306 307 The QItemSelection class is one of the \l{Model/View Classes} 308 and is part of Qt's \l{Model/View Programming}{model/view framework}. 309 310 An item selection can be constructed and initialized to contain a 311 range of items from an existing model. The following example constructs 312 a selection that contains a range of items from the given \c model, 313 beginning at the \c topLeft, and ending at the \c bottomRight. 314 315 \snippet doc/src/snippets/code/src_gui_itemviews_qitemselectionmodel.cpp 0 316 317 An empty item selection can be constructed, and later populated as 318 required. So, if the model is going to be unavailable when we construct 319 the item selection, we can rewrite the above code in the following way: 320 321 \snippet doc/src/snippets/code/src_gui_itemviews_qitemselectionmodel.cpp 1 322 323 QItemSelection saves memory, and avoids unnecessary work, by working with 324 selection ranges rather than recording the model item index for each 325 item in the selection. Generally, an instance of this class will contain 326 a list of non-overlapping selection ranges. 327 328 Use merge() to merge one item selection into another without making 329 overlapping ranges. Use split() to split one selection range into 330 smaller ranges based on a another selection range. 331 332 \sa {Model/View Programming}, QItemSelectionModel 333 306 \class QItemSelection 307 308 \brief The QItemSelection class manages information about selected items in a model. 309 310 \ingroup model-view 311 312 A QItemSelection describes the items in a model that have been 313 selected by the user. A QItemSelection is basically a list of 314 selection ranges, see QItemSelectionRange. It provides functions for 315 creating and manipulating selections, and selecting a range of items 316 from a model. 317 318 The QItemSelection class is one of the \l{Model/View Classes} 319 and is part of Qt's \l{Model/View Programming}{model/view framework}. 320 321 An item selection can be constructed and initialized to contain a 322 range of items from an existing model. The following example constructs 323 a selection that contains a range of items from the given \c model, 324 beginning at the \c topLeft, and ending at the \c bottomRight. 325 326 \snippet doc/src/snippets/code/src_gui_itemviews_qitemselectionmodel.cpp 0 327 328 An empty item selection can be constructed, and later populated as 329 required. So, if the model is going to be unavailable when we construct 330 the item selection, we can rewrite the above code in the following way: 331 332 \snippet doc/src/snippets/code/src_gui_itemviews_qitemselectionmodel.cpp 1 333 334 QItemSelection saves memory, and avoids unnecessary work, by working with 335 selection ranges rather than recording the model item index for each 336 item in the selection. Generally, an instance of this class will contain 337 a list of non-overlapping selection ranges. 338 339 Use merge() to merge one item selection into another without making 340 overlapping ranges. Use split() to split one selection range into 341 smaller ranges based on a another selection range. 342 343 \sa {Model/View Programming}, QItemSelectionModel 334 344 */ 335 345 … … 405 415 QList<QItemSelectionRange>::const_iterator it = begin(); 406 416 for (; it != end(); ++it) 407 result += (*it).indexes();417 indexesFromRange(*it, result); 408 418 return result; 409 419 } 410 420 411 421 /*! 412 Merges the \a other selection with this QItemSelection using the413 \a command given. This method guarantees that no ranges are overlapping.414 415 Note that only QItemSelectionModel::Select,416 QItemSelectionModel::Deselect, and QItemSelectionModel::Toggle are417 supported.418 419 \sa split()422 Merges the \a other selection with this QItemSelection using the 423 \a command given. This method guarantees that no ranges are overlapping. 424 425 Note that only QItemSelectionModel::Select, 426 QItemSelectionModel::Deselect, and QItemSelectionModel::Toggle are 427 supported. 428 429 \sa split() 420 430 */ 421 431 void QItemSelection::merge(const QItemSelection &other, QItemSelectionModel::SelectionFlags command) … … 469 479 470 480 /*! 471 Splits the selection \a range using the selection \a other range.472 Removes all items in \a other from \a range and puts the result in \a result.473 This can be compared with the semantics of the \e subtract operation of a set.474 \sa merge()481 Splits the selection \a range using the selection \a other range. 482 Removes all items in \a other from \a range and puts the result in \a result. 483 This can be compared with the semantics of the \e subtract operation of a set. 484 \sa merge() 475 485 */ 476 486 … … 519 529 520 530 /*! 521 \internal522 523 returns a QItemSelection where all ranges have been expanded to:524 Rows: left: 0 and right: columnCount()-1525 Columns: top: 0 and bottom: rowCount()-1531 \internal 532 533 returns a QItemSelection where all ranges have been expanded to: 534 Rows: left: 0 and right: columnCount()-1 535 Columns: top: 0 and bottom: rowCount()-1 526 536 */ 527 537 … … 558 568 559 569 /*! 560 \internal570 \internal 561 571 */ 562 572 void QItemSelectionModelPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &parent, … … 564 574 { 565 575 Q_Q(QItemSelectionModel); 576 finalize(); 566 577 567 578 // update current index … … 581 592 } 582 593 583 // update selectionsx 584 QModelIndex tl = model->index(start, 0, parent); 585 QModelIndex br = model->index(end, model->columnCount(parent) - 1, parent); 586 q->select(QItemSelection(tl, br), QItemSelectionModel::Deselect); 587 finalize(); 588 } 589 590 /*! 591 \internal 594 QItemSelection deselected; 595 QItemSelection::iterator it = ranges.begin(); 596 while (it != ranges.end()) { 597 if (it->topLeft().parent() != parent) { // Check parents until reaching root or contained in range 598 QModelIndex itParent = it->topLeft().parent(); 599 while (itParent.isValid() && itParent.parent() != parent) 600 itParent = itParent.parent(); 601 602 if (itParent.isValid() && start <= itParent.row() && itParent.row() <= end) { 603 deselected.append(*it); 604 it = ranges.erase(it); 605 } else { 606 ++it; 607 } 608 } else if (start <= it->bottom() && it->bottom() <= end // Full inclusion 609 && start <= it->top() && it->top() <= end) { 610 deselected.append(*it); 611 it = ranges.erase(it); 612 } else if (start <= it->top() && it->top() <= end) { // Top intersection 613 deselected.append(QItemSelectionRange(it->topLeft(), model->index(end, it->left(), it->parent()))); 614 *it = QItemSelectionRange(model->index(end + 1, it->left(), it->parent()), it->bottomRight()); 615 ++it; 616 } else if (start <= it->bottom() && it->bottom() <= end) { // Bottom intersection 617 deselected.append(QItemSelectionRange(model->index(start, it->right(), it->parent()), it->bottomRight())); 618 *it = QItemSelectionRange(it->topLeft(), model->index(start - 1, it->right(), it->parent())); 619 ++it; 620 } else { 621 if (it->top() < start && end < it->bottom()) // Middle intersection (do nothing) 622 deselected.append(QItemSelectionRange(model->index(start, it->right(), it->parent()), 623 model->index(end, it->left(), it->parent()))); 624 ++it; 625 } 626 } 627 628 if (!deselected.isEmpty()) 629 emit q->selectionChanged(QItemSelection(), deselected); 630 } 631 632 /*! 633 \internal 592 634 */ 593 635 void QItemSelectionModelPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &parent, … … 620 662 621 663 /*! 622 \internal623 624 Split selection ranges if columns are about to be inserted in the middle.664 \internal 665 666 Split selection ranges if columns are about to be inserted in the middle. 625 667 */ 626 668 void QItemSelectionModelPrivate::_q_columnsAboutToBeInserted(const QModelIndex &parent, … … 649 691 650 692 /*! 651 \internal652 653 Split selection ranges if rows are about to be inserted in the middle.693 \internal 694 695 Split selection ranges if rows are about to be inserted in the middle. 654 696 */ 655 697 void QItemSelectionModelPrivate::_q_rowsAboutToBeInserted(const QModelIndex &parent, … … 678 720 679 721 /*! 680 \internal681 682 Split selection into individual (persistent) indexes. This is done in683 preparation for the layoutChanged() signal, where the indexes can be684 merged again.722 \internal 723 724 Split selection into individual (persistent) indexes. This is done in 725 preparation for the layoutChanged() signal, where the indexes can be 726 merged again. 685 727 */ 686 728 void QItemSelectionModelPrivate::_q_layoutAboutToBeChanged() … … 689 731 savedPersistentCurrentIndexes.clear(); 690 732 691 // special case for when all indexes are selected 733 // optimisation for when all indexes are selected 734 // (only if there is lots of items (1000) because this is not entirely correct) 692 735 if (ranges.isEmpty() && currentSelection.count() == 1) { 693 736 QItemSelectionRange range = currentSelection.first(); 694 737 QModelIndex parent = range.parent(); 695 if (range.top() == 0 738 tableRowCount = model->rowCount(parent); 739 tableColCount = model->columnCount(parent); 740 if (tableRowCount * tableColCount > 1000 741 && range.top() == 0 696 742 && range.left() == 0 697 && range.bottom() == model->rowCount(parent)- 1698 && range.right() == model->columnCount(parent)- 1) {743 && range.bottom() == tableRowCount - 1 744 && range.right() == tableColCount - 1) { 699 745 tableSelected = true; 700 746 tableParent = parent; 701 tableColCount = model->columnCount(parent);702 tableRowCount = model->rowCount(parent);703 747 return; 704 748 } … … 716 760 717 761 /*! 718 \internal719 720 Merges \a indexes into an item selection made up of ranges.721 Assumes that the indexes are sorted.762 \internal 763 764 Merges \a indexes into an item selection made up of ranges. 765 Assumes that the indexes are sorted. 722 766 */ 723 767 static QItemSelection mergeIndexes(const QList<QPersistentModelIndex> &indexes) … … 764 808 765 809 /*! 766 \internal767 768 Merge the selected indexes into selection ranges again.810 \internal 811 812 Merge the selected indexes into selection ranges again. 769 813 */ 770 814 void QItemSelectionModelPrivate::_q_layoutChanged() … … 808 852 809 853 /*! 810 \class QItemSelectionModel811 812 \brief The QItemSelectionModel class keeps track of a view's selected items.813 814 \ingroup model-view815 816 A QItemSelectionModel keeps track of the selected items in a view, or817 in several views onto the same model. It also keeps track of the818 currently selected item in a view.819 820 The QItemSelectionModel class is one of the \l{Model/View Classes}821 and is part of Qt's \l{Model/View Programming}{model/view framework}.822 823 The selected items are stored using ranges. Whenever you want to824 modify the selected items use select() and provide either a825 QItemSelection, or a QModelIndex and a QItemSelectionModel::SelectionFlag.826 827 The QItemSelectionModel takes a two layer approach to selection828 management, dealing with both selected items that have been committed829 and items that are part of the current selection. The current830 selected items are part of the current interactive selection (for831 example with rubber-band selection or keyboard-shift selections).832 833 To update the currently selected items, use the bitwise OR of834 QItemSelectionModel::Current and any of the other SelectionFlags.835 If you omit the QItemSelectionModel::Current command, a new current836 selection will be created, and the previous one added to the whole837 selection. All functions operate on both layers; for example,838 selectedItems() will return items from both layers.839 840 \sa {Model/View Programming}, QAbstractItemModel, {Chart Example}841 */ 842 843 /*! 844 Constructs a selection model that operates on the specified item \a model.854 \class QItemSelectionModel 855 856 \brief The QItemSelectionModel class keeps track of a view's selected items. 857 858 \ingroup model-view 859 860 A QItemSelectionModel keeps track of the selected items in a view, or 861 in several views onto the same model. It also keeps track of the 862 currently selected item in a view. 863 864 The QItemSelectionModel class is one of the \l{Model/View Classes} 865 and is part of Qt's \l{Model/View Programming}{model/view framework}. 866 867 The selected items are stored using ranges. Whenever you want to 868 modify the selected items use select() and provide either a 869 QItemSelection, or a QModelIndex and a QItemSelectionModel::SelectionFlag. 870 871 The QItemSelectionModel takes a two layer approach to selection 872 management, dealing with both selected items that have been committed 873 and items that are part of the current selection. The current 874 selected items are part of the current interactive selection (for 875 example with rubber-band selection or keyboard-shift selections). 876 877 To update the currently selected items, use the bitwise OR of 878 QItemSelectionModel::Current and any of the other SelectionFlags. 879 If you omit the QItemSelectionModel::Current command, a new current 880 selection will be created, and the previous one added to the whole 881 selection. All functions operate on both layers; for example, 882 selectedItems() will return items from both layers. 883 884 \sa {Model/View Programming}, QAbstractItemModel, {Chart Example} 885 */ 886 887 /*! 888 Constructs a selection model that operates on the specified item \a model. 845 889 */ 846 890 QItemSelectionModel::QItemSelectionModel(QAbstractItemModel *model) … … 865 909 866 910 /*! 867 Constructs a selection model that operates on the specified item \a model with \a parent.911 Constructs a selection model that operates on the specified item \a model with \a parent. 868 912 */ 869 913 QItemSelectionModel::QItemSelectionModel(QAbstractItemModel *model, QObject *parent) … … 888 932 889 933 /*! 890 \internal934 \internal 891 935 */ 892 936 QItemSelectionModel::QItemSelectionModel(QItemSelectionModelPrivate &dd, QAbstractItemModel *model) … … 911 955 912 956 /*! 913 Destroys the selection model.957 Destroys the selection model. 914 958 */ 915 959 QItemSelectionModel::~QItemSelectionModel() … … 933 977 934 978 /*! 935 Selects the model item \a index using the specified \a command, and emits936 selectionChanged().937 938 \sa QItemSelectionModel::SelectionFlags979 Selects the model item \a index using the specified \a command, and emits 980 selectionChanged(). 981 982 \sa QItemSelectionModel::SelectionFlags 939 983 */ 940 984 void QItemSelectionModel::select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) … … 945 989 946 990 /*! 947 \fn void QItemSelectionModel::currentChanged(const QModelIndex ¤t, const QModelIndex &previous)948 949 This signal is emitted whenever the current item changes. The \a previous950 model item index is replaced by the \a current index as the selection's951 current item.952 953 Note that this signal will not be emitted when the item model is reset.954 955 \sa currentIndex() setCurrentIndex() selectionChanged()956 */ 957 958 /*! 959 \fn void QItemSelectionModel::currentColumnChanged(const QModelIndex ¤t, const QModelIndex &previous)960 961 This signal is emitted if the \a current item changes and its column is962 different to the column of the \a previous current item.963 964 Note that this signal will not be emitted when the item model is reset.965 966 \sa currentChanged() currentRowChanged() currentIndex() setCurrentIndex()967 */ 968 969 /*! 970 \fn void QItemSelectionModel::currentRowChanged(const QModelIndex ¤t, const QModelIndex &previous)971 972 This signal is emitted if the \a current item changes and its row is973 different to the row of the \a previous current item.974 975 Note that this signal will not be emitted when the item model is reset.976 977 \sa currentChanged() currentColumnChanged() currentIndex() setCurrentIndex()991 \fn void QItemSelectionModel::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) 992 993 This signal is emitted whenever the current item changes. The \a previous 994 model item index is replaced by the \a current index as the selection's 995 current item. 996 997 Note that this signal will not be emitted when the item model is reset. 998 999 \sa currentIndex() setCurrentIndex() selectionChanged() 1000 */ 1001 1002 /*! 1003 \fn void QItemSelectionModel::currentColumnChanged(const QModelIndex ¤t, const QModelIndex &previous) 1004 1005 This signal is emitted if the \a current item changes and its column is 1006 different to the column of the \a previous current item. 1007 1008 Note that this signal will not be emitted when the item model is reset. 1009 1010 \sa currentChanged() currentRowChanged() currentIndex() setCurrentIndex() 1011 */ 1012 1013 /*! 1014 \fn void QItemSelectionModel::currentRowChanged(const QModelIndex ¤t, const QModelIndex &previous) 1015 1016 This signal is emitted if the \a current item changes and its row is 1017 different to the row of the \a previous current item. 1018 1019 Note that this signal will not be emitted when the item model is reset. 1020 1021 \sa currentChanged() currentColumnChanged() currentIndex() setCurrentIndex() 978 1022 */ 979 1023 … … 992 1036 993 1037 /*! 994 \enum QItemSelectionModel::SelectionFlag995 996 This enum describes the way the selection model will be updated.997 998 \value NoUpdate No selection will be made.999 \value Clear The complete selection will be cleared.1000 \value Select All specified indexes will be selected.1001 \value Deselect All specified indexes will be deselected.1002 \value Toggle All specified indexes will be selected or1003 deselected depending on their current state.1004 \value Current The current selection will be updated.1005 \value Rows All indexes will be expanded to span rows.1006 \value Columns All indexes will be expanded to span columns.1007 \value SelectCurrent A combination of Select and Current, provided for1008 convenience.1009 \value ToggleCurrent A combination of Toggle and Current, provided for1010 convenience.1011 \value ClearAndSelect A combination of Clear and Select, provided for1012 convenience.1013 */ 1014 1015 /*! 1016 Selects the item \a selection using the specified \a command, and emits1017 selectionChanged().1018 1019 \sa QItemSelectionModel::SelectionFlag1038 \enum QItemSelectionModel::SelectionFlag 1039 1040 This enum describes the way the selection model will be updated. 1041 1042 \value NoUpdate No selection will be made. 1043 \value Clear The complete selection will be cleared. 1044 \value Select All specified indexes will be selected. 1045 \value Deselect All specified indexes will be deselected. 1046 \value Toggle All specified indexes will be selected or 1047 deselected depending on their current state. 1048 \value Current The current selection will be updated. 1049 \value Rows All indexes will be expanded to span rows. 1050 \value Columns All indexes will be expanded to span columns. 1051 \value SelectCurrent A combination of Select and Current, provided for 1052 convenience. 1053 \value ToggleCurrent A combination of Toggle and Current, provided for 1054 convenience. 1055 \value ClearAndSelect A combination of Clear and Select, provided for 1056 convenience. 1057 */ 1058 1059 /*! 1060 Selects the item \a selection using the specified \a command, and emits 1061 selectionChanged(). 1062 1063 \sa QItemSelectionModel::SelectionFlag 1020 1064 */ 1021 1065 void QItemSelectionModel::select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) … … 1057 1101 1058 1102 /*! 1059 Clears the selection model. Emits selectionChanged() and currentChanged().1103 Clears the selection model. Emits selectionChanged() and currentChanged(). 1060 1104 */ 1061 1105 void QItemSelectionModel::clear() … … 1073 1117 1074 1118 /*! 1075 Clears the selection model. Does not emit any signals.1119 Clears the selection model. Does not emit any signals. 1076 1120 */ 1077 1121 void QItemSelectionModel::reset() … … 1083 1127 1084 1128 /*! 1085 \since 4.21086 Clears the selection in the selection model. Emits selectionChanged().1129 \since 4.2 1130 Clears the selection in the selection model. Emits selectionChanged(). 1087 1131 */ 1088 1132 void QItemSelectionModel::clearSelection() … … 1100 1144 1101 1145 /*! 1102 Sets the model item \a index to be the current item, and emits1103 currentChanged(). The current item is used for keyboard navigation and1104 focus indication; it is independent of any selected items, although a1105 selected item can also be the current item.1106 1107 Depending on the specified \a command, the \a index can also become part1108 of the current selection.1109 \sa select()1146 Sets the model item \a index to be the current item, and emits 1147 currentChanged(). The current item is used for keyboard navigation and 1148 focus indication; it is independent of any selected items, although a 1149 selected item can also be the current item. 1150 1151 Depending on the specified \a command, the \a index can also become part 1152 of the current selection. 1153 \sa select() 1110 1154 */ 1111 1155 void QItemSelectionModel::setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) … … 1131 1175 1132 1176 /*! 1133 Returns the model item index for the current item, or an invalid index1134 if there is no current item.1177 Returns the model item index for the current item, or an invalid index 1178 if there is no current item. 1135 1179 */ 1136 1180 QModelIndex QItemSelectionModel::currentIndex() const … … 1140 1184 1141 1185 /*! 1142 Returns true if the given model item \a index is selected.1186 Returns true if the given model item \a index is selected. 1143 1187 */ 1144 1188 bool QItemSelectionModel::isSelected(const QModelIndex &index) const … … 1177 1221 1178 1222 /*! 1179 Returns true if all items are selected in the \a row with the given1180 \a parent.1181 1182 Note that this function is usually faster than calling isSelected()1183 on all items in the same row and that unselectable items are1184 ignored.1223 Returns true if all items are selected in the \a row with the given 1224 \a parent. 1225 1226 Note that this function is usually faster than calling isSelected() 1227 on all items in the same row and that unselectable items are 1228 ignored. 1185 1229 */ 1186 1230 bool QItemSelectionModel::isRowSelected(int row, const QModelIndex &parent) const … … 1237 1281 1238 1282 /*! 1239 Returns true if all items are selected in the \a column with the given1240 \a parent.1241 1242 Note that this function is usually faster than calling isSelected()1243 on all items in the same column and that unselectable items are1244 ignored.1283 Returns true if all items are selected in the \a column with the given 1284 \a parent. 1285 1286 Note that this function is usually faster than calling isSelected() 1287 on all items in the same column and that unselectable items are 1288 ignored. 1245 1289 */ 1246 1290 bool QItemSelectionModel::isColumnSelected(int column, const QModelIndex &parent) const … … 1297 1341 1298 1342 /*! 1299 Returns true if there are anyitems selected in the \a row with the given1300 \a parent.1343 Returns true if there are any items selected in the \a row with the given 1344 \a parent. 1301 1345 */ 1302 1346 bool QItemSelectionModel::rowIntersectsSelection(int row, const QModelIndex &parent) const … … 1314 1358 int right = sel.at(i).right(); 1315 1359 if (top <= row && bottom >= row) { 1316 Qt::ItemFlags leftFlags = d->model->index(row, left, parent).flags();1317 Qt::ItemFlags rightFlags = d->model->index(row, right, parent).flags();1318 if ((leftFlags & Qt::ItemIsSelectable) && (leftFlags & Qt::ItemIsEnabled)1319 && (rightFlags & Qt::ItemIsSelectable) && (rightFlags & Qt::ItemIsEnabled))1320 return true;1360 for (int j = left; j <= right; j++) { 1361 const Qt::ItemFlags flags = d->model->index(row, j, parent).flags(); 1362 if ((flags & Qt::ItemIsSelectable) && (flags & Qt::ItemIsEnabled)) 1363 return true; 1364 } 1321 1365 } 1322 1366 } … … 1326 1370 1327 1371 /*! 1328 Returns true if there are anyitems selected in the \a column with the given1329 \a parent.1372 Returns true if there are any items selected in the \a column with the given 1373 \a parent. 1330 1374 */ 1331 1375 bool QItemSelectionModel::columnIntersectsSelection(int column, const QModelIndex &parent) const … … 1343 1387 int bottom = sel.at(i).bottom(); 1344 1388 if (left <= column && right >= column) { 1345 Qt::ItemFlags topFlags = d->model->index(top, column, parent).flags();1346 Qt::ItemFlags bottomFlags = d->model->index(bottom, column, parent).flags();1347 if ((topFlags & Qt::ItemIsSelectable) && (topFlags & Qt::ItemIsEnabled)1348 && (bottomFlags & Qt::ItemIsSelectable) && (bottomFlags & Qt::ItemIsEnabled))1349 return true;1389 for (int j = top; j <= bottom; j++) { 1390 const Qt::ItemFlags flags = d->model->index(j, column, parent).flags(); 1391 if ((flags & Qt::ItemIsSelectable) && (flags & Qt::ItemIsEnabled)) 1392 return true; 1393 } 1350 1394 } 1351 1395 } … … 1367 1411 sel.merge(d->currentSelection, d->currentCommand); 1368 1412 return !sel.isEmpty(); 1369 } 1370 else { 1413 } else { 1371 1414 return !(d->ranges.isEmpty() && d->currentSelection.isEmpty()); 1372 1415 } … … 1374 1417 1375 1418 /*! 1376 Returns a list of all selected model item indexes. The list contains no1377 duplicates, and is not sorted.1419 Returns a list of all selected model item indexes. The list contains no 1420 duplicates, and is not sorted. 1378 1421 */ 1379 1422 QModelIndexList QItemSelectionModel::selectedIndexes() const … … 1386 1429 1387 1430 /*! 1388 \since 4.21389 Returns the indexes in the given \a column for the rows where all columns are selected.1390 1391 \sa selectedIndexes(), selectedColumns()1431 \since 4.2 1432 Returns the indexes in the given \a column for the rows where all columns are selected. 1433 1434 \sa selectedIndexes(), selectedColumns() 1392 1435 */ 1393 1436 … … 1450 1493 1451 1494 /*! 1452 Returns the selection ranges stored in the selection model.1495 Returns the selection ranges stored in the selection model. 1453 1496 */ 1454 1497 const QItemSelection QItemSelectionModel::selection() const … … 1470 1513 1471 1514 /*! 1472 Returns the item model operated on by the selection model.1515 Returns the item model operated on by the selection model. 1473 1516 */ 1474 1517 const QAbstractItemModel *QItemSelectionModel::model() const … … 1478 1521 1479 1522 /*! 1480 Compares the two selections \a newSelection and \a oldSelection1481 and emits selectionChanged() with the deselected and selected items.1523 Compares the two selections \a newSelection and \a oldSelection 1524 and emits selectionChanged() with the deselected and selected items. 1482 1525 */ 1483 1526 void QItemSelectionModel::emitSelectionChanged(const QItemSelection &newSelection, … … 1546 1589 } 1547 1590 1548 emit selectionChanged(selected, deselected); 1591 if (!selected.isEmpty() || !deselected.isEmpty()) 1592 emit selectionChanged(selected, deselected); 1549 1593 } 1550 1594 … … 1554 1598 #ifndef Q_BROKEN_DEBUG_STREAM 1555 1599 dbg.nospace() << "QItemSelectionRange(" << range.topLeft() 1556 << "," << range.bottomRight() << ")";1600 << ',' << range.bottomRight() << ')'; 1557 1601 return dbg.space(); 1558 1602 #else -
trunk/src/gui/itemviews/qitemselectionmodel.h
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 ** -
trunk/src/gui/itemviews/qitemselectionmodel_p.h
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 ** … … 66 66 : model(0), 67 67 currentCommand(QItemSelectionModel::NoUpdate), 68 tableSelected(false) {}68 tableSelected(false), tableColCount(0), tableRowCount(0) {} 69 69 70 70 QItemSelection expandSelection(const QItemSelection &selection, -
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 (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 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 around the 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 if (d->commonListView && d->viewMode == mode) 462 return; 461 463 d->viewMode = mode; 462 464 465 delete d->commonListView; 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->viewport->update(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 \reimp 647 648 We have a QListView way of knowing what elements are on the viewport 649 through the intersectingSet function 650 */ 651 QItemViewPaintPairs QListViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const 652 { 653 Q_ASSERT(r); 654 Q_Q(const QListView); 655 QRect &rect = *r; 656 const QRect viewportRect = viewport->rect(); 657 QItemViewPaintPairs ret; 658 const QSet<QModelIndex> visibleIndexes = intersectingSet(viewportRect).toList().toSet(); 659 for (int i = 0; i < indexes.count(); ++i) { 660 const QModelIndex &index = indexes.at(i); 661 if (visibleIndexes.contains(index)) { 662 const QRect current = q->visualRect(index); 663 ret += qMakePair(current, index); 664 rect |= current; 665 } 666 } 667 rect &= viewportRect; 668 return ret; 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 if (!isVisible()) 776 return; 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->viewport->update(d->mapToViewport(rect.united(d->elasticBand))); 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->viewport->update(d->mapToViewport(d->elasticBand)); 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 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 897 } 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 int maxSize = (flow() == TopToBottom) 970 ? qMax(viewport()->size().width(), d->contentsSize().width()) - 2 * d->spacing() 971 : qMax(viewport()->size().height(), d->contentsSize().height()) - 2 * d->spacing(); 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 if (flow() == TopToBottom) 979 option.rect.setWidth(qMin(maxSize, option.rect.width())); 980 else 981 option.rect.setHeight(qMin(maxSize, option.rect.height())); 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 const QVector<QModelIndex> intersectVector = 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->column, 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->column, 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 QVector<QModelIndex> intersectVector; 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 intersectVector = 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 intersectVector = 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 intersectVector = 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 intersectVector = 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 or its view mode is ListView, 1235 this function will have no 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 const QVector<QModelIndex> intersectVector = 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 QVector<QModelIndex> intersectVector = 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 intersectVector = 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 //we only display the children of the root in a listview 1402 //we're not interested in the other model indexes 1403 if (parent != d->root) 1404 continue; 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, parent); 1414 const QModelIndex bottom = d->model->index(b, c, parent); 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 if (!d->selectionModel) 1431 return QModelIndexList(); 1432 1433 QModelIndexList viewSelected = d->selectionModel->selectedIndexes(); 1434 for (int i = 0; i < viewSelected.count(); ++i) { 1435 const QModelIndex &index = viewSelected.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 if (max < 0 || last < first) { 1704 return true; // nothing to do 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 const QVector<QModelIndex> intersectVector = intersectingSet(rect); 1796 QVector<QModelIndex>::const_iterator it = intersectVector.begin(); 2114 1797 for (; it != intersectVector.end(); ++it) { 2115 1798 if (!tl.isValid() && !br.isValid()) { … … 2135 1818 } 2136 1819 1820 #ifndef QT_NO_DRAGANDDROP 1821 QAbstractItemView::DropIndicatorPosition QListViewPrivate::position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const 1822 { 1823 if (viewMode == QListView::ListMode && flow == QListView::LeftToRight) 1824 return static_cast<QListModeViewBase *>(commonListView)->position(pos, rect, idx); 1825 else 1826 return QAbstractItemViewPrivate::position(pos, rect, idx); 1827 } 1828 #endif 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 hint = QListView::PositionAtBottom; 2129 if (hint == QListView::EnsureVisible) 2130 return value; 2131 2132 return perItemScrollToValue(index, value, area.width(), hint, Qt::Horizontal, isWrapping(), rect.width()); 2133 } 2134 2135 void QListModeViewBase::scrollContentsBy(int dx, int dy, bool scrollElasticBand) 2174 2136 { 2175 2137 // ### reorder this logic 2176 const int verticalValue = verticalScrollBar Value();2177 const int horizontalValue = horizontalScrollBar Value();2138 const int verticalValue = verticalScrollBar()->value(); 2139 const int horizontalValue = horizontalScrollBar()->value(); 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(scrollValueMap.at(currentValue)); 2168 int previousCoordinate = flowPositions.at(scrollValueMap.at(previousValue)); 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(scrollValueMap.at(currentValue)); 2174 int previousCoordinate = flowPositions.at(scrollValueMap.at(previousValue)); 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 QListModeViewBase::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 QListModeViewBase::initStaticLayout(const QListViewLayoutInfo &info) 2267 2230 { 2268 2231 int x, y; … … 2272 2235 segmentStartRows.clear(); 2273 2236 segmentExtents.clear(); 2237 scrollValueMap.clear(); 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 QListModeViewBase::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 scrollValueMap.append(flowPositions.count()); 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 scrollValueMap.append(flowPositions.count()); 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 QVector<QModelIndex> QListModeViewBase::intersectingSet(const QRect &area) const 2371 { 2372 QVector<QModelIndex> ret; 2407 2373 int segStartPosition; 2408 2374 int segEndPosition; … … 2421 2387 } 2422 2388 if (segmentPositions.count() < 2 || flowPositions.isEmpty()) 2423 return ;2389 return ret; 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 ret += index; 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 // But we don't shrink the items. 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(rect.width(), qMax(contentsSize.width(), viewport()->width()) - 2 * spacing())); 2463 2430 } else { // LeftToRight 2464 2431 result.setTop(spacing()); 2465 result.setHeight(qMax( csize.height(), vsize.height()) - 2 * spacing());2432 result.setHeight(qMax(rect.height(), qMax(contentsSize.height(), viewport()->height()) - 2 * spacing())); 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 QListModeViewBase::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 QListModeViewBase::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 QIconModeViewBase::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 QIconModeViewBase::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 QIconModeViewBase::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 QIconModeViewBase::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 QIconModeViewBase::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 QIconModeViewBase::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 QIconModeViewBase::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 QIconModeViewBase *_this = static_cast<QIconModeViewBase *>(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 = _this->dd->listViewItemToIndex(*vi); 2859 2982 Q_ASSERT(index.isValid()); 2860 _this->inter sectVector.append(index);2983 _this->interSectingVector->append(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 QIconModeViewBase::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 QIconModeViewBase::draggedItemsDelta() const 2906 3017 { 2907 3018 if (movement() == QListView::Snap) { … … 2913 3024 } 2914 3025 2915 QRect Q DynamicListViewBase::draggedItemsRect() const3026 QRect QIconModeViewBase::draggedItemsRect() const 2916 3027 { 2917 3028 QRect rect = itemsRect(draggedItems); … … 2932 3043 } 2933 3044 2934 void Q DynamicListViewBase::clear()3045 void QIconModeViewBase::clear() 2935 3046 { 2936 3047 tree.destroy(); … … 2941 3052 } 2942 3053 2943 void Q DynamicListViewBase::updateContentsSize()3054 void QIconModeViewBase::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->commonListView->itemIndex(itm); 2997 3108 } 2998 3109 -
trunk/src/gui/itemviews/qlistview.h
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 ** -
trunk/src/gui/itemviews/qlistview_p.h
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 ** … … 68 68 { 69 69 friend class QListViewPrivate; 70 friend class Q StaticListViewBase;71 friend class Q DynamicListViewBase;70 friend class QListModeViewBase; 71 friend class QIconModeViewBase; 72 72 public: 73 73 inline QListViewItem() … … 85 85 { return !(*this == other); } 86 86 inline bool isValid() const 87 { return (x > -1) && (y > -1) && (w > 0) && (h > 0) && (indexHint > -1); }87 { return rect().isValid() && (indexHint > -1); } 88 88 inline void invalidate() 89 89 { x = -1; y = -1; w = 0; h = 0; } … … 121 121 { 122 122 public: 123 inline QCommonListViewBase(QListView *q, QListViewPrivate *d) : dd(d), qq(q) {} 124 123 inline QCommonListViewBase(QListView *q, QListViewPrivate *d) : dd(d), qq(q), batchStartRow(0), batchSavedDeltaSeg(0) {} 124 virtual ~QCommonListViewBase() {} 125 126 //common interface 127 virtual int itemIndex(const QListViewItem &item) const = 0; 128 virtual QListViewItem indexToListViewItem(const QModelIndex &index) const = 0; 129 virtual bool doBatchedItemLayout(const QListViewLayoutInfo &info, int max) = 0; 130 virtual void clear() = 0; 131 virtual void setRowCount(int) = 0; 132 virtual QVector<QModelIndex> intersectingSet(const QRect &area) const = 0; 133 virtual void dataChanged(const QModelIndex &, const QModelIndex &) = 0; 134 135 virtual int horizontalScrollToValue(int index, QListView::ScrollHint hint, 136 bool leftOf, bool rightOf, const QRect &area, const QRect &rect) const; 137 virtual int verticalScrollToValue(int index, QListView::ScrollHint hint, 138 bool above, bool below, const QRect &area, const QRect &rect) const; 139 virtual void scrollContentsBy(int dx, int dy, bool scrollElasticBand); 140 virtual QRect mapToViewport(const QRect &rect) const {return rect;} 141 virtual int horizontalOffset() const; 142 virtual int verticalOffset() const { return verticalScrollBar()->value(); } 143 virtual void updateHorizontalScrollBar(const QSize &step); 144 virtual void updateVerticalScrollBar(const QSize &step); 145 virtual void appendHiddenRow(int row); 146 virtual void removeHiddenRow(int row); 147 virtual void setPositionForIndex(const QPoint &, const QModelIndex &) { } 148 149 #ifndef QT_NO_DRAGANDDROP 150 virtual void paintDragDrop(QPainter *painter) = 0; 151 virtual bool filterDragMoveEvent(QDragMoveEvent *) { return false; } 152 virtual bool filterDragLeaveEvent(QDragLeaveEvent *) { return false; } 153 virtual bool filterDropEvent(QDropEvent *) { return false; } 154 virtual bool filterStartDrag(Qt::DropActions) { return false; } 155 #endif 156 157 158 //other inline members 125 159 inline int spacing() const; 126 160 inline bool isWrapping() const; … … 134 168 inline int column() const; 135 169 136 inline int verticalScrollBarValue() const;137 inline int horizontalScrollBarValue() const;170 inline QScrollBar *verticalScrollBar() const; 171 inline QScrollBar *horizontalScrollBar() const; 138 172 inline QListView::ScrollMode verticalScrollMode() const; 139 173 inline QListView::ScrollMode horizontalScrollMode() const; … … 154 188 inline int hiddenCount() const; 155 189 156 inline void clearIntersections() const;157 inline void appendToIntersections(const QModelIndex &idx) const;158 159 190 inline bool isRightToLeft() const; 160 191 161 192 QListViewPrivate *dd; 162 193 QListView *qq; 163 }; 164 165 // ### rename to QListModeViewBase 166 class QStaticListViewBase : public QCommonListViewBase 167 { 168 friend class QListViewPrivate; 194 QSize contentsSize; 195 int batchStartRow; 196 int batchSavedDeltaSeg; 197 }; 198 199 class QListModeViewBase : public QCommonListViewBase 200 { 169 201 public: 170 QStaticListViewBase(QListView *q, QListViewPrivate *d) : QCommonListViewBase(q, d), 171 batchStartRow(0), batchSavedDeltaSeg(0), batchSavedPosition(0) {} 202 QListModeViewBase(QListView *q, QListViewPrivate *d) : QCommonListViewBase(q, d) {} 172 203 173 204 QVector<int> flowPositions; … … 175 206 QVector<int> segmentStartRows; 176 207 QVector<int> segmentExtents; 177 178 QSize contentsSize; 208 QVector<int> scrollValueMap; 179 209 180 210 // used when laying out in batches 181 int batchStartRow;182 int batchSavedDeltaSeg;183 211 int batchSavedPosition; 184 212 213 //reimplementations 214 int itemIndex(const QListViewItem &item) const { return item.indexHint; } 215 QListViewItem indexToListViewItem(const QModelIndex &index) const; 185 216 bool doBatchedItemLayout(const QListViewLayoutInfo &info, int max); 186 217 void clear(); 218 void setRowCount(int rowCount) { flowPositions.resize(rowCount); } 219 QVector<QModelIndex> intersectingSet(const QRect &area) const; 220 void dataChanged(const QModelIndex &, const QModelIndex &); 221 222 int horizontalScrollToValue(int index, QListView::ScrollHint hint, 223 bool leftOf, bool rightOf,const QRect &area, const QRect &rect) const; 224 int verticalScrollToValue(int index, QListView::ScrollHint hint, 225 bool above, bool below, const QRect &area, const QRect &rect) const; 226 void scrollContentsBy(int dx, int dy, bool scrollElasticBand); 227 QRect mapToViewport(const QRect &rect) const; 228 int horizontalOffset() const; 229 int verticalOffset() const; 230 void updateHorizontalScrollBar(const QSize &step); 231 void updateVerticalScrollBar(const QSize &step); 232 233 #ifndef QT_NO_DRAGANDDROP 234 void paintDragDrop(QPainter *painter); 235 236 // The next two methods are to be used on LefToRight flow only. 237 // WARNING: Plenty of duplicated code from QAbstractItemView{,Private}. 238 QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const; 239 void dragMoveEvent(QDragMoveEvent *e); 240 #endif 241 242 private: 187 243 QPoint initStaticLayout(const QListViewLayoutInfo &info); 188 244 void doStaticLayout(const QListViewLayoutInfo &info); 189 void intersectingStaticSet(const QRect &area) const;190 191 int itemIndex(const QListViewItem &item) const;192 193 int perItemScrollingPageSteps(int length, int bounds, bool wrap) const;194 195 245 int perItemScrollToValue(int index, int value, int height, 196 246 QAbstractItemView::ScrollHint hint, 197 247 Qt::Orientation orientation, bool wrap, int extent) const; 198 199 QRect mapToViewport(const QRect &rect) const; 200 201 QListViewItem indexToListViewItem(const QModelIndex &index) const; 202 203 void scrollContentsBy(int &dx, int &dy); 204 205 int verticalPerItemValue(int itemIndex, int verticalValue, int areaHeight, 206 bool above, bool below, bool wrap, QListView::ScrollHint hint, int itemHeight) const; 207 int horizontalPerItemValue(int itemIndex, int horizontalValue, int areaWidth, 208 bool leftOf, bool rightOf, bool wrap, QListView::ScrollHint hint, int itemWidth) const; 209 210 void clear(); 211 }; 212 213 // ### rename to QIconModeViewBase 214 class QDynamicListViewBase : public QCommonListViewBase 215 { 216 friend class QListViewPrivate; 248 int perItemScrollingPageSteps(int length, int bounds, bool wrap) const; 249 }; 250 251 class QIconModeViewBase : public QCommonListViewBase 252 { 217 253 public: 218 QDynamicListViewBase(QListView *q, QListViewPrivate *d) : QCommonListViewBase(q, d), 219 batchStartRow(0), batchSavedDeltaSeg(0) {} 254 QIconModeViewBase(QListView *q, QListViewPrivate *d) : QCommonListViewBase(q, d), interSectingVector(0) {} 220 255 221 256 QBspTree tree; … … 223 258 QBitArray moved; 224 259 225 QSize contentsSize;226 227 260 QVector<QModelIndex> draggedItems; // indices to the tree.itemVector 228 261 mutable QPoint draggedItemsPos; 229 262 230 263 // used when laying out in batches 231 int batchStartRow; 232 int batchSavedDeltaSeg; 233 264 QVector<QModelIndex> *interSectingVector; //used from within intersectingSet 265 266 //reimplementations 267 int itemIndex(const QListViewItem &item) const; 268 QListViewItem indexToListViewItem(const QModelIndex &index) const; 269 bool doBatchedItemLayout(const QListViewLayoutInfo &info, int max); 270 void clear(); 271 void setRowCount(int rowCount); 272 QVector<QModelIndex> intersectingSet(const QRect &area) const; 273 274 void scrollContentsBy(int dx, int dy, bool scrollElasticBand); 234 275 void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); 235 bool doBatchedItemLayout(const QListViewLayoutInfo &info, int max); 236 276 void appendHiddenRow(int row); 277 void removeHiddenRow(int row); 278 void setPositionForIndex(const QPoint &position, const QModelIndex &index); 279 280 #ifndef QT_NO_DRAGANDDROP 281 void paintDragDrop(QPainter *painter); 282 bool filterDragMoveEvent(QDragMoveEvent *); 283 bool filterDragLeaveEvent(QDragLeaveEvent *); 284 bool filterDropEvent(QDropEvent *e); 285 bool filterStartDrag(Qt::DropActions); 286 #endif 287 288 private: 237 289 void initBspTree(const QSize &contents); 238 290 QPoint initDynamicLayout(const QListViewLayoutInfo &info); 239 291 void doDynamicLayout(const QListViewLayoutInfo &info); 240 void intersectingDynamicSet(const QRect &area) const;241 242 292 static void addLeaf(QVector<int> &leaf, const QRect &area, 243 293 uint visited, QBspTree::Data data); 244 245 void insertItem(int index); 246 void removeItem(int index); 294 QRect itemsRect(const QVector<QModelIndex> &indexes) const; 295 QRect draggedItemsRect() const; 296 QPoint snapToGrid(const QPoint &pos) const; 297 void updateContentsSize(); 298 QPoint draggedItemsDelta() const; 299 void drawItems(QPainter *painter, const QVector<QModelIndex> &indexes) const; 247 300 void moveItem(int index, const QPoint &dest); 248 301 249 int itemIndex(const QListViewItem &item) const;250 251 void createItems(int to);252 void drawItems(QPainter *painter, const QVector<QModelIndex> &indexes) const;253 QRect itemsRect(const QVector<QModelIndex> &indexes) const;254 255 QPoint draggedItemsDelta() const;256 QRect draggedItemsRect() const;257 258 QPoint snapToGrid(const QPoint &pos) const;259 260 void scrollElasticBandBy(int dx, int dy);261 262 QListViewItem indexToListViewItem(const QModelIndex &index) const;263 264 void clear();265 void updateContentsSize();266 302 }; 267 303 … … 278 314 bool doItemsLayout(int num); 279 315 280 inline voidintersectingSet(const QRect &area, bool doLayout = true) const {316 inline QVector<QModelIndex> intersectingSet(const QRect &area, bool doLayout = true) const { 281 317 if (doLayout) executePostedLayout(); 282 318 QRect a = (q_func()->isRightToLeft() ? flipX(area.normalized()) : area.normalized()); 283 if (viewMode == QListView::ListMode) staticListView->intersectingStaticSet(a); 284 else dynamicListView->intersectingDynamicSet(a); 319 return commonListView->intersectingSet(a); 285 320 } 286 321 287 // ### FIXME: 288 inline void resetBatchStartRow() 289 { if (viewMode == QListView::ListMode) staticListView->batchStartRow = 0; 290 else dynamicListView->batchStartRow = 0; } 291 inline int batchStartRow() const 292 { return (viewMode == QListView::ListMode 293 ? staticListView->batchStartRow : dynamicListView->batchStartRow); } 294 inline QSize contentsSize() const 295 { return (viewMode == QListView::ListMode 296 ? staticListView->contentsSize : dynamicListView->contentsSize); } 297 inline void setContentsSize(int w, int h) 298 { if (viewMode == QListView::ListMode) staticListView->contentsSize = QSize(w, h); 299 else dynamicListView->contentsSize = QSize(w, h); } 322 inline void resetBatchStartRow() { commonListView->batchStartRow = 0; } 323 inline int batchStartRow() const { return commonListView->batchStartRow; } 324 inline QSize contentsSize() const { return commonListView->contentsSize; } 325 inline void setContentsSize(int w, int h) { commonListView->contentsSize = QSize(w, h); } 300 326 301 327 inline int flipX(int x) const … … 308 334 { if (q_func()->isRightToLeft()) return flipX(item.rect()); return item.rect(); } 309 335 310 int itemIndex(const QListViewItem &item) const;311 336 QListViewItem indexToListViewItem(const QModelIndex &index) const; 312 337 inline QModelIndex listViewItemToIndex(const QListViewItem &item) const 313 { return model->index(itemIndex(item), column, root); } 314 315 QRect mapToViewport(const QRect &rect, bool greedy = false) const; 338 { return model->index(commonListView->itemIndex(item), column, root); } 339 340 QRect rectForIndex(const QModelIndex &index) const 341 { 342 if (!isIndexValid(index) || index.parent() != root || index.column() != column || isHidden(index.row())) 343 return QRect(); 344 executePostedLayout(); 345 return viewItemRect(indexToListViewItem(index)); 346 } 347 348 void viewUpdateGeometries() { q_func()->updateGeometries(); } 349 350 351 QRect mapToViewport(const QRect &rect, bool extend = true) const; 316 352 317 353 QModelIndex closestIndex(const QRect &target, const QVector<QModelIndex> &candidates) const; … … 326 362 QItemSelection selection(const QRect &rect) const; 327 363 void selectAll(QItemSelectionModel::SelectionFlags command); 364 365 #ifndef QT_NO_DRAGANDDROP 366 virtual QAbstractItemView::DropIndicatorPosition position(const QPoint &pos, const QRect &rect, const QModelIndex &idx) const; 367 #endif 328 368 329 369 inline void setGridSize(const QSize &size) { grid = size; } … … 352 392 void scrollElasticBandBy(int dx, int dy); 353 393 354 // ### FIXME: we only need one at a time 355 QDynamicListViewBase *dynamicListView; 356 QStaticListViewBase *staticListView; 394 QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const; 395 396 void emitIndexesMoved(const QModelIndexList &indexes) { emit q_func()->indexesMoved(indexes); } 397 398 399 QCommonListViewBase *commonListView; 357 400 358 401 // ### FIXME: see if we can move the members into the dynamic/static classes … … 384 427 QRect layoutBounds; 385 428 386 // used for intersecting set387 mutable QVector<QModelIndex> intersectVector;388 389 429 // timers 390 430 QBasicTimer batchLayoutTimer; … … 415 455 inline int QCommonListViewBase::column() const { return dd->column; } 416 456 417 inline int QCommonListViewBase::verticalScrollBarValue() const { return qq->verticalScrollBar()->value(); }418 inline int QCommonListViewBase::horizontalScrollBarValue() const { return qq->horizontalScrollBar()->value(); }457 inline QScrollBar *QCommonListViewBase::verticalScrollBar() const { return qq->verticalScrollBar(); } 458 inline QScrollBar *QCommonListViewBase::horizontalScrollBar() const { return qq->horizontalScrollBar(); } 419 459 inline QListView::ScrollMode QCommonListViewBase::verticalScrollMode() const { return qq->verticalScrollMode(); } 420 460 inline QListView::ScrollMode QCommonListViewBase::horizontalScrollMode() const { return qq->horizontalScrollMode(); } … … 439 479 inline int QCommonListViewBase::hiddenCount() const { return dd->hiddenRows.count(); } 440 480 441 inline void QCommonListViewBase::clearIntersections() const { dd->intersectVector.clear(); }442 inline void QCommonListViewBase::appendToIntersections(const QModelIndex &idx) const { dd->intersectVector.append(idx); }443 444 481 inline bool QCommonListViewBase::isRightToLeft() const { return qq->isRightToLeft(); } 445 482 -
trunk/src/gui/itemviews/qlistwidget.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 ** … … 168 168 endRemoveRows(); 169 169 return item; 170 } 171 172 void QListModel::move(int srcRow, int dstRow) 173 { 174 if (srcRow == dstRow 175 || srcRow < 0 || srcRow >= items.count() 176 || dstRow < 0 || dstRow > items.count()) 177 return; 178 179 if (!beginMoveRows(QModelIndex(), srcRow, srcRow, QModelIndex(), dstRow)) 180 return; 181 if (srcRow < dstRow) 182 --dstRow; 183 items.move(srcRow, dstRow); 184 endMoveRows(); 170 185 } 171 186 … … 448 463 \ingroup model-view 449 464 450 QListWidgetItem is used to represent items in a list provided by the 451 QListWidget class. Each item can hold several pieces of information, 452 and will display these appropriately. 453 454 The item view convenience classes use a classic item-based interface 455 rather than a pure model/view approach. For a more flexible list view 456 widget, consider using the QListView class with a standard model. 457 458 List items can be automatically inserted into a list when they are 459 constructed by specifying the list widget: 465 A QListWidgetItem represents a single item in a QListWidget. Each item can 466 hold several pieces of information, and will display them appropriately. 467 468 The item view convenience classes use a classic item-based interface rather 469 than a pure model/view approach. For a more flexible list view widget, 470 consider using the QListView class with a standard model. 471 472 List items can be inserted automatically into a list, when they are 473 constructed, by specifying the list widget: 460 474 461 475 \snippet doc/src/snippets/qlistwidget-using/mainwindow.cpp 2 462 476 463 They can also be created without a parent widget, and later inserted into464 a list (see \l{QListWidget::insertItem()}).477 Alternatively, list items can also be created without a parent widget, and 478 later inserted into a list using QListWidget::insertItem(). 465 479 466 480 List items are typically used to display text() and an icon(). These are … … 472 486 473 487 By default, items are enabled, selectable, checkable, and can be the source 474 of a drag and drop operation. 488 of drag and drop operations. 489 475 490 Each item's flags can be changed by calling setFlags() with the appropriate 476 value (see \l{Qt::ItemFlags}). Checkable items can be checked, unchecked and491 value (see Qt::ItemFlags). Checkable items can be checked, unchecked and 477 492 partially checked with the setCheckState() function. The corresponding 478 checkState() function indicates what check state the item currently has. 479 480 The isHidden() function can be used to determine whether the 481 item is hidden. Items can be hidden with setHidden(). 493 checkState() function indicates the item's current check state. 494 495 The isHidden() function can be used to determine whether the item is 496 hidden. To hide an item, use setHidden(). 497 482 498 483 499 \section1 Subclassing 484 500 485 501 When subclassing QListWidgetItem to provide custom items, it is possible to 486 define new types for them so that they canbe distinguished from standard487 items. The constructors for subclasses that require this feature need to488 call the base class constructor with a new type value equal to or greater489 than \l UserType.502 define new types for them enabling them to be distinguished from standard 503 items. For subclasses that require this feature, ensure that you call the 504 base class constructor with a new type value equal to or greater than 505 \l UserType, within \e your constructor. 490 506 491 507 \sa QListWidget, {Model/View Programming}, QTreeWidgetItem, QTableWidgetItem … … 516 532 \fn QListWidget *QListWidgetItem::listWidget() const 517 533 518 Returns the list widget that containsthe item.519 */ 520 521 /*! 522 \fn void QListWidgetItem::setSelected(bool select)523 \since 4.2524 525 Sets the selected state of the item to \a select.526 527 \sa isSelected()528 */ 529 530 /*! 531 \fn bool QListWidgetItem::isSelected() const532 \since 4.2533 534 Returns true if the item is selected,otherwise returns false.535 536 \sa setSelected()537 */ 538 539 /*! 540 \fn void QListWidgetItem::setHidden(bool hide)541 \since 4.2542 543 Hides the item if \a hide is true,otherwise shows the item.544 545 \sa isHidden()546 */ 547 548 /*! 549 \fn bool QListWidgetItem::isHidden() const550 \since 4.2551 552 Returns true if the item is hidden,otherwise returns false.553 554 \sa setHidden()534 Returns the list widget containing the item. 535 */ 536 537 /*! 538 \fn void QListWidgetItem::setSelected(bool select) 539 \since 4.2 540 541 Sets the selected state of the item to \a select. 542 543 \sa isSelected() 544 */ 545 546 /*! 547 \fn bool QListWidgetItem::isSelected() const 548 \since 4.2 549 550 Returns true if the item is selected; otherwise returns false. 551 552 \sa setSelected() 553 */ 554 555 /*! 556 \fn void QListWidgetItem::setHidden(bool hide) 557 \since 4.2 558 559 Hides the item if \a hide is true; otherwise shows the item. 560 561 \sa isHidden() 562 */ 563 564 /*! 565 \fn bool QListWidgetItem::isHidden() const 566 \since 4.2 567 568 Returns true if the item is hidden; otherwise returns false. 569 570 \sa setHidden() 555 571 */ 556 572 … … 559 575 560 576 Constructs an empty list widget item of the specified \a type with the 561 given \a parent. 562 If the parent is not specified, the item will need to be inserted into a 563 list widget with QListWidget::insertItem(). 577 given \a parent. If \a parent is not specified, the item will need to be 578 inserted into a list widget with QListWidget::insertItem(). 579 580 This constructor inserts the item into the model of the parent that is 581 passed to the constructor. If the model is sorted then the behavior of the 582 insert is undetermined since the model will call the \c '<' operator method 583 on the item which, at this point, is not yet constructed. To avoid the 584 undetermined behavior, we recommend not to specify the parent and use 585 QListWidget::insertItem() instead. 564 586 565 587 \sa type() … … 580 602 581 603 Constructs an empty list widget item of the specified \a type with the 582 given \a text and \a parent. 583 If the parent is not specified, the item will need to be inserted into a 584 list widget with QListWidget::insertItem(). 604 given \a text and \a parent. If the parent is not specified, the item will 605 need to be inserted into a list widget with QListWidget::insertItem(). 606 607 This constructor inserts the item into the model of the parent that is 608 passed to the constructor. If the model is sorted then the behavior of the 609 insert is undetermined since the model will call the \c '<' operator method 610 on the item which, at this point, is not yet constructed. To avoid the 611 undetermined behavior, we recommend not to specify the parent and use 612 QListWidget::insertItem() instead. 585 613 586 614 \sa type() … … 603 631 604 632 Constructs an empty list widget item of the specified \a type with the 605 given \a icon, \a text and \a parent. 606 If the parent is not specified, the item will need to be inserted into a 607 list widget with QListWidget::insertItem(). 633 given \a icon, \a text and \a parent. If the parent is not specified, the 634 item will need to be inserted into a list widget with 635 QListWidget::insertItem(). 636 637 This constructor inserts the item into the model of the parent that is 638 passed to the constructor. If the model is sorted then the behavior of the 639 insert is undetermined since the model will call the \c '<' operator method 640 on the item which, at this point, is not yet constructed. To avoid the 641 undetermined behavior, we recommend not to specify the parent and use 642 QListWidget::insertItem() instead. 608 643 609 644 \sa type() … … 625 660 626 661 /*! 627 Destroys the list item.662 Destroys the list item. 628 663 */ 629 664 QListWidgetItem::~QListWidgetItem() … … 635 670 636 671 /*! 637 Creates an exact copy of the item.672 Creates an exact copy of the item. 638 673 */ 639 674 QListWidgetItem *QListWidgetItem::clone() const … … 643 678 644 679 /*! 645 This function sets the data for a given \a role to the given \a value (see 646 \l{Qt::ItemDataRole}). Reimplement this function if you need 647 extra roles or special behavior for certain roles. 648 649 \sa Qt::ItemDataRole, data() 680 Sets the data for a given \a role to the given \a value. Reimplement this 681 function if you need extra roles or special behavior for certain roles. 682 683 \sa Qt::ItemDataRole, data() 650 684 */ 651 685 void QListWidgetItem::setData(int role, const QVariant &value) … … 669 703 670 704 /*! 671 This function returns the item's data for a given \a role (see 672 Qt::ItemDataRole). Reimplement this function if you need 673 extra roles or special behavior for certain roles. 705 Returns the item's data for a given \a role. Reimplement this function if 706 you need extra roles or special behavior for certain roles. 707 708 \sa Qt::ItemDataRole, setData() 674 709 */ 675 710 QVariant QListWidgetItem::data(int role) const … … 683 718 684 719 /*! 685 Returns true if this item's text is less then \a other item's text;686 otherwise returns false.720 Returns true if this item's text is less then \a other item's text; 721 otherwise returns false. 687 722 */ 688 723 bool QListWidgetItem::operator<(const QListWidgetItem &other) const 689 724 { 690 return text() < other.text(); 725 const QVariant v1 = data(Qt::DisplayRole), v2 = other.data(Qt::DisplayRole); 726 return QAbstractItemModelPrivate::variantLessThan(v1, v2); 691 727 } 692 728 … … 712 748 out << d->values; 713 749 } 750 #endif // QT_NO_DATASTREAM 714 751 715 752 /*! 716 753 \since 4.1 717 754 718 Constructs a copy of \a other. Note that type() and listWidget() 719 are notcopied.755 Constructs a copy of \a other. Note that type() and listWidget() are not 756 copied. 720 757 721 758 This function is useful when reimplementing clone(). … … 732 769 733 770 /*! 734 Assigns \a other's data and flags to this item. Note that type() 735 andlistWidget() are not copied.771 Assigns \a other's data and flags to this item. Note that type() and 772 listWidget() are not copied. 736 773 737 774 This function is useful when reimplementing clone(). … … 746 783 } 747 784 785 #ifndef QT_NO_DATASTREAM 786 748 787 /*! 749 788 \relates QListWidgetItem … … 779 818 780 819 /*! 781 \fn Qt::ItemFlags QListWidgetItem::flags() const782 783 Returns the item flags for this item (see \l{Qt::ItemFlags}).820 \fn Qt::ItemFlags QListWidgetItem::flags() const 821 822 Returns the item flags for this item (see \l{Qt::ItemFlags}). 784 823 */ 785 824 … … 825 864 826 865 /*! 827 \fn QFont QListWidgetItem::font() const 828 829 Returns the font used to display this list item's text. 830 */ 831 832 /*! 833 \fn int QListWidgetItem::textAlignment() const 834 835 Returns the text alignment for the list item (see \l{Qt::AlignmentFlag}). 866 \fn QFont QListWidgetItem::font() const 867 868 Returns the font used to display this list item's text. 869 */ 870 871 /*! 872 \fn int QListWidgetItem::textAlignment() const 873 874 Returns the text alignment for the list item. 875 876 \sa Qt::AlignmentFlag 836 877 */ 837 878 … … 879 920 880 921 /*! 881 \fn QSize QListWidgetItem::sizeHint() const882 \since 4.1883 884 Returns the size hint set for the list item.885 */ 886 887 /*! 888 \fn void QListWidgetItem::setSizeHint(const QSize &size)889 \since 4.1890 891 Sets the size hint for the list item to be \a size.892 If no size hint is set, the item delegate will compute the893 size hint based on the item data. 894 */ 895 896 /*! 897 \fn void QListWidgetItem::setFlags(Qt::ItemFlags flags) 898 899 Sets the item flags for the list item to \a flags (see 900 \l{Qt::ItemFlags}).922 \fn QSize QListWidgetItem::sizeHint() const 923 \since 4.1 924 925 Returns the size hint set for the list item. 926 */ 927 928 /*! 929 \fn void QListWidgetItem::setSizeHint(const QSize &size) 930 \since 4.1 931 932 Sets the size hint for the list item to be \a size. If no size hint is set, 933 the item delegate will compute the size hint based on the item data. 934 */ 935 936 /*! 937 \fn void QListWidgetItem::setFlags(Qt::ItemFlags flags) 938 939 Sets the item flags for the list item to \a flags. 940 941 \sa Qt::ItemFlags 901 942 */ 902 943 void QListWidgetItem::setFlags(Qt::ItemFlags aflags) { … … 927 968 928 969 Sets the status tip for the list item to the text specified by 929 \a statusTip. QListWidget mouse tracking needs to be enabled for this970 \a statusTip. QListWidget mouseTracking needs to be enabled for this 930 971 feature to work. 931 972 932 \sa statusTip() setToolTip() setWhatsThis()973 \sa statusTip(), setToolTip(), setWhatsThis(), QWidget::setMouseTracking() 933 974 */ 934 975 … … 938 979 Sets the tooltip for the list item to the text specified by \a toolTip. 939 980 940 \sa toolTip() setStatusTip()setWhatsThis()981 \sa toolTip(), setStatusTip(), setWhatsThis() 941 982 */ 942 983 … … 944 985 \fn void QListWidgetItem::setWhatsThis(const QString &whatsThis) 945 986 946 Sets the "What's This?" help for the list item to the text specified 947 by \a whatsThis. 948 949 \sa whatsThis() setStatusTip() setToolTip() 950 */ 951 952 /*! 953 \fn void QListWidgetItem::setFont(const QFont &font) 954 955 Sets the font used when painting the item to the given \a font. 956 */ 957 958 /*! 959 \fn void QListWidgetItem::setTextAlignment(int alignment) 960 961 Sets the list item's text alignment to \a alignment (see 962 \l{Qt::AlignmentFlag}). 987 Sets the "What's This?" help for the list item to the text specified by 988 \a whatsThis. 989 990 \sa whatsThis(), setStatusTip(), setToolTip() 991 */ 992 993 /*! 994 \fn void QListWidgetItem::setFont(const QFont &font) 995 996 Sets the font used when painting the item to the given \a font. 997 */ 998 999 /*! 1000 \fn void QListWidgetItem::setTextAlignment(int alignment) 1001 1002 Sets the list item's text alignment to \a alignment. 1003 1004 \sa Qt::AlignmentFlag 963 1005 */ 964 1006 … … 1015 1057 q, SLOT(_q_emitItemActivated(QModelIndex))); 1016 1058 QObject::connect(q, SIGNAL(entered(QModelIndex)), q, SLOT(_q_emitItemEntered(QModelIndex))); 1017 QObject::connect(model (), SIGNAL(dataChanged(QModelIndex,QModelIndex)),1059 QObject::connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), 1018 1060 q, SLOT(_q_emitItemChanged(QModelIndex))); 1019 1061 QObject::connect(q->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), … … 1021 1063 QObject::connect(q->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), 1022 1064 q, SIGNAL(itemSelectionChanged())); 1023 QObject::connect(model (), SIGNAL(dataChanged(QModelIndex,QModelIndex)),1065 QObject::connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), 1024 1066 q, SLOT(_q_dataChanged(QModelIndex,QModelIndex))); 1025 QObject::connect(model (), SIGNAL(columnsRemoved(QModelIndex,int,int)), q, SLOT(_q_sort()));1067 QObject::connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)), q, SLOT(_q_sort())); 1026 1068 } 1027 1069 … … 1029 1071 { 1030 1072 Q_Q(QListWidget); 1031 emit q->itemPressed( model()->at(index.row()));1073 emit q->itemPressed(listModel()->at(index.row())); 1032 1074 } 1033 1075 … … 1035 1077 { 1036 1078 Q_Q(QListWidget); 1037 emit q->itemClicked( model()->at(index.row()));1079 emit q->itemClicked(listModel()->at(index.row())); 1038 1080 } 1039 1081 … … 1041 1083 { 1042 1084 Q_Q(QListWidget); 1043 emit q->itemDoubleClicked( model()->at(index.row()));1085 emit q->itemDoubleClicked(listModel()->at(index.row())); 1044 1086 } 1045 1087 … … 1047 1089 { 1048 1090 Q_Q(QListWidget); 1049 emit q->itemActivated( model()->at(index.row()));1091 emit q->itemActivated(listModel()->at(index.row())); 1050 1092 } 1051 1093 … … 1053 1095 { 1054 1096 Q_Q(QListWidget); 1055 emit q->itemEntered( model()->at(index.row()));1097 emit q->itemEntered(listModel()->at(index.row())); 1056 1098 } 1057 1099 … … 1059 1101 { 1060 1102 Q_Q(QListWidget); 1061 emit q->itemChanged( model()->at(index.row()));1103 emit q->itemChanged(listModel()->at(index.row())); 1062 1104 } 1063 1105 … … 1067 1109 Q_Q(QListWidget); 1068 1110 QPersistentModelIndex persistentCurrent = current; 1069 QListWidgetItem *currentItem = model()->at(persistentCurrent.row());1070 emit q->currentItemChanged(currentItem, model()->at(previous.row()));1111 QListWidgetItem *currentItem = listModel()->at(persistentCurrent.row()); 1112 emit q->currentItemChanged(currentItem, listModel()->at(previous.row())); 1071 1113 1072 1114 //persistentCurrent is invalid if something changed the model in response … … 1083 1125 { 1084 1126 if (sortingEnabled) 1085 model ()->sort(0, sortOrder);1127 model->sort(0, sortOrder); 1086 1128 } 1087 1129 … … 1090 1132 { 1091 1133 if (sortingEnabled && topLeft.isValid() && bottomRight.isValid()) 1092 model()->ensureSorted(topLeft.column(), sortOrder,1134 listModel()->ensureSorted(topLeft.column(), sortOrder, 1093 1135 topLeft.row(), bottomRight.row()); 1094 1136 } … … 1099 1141 1100 1142 \ingroup model-view 1101 \mainclass 1102 1103 QListWidget is a convenience class that provides a list view similar to 1104 the one supplied by QListView, but with a classic item-based interface1105 for adding and removing items. QListWidget uses an internal model to1106 manageeach QListWidgetItem in the list.1143 1144 1145 QListWidget is a convenience class that provides a list view similar to the 1146 one supplied by QListView, but with a classic item-based interface for 1147 adding and removing items. QListWidget uses an internal model to manage 1148 each QListWidgetItem in the list. 1107 1149 1108 1150 For a more flexible list view widget, use the QListView class with a … … 1119 1161 1120 1162 There are two ways to add items to the list: they can be constructed with 1121 the list widget as their parent widget, or they can be constructed with 1122 no parent widget and added to the list later. If a list widget already1123 existswhen the items are constructed, the first method is easier to use:1163 the list widget as their parent widget, or they can be constructed with no 1164 parent widget and added to the list later. If a list widget already exists 1165 when the items are constructed, the first method is easier to use: 1124 1166 1125 1167 \snippet doc/src/snippets/qlistwidget-using/mainwindow.cpp 1 1126 1168 1127 If you need to insert a new item into the list at a particular position, 1128 i t is more required to construct the item without a parent widget and1129 use the insertItem() function to place it within the list. The list1130 widget willtake ownership of the item.1169 If you need to insert a new item into the list at a particular position, it 1170 is more required to construct the item without a parent widget and use the 1171 insertItem() function to place it within the list. The list widget will 1172 take ownership of the item. 1131 1173 1132 1174 \snippet doc/src/snippets/qlistwidget-using/mainwindow.cpp 6 1133 1175 \snippet doc/src/snippets/qlistwidget-using/mainwindow.cpp 7 1134 1176 1135 For multiple items, insertItems() can be used instead. The number of 1136 i tems in the list is found with the count() function.1137 To remove items from thelist, use takeItem().1177 For multiple items, insertItems() can be used instead. The number of items 1178 in the list is found with the count() function. To remove items from the 1179 list, use takeItem(). 1138 1180 1139 1181 The current item in the list can be found with currentItem(), and changed … … 1159 1201 \fn void QListWidget::addItem(QListWidgetItem *item) 1160 1202 1161 Inserts the \a item at the theend of the list widget.1162 1163 \warning A QListWidgetItem can only be added to a 1164 QListWidget once. Adding the same QListWidgetItem multiple1165 times to a QListWidget will result inundefined behavior.1203 Inserts the \a item at the end of the list widget. 1204 1205 \warning A QListWidgetItem can only be added to a QListWidget once. Adding 1206 the same QListWidgetItem multiple times to a QListWidget will result in 1207 undefined behavior. 1166 1208 1167 1209 \sa insertItem() … … 1171 1213 \fn void QListWidget::addItem(const QString &label) 1172 1214 1173 Inserts an item with the text \a label at the end of the list 1174 widget. 1215 Inserts an item with the text \a label at the end of the list widget. 1175 1216 */ 1176 1217 … … 1186 1227 \fn void QListWidget::itemPressed(QListWidgetItem *item) 1187 1228 1188 This signal is emitted with the specified \a item when a mouse button is pressed1189 on an item in the widget.1229 This signal is emitted with the specified \a item when a mouse button is 1230 pressed on an item in the widget. 1190 1231 1191 1232 \sa itemClicked(), itemDoubleClicked() … … 1195 1236 \fn void QListWidget::itemClicked(QListWidgetItem *item) 1196 1237 1197 This signal is emitted with the specified \a item when a mouse button is clicked1198 on an item in the widget.1238 This signal is emitted with the specified \a item when a mouse button is 1239 clicked on an item in the widget. 1199 1240 1200 1241 \sa itemPressed(), itemDoubleClicked() … … 1204 1245 \fn void QListWidget::itemDoubleClicked(QListWidgetItem *item) 1205 1246 1206 This signal is emitted with the specified \a item when a mouse button is double1207 clicked on an item in the widget.1247 This signal is emitted with the specified \a item when a mouse button is 1248 double clicked on an item in the widget. 1208 1249 1209 1250 \sa itemClicked(), itemPressed() … … 1213 1254 \fn void QListWidget::itemActivated(QListWidgetItem *item) 1214 1255 1215 This signal is emitted when the \a item is activated. The \a item 1216 is activated when the user clicks or double clicks on it,1217 depending on the system configuration. It is also activated when1218 the user presses the activation key (on Windows and X11 this is1219 the \gui Return key, on Mac OSX it is \key{Ctrl+0}).1256 This signal is emitted when the \a item is activated. The \a item is 1257 activated when the user clicks or double clicks on it, depending on the 1258 system configuration. It is also activated when the user presses the 1259 activation key (on Windows and X11 this is the \gui Return key, on Mac OS 1260 X it is \key{Ctrl+0}). 1220 1261 */ 1221 1262 … … 1223 1264 \fn void QListWidget::itemEntered(QListWidgetItem *item) 1224 1265 1225 This signal is emitted when the mouse cursor enters an item. The 1226 \a item is the item entered. This signal is only emitted when 1227 mouseTracking is turned on, or when a mouse button is pressed 1228 while moving into an item. 1266 This signal is emitted when the mouse cursor enters an item. The \a item is 1267 the item entered. This signal is only emitted when mouseTracking is turned 1268 on, or when a mouse button is pressed while moving into an item. 1269 1270 \sa QWidget::setMouseTracking() 1229 1271 */ 1230 1272 … … 1238 1280 \fn void QListWidget::currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous) 1239 1281 1240 This signal is emitted whenever the current item changes. The \a 1241 previous item is the item that previously had the focus, \a 1242 current is the new current item. 1243 */ 1244 1245 /*! 1246 \fn void QListWidget::currentTextChanged(const QString ¤tText) 1247 1248 This signal is emitted whenever the current item changes. The \a currentText 1249 is the text data in the current item. If there is no current item, the \a currentText 1250 is invalid. 1251 */ 1252 1253 /*! 1254 \fn void QListWidget::currentRowChanged(int currentRow) 1255 1256 This signal is emitted whenever the current item changes. The \a currentRow 1257 is the row of the current item. If there is no current item, the \a currentRow is -1. 1282 This signal is emitted whenever the current item changes. 1283 1284 \a previous is the item that previously had the focus; \a current is the 1285 new current item. 1286 */ 1287 1288 /*! 1289 \fn void QListWidget::currentTextChanged(const QString ¤tText) 1290 1291 This signal is emitted whenever the current item changes. 1292 1293 \a currentText is the text data in the current item. If there is no current 1294 item, the \a currentText is invalid. 1295 */ 1296 1297 /*! 1298 \fn void QListWidget::currentRowChanged(int currentRow) 1299 1300 This signal is emitted whenever the current item changes. 1301 1302 \a currentRow is the row of the current item. If there is no current item, 1303 the \a currentRow is -1. 1258 1304 */ 1259 1305 … … 1263 1309 This signal is emitted whenever the selection changes. 1264 1310 1265 \sa selectedItems() isItemSelected()currentItemChanged()1266 */ 1267 1268 /*! 1269 \since 4.31270 1271 \fn void QListWidget::removeItemWidget(QListWidgetItem *item)1272 1273 Removes the widget set on the given \a item.1311 \sa selectedItems(), QListWidgetItem::isSelected(), currentItemChanged() 1312 */ 1313 1314 /*! 1315 \since 4.3 1316 1317 \fn void QListWidget::removeItemWidget(QListWidgetItem *item) 1318 1319 Removes the widget set on the given \a item. 1274 1320 */ 1275 1321 … … 1303 1349 { 1304 1350 Q_D(const QListWidget); 1305 if (row < 0 || row >= d->model ()->rowCount())1351 if (row < 0 || row >= d->model->rowCount()) 1306 1352 return 0; 1307 return d-> model()->at(row);1353 return d->listModel()->at(row); 1308 1354 } 1309 1355 … … 1317 1363 { 1318 1364 Q_D(const QListWidget); 1319 return d-> model()->index(const_cast<QListWidgetItem*>(item)).row();1365 return d->listModel()->index(const_cast<QListWidgetItem*>(item)).row(); 1320 1366 } 1321 1367 … … 1331 1377 Q_D(QListWidget); 1332 1378 if (item && !item->view) 1333 d-> model()->insert(row, item);1334 } 1335 1336 /*! 1337 Inserts an item with the text \a label in the list widget at the 1338 positiongiven by \a row.1379 d->listModel()->insert(row, item); 1380 } 1381 1382 /*! 1383 Inserts an item with the text \a label in the list widget at the position 1384 given by \a row. 1339 1385 1340 1386 \sa addItem() … … 1344 1390 { 1345 1391 Q_D(QListWidget); 1346 d-> model()->insert(row, new QListWidgetItem(label));1392 d->listModel()->insert(row, new QListWidgetItem(label)); 1347 1393 } 1348 1394 … … 1357 1403 { 1358 1404 Q_D(QListWidget); 1359 d-> model()->insert(row, labels);1360 } 1361 1362 /*! 1363 Removes and returns the item from the given \a row in the list widget; otherwise1364 returns 0.1365 1366 Items removed from a list widget will not be managed by Qt, and will need to be1367 deleted manually.1405 d->listModel()->insert(row, labels); 1406 } 1407 1408 /*! 1409 Removes and returns the item from the given \a row in the list widget; 1410 otherwise returns 0. 1411 1412 Items removed from a list widget will not be managed by Qt, and will need 1413 to be deleted manually. 1368 1414 1369 1415 \sa insertItem(), addItem() … … 1373 1419 { 1374 1420 Q_D(QListWidget); 1375 if (row < 0 || row >= d->model ()->rowCount())1421 if (row < 0 || row >= d->model->rowCount()) 1376 1422 return 0; 1377 return d-> model()->take(row);1378 } 1379 1380 /*! 1381 \property QListWidget::count1382 \brief the number of items in the list including any hidden items.1423 return d->listModel()->take(row); 1424 } 1425 1426 /*! 1427 \property QListWidget::count 1428 \brief the number of items in the list including any hidden items. 1383 1429 */ 1384 1430 … … 1386 1432 { 1387 1433 Q_D(const QListWidget); 1388 return d->model ()->rowCount();1389 } 1390 1391 /*! 1392 Returns the current item.1434 return d->model->rowCount(); 1435 } 1436 1437 /*! 1438 Returns the current item. 1393 1439 */ 1394 1440 QListWidgetItem *QListWidget::currentItem() const 1395 1441 { 1396 1442 Q_D(const QListWidget); 1397 return d->model()->at(currentIndex().row()); 1398 } 1399 1400 1401 /*! 1402 Sets the current item to \a item. 1403 1404 Depending on the current selection mode, the item may also be selected. 1443 return d->listModel()->at(currentIndex().row()); 1444 } 1445 1446 1447 /*! 1448 Sets the current item to \a item. 1449 1450 Unless the selection mode is \l{QAbstractItemView::}{NoSelection}, 1451 the item is also be selected. 1405 1452 */ 1406 1453 void QListWidget::setCurrentItem(QListWidgetItem *item) … … 1410 1457 1411 1458 /*! 1412 \since 4.41413 Set the current item to \a item, using the given \a command.1459 \since 4.4 1460 Set the current item to \a item, using the given \a command. 1414 1461 */ 1415 1462 void QListWidget::setCurrentItem(QListWidgetItem *item, QItemSelectionModel::SelectionFlags command) … … 1419 1466 1420 1467 /*! 1421 \property QListWidget::currentRow1422 \brief the row of the current item.1423 1424 Depending on the current selection mode, the row may also be selected.1468 \property QListWidget::currentRow 1469 \brief the row of the current item. 1470 1471 Depending on the current selection mode, the row may also be selected. 1425 1472 */ 1426 1473 … … 1433 1480 { 1434 1481 Q_D(QListWidget); 1435 QModelIndex index = d-> model()->index(row);1482 QModelIndex index = d->listModel()->index(row); 1436 1483 if (d->selectionMode == SingleSelection) 1437 1484 selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect); … … 1443 1490 1444 1491 /*! 1445 \since 4.41446 1447 Sets the current row to be the given \a row, using the given \a command,1492 \since 4.4 1493 1494 Sets the current row to be the given \a row, using the given \a command, 1448 1495 */ 1449 1496 void QListWidget::setCurrentRow(int row, QItemSelectionModel::SelectionFlags command) 1450 1497 { 1451 1498 Q_D(QListWidget); 1452 d->selectionModel->setCurrentIndex(d-> model()->index(row), command);1499 d->selectionModel->setCurrentIndex(d->listModel()->index(row), command); 1453 1500 } 1454 1501 … … 1459 1506 { 1460 1507 Q_D(const QListWidget); 1461 return d-> model()->at(indexAt(p).row());1508 return d->listModel()->at(indexAt(p).row()); 1462 1509 1463 1510 } … … 1472 1519 1473 1520 /*! 1474 Returns the rectangle on the viewport occupied by the item at \a item.1521 Returns the rectangle on the viewport occupied by the item at \a item. 1475 1522 */ 1476 1523 QRect QListWidget::visualItemRect(const QListWidgetItem *item) const 1477 1524 { 1478 1525 Q_D(const QListWidget); 1479 QModelIndex index = d-> model()->index(const_cast<QListWidgetItem*>(item));1526 QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item)); 1480 1527 return visualRect(index); 1481 1528 } 1482 1529 1483 1530 /*! 1484 Sorts all the items in the list widget according to the specified \a order.1531 Sorts all the items in the list widget according to the specified \a order. 1485 1532 */ 1486 1533 void QListWidget::sortItems(Qt::SortOrder order) … … 1488 1535 Q_D(QListWidget); 1489 1536 d->sortOrder = order; 1490 d-> model()->sort(0, order);1537 d->listModel()->sort(0, order); 1491 1538 } 1492 1539 … … 1496 1543 \brief whether sorting is enabled 1497 1544 1498 If this property is true, sorting is enabled for the list; if the 1499 property is false, sorting is not enabled. The default value is false. 1545 If this property is true, sorting is enabled for the list; if the property 1546 is false, sorting is not enabled. 1547 1548 The default value is false. 1500 1549 */ 1501 1550 void QListWidget::setSortingEnabled(bool enable) … … 1512 1561 1513 1562 /*! 1514 \internal1563 \internal 1515 1564 */ 1516 1565 Qt::SortOrder QListWidget::sortOrder() const … … 1521 1570 1522 1571 /*! 1523 Starts editing the \a item if it is editable.1572 Starts editing the \a item if it is editable. 1524 1573 */ 1525 1574 … … 1527 1576 { 1528 1577 Q_D(QListWidget); 1529 edit(d->model()->index(item)); 1530 } 1531 1532 /*! 1533 Opens an editor for the given \a item. The editor remains open after editing. 1534 1535 \sa closePersistentEditor() 1578 edit(d->listModel()->index(item)); 1579 } 1580 1581 /*! 1582 Opens an editor for the given \a item. The editor remains open after 1583 editing. 1584 1585 \sa closePersistentEditor() 1536 1586 */ 1537 1587 void QListWidget::openPersistentEditor(QListWidgetItem *item) 1538 1588 { 1539 1589 Q_D(QListWidget); 1540 QModelIndex index = d-> model()->index(item);1590 QModelIndex index = d->listModel()->index(item); 1541 1591 QAbstractItemView::openPersistentEditor(index); 1542 1592 } 1543 1593 1544 1594 /*! 1545 Closes the persistent editor for the given \a item.1546 1547 \sa openPersistentEditor()1595 Closes the persistent editor for the given \a item. 1596 1597 \sa openPersistentEditor() 1548 1598 */ 1549 1599 void QListWidget::closePersistentEditor(QListWidgetItem *item) 1550 1600 { 1551 1601 Q_D(QListWidget); 1552 QModelIndex index = d-> model()->index(item);1602 QModelIndex index = d->listModel()->index(item); 1553 1603 QAbstractItemView::closePersistentEditor(index); 1554 1604 } … … 1562 1612 { 1563 1613 Q_D(const QListWidget); 1564 QModelIndex index = d-> model()->index(item);1614 QModelIndex index = d->listModel()->index(item); 1565 1615 return QAbstractItemView::indexWidget(index); 1566 1616 } … … 1571 1621 Sets the \a widget to be displayed in the give \a item. 1572 1622 1573 This function should only be used to display static content in the place of a list 1574 widget item. If you want to display custom dynamic content or implement a custom 1575 editor widget, use QListView and subclass QItemDelegate instead. 1623 This function should only be used to display static content in the place of 1624 a list widget item. If you want to display custom dynamic content or 1625 implement a custom editor widget, use QListView and subclass QItemDelegate 1626 instead. 1576 1627 1577 1628 \sa {Delegate Classes} … … 1580 1631 { 1581 1632 Q_D(QListWidget); 1582 QModelIndex index = d-> model()->index(item);1633 QModelIndex index = d->listModel()->index(item); 1583 1634 QAbstractItemView::setIndexWidget(index, widget); 1584 1635 } 1585 1636 1586 1637 /*! 1587 Returns true if \a item is selected; otherwise returns false.1588 1589 \obsolete1590 1591 This function is deprecated. Use \l{QListWidgetItem::isSelected()}instead.1638 Returns true if \a item is selected; otherwise returns false. 1639 1640 \obsolete 1641 1642 This function is deprecated. Use QListWidgetItem::isSelected() instead. 1592 1643 */ 1593 1644 bool QListWidget::isItemSelected(const QListWidgetItem *item) const 1594 1645 { 1595 1646 Q_D(const QListWidget); 1596 QModelIndex index = d-> model()->index(const_cast<QListWidgetItem*>(item));1647 QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item)); 1597 1648 return selectionModel()->isSelected(index); 1598 1649 } 1599 1650 1600 1651 /*! 1601 Selects or deselects the given \a item depending on whether \a select is1602 true of false.1603 1604 \obsolete1605 1606 This function is deprecated. Use \l{QListWidgetItem::setSelected()}instead.1652 Selects or deselects the given \a item depending on whether \a select is 1653 true of false. 1654 1655 \obsolete 1656 1657 This function is deprecated. Use QListWidgetItem::setSelected() instead. 1607 1658 */ 1608 1659 void QListWidget::setItemSelected(const QListWidgetItem *item, bool select) 1609 1660 { 1610 1661 Q_D(QListWidget); 1611 QModelIndex index = d-> model()->index(const_cast<QListWidgetItem*>(item));1662 QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item)); 1612 1663 1613 1664 if (d->selectionMode == SingleSelection) { … … 1624 1675 1625 1676 /*! 1626 Returns a list of all selected items in the list widget.1677 Returns a list of all selected items in the list widget. 1627 1678 */ 1628 1679 … … 1633 1684 QList<QListWidgetItem*> items; 1634 1685 for (int i = 0; i < indexes.count(); ++i) 1635 items.append(d-> model()->at(indexes.at(i).row()));1686 items.append(d->listModel()->at(indexes.at(i).row())); 1636 1687 return items; 1637 1688 } 1638 1689 1639 1690 /*! 1640 Finds items with the text that matches the string \a text using the given \a flags. 1691 Finds items with the text that matches the string \a text using the given 1692 \a flags. 1641 1693 */ 1642 1694 … … 1644 1696 { 1645 1697 Q_D(const QListWidget); 1646 QModelIndexList indexes = d-> model()->match(model()->index(0, 0, QModelIndex()),1698 QModelIndexList indexes = d->listModel()->match(model()->index(0, 0, QModelIndex()), 1647 1699 Qt::DisplayRole, text, -1, flags); 1648 1700 QList<QListWidgetItem*> items; 1649 1701 for (int i = 0; i < indexes.size(); ++i) 1650 items.append(d-> model()->at(indexes.at(i).row()));1702 items.append(d->listModel()->at(indexes.at(i).row())); 1651 1703 return items; 1652 1704 } 1653 1705 1654 1706 /*! 1655 Returns true if the \a item is explicitly hidden; otherwise returns false.1656 1657 \obsolete1658 1659 This function is deprecated. Use \l{QListWidgetItem::isHidden()}instead.1707 Returns true if the \a item is explicitly hidden; otherwise returns false. 1708 1709 \obsolete 1710 1711 This function is deprecated. Use QListWidgetItem::isHidden() instead. 1660 1712 */ 1661 1713 bool QListWidget::isItemHidden(const QListWidgetItem *item) const … … 1665 1717 1666 1718 /*! 1667 If \a hide is true, the \a item will be hidden; otherwise it will be shown.1668 1669 \obsolete1670 1671 This function is deprecated. Use \l{QListWidgetItem::setHidden()}instead.1719 If \a hide is true, the \a item will be hidden; otherwise it will be shown. 1720 1721 \obsolete 1722 1723 This function is deprecated. Use QListWidgetItem::setHidden() instead. 1672 1724 */ 1673 1725 void QListWidget::setItemHidden(const QListWidgetItem *item, bool hide) … … 1677 1729 1678 1730 /*! 1679 Scrolls the view if necessary to ensure that the \a item is 1680 visible. The \a hint parameter specifies more precisely where the 1681 \a item should be located after the operation.1731 Scrolls the view if necessary to ensure that the \a item is visible. 1732 1733 \a hint specifies where the \a item should be located after the operation. 1682 1734 */ 1683 1735 … … 1685 1737 { 1686 1738 Q_D(QListWidget); 1687 QModelIndex index = d-> model()->index(const_cast<QListWidgetItem*>(item));1739 QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item)); 1688 1740 QListView::scrollTo(index, hint); 1689 1741 } … … 1692 1744 Removes all items and selections in the view. 1693 1745 1694 \ noteAll items will be permanently deleted.1746 \warning All items will be permanently deleted. 1695 1747 */ 1696 1748 void QListWidget::clear() … … 1698 1750 Q_D(QListWidget); 1699 1751 selectionModel()->clear(); 1700 d-> model()->clear();1752 d->listModel()->clear(); 1701 1753 } 1702 1754 … … 1709 1761 QStringList QListWidget::mimeTypes() const 1710 1762 { 1711 return d_func()-> model()->QAbstractListModel::mimeTypes();1763 return d_func()->listModel()->QAbstractListModel::mimeTypes(); 1712 1764 } 1713 1765 … … 1717 1769 mimeTypes() function. 1718 1770 1719 If the list of items is empty, 0 is returned rather than a serialized1720 emptylist.1771 If the list of items is empty, 0 is returned instead of a serialized empty 1772 list. 1721 1773 */ 1722 1774 QMimeData *QListWidget::mimeData(const QList<QListWidgetItem*>) const 1723 1775 { 1724 return d_func()-> model()->internalMimeData();1776 return d_func()->listModel()->internalMimeData(); 1725 1777 } 1726 1778 1727 1779 #ifndef QT_NO_DRAGANDDROP 1728 1780 /*! 1729 Handles the \a data supplied by an external drag and drop operation 1730 that ended with the given \a action in the given \a index. 1731 Returns true if the data and action can be handled by the model; 1732 otherwise returns false. 1781 Handles \a data supplied by an external drag and drop operation that ended 1782 with the given \a action in the given \a index. Returns true if \a data and 1783 \a action can be handled by the model; otherwise returns false. 1733 1784 1734 1785 \sa supportedDropActions() … … 1745 1796 column = -1; 1746 1797 } 1747 return d_func()-> model()->QAbstractListModel::dropMimeData(data, action , row, column, idx);1798 return d_func()->listModel()->QAbstractListModel::dropMimeData(data, action , row, column, idx); 1748 1799 } 1749 1800 … … 1769 1820 if (persIndexes.contains(topIndex)) 1770 1821 return; 1822 qSort(persIndexes); // The dropped items will remain in the same visual order. 1771 1823 1772 1824 QPersistentModelIndex dropRow = model()->index(row, col, topIndex); 1773 1825 1774 QList<QListWidgetItem *> taken; 1775 for (int i = 0; i < persIndexes.count(); ++i) 1776 taken.append(takeItem(persIndexes.at(i).row())); 1777 1778 // insert them back in at their new positions 1826 int r = row == -1 ? count() : (dropRow.row() >= 0 ? dropRow.row() : row); 1779 1827 for (int i = 0; i < persIndexes.count(); ++i) { 1780 // Either at a specific point or appended 1781 if (row == -1) { 1782 insertItem(count(), taken.takeFirst()); 1783 } else { 1784 int r = dropRow.row() >= 0 ? dropRow.row() : row; 1785 insertItem(qMin(r, count()), taken.takeFirst()); 1786 } 1828 const QPersistentModelIndex &pIndex = persIndexes.at(i); 1829 d->listModel()->move(pIndex.row(), r); 1830 r = pIndex.row() + 1; // Dropped items are inserted contiguously and in the right order. 1787 1831 } 1788 1832 … … 1797 1841 1798 1842 /*! 1799 Returns the drop actions supported by this view.1800 1801 \sa Qt::DropActions1843 Returns the drop actions supported by this view. 1844 1845 \sa Qt::DropActions 1802 1846 */ 1803 1847 Qt::DropActions QListWidget::supportedDropActions() const 1804 1848 { 1805 1849 Q_D(const QListWidget); 1806 return d-> model()->QAbstractListModel::supportedDropActions() | Qt::MoveAction;1850 return d->listModel()->QAbstractListModel::supportedDropActions() | Qt::MoveAction; 1807 1851 } 1808 1852 #endif // QT_NO_DRAGANDDROP 1809 1853 1810 1854 /*! 1811 Returns a list of pointers to the items contained in the \a data object.1812 Ifthe object was not created by a QListWidget in the same process, the list1813 is empty.1855 Returns a list of pointers to the items contained in the \a data object. If 1856 the object was not created by a QListWidget in the same process, the list 1857 is empty. 1814 1858 */ 1815 1859 QList<QListWidgetItem*> QListWidget::items(const QMimeData *data) const … … 1822 1866 1823 1867 /*! 1824 Returns the QModelIndex assocated with the given \a item.1868 Returns the QModelIndex assocated with the given \a item. 1825 1869 */ 1826 1870 … … 1828 1872 { 1829 1873 Q_D(const QListWidget); 1830 return d-> model()->index(item);1831 } 1832 1833 /*! 1834 Returns a pointer to the QListWidgetItem assocated with the given \a index.1874 return d->listModel()->index(item); 1875 } 1876 1877 /*! 1878 Returns a pointer to the QListWidgetItem assocated with the given \a index. 1835 1879 */ 1836 1880 … … 1839 1883 Q_D(const QListWidget); 1840 1884 if (d->isIndexValid(index)) 1841 return d-> model()->at(index.row());1885 return d->listModel()->at(index.row()); 1842 1886 return 0; 1843 1887 } 1844 1888 1845 1889 /*! 1846 \internal1890 \internal 1847 1891 */ 1848 1892 void QListWidget::setModel(QAbstractItemModel * /*model*/) -
trunk/src/gui/itemviews/qlistwidget.h
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 ** -
trunk/src/gui/itemviews/qlistwidget_p.h
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 ** … … 78 78 }; 79 79 80 class Q ListModel : public QAbstractListModel80 class Q_AUTOTEST_EXPORT QListModel : public QAbstractListModel 81 81 { 82 82 Q_OBJECT … … 91 91 void remove(QListWidgetItem *item); 92 92 QListWidgetItem *take(int row); 93 void move(int srcRow, int dstRow); 93 94 94 95 int rowCount(const QModelIndex &parent = QModelIndex()) const; … … 144 145 public: 145 146 QListWidgetPrivate() : QListViewPrivate(), sortOrder(Qt::AscendingOrder), sortingEnabled(false) {} 146 inline QListModel * model() const { return qobject_cast<QListModel*>(q_func()->model()); }147 inline QListModel *listModel() const { return qobject_cast<QListModel*>(model); } 147 148 void setup(); 148 149 void _q_emitItemPressed(const QModelIndex &index); … … 164 165 QListWidgetItemPrivate(QListWidgetItem *item) : q(item), theid(-1) {} 165 166 QListWidgetItem *q; 166 int id;167 167 QVector<QWidgetItemData> values; 168 168 int theid; -
trunk/src/gui/itemviews/qproxymodel.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 ** -
trunk/src/gui/itemviews/qproxymodel.h
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 ** -
trunk/src/gui/itemviews/qproxymodel_p.h
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 ** -
trunk/src/gui/itemviews/qsortfilterproxymodel.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 ** … … 56 56 57 57 typedef QList<QPair<QModelIndex, QPersistentModelIndex> > QModelIndexPairList; 58 59 static inline QSet<int> qVectorToSet(const QVector<int> &vector) 60 { 61 QSet<int> set; 62 set.reserve(vector.size()); 63 for(int i=0; i < vector.size(); ++i) 64 set << vector.at(i); 65 return set; 66 } 58 67 59 68 class QSortFilterProxyModelLessThan … … 138 147 QModelIndex proxy_to_source(const QModelIndex &proxyIndex) const; 139 148 QModelIndex source_to_proxy(const QModelIndex &sourceIndex) const; 149 bool can_create_mapping(const QModelIndex &source_parent) const; 140 150 141 151 void remove_from_mapping(const QModelIndex &source_parent); … … 145 155 { 146 156 Q_ASSERT(proxy_index.isValid()); 157 Q_ASSERT(proxy_index.model() == q_func()); 147 158 const void *p = proxy_index.internalPointer(); 148 159 Q_ASSERT(p); … … 164 175 void _q_sourceHeaderDataChanged(Qt::Orientation orientation, int start, int end); 165 176 177 void _q_sourceAboutToBeReset(); 166 178 void _q_sourceReset(); 167 179 … … 224 236 void update_persistent_indexes(const QModelIndexPairList &source_indexes); 225 237 226 void filter_changed( );227 voidhandle_filter_changed(238 void filter_changed(const QModelIndex &source_parent = QModelIndex()); 239 QSet<int> handle_filter_changed( 228 240 QVector<int> &source_to_proxy, QVector<int> &proxy_to_source, 229 241 const QModelIndex &source_parent, Qt::Orientation orient); … … 312 324 if (!proxy_index.isValid()) 313 325 return QModelIndex(); // for now; we may want to be able to set a root index later 326 if (proxy_index.model() != q_func()) { 327 qWarning() << "QSortFilterProxyModel: index from wrong model passed to mapToSource"; 328 return QModelIndex(); 329 } 314 330 IndexMap::const_iterator it = index_to_iterator(proxy_index); 315 331 Mapping *m = it.value(); … … 325 341 if (!source_index.isValid()) 326 342 return QModelIndex(); // for now; we may want to be able to set a root index later 343 if (source_index.model() != model) { 344 qWarning() << "QSortFilterProxyModel: index from wrong model passed to mapFromSource"; 345 return QModelIndex(); 346 } 327 347 QModelIndex source_parent = source_index.parent(); 328 348 IndexMap::const_iterator it = create_mapping(source_parent); … … 335 355 return QModelIndex(); 336 356 return create_index(proxy_row, proxy_column, it); 357 } 358 359 bool QSortFilterProxyModelPrivate::can_create_mapping(const QModelIndex &source_parent) const 360 { 361 if (source_parent.isValid()) { 362 QModelIndex source_grand_parent = source_parent.parent(); 363 IndexMap::const_iterator it = source_index_mapping.constFind(source_grand_parent); 364 if (it == source_index_mapping.constEnd()) { 365 // Don't care, since we don't have mapping for the grand parent 366 return false; 367 } 368 Mapping *gm = it.value(); 369 if (gm->proxy_rows.at(source_parent.row()) == -1 || 370 gm->proxy_columns.at(source_parent.column()) == -1) { 371 // Don't care, since parent is filtered 372 return false; 373 } 374 } 375 return true; 337 376 } 338 377 … … 642 681 IndexMap::const_iterator it = source_index_mapping.constFind(source_parent); 643 682 if (it == source_index_mapping.constEnd()) { 644 if (source_parent.isValid()) { 645 QModelIndex source_grand_parent = source_parent.parent(); 646 it = source_index_mapping.constFind(source_grand_parent); 647 if (it == source_index_mapping.constEnd()) { 648 // Don't care, since we don't have mapping for the grand parent 649 return; 650 } 651 Mapping *gm = it.value(); 652 if (gm->proxy_rows.at(source_parent.row()) == -1 || 653 gm->proxy_columns.at(source_parent.column()) == -1) { 654 // Don't care, since parent is filtered 655 return; 656 } 657 } 683 if (!can_create_mapping(source_parent)) 684 return; 658 685 it = create_mapping(source_parent); 659 686 Mapping *m = it.value(); … … 705 732 : q->filterAcceptsColumn(i, source_parent)) { 706 733 source_items.append(i); 734 } 735 } 736 737 if (model->rowCount(source_parent) == delta_item_count) { 738 // Items were inserted where there were none before. 739 // If it was new rows make sure to create mappings for columns so that a 740 // valid mapping can be retreived later and vice-versa. 741 742 QVector<int> &orthogonal_proxy_to_source = (orient == Qt::Horizontal) ? m->source_rows : m->source_columns; 743 QVector<int> &orthogonal_source_to_proxy = (orient == Qt::Horizontal) ? m->proxy_rows : m->proxy_columns; 744 745 if (orthogonal_source_to_proxy.isEmpty()) { 746 const int ortho_end = (orient == Qt::Horizontal) ? model->rowCount(source_parent) : model->columnCount(source_parent); 747 748 for (int ortho_item = 0; ortho_item < ortho_end; ++ortho_item) { 749 if ((orient == Qt::Horizontal) ? q->filterAcceptsRow(ortho_item, source_parent) 750 : q->filterAcceptsColumn(ortho_item, source_parent)) { 751 orthogonal_proxy_to_source.append(ortho_item); 752 } 753 } 754 orthogonal_source_to_proxy.resize(orthogonal_proxy_to_source.size()); 755 756 if (orient == Qt::Horizontal) { 757 // We're reacting to columnsInserted, but we've just inserted new rows. Sort them. 758 sort_source_rows(orthogonal_proxy_to_source, source_parent); 759 } 760 build_source_to_proxy_mapping(orthogonal_proxy_to_source, orthogonal_source_to_proxy); 707 761 } 708 762 } … … 867 921 proxy_low = INT_MAX; 868 922 proxy_high = INT_MIN; 869 for each (int source_item, source_items) {870 int proxy_item = source_to_proxy.at(source_item );923 for (int i = 0; i < source_items.count(); ++i) { 924 int proxy_item = source_to_proxy.at(source_items.at(i)); 871 925 Q_ASSERT(proxy_item != -1); 872 926 if (proxy_item < proxy_low) … … 929 983 } 930 984 985 931 986 /*! 932 987 \internal … … 935 990 new filter. 936 991 */ 937 void QSortFilterProxyModelPrivate::filter_changed() 938 { 939 QMap<QModelIndex, Mapping *>::const_iterator it; 940 for (it = source_index_mapping.constBegin(); it != source_index_mapping.constEnd(); ++it) { 941 QModelIndex source_parent = it.key(); 942 Mapping *m = it.value(); 943 handle_filter_changed(m->proxy_rows, m->source_rows, source_parent, Qt::Vertical); 944 handle_filter_changed(m->proxy_columns, m->source_columns, source_parent, Qt::Horizontal); 992 void QSortFilterProxyModelPrivate::filter_changed(const QModelIndex &source_parent) 993 { 994 IndexMap::const_iterator it = source_index_mapping.constFind(source_parent); 995 if (it == source_index_mapping.constEnd()) 996 return; 997 Mapping *m = it.value(); 998 QSet<int> rows_removed = handle_filter_changed(m->proxy_rows, m->source_rows, source_parent, Qt::Vertical); 999 QSet<int> columns_removed = handle_filter_changed(m->proxy_columns, m->source_columns, source_parent, Qt::Horizontal); 1000 QVector<QModelIndex>::iterator it2 = m->mapped_children.end(); 1001 while (it2 != m->mapped_children.begin()) { 1002 --it2; 1003 const QModelIndex source_child_index = *it2; 1004 if (rows_removed.contains(source_child_index.row()) || columns_removed.contains(source_child_index.column())) { 1005 it2 = m->mapped_children.erase(it2); 1006 remove_from_mapping(source_child_index); 1007 } else { 1008 filter_changed(source_child_index); 1009 } 945 1010 } 946 1011 } … … 948 1013 /*! 949 1014 \internal 950 */ 951 void QSortFilterProxyModelPrivate::handle_filter_changed( 1015 returns the removed items indexes 1016 */ 1017 QSet<int> QSortFilterProxyModelPrivate::handle_filter_changed( 952 1018 QVector<int> &source_to_proxy, QVector<int> &proxy_to_source, 953 1019 const QModelIndex &source_parent, Qt::Orientation orient) … … 956 1022 // Figure out which mapped items to remove 957 1023 QVector<int> source_items_remove; 958 foreach (int source_item, proxy_to_source) { 1024 for (int i = 0; i < proxy_to_source.count(); ++i) { 1025 const int source_item = proxy_to_source.at(i); 959 1026 if ((orient == Qt::Vertical) 960 1027 ? !q->filterAcceptsRow(source_item, source_parent) … … 986 1053 source_items_insert, source_parent, orient); 987 1054 } 1055 return qVectorToSet(source_items_remove); 988 1056 } 989 1057 … … 1033 1101 } 1034 1102 1035 if (!source_rows_remove.isEmpty()) 1103 if (!source_rows_remove.isEmpty()) { 1036 1104 remove_source_items(m->proxy_rows, m->source_rows, 1037 1105 source_rows_remove, source_parent, Qt::Vertical); 1106 QSet<int> source_rows_remove_set = qVectorToSet(source_rows_remove); 1107 QVector<QModelIndex>::iterator it = m->mapped_children.end(); 1108 while (it != m->mapped_children.begin()) { 1109 --it; 1110 const QModelIndex source_child_index = *it; 1111 if (source_rows_remove_set.contains(source_child_index.row())) { 1112 it = m->mapped_children.erase(it); 1113 remove_from_mapping(source_child_index); 1114 } 1115 } 1116 } 1038 1117 1039 1118 if (!source_rows_resort.isEmpty()) { … … 1098 1177 } 1099 1178 1179 void QSortFilterProxyModelPrivate::_q_sourceAboutToBeReset() 1180 { 1181 Q_Q(QSortFilterProxyModel); 1182 q->beginResetModel(); 1183 invalidatePersistentIndexes(); 1184 clear_mapping(); 1185 } 1186 1100 1187 void QSortFilterProxyModelPrivate::_q_sourceReset() 1101 1188 { 1102 1189 Q_Q(QSortFilterProxyModel); 1103 1190 // All internal structures are deleted in clear() 1104 q-> reset();1191 q->endResetModel(); 1105 1192 update_source_sort_column(); 1106 1193 if (dynamic_sortfilter) … … 1112 1199 Q_Q(QSortFilterProxyModel); 1113 1200 saved_persistent_indexes.clear(); 1201 emit q->layoutAboutToBeChanged(); 1114 1202 if (persistent.indexes.isEmpty()) 1115 1203 return; 1116 emit q->layoutAboutToBeChanged(); 1204 1117 1205 saved_persistent_indexes = store_persistent_indexes(); 1118 1206 } … … 1122 1210 Q_Q(QSortFilterProxyModel); 1123 1211 if (saved_persistent_indexes.isEmpty()) { 1124 q->invalidate(); 1212 clear_mapping(); 1213 emit q->layoutChanged(); 1125 1214 return; 1126 1215 } … … 1144 1233 //Force the creation of a mapping now, even if its empty. 1145 1234 //We need it because the proxy can be acessed at the moment it emits rowsAboutToBeInserted in insert_source_items 1146 create_mapping(source_parent); 1235 if (can_create_mapping(source_parent)) 1236 create_mapping(source_parent); 1147 1237 } 1148 1238 … … 1175 1265 //Force the creation of a mapping now, even if its empty. 1176 1266 //We need it because the proxy can be acessed at the moment it emits columnsAboutToBeInserted in insert_source_items 1177 create_mapping(source_parent); 1267 if (can_create_mapping(source_parent)) 1268 create_mapping(source_parent); 1178 1269 } 1179 1270 … … 1226 1317 \since 4.1 1227 1318 \class QSortFilterProxyModel 1228 \brief The QSortFilterProxyModel class provides support for sorting and filtering data passed1229 between another model and a view.1319 \brief The QSortFilterProxyModel class provides support for sorting and 1320 filtering data passed between another model and a view. 1230 1321 1231 1322 \ingroup model-view 1232 1323 1233 QSortFilterProxyModel can be used for sorting items, filtering 1234 out items, or both. The model transforms the structure of a 1235 source model by mapping the model indexes it supplies to new 1236 indexes, corresponding to different locations, for views to use. 1237 This approach allows a given source model to be restructured as 1238 far as views are concerned without requiring any transformations 1239 on the underlying data, and without duplicating the data in 1324 QSortFilterProxyModel can be used for sorting items, filtering out items, 1325 or both. The model transforms the structure of a source model by mapping 1326 the model indexes it supplies to new indexes, corresponding to different 1327 locations, for views to use. This approach allows a given source model to 1328 be restructured as far as views are concerned without requiring any 1329 transformations on the underlying data, and without duplicating the data in 1240 1330 memory. 1241 1331 1242 Let's assume that we want to sort and filter the items provided 1243 by a custom model. The code to set up the model and the view, \e1244 without sorting andfiltering, would look like this:1332 Let's assume that we want to sort and filter the items provided by a custom 1333 model. The code to set up the model and the view, \e without sorting and 1334 filtering, would look like this: 1245 1335 1246 1336 \snippet doc/src/snippets/qsortfilterproxymodel-details/main.cpp 1 1247 1337 1248 To add sorting and filtering support to \c MyItemModel, we need 1249 to create a QSortFilterProxyModel, call setSourceModel() with the 1250 \c MyItemModel as argument, and install the QSortFilterProxyModel 1251 on the view: 1338 To add sorting and filtering support to \c MyItemModel, we need to create 1339 a QSortFilterProxyModel, call setSourceModel() with the \c MyItemModel as 1340 argument, and install the QSortFilterProxyModel on the view: 1252 1341 1253 1342 \snippet doc/src/snippets/qsortfilterproxymodel-details/main.cpp 0 1254 1343 \snippet doc/src/snippets/qsortfilterproxymodel-details/main.cpp 2 1255 1344 1256 At this point, neither sorting nor filtering is enabled; the 1257 original data is displayed in the view. Any changes made through 1258 the QSortFilterProxyModel are applied to the original model. 1259 1260 The QSortFilterProxyModel acts as a wrapper for the original 1261 model. If you need to convert source \l{QModelIndex}es to 1262 sorted/filtered model indexes or vice versa, use mapToSource(), 1263 mapFromSource(), mapSelectionToSource(), and 1264 mapSelectionFromSource(). 1265 1266 \note By default, the model does not dynamically re-sort and re-filter 1267 data whenever the original model changes. This behavior can be 1268 changed by setting the \l{QSortFilterProxyModel::dynamicSortFilter} 1269 {dynamicSortFilter} property. 1270 1271 The \l{itemviews/basicsortfiltermodel}{Basic Sort/Filter Model} 1272 and \l{itemviews/customsortfiltermodel}{Custom Sort/Filter Model} 1273 examples illustrate how to use QSortFilterProxyModel to perform 1274 basic sorting and filtering and how to subclass it to implement 1275 custom behavior. 1345 At this point, neither sorting nor filtering is enabled; the original data 1346 is displayed in the view. Any changes made through the 1347 QSortFilterProxyModel are applied to the original model. 1348 1349 The QSortFilterProxyModel acts as a wrapper for the original model. If you 1350 need to convert source \l{QModelIndex}es to sorted/filtered model indexes 1351 or vice versa, use mapToSource(), mapFromSource(), mapSelectionToSource(), 1352 and mapSelectionFromSource(). 1353 1354 \note By default, the model does not dynamically re-sort and re-filter data 1355 whenever the original model changes. This behavior can be changed by 1356 setting the \l{QSortFilterProxyModel::dynamicSortFilter}{dynamicSortFilter} 1357 property. 1358 1359 The \l{itemviews/basicsortfiltermodel}{Basic Sort/Filter Model} and 1360 \l{itemviews/customsortfiltermodel}{Custom Sort/Filter Model} examples 1361 illustrate how to use QSortFilterProxyModel to perform basic sorting and 1362 filtering and how to subclass it to implement custom behavior. 1276 1363 1277 1364 \section1 Sorting 1278 1365 1279 1366 QTableView and QTreeView have a 1280 \l{QTreeView::sortingEnabled}{sortingEnabled} property that 1281 controls whether the user can sort the view by clicking the1282 view's horizontalheader. For example:1367 \l{QTreeView::sortingEnabled}{sortingEnabled} property that controls 1368 whether the user can sort the view by clicking the view's horizontal 1369 header. For example: 1283 1370 1284 1371 \snippet doc/src/snippets/qsortfilterproxymodel-details/main.cpp 3 1285 1372 1286 When this feature is on (the default is off), clicking on a 1287 header section sorts the items according to that column. By 1288 clicking repeatedly, the user can alternate between ascending and 1289 descending order. 1373 When this feature is on (the default is off), clicking on a header section 1374 sorts the items according to that column. By clicking repeatedly, the user 1375 can alternate between ascending and descending order. 1290 1376 1291 1377 \image qsortfilterproxymodel-sorting.png A sorted QTreeView 1292 1378 1293 Behind the scene, the view calls the sort() virtual function on 1294 the model to reorder the data in the model. To make your data 1295 sortable, you can either implement sort() in your model, or you 1296 use a QSortFilterProxyModel to wrap your model -- 1297 QSortFilterProxyModel provides a generic sort() reimplementation 1298 that operates on the sortRole() (Qt::DisplayRole by default) of 1299 the items and that understands several data types, including \c 1300 int, QString, and QDateTime. For hierarchical models, sorting is 1301 applied recursively to all child items. String comparisons are 1302 case sensitive by default; this can be changed by setting the 1303 \l{QSortFilterProxyModel::}{sortCaseSensitivity} property. 1379 Behind the scene, the view calls the sort() virtual function on the model 1380 to reorder the data in the model. To make your data sortable, you can 1381 either implement sort() in your model, or use a QSortFilterProxyModel to 1382 wrap your model -- QSortFilterProxyModel provides a generic sort() 1383 reimplementation that operates on the sortRole() (Qt::DisplayRole by 1384 default) of the items and that understands several data types, including 1385 \c int, QString, and QDateTime. For hierarchical models, sorting is applied 1386 recursively to all child items. String comparisons are case sensitive by 1387 default; this can be changed by setting the \l{QSortFilterProxyModel::} 1388 {sortCaseSensitivity} property. 1304 1389 1305 1390 Custom sorting behavior is achieved by subclassing … … 1313 1398 example.) 1314 1399 1315 An alternative approach to sorting is to disable sorting on the 1316 view and to impose a certain order to the user. This is done by1317 explicitly calling sort() with the desired column and order as1318 arguments on the QSortFilterProxyModel (or on the original model1319 if it implements sort()).For example:1400 An alternative approach to sorting is to disable sorting on the view and to 1401 impose a certain order to the user. This is done by explicitly calling 1402 sort() with the desired column and order as arguments on the 1403 QSortFilterProxyModel (or on the original model if it implements sort()). 1404 For example: 1320 1405 1321 1406 \snippet doc/src/snippets/qsortfilterproxymodel-details/main.cpp 4 1322 1407 1323 QSortFilterProxyModel can be sorted by column -1, in which case it 1324 returnsto the sort order of the underlying source model.1408 QSortFilterProxyModel can be sorted by column -1, in which case it returns 1409 to the sort order of the underlying source model. 1325 1410 1326 1411 \section1 Filtering 1327 1412 1328 In addition to sorting, QSortFilterProxyModel can be used to hide 1329 items that don't match a certain filter. The filter is specified 1330 using a QRegExp object and is applied to the filterRole() 1331 (Qt::DisplayRole by default) of each item, for a given column. 1332 The QRegExp object can be used to match a regular expression, a 1333 wildcard pattern, or a fixed string. For example: 1413 In addition to sorting, QSortFilterProxyModel can be used to hide items 1414 that do not match a certain filter. The filter is specified using a QRegExp 1415 object and is applied to the filterRole() (Qt::DisplayRole by default) of 1416 each item, for a given column. The QRegExp object can be used to match a 1417 regular expression, a wildcard pattern, or a fixed string. For example: 1334 1418 1335 1419 \snippet doc/src/snippets/qsortfilterproxymodel-details/main.cpp 5 1336 1420 1337 For hierarchical models, the filter is applied recursively to all 1338 children. If a parent item doesn't match the filter, none of its 1339 children will be shown. 1340 1341 A common use case is to let the user specify the filter regexp, 1342 wildcard pattern, or fixed string in a QLineEdit and to connect 1343 the \l{QLineEdit::textChanged()}{textChanged()} signal to 1344 setFilterRegExp(), setFilterWildcard(), or setFilterFixedString() 1345 to reapply the filter. 1421 For hierarchical models, the filter is applied recursively to all children. 1422 If a parent item doesn't match the filter, none of its children will be 1423 shown. 1424 1425 A common use case is to let the user specify the filter regexp, wildcard 1426 pattern, or fixed string in a QLineEdit and to connect the 1427 \l{QLineEdit::textChanged()}{textChanged()} signal to setFilterRegExp(), 1428 setFilterWildcard(), or setFilterFixedString() to reapply the filter. 1346 1429 1347 1430 Custom filtering behavior can be achieved by reimplementing the 1348 1431 filterAcceptsRow() and filterAcceptsColumn() functions. For 1349 example, the following implementation ignores the 1350 \l{QSortFilterProxyModel::filterKeyColumn}{filterKeyColumn} 1351 property and performs filtering on columns 0, 1, and 2: 1432 example (from the \l{itemviews/customsortfiltermodel} 1433 {Custom Sort/Filter Model} example), the following implementation ignores 1434 the \l{QSortFilterProxyModel::filterKeyColumn}{filterKeyColumn} property 1435 and performs filtering on columns 0, 1, and 2: 1352 1436 1353 1437 \snippet examples/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp 3 … … 1359 1443 If you are working with large amounts of filtering and have to invoke 1360 1444 invalidateFilter() repeatedly, using reset() may be more efficient, 1361 depending on the implementation of your model. However, note that reset()1362 returns the proxy model to its original state, losing selection1363 information, and willcause the proxy model to be repopulated.1445 depending on the implementation of your model. However, reset() returns the 1446 proxy model to its original state, losing selection information, and will 1447 cause the proxy model to be repopulated. 1364 1448 1365 1449 \section1 Subclassing 1366 1450 1367 \bold{Note:} Some general guidelines for subclassing models are1368 available in the \l{Model Subclassing Reference}.1369 1370 1451 Since QAbstractProxyModel and its subclasses are derived from 1371 QAbstractItemModel, much of the same advice about subclassing normal 1372 models also applies to proxy models. In addition, it is worth noting 1373 that many of the default implementations of functions in this class 1374 are written so that they call the equivalent functions in the relevant 1375 source model. This simple proxying mechanism may need to be overridden 1376 for source models with more complex behavior; for example, if the 1377 source model provides a custom hasChildren() implementation, you 1378 should also provide one in the proxy model. 1452 QAbstractItemModel, much of the same advice about subclassing normal models 1453 also applies to proxy models. In addition, it is worth noting that many of 1454 the default implementations of functions in this class are written so that 1455 they call the equivalent functions in the relevant source model. This 1456 simple proxying mechanism may need to be overridden for source models with 1457 more complex behavior; for example, if the source model provides a custom 1458 hasChildren() implementation, you should also provide one in the proxy 1459 model. 1460 1461 \note Some general guidelines for subclassing models are available in the 1462 \l{Model Subclassing Reference}. 1379 1463 1380 1464 \sa QAbstractProxyModel, QAbstractItemModel, {Model/View Programming}, … … 1418 1502 Q_D(QSortFilterProxyModel); 1419 1503 1504 beginResetModel(); 1505 1420 1506 disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), 1421 1507 this, SLOT(_q_sourceDataChanged(QModelIndex,QModelIndex))); … … 1454 1540 this, SLOT(_q_sourceLayoutChanged())); 1455 1541 1542 disconnect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_sourceAboutToBeReset())); 1456 1543 disconnect(d->model, SIGNAL(modelReset()), this, SLOT(_q_sourceReset())); 1457 1544 … … 1494 1581 this, SLOT(_q_sourceLayoutChanged())); 1495 1582 1583 connect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_sourceAboutToBeReset())); 1496 1584 connect(d->model, SIGNAL(modelReset()), this, SLOT(_q_sourceReset())); 1497 1585 1498 1586 d->clear_mapping(); 1499 reset(); 1500 d->update_source_sort_column(); 1587 endResetModel(); 1588 if (d->update_source_sort_column() && d->dynamic_sortfilter) 1589 d->sort(); 1501 1590 } 1502 1591 … … 1938 2027 1939 2028 Setting this property overwrites the current 1940 \l{QSortFilterProxyModel::filterCaseSensitivity} 1941 {filterCaseSensitivity}. By default, the QRegExp is an empty 1942 string matching all contents. 2029 \l{QSortFilterProxyModel::filterCaseSensitivity}{filterCaseSensitivity}. 2030 By default, the QRegExp is an empty string matching all contents. 2031 2032 If no QRegExp or an empty string is set, everything in the source model 2033 will be accepted. 1943 2034 1944 2035 \sa filterCaseSensitivity, setFilterWildcard(), setFilterFixedString() … … 2263 2354 QVariant l = (left.model() ? left.model()->data(left, d->sort_role) : QVariant()); 2264 2355 QVariant r = (right.model() ? right.model()->data(right, d->sort_role) : QVariant()); 2265 switch (l. type()) {2356 switch (l.userType()) { 2266 2357 case QVariant::Invalid: 2267 2358 return (r.type() == QVariant::Invalid); … … 2274 2365 case QVariant::ULongLong: 2275 2366 return l.toULongLong() < r.toULongLong(); 2367 case QMetaType::Float: 2368 return l.toFloat() < r.toFloat(); 2276 2369 case QVariant::Double: 2277 2370 return l.toDouble() < r.toDouble(); -
trunk/src/gui/itemviews/qsortfilterproxymodel.h
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 ** … … 178 178 Q_PRIVATE_SLOT(d_func(), void _q_sourceDataChanged(const QModelIndex &source_top_left, const QModelIndex &source_bottom_right)) 179 179 Q_PRIVATE_SLOT(d_func(), void _q_sourceHeaderDataChanged(Qt::Orientation orientation, int start, int end)) 180 Q_PRIVATE_SLOT(d_func(), void _q_sourceAboutToBeReset()) 180 181 Q_PRIVATE_SLOT(d_func(), void _q_sourceReset()) 181 182 Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutAboutToBeChanged()) -
trunk/src/gui/itemviews/qstandarditemmodel.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 ** … … 330 330 QStandardItemModelPrivate::~QStandardItemModelPrivate() 331 331 { 332 delete root;333 332 delete itemPrototype; 334 333 qDeleteAll(columnHeaderItems); … … 555 554 { 556 555 Q_Q(QStandardItemModel); 557 if (parent == root )556 if (parent == root.data()) 558 557 rowHeaderItems.insert(row, count, 0); 559 558 q->endInsertRows(); … … 567 566 { 568 567 Q_Q(QStandardItemModel); 569 if (parent == root )568 if (parent == root.data()) 570 569 columnHeaderItems.insert(column, count, 0); 571 570 q->endInsertColumns(); … … 579 578 { 580 579 Q_Q(QStandardItemModel); 581 if (parent == root ) {580 if (parent == root.data()) { 582 581 for (int i = row; i < row + count; ++i) { 583 582 QStandardItem *oldItem = rowHeaderItems.at(i); … … 598 597 { 599 598 Q_Q(QStandardItemModel); 600 if (parent == root ) {599 if (parent == root.data()) { 601 600 for (int i = column; i < column + count; ++i) { 602 601 QStandardItem *oldItem = columnHeaderItems.at(i); … … 779 778 QStandardItem::~QStandardItem() 780 779 { 781 Q_D(QStandardItem);782 delete d;783 780 } 784 781 … … 791 788 { 792 789 Q_D(const QStandardItem); 793 if (!d->model || (d->model->d_func()->root != d->parent))790 if (!d->model || (d->model->d_func()->root.data() != d->parent)) 794 791 return d->parent; 795 792 return 0; … … 900 897 return (Qt::ItemIsSelectable|Qt::ItemIsEnabled|Qt::ItemIsEditable 901 898 |Qt::ItemIsDragEnabled|Qt::ItemIsDropEnabled); 902 return ((Qt::ItemFlags)(v.toInt()));899 return Qt::ItemFlags(v.toInt()); 903 900 } 904 901 … … 1743 1740 if ((row < 0) || (row >= rowCount())) 1744 1741 return QList<QStandardItem*>(); 1742 if (d->model) 1743 d->model->d_func()->rowsAboutToBeRemoved(this, row, row); 1745 1744 QList<QStandardItem*> items; 1746 int index = d->childIndex(row, 0); 1747 for (int column = 0; column < d->columnCount(); ++column) { 1748 QStandardItem *ch = d->children.at(index); 1749 if (ch) { 1750 ch->d_func()->setParentAndModel(0, 0); 1751 d->children.replace(index, 0); 1745 int index = d->childIndex(row, 0); // Will return -1 if there are no columns 1746 if (index != -1) { 1747 int col_count = d->columnCount(); 1748 for (int column = 0; column < col_count; ++column) { 1749 QStandardItem *ch = d->children.at(index + column); 1750 if (ch) 1751 ch->d_func()->setParentAndModel(0, 0); 1752 items.append(ch); 1752 1753 } 1753 items.append(ch); 1754 ++index; 1755 } 1756 removeRow(row); 1754 d->children.remove(index, col_count); 1755 } 1756 d->rows--; 1757 if (d->model) 1758 d->model->d_func()->rowsRemoved(this, row, 1); 1757 1759 return items; 1758 1760 } … … 1770 1772 if ((column < 0) || (column >= columnCount())) 1771 1773 return QList<QStandardItem*>(); 1774 if (d->model) 1775 d->model->d_func()->columnsAboutToBeRemoved(this, column, column); 1772 1776 QList<QStandardItem*> items; 1773 int index = d->childIndex(0, column); 1774 for (int row = 0; row < d->rowCount(); ++row) { 1777 1778 for (int row = d->rowCount() - 1; row >= 0; --row) { 1779 int index = d->childIndex(row, column); 1775 1780 QStandardItem *ch = d->children.at(index); 1776 if (ch) {1781 if (ch) 1777 1782 ch->d_func()->setParentAndModel(0, 0); 1778 d->children.replace(index, 0);1779 }1780 items.append(ch);1781 index += d->columnCount();1782 }1783 removeColumn(column);1783 d->children.remove(index); 1784 items.prepend(ch); 1785 } 1786 d->columns--; 1787 if (d->model) 1788 d->model->d_func()->columnsRemoved(this, column, 1); 1784 1789 return items; 1785 1790 } … … 1802 1807 const QVariant l = data(role), r = other.data(role); 1803 1808 // this code is copied from QSortFilterProxyModel::lessThan() 1804 switch (l. type()) {1809 switch (l.userType()) { 1805 1810 case QVariant::Invalid: 1806 1811 return (r.type() == QVariant::Invalid); … … 1813 1818 case QVariant::ULongLong: 1814 1819 return l.toULongLong() < r.toULongLong(); 1820 case QMetaType::Float: 1821 return l.toFloat() < r.toFloat(); 1815 1822 case QVariant::Double: 1816 1823 return l.toDouble() < r.toDouble(); … … 1891 1898 qint32 flags; 1892 1899 in >> flags; 1893 setFlags( (Qt::ItemFlags)flags);1900 setFlags(Qt::ItemFlags(flags)); 1894 1901 } 1895 1902 … … 1939 1946 } 1940 1947 1941 #endif // !QT_NO_DATASTREAM1948 #endif // QT_NO_DATASTREAM 1942 1949 1943 1950 /*! … … 2080 2087 { 2081 2088 Q_D(QStandardItemModel); 2082 delete d->root; 2083 d->root = new QStandardItem; 2089 d->root.reset(new QStandardItem); 2084 2090 d->root->d_func()->setModel(this); 2085 2091 qDeleteAll(d->columnHeaderItems); … … 2228 2234 { 2229 2235 Q_D(const QStandardItemModel); 2230 return d->root ;2236 return d->root.data(); 2231 2237 } 2232 2238 … … 2730 2736 { 2731 2737 Q_D(QStandardItemModel); 2732 QStandardItem *item = parent.isValid() ? itemFromIndex(parent) : d->root ;2738 QStandardItem *item = parent.isValid() ? itemFromIndex(parent) : d->root.data(); 2733 2739 if (item == 0) 2734 2740 return false; … … 2742 2748 { 2743 2749 Q_D(QStandardItemModel); 2744 QStandardItem *item = parent.isValid() ? itemFromIndex(parent) : d->root ;2750 QStandardItem *item = parent.isValid() ? itemFromIndex(parent) : d->root.data(); 2745 2751 if (item == 0) 2746 2752 return false; … … 2908 2914 itemsSet.reserve(indexes.count()); 2909 2915 stack.reserve(indexes.count()); 2910 for each (const QModelIndex &index, indexes) {2911 QStandardItem *item = itemFromIndex(index );2916 for (int i = 0; i < indexes.count(); ++i) { 2917 QStandardItem *item = itemFromIndex(indexes.at(i)); 2912 2918 itemsSet << item; 2913 2919 stack.push(item); … … 2966 2972 stream out an item and his children 2967 2973 */ 2968 static voiddecodeDataRecursive(QDataStream &stream, QStandardItem *item)2974 void QStandardItemModelPrivate::decodeDataRecursive(QDataStream &stream, QStandardItem *item) 2969 2975 { 2970 2976 int colCount, childCount; … … 2977 2983 while(childPos > 0) { 2978 2984 childPos--; 2979 QStandardItem *child = new QStandardItem;2985 QStandardItem *child = createItem(); 2980 2986 decodeDataRecursive(stream, child); 2981 2987 item->setChild( childPos / colCount, childPos % colCount, child); … … 2990 2996 int row, int column, const QModelIndex &parent) 2991 2997 { 2998 Q_D(QStandardItemModel); 2992 2999 // check if the action is supported 2993 3000 if (!data || !(action == Qt::CopyAction || action == Qt::MoveAction)) … … 3021 3028 while (!stream.atEnd()) { 3022 3029 int r, c; 3023 QStandardItem *item = new QStandardItem;3030 QStandardItem *item = d->createItem(); 3024 3031 stream >> r >> c; 3025 d ecodeDataRecursive(stream, item);3032 d->decodeDataRecursive(stream, item); 3026 3033 3027 3034 rows.append(r); -
trunk/src/gui/itemviews/qstandarditemmodel.h
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 ** … … 241 241 QStandardItem(QStandardItemPrivate &dd); 242 242 QStandardItem &operator=(const QStandardItem &other); 243 QS tandardItemPrivate *d_ptr;243 QScopedPointer<QStandardItemPrivate> d_ptr; 244 244 245 245 void emitDataChanged(); -
trunk/src/gui/itemviews/qstandarditemmodel_p.h
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 ** … … 76 76 rows(0), 77 77 columns(0), 78 q_ptr(0), 78 79 lastIndexOf(2) 79 80 { } … … 153 154 Q_Q(const QStandardItemModel); 154 155 if (!index.isValid()) 155 return root ;156 return root.data(); 156 157 if (index.model() != q) 157 158 return 0; … … 176 177 const QModelIndex &bottomRight); 177 178 179 void decodeDataRecursive(QDataStream &stream, QStandardItem *item); 180 178 181 QVector<QStandardItem*> columnHeaderItems; 179 182 QVector<QStandardItem*> rowHeaderItems; 180 QS tandardItem *root;183 QScopedPointer<QStandardItem> root; 181 184 const QStandardItem *itemPrototype; 182 185 int sortRole; -
trunk/src/gui/itemviews/qstringlistmodel.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 ** … … 55 55 56 56 \ingroup model-view 57 \mainclass 57 58 58 59 59 QStringListModel is an editable model that can be used for simple -
trunk/src/gui/itemviews/qstringlistmodel.h
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 ** -
trunk/src/gui/itemviews/qstyleditemdelegate.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 ** … … 48 48 #include <qlineedit.h> 49 49 #include <qtextedit.h> 50 #include <qplaintextedit.h> 50 51 #include <qpainter.h> 51 52 #include <qpalette.h> … … 112 113 113 114 \ingroup model-view 114 \mainclass 115 115 116 \since 4.4 116 117 … … 148 149 \row \o \l Qt::BackgroundColorRole \o QColor (obsolete; use Qt::BackgroundRole instead) 149 150 \row \o \l Qt::CheckStateRole \o Qt::CheckState 150 \row \o \l Qt::DecorationRole \o QIcon and QColor151 \row \o \l Qt::DecorationRole \o QIcon, QPixmap, QImage and QColor 151 152 \row \o \l Qt::DisplayRole \o QString and types with a string representation 152 153 \row \o \l Qt::EditRole \o See QItemEditorFactory for details … … 267 268 { 268 269 QString text; 269 switch (value.type()) { 270 switch (value.userType()) { 271 case QMetaType::Float: 270 272 case QVariant::Double: 271 text = locale.toString(value.to Double());273 text = locale.toString(value.toReal()); 272 274 break; 273 275 case QVariant::Int: … … 322 324 value = index.data(Qt::TextAlignmentRole); 323 325 if (value.isValid() && !value.isNull()) 324 option->displayAlignment = (Qt::Alignment)value.toInt();326 option->displayAlignment = Qt::Alignment(value.toInt()); 325 327 326 328 value = index.data(Qt::ForegroundRole); … … 508 510 509 511 /*! 510 Gets data drom the \a editor widget and stores it in the specified512 Gets data from the \a editor widget and stores it in the specified 511 513 \a model at the item \a index. 512 514 … … 647 649 case Qt::Key_Return: 648 650 #ifndef QT_NO_TEXTEDIT 649 if (qobject_cast<QTextEdit *>(editor))651 if (qobject_cast<QTextEdit *>(editor) || qobject_cast<QPlainTextEdit *>(editor)) 650 652 return false; // don't filter enter key events for QTextEdit 651 653 // We want the editor to be able to process the key press … … 671 673 editor->parentWidget()->setFocus(); 672 674 return true; 673 } else if (event->type() == QEvent::FocusOut || event->type() == QEvent::Hide) {675 } else if (event->type() == QEvent::FocusOut || (event->type() == QEvent::Hide && editor->isWindow())) { 674 676 //the Hide event will take care of he editors that are in fact complete dialogs 675 677 if (!editor->isActiveWindow() || (QApplication::focusWidget() != editor)) { … … 686 688 return false; 687 689 #endif 688 // Opening a modal dialog will start a new eventloop 689 // that will process the deleteLater event. 690 QWidget *activeModalWidget = QApplication::activeModalWidget(); 691 if (activeModalWidget 692 && !activeModalWidget->isAncestorOf(editor) 693 && qobject_cast<QDialog*>(activeModalWidget)) 694 return false; 690 695 691 emit commitData(editor); 696 692 emit closeEditor(editor, NoHint); … … 752 748 } 753 749 754 Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked 750 Qt::CheckState state; 751 if ( flags & Qt::ItemIsTristate ) { 752 state = static_cast<Qt::CheckState>( (value.toInt() + 1) % 3 ); 753 } else { 754 state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked 755 755 ? Qt::Unchecked : Qt::Checked); 756 } 756 757 return model->setData(index, state, Qt::CheckStateRole); 757 758 } -
trunk/src/gui/itemviews/qstyleditemdelegate.h
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 ** -
trunk/src/gui/itemviews/qtableview.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 ** … … 59 59 60 60 QT_BEGIN_NAMESPACE 61 62 /** \internal 63 Add a span to the collection. the collection takes the ownership. 64 */ 65 void QSpanCollection::addSpan(QSpanCollection::Span *span) 66 { 67 spans.append(span); 68 Index::iterator it_y = index.lowerBound(-span->top()); 69 if (it_y == index.end() || it_y.key() != -span->top()) { 70 //there is no spans that starts with the row in the index, so create a sublist for it. 71 SubIndex sub_index; 72 if (it_y != index.end()) { 73 //the previouslist is the list of spans that sarts _before_ the row of the span. 74 // and which may intersect this row. 75 const SubIndex previousList = it_y.value(); 76 foreach(Span *s, previousList) { 77 //If a subspans intersect the row, we need to split it into subspans 78 if(s->bottom() >= span->top()) 79 sub_index.insert(-s->left(), s); 80 } 81 } 82 it_y = index.insert(-span->top(), sub_index); 83 //we will insert span to *it_y in the later loop 84 } 85 86 //insert the span as supspan in all the lists that intesects the span 87 while(-it_y.key() <= span->bottom()) { 88 (*it_y).insert(-span->left(), span); 89 if(it_y == index.begin()) 90 break; 91 --it_y; 92 } 93 } 94 95 96 /** \internal 97 * Has to be called after the height and width of a span is changed. 98 * 99 * old_height is the height before the change 100 * 101 * if the size of the span is now 0x0 the span will be deleted. 102 */ 103 void QSpanCollection::updateSpan(QSpanCollection::Span *span, int old_height) 104 { 105 if (old_height < span->height()) { 106 //add the span as subspan in all the lists that intersect the new covered columns 107 Index::iterator it_y = index.lowerBound(-(span->top() + old_height - 1)); 108 Q_ASSERT(it_y != index.end()); //it_y must exist since the span is in the list 109 while (-it_y.key() <= span->bottom()) { 110 (*it_y).insert(-span->left(), span); 111 if(it_y == index.begin()) 112 break; 113 --it_y; 114 } 115 } else if (old_height > span->height()) { 116 //remove the span from all the subspans lists that intersect the columns not covered anymore 117 Index::iterator it_y = index.lowerBound(qMin(-span->bottom(), 0)); 118 Q_ASSERT(it_y != index.end()); //it_y must exist since the span is in the list 119 while (-it_y.key() <= span->top() + old_height -1) { 120 if (-it_y.key() > span->bottom()) { 121 (*it_y).remove(-span->left()); 122 if (it_y->isEmpty()) { 123 it_y = index.erase(it_y) - 1; 124 } 125 } 126 if(it_y == index.begin()) 127 break; 128 --it_y; 129 } 130 } 131 132 if (span->width() == 0 && span->height() == 0) { 133 spans.removeOne(span); 134 delete span; 135 } 136 } 137 138 /** \internal 139 * \return a spans that spans over cell x,y (column,row) or 0 if there is none. 140 */ 141 QSpanCollection::Span *QSpanCollection::spanAt(int x, int y) const 142 { 143 Index::const_iterator it_y = index.lowerBound(-y); 144 if (it_y == index.end()) 145 return 0; 146 SubIndex::const_iterator it_x = (*it_y).lowerBound(-x); 147 if (it_x == (*it_y).end()) 148 return 0; 149 Span *span = *it_x; 150 if (span->right() >= x && span->bottom() >= y) 151 return span; 152 return 0; 153 } 154 155 156 /** \internal 157 * remove and deletes all spans inside the collection 158 */ 159 void QSpanCollection::clear() 160 { 161 qDeleteAll(spans); 162 index.clear(); 163 spans.clear(); 164 } 165 166 /** \internal 167 * return a list to all the spans that spans over cells in the given rectangle 168 */ 169 QList<QSpanCollection::Span *> QSpanCollection::spansInRect(int x, int y, int w, int h) const 170 { 171 QSet<Span *> list; 172 Index::const_iterator it_y = index.lowerBound(-y); 173 if(it_y == index.end()) 174 --it_y; 175 while(-it_y.key() <= y + h) { 176 SubIndex::const_iterator it_x = (*it_y).lowerBound(-x); 177 if (it_x == (*it_y).end()) 178 --it_x; 179 while(-it_x.key() <= x + w) { 180 Span *s = *it_x; 181 if (s->bottom() >= y && s->right() >= x) 182 list << s; 183 if (it_x == (*it_y).begin()) 184 break; 185 --it_x; 186 } 187 if(it_y == index.begin()) 188 break; 189 --it_y; 190 } 191 return list.toList(); 192 } 193 194 #undef DEBUG_SPAN_UPDATE 195 196 #ifdef DEBUG_SPAN_UPDATE 197 QDebug operator<<(QDebug str, const QSpanCollection::Span &span) 198 { 199 str << "(" << span.top() << "," << span.left() << "," << span.bottom() << "," << span.right() << ")"; 200 return str; 201 } 202 #endif 203 204 /** \internal 205 * Updates the span collection after row insertion. 206 */ 207 void QSpanCollection::updateInsertedRows(int start, int end) 208 { 209 #ifdef DEBUG_SPAN_UPDATE 210 qDebug() << Q_FUNC_INFO; 211 qDebug() << start << end; 212 qDebug() << index; 213 #endif 214 if (spans.isEmpty()) 215 return; 216 217 int delta = end - start + 1; 218 #ifdef DEBUG_SPAN_UPDATE 219 qDebug("Before"); 220 #endif 221 for (SpanList::iterator it = spans.begin(); it != spans.end(); ++it) { 222 Span *span = *it; 223 #ifdef DEBUG_SPAN_UPDATE 224 qDebug() << span << *span; 225 #endif 226 if (span->m_bottom < start) 227 continue; 228 if (span->m_top >= start) 229 span->m_top += delta; 230 span->m_bottom += delta; 231 } 232 233 #ifdef DEBUG_SPAN_UPDATE 234 qDebug("After"); 235 foreach (QSpanCollection::Span *span, spans) 236 qDebug() << span << *span; 237 #endif 238 239 for (Index::iterator it_y = index.begin(); it_y != index.end(); ) { 240 int y = -it_y.key(); 241 if (y < start) { 242 ++it_y; 243 continue; 244 } 245 246 index.insert(-y - delta, it_y.value()); 247 it_y = index.erase(it_y); 248 } 249 #ifdef DEBUG_SPAN_UPDATE 250 qDebug() << index; 251 #endif 252 } 253 254 /** \internal 255 * Updates the span collection after column insertion. 256 */ 257 void QSpanCollection::updateInsertedColumns(int start, int end) 258 { 259 #ifdef DEBUG_SPAN_UPDATE 260 qDebug() << Q_FUNC_INFO; 261 qDebug() << start << end; 262 qDebug() << index; 263 #endif 264 if (spans.isEmpty()) 265 return; 266 267 int delta = end - start + 1; 268 #ifdef DEBUG_SPAN_UPDATE 269 qDebug("Before"); 270 #endif 271 for (SpanList::iterator it = spans.begin(); it != spans.end(); ++it) { 272 Span *span = *it; 273 #ifdef DEBUG_SPAN_UPDATE 274 qDebug() << span << *span; 275 #endif 276 if (span->m_right < start) 277 continue; 278 if (span->m_left >= start) 279 span->m_left += delta; 280 span->m_right += delta; 281 } 282 283 #ifdef DEBUG_SPAN_UPDATE 284 qDebug("After"); 285 foreach (QSpanCollection::Span *span, spans) 286 qDebug() << span << *span; 287 #endif 288 289 for (Index::iterator it_y = index.begin(); it_y != index.end(); ++it_y) { 290 SubIndex &subindex = it_y.value(); 291 for (SubIndex::iterator it = subindex.begin(); it != subindex.end(); ) { 292 int x = -it.key(); 293 if (x < start) { 294 ++it; 295 continue; 296 } 297 subindex.insert(-x - delta, it.value()); 298 it = subindex.erase(it); 299 } 300 } 301 #ifdef DEBUG_SPAN_UPDATE 302 qDebug() << index; 303 #endif 304 } 305 306 /** \internal 307 * Cleans a subindex from to be deleted spans. The update argument is used 308 * to move the spans inside the subindex, in case their anchor changed. 309 * \return true if no span in this subindex starts at y, and should thus be deleted. 310 */ 311 bool QSpanCollection::cleanSpanSubIndex(QSpanCollection::SubIndex &subindex, int y, bool update) 312 { 313 if (subindex.isEmpty()) 314 return true; 315 316 bool should_be_deleted = true; 317 SubIndex::iterator it = subindex.end(); 318 do { 319 --it; 320 int x = -it.key(); 321 Span *span = it.value(); 322 if (span->will_be_deleted) { 323 it = subindex.erase(it); 324 continue; 325 } 326 if (update && span->m_left != x) { 327 subindex.insert(-span->m_left, span); 328 it = subindex.erase(it); 329 } 330 if (should_be_deleted && span->m_top == y) 331 should_be_deleted = false; 332 } while (it != subindex.begin()); 333 334 return should_be_deleted; 335 } 336 337 /** \internal 338 * Updates the span collection after row removal. 339 */ 340 void QSpanCollection::updateRemovedRows(int start, int end) 341 { 342 #ifdef DEBUG_SPAN_UPDATE 343 qDebug() << Q_FUNC_INFO; 344 qDebug() << start << end; 345 qDebug() << index; 346 #endif 347 if (spans.isEmpty()) 348 return; 349 350 SpanList spansToBeDeleted; 351 int delta = end - start + 1; 352 #ifdef DEBUG_SPAN_UPDATE 353 qDebug("Before"); 354 #endif 355 for (SpanList::iterator it = spans.begin(); it != spans.end(); ) { 356 Span *span = *it; 357 #ifdef DEBUG_SPAN_UPDATE 358 qDebug() << span << *span; 359 #endif 360 if (span->m_bottom < start) { 361 ++it; 362 continue; 363 } 364 if (span->m_top < start) { 365 if (span->m_bottom <= end) 366 span->m_bottom = start - 1; 367 else 368 span->m_bottom -= delta; 369 } else { 370 if (span->m_bottom > end) { 371 if (span->m_top <= end) 372 span->m_top = start; 373 else 374 span->m_top -= delta; 375 span->m_bottom -= delta; 376 } else { 377 span->will_be_deleted = true; 378 } 379 } 380 if (span->m_top == span->m_bottom && span->m_left == span->m_right) 381 span->will_be_deleted = true; 382 if (span->will_be_deleted) { 383 spansToBeDeleted.append(span); 384 it = spans.erase(it); 385 } else { 386 ++it; 387 } 388 } 389 390 #ifdef DEBUG_SPAN_UPDATE 391 qDebug("After"); 392 foreach (QSpanCollection::Span *span, spans) 393 qDebug() << span << *span; 394 #endif 395 if (spans.isEmpty()) { 396 qDeleteAll(spansToBeDeleted); 397 index.clear(); 398 return; 399 } 400 401 Index::iterator it_y = index.end(); 402 do { 403 --it_y; 404 int y = -it_y.key(); 405 SubIndex &subindex = it_y.value(); 406 if (y < start) { 407 if (cleanSpanSubIndex(subindex, y)) 408 it_y = index.erase(it_y); 409 } else if (y >= start && y <= end) { 410 bool span_at_start = false; 411 SubIndex spansToBeMoved; 412 for (SubIndex::iterator it = subindex.begin(); it != subindex.end(); ++it) { 413 Span *span = it.value(); 414 if (span->will_be_deleted) 415 continue; 416 if (!span_at_start && span->m_top == start) 417 span_at_start = true; 418 spansToBeMoved.insert(it.key(), span); 419 } 420 421 if (y == start && span_at_start) 422 subindex.clear(); 423 else 424 it_y = index.erase(it_y); 425 426 if (span_at_start) { 427 Index::iterator it_start; 428 if (y == start) 429 it_start = it_y; 430 else { 431 it_start = index.find(-start); 432 if (it_start == index.end()) 433 it_start = index.insert(-start, SubIndex()); 434 } 435 SubIndex &start_subindex = it_start.value(); 436 for (SubIndex::iterator it = spansToBeMoved.begin(); it != spansToBeMoved.end(); ++it) 437 start_subindex.insert(it.key(), it.value()); 438 } 439 } else { 440 if (y == end + 1) { 441 Index::iterator it_top = index.find(-y + delta); 442 if (it_top == index.end()) 443 it_top = index.insert(-y + delta, SubIndex()); 444 for (SubIndex::iterator it = subindex.begin(); it != subindex.end(); ) { 445 Span *span = it.value(); 446 if (!span->will_be_deleted) 447 it_top.value().insert(it.key(), span); 448 ++it; 449 } 450 } else { 451 index.insert(-y + delta, subindex); 452 } 453 it_y = index.erase(it_y); 454 } 455 } while (it_y != index.begin()); 456 457 #ifdef DEBUG_SPAN_UPDATE 458 qDebug() << index; 459 qDebug("Deleted"); 460 foreach (QSpanCollection::Span *span, spansToBeDeleted) 461 qDebug() << span << *span; 462 #endif 463 qDeleteAll(spansToBeDeleted); 464 } 465 466 /** \internal 467 * Updates the span collection after column removal. 468 */ 469 void QSpanCollection::updateRemovedColumns(int start, int end) 470 { 471 #ifdef DEBUG_SPAN_UPDATE 472 qDebug() << Q_FUNC_INFO; 473 qDebug() << start << end; 474 qDebug() << index; 475 #endif 476 if (spans.isEmpty()) 477 return; 478 479 SpanList toBeDeleted; 480 int delta = end - start + 1; 481 #ifdef DEBUG_SPAN_UPDATE 482 qDebug("Before"); 483 #endif 484 for (SpanList::iterator it = spans.begin(); it != spans.end(); ) { 485 Span *span = *it; 486 #ifdef DEBUG_SPAN_UPDATE 487 qDebug() << span << *span; 488 #endif 489 if (span->m_right < start) { 490 ++it; 491 continue; 492 } 493 if (span->m_left < start) { 494 if (span->m_right <= end) 495 span->m_right = start - 1; 496 else 497 span->m_right -= delta; 498 } else { 499 if (span->m_right > end) { 500 if (span->m_left <= end) 501 span->m_left = start; 502 else 503 span->m_left -= delta; 504 span->m_right -= delta; 505 } else { 506 span->will_be_deleted = true; 507 } 508 } 509 if (span->m_top == span->m_bottom && span->m_left == span->m_right) 510 span->will_be_deleted = true; 511 if (span->will_be_deleted) { 512 toBeDeleted.append(span); 513 it = spans.erase(it); 514 } else { 515 ++it; 516 } 517 } 518 519 #ifdef DEBUG_SPAN_UPDATE 520 qDebug("After"); 521 foreach (QSpanCollection::Span *span, spans) 522 qDebug() << span << *span; 523 #endif 524 if (spans.isEmpty()) { 525 qDeleteAll(toBeDeleted); 526 index.clear(); 527 return; 528 } 529 530 for (Index::iterator it_y = index.begin(); it_y != index.end(); ) { 531 int y = -it_y.key(); 532 if (cleanSpanSubIndex(it_y.value(), y, true)) 533 it_y = index.erase(it_y); 534 else 535 ++it_y; 536 } 537 538 #ifdef DEBUG_SPAN_UPDATE 539 qDebug() << index; 540 qDebug("Deleted"); 541 foreach (QSpanCollection::Span *span, toBeDeleted) 542 qDebug() << span << *span; 543 #endif 544 qDeleteAll(toBeDeleted); 545 } 546 547 #ifdef QT_BUILD_INTERNAL 548 /*! 549 \internal 550 Checks whether the span index structure is self-consistent, and consistent with the spans list. 551 */ 552 bool QSpanCollection::checkConsistency() const 553 { 554 for (Index::const_iterator it_y = index.begin(); it_y != index.end(); ++it_y) { 555 int y = -it_y.key(); 556 const SubIndex &subIndex = it_y.value(); 557 for (SubIndex::const_iterator it = subIndex.begin(); it != subIndex.end(); ++it) { 558 int x = -it.key(); 559 Span *span = it.value(); 560 if (!spans.contains(span) || span->left() != x 561 || y < span->top() || y > span->bottom()) 562 return false; 563 } 564 } 565 566 foreach (const Span *span, spans) { 567 if (span->width() < 1 || span->height() < 1 568 || (span->width() == 1 && span->height() == 1)) 569 return false; 570 for (int y = span->top(); y <= span->bottom(); ++y) { 571 Index::const_iterator it_y = index.find(-y); 572 if (it_y == index.end()) { 573 if (y == span->top()) 574 return false; 575 else 576 continue; 577 } 578 const SubIndex &subIndex = it_y.value(); 579 SubIndex::const_iterator it = subIndex.find(-span->left()); 580 if (it == subIndex.end() || it.value() != span) 581 return false; 582 } 583 } 584 return true; 585 } 586 #endif 61 587 62 588 class QTableCornerButton : public QAbstractButton … … 150 676 void QTableViewPrivate::setSpan(int row, int column, int rowSpan, int columnSpan) 151 677 { 152 if (row < 0 || column < 0 || rowSpan < 0 || columnSpan < 0) 678 if (row < 0 || column < 0 || rowSpan <= 0 || columnSpan <= 0) { 679 qWarning() << "QTableView::setSpan: invalid span given: (" << row << ',' << column << ',' << rowSpan << ',' << columnSpan << ')'; 153 680 return; 154 Span sp(row, column, rowSpan, columnSpan); 155 QList<Span>::iterator it; 156 for (it = spans.begin(); it != spans.end(); ++it) { 157 if (((*it).top() == sp.top()) && ((*it).left() == sp.left())) { 158 if ((sp.height() == 1) && (sp.width() == 1)) 159 spans.erase(it); // "Implicit" span (1, 1), no need to store it 160 else 161 *it = sp; // Replace 681 } 682 QSpanCollection::Span *sp = spans.spanAt(column, row); 683 if (sp) { 684 if (sp->top() != row || sp->left() != column) { 685 qWarning() << "QTableView::setSpan: span cannot overlap"; 162 686 return; 163 687 } 164 } 165 spans.append(sp); 688 if (rowSpan == 1 && columnSpan == 1) { 689 rowSpan = columnSpan = 0; 690 } 691 const int old_height = sp->height(); 692 sp->m_bottom = row + rowSpan - 1; 693 sp->m_right = column + columnSpan - 1; 694 spans.updateSpan(sp, old_height); 695 return; 696 } else if (rowSpan == 1 && columnSpan == 1) { 697 qWarning() << "QTableView::setSpan: single cell span won't be added"; 698 return; 699 } 700 sp = new QSpanCollection::Span(row, column, rowSpan, columnSpan); 701 spans.addSpan(sp); 166 702 } 167 703 … … 170 706 Gets the span information for the cell at (\a row, \a column). 171 707 */ 172 QTableViewPrivate::Span QTableViewPrivate::span(int row, int column) const 173 { 174 QList<Span>::const_iterator it; 175 for (it = spans.constBegin(); it != spans.constEnd(); ++it) { 176 Span span = *it; 177 if (isInSpan(row, column, span)) 178 return span; 179 } 180 return Span(row, column, 1, 1); 708 QSpanCollection::Span QTableViewPrivate::span(int row, int column) const 709 { 710 QSpanCollection::Span *sp = spans.spanAt(column, row); 711 if (sp) 712 return *sp; 713 714 return QSpanCollection::Span(row, column, 1, 1); 181 715 } 182 716 … … 234 768 /*! 235 769 \internal 236 Returns true if one or more spans intersect column \a column.237 */238 bool QTableViewPrivate::spansIntersectColumn(int column) const239 {240 QList<Span>::const_iterator it;241 for (it = spans.constBegin(); it != spans.constEnd(); ++it) {242 Span span = *it;243 if (spanContainsColumn(column, span.left(), span.width()))244 return true;245 }246 return false;247 }248 249 /*!250 \internal251 Returns true if one or more spans intersect row \a row.252 */253 bool QTableViewPrivate::spansIntersectRow(int row) const254 {255 QList<Span>::const_iterator it;256 for (it = spans.constBegin(); it != spans.constEnd(); ++it) {257 Span span = *it;258 if (spanContainsRow(row, span.top(), span.height()))259 return true;260 }261 return false;262 }263 264 /*!265 \internal266 Returns true if one or more spans intersect one or more columns.267 */268 bool QTableViewPrivate::spansIntersectColumns(const QList<int> &columns) const269 {270 QList<int>::const_iterator it;271 for (it = columns.constBegin(); it != columns.constEnd(); ++it) {272 if (spansIntersectColumn(*it))273 return true;274 }275 return false;276 }277 278 /*!279 \internal280 Returns true if one or more spans intersect one or more rows.281 */282 bool QTableViewPrivate::spansIntersectRows(const QList<int> &rows) const283 {284 QList<int>::const_iterator it;285 for (it = rows.constBegin(); it != rows.constEnd(); ++it) {286 if (spansIntersectRow(*it))287 return true;288 }289 return false;290 }291 292 /*!293 \internal294 770 Returns the visual rect for the given \a span. 295 771 */ 296 QRect QTableViewPrivate::visualSpanRect(const Span &span) const772 QRect QTableViewPrivate::visualSpanRect(const QSpanCollection::Span &span) const 297 773 { 298 774 Q_Q(const QTableView); … … 320 796 \a drawn is a QBitArray of visualRowCountxvisualCoulumnCount which say if particular cell has been drawn 321 797 */ 322 void QTableViewPrivate::drawAndClipSpans(const QRe ct&area, QPainter *painter,798 void QTableViewPrivate::drawAndClipSpans(const QRegion &area, QPainter *painter, 323 799 const QStyleOptionViewItemV4 &option, QBitArray *drawn, 324 800 int firstVisualRow, int lastVisualRow, int firstVisualColumn, int lastVisualColumn) … … 327 803 QRegion region = viewport->rect(); 328 804 329 QList<Span>::const_iterator it; 330 for (it = spans.constBegin(); it != spans.constEnd(); ++it) { 331 Span span = *it; 332 333 int row = span.top(); 334 int col = span.left(); 335 if (isHidden(row, col)) 336 continue; 805 QList<QSpanCollection::Span *> visibleSpans; 806 bool sectionMoved = verticalHeader->sectionsMoved() || horizontalHeader->sectionsMoved(); 807 808 if (!sectionMoved) { 809 visibleSpans = spans.spansInRect(logicalColumn(firstVisualColumn), logicalRow(firstVisualRow), 810 lastVisualColumn - firstVisualColumn + 1, lastVisualRow - firstVisualRow + 1); 811 } else { 812 QSet<QSpanCollection::Span *> set; 813 for(int x = firstVisualColumn; x <= lastVisualColumn; x++) 814 for(int y = firstVisualRow; y <= lastVisualRow; y++) 815 set.insert(spans.spanAt(x,y)); 816 set.remove(0); 817 visibleSpans = set.toList(); 818 } 819 820 foreach (QSpanCollection::Span *span, visibleSpans) { 821 int row = span->top(); 822 int col = span->left(); 337 823 QModelIndex index = model->index(row, col, root); 338 824 if (!index.isValid()) 339 825 continue; 340 QRect rect = visualSpanRect( span);826 QRect rect = visualSpanRect(*span); 341 827 rect.translate(scrollDelayOffset); 342 if (! rect.intersects(area))828 if (!area.intersects(rect)) 343 829 continue; 344 830 QStyleOptionViewItemV4 opt = option; 345 831 opt.rect = rect; 346 alternateBase = alternatingColors && (span .top() & 1);832 alternateBase = alternatingColors && (span->top() & 1); 347 833 if (alternateBase) 348 834 opt.features |= QStyleOptionViewItemV2::Alternate; … … 351 837 drawCell(painter, opt, index); 352 838 region -= rect; 353 for (int r = span .top(); r <= span.bottom(); ++r) {839 for (int r = span->top(); r <= span->bottom(); ++r) { 354 840 const int vr = visualRow(r); 355 841 if (vr < firstVisualRow || vr > lastVisualRow) 356 842 continue; 357 for (int c = span .left(); c <= span.right(); ++c) {843 for (int c = span->left(); c <= span->right(); ++c) { 358 844 const int vc = visualColumn(c); 359 845 if (vc < firstVisualColumn || vc > lastVisualColumn) … … 366 852 } 367 853 painter->setClipRegion(region); 854 } 855 856 /*! 857 \internal 858 Updates spans after row insertion. 859 */ 860 void QTableViewPrivate::_q_updateSpanInsertedRows(const QModelIndex &parent, int start, int end) 861 { 862 Q_UNUSED(parent) 863 spans.updateInsertedRows(start, end); 864 } 865 866 /*! 867 \internal 868 Updates spans after column insertion. 869 */ 870 void QTableViewPrivate::_q_updateSpanInsertedColumns(const QModelIndex &parent, int start, int end) 871 { 872 Q_UNUSED(parent) 873 spans.updateInsertedColumns(start, end); 874 } 875 876 /*! 877 \internal 878 Updates spans after row removal. 879 */ 880 void QTableViewPrivate::_q_updateSpanRemovedRows(const QModelIndex &parent, int start, int end) 881 { 882 Q_UNUSED(parent) 883 spans.updateRemovedRows(start, end); 884 } 885 886 /*! 887 \internal 888 Updates spans after column removal. 889 */ 890 void QTableViewPrivate::_q_updateSpanRemovedColumns(const QModelIndex &parent, int start, int end) 891 { 892 Q_UNUSED(parent) 893 spans.updateRemovedColumns(start, end); 368 894 } 369 895 … … 398 924 } 399 925 400 if (opt.features & QStyleOptionViewItemV2::Alternate) 401 painter->fillRect(opt.rect, opt.palette.brush(QPalette::AlternateBase)); 926 q->style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, q); 402 927 403 928 if (const QWidget *widget = editorForIndex(index).editor) { … … 419 944 \ingroup model-view 420 945 \ingroup advanced 421 \mainclass 946 422 947 423 948 A QTableView implements a table view that displays items from a … … 540 1065 { 541 1066 Q_D(QTableView); 1067 if (model == d->model) 1068 return; 1069 //let's disconnect from the old model 1070 if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) { 1071 disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)), 1072 this, SLOT(_q_updateSpanInsertedRows(QModelIndex,int,int))); 1073 disconnect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)), 1074 this, SLOT(_q_updateSpanInsertedColumns(QModelIndex,int,int))); 1075 disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)), 1076 this, SLOT(_q_updateSpanRemovedRows(QModelIndex,int,int))); 1077 disconnect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)), 1078 this, SLOT(_q_updateSpanRemovedColumns(QModelIndex,int,int))); 1079 } 1080 if (model) { //and connect to the new one 1081 connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)), 1082 this, SLOT(_q_updateSpanInsertedRows(QModelIndex,int,int))); 1083 connect(model, SIGNAL(columnsInserted(QModelIndex,int,int)), 1084 this, SLOT(_q_updateSpanInsertedColumns(QModelIndex,int,int))); 1085 connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)), 1086 this, SLOT(_q_updateSpanRemovedRows(QModelIndex,int,int))); 1087 connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)), 1088 this, SLOT(_q_updateSpanRemovedColumns(QModelIndex,int,int))); 1089 } 542 1090 d->verticalHeader->setModel(model); 543 1091 d->horizontalHeader->setModel(model); … … 626 1174 this, SLOT(resizeColumnToContents(int))); 627 1175 connect(d->horizontalHeader, SIGNAL(geometriesChanged()), this, SLOT(updateGeometries())); 1176 1177 //update the sorting enabled states on the new header 1178 setSortingEnabled(d->sortingEnabled); 628 1179 } 629 1180 … … 754 1305 uint y = verticalHeader->length() - verticalHeader->offset() - 1; 755 1306 756 QVector<QRect> rects = event->region().rects(); 1307 const QRegion region = event->region().translated(offset); 1308 const QVector<QRect> rects = region.rects(); 757 1309 758 1310 //firstVisualRow is the visual index of the first visible row. lastVisualRow is the visual index of the last visible Row. … … 774 1326 QBitArray drawn((lastVisualRow - firstVisualRow + 1) * (lastVisualColumn - firstVisualColumn + 1)); 775 1327 1328 if (d->hasSpans()) { 1329 d->drawAndClipSpans(region, &painter, option, &drawn, 1330 firstVisualRow, lastVisualRow, firstVisualColumn, lastVisualColumn); 1331 } 1332 776 1333 for (int i = 0; i < rects.size(); ++i) { 777 1334 QRect dirtyArea = rects.at(i); 778 dirtyArea.translate(offset);779 1335 dirtyArea.setBottom(qMin(dirtyArea.bottom(), int(y))); 780 1336 if (rightToLeft) { … … 783 1339 dirtyArea.setRight(qMin(dirtyArea.right(), int(x))); 784 1340 } 785 786 if (d->hasSpans())787 d->drawAndClipSpans(dirtyArea, &painter, option, &drawn,788 firstVisualRow, lastVisualRow, firstVisualColumn, lastVisualColumn);789 1341 790 1342 // get the horizontal start and end visual sections … … 914 1466 if (r >= 0 && c >= 0) { 915 1467 if (d->hasSpans()) { 916 Q TableViewPrivate::Span span = d->span(r, c);1468 QSpanCollection::Span span = d->span(r, c); 917 1469 r = span.top(); 918 1470 c = span.left(); … … 986 1538 while (isRowHidden(d->logicalRow(row)) && row < bottom) 987 1539 ++row; 1540 d->visualCursor = QPoint(column, row); 988 1541 return d->model->index(d->logicalRow(row), d->logicalColumn(column), d->root); 989 1542 } 990 1543 991 int visualRow = d->visualRow(current.row()); 1544 // Update visual cursor if current index has changed. 1545 QPoint visualCurrent(d->visualColumn(current.column()), d->visualRow(current.row())); 1546 if (visualCurrent != d->visualCursor) { 1547 if (d->hasSpans()) { 1548 QSpanCollection::Span span = d->span(current.row(), current.column()); 1549 if (span.top() > d->visualCursor.y() || d->visualCursor.y() > span.bottom() 1550 || span.left() > d->visualCursor.x() || d->visualCursor.x() > span.right()) 1551 d->visualCursor = visualCurrent; 1552 } else { 1553 d->visualCursor = visualCurrent; 1554 } 1555 } 1556 1557 int visualRow = d->visualCursor.y(); 1558 if (visualRow > bottom) 1559 visualRow = bottom; 992 1560 Q_ASSERT(visualRow != -1); 993 int visualColumn = d->visualColumn(current.column()); 1561 int visualColumn = d->visualCursor.x(); 1562 if (visualColumn > right) 1563 visualColumn = right; 994 1564 Q_ASSERT(visualColumn != -1); 995 1565 … … 1002 1572 1003 1573 switch (cursorAction) { 1004 case MoveUp: 1574 case MoveUp: { 1575 int originalRow = visualRow; 1005 1576 #ifdef QT_KEYPAD_NAVIGATION 1006 1577 if (QApplication::keypadNavigationEnabled() && visualRow == 0) 1007 1578 visualRow = d->visualRow(model()->rowCount() - 1) + 1; 1579 // FIXME? visualRow = bottom + 1; 1008 1580 #endif 1009 --visualRow; 1010 while (visualRow > 0 && d->isVisualRowHiddenOrDisabled(visualRow, visualColumn)) 1581 int r = d->logicalRow(visualRow); 1582 int c = d->logicalColumn(visualColumn); 1583 if (r != -1 && d->hasSpans()) { 1584 QSpanCollection::Span span = d->span(r, c); 1585 if (span.width() > 1 || span.height() > 1) 1586 visualRow = d->visualRow(span.top()); 1587 } 1588 while (visualRow >= 0) { 1011 1589 --visualRow; 1590 r = d->logicalRow(visualRow); 1591 c = d->logicalColumn(visualColumn); 1592 if (r == -1 || (!isRowHidden(r) && d->isCellEnabled(r, c))) 1593 break; 1594 } 1595 if (visualRow < 0) 1596 visualRow = originalRow; 1597 break; 1598 } 1599 case MoveDown: { 1600 int originalRow = visualRow; 1012 1601 if (d->hasSpans()) { 1013 int row = d->logicalRow(visualRow); 1014 QTableViewPrivate::Span span = d->span(row, current.column()); 1015 visualRow = d->visualRow(span.top()); 1016 visualColumn = d->visualColumn(span.left()); 1017 } 1018 break; 1019 case MoveDown: 1020 if (d->hasSpans()) { 1021 QTableViewPrivate::Span span = d->span(current.row(), current.column()); 1602 QSpanCollection::Span span = d->span(current.row(), current.column()); 1022 1603 visualRow = d->visualRow(d->rowSpanEndLogical(span.top(), span.height())); 1023 1604 } … … 1026 1607 visualRow = -1; 1027 1608 #endif 1028 ++visualRow; 1029 while (visualRow < bottom && d->isVisualRowHiddenOrDisabled(visualRow, visualColumn)) 1609 int r = d->logicalRow(visualRow); 1610 int c = d->logicalColumn(visualColumn); 1611 if (r != -1 && d->hasSpans()) { 1612 QSpanCollection::Span span = d->span(r, c); 1613 if (span.width() > 1 || span.height() > 1) 1614 visualRow = d->visualRow(d->rowSpanEndLogical(span.top(), span.height())); 1615 } 1616 while (visualRow <= bottom) { 1030 1617 ++visualRow; 1031 if (d->hasSpans()) { 1032 int row = d->logicalRow(visualRow); 1033 QTableViewPrivate::Span span = d->span(row, current.column()); 1034 visualColumn = d->visualColumn(span.left()); 1035 } 1618 r = d->logicalRow(visualRow); 1619 c = d->logicalColumn(visualColumn); 1620 if (r == -1 || (!isRowHidden(r) && d->isCellEnabled(r, c))) 1621 break; 1622 } 1623 if (visualRow > bottom) 1624 visualRow = originalRow; 1036 1625 break; 1037 case MovePrevious: { 1038 int left = 0; 1039 while (d->isVisualColumnHiddenOrDisabled(visualRow, left) && left < right) 1040 ++left; 1041 if (visualColumn == left) { 1042 visualColumn = right; 1043 int top = 0; 1044 while (top < bottom && d->isVisualRowHiddenOrDisabled(top, visualColumn)) 1045 ++top; 1046 if (visualRow == top) 1626 } 1627 case MovePrevious: 1628 case MoveLeft: { 1629 int originalRow = visualRow; 1630 int originalColumn = visualColumn; 1631 bool firstTime = true; 1632 bool looped = false; 1633 bool wrapped = false; 1634 do { 1635 int r = d->logicalRow(visualRow); 1636 int c = d->logicalColumn(visualColumn); 1637 if (firstTime && c != -1 && d->hasSpans()) { 1638 firstTime = false; 1639 QSpanCollection::Span span = d->span(r, c); 1640 if (span.width() > 1 || span.height() > 1) 1641 visualColumn = d->visualColumn(span.left()); 1642 } 1643 while (visualColumn >= 0) { 1644 --visualColumn; 1645 r = d->logicalRow(visualRow); 1646 c = d->logicalColumn(visualColumn); 1647 if (r == -1 || c == -1 || (!isRowHidden(r) && !isColumnHidden(c) && d->isCellEnabled(r, c))) 1648 break; 1649 if (wrapped && (originalRow < visualRow || (originalRow == visualRow && originalColumn <= visualColumn))) { 1650 looped = true; 1651 break; 1652 } 1653 } 1654 if (cursorAction == MoveLeft || visualColumn >= 0) 1655 break; 1656 visualColumn = right + 1; 1657 if (visualRow == 0) { 1658 wrapped = true; 1047 1659 visualRow = bottom; 1048 else1660 } else { 1049 1661 --visualRow; 1050 while (visualRow > 0 && d->isVisualRowHiddenOrDisabled(visualRow, visualColumn)) 1051 --visualRow; 1052 break; 1053 } // else MoveLeft 1054 } 1055 case MoveLeft: 1056 --visualColumn; 1057 while (visualColumn > 0 && d->isVisualColumnHiddenOrDisabled(visualRow, visualColumn)) 1058 --visualColumn; 1059 if (d->hasSpans()) { 1060 int column = d->logicalColumn(visualColumn); 1061 QTableViewPrivate::Span span = d->span(current.row(), column); 1062 visualRow = d->visualRow(span.top()); 1063 visualColumn = d->visualColumn(span.left()); 1064 } 1662 } 1663 } while (!looped); 1664 if (visualColumn < 0) 1665 visualColumn = originalColumn; 1065 1666 break; 1667 } 1066 1668 case MoveNext: 1067 if (visualColumn == right) { 1068 visualColumn = 0; 1069 while (visualColumn < right && d->isVisualColumnHiddenOrDisabled(visualRow, visualColumn)) 1669 case MoveRight: { 1670 int originalRow = visualRow; 1671 int originalColumn = visualColumn; 1672 bool firstTime = true; 1673 bool looped = false; 1674 bool wrapped = false; 1675 do { 1676 int r = d->logicalRow(visualRow); 1677 int c = d->logicalColumn(visualColumn); 1678 if (firstTime && c != -1 && d->hasSpans()) { 1679 firstTime = false; 1680 QSpanCollection::Span span = d->span(r, c); 1681 if (span.width() > 1 || span.height() > 1) 1682 visualColumn = d->visualColumn(d->columnSpanEndLogical(span.left(), span.width())); 1683 } 1684 while (visualColumn <= right) { 1070 1685 ++visualColumn; 1071 if (visualRow == bottom) 1686 r = d->logicalRow(visualRow); 1687 c = d->logicalColumn(visualColumn); 1688 if (r == -1 || c == -1 || (!isRowHidden(r) && !isColumnHidden(c) && d->isCellEnabled(r, c))) 1689 break; 1690 if (wrapped && (originalRow > visualRow || (originalRow == visualRow && originalColumn >= visualColumn))) { 1691 looped = true; 1692 break; 1693 } 1694 } 1695 if (cursorAction == MoveRight || visualColumn <= right) 1696 break; 1697 visualColumn = -1; 1698 if (visualRow == bottom) { 1699 wrapped = true; 1072 1700 visualRow = 0; 1073 else1701 } else { 1074 1702 ++visualRow; 1075 while (visualRow < bottom && d->isVisualRowHiddenOrDisabled(visualRow, visualColumn)) 1076 ++visualRow; 1077 break; 1078 } // else MoveRight 1079 case MoveRight: 1080 if (d->hasSpans()) { 1081 QTableViewPrivate::Span span = d->span(current.row(), current.column()); 1082 visualColumn = d->visualColumn(d->columnSpanEndLogical(span.left(), span.width())); 1083 } 1084 ++visualColumn; 1085 while (visualColumn < right && d->isVisualColumnHiddenOrDisabled(visualRow, visualColumn)) 1086 ++visualColumn; 1087 if (d->hasSpans()) { 1088 int column = d->logicalColumn(visualColumn); 1089 QTableViewPrivate::Span span = d->span(current.row(), column); 1090 visualRow = d->visualRow(span.top()); 1091 } 1703 } 1704 } while (!looped); 1705 if (visualColumn > right) 1706 visualColumn = originalColumn; 1092 1707 break; 1708 } 1093 1709 case MoveHome: 1094 1710 visualColumn = 0; … … 1107 1723 break; 1108 1724 case MovePageUp: { 1109 int top = 0; 1110 while (top < bottom && d->isVisualRowHiddenOrDisabled(top, visualColumn)) 1111 ++top; 1112 int newRow = qMax(rowAt(visualRect(current).top() - d->viewport->height()), top); 1113 return d->model->index(qBound(0, newRow, bottom), current.column(), d->root); 1725 int newRow = rowAt(visualRect(current).top() - d->viewport->height()); 1726 if (newRow == -1) 1727 newRow = d->logicalRow(0); 1728 return d->model->index(newRow, current.column(), d->root); 1114 1729 } 1115 1730 case MovePageDown: { 1116 int newRow = qMin(rowAt(visualRect(current).bottom() + d->viewport->height()), bottom);1117 if (newRow < 0)1118 newRow = bottom;1119 return d->model->index( qBound(0, newRow, bottom), current.column(), d->root);1731 int newRow = rowAt(visualRect(current).bottom() + d->viewport->height()); 1732 if (newRow == -1) 1733 newRow = d->logicalRow(bottom); 1734 return d->model->index(newRow, current.column(), d->root); 1120 1735 }} 1121 1736 1737 d->visualCursor = QPoint(visualColumn, visualRow); 1122 1738 int logicalRow = d->logicalRow(visualRow); 1123 1739 int logicalColumn = d->logicalColumn(visualColumn); … … 1126 1742 1127 1743 QModelIndex result = d->model->index(logicalRow, logicalColumn, d->root); 1128 if (! isIndexHidden(result) && d->isIndexEnabled(result))1129 return d->model->index(logicalRow, logicalColumn, d->root);1744 if (!d->isRowHidden(logicalRow) && !d->isColumnHidden(logicalColumn) && d->isIndexEnabled(result)) 1745 return result; 1130 1746 1131 1747 return QModelIndex(); … … 1162 1778 do { 1163 1779 expanded = false; 1164 QList<QTableViewPrivate::Span>::const_iterator it; 1165 for (it = d->spans.constBegin(); it != d->spans.constEnd(); ++it) { 1166 QTableViewPrivate::Span span = *it; 1780 foreach (QSpanCollection::Span *it, d->spans.spans) { 1781 const QSpanCollection::Span &span = *it; 1167 1782 int t = d->visualRow(span.top()); 1168 1783 int l = d->visualColumn(span.left()); … … 1254 1869 bool horizontalMoved = horizontalHeader()->sectionsMoved(); 1255 1870 1256 if ((verticalMoved && horizontalMoved) || d->hasSpans()) {1871 if ((verticalMoved && horizontalMoved) || (d->hasSpans() && (verticalMoved || horizontalMoved))) { 1257 1872 for (int i = 0; i < selection.count(); ++i) { 1258 1873 QItemSelectionRange range = selection.at(i); … … 1297 1912 continue; 1298 1913 d->trimHiddenSelections(&range); 1299 QRect tl = visualRect(range.topLeft()); 1300 QRect br = visualRect(range.bottomRight()); 1301 selectionRegion += QRegion(tl|br); 1914 1915 const int rtop = rowViewportPosition(range.top()); 1916 const int rbottom = rowViewportPosition(range.bottom()) + rowHeight(range.bottom()); 1917 const int rleft = columnViewportPosition(range.left()); 1918 const int rright = columnViewportPosition(range.right()) + columnWidth(range.right()); 1919 selectionRegion += QRect(QPoint(rleft, rtop), QPoint(rright, rbottom)); 1920 if (d->hasSpans()) { 1921 foreach (QSpanCollection::Span *s, 1922 d->spans.spansInRect(range.left(), range.top(), range.width(), range.height())) { 1923 if (range.contains(s->top(), s->left(), range.parent())) 1924 selectionRegion += d->visualSpanRect(*s); 1925 } 1926 } 1302 1927 } 1303 1928 } … … 1429 2054 } 1430 2055 } 2056 columnsInViewport = qMax(columnsInViewport, 1); //there must be always at least 1 column 2057 1431 2058 if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) { 1432 2059 const int visibleColumns = columnCount - d->horizontalHeader->hiddenSectionCount(); … … 1455 2082 } 1456 2083 } 2084 rowsInViewport = qMax(rowsInViewport, 1); //there must be always at least 1 row 2085 1457 2086 if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) { 1458 2087 const int visibleRows = rowCount - d->verticalHeader->hiddenSectionCount(); … … 1492 2121 if (!model()) 1493 2122 return -1; 2123 2124 ensurePolished(); 1494 2125 1495 2126 int left = qMax(0, columnAt(0)); … … 1549 2180 if (!model()) 1550 2181 return -1; 2182 2183 ensurePolished(); 1551 2184 1552 2185 int top = qMax(0, rowAt(0)); … … 1727 2360 \brief whether sorting is enabled 1728 2361 1729 If this property is true, sorting is enabled for the table; if the 1730 property is false, sorting is not enabled. The default value is false. 2362 If this property is true, sorting is enabled for the table. If 2363 this property is false, sorting is not enabled. The default value 2364 is false. 2365 2366 \note. Setting the property to true with setSortingEnabled() 2367 immediately triggers a call to sortByColumn() with the current 2368 sort section and order. 1731 2369 1732 2370 \sa sortByColumn() 1733 2371 */ 1734 2372 2373 /*! 2374 If \a enabled true enables sorting for the table and immediately 2375 trigger a call to sortByColumn() with the current sort section and 2376 order 2377 */ 1735 2378 void QTableView::setSortingEnabled(bool enable) 1736 2379 { … … 1744 2387 this, SLOT(selectColumn(int))); 1745 2388 connect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), 1746 this, SLOT(sortByColumn(int)) );2389 this, SLOT(sortByColumn(int)), Qt::UniqueConnection); 1747 2390 sortByColumn(horizontalHeader()->sortIndicatorSection(), 1748 2391 horizontalHeader()->sortIndicatorOrder()); 1749 2392 } else { 1750 2393 connect(d->horizontalHeader, SIGNAL(sectionEntered(int)), 1751 this, SLOT(_q_selectColumn(int)) );2394 this, SLOT(_q_selectColumn(int)), Qt::UniqueConnection); 1752 2395 connect(horizontalHeader(), SIGNAL(sectionPressed(int)), 1753 this, SLOT(selectColumn(int)) );2396 this, SLOT(selectColumn(int)), Qt::UniqueConnection); 1754 2397 disconnect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), 1755 2398 this, SLOT(sortByColumn(int))); … … 1869 2512 { 1870 2513 Q_D(const QTableView); 1871 if (!d->isIndexValid(index) || index.parent() != d->root || isIndexHidden(index) ) 2514 if (!d->isIndexValid(index) || index.parent() != d->root 2515 || (!d->hasSpans() && isIndexHidden(index))) 1872 2516 return QRect(); 1873 2517 … … 1875 2519 1876 2520 if (d->hasSpans()) { 1877 Q TableViewPrivate::Span span = d->span(index.row(), index.column());2521 QSpanCollection::Span span = d->span(index.row(), index.column()); 1878 2522 return d->visualSpanRect(span); 1879 2523 } … … 1904 2548 return; 1905 2549 1906 Q TableViewPrivate::Span span;2550 QSpanCollection::Span span; 1907 2551 if (d->hasSpans()) 1908 2552 span = d->span(index.row(), index.column()); … … 1937 2581 int hiddenSections = 0; 1938 2582 if (d->horizontalHeader->sectionsHidden()) { 1939 for (int s = horizontalIndex ; s >= 0; --s) {2583 for (int s = horizontalIndex - 1; s >= 0; --s) { 1940 2584 int column = d->horizontalHeader->logicalIndex(s); 1941 2585 if (d->horizontalHeader->isSectionHidden(column)) … … 1992 2636 int hiddenSections = 0; 1993 2637 if (d->verticalHeader->sectionsHidden()) { 1994 for (int s = verticalIndex ; s >= 0; --s) {2638 for (int s = verticalIndex - 1; s >= 0; --s) { 1995 2639 int row = d->verticalHeader->logicalIndex(s); 1996 2640 if (d->verticalHeader->isSectionHidden(row)) … … 2011 2655 } 2012 2656 2013 d->setDirtyRegion(visualRect(index));2657 update(index); 2014 2658 } 2015 2659 … … 2059 2703 int viewportHeight = d->viewport->height(); 2060 2704 int viewportWidth = d->viewport->width(); 2061 if (d->hasSpans() && d->spansIntersectColumns(d->columnsToUpdate)) {2705 if (d->hasSpans()) { 2062 2706 rect = QRect(0, 0, viewportWidth, viewportHeight); 2063 2707 } else { … … 2084 2728 int viewportWidth = d->viewport->width(); 2085 2729 int top; 2086 if (d->hasSpans() && d->spansIntersectRows(d->rowsToUpdate)) {2730 if (d->hasSpans()) { 2087 2731 top = 0; 2088 2732 } else { … … 2115 2759 int logicalOldIndex = d->verticalHeader->logicalIndex(oldIndex); 2116 2760 int logicalNewIndex = d->verticalHeader->logicalIndex(newIndex); 2117 if (d->hasSpans() && (d->spansIntersectRow(logicalOldIndex) || d->spansIntersectRow(logicalNewIndex))) {2761 if (d->hasSpans()) { 2118 2762 d->viewport->update(); 2119 2763 } else { … … 2143 2787 int logicalOldIndex = d->horizontalHeader->logicalIndex(oldIndex); 2144 2788 int logicalNewIndex = d->horizontalHeader->logicalIndex(newIndex); 2145 if (d->hasSpans() && (d->spansIntersectColumn(logicalOldIndex) || d->spansIntersectColumn(logicalNewIndex))) {2789 if (d->hasSpans()) { 2146 2790 d->viewport->update(); 2147 2791 } else { … … 2326 2970 return true; 2327 2971 if (d->hasSpans()) { 2328 Q TableViewPrivate::Span span = d->span(index.row(), index.column());2972 QSpanCollection::Span span = d->span(index.row(), index.column()); 2329 2973 return !((span.top() == index.row()) && (span.left() == index.column())); 2330 2974 } … … 2417 3061 QItemSelectionModel::SelectionFlags command = q->selectionCommand(index); 2418 3062 selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate); 2419 if (( !(command & QItemSelectionModel::Current) && anchor)3063 if ((anchor && !(command & QItemSelectionModel::Current)) 2420 3064 || (q->selectionMode() == QTableView::SingleSelection)) 2421 3065 rowSectionAnchor = row; 3066 3067 if (q->selectionMode() != QTableView::SingleSelection 3068 && command.testFlag(QItemSelectionModel::Toggle)) { 3069 if (anchor) 3070 ctrlDragSelectionFlag = verticalHeader->selectionModel()->selectedRows().contains(index) 3071 ? QItemSelectionModel::Deselect : QItemSelectionModel::Select; 3072 command &= ~QItemSelectionModel::Toggle; 3073 command |= ctrlDragSelectionFlag; 3074 if (!anchor) 3075 command |= QItemSelectionModel::Current; 3076 } 3077 2422 3078 QModelIndex tl = model->index(qMin(rowSectionAnchor, row), 0, root); 2423 3079 QModelIndex br = model->index(qMax(rowSectionAnchor, row), model->columnCount(root) - 1, root); … … 2443 3099 QItemSelectionModel::SelectionFlags command = q->selectionCommand(index); 2444 3100 selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate); 2445 if (( !(command & QItemSelectionModel::Current) && anchor)3101 if ((anchor && !(command & QItemSelectionModel::Current)) 2446 3102 || (q->selectionMode() == QTableView::SingleSelection)) 2447 3103 columnSectionAnchor = column; 3104 3105 if (q->selectionMode() != QTableView::SingleSelection 3106 && command.testFlag(QItemSelectionModel::Toggle)) { 3107 if (anchor) 3108 ctrlDragSelectionFlag = horizontalHeader->selectionModel()->selectedColumns().contains(index) 3109 ? QItemSelectionModel::Deselect : QItemSelectionModel::Select; 3110 command &= ~QItemSelectionModel::Toggle; 3111 command |= ctrlDragSelectionFlag; 3112 if (!anchor) 3113 command |= QItemSelectionModel::Current; 3114 } 3115 2448 3116 QModelIndex tl = model->index(0, qMin(columnSectionAnchor, column), root); 2449 3117 QModelIndex br = model->index(model->rowCount(root) - 1, -
trunk/src/gui/itemviews/qtableview.h
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 ** … … 183 183 Q_PRIVATE_SLOT(d_func(), void _q_selectRow(int)) 184 184 Q_PRIVATE_SLOT(d_func(), void _q_selectColumn(int)) 185 Q_PRIVATE_SLOT(d_func(), void _q_updateSpanInsertedRows(QModelIndex,int,int)) 186 Q_PRIVATE_SLOT(d_func(), void _q_updateSpanInsertedColumns(QModelIndex,int,int)) 187 Q_PRIVATE_SLOT(d_func(), void _q_updateSpanRemovedRows(QModelIndex,int,int)) 188 Q_PRIVATE_SLOT(d_func(), void _q_updateSpanRemovedColumns(QModelIndex,int,int)) 185 189 }; 186 190 -
trunk/src/gui/itemviews/qtableview_p.h
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 ** … … 54 54 // 55 55 56 #include <QtCore/QList> 57 #include <QtCore/QLinkedList> 58 #include <QtCore/QMap> 59 #include <QtCore/QSet> 60 #include <QtCore/QDebug> 56 61 #include "private/qabstractitemview_p.h" 57 62 … … 59 64 60 65 QT_BEGIN_NAMESPACE 66 67 /** \internal 68 * 69 * This is a list of span with a binary index to look up quickly a span at a certain index. 70 * 71 * The index is a map of map. 72 * spans are mentaly divided into sub spans so that the start of any subspans doesn't overlap 73 * with any other subspans. There is no real representation of the subspans. 74 * The key of the first map is the row where the subspan starts, the value of the first map is 75 * a list (map) of all subspans that starts at the same row. It is indexed with its row 76 */ 77 class Q_AUTOTEST_EXPORT QSpanCollection 78 { 79 public: 80 struct Span 81 { 82 int m_top; 83 int m_left; 84 int m_bottom; 85 int m_right; 86 bool will_be_deleted; 87 Span() 88 : m_top(-1), m_left(-1), m_bottom(-1), m_right(-1), will_be_deleted(false) { } 89 Span(int row, int column, int rowCount, int columnCount) 90 : m_top(row), m_left(column), m_bottom(row+rowCount-1), m_right(column+columnCount-1), will_be_deleted(false) { } 91 inline int top() const { return m_top; } 92 inline int left() const { return m_left; } 93 inline int bottom() const { return m_bottom; } 94 inline int right() const { return m_right; } 95 inline int height() const { return m_bottom - m_top + 1; } 96 inline int width() const { return m_right - m_left + 1; } 97 }; 98 99 ~QSpanCollection() 100 { 101 qDeleteAll(spans); 102 } 103 104 void addSpan(Span *span); 105 void updateSpan(Span *span, int old_height); 106 Span *spanAt(int x, int y) const; 107 void clear(); 108 QList<Span *> spansInRect(int x, int y, int w, int h) const; 109 110 void updateInsertedRows(int start, int end); 111 void updateInsertedColumns(int start, int end); 112 void updateRemovedRows(int start, int end); 113 void updateRemovedColumns(int start, int end); 114 115 #ifdef QT_BUILD_INTERNAL 116 bool checkConsistency() const; 117 #endif 118 119 typedef QLinkedList<Span *> SpanList; 120 SpanList spans; //lists of all spans 121 private: 122 //the indexes are negative so the QMap::lowerBound do what i need. 123 typedef QMap<int, Span *> SubIndex; 124 typedef QMap<int, SubIndex> Index; 125 Index index; 126 127 bool cleanSpanSubIndex(SubIndex &subindex, int end, bool update = false); 128 }; 129 130 Q_DECLARE_TYPEINFO ( QSpanCollection::Span, Q_MOVABLE_TYPE); 131 61 132 62 133 class QTableViewPrivate : public QAbstractItemViewPrivate … … 69 140 columnResizeTimerID(0), rowResizeTimerID(0), 70 141 horizontalHeader(0), verticalHeader(0), 71 sortingEnabled(false), geometryRecursionBlock(false) 142 sortingEnabled(false), geometryRecursionBlock(false), 143 visualCursor(QPoint()) 72 144 { 73 145 wrapItemText = true; … … 99 171 int sectionSpanSize(const QHeaderView *header, int logical, int span) const; 100 172 bool spanContainsSection(const QHeaderView *header, int logical, int spanLogical, int span) const; 101 bool spansIntersectColumn(int column) const; 102 bool spansIntersectRow(int row) const; 103 bool spansIntersectColumns(const QList<int> &columns) const; 104 bool spansIntersectRows(const QList<int> &rows) const; 105 void drawAndClipSpans(const QRect &area, QPainter *painter, 173 void drawAndClipSpans(const QRegion &area, QPainter *painter, 106 174 const QStyleOptionViewItemV4 &option, QBitArray *drawn, 107 175 int firstVisualRow, int lastVisualRow, int firstVisualColumn, int lastVisualColumn); … … 121 189 bool sortingEnabled; 122 190 bool geometryRecursionBlock; 123 124 struct Span 125 { 126 int m_top; 127 int m_left; 128 int m_bottom; 129 int m_right; 130 Span() 131 : m_top(-1), m_left(-1), m_bottom(-1), m_right(-1) { } 132 Span(int row, int column, int rowCount, int columnCount) 133 : m_top(row), m_left(column), m_bottom(row+rowCount-1), m_right(column+columnCount-1) { } 134 inline int top() const { return m_top; } 135 inline int left() const { return m_left; } 136 inline int bottom() const { return m_bottom; } 137 inline int right() const { return m_right; } 138 inline int height() const { return m_bottom - m_top + 1; } 139 inline int width() const { return m_right - m_left + 1; } 140 }; 141 QList<Span> spans; 191 QPoint visualCursor; // (Row,column) cell coordinates to track through span navigation. 192 193 QSpanCollection spans; 142 194 143 195 void setSpan(int row, int column, int rowSpan, int columnSpan); 144 Span span(int row, int column) const;196 QSpanCollection::Span span(int row, int column) const; 145 197 inline int rowSpan(int row, int column) const { 146 198 return span(row, column).height(); … … 150 202 } 151 203 inline bool hasSpans() const { 152 return !spans.isEmpty(); 153 } 154 inline bool spanContainsRow(int row, int spanRow, int span) const { 155 return spanContainsSection(verticalHeader, row, spanRow, span); 156 } 157 inline bool spanContainsColumn(int column, int spanColumn, int span) const { 158 return spanContainsSection(horizontalHeader, column, spanColumn, span); 159 } 160 inline bool isInSpan(int row, int column, const Span &span) const { 161 return spanContainsRow(row, span.top(), span.height()) 162 && spanContainsColumn(column, span.left(), span.width()); 204 return !spans.spans.isEmpty(); 163 205 } 164 206 inline int rowSpanHeight(int row, int span) const { … … 195 237 } 196 238 197 QRect visualSpanRect(const Span &span) const;239 QRect visualSpanRect(const QSpanCollection::Span &span) const; 198 240 199 241 void _q_selectRow(int row); … … 202 244 void selectRow(int row, bool anchor); 203 245 void selectColumn(int column, bool anchor); 246 247 void _q_updateSpanInsertedRows(const QModelIndex &parent, int start, int end); 248 void _q_updateSpanInsertedColumns(const QModelIndex &parent, int start, int end); 249 void _q_updateSpanRemovedRows(const QModelIndex &parent, int start, int end); 250 void _q_updateSpanRemovedColumns(const QModelIndex &parent, int start, int end); 204 251 }; 205 252 -
trunk/src/gui/itemviews/qtablewidget.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 ** … … 227 227 itm->d->id = -1; 228 228 tableItems[i] = 0; 229 QModelIndex ind = index(itm); 230 emit dataChanged(ind, ind); 229 231 } 230 232 return itm; … … 531 533 } 532 534 533 bool QTableModel::canConvertToDouble(const QVariant &value)534 {535 switch (value.type()) {536 case QVariant::Bool:537 case QVariant::Int:538 case QVariant::UInt:539 case QVariant::LongLong:540 case QVariant::ULongLong:541 case QVariant::Double:542 case QVariant::Char:543 return true;544 default:545 return false;546 }547 return false;548 }549 550 551 535 /* 552 536 \internal … … 588 572 vit = sortedInsertionIterator(vit, colItems.end(), order, item); 589 573 int newRow = qMax((int)(vit - colItems.begin()), 0); 574 if ((newRow < oldRow) && !(*item < *colItems.at(oldRow - 1)) && !(*colItems.at(oldRow - 1) < *item)) 575 newRow = oldRow; 590 576 vit = colItems.insert(vit, item); 591 577 if (newRow != oldRow) { … … 1411 1397 { 1412 1398 const QVariant v1 = data(Qt::DisplayRole), v2 = other.data(Qt::DisplayRole); 1413 if (QTableModel::canConvertToDouble(v1) && QTableModel::canConvertToDouble(v2)) 1414 return v1.toDouble() < v2.toDouble(); 1415 return v1.toString() < v2.toString(); 1399 return QAbstractItemModelPrivate::variantLessThan(v1, v2); 1416 1400 } 1417 1401 … … 1507 1491 1508 1492 \ingroup model-view 1509 \mainclass 1493 1510 1494 1511 1495 Table widgets provide standard table display facilities for applications. … … 1589 1573 QObject::connect(q, SIGNAL(entered(QModelIndex)), q, SLOT(_q_emitItemEntered(QModelIndex))); 1590 1574 // model signals 1591 QObject::connect(model (), SIGNAL(dataChanged(QModelIndex,QModelIndex)),1575 QObject::connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), 1592 1576 q, SLOT(_q_emitItemChanged(QModelIndex))); 1593 1577 // selection signals … … 1597 1581 q, SIGNAL(itemSelectionChanged())); 1598 1582 // sorting 1599 QObject::connect(model (), SIGNAL(dataChanged(QModelIndex,QModelIndex)),1583 QObject::connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), 1600 1584 q, SLOT(_q_dataChanged(QModelIndex,QModelIndex))); 1601 QObject::connect(model (), SIGNAL(columnsRemoved(QModelIndex,int,int)), q, SLOT(_q_sort()));1585 QObject::connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)), q, SLOT(_q_sort())); 1602 1586 } 1603 1587 … … 1605 1589 { 1606 1590 Q_Q(QTableWidget); 1607 if (QTableWidgetItem *item = model()->item(index))1591 if (QTableWidgetItem *item = tableModel()->item(index)) 1608 1592 emit q->itemPressed(item); 1609 1593 emit q->cellPressed(index.row(), index.column()); … … 1613 1597 { 1614 1598 Q_Q(QTableWidget); 1615 if (QTableWidgetItem *item = model()->item(index))1599 if (QTableWidgetItem *item = tableModel()->item(index)) 1616 1600 emit q->itemClicked(item); 1617 1601 emit q->cellClicked(index.row(), index.column()); … … 1621 1605 { 1622 1606 Q_Q(QTableWidget); 1623 if (QTableWidgetItem *item = model()->item(index))1607 if (QTableWidgetItem *item = tableModel()->item(index)) 1624 1608 emit q->itemDoubleClicked(item); 1625 1609 emit q->cellDoubleClicked(index.row(), index.column()); … … 1629 1613 { 1630 1614 Q_Q(QTableWidget); 1631 if (QTableWidgetItem *item = model()->item(index))1615 if (QTableWidgetItem *item = tableModel()->item(index)) 1632 1616 emit q->itemActivated(item); 1633 1617 emit q->cellActivated(index.row(), index.column()); … … 1637 1621 { 1638 1622 Q_Q(QTableWidget); 1639 if (QTableWidgetItem *item = model()->item(index))1623 if (QTableWidgetItem *item = tableModel()->item(index)) 1640 1624 emit q->itemEntered(item); 1641 1625 emit q->cellEntered(index.row(), index.column()); … … 1645 1629 { 1646 1630 Q_Q(QTableWidget); 1647 if (QTableWidgetItem *item = model()->item(index))1631 if (QTableWidgetItem *item = tableModel()->item(index)) 1648 1632 emit q->itemChanged(item); 1649 1633 emit q->cellChanged(index.row(), index.column()); … … 1654 1638 { 1655 1639 Q_Q(QTableWidget); 1656 QTableWidgetItem *currentItem = model()->item(current);1657 QTableWidgetItem *previousItem = model()->item(previous);1640 QTableWidgetItem *currentItem = tableModel()->item(current); 1641 QTableWidgetItem *previousItem = tableModel()->item(previous); 1658 1642 if (currentItem || previousItem) 1659 1643 emit q->currentItemChanged(currentItem, previousItem); … … 1663 1647 void QTableWidgetPrivate::_q_sort() 1664 1648 { 1665 Q_Q(QTableWidget);1666 1649 if (sortingEnabled) { 1667 int column = q->horizontalHeader()->sortIndicatorSection();1668 Qt::SortOrder order = q->horizontalHeader()->sortIndicatorOrder();1669 model ()->sort(column, order);1650 int column = horizontalHeader->sortIndicatorSection(); 1651 Qt::SortOrder order = horizontalHeader->sortIndicatorOrder(); 1652 model->sort(column, order); 1670 1653 } 1671 1654 } … … 1674 1657 const QModelIndex &bottomRight) 1675 1658 { 1676 Q_Q(QTableWidget);1677 1659 if (sortingEnabled && topLeft.isValid() && bottomRight.isValid()) { 1678 int column = q->horizontalHeader()->sortIndicatorSection();1660 int column = horizontalHeader->sortIndicatorSection(); 1679 1661 if (column >= topLeft.column() && column <= bottomRight.column()) { 1680 Qt::SortOrder order = q->horizontalHeader()->sortIndicatorOrder();1681 model()->ensureSorted(column, order, topLeft.row(), bottomRight.row());1662 Qt::SortOrder order = horizontalHeader->sortIndicatorOrder(); 1663 tableModel()->ensureSorted(column, order, topLeft.row(), bottomRight.row()); 1682 1664 } 1683 1665 } … … 1740 1722 This signal is emitted whenever the selection changes. 1741 1723 1742 \sa selectedItems() isItemSelected()1724 \sa selectedItems() QTableWidgetItem::isSelected() 1743 1725 */ 1744 1726 … … 1883 1865 { 1884 1866 Q_D(QTableWidget); 1885 d-> model()->setRowCount(rows);1867 d->tableModel()->setRowCount(rows); 1886 1868 } 1887 1869 … … 1893 1875 { 1894 1876 Q_D(const QTableWidget); 1895 return d->model ()->rowCount();1877 return d->model->rowCount(); 1896 1878 } 1897 1879 … … 1906 1888 { 1907 1889 Q_D(QTableWidget); 1908 d-> model()->setColumnCount(columns);1890 d->tableModel()->setColumnCount(columns); 1909 1891 } 1910 1892 … … 1916 1898 { 1917 1899 Q_D(const QTableWidget); 1918 return d->model ()->columnCount();1900 return d->model->columnCount(); 1919 1901 } 1920 1902 … … 1925 1907 { 1926 1908 Q_D(const QTableWidget); 1927 return d-> model()->index(item).row();1909 return d->tableModel()->index(item).row(); 1928 1910 } 1929 1911 … … 1934 1916 { 1935 1917 Q_D(const QTableWidget); 1936 return d-> model()->index(item).column();1918 return d->tableModel()->index(item).column(); 1937 1919 } 1938 1920 … … 1947 1929 { 1948 1930 Q_D(const QTableWidget); 1949 return d-> model()->item(row, column);1931 return d->tableModel()->item(row, column); 1950 1932 } 1951 1933 … … 1976 1958 } else { 1977 1959 item->view = this; 1978 d-> model()->setItem(row, column, item);1960 d->tableModel()->setItem(row, column, item); 1979 1961 } 1980 1962 } else { … … 1989 1971 { 1990 1972 Q_D(QTableWidget); 1991 QTableWidgetItem *item = d-> model()->takeItem(row, column);1973 QTableWidgetItem *item = d->tableModel()->takeItem(row, column); 1992 1974 if (item) 1993 1975 item->view = 0; … … 2001 1983 { 2002 1984 Q_D(const QTableWidget); 2003 return d-> model()->verticalHeaderItem(row);1985 return d->tableModel()->verticalHeaderItem(row); 2004 1986 } 2005 1987 … … 2012 1994 if (item) { 2013 1995 item->view = this; 2014 d-> model()->setVerticalHeaderItem(row, item);1996 d->tableModel()->setVerticalHeaderItem(row, item); 2015 1997 } else { 2016 1998 delete takeVerticalHeaderItem(row); … … 2025 2007 { 2026 2008 Q_D(QTableWidget); 2027 QTableWidgetItem *itm = d-> model()->takeVerticalHeaderItem(row);2009 QTableWidgetItem *itm = d->tableModel()->takeVerticalHeaderItem(row); 2028 2010 if (itm) 2029 2011 itm->view = 0; … … 2038 2020 { 2039 2021 Q_D(const QTableWidget); 2040 return d-> model()->horizontalHeaderItem(column);2022 return d->tableModel()->horizontalHeaderItem(column); 2041 2023 } 2042 2024 … … 2049 2031 if (item) { 2050 2032 item->view = this; 2051 d-> model()->setHorizontalHeaderItem(column, item);2033 d->tableModel()->setHorizontalHeaderItem(column, item); 2052 2034 } else { 2053 2035 delete takeHorizontalHeaderItem(column); … … 2062 2044 { 2063 2045 Q_D(QTableWidget); 2064 QTableWidgetItem *itm = d-> model()->takeHorizontalHeaderItem(column);2046 QTableWidgetItem *itm = d->tableModel()->takeHorizontalHeaderItem(column); 2065 2047 if (itm) 2066 2048 itm->view = 0; … … 2074 2056 { 2075 2057 Q_D(QTableWidget); 2076 QTableModel *model = d-> model();2058 QTableModel *model = d->tableModel(); 2077 2059 QTableWidgetItem *item = 0; 2078 2060 for (int i = 0; i < model->rowCount() && i < labels.count(); ++i) { … … 2092 2074 { 2093 2075 Q_D(QTableWidget); 2094 QTableModel *model = d-> model();2076 QTableModel *model = d->tableModel(); 2095 2077 QTableWidgetItem *item = 0; 2096 2078 for (int i = 0; i < model->columnCount() && i < labels.count(); ++i) { … … 2132 2114 { 2133 2115 Q_D(const QTableWidget); 2134 return d-> model()->item(currentIndex());2116 return d->tableModel()->item(currentIndex()); 2135 2117 } 2136 2118 … … 2138 2120 Sets the current item to \a item. 2139 2121 2140 Depending on the current \l{QAbstractItemView::SelectionMode}{selection mode},2141 the item mayalso be selected.2122 Unless the selection mode is \l{QAbstractItemView::}{NoSelection}, 2123 the item is also be selected. 2142 2124 2143 2125 \sa currentItem(), setCurrentCell() … … 2146 2128 { 2147 2129 Q_D(QTableWidget); 2148 setCurrentIndex(d-> model()->index(item));2130 setCurrentIndex(d->tableModel()->index(item)); 2149 2131 } 2150 2132 … … 2159 2141 { 2160 2142 Q_D(QTableWidget); 2161 d->selectionModel->setCurrentIndex(d-> model()->index(item), command);2143 d->selectionModel->setCurrentIndex(d->tableModel()->index(item), command); 2162 2144 } 2163 2145 … … 2198 2180 { 2199 2181 Q_D(QTableWidget); 2200 d->model ()->sort(column, order);2182 d->model->sort(column, order); 2201 2183 horizontalHeader()->setSortIndicator(column, order); 2202 2184 } … … 2227 2209 if (!item) 2228 2210 return; 2229 edit(d-> model()->index(item));2211 edit(d->tableModel()->index(item)); 2230 2212 } 2231 2213 … … 2240 2222 if (!item) 2241 2223 return; 2242 QModelIndex index = d-> model()->index(item);2224 QModelIndex index = d->tableModel()->index(item); 2243 2225 QAbstractItemView::openPersistentEditor(index); 2244 2226 } … … 2254 2236 if (!item) 2255 2237 return; 2256 QModelIndex index = d-> model()->index(item);2238 QModelIndex index = d->tableModel()->index(item); 2257 2239 QAbstractItemView::closePersistentEditor(index); 2258 2240 } … … 2304 2286 { 2305 2287 Q_D(const QTableWidget); 2306 QModelIndex index = d-> model()->index(item);2288 QModelIndex index = d->tableModel()->index(item); 2307 2289 return selectionModel()->isSelected(index); 2308 2290 } … … 2318 2300 { 2319 2301 Q_D(QTableWidget); 2320 QModelIndex index = d-> model()->index(item);2302 QModelIndex index = d->tableModel()->index(item); 2321 2303 selectionModel()->select(index, select ? QItemSelectionModel::Select : QItemSelectionModel::Deselect); 2322 2304 } … … 2375 2357 if (isIndexHidden(index)) 2376 2358 continue; 2377 QTableWidgetItem *item = d-> model()->item(index);2359 QTableWidgetItem *item = d->tableModel()->item(index); 2378 2360 if (item) 2379 2361 items.append(item); … … 2391 2373 QModelIndexList indexes; 2392 2374 for (int column = 0; column < columnCount(); ++column) 2393 indexes += d->model ()->match(model()->index(0, column, QModelIndex()),2375 indexes += d->model->match(model()->index(0, column, QModelIndex()), 2394 2376 Qt::DisplayRole, text, -1, flags); 2395 2377 QList<QTableWidgetItem*> items; 2396 2378 for (int i = 0; i < indexes.size(); ++i) 2397 items.append(d-> model()->item(indexes.at(i)));2379 items.append(d->tableModel()->item(indexes.at(i))); 2398 2380 return items; 2399 2381 } … … 2429 2411 { 2430 2412 Q_D(const QTableWidget); 2431 return d-> model()->item(indexAt(p));2413 return d->tableModel()->item(indexAt(p)); 2432 2414 } 2433 2415 … … 2440 2422 if (!item) 2441 2423 return QRect(); 2442 QModelIndex index = d-> model()->index(const_cast<QTableWidgetItem*>(item));2424 QModelIndex index = d->tableModel()->index(const_cast<QTableWidgetItem*>(item)); 2443 2425 Q_ASSERT(index.isValid()); 2444 2426 return visualRect(index); … … 2456 2438 if (!item) 2457 2439 return; 2458 QModelIndex index = d-> model()->index(const_cast<QTableWidgetItem*>(item));2440 QModelIndex index = d->tableModel()->index(const_cast<QTableWidgetItem*>(item)); 2459 2441 Q_ASSERT(index.isValid()); 2460 2442 QTableView::scrollTo(index, hint); … … 2469 2451 { 2470 2452 Q_D(const QTableWidget); 2471 return d-> model()->itemPrototype();2453 return d->tableModel()->itemPrototype(); 2472 2454 } 2473 2455 … … 2477 2459 The table widget will use the item prototype clone function when it needs 2478 2460 to create a new table item. For example when the user is editing 2479 editingin an empty cell. This is useful when you have a QTableWidgetItem2461 in an empty cell. This is useful when you have a QTableWidgetItem 2480 2462 subclass and want to make sure that QTableWidget creates instances of 2481 2463 your subclass. … … 2488 2470 { 2489 2471 Q_D(QTableWidget); 2490 d-> model()->setItemPrototype(item);2472 d->tableModel()->setItemPrototype(item); 2491 2473 } 2492 2474 … … 2497 2479 { 2498 2480 Q_D(QTableWidget); 2499 d-> model()->insertRows(row);2481 d->tableModel()->insertRows(row); 2500 2482 } 2501 2483 … … 2506 2488 { 2507 2489 Q_D(QTableWidget); 2508 d-> model()->insertColumns(column);2490 d->tableModel()->insertColumns(column); 2509 2491 } 2510 2492 … … 2515 2497 { 2516 2498 Q_D(QTableWidget); 2517 d-> model()->removeRows(row);2499 d->tableModel()->removeRows(row); 2518 2500 } 2519 2501 … … 2524 2506 { 2525 2507 Q_D(QTableWidget); 2526 d-> model()->removeColumns(column);2508 d->tableModel()->removeColumns(column); 2527 2509 } 2528 2510 … … 2537 2519 Q_D(QTableWidget); 2538 2520 selectionModel()->clear(); 2539 d-> model()->clear();2521 d->tableModel()->clear(); 2540 2522 } 2541 2523 … … 2551 2533 Q_D(QTableWidget); 2552 2534 selectionModel()->clear(); 2553 d-> model()->clearContents();2535 d->tableModel()->clearContents(); 2554 2536 } 2555 2537 … … 2562 2544 QStringList QTableWidget::mimeTypes() const 2563 2545 { 2564 return d_func()-> model()->QAbstractTableModel::mimeTypes();2546 return d_func()->tableModel()->QAbstractTableModel::mimeTypes(); 2565 2547 } 2566 2548 … … 2575 2557 QMimeData *QTableWidget::mimeData(const QList<QTableWidgetItem*>) const 2576 2558 { 2577 return d_func()-> model()->internalMimeData();2559 return d_func()->tableModel()->internalMimeData(); 2578 2560 } 2579 2561 … … 2597 2579 } 2598 2580 #endif 2599 return d_func()-> model()->QAbstractTableModel::dropMimeData(data, action , row, column, idx);2581 return d_func()->tableModel()->QAbstractTableModel::dropMimeData(data, action , row, column, idx); 2600 2582 } 2601 2583 … … 2607 2589 Qt::DropActions QTableWidget::supportedDropActions() const 2608 2590 { 2609 return d_func()-> model()->QAbstractTableModel::supportedDropActions() | Qt::MoveAction;2591 return d_func()->tableModel()->QAbstractTableModel::supportedDropActions() | Qt::MoveAction; 2610 2592 } 2611 2593 … … 2631 2613 { 2632 2614 Q_D(const QTableWidget); 2633 return d-> model()->index(item);2615 return d->tableModel()->index(item); 2634 2616 } 2635 2617 … … 2641 2623 { 2642 2624 Q_D(const QTableWidget); 2643 return d-> model()->item(index);2625 return d->tableModel()->item(index); 2644 2626 } 2645 2627 -
trunk/src/gui/itemviews/qtablewidget.h
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 ** -
trunk/src/gui/itemviews/qtablewidget_p.h
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 ** … … 145 145 static bool itemGreaterThan(const QPair<QTableWidgetItem*,int> &left, 146 146 const QPair<QTableWidgetItem*,int> &right); 147 static bool canConvertToDouble(const QVariant &value);148 147 149 148 void ensureSorted(int column, Qt::SortOrder order, int start, int end); … … 191 190 public: 192 191 QTableWidgetPrivate() : QTableViewPrivate() {} 193 inline QTableModel * model() const { return qobject_cast<QTableModel*>(q_func()->model()); }192 inline QTableModel *tableModel() const { return qobject_cast<QTableModel*>(model); } 194 193 void setup(); 195 194 -
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 -
trunk/src/gui/itemviews/qtreeview.h
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 ** … … 145 145 void sortByColumn(int column, Qt::SortOrder order); 146 146 147 void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); 148 void selectAll(); 149 147 150 Q_SIGNALS: 148 151 void expanded(const QModelIndex &index); … … 150 153 151 154 public Q_SLOTS: 152 void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);153 155 void hideColumn(int column); 154 156 void showColumn(int column); … … 157 159 void resizeColumnToContents(int column); 158 160 void sortByColumn(int column); 159 void selectAll();160 161 void expandAll(); 161 162 void collapseAll(); … … 223 224 Q_DECLARE_PRIVATE(QTreeView) 224 225 Q_DISABLE_COPY(QTreeView) 226 #ifndef QT_NO_ANIMATION 225 227 Q_PRIVATE_SLOT(d_func(), void _q_endAnimatedOperation()) 226 Q_PRIVATE_SLOT(d_func(), void _q_animate()) 227 Q_PRIVATE_SLOT(d_func(), void _q_currentChanged(const QModelIndex&, const QModelIndex &)) 228 Q_PRIVATE_SLOT(d_func(), void _q_columnsAboutToBeRemoved(const QModelIndex &, int, int)) 229 Q_PRIVATE_SLOT(d_func(), void _q_columnsRemoved(const QModelIndex &, int, int)) 228 #endif //QT_NO_ANIMATION 230 229 Q_PRIVATE_SLOT(d_func(), void _q_modelAboutToBeReset()) 231 230 Q_PRIVATE_SLOT(d_func(), void _q_sortIndicatorChanged(int column, Qt::SortOrder order)) 232 Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed())233 231 }; 234 232 -
trunk/src/gui/itemviews/qtreeview_p.h
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 ** … … 55 55 56 56 #include "private/qabstractitemview_p.h" 57 #include <QtCore/qvariantanimation.h> 57 58 58 59 #ifndef QT_NO_TREEVIEW … … 62 63 struct QTreeViewItem 63 64 { 64 QTreeViewItem() : expanded(false), spanning(false), total(0), level(0), height(0) {} 65 QTreeViewItem() : expanded(false), spanning(false), hasChildren(false), 66 hasMoreSiblings(false), total(0), level(0), height(0) {} 65 67 QModelIndex index; // we remove items whenever the indexes are invalidated 66 68 uint expanded : 1; 67 69 uint spanning : 1; 68 uint total : 30; // total number of children visible 70 uint hasChildren : 1; // if the item has visible children (even if collapsed) 71 uint hasMoreSiblings : 1; 72 uint total : 28; // total number of children visible 69 73 uint level : 16; // indentation 70 74 int height : 16; // row height … … 82 86 itemsExpandable(true), sortingEnabled(false), 83 87 expandsOnDoubleClick(true), 84 allColumnsShowFocus(false), 88 allColumnsShowFocus(false), current(0), spanning(false), 85 89 animationsEnabled(false), columnResizeTimerID(0), 86 90 autoExpandDelay(-1), hoverBranch(-1), geometryRecursionBlock(false) {} … … 89 93 void initialize(); 90 94 91 struct AnimatedOperation 95 QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const; 96 97 #ifndef QT_NO_ANIMATION 98 struct AnimatedOperation : public QVariantAnimation 92 99 { 93 enum Type { Expand, Collapse };94 100 int item; 95 int top;96 int duration;97 Type type;98 101 QPixmap before; 99 102 QPixmap after; 100 }; 103 QWidget *viewport; 104 AnimatedOperation() : item(0) { setEasingCurve(QEasingCurve::InOutQuad); } 105 int top() const { return startValue().toInt(); } 106 QRect rect() const { QRect rect = viewport->rect(); rect.moveTop(top()); return rect; } 107 void updateCurrentValue(const QVariant &) { viewport->update(rect()); } 108 void updateState(State state, State) { if (state == Stopped) before = after = QPixmap(); } 109 } animatedOperation; 110 void prepareAnimatedOperation(int item, QVariantAnimation::Direction d); 111 void beginAnimatedOperation(); 112 void drawAnimatedOperation(QPainter *painter) const; 113 QPixmap renderTreeToPixmapForAnimation(const QRect &rect) const; 114 void _q_endAnimatedOperation(); 115 #endif //QT_NO_ANIMATION 101 116 102 117 void expand(int item, bool emitSignal); 103 118 void collapse(int item, bool emitSignal); 104 119 105 void prepareAnimatedOperation(int item, AnimatedOperation::Type type);106 void beginAnimatedOperation();107 void _q_endAnimatedOperation();108 void drawAnimatedOperation(QPainter *painter) const;109 QPixmap renderTreeToPixmapForAnimation(const QRect &rect) const;110 111 inline QRect animationRect() const112 { return QRect(0, animatedOperation.top, viewport->width(),113 viewport->height() - animatedOperation.top); }114 115 void _q_currentChanged(const QModelIndex&, const QModelIndex&);116 120 void _q_columnsAboutToBeRemoved(const QModelIndex &, int, int); 117 121 void _q_columnsRemoved(const QModelIndex &, int, int); 118 122 void _q_modelAboutToBeReset(); 119 void _q_animate();120 123 void _q_sortIndicatorChanged(int column, Qt::SortOrder order); 121 124 void _q_modelDestroyed(); … … 178 181 // used when expanding and collapsing items 179 182 QSet<QPersistentModelIndex> expandedIndexes; 180 QStack<bool> expandParent;181 AnimatedOperation animatedOperation;182 183 bool animationsEnabled; 183 184 -
trunk/src/gui/itemviews/qtreewidget.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 ** … … 76 76 77 77 \ingroup model-view 78 \mainclass 78 79 79 */ 80 80 … … 578 578 return; 579 579 580 //layoutAboutToBeChanged and layoutChanged will be called by sortChildren 580 //layoutAboutToBeChanged and layoutChanged will be called by sortChildren 581 581 rootItem->sortChildren(column, order, true); 582 582 } … … 623 623 lit = sortedInsertionIterator(lit, lst.end(), order, item); 624 624 int newRow = qMax(lit - lst.begin(), 0); 625 626 if ((newRow < oldRow) && !(*item < *lst.at(oldRow - 1)) && !(*lst.at(oldRow - 1) < *item )) 627 newRow = oldRow; 628 625 629 lit = lst.insert(lit, item); 626 630 if (newRow != oldRow) { … … 854 858 for (int c = 0; c < colCount; ++c) { 855 859 QModelIndex from = createIndex(oldRow, c, item); 856 if (static_cast<QAbstractItemModelPrivate *>(d_ptr )->persistent.indexes.contains(from)) {860 if (static_cast<QAbstractItemModelPrivate *>(d_ptr.data())->persistent.indexes.contains(from)) { 857 861 QModelIndex to = createIndex(r, c, item); 858 862 fromList << from; … … 1577 1581 return; 1578 1582 1579 view-> viewport()->update( view->d_func()->itemDecorationRect(view->d_func()->index(this)));1583 view->scheduleDelayedItemsLayout(); 1580 1584 } 1581 1585 … … 1769 1773 if (children.count() && (itemFlags & Qt::ItemIsTristate)) 1770 1774 return childrenCheckState(column); 1775 // fallthrough intended 1771 1776 default: 1772 1777 if (column >= 0 && column < values.size()) { … … 1788 1793 { 1789 1794 int column = view ? view->sortColumn() : 0; 1790 return text(column) < other.text(column); 1795 const QVariant v1 = data(column, Qt::DisplayRole); 1796 const QVariant v2 = other.data(column, Qt::DisplayRole); 1797 return QAbstractItemModelPrivate::variantLessThan(v1, v2); 1791 1798 } 1792 1799 … … 1828 1835 out << values << d->display; 1829 1836 } 1837 #endif // QT_NO_DATASTREAM 1830 1838 1831 1839 /*! … … 1863 1871 return *this; 1864 1872 } 1865 1866 #endif // QT_NO_DATASTREAM1867 1873 1868 1874 /*! … … 2072 2078 { 2073 2079 QTreeModel *model = (q->view ? qobject_cast<QTreeModel*>(q->view->model()) : 0); 2080 if (!model) 2081 return; 2074 2082 model->sortItems(&q->children, column, order); 2075 2083 if (climb) { 2076 2084 QList<QTreeWidgetItem*>::iterator it = q->children.begin(); 2077 2085 for (; it != q->children.end(); ++it) { 2078 //here we call the private object's method to avoid emitting 2086 //here we call the private object's method to avoid emitting 2079 2087 //the layoutAboutToBeChanged and layoutChanged signals 2080 2088 (*it)->d->sortChildren(column, order, climb); … … 2278 2286 void QTreeWidgetPrivate::_q_sort() 2279 2287 { 2280 Q_Q(QTreeWidget);2281 2288 if (sortingEnabled) { 2282 int column = q->header()->sortIndicatorSection();2283 Qt::SortOrder order = q->header()->sortIndicatorOrder();2284 model()->sort(column, order);2289 int column = header->sortIndicatorSection(); 2290 Qt::SortOrder order = header->sortIndicatorOrder(); 2291 treeModel()->sort(column, order); 2285 2292 } 2286 2293 } … … 2291 2298 QModelIndexList indices = selected.indexes(); 2292 2299 int i; 2293 QTreeModel *m = model();2300 QTreeModel *m = treeModel(); 2294 2301 for (i = 0; i < indices.count(); ++i) { 2295 2302 QTreeWidgetItem *item = m->item(indices.at(i)); … … 2309 2316 const QModelIndex &bottomRight) 2310 2317 { 2311 Q_Q(QTreeWidget);2312 2318 if (sortingEnabled && topLeft.isValid() && bottomRight.isValid() 2313 && ! model()->sortPendingTimer.isActive()) {2314 int column = q->header()->sortIndicatorSection();2319 && !treeModel()->sortPendingTimer.isActive()) { 2320 int column = header->sortIndicatorSection(); 2315 2321 if (column >= topLeft.column() && column <= bottomRight.column()) { 2316 Qt::SortOrder order = q->header()->sortIndicatorOrder();2317 model()->ensureSorted(column, order, topLeft.row(),2322 Qt::SortOrder order = header->sortIndicatorOrder(); 2323 treeModel()->ensureSorted(column, order, topLeft.row(), 2318 2324 bottomRight.row(), topLeft.parent()); 2319 2325 } … … 2328 2334 2329 2335 \ingroup model-view 2330 \mainclass 2336 2331 2337 2332 2338 The QTreeWidget class is a convenience class that provides a standard … … 2437 2443 expandAll() is invoked. 2438 2444 2439 \sa isItemExpanded(), itemCollapsed(), expandItem()2445 \sa QTreeWidgetItem::isExpanded(), itemCollapsed(), expandItem() 2440 2446 */ 2441 2447 … … 2449 2455 collapseAll() is invoked. 2450 2456 2451 \sa isItemExpanded(), itemExpanded(), collapseItem()2457 \sa QTreeWidgetItem::isExpanded(), itemExpanded(), collapseItem() 2452 2458 */ 2453 2459 … … 2543 2549 { 2544 2550 Q_D(const QTreeWidget); 2545 return d->model ()->columnCount();2551 return d->model->columnCount(); 2546 2552 } 2547 2553 … … 2555 2561 if (columns < 0) 2556 2562 return; 2557 d-> model()->setColumnCount(columns);2563 d->treeModel()->setColumnCount(columns); 2558 2564 } 2559 2565 … … 2572 2578 { 2573 2579 Q_D(const QTreeWidget); 2574 return d-> model()->rootItem;2580 return d->treeModel()->rootItem; 2575 2581 } 2576 2582 … … 2585 2591 { 2586 2592 Q_D(const QTreeWidget); 2587 return d-> model()->rootItem->child(index);2593 return d->treeModel()->rootItem->child(index); 2588 2594 } 2589 2595 … … 2600 2606 { 2601 2607 Q_D(const QTreeWidget); 2602 return d-> model()->rootItem->childCount();2608 return d->treeModel()->rootItem->childCount(); 2603 2609 } 2604 2610 … … 2614 2620 { 2615 2621 Q_D(QTreeWidget); 2616 d-> model()->rootItem->insertChild(index, item);2622 d->treeModel()->rootItem->insertChild(index, item); 2617 2623 } 2618 2624 … … 2639 2645 { 2640 2646 Q_D(QTreeWidget); 2641 return d-> model()->rootItem->takeChild(index);2647 return d->treeModel()->rootItem->takeChild(index); 2642 2648 } 2643 2649 … … 2648 2654 { 2649 2655 Q_D(QTreeWidget); 2650 d-> model()->executePendingSort();2651 return d-> model()->rootItem->children.indexOf(item);2656 d->treeModel()->executePendingSort(); 2657 return d->treeModel()->rootItem->children.indexOf(item); 2652 2658 } 2653 2659 … … 2661 2667 { 2662 2668 Q_D(const QTreeWidget); 2663 d-> model()->executePendingSort();2664 return d-> model()->rootItem->children.indexOf(item);2669 d->treeModel()->executePendingSort(); 2670 return d->treeModel()->rootItem->children.indexOf(item); 2665 2671 } 2666 2672 … … 2677 2683 { 2678 2684 Q_D(QTreeWidget); 2679 d-> model()->rootItem->insertChildren(index, items);2685 d->treeModel()->rootItem->insertChildren(index, items); 2680 2686 } 2681 2687 … … 2699 2705 { 2700 2706 Q_D(const QTreeWidget); 2701 return d-> model()->headerItem;2707 return d->treeModel()->headerItem; 2702 2708 } 2703 2709 … … 2720 2726 int oldCount = columnCount(); 2721 2727 if (oldCount < item->columnCount()) 2722 d-> model()->beginInsertColumns(QModelIndex(), oldCount, item->columnCount());2728 d->treeModel()->beginInsertColumns(QModelIndex(), oldCount, item->columnCount()); 2723 2729 else 2724 d-> model()->beginRemoveColumns(QModelIndex(), item->columnCount(), oldCount);2725 delete d-> model()->headerItem;2726 d-> model()->headerItem = item;2730 d->treeModel()->beginRemoveColumns(QModelIndex(), item->columnCount(), oldCount); 2731 delete d->treeModel()->headerItem; 2732 d->treeModel()->headerItem = item; 2727 2733 if (oldCount < item->columnCount()) 2728 d-> model()->endInsertColumns();2734 d->treeModel()->endInsertColumns(); 2729 2735 else 2730 d-> model()->endRemoveColumns();2731 d-> model()->headerDataChanged(Qt::Horizontal, 0, oldCount);2736 d->treeModel()->endRemoveColumns(); 2737 d->treeModel()->headerDataChanged(Qt::Horizontal, 0, oldCount); 2732 2738 } 2733 2739 … … 2746 2752 if (columnCount() < labels.count()) 2747 2753 setColumnCount(labels.count()); 2748 QTreeModel *model = d->model(); 2749 QTreeWidgetItem *item = model->headerItem; 2754 QTreeWidgetItem *item = d->treeModel()->headerItem; 2750 2755 for (int i = 0; i < labels.count(); ++i) 2751 2756 item->setText(i, labels.at(i)); … … 2784 2789 Sets the current \a item in the tree widget. 2785 2790 2786 Depending on the current selection mode, the item may also be selected. 2791 Unless the selection mode is \l{QAbstractItemView::}{NoSelection}, 2792 the item is also be selected. 2787 2793 2788 2794 \sa currentItem(), currentItemChanged() … … 2846 2852 { 2847 2853 Q_D(const QTreeWidget); 2848 return visualRect(d->index(item)); 2854 //the visual rect for an item is across all columns. So we need to determine 2855 //what is the first and last column and get their visual index rects 2856 QModelIndex base = d->index(item); 2857 const int firstVisiblesection = header()->logicalIndexAt(- header()->offset()); 2858 const int lastVisibleSection = header()->logicalIndexAt(header()->length() - header()->offset() - 1); 2859 QModelIndex first = base.sibling(base.row(), header()->logicalIndex(firstVisiblesection)); 2860 QModelIndex last = base.sibling(base.row(), header()->logicalIndex(lastVisibleSection)); 2861 return visualRect(first) | visualRect(last); 2849 2862 } 2850 2863 … … 2875 2888 Q_D(QTreeWidget); 2876 2889 header()->setSortIndicator(column, order); 2877 d->model ()->sort(column, order);2890 d->model->sort(column, order); 2878 2891 } 2879 2892 … … 3042 3055 { 3043 3056 Q_D(const QTreeWidget); 3044 QModelIndexList indexes = d->model ()->match(model()->index(0, column, QModelIndex()),3057 QModelIndexList indexes = d->model->match(model()->index(0, column, QModelIndex()), 3045 3058 Qt::DisplayRole, text, -1, flags); 3046 3059 QList<QTreeWidgetItem*> items; … … 3060 3073 { 3061 3074 Q_D(const QTreeWidget); 3062 if (item == d-> model()->headerItem)3075 if (item == d->treeModel()->headerItem) 3063 3076 return header()->isHidden(); 3064 3077 if (d->hiddenIndexes.isEmpty()) 3065 3078 return false; 3066 QTreeModel::SkipSorting skipSorting(d-> model());3079 QTreeModel::SkipSorting skipSorting(d->treeModel()); 3067 3080 return d->isRowHidden(d->index(item)); 3068 3081 } … … 3080 3093 { 3081 3094 Q_D(QTreeWidget); 3082 if (item == d-> model()->headerItem) {3095 if (item == d->treeModel()->headerItem) { 3083 3096 header()->setHidden(hide); 3084 3097 } else { … … 3100 3113 { 3101 3114 Q_D(const QTreeWidget); 3102 QTreeModel::SkipSorting skipSorting(d-> model());3115 QTreeModel::SkipSorting skipSorting(d->treeModel()); 3103 3116 return isExpanded(d->index(item)); 3104 3117 } … … 3110 3123 \sa expandItem(), collapseItem(), itemExpanded() 3111 3124 3112 \obsolete3113 3114 This function is deprecated. Use \l{QTreeWidgetItem::setExpanded()} instead.3125 \obsolete 3126 3127 This function is deprecated. Use \l{QTreeWidgetItem::setExpanded()} instead. 3115 3128 */ 3116 3129 void QTreeWidget::setItemExpanded(const QTreeWidgetItem *item, bool expand) 3117 3130 { 3118 3131 Q_D(QTreeWidget); 3119 QTreeModel::SkipSorting skipSorting(d-> model());3132 QTreeModel::SkipSorting skipSorting(d->treeModel()); 3120 3133 setExpanded(d->index(item), expand); 3121 3134 } … … 3132 3145 { 3133 3146 Q_D(const QTreeWidget); 3134 if (item == d-> model()->headerItem)3147 if (item == d->treeModel()->headerItem) 3135 3148 return false; // We can't set the header items to spanning 3136 3149 const QModelIndex index = d->index(item); … … 3149 3162 { 3150 3163 Q_D(QTreeWidget); 3151 if (item == d-> model()->headerItem)3164 if (item == d->treeModel()->headerItem) 3152 3165 return; // We can't set header items to spanning 3153 3166 const QModelIndex index = d->index(item); … … 3163 3176 { 3164 3177 Q_D(const QTreeWidget); 3165 if (item == d-> model()->headerItem)3178 if (item == d->treeModel()->headerItem) 3166 3179 return 0; 3167 3180 const QModelIndex index = d->index(item); … … 3178 3191 { 3179 3192 Q_D(const QTreeWidget); 3180 if (item == d-> model()->headerItem)3193 if (item == d->treeModel()->headerItem) 3181 3194 return 0; 3182 3195 const QModelIndex index = d->index(item); … … 3218 3231 { 3219 3232 Q_D(QTreeWidget); 3220 QTreeModel::SkipSorting skipSorting(d-> model());3233 QTreeModel::SkipSorting skipSorting(d->treeModel()); 3221 3234 expand(d->index(item)); 3222 3235 } … … 3231 3244 { 3232 3245 Q_D(QTreeWidget); 3233 QTreeModel::SkipSorting skipSorting(d-> model());3246 QTreeModel::SkipSorting skipSorting(d->treeModel()); 3234 3247 collapse(d->index(item)); 3235 3248 } … … 3248 3261 Q_D(QTreeWidget); 3249 3262 selectionModel()->clear(); 3250 d-> model()->clear();3263 d->treeModel()->clear(); 3251 3264 } 3252 3265 … … 3273 3286 { 3274 3287 Q_D(const QTreeWidget); 3275 if (d-> model()->cachedIndexes.isEmpty()) {3288 if (d->treeModel()->cachedIndexes.isEmpty()) { 3276 3289 QList<QModelIndex> indexes; 3277 3290 for (int i = 0; i < items.count(); ++i) { … … 3281 3294 } 3282 3295 } 3283 return model()->QAbstractItemModel::mimeData(indexes);3284 } 3285 return d-> model()->internalMimeData();3296 return d->model->QAbstractItemModel::mimeData(indexes); 3297 } 3298 return d->treeModel()->internalMimeData(); 3286 3299 } 3287 3300 … … 3427 3440 Q_D(QTreeWidget); 3428 3441 if (e->type() == QEvent::Polish) 3429 d-> model()->executePendingSort();3442 d->treeModel()->executePendingSort(); 3430 3443 return QTreeView::event(e); 3431 3444 } -
trunk/src/gui/itemviews/qtreewidget.h
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 ** -
trunk/src/gui/itemviews/qtreewidget_p.h
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 ** … … 220 220 public: 221 221 QTreeWidgetPrivate() : QTreeViewPrivate(), explicitSortColumn(-1) {} 222 inline QTreeModel *model() const 223 { return qobject_cast<QTreeModel*>(q_func()->model()); } 222 inline QTreeModel *treeModel() const { return qobject_cast<QTreeModel*>(model); } 224 223 inline QModelIndex index(const QTreeWidgetItem *item, int column = 0) const 225 { return model()->index(item, column); }224 { return treeModel()->index(item, column); } 226 225 inline QTreeWidgetItem *item(const QModelIndex &index) const 227 { return model()->item(index); }226 { return treeModel()->item(index); } 228 227 void _q_emitItemPressed(const QModelIndex &index); 229 228 void _q_emitItemClicked(const QModelIndex &index); -
trunk/src/gui/itemviews/qtreewidgetitemiterator.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 ** … … 98 98 QTreeModel *model = qobject_cast<QTreeModel*>(widget->model()); 99 99 Q_ASSERT(model); 100 d_ptr = new QTreeWidgetItemIteratorPrivate(this, model);100 d_ptr.reset(new QTreeWidgetItemIteratorPrivate(this, model)); 101 101 model->iterators.append(this); 102 102 if (!model->rootItem->children.isEmpty()) current = model->rootItem->children.first(); … … 151 151 { 152 152 d_func()->m_model->iterators.removeAll(this); 153 delete d_ptr;154 153 } 155 154 -
trunk/src/gui/itemviews/qtreewidgetitemiterator.h
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 ** … … 44 44 45 45 #include <QtCore/qglobal.h> 46 #include <QtCore/qscopedpointer.h> 46 47 47 48 QT_BEGIN_HEADER … … 106 107 private: 107 108 bool matchesFlags(const QTreeWidgetItem *item) const; 108 Q TreeWidgetItemIteratorPrivate *d_ptr;109 QScopedPointer<QTreeWidgetItemIteratorPrivate> d_ptr; 109 110 QTreeWidgetItem *current; 110 111 IteratorFlags flags; -
trunk/src/gui/itemviews/qtreewidgetitemiterator_p.h
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 ** … … 74 74 75 75 QTreeWidgetItemIteratorPrivate(const QTreeWidgetItemIteratorPrivate& other) 76 : m_currentIndex(other.m_currentIndex), m_model(other.m_model), m_parentIndex(other.m_parentIndex) 76 : m_currentIndex(other.m_currentIndex), m_model(other.m_model), 77 m_parentIndex(other.m_parentIndex), q_ptr(other.q_ptr) 77 78 { 78 79 -
trunk/src/gui/itemviews/qwidgetitemdata_p.h
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 **
Note:
See TracChangeset
for help on using the changeset viewer.