diff options
Diffstat (limited to 'src/gui/itemviews')
29 files changed, 1464 insertions, 1182 deletions
diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index f7d5f1b..ed2b3c5 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -108,16 +108,16 @@ void QAbstractItemViewPrivate::init() Q_Q(QAbstractItemView); q->setItemDelegate(new QStyledItemDelegate(q)); - q->verticalScrollBar()->setRange(0, 0); - q->horizontalScrollBar()->setRange(0, 0); + vbar->setRange(0, 0); + hbar->setRange(0, 0); - QObject::connect(q->verticalScrollBar(), SIGNAL(actionTriggered(int)), + QObject::connect(vbar, SIGNAL(actionTriggered(int)), q, SLOT(verticalScrollbarAction(int))); - QObject::connect(q->horizontalScrollBar(), SIGNAL(actionTriggered(int)), + QObject::connect(hbar, SIGNAL(actionTriggered(int)), q, SLOT(horizontalScrollbarAction(int))); - QObject::connect(q->verticalScrollBar(), SIGNAL(valueChanged(int)), + QObject::connect(vbar, SIGNAL(valueChanged(int)), q, SLOT(verticalScrollbarValueChanged(int))); - QObject::connect(q->horizontalScrollBar(), SIGNAL(valueChanged(int)), + QObject::connect(hbar, SIGNAL(valueChanged(int)), q, SLOT(horizontalScrollbarValueChanged(int))); viewport->setBackgroundRole(QPalette::Base); @@ -127,6 +127,37 @@ void QAbstractItemViewPrivate::init() q->setAttribute(Qt::WA_InputMethodEnabled); } +void QAbstractItemViewPrivate::checkMouseMove(const QPersistentModelIndex &index) +{ + //we take a persistent model index because the model might change by emitting signals + Q_Q(QAbstractItemView); + if (viewportEnteredNeeded || enteredIndex != index) { + viewportEnteredNeeded = false; + + if (index.isValid()) { + emit q->entered(index); +#ifndef QT_NO_STATUSTIP + QString statustip = model->data(index, Qt::StatusTipRole).toString(); + if (parent && !statustip.isEmpty()) { + QStatusTipEvent tip(statustip); + QApplication::sendEvent(parent, &tip); + } +#endif + } else { +#ifndef QT_NO_STATUSTIP + if (parent) { + QString emptyString; + QStatusTipEvent tip( emptyString ); + QApplication::sendEvent(parent, &tip); + } +#endif + emit q->viewportEntered(); + } + enteredIndex = index; + } +} + + /*! \class QAbstractItemView @@ -820,8 +851,8 @@ QAbstractItemDelegate *QAbstractItemView::itemDelegateForColumn(int column) cons } /*! - Returns the item delegate used by this view and model for - the given \a index. + Returns the item delegate used by this view and model for + the given \a index. */ QAbstractItemDelegate *QAbstractItemView::itemDelegate(const QModelIndex &index) const { @@ -830,14 +861,14 @@ QAbstractItemDelegate *QAbstractItemView::itemDelegate(const QModelIndex &index) } /*! - \property QAbstractItemView::selectionMode - \brief which selection mode the view operates in + \property QAbstractItemView::selectionMode + \brief which selection mode the view operates in - This property controls whether the user can select one or many items - and, in many-item selections, whether the selection must be a - continuous range of items. + This property controls whether the user can select one or many items + and, in many-item selections, whether the selection must be a + continuous range of items. - \sa SelectionMode SelectionBehavior + \sa SelectionMode SelectionBehavior */ void QAbstractItemView::setSelectionMode(SelectionMode mode) { @@ -852,13 +883,13 @@ QAbstractItemView::SelectionMode QAbstractItemView::selectionMode() const } /*! - \property QAbstractItemView::selectionBehavior - \brief which selection behavior the view uses + \property QAbstractItemView::selectionBehavior + \brief which selection behavior the view uses - This property holds whether selections are done - in terms of single items, rows or columns. + This property holds whether selections are done + in terms of single items, rows or columns. - \sa SelectionMode SelectionBehavior + \sa SelectionMode SelectionBehavior */ void QAbstractItemView::setSelectionBehavior(QAbstractItemView::SelectionBehavior behavior) @@ -929,6 +960,7 @@ void QAbstractItemView::reset() d->currentIndexSet = false; setState(NoState); setRootIndex(QModelIndex()); + d->selectionModel->reset(); } /*! @@ -959,11 +991,11 @@ QModelIndex QAbstractItemView::rootIndex() const } /*! - Selects all item in the view. - This function wil use the selection selection behavior - set on the view when selecting. + Selects all items in the view. + This function will use the selection behavior + set on the view when selecting. - \sa setSelection(), selectedIndexes(), clearSelection() + \sa setSelection(), selectedIndexes(), clearSelection() */ void QAbstractItemView::selectAll() { @@ -1192,10 +1224,10 @@ bool QAbstractItemView::tabKeyNavigation() const #ifndef QT_NO_DRAGANDDROP /*! - \property QAbstractItemView::showDropIndicator - \brief whether the drop indicator is shown when dragging items and dropping. + \property QAbstractItemView::showDropIndicator + \brief whether the drop indicator is shown when dragging items and dropping. - \sa dragEnabled DragDropMode dragDropOverwriteMode acceptDrops + \sa dragEnabled DragDropMode dragDropOverwriteMode acceptDrops */ void QAbstractItemView::setDropIndicatorShown(bool enable) @@ -1211,10 +1243,10 @@ bool QAbstractItemView::showDropIndicator() const } /*! - \property QAbstractItemView::dragEnabled - \brief whether the view supports dragging of its own items + \property QAbstractItemView::dragEnabled + \brief whether the view supports dragging of its own items - \sa showDropIndicator DragDropMode dragDropOverwriteMode acceptDrops + \sa showDropIndicator DragDropMode dragDropOverwriteMode acceptDrops */ void QAbstractItemView::setDragEnabled(bool enable) @@ -1250,11 +1282,11 @@ bool QAbstractItemView::dragEnabled() const */ /*! - \property QAbstractItemView::dragDropMode - \brief the drag and drop event the view will act upon + \property QAbstractItemView::dragDropMode + \brief the drag and drop event the view will act upon - \since 4.2 - \sa showDropIndicator dragDropOverwriteMode + \since 4.2 + \sa showDropIndicator dragDropOverwriteMode */ void QAbstractItemView::setDragDropMode(DragDropMode behavior) { @@ -1290,14 +1322,14 @@ QAbstractItemView::DragDropMode QAbstractItemView::dragDropMode() const #endif // QT_NO_DRAGANDDROP /*! - \property QAbstractItemView::alternatingRowColors - \brief whether to draw the background using alternating colors + \property QAbstractItemView::alternatingRowColors + \brief whether to draw the background using alternating colors - If this property is true, the item background will be drawn using - QPalette::Base and QPalette::AlternateBase; otherwise the background - will be drawn using the QPalette::Base color. + If this property is true, the item background will be drawn using + QPalette::Base and QPalette::AlternateBase; otherwise the background + will be drawn using the QPalette::Base color. - By default, this property is false. + By default, this property is false. */ void QAbstractItemView::setAlternatingRowColors(bool enable) { @@ -1426,10 +1458,10 @@ bool QAbstractItemView::viewportEvent(QEvent *event) case QEvent::HoverEnter: { QHoverEvent *he = static_cast<QHoverEvent*>(event); d->hover = indexAt(he->pos()); - d->viewport->update(visualRect(d->hover)); + update(d->hover); break; } case QEvent::HoverLeave: { - d->viewport->update(visualRect(d->hover)); // update old + update(d->hover); // update old d->hover = QModelIndex(); break; } case QEvent::HoverMove: { @@ -1557,7 +1589,7 @@ void QAbstractItemView::mouseMoveEvent(QMouseEvent *event) } #endif // QT_NO_DRAGANDDROP - QModelIndex index = indexAt(bottomRight); + QPersistentModelIndex index = indexAt(bottomRight); QModelIndex buddy = d->model->buddy(d->pressedIndex); if ((state() == EditingState && d->hasEditor(buddy)) || edit(index, NoEditTriggers, event)) @@ -1568,36 +1600,10 @@ void QAbstractItemView::mouseMoveEvent(QMouseEvent *event) else topLeft = bottomRight; - if (d->viewportEnteredNeeded || d->enteredIndex != index) { - d->viewportEnteredNeeded = false; - - // signal handlers may change the model - QPersistentModelIndex persistent = index; - if (persistent.isValid()) { - emit entered(persistent); -#ifndef QT_NO_STATUSTIP - QString statustip = d->model->data(persistent, Qt::StatusTipRole).toString(); - if (parent() && !statustip.isEmpty()) { - QStatusTipEvent tip(statustip); - QApplication::sendEvent(parent(), &tip); - } -#endif - } else { -#ifndef QT_NO_STATUSTIP - if (parent()) { - QString emptyString; - QStatusTipEvent tip(emptyString); - QApplication::sendEvent(parent(), &tip); - } -#endif - emit viewportEntered(); - } - d->enteredIndex = persistent; - index = persistent; - } + d->checkMouseMove(index); #ifndef QT_NO_DRAGANDDROP - if (index.isValid() + if (d->pressedIndex.isValid() && d->dragEnabled && (state() != DragSelectingState) && (event->buttons() != Qt::NoButton) @@ -1613,14 +1619,13 @@ void QAbstractItemView::mouseMoveEvent(QMouseEvent *event) // Do the normalize ourselves, since QRect::normalized() is flawed QRect selectionRect = QRect(topLeft, bottomRight); - QPersistentModelIndex persistent = index; setSelection(selectionRect, command); // set at the end because it might scroll the view - if (persistent.isValid() - && (persistent != d->selectionModel->currentIndex()) - && d->isIndexEnabled(persistent)) - d->selectionModel->setCurrentIndex(persistent, QItemSelectionModel::NoUpdate); + if (index.isValid() + && (index != d->selectionModel->currentIndex()) + && d->isIndexEnabled(index)) + d->selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate); } } @@ -1642,7 +1647,7 @@ void QAbstractItemView::mouseReleaseEvent(QMouseEvent *event) if (d->isIndexValid(index) && d->isIndexEnabled(index) && d->sendDelegateEvent(index, event)) - d->viewport->update(visualRect(index)); + update(index); return; } @@ -2165,11 +2170,12 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event) } #endif bool modified = (event->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier)); - if (!event->text().isEmpty() && !modified) { - if (!edit(currentIndex(), AnyKeyPressed, event)) - keyboardSearch(event->text()); + if (!event->text().isEmpty() && !modified && !edit(currentIndex(), AnyKeyPressed, event)) { + keyboardSearch(event->text()); + event->accept(); + } else { + event->ignore(); } - event->ignore(); break; } } } @@ -2195,6 +2201,8 @@ void QAbstractItemView::resizeEvent(QResizeEvent *event) void QAbstractItemView::timerEvent(QTimerEvent *event) { Q_D(QAbstractItemView); + if (event->timerId() == d->fetchMoreTimer.timerId()) + d->fetchMore(); if (event->timerId() == d->autoScrollTimer.timerId()) doAutoScroll(); else if (event->timerId() == d->updateTimer.timerId()) @@ -2250,8 +2258,8 @@ void QAbstractItemView::inputMethodEvent(QInputMethodEvent *event) \value BelowItem The item will be dropped below the index. \value OnViewport The item will be dropped onto a region of the viewport with -no items. The way each view handles items dropped onto the viewport depends on -the behavior of the underlying model in use. + no items. The way each view handles items dropped onto the viewport depends on + the behavior of the underlying model in use. */ @@ -2268,11 +2276,11 @@ QAbstractItemView::DropIndicatorPosition QAbstractItemView::dropIndicatorPositio #endif /*! - This convenience function returns a list of all selected and - non-hidden item indexes in the view. The list contains no - duplicates, and is not sorted. + This convenience function returns a list of all selected and + non-hidden item indexes in the view. The list contains no + duplicates, and is not sorted. - \sa QItemSelectionModel::selectedIndexes() + \sa QItemSelectionModel::selectedIndexes() */ QModelIndexList QAbstractItemView::selectedIndexes() const { @@ -2325,7 +2333,7 @@ bool QAbstractItemView::edit(const QModelIndex &index, EditTrigger trigger, QEve } if (d->sendDelegateEvent(index, event)) { - d->viewport->update(visualRect(index)); + update(index); return true; } @@ -2354,8 +2362,8 @@ bool QAbstractItemView::edit(const QModelIndex &index, EditTrigger trigger, QEve } /*! - \internal - Updates the data shown in the open editor widgets in the view. + \internal + Updates the data shown in the open editor widgets in the view. */ void QAbstractItemView::updateEditorData() { @@ -2364,8 +2372,8 @@ void QAbstractItemView::updateEditorData() } /*! - \internal - Updates the geometry of the open editor widgets in the view. + \internal + Updates the geometry of the open editor widgets in the view. */ void QAbstractItemView::updateEditorGeometries() { @@ -2397,8 +2405,8 @@ void QAbstractItemView::updateEditorGeometries() //we release the editor outside of the loop because it might change the focus and try //to change the d->editors list. - foreach(QWidget *editor, editorsToRelease) { - d->releaseEditor(editor); + for (int i = 0; i < editorsToRelease.count(); ++i) { + d->releaseEditor(editorsToRelease.at(i)); } } @@ -2410,27 +2418,29 @@ void QAbstractItemView::updateEditorGeometries() void QAbstractItemView::updateGeometries() { updateEditorGeometries(); - QMetaObject::invokeMethod(this, "_q_fetchMore", Qt::QueuedConnection); + d_func()->fetchMoreTimer.start(0, this); //fetch more later } /*! - \internal + \internal */ void QAbstractItemView::verticalScrollbarValueChanged(int value) { Q_D(QAbstractItemView); if (verticalScrollBar()->maximum() == value && d->model->canFetchMore(d->root)) d->model->fetchMore(d->root); + d->checkMouseMove(viewport()->mapFromGlobal(QCursor::pos())); } /*! - \internal + \internal */ void QAbstractItemView::horizontalScrollbarValueChanged(int value) { Q_D(QAbstractItemView); if (horizontalScrollBar()->maximum() == value && d->model->canFetchMore(d->root)) d->model->fetchMore(d->root); + d->checkMouseMove(viewport()->mapFromGlobal(QCursor::pos())); } /*! @@ -2525,9 +2535,9 @@ void QAbstractItemView::closeEditor(QWidget *editor, QAbstractItemDelegate::EndE } /*! - Commit the data in the \a editor to the model. + Commit the data in the \a editor to the model. - \sa closeEditor() + \sa closeEditor() */ void QAbstractItemView::commitData(QWidget *editor) { @@ -2546,9 +2556,9 @@ void QAbstractItemView::commitData(QWidget *editor) } /*! - This function is called when the given \a editor has been destroyed. + This function is called when the given \a editor has been destroyed. - \sa closeEditor() + \sa closeEditor() */ void QAbstractItemView::editorDestroyed(QObject *editor) { @@ -2619,12 +2629,12 @@ int QAbstractItemView::verticalStepsPerItem() const } /*! - Moves to and selects the item best matching the string \a search. - If no item is found nothing happens. + Moves to and selects the item best matching the string \a search. + If no item is found nothing happens. - In the default implementation, the search is reset if \a search is empty, or - the time interval since the last search has exceeded - QApplication::keyboardInputInterval(). + In the default implementation, the search is reset if \a search is empty, or + the time interval since the last search has exceeded + QApplication::keyboardInputInterval(). */ void QAbstractItemView::keyboardSearch(const QString &search) { @@ -2679,9 +2689,9 @@ void QAbstractItemView::keyboardSearch(const QString &search) setCurrentIndex(firstMatch); break; } - int row = firstMatch.row() + 1; - if (row >= d->model->rowCount(firstMatch.parent())) - row = 0; + int row = firstMatch.row() + 1; + if (row >= d->model->rowCount(firstMatch.parent())) + row = 0; current = firstMatch.sibling(row, firstMatch.column()); //avoid infinite loop if all the matching items are disabled. @@ -2794,9 +2804,9 @@ void QAbstractItemView::openPersistentEditor(const QModelIndex &index) } /*! - Closes the persistent editor for the item at the given \a index. + Closes the persistent editor for the item at the given \a index. - \sa openPersistentEditor() + \sa openPersistentEditor() */ void QAbstractItemView::closePersistentEditor(const QModelIndex &index) { @@ -2851,9 +2861,9 @@ void QAbstractItemView::setIndexWidget(const QModelIndex &index, QWidget *widget d->persistent.insert(widget); d->addEditor(index, widget, true); widget->show(); + dataChanged(index, index); // update the geometry if (!d->delayedPendingLayout) widget->setGeometry(visualRect(index)); - dataChanged(index, index); // update the geometry } } @@ -2960,7 +2970,7 @@ void QAbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelInde void QAbstractItemView::rowsInserted(const QModelIndex &, int, int) { if (!isVisible()) - QMetaObject::invokeMethod(this, "_q_fetchMore", Qt::QueuedConnection); + d_func()->fetchMoreTimer.start(0, this); //fetch more later else updateEditorGeometries(); } @@ -3144,9 +3154,7 @@ void QAbstractItemView::selectionChanged(const QItemSelection &selected, { Q_D(QAbstractItemView); if (isVisible() && updatesEnabled()) { - d->setDirtyRegion(visualRegionForSelection(deselected)); - d->setDirtyRegion(visualRegionForSelection(selected)); - d->updateDirtyRegion(); + d->viewport->update(visualRegionForSelection(deselected) | visualRegionForSelection(selected)); } } @@ -3174,19 +3182,18 @@ void QAbstractItemView::currentChanged(const QModelIndex ¤t, const QModelI closeEditor(editor, QAbstractItemDelegate::NoHint); } if (isVisible()) { - d->setDirtyRegion(visualRect(previous)); - d->updateDirtyRegion(); + update(previous); } } + if (current.isValid() && !d->autoScrollTimer.isActive()) { if (isVisible()) { if (d->autoScroll) scrollTo(current); - d->setDirtyRegion(visualRect(current)); - d->updateDirtyRegion(); + update(current); edit(current, CurrentChanged, 0); if (current.row() == (d->model->rowCount(d->root) - 1)) - d->_q_fetchMore(); + d->fetchMore(); } else { d->shouldScrollToCurrentOnShow = d->autoScroll; } @@ -3334,14 +3341,14 @@ void QAbstractItemView::setDirtyRegion(const QRegion ®ion) } /*! - Prepares the view for scrolling by (\a{dx},\a{dy}) pixels by moving the dirty regions in the - opposite direction. You only need to call this function if you are implementing a scrolling - viewport in your view subclass. + Prepares the view for scrolling by (\a{dx},\a{dy}) pixels by moving the dirty regions in the + opposite direction. You only need to call this function if you are implementing a scrolling + viewport in your view subclass. - If you implement scrollContentsBy() in a subclass of QAbstractItemView, call this function - before you call QWidget::scroll() on the viewport. Alternatively, just call update(). + If you implement scrollContentsBy() in a subclass of QAbstractItemView, call this function + before you call QWidget::scroll() on the viewport. Alternatively, just call update(). - \sa scrollContentsBy(), dirtyRegionOffset(), setDirtyRegion() + \sa scrollContentsBy(), dirtyRegionOffset(), setDirtyRegion() */ void QAbstractItemView::scrollDirtyRegion(int dx, int dy) { @@ -3350,13 +3357,13 @@ void QAbstractItemView::scrollDirtyRegion(int dx, int dy) } /*! - Returns the offset of the dirty regions in the view. + Returns the offset of the dirty regions in the view. - If you use scrollDirtyRegion() and implement a paintEvent() in a subclass of - QAbstractItemView, you should translate the area given by the paint event with - the offset returned from this function. + If you use scrollDirtyRegion() and implement a paintEvent() in a subclass of + QAbstractItemView, you should translate the area given by the paint event with + the offset returned from this function. - \sa scrollDirtyRegion(), setDirtyRegion() + \sa scrollDirtyRegion(), setDirtyRegion() */ QPoint QAbstractItemView::dirtyRegionOffset() const { @@ -3528,7 +3535,7 @@ QItemSelectionModel::SelectionFlags QAbstractItemViewPrivate::extendedSelectionC const bool shiftKeyPressed = modifiers & Qt::ShiftModifier; const bool controlKeyPressed = modifiers & Qt::ControlModifier; if (((index == pressedIndex && selectionModel->isSelected(index)) - || !index.isValid()) && state != QAbstractItemView::DragSelectingState + || !index.isValid()) && state != QAbstractItemView::DragSelectingState && !shiftKeyPressed && !controlKeyPressed && !rightButtonPressed) return QItemSelectionModel::ClearAndSelect|selectionBehaviorFlags(); return QItemSelectionModel::NoUpdate; @@ -3607,8 +3614,9 @@ QAbstractItemViewPrivate::contiguousSelectionCommand(const QModelIndex &index, } } -void QAbstractItemViewPrivate::_q_fetchMore() +void QAbstractItemViewPrivate::fetchMore() { + fetchMoreTimer.stop(); if (!model->canFetchMore(root)) return; int last = model->rowCount(root) - 1; @@ -3759,7 +3767,7 @@ void QAbstractItemViewPrivate::updateEditorData(const QModelIndex &tl, const QMo but the behavior is view dependant (table just clears the selected indexes for example). Either remove the selected rows or clear them - */ +*/ void QAbstractItemViewPrivate::clearOrRemove() { #ifndef QT_NO_DRAGANDDROP @@ -3795,11 +3803,11 @@ void QAbstractItemViewPrivate::clearOrRemove() When persistent aeditor gets/loses focus, we need to check and setcorrectly the current index. - */ +*/ void QAbstractItemViewPrivate::checkPersistentEditorFocus() { Q_Q(QAbstractItemView); - if (QWidget *widget = qApp->focusWidget()) { + if (QWidget *widget = QApplication::focusWidget()) { if (persistent.contains(widget)) { //a persistent editor has gained the focus QModelIndex index = indexForEditor(widget); @@ -3881,30 +3889,48 @@ bool QAbstractItemViewPrivate::openEditor(const QModelIndex &index, QEvent *even return true; } -QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes, QRect *r) const +/* + \internal + + returns the pair QRect/QModelIndex that should be painted on the viewports's rect +*/ + +QItemViewPaintPairs QAbstractItemViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const { + Q_ASSERT(r); Q_Q(const QAbstractItemView); - QRect rect = q->visualRect(indexes.at(0)); - QList<QRect> rects; + QRect &rect = *r; + const QRect viewportRect = viewport->rect(); + QItemViewPaintPairs ret; for (int i = 0; i < indexes.count(); ++i) { - rects.append(q->visualRect(indexes.at(i))); - rect |= rects.at(i); + const QModelIndex &index = indexes.at(i); + const QRect current = q->visualRect(index); + if (current.intersects(viewportRect)) { + ret += qMakePair(current, index); + rect |= current; + } } - rect = rect.intersected(viewport->rect()); - if (rect.width() <= 0 || rect.height() <= 0) + rect &= viewportRect; + return ret; +} + +QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes, QRect *r) const +{ + Q_ASSERT(r); + QItemViewPaintPairs paintPairs = draggablePaintPairs(indexes, r); + if (paintPairs.isEmpty()) return QPixmap(); - QImage image(rect.size(), QImage::Format_ARGB32_Premultiplied); - image.fill(0); - QPainter painter(&image); + QPixmap pixmap(r->size()); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); QStyleOptionViewItemV4 option = viewOptionsV4(); option.state |= QStyle::State_Selected; - for (int j = 0; j < indexes.count(); ++j) { - option.rect = QRect(rects.at(j).topLeft() - rect.topLeft(), rects.at(j).size()); - delegateForIndex(indexes.at(j))->paint(&painter, option, indexes.at(j)); + for (int j = 0; j < paintPairs.count(); ++j) { + option.rect = paintPairs.at(j).first.translated(-r->topLeft()); + const QModelIndex ¤t = paintPairs.at(j).second; + delegateForIndex(current)->paint(&painter, option, current); } - painter.end(); - if (r) *r = rect; - return QPixmap::fromImage(image); + return pixmap; } void QAbstractItemViewPrivate::selectAll(QItemSelectionModel::SelectionFlags command) diff --git a/src/gui/itemviews/qabstractitemview.h b/src/gui/itemviews/qabstractitemview.h index f98dd16..da6f0ea 100644 --- a/src/gui/itemviews/qabstractitemview.h +++ b/src/gui/itemviews/qabstractitemview.h @@ -353,7 +353,6 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_rowsRemoved(const QModelIndex&, int, int)) Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed()) Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged()) - Q_PRIVATE_SLOT(d_func(), void _q_fetchMore()) friend class QTreeViewPrivate; // needed to compile with MSVC friend class QAccessibleItemRow; diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index b74091c..557e98b 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -61,11 +61,10 @@ #include "QtGui/qmime.h" #include "QtGui/qpainter.h" #include "QtCore/qpair.h" -#include "QtCore/qtimer.h" -#include "QtCore/qtimeline.h" #include "QtGui/qregion.h" #include "QtCore/qdebug.h" #include "QtGui/qpainter.h" +#include "QtCore/qbasictimer.h" #ifndef QT_NO_ITEMVIEWS @@ -87,6 +86,9 @@ struct QEditorInfo }; +typedef QPair<QRect, QModelIndex> QItemViewPaintPair; +typedef QList<QItemViewPaintPair> QItemViewPaintPairs; + class QEmptyModel : public QAbstractItemModel { public: @@ -99,7 +101,7 @@ public: QVariant data(const QModelIndex &, int) const { return QVariant(); } }; -class Q_GUI_EXPORT QAbstractItemViewPrivate : public QAbstractScrollAreaPrivate +class Q_AUTOTEST_EXPORT QAbstractItemViewPrivate : public QAbstractScrollAreaPrivate { Q_DECLARE_PUBLIC(QAbstractItemView) @@ -109,13 +111,14 @@ public: void init(); - void _q_rowsRemoved(const QModelIndex &parent, int start, int end); - void _q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end); - void _q_columnsRemoved(const QModelIndex &parent, int start, int end); - void _q_columnsInserted(const QModelIndex &parent, int start, int end); - void _q_modelDestroyed(); - void _q_layoutChanged(); - void _q_fetchMore(); + virtual void _q_rowsRemoved(const QModelIndex &parent, int start, int end); + virtual void _q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end); + virtual void _q_columnsRemoved(const QModelIndex &parent, int start, int end); + virtual void _q_columnsInserted(const QModelIndex &parent, int start, int end); + virtual void _q_modelDestroyed(); + virtual void _q_layoutChanged(); + + void fetchMore(); bool shouldEdit(QAbstractItemView::EditTrigger trigger, const QModelIndex &index) const; bool shouldForwardEvent(QAbstractItemView::EditTrigger trigger, const QEvent *event) const; @@ -139,6 +142,9 @@ public: const QEvent *event) const; virtual void selectAll(QItemSelectionModel::SelectionFlags command); + void checkMouseMove(const QPersistentModelIndex &index); + inline void checkMouseMove(const QPoint &pos) { checkMouseMove(q_func()->indexAt(pos)); } + inline QItemSelectionModel::SelectionFlags selectionBehaviorFlags() const { switch (selectionBehavior) { @@ -173,7 +179,9 @@ public: q_func()->style()->drawPrimitive(QStyle::PE_IndicatorItemViewItemDrop, &opt, painter, q_func()); } } + #endif + virtual QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const; inline void releaseEditor(QWidget *editor) const { if (editor) { @@ -218,7 +226,7 @@ public: void clearOrRemove(); void checkPersistentEditorFocus(); - QPixmap renderToPixmap(const QModelIndexList &indexes, QRect *r = 0) const; + QPixmap renderToPixmap(const QModelIndexList &indexes, QRect *r) const; inline QPoint offset() const { const Q_Q(QAbstractItemView); @@ -372,7 +380,6 @@ public: QBasicTimer updateTimer; QBasicTimer delayedEditing; QBasicTimer delayedAutoScroll; //used when an item is clicked - QTimeLine timeline; QAbstractItemView::ScrollMode verticalScrollMode; QAbstractItemView::ScrollMode horizontalScrollMode; @@ -384,6 +391,7 @@ public: private: mutable QBasicTimer delayedLayout; + mutable QBasicTimer fetchMoreTimer; }; QT_BEGIN_INCLUDE_NAMESPACE diff --git a/src/gui/itemviews/qcolumnview.cpp b/src/gui/itemviews/qcolumnview.cpp index c3ffe51..c544394 100644 --- a/src/gui/itemviews/qcolumnview.cpp +++ b/src/gui/itemviews/qcolumnview.cpp @@ -52,7 +52,6 @@ #include <qscrollbar.h> #include <qpainter.h> #include <qdebug.h> -#include <qpainterpath.h> QT_BEGIN_NAMESPACE @@ -108,9 +107,13 @@ void QColumnViewPrivate::initialize() { Q_Q(QColumnView); q->setTextElideMode(Qt::ElideMiddle); - q->connect(¤tAnimation, SIGNAL(frameChanged(int)), - q->horizontalScrollBar(), SLOT(setValue(int))); - q->connect(¤tAnimation, SIGNAL(finished()), q, SLOT(_q_changeCurrentColumn())); +#ifndef QT_NO_ANIMATION + QObject::connect(¤tAnimation, SIGNAL(finished()), q, SLOT(_q_changeCurrentColumn())); + currentAnimation.setDuration(ANIMATION_DURATION_MSEC); + currentAnimation.setTargetObject(hbar); + currentAnimation.setPropertyName("value"); + currentAnimation.setEasingCurve(QEasingCurve::InOutQuad); +#endif //QT_NO_ANIMATION delete itemDelegate; q->setItemDelegate(new QColumnViewDelegate(q)); } @@ -260,10 +263,12 @@ void QColumnView::scrollTo(const QModelIndex &index, ScrollHint hint) if (!index.isValid() || d->columns.isEmpty()) return; - if (d->currentAnimation.state() == QTimeLine::Running) +#ifndef QT_NO_ANIMATION + if (d->currentAnimation.state() == QPropertyAnimation::Running) return; d->currentAnimation.stop(); +#endif //QT_NO_ANIMATION // Fill up what is needed to get to index d->closeColumns(index, true); @@ -326,22 +331,12 @@ void QColumnView::scrollTo(const QModelIndex &index, ScrollHint hint) } } - //horizontalScrollBar()->setValue(newScrollbarValue); - //d->_q_changeCurrentColumn(); - //return; - // or do the following currentAnimation - - int oldValue = horizontalScrollBar()->value(); - - if (oldValue < newScrollbarValue) { - d->currentAnimation.setFrameRange(oldValue, newScrollbarValue); - d->currentAnimation.setDirection(QTimeLine::Forward); - d->currentAnimation.setCurrentTime(0); - } else { - d->currentAnimation.setFrameRange(newScrollbarValue, oldValue); - d->currentAnimation.setDirection(QTimeLine::Backward); - } +#ifndef QT_NO_ANIMATION + d->currentAnimation.setEndValue(newScrollbarValue); d->currentAnimation.start(); +#else + horizontalScrollBar()->setValue(newScrollbarValue); +#endif //QT_NO_ANIMATION } /*! @@ -410,8 +405,10 @@ void QColumnView::resizeEvent(QResizeEvent *event) void QColumnViewPrivate::updateScrollbars() { Q_Q(QColumnView); - if (currentAnimation.state() == QTimeLine::Running) +#ifndef QT_NO_ANIMATION + if (currentAnimation.state() == QPropertyAnimation::Running) return; +#endif //QT_NO_ANIMATION // find the total horizontal length of the laid out columns int horizontalLength = 0; @@ -421,23 +418,23 @@ void QColumnViewPrivate::updateScrollbars() horizontalLength = (columns.first()->x() + columns.first()->width()) - columns.last()->x(); } - QSize viewportSize = q->viewport()->size(); - if (horizontalLength < viewportSize.width() && q->horizontalScrollBar()->value() == 0) { - q->horizontalScrollBar()->setRange(0, 0); + QSize viewportSize = viewport->size(); + if (horizontalLength < viewportSize.width() && hbar->value() == 0) { + hbar->setRange(0, 0); } else { int visibleLength = qMin(horizontalLength + q->horizontalOffset(), viewportSize.width()); int hiddenLength = horizontalLength - visibleLength; - if (hiddenLength != q->horizontalScrollBar()->maximum()) - q->horizontalScrollBar()->setRange(0, hiddenLength); + if (hiddenLength != hbar->maximum()) + hbar->setRange(0, hiddenLength); } if (!columns.isEmpty()) { int pageStepSize = columns.at(0)->width(); - if (pageStepSize != q->horizontalScrollBar()->pageStep()) - q->horizontalScrollBar()->setPageStep(pageStepSize); + if (pageStepSize != hbar->pageStep()) + hbar->setPageStep(pageStepSize); } - bool visible = (q->horizontalScrollBar()->maximum() > 0); - if (visible != q->horizontalScrollBar()->isVisible()) - q->horizontalScrollBar()->setVisible(visible); + bool visible = (hbar->maximum() > 0); + if (visible != hbar->isVisible()) + hbar->setVisible(visible); } /*! @@ -696,7 +693,7 @@ QAbstractItemView *QColumnViewPrivate::createColumn(const QModelIndex &index, bo q, SIGNAL(pressed(const QModelIndex &))); view->setFocusPolicy(Qt::NoFocus); - view->setParent(q->viewport()); + view->setParent(viewport); Q_ASSERT(view); // Setup corner grip @@ -707,13 +704,13 @@ QAbstractItemView *QColumnViewPrivate::createColumn(const QModelIndex &index, bo } if (columnSizes.count() > columns.count()) { - view->setGeometry(0, 0, columnSizes.at(columns.count()), q->viewport()->height()); + view->setGeometry(0, 0, columnSizes.at(columns.count()), viewport->height()); } else { int initialWidth = view->sizeHint().width(); if (q->isRightToLeft()) - view->setGeometry(q->viewport()->width() - initialWidth, 0, initialWidth, q->viewport()->height()); + view->setGeometry(viewport->width() - initialWidth, 0, initialWidth, viewport->height()); else - view->setGeometry(0, 0, initialWidth, q->viewport()->height()); + view->setGeometry(0, 0, initialWidth, viewport->height()); columnSizes.resize(qMax(columnSizes.count(), columns.count() + 1)); columnSizes[columns.count()] = initialWidth; } @@ -896,6 +893,15 @@ QList<int> QColumnView::columnWidths() const /*! \reimp */ +void QColumnView::rowsInserted(const QModelIndex &parent, int start, int end) +{ + QAbstractItemView::rowsInserted(parent, start, end); + d_func()->checkColumnCreation(parent); +} + +/*! + \reimp +*/ void QColumnView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) { Q_D(QColumnView); @@ -1036,7 +1042,6 @@ QColumnViewPrivate::QColumnViewPrivate() : QAbstractItemViewPrivate() ,showResizeGrips(true) ,offset(0) -,currentAnimation(ANIMATION_DURATION_MSEC) ,previewWidget(0) ,previewColumn(0) { @@ -1048,6 +1053,41 @@ QColumnViewPrivate::~QColumnViewPrivate() /*! \internal + + */ +void QColumnViewPrivate::_q_columnsInserted(const QModelIndex &parent, int start, int end) +{ + QAbstractItemViewPrivate::_q_columnsInserted(parent, start, end); + checkColumnCreation(parent); +} + +/*! + \internal + + Makes sure we create a corresponding column as a result of changing the model. + + */ +void QColumnViewPrivate::checkColumnCreation(const QModelIndex &parent) +{ + if (parent == q_func()->currentIndex() && model->hasChildren(parent)) { + //the parent has children and is the current + //let's try to find out if there is already a mapping that is good + for (int i = 0; i < columns.count(); ++i) { + QAbstractItemView *view = columns.at(i); + if (view->rootIndex() == parent) { + if (view == previewColumn) { + //let's recreate the parent + closeColumns(parent, false); + createColumn(parent, true /*show*/); + } + break; + } + } + } +} + +/*! + \internal Place all of the columns where they belong inside of the viewport, resize as necessary. */ void QColumnViewPrivate::doLayout() @@ -1056,11 +1096,11 @@ void QColumnViewPrivate::doLayout() if (!model || columns.isEmpty()) return; - int viewportHeight = q->viewport()->height(); + int viewportHeight = viewport->height(); int x = columns.at(0)->x(); if (q->isRightToLeft()) { - x = q->viewport()->width() + q->horizontalOffset(); + x = viewport->width() + q->horizontalOffset(); for (int i = 0; i < columns.size(); ++i) { QAbstractItemView *view = columns.at(i); x -= view->width(); @@ -1116,7 +1156,7 @@ void QColumnViewDelegate::paint(QPainter *painter, // Draw > if (index.model()->hasChildren(index)) { const QWidget *view = opt.widget; - QStyle *style = view ? view->style() : qApp->style(); + QStyle *style = view ? view->style() : QApplication::style(); style->drawPrimitive(QStyle::PE_IndicatorColumnViewArrow, &opt, painter, view); } } diff --git a/src/gui/itemviews/qcolumnview.h b/src/gui/itemviews/qcolumnview.h index 880870a..f8697e9 100644 --- a/src/gui/itemviews/qcolumnview.h +++ b/src/gui/itemviews/qcolumnview.h @@ -97,16 +97,14 @@ protected: QRegion visualRegionForSelection(const QItemSelection &selection) const; int horizontalOffset() const; int verticalOffset() const; - void scrollContentsBy(int dx, int dy); + void rowsInserted(const QModelIndex &parent, int start, int end); + void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); // QColumnView functions + void scrollContentsBy(int dx, int dy); virtual QAbstractItemView* createColumn(const QModelIndex &rootIndex); void initializeColumn(QAbstractItemView *column) const; -protected Q_SLOTS: - // QAbstractItemView overloads - void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); - private: Q_DECLARE_PRIVATE(QColumnView) Q_DISABLE_COPY(QColumnView) diff --git a/src/gui/itemviews/qcolumnview_p.h b/src/gui/itemviews/qcolumnview_p.h index 92a4d2a..3f99220 100644 --- a/src/gui/itemviews/qcolumnview_p.h +++ b/src/gui/itemviews/qcolumnview_p.h @@ -60,7 +60,7 @@ #include <private/qabstractitemview_p.h> #include <QtCore/qabstractitemmodel.h> -#include <QtCore/qtimeline.h> +#include <QtCore/qpropertyanimation.h> #include <QtGui/qabstractitemdelegate.h> #include <QtGui/qabstractitemview.h> #include <QtGui/qitemdelegate.h> @@ -148,16 +148,21 @@ public: void closeColumns(const QModelIndex &parent = QModelIndex(), bool build = false); void doLayout(); void setPreviewWidget(QWidget *widget); + void checkColumnCreation(const QModelIndex &parent); + void _q_gripMoved(int offset); void _q_changeCurrentColumn(); void _q_clicked(const QModelIndex &index); + void _q_columnsInserted(const QModelIndex &parent, int start, int end); QList<QAbstractItemView*> columns; QVector<int> columnSizes; // used during init and corner moving bool showResizeGrips; int offset; - QTimeLine currentAnimation; +#ifndef QT_NO_ANIMATION + QPropertyAnimation currentAnimation; +#endif QWidget *previewWidget; QAbstractItemView *previewColumn; }; diff --git a/src/gui/itemviews/qdirmodel.cpp b/src/gui/itemviews/qdirmodel.cpp index c3a080c..c5618b6 100644 --- a/src/gui/itemviews/qdirmodel.cpp +++ b/src/gui/itemviews/qdirmodel.cpp @@ -44,6 +44,7 @@ #ifndef QT_NO_DIRMODEL #include <qstack.h> #include <qfile.h> +#include <qfilesystemmodel.h> #include <qurl.h> #include <qmime.h> #include <qpair.h> @@ -1338,14 +1339,14 @@ QString QDirModelPrivate::size(const QModelIndex &index) const const quint64 tb = 1024 * gb; quint64 bytes = n->info.size(); if (bytes >= tb) - return QLocale().toString(bytes / tb) + QString::fromLatin1(" TB"); + return QFileSystemModel::tr("%1 TB").arg(QLocale().toString(qreal(bytes) / tb, 'f', 3)); if (bytes >= gb) - return QLocale().toString(bytes / gb) + QString::fromLatin1(" GB"); + return QFileSystemModel::tr("%1 GB").arg(QLocale().toString(qreal(bytes) / gb, 'f', 2)); if (bytes >= mb) - return QLocale().toString(bytes / mb) + QString::fromLatin1(" MB"); + return QFileSystemModel::tr("%1 MB").arg(QLocale().toString(qreal(bytes) / mb, 'f', 1)); if (bytes >= kb) - return QLocale().toString(bytes / kb) + QString::fromLatin1(" KB"); - return QLocale().toString(bytes) + QString::fromLatin1(" bytes"); + return QFileSystemModel::tr("%1 KB").arg(QLocale().toString(bytes / kb)); + return QFileSystemModel::tr("%1 bytes").arg(QLocale().toString(bytes)); } QString QDirModelPrivate::type(const QModelIndex &index) const diff --git a/src/gui/itemviews/qfileiconprovider.cpp b/src/gui/itemviews/qfileiconprovider.cpp index 6338e49..dd4341b 100644 --- a/src/gui/itemviews/qfileiconprovider.cpp +++ b/src/gui/itemviews/qfileiconprovider.cpp @@ -48,15 +48,14 @@ #include <qpixmapcache.h> #if defined(Q_WS_WIN) #define _WIN32_IE 0x0500 +#include <qt_windows.h> +#include <commctrl.h> #include <objbase.h> #include <private/qpixmapdata_p.h> #elif defined(Q_WS_MAC) -#include <private/qt_mac_p.h> +#include <private/qt_cocoa_helpers_mac_p.h> #endif #include <private/qfunctions_p.h> -#ifdef Q_OS_WINCE -#include <Commctrl.h> -#endif #ifndef SHGFI_ADDOVERLAYS #define SHGFI_ADDOVERLAYS 0x000000020 @@ -215,8 +214,7 @@ QIcon QFileIconProvider::icon(IconType type) const QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const { QIcon retIcon; - QString fileExtension = fileInfo.suffix().toUpper(); - fileExtension.prepend( QLatin1String(".") ); + const QString fileExtension = QLatin1Char('.') + fileInfo.suffix().toUpper(); QString key; if (fileInfo.isFile() && !fileInfo.isExecutable() && !fileInfo.isSymLink()) @@ -244,10 +242,10 @@ QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const //Get the small icon #ifndef Q_OS_WINCE - val = SHGetFileInfo((const WCHAR *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, + val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_SMALLICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS); #else - val = SHGetFileInfo((const WCHAR *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, + val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_SYSICONINDEX); #endif if (val) { @@ -283,10 +281,10 @@ QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const //Get the big icon #ifndef Q_OS_WINCE - val = SHGetFileInfo((const WCHAR *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, + val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_LARGEICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS); #else - val = SHGetFileInfo((const WCHAR *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, + val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, sizeof(SHFILEINFO), SHGFI_LARGEICON|SHGFI_SYSICONINDEX); #endif if (val) { @@ -353,10 +351,11 @@ QIcon QFileIconProviderPrivate::getMacIcon(const QFileInfo &fi) const return retIcon; IconRef iconRef; SInt16 iconLabel; - status = GetIconRefFromFileInfo(&macRef, macName.length, macName.unicode, kIconServicesCatalogInfoMask, &info, kIconServicesNormalUsageFlag, &iconRef, &iconLabel); + status = GetIconRefFromFileInfo(&macRef, macName.length, macName.unicode, + kIconServicesCatalogInfoMask, &info, kIconServicesNormalUsageFlag, + &iconRef, &iconLabel); if (status != noErr) return retIcon; - extern void qt_mac_constructQIconFromIconRef(const IconRef, const IconRef, QIcon*, QStyle::StandardPixmap = QStyle::SP_CustomBase); // qmacstyle_mac.cpp qt_mac_constructQIconFromIconRef(iconRef, 0, &retIcon); ReleaseIconRef(iconRef); @@ -391,11 +390,9 @@ QIcon QFileIconProvider::icon(const QFileInfo &info) const return icon; #endif if (info.isRoot()) -#if defined (Q_WS_WIN) && !defined(Q_OS_WINCE) +#if defined (Q_WS_WIN) && !defined(Q_WS_WINCE) { - uint type = DRIVE_UNKNOWN; - QT_WA({ type = GetDriveTypeW((wchar_t *)info.absoluteFilePath().utf16()); }, - { type = GetDriveTypeA(info.absoluteFilePath().toLocal8Bit()); }); + UINT type = GetDriveType((wchar_t *)info.absoluteFilePath().utf16()); switch (type) { case DRIVE_REMOVABLE: @@ -451,26 +448,22 @@ QString QFileIconProvider::type(const QFileInfo &info) const } if (info.isDir()) - return QApplication::translate("QFileDialog", #ifdef Q_WS_WIN - "File Folder", "Match Windows Explorer" + return QApplication::translate("QFileDialog", "File Folder", "Match Windows Explorer"); #else - "Folder", "All other platforms" + return QApplication::translate("QFileDialog", "Folder", "All other platforms"); #endif - ); // Windows - "File Folder" // OS X - "Folder" // Konqueror - "Folder" // Nautilus - "folder" if (info.isSymLink()) - return QApplication::translate("QFileDialog", #ifdef Q_OS_MAC - "Alias", "Mac OS X Finder" + return QApplication::translate("QFileDialog", "Alias", "Mac OS X Finder"); #else - "Shortcut", "All other platforms" + return QApplication::translate("QFileDialog", "Shortcut", "All other platforms"); #endif - ); // OS X - "Alias" // Windows - "Shortcut" // Konqueror - "Folder" or "TXT File" i.e. what it is pointing to diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp index d5a20cb..2419c18 100644 --- a/src/gui/itemviews/qheaderview.cpp +++ b/src/gui/itemviews/qheaderview.cpp @@ -62,9 +62,11 @@ #ifndef QT_NO_DATASTREAM #include <qdatastream.h> +#endif QT_BEGIN_NAMESPACE +#ifndef QT_NO_DATASTREAM QDataStream &operator<<(QDataStream &out, const QHeaderViewPrivate::SectionSpan &span) { span.write(out); @@ -76,7 +78,7 @@ QDataStream &operator>>(QDataStream &in, QHeaderViewPrivate::SectionSpan &span) span.read(in); return in; } -#endif +#endif // QT_NO_DATASTREAM /*! @@ -520,31 +522,29 @@ int QHeaderView::length() const QSize QHeaderView::sizeHint() const { Q_D(const QHeaderView); - if (count() < 1) - return QSize(0, 0); if (d->cachedSizeHint.isValid()) return d->cachedSizeHint; - int width = 0; - int height = 0; + d->cachedSizeHint = QSize(0, 0); //reinitialize the cached size hint + const int sectionCount = count(); + // get size hint for the first n sections - int c = qMin(count(), 100); - for (int i = 0; i < c; ++i) { + int i = 0; + for (int checked = 0; checked < 100 && i < sectionCount; ++i) { if (isSectionHidden(i)) continue; + checked++; QSize hint = sectionSizeFromContents(i); - width = qMax(hint.width(), width); - height = qMax(hint.height(), height); + d->cachedSizeHint = d->cachedSizeHint.expandedTo(hint); } // get size hint for the last n sections - c = qMax(count() - 100, c); - for (int j = count() - 1; j >= c; --j) { + i = qMax(i, sectionCount - 100 ); + for (int j = sectionCount - 1, checked = 0; j >= i && checked < 100; --j) { if (isSectionHidden(j)) continue; + checked++; QSize hint = sectionSizeFromContents(j); - width = qMax(hint.width(), width); - height = qMax(hint.height(), height); + d->cachedSizeHint = d->cachedSizeHint.expandedTo(hint); } - d->cachedSizeHint = QSize(width, height); return d->cachedSizeHint; } @@ -1151,7 +1151,8 @@ void QHeaderView::setResizeMode(ResizeMode mode) \overload Sets the constraints on how the section specified by \a logicalIndex in - the header can be resized to those described by the given \a mode. + the header can be resized to those described by the given \a mode. The logical + index should exist at the time this function is called. \note This setting will be ignored for the last section if the stretchLastSection property is set to true. This is the default for the horizontal headers provided @@ -1195,7 +1196,7 @@ QHeaderView::ResizeMode QHeaderView::resizeMode(int logicalIndex) const Q_D(const QHeaderView); int visual = visualIndex(logicalIndex); Q_ASSERT(visual != -1); - return d->visualIndexResizeMode(visual); + return d->headerSectionResizeMode(visual); } /*! @@ -1234,7 +1235,7 @@ void QHeaderView::setSortIndicatorShown(bool show) if (sortIndicatorSection() < 0 || sortIndicatorSection() > count()) return; - if (d->visualIndexResizeMode(sortIndicatorSection()) == ResizeToContents) + if (d->headerSectionResizeMode(sortIndicatorSection()) == ResizeToContents) resizeSections(); d->viewport->update(); @@ -1535,7 +1536,7 @@ bool QHeaderView::restoreState(const QByteArray &state) } return false; } -#endif +#endif // QT_NO_DATASTREAM /*! \reimp @@ -1969,20 +1970,19 @@ void QHeaderView::currentChanged(const QModelIndex ¤t, const QModelIndex & if (d->orientation == Qt::Horizontal && current.column() != old.column()) { if (old.isValid() && old.parent() == d->root) - d->setDirtyRegion(QRect(sectionViewportPosition(old.column()), 0, + d->viewport->update(QRect(sectionViewportPosition(old.column()), 0, sectionSize(old.column()), d->viewport->height())); if (current.isValid() && current.parent() == d->root) - d->setDirtyRegion(QRect(sectionViewportPosition(current.column()), 0, + d->viewport->update(QRect(sectionViewportPosition(current.column()), 0, sectionSize(current.column()), d->viewport->height())); } else if (d->orientation == Qt::Vertical && current.row() != old.row()) { if (old.isValid() && old.parent() == d->root) - d->setDirtyRegion(QRect(0, sectionViewportPosition(old.row()), + d->viewport->update(QRect(0, sectionViewportPosition(old.row()), d->viewport->width(), sectionSize(old.row()))); if (current.isValid() && current.parent() == d->root) - d->setDirtyRegion(QRect(0, sectionViewportPosition(current.row()), + d->viewport->update(QRect(0, sectionViewportPosition(current.row()), d->viewport->width(), sectionSize(current.row()))); } - d->updateDirtyRegion(); } @@ -2538,7 +2538,7 @@ QSize QHeaderView::sectionSizeFromContents(int logicalIndex) const if (opt.icon.isNull()) opt.icon = qvariant_cast<QPixmap>(variant); QSize size = style()->sizeFromContents(QStyle::CT_HeaderSection, &opt, QSize(), this); - if (isSortIndicatorShown() && sortIndicatorSection() == logicalIndex) { + if (isSortIndicatorShown()) { int margin = style()->pixelMetric(QStyle::PM_HeaderMargin, &opt, this); if (d->orientation == Qt::Horizontal) size.rwidth() += size.height() + margin; @@ -2936,22 +2936,25 @@ int QHeaderViewPrivate::lastVisibleVisualIndex() const void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool useGlobalMode) { Q_Q(QHeaderView); + //stop the timer in case it is delayed + delayedResize.stop(); executePostedLayout(); if (sectionCount == 0) return; + + if (resizeRecursionBlock) + return; + resizeRecursionBlock = true; + invalidateCachedSizeHint(); + const int lastVisibleSection = lastVisibleVisualIndex(); + // find stretchLastSection if we have it int stretchSection = -1; - if (stretchLastSection && !useGlobalMode) { - for (int i = sectionCount - 1; i >= 0; --i) { - if (!isVisualIndexHidden(i)) { - stretchSection = i; - break; - } - } - } + if (stretchLastSection && !useGlobalMode) + stretchSection = lastVisibleVisualIndex(); // count up the number of strected sections and how much space left for them int lengthToStrech = (orientation == Qt::Horizontal ? viewport->width() : viewport->height()); @@ -2965,7 +2968,7 @@ void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool if (useGlobalMode && (i != stretchSection)) resizeMode = globalMode; else - resizeMode = (i == stretchSection ? QHeaderView::Stretch : visualIndexResizeMode(i)); + resizeMode = (i == stretchSection ? QHeaderView::Stretch : headerSectionResizeMode(i)); if (resizeMode == QHeaderView::Stretch) { ++numberOfStretchedSections; @@ -2997,7 +3000,6 @@ void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool int spanStartSection = 0; int previousSectionLength = 0; - const int lastVisibleSection = lastVisibleVisualIndex(); QHeaderView::ResizeMode previousSectionResizeMode = QHeaderView::Interactive; @@ -3016,7 +3018,7 @@ void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool else resizeMode = (i == stretchSection ? QHeaderView::Stretch - : visualIndexResizeMode(i)); + : newSectionResizeMode); if (resizeMode == QHeaderView::Stretch && stretchSectionLength != -1) { if (i == lastVisibleSection) newSectionLength = qMax(stretchSectionLength, lastSectionSize); @@ -3053,7 +3055,7 @@ void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool (sectionCount - spanStartSection) * previousSectionLength, previousSectionResizeMode); //Q_ASSERT(headerLength() == length); - + resizeRecursionBlock = false; viewport->update(); } @@ -3470,11 +3472,10 @@ void QHeaderViewPrivate::setGlobalHeaderResizeMode(QHeaderView::ResizeMode mode) int QHeaderViewPrivate::viewSectionSizeHint(int logical) const { - Q_Q(const QHeaderView); - if (QAbstractItemView *parent = qobject_cast<QAbstractItemView*>(q->parent())) { + if (QAbstractItemView *view = qobject_cast<QAbstractItemView*>(parent)) { return (orientation == Qt::Horizontal - ? parent->sizeHintForColumn(logical) - : parent->sizeHintForRow(logical)); + ? view->sizeHintForColumn(logical) + : view->sizeHintForRow(logical)); } return 0; } @@ -3570,9 +3571,9 @@ bool QHeaderViewPrivate::read(QDataStream &in) return true; } -QT_END_NAMESPACE +#endif // QT_NO_DATASTREAM -#endif // QT_NO_DATASTREAEM +QT_END_NAMESPACE #endif // QT_NO_ITEMVIEWS diff --git a/src/gui/itemviews/qheaderview.h b/src/gui/itemviews/qheaderview.h index f752ae2..3a66c9a 100644 --- a/src/gui/itemviews/qheaderview.h +++ b/src/gui/itemviews/qheaderview.h @@ -221,14 +221,13 @@ protected: bool isIndexHidden(const QModelIndex &index) const; QModelIndex moveCursor(CursorAction, Qt::KeyboardModifiers); - void setSelection(const QRect&, QItemSelectionModel::SelectionFlags); + void setSelection(const QRect& rect, QItemSelectionModel::SelectionFlags flags); QRegion visualRegionForSelection(const QItemSelection &selection) const; void initStyleOption(QStyleOptionHeader *option) const; private: Q_PRIVATE_SLOT(d_func(), void _q_sectionsRemoved(const QModelIndex &parent, int logicalFirst, int logicalLast)) Q_PRIVATE_SLOT(d_func(), void _q_layoutAboutToBeChanged()) - Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged()) Q_DECLARE_PRIVATE(QHeaderView) Q_DISABLE_COPY(QHeaderView) }; diff --git a/src/gui/itemviews/qheaderview_p.h b/src/gui/itemviews/qheaderview_p.h index 3cea0b7..1e34521 100644 --- a/src/gui/itemviews/qheaderview_p.h +++ b/src/gui/itemviews/qheaderview_p.h @@ -90,6 +90,7 @@ public: highlightSelected(false), stretchLastSection(false), cascadingResizing(false), + resizeRecursionBlock(false), stretchSections(0), contentsSections(0), minimumSectionSize(-1), @@ -169,10 +170,6 @@ public: if (!sectionHidden.isEmpty()) sectionHidden.setBit(visual, hidden); } - inline QHeaderView::ResizeMode visualIndexResizeMode(int visual) const { - return headerSectionResizeMode(visual); - } - inline bool hasAutoResizeSections() const { return stretchSections || stretchLastSection || contentsSections; } @@ -210,7 +207,7 @@ public: } inline bool sectionIsCascadable(int visual) const { - return visualIndexResizeMode(visual) == QHeaderView::Interactive; + return headerSectionResizeMode(visual) == QHeaderView::Interactive; } inline int modelSectionCount() const { @@ -230,7 +227,6 @@ public: inline void executePostedResize() const { if (delayedResize.isActive() && state == NoState) { - delayedResize.stop(); const_cast<QHeaderView*>(q_func())->resizeSections(); } } @@ -274,6 +270,7 @@ public: bool highlightSelected; bool stretchLastSection; bool cascadingResizing; + bool resizeRecursionBlock; int stretchSections; int contentsSections; int defaultSectionSize; diff --git a/src/gui/itemviews/qitemdelegate.cpp b/src/gui/itemviews/qitemdelegate.cpp index 2dd5540..bd6dc62 100644 --- a/src/gui/itemviews/qitemdelegate.cpp +++ b/src/gui/itemviews/qitemdelegate.cpp @@ -861,6 +861,8 @@ void QItemDelegate::drawBackground(QPainter *painter, /*! \internal + + Code duplicated in QCommonStylePrivate::viewItemLayout */ void QItemDelegate::doLayout(const QStyleOptionViewItem &option, @@ -882,8 +884,10 @@ void QItemDelegate::doLayout(const QStyleOptionViewItem &option, int w, h; textRect->adjust(-textMargin, 0, textMargin, 0); // add width padding - if (textRect->height() == 0 && !hasPixmap) + if (textRect->height() == 0 && (!hasPixmap || !hint)) { + //if there is no text, we still want to have a decent height for the item sizeHint and the editor size textRect->setHeight(option.fontMetrics.height()); + } QSize pm(0, 0); if (hasPixmap) { @@ -1219,7 +1223,7 @@ bool QItemDelegate::eventFilter(QObject *object, QEvent *event) if (editor->parentWidget()) editor->parentWidget()->setFocus(); return true; - } else if (event->type() == QEvent::FocusOut || event->type() == QEvent::Hide) { + } else if (event->type() == QEvent::FocusOut || (event->type() == QEvent::Hide && editor->isWindow())) { //the Hide event will take care of he editors that are in fact complete dialogs if (!editor->isActiveWindow() || (QApplication::focusWidget() != editor)) { QWidget *w = QApplication::focusWidget(); @@ -1234,12 +1238,7 @@ bool QItemDelegate::eventFilter(QObject *object, QEvent *event) if (QDragManager::self() && QDragManager::self()->object != 0) return false; #endif - // Opening a modal dialog will start a new eventloop - // that will process the deleteLater event. - if (QApplication::activeModalWidget() - && !QApplication::activeModalWidget()->isAncestorOf(editor) - && qobject_cast<QDialog*>(QApplication::activeModalWidget())) - return false; + emit commitData(editor); emit closeEditor(editor, NoHint); } @@ -1297,8 +1296,14 @@ bool QItemDelegate::editorEvent(QEvent *event, return false; } - Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked + Qt::CheckState state; + if ( flags & Qt::ItemIsTristate ) { + state = static_cast<Qt::CheckState>( (value.toInt() + 1) % 3 ); + } else { + state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked ? Qt::Unchecked : Qt::Checked); + } + return model->setData(index, state, Qt::CheckStateRole); } diff --git a/src/gui/itemviews/qitemselectionmodel.cpp b/src/gui/itemviews/qitemselectionmodel.cpp index d9f55e3..9dad95f 100644 --- a/src/gui/itemviews/qitemselectionmodel.cpp +++ b/src/gui/itemviews/qitemselectionmodel.cpp @@ -270,67 +270,77 @@ QItemSelectionRange QItemSelectionRange::intersect(const QItemSelectionRange &ot */ -/*! - Returns the list of model index items stored in the selection. -*/ +/* + \internal -QModelIndexList QItemSelectionRange::indexes() const + utility function for getting the indexes from a range + it avoid concatenating list and works on one + */ + +static void indexesFromRange(const QItemSelectionRange &range, QModelIndexList &result) { - QModelIndex index; - QModelIndexList result; - if (isValid() && model()) { - for (int column = left(); column <= right(); ++column) { - for (int row = top(); row <= bottom(); ++row) { - index = model()->index(row, column, parent()); - Qt::ItemFlags flags = model()->flags(index); + if (range.isValid() && range.model()) { + for (int column = range.left(); column <= range.right(); ++column) { + for (int row = range.top(); row <= range.bottom(); ++row) { + QModelIndex index = range.model()->index(row, column, range.parent()); + Qt::ItemFlags flags = range.model()->flags(index); if ((flags & Qt::ItemIsSelectable) && (flags & Qt::ItemIsEnabled)) result.append(index); } } } - return result; } /*! - \class QItemSelection + Returns the list of model index items stored in the selection. +*/ - \brief The QItemSelection class manages information about selected items in a model. +QModelIndexList QItemSelectionRange::indexes() const +{ + QModelIndexList result; + indexesFromRange(*this, result); + return result; +} - \ingroup model-view +/*! + \class QItemSelection - A QItemSelection describes the items in a model that have been - selected by the user. A QItemSelection is basically a list of - selection ranges, see QItemSelectionRange. It provides functions for - creating and manipulating selections, and selecting a range of items - from a model. + \brief The QItemSelection class manages information about selected items in a model. - The QItemSelection class is one of the \l{Model/View Classes} - and is part of Qt's \l{Model/View Programming}{model/view framework}. + \ingroup model-view - An item selection can be constructed and initialized to contain a - range of items from an existing model. The following example constructs - a selection that contains a range of items from the given \c model, - beginning at the \c topLeft, and ending at the \c bottomRight. + A QItemSelection describes the items in a model that have been + selected by the user. A QItemSelection is basically a list of + selection ranges, see QItemSelectionRange. It provides functions for + creating and manipulating selections, and selecting a range of items + from a model. - \snippet doc/src/snippets/code/src_gui_itemviews_qitemselectionmodel.cpp 0 + The QItemSelection class is one of the \l{Model/View Classes} + and is part of Qt's \l{Model/View Programming}{model/view framework}. + + An item selection can be constructed and initialized to contain a + range of items from an existing model. The following example constructs + a selection that contains a range of items from the given \c model, + beginning at the \c topLeft, and ending at the \c bottomRight. - An empty item selection can be constructed, and later populated as - required. So, if the model is going to be unavailable when we construct - the item selection, we can rewrite the above code in the following way: + \snippet doc/src/snippets/code/src_gui_itemviews_qitemselectionmodel.cpp 0 - \snippet doc/src/snippets/code/src_gui_itemviews_qitemselectionmodel.cpp 1 + An empty item selection can be constructed, and later populated as + required. So, if the model is going to be unavailable when we construct + the item selection, we can rewrite the above code in the following way: - QItemSelection saves memory, and avoids unnecessary work, by working with - selection ranges rather than recording the model item index for each - item in the selection. Generally, an instance of this class will contain - a list of non-overlapping selection ranges. + \snippet doc/src/snippets/code/src_gui_itemviews_qitemselectionmodel.cpp 1 - Use merge() to merge one item selection into another without making - overlapping ranges. Use split() to split one selection range into - smaller ranges based on a another selection range. + QItemSelection saves memory, and avoids unnecessary work, by working with + selection ranges rather than recording the model item index for each + item in the selection. Generally, an instance of this class will contain + a list of non-overlapping selection ranges. - \sa {Model/View Programming}, QItemSelectionModel + Use merge() to merge one item selection into another without making + overlapping ranges. Use split() to split one selection range into + smaller ranges based on a another selection range. + \sa {Model/View Programming}, QItemSelectionModel */ /*! @@ -404,19 +414,19 @@ QModelIndexList QItemSelection::indexes() const QModelIndexList result; QList<QItemSelectionRange>::const_iterator it = begin(); for (; it != end(); ++it) - result += (*it).indexes(); + indexesFromRange(*it, result); return result; } /*! - Merges the \a other selection with this QItemSelection using the - \a command given. This method guarantees that no ranges are overlapping. + Merges the \a other selection with this QItemSelection using the + \a command given. This method guarantees that no ranges are overlapping. - Note that only QItemSelectionModel::Select, - QItemSelectionModel::Deselect, and QItemSelectionModel::Toggle are - supported. + Note that only QItemSelectionModel::Select, + QItemSelectionModel::Deselect, and QItemSelectionModel::Toggle are + supported. - \sa split() + \sa split() */ void QItemSelection::merge(const QItemSelection &other, QItemSelectionModel::SelectionFlags command) { @@ -468,10 +478,10 @@ void QItemSelection::merge(const QItemSelection &other, QItemSelectionModel::Sel } /*! - Splits the selection \a range using the selection \a other range. - Removes all items in \a other from \a range and puts the result in \a result. - This can be compared with the semantics of the \e subtract operation of a set. - \sa merge() + Splits the selection \a range using the selection \a other range. + Removes all items in \a other from \a range and puts the result in \a result. + This can be compared with the semantics of the \e subtract operation of a set. + \sa merge() */ void QItemSelection::split(const QItemSelectionRange &range, @@ -518,11 +528,11 @@ void QItemSelection::split(const QItemSelectionRange &range, } /*! - \internal + \internal - returns a QItemSelection where all ranges have been expanded to: - Rows: left: 0 and right: columnCount()-1 - Columns: top: 0 and bottom: rowCount()-1 + returns a QItemSelection where all ranges have been expanded to: + Rows: left: 0 and right: columnCount()-1 + Columns: top: 0 and bottom: rowCount()-1 */ QItemSelection QItemSelectionModelPrivate::expandSelection(const QItemSelection &selection, @@ -557,7 +567,7 @@ QItemSelection QItemSelectionModelPrivate::expandSelection(const QItemSelection } /*! - \internal + \internal */ void QItemSelectionModelPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) @@ -588,7 +598,7 @@ void QItemSelectionModelPrivate::_q_rowsAboutToBeRemoved(const QModelIndex &pare } /*! - \internal + \internal */ void QItemSelectionModelPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end) @@ -619,9 +629,9 @@ void QItemSelectionModelPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &p } /*! - \internal + \internal - Split selection ranges if columns are about to be inserted in the middle. + Split selection ranges if columns are about to be inserted in the middle. */ void QItemSelectionModelPrivate::_q_columnsAboutToBeInserted(const QModelIndex &parent, int start, int end) @@ -648,9 +658,9 @@ void QItemSelectionModelPrivate::_q_columnsAboutToBeInserted(const QModelIndex & } /*! - \internal + \internal - Split selection ranges if rows are about to be inserted in the middle. + Split selection ranges if rows are about to be inserted in the middle. */ void QItemSelectionModelPrivate::_q_rowsAboutToBeInserted(const QModelIndex &parent, int start, int end) @@ -677,11 +687,11 @@ void QItemSelectionModelPrivate::_q_rowsAboutToBeInserted(const QModelIndex &par } /*! - \internal + \internal - Split selection into individual (persistent) indexes. This is done in - preparation for the layoutChanged() signal, where the indexes can be - merged again. + Split selection into individual (persistent) indexes. This is done in + preparation for the layoutChanged() signal, where the indexes can be + merged again. */ void QItemSelectionModelPrivate::_q_layoutAboutToBeChanged() { @@ -715,10 +725,10 @@ void QItemSelectionModelPrivate::_q_layoutAboutToBeChanged() } /*! - \internal + \internal - Merges \a indexes into an item selection made up of ranges. - Assumes that the indexes are sorted. + Merges \a indexes into an item selection made up of ranges. + Assumes that the indexes are sorted. */ static QItemSelection mergeIndexes(const QList<QPersistentModelIndex> &indexes) { @@ -763,9 +773,9 @@ static QItemSelection mergeIndexes(const QList<QPersistentModelIndex> &indexes) } /*! - \internal + \internal - Merge the selected indexes into selection ranges again. + Merge the selected indexes into selection ranges again. */ void QItemSelectionModelPrivate::_q_layoutChanged() { @@ -807,41 +817,41 @@ void QItemSelectionModelPrivate::_q_layoutChanged() } /*! - \class QItemSelectionModel + \class QItemSelectionModel - \brief The QItemSelectionModel class keeps track of a view's selected items. + \brief The QItemSelectionModel class keeps track of a view's selected items. - \ingroup model-view + \ingroup model-view - A QItemSelectionModel keeps track of the selected items in a view, or - in several views onto the same model. It also keeps track of the - currently selected item in a view. + A QItemSelectionModel keeps track of the selected items in a view, or + in several views onto the same model. It also keeps track of the + currently selected item in a view. - The QItemSelectionModel class is one of the \l{Model/View Classes} - and is part of Qt's \l{Model/View Programming}{model/view framework}. + The QItemSelectionModel class is one of the \l{Model/View Classes} + and is part of Qt's \l{Model/View Programming}{model/view framework}. - The selected items are stored using ranges. Whenever you want to - modify the selected items use select() and provide either a - QItemSelection, or a QModelIndex and a QItemSelectionModel::SelectionFlag. + The selected items are stored using ranges. Whenever you want to + modify the selected items use select() and provide either a + QItemSelection, or a QModelIndex and a QItemSelectionModel::SelectionFlag. - The QItemSelectionModel takes a two layer approach to selection - management, dealing with both selected items that have been committed - and items that are part of the current selection. The current - selected items are part of the current interactive selection (for - example with rubber-band selection or keyboard-shift selections). + The QItemSelectionModel takes a two layer approach to selection + management, dealing with both selected items that have been committed + and items that are part of the current selection. The current + selected items are part of the current interactive selection (for + example with rubber-band selection or keyboard-shift selections). - To update the currently selected items, use the bitwise OR of - QItemSelectionModel::Current and any of the other SelectionFlags. - If you omit the QItemSelectionModel::Current command, a new current - selection will be created, and the previous one added to the whole - selection. All functions operate on both layers; for example, - selectedItems() will return items from both layers. + To update the currently selected items, use the bitwise OR of + QItemSelectionModel::Current and any of the other SelectionFlags. + If you omit the QItemSelectionModel::Current command, a new current + selection will be created, and the previous one added to the whole + selection. All functions operate on both layers; for example, + selectedItems() will return items from both layers. - \sa {Model/View Programming}, QAbstractItemModel, {Chart Example} + \sa {Model/View Programming}, QAbstractItemModel, {Chart Example} */ /*! - Constructs a selection model that operates on the specified item \a model. + Constructs a selection model that operates on the specified item \a model. */ QItemSelectionModel::QItemSelectionModel(QAbstractItemModel *model) : QObject(*new QItemSelectionModelPrivate, model) @@ -864,7 +874,7 @@ QItemSelectionModel::QItemSelectionModel(QAbstractItemModel *model) } /*! - Constructs a selection model that operates on the specified item \a model with \a parent. + Constructs a selection model that operates on the specified item \a model with \a parent. */ QItemSelectionModel::QItemSelectionModel(QAbstractItemModel *model, QObject *parent) : QObject(*new QItemSelectionModelPrivate, parent) @@ -887,7 +897,7 @@ QItemSelectionModel::QItemSelectionModel(QAbstractItemModel *model, QObject *par } /*! - \internal + \internal */ QItemSelectionModel::QItemSelectionModel(QItemSelectionModelPrivate &dd, QAbstractItemModel *model) : QObject(dd, model) @@ -910,7 +920,7 @@ QItemSelectionModel::QItemSelectionModel(QItemSelectionModelPrivate &dd, QAbstra } /*! - Destroys the selection model. + Destroys the selection model. */ QItemSelectionModel::~QItemSelectionModel() { @@ -932,10 +942,10 @@ QItemSelectionModel::~QItemSelectionModel() } /*! - Selects the model item \a index using the specified \a command, and emits - selectionChanged(). + Selects the model item \a index using the specified \a command, and emits + selectionChanged(). - \sa QItemSelectionModel::SelectionFlags + \sa QItemSelectionModel::SelectionFlags */ void QItemSelectionModel::select(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) { @@ -944,37 +954,37 @@ void QItemSelectionModel::select(const QModelIndex &index, QItemSelectionModel:: } /*! - \fn void QItemSelectionModel::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) + \fn void QItemSelectionModel::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) - This signal is emitted whenever the current item changes. The \a previous - model item index is replaced by the \a current index as the selection's - current item. + This signal is emitted whenever the current item changes. The \a previous + model item index is replaced by the \a current index as the selection's + current item. - Note that this signal will not be emitted when the item model is reset. + Note that this signal will not be emitted when the item model is reset. - \sa currentIndex() setCurrentIndex() selectionChanged() + \sa currentIndex() setCurrentIndex() selectionChanged() */ /*! - \fn void QItemSelectionModel::currentColumnChanged(const QModelIndex ¤t, const QModelIndex &previous) + \fn void QItemSelectionModel::currentColumnChanged(const QModelIndex ¤t, const QModelIndex &previous) - This signal is emitted if the \a current item changes and its column is - different to the column of the \a previous current item. + This signal is emitted if the \a current item changes and its column is + different to the column of the \a previous current item. - Note that this signal will not be emitted when the item model is reset. + Note that this signal will not be emitted when the item model is reset. - \sa currentChanged() currentRowChanged() currentIndex() setCurrentIndex() + \sa currentChanged() currentRowChanged() currentIndex() setCurrentIndex() */ /*! - \fn void QItemSelectionModel::currentRowChanged(const QModelIndex ¤t, const QModelIndex &previous) + \fn void QItemSelectionModel::currentRowChanged(const QModelIndex ¤t, const QModelIndex &previous) - This signal is emitted if the \a current item changes and its row is - different to the row of the \a previous current item. + This signal is emitted if the \a current item changes and its row is + different to the row of the \a previous current item. - Note that this signal will not be emitted when the item model is reset. + Note that this signal will not be emitted when the item model is reset. - \sa currentChanged() currentColumnChanged() currentIndex() setCurrentIndex() + \sa currentChanged() currentColumnChanged() currentIndex() setCurrentIndex() */ /*! @@ -991,32 +1001,32 @@ void QItemSelectionModel::select(const QModelIndex &index, QItemSelectionModel:: */ /*! - \enum QItemSelectionModel::SelectionFlag + \enum QItemSelectionModel::SelectionFlag - This enum describes the way the selection model will be updated. + This enum describes the way the selection model will be updated. - \value NoUpdate No selection will be made. - \value Clear The complete selection will be cleared. - \value Select All specified indexes will be selected. - \value Deselect All specified indexes will be deselected. - \value Toggle All specified indexes will be selected or - deselected depending on their current state. - \value Current The current selection will be updated. - \value Rows All indexes will be expanded to span rows. - \value Columns All indexes will be expanded to span columns. - \value SelectCurrent A combination of Select and Current, provided for - convenience. - \value ToggleCurrent A combination of Toggle and Current, provided for - convenience. - \value ClearAndSelect A combination of Clear and Select, provided for - convenience. + \value NoUpdate No selection will be made. + \value Clear The complete selection will be cleared. + \value Select All specified indexes will be selected. + \value Deselect All specified indexes will be deselected. + \value Toggle All specified indexes will be selected or + deselected depending on their current state. + \value Current The current selection will be updated. + \value Rows All indexes will be expanded to span rows. + \value Columns All indexes will be expanded to span columns. + \value SelectCurrent A combination of Select and Current, provided for + convenience. + \value ToggleCurrent A combination of Toggle and Current, provided for + convenience. + \value ClearAndSelect A combination of Clear and Select, provided for + convenience. */ /*! - Selects the item \a selection using the specified \a command, and emits - selectionChanged(). + Selects the item \a selection using the specified \a command, and emits + selectionChanged(). - \sa QItemSelectionModel::SelectionFlag + \sa QItemSelectionModel::SelectionFlag */ void QItemSelectionModel::select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) { @@ -1056,7 +1066,7 @@ void QItemSelectionModel::select(const QItemSelection &selection, QItemSelection } /*! - Clears the selection model. Emits selectionChanged() and currentChanged(). + Clears the selection model. Emits selectionChanged() and currentChanged(). */ void QItemSelectionModel::clear() { @@ -1072,7 +1082,7 @@ void QItemSelectionModel::clear() } /*! - Clears the selection model. Does not emit any signals. + Clears the selection model. Does not emit any signals. */ void QItemSelectionModel::reset() { @@ -1082,8 +1092,8 @@ void QItemSelectionModel::reset() } /*! - \since 4.2 - Clears the selection in the selection model. Emits selectionChanged(). + \since 4.2 + Clears the selection in the selection model. Emits selectionChanged(). */ void QItemSelectionModel::clearSelection() { @@ -1099,14 +1109,14 @@ void QItemSelectionModel::clearSelection() /*! - Sets the model item \a index to be the current item, and emits - currentChanged(). The current item is used for keyboard navigation and - focus indication; it is independent of any selected items, although a - selected item can also be the current item. + Sets the model item \a index to be the current item, and emits + currentChanged(). The current item is used for keyboard navigation and + focus indication; it is independent of any selected items, although a + selected item can also be the current item. - Depending on the specified \a command, the \a index can also become part - of the current selection. - \sa select() + Depending on the specified \a command, the \a index can also become part + of the current selection. + \sa select() */ void QItemSelectionModel::setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) { @@ -1130,8 +1140,8 @@ void QItemSelectionModel::setCurrentIndex(const QModelIndex &index, QItemSelecti } /*! - Returns the model item index for the current item, or an invalid index - if there is no current item. + Returns the model item index for the current item, or an invalid index + if there is no current item. */ QModelIndex QItemSelectionModel::currentIndex() const { @@ -1139,7 +1149,7 @@ QModelIndex QItemSelectionModel::currentIndex() const } /*! - Returns true if the given model item \a index is selected. + Returns true if the given model item \a index is selected. */ bool QItemSelectionModel::isSelected(const QModelIndex &index) const { @@ -1176,12 +1186,12 @@ bool QItemSelectionModel::isSelected(const QModelIndex &index) const } /*! - Returns true if all items are selected in the \a row with the given - \a parent. + Returns true if all items are selected in the \a row with the given + \a parent. - Note that this function is usually faster than calling isSelected() - on all items in the same row and that unselectable items are - ignored. + Note that this function is usually faster than calling isSelected() + on all items in the same row and that unselectable items are + ignored. */ bool QItemSelectionModel::isRowSelected(int row, const QModelIndex &parent) const { @@ -1236,12 +1246,12 @@ bool QItemSelectionModel::isRowSelected(int row, const QModelIndex &parent) cons } /*! - Returns true if all items are selected in the \a column with the given - \a parent. + Returns true if all items are selected in the \a column with the given + \a parent. - Note that this function is usually faster than calling isSelected() - on all items in the same column and that unselectable items are - ignored. + Note that this function is usually faster than calling isSelected() + on all items in the same column and that unselectable items are + ignored. */ bool QItemSelectionModel::isColumnSelected(int column, const QModelIndex &parent) const { @@ -1296,8 +1306,8 @@ bool QItemSelectionModel::isColumnSelected(int column, const QModelIndex &parent } /*! - Returns true if there are any items selected in the \a row with the given - \a parent. + Returns true if there are any items selected in the \a row with the given + \a parent. */ bool QItemSelectionModel::rowIntersectsSelection(int row, const QModelIndex &parent) const { @@ -1325,8 +1335,8 @@ bool QItemSelectionModel::rowIntersectsSelection(int row, const QModelIndex &par } /*! - Returns true if there are any items selected in the \a column with the given - \a parent. + Returns true if there are any items selected in the \a column with the given + \a parent. */ bool QItemSelectionModel::columnIntersectsSelection(int column, const QModelIndex &parent) const { @@ -1366,15 +1376,14 @@ bool QItemSelectionModel::hasSelection() const QItemSelection sel = d->ranges; sel.merge(d->currentSelection, d->currentCommand); return !sel.isEmpty(); - } - else { + } else { return !(d->ranges.isEmpty() && d->currentSelection.isEmpty()); } } /*! - Returns a list of all selected model item indexes. The list contains no - duplicates, and is not sorted. + Returns a list of all selected model item indexes. The list contains no + duplicates, and is not sorted. */ QModelIndexList QItemSelectionModel::selectedIndexes() const { @@ -1385,10 +1394,10 @@ QModelIndexList QItemSelectionModel::selectedIndexes() const } /*! - \since 4.2 - Returns the indexes in the given \a column for the rows where all columns are selected. + \since 4.2 + Returns the indexes in the given \a column for the rows where all columns are selected. - \sa selectedIndexes(), selectedColumns() + \sa selectedIndexes(), selectedColumns() */ QModelIndexList QItemSelectionModel::selectedRows(int column) const @@ -1449,7 +1458,7 @@ QModelIndexList QItemSelectionModel::selectedColumns(int row) const } /*! - Returns the selection ranges stored in the selection model. + Returns the selection ranges stored in the selection model. */ const QItemSelection QItemSelectionModel::selection() const { @@ -1469,7 +1478,7 @@ const QItemSelection QItemSelectionModel::selection() const } /*! - Returns the item model operated on by the selection model. + Returns the item model operated on by the selection model. */ const QAbstractItemModel *QItemSelectionModel::model() const { @@ -1477,8 +1486,8 @@ const QAbstractItemModel *QItemSelectionModel::model() const } /*! - Compares the two selections \a newSelection and \a oldSelection - and emits selectionChanged() with the deselected and selected items. + Compares the two selections \a newSelection and \a oldSelection + and emits selectionChanged() with the deselected and selected items. */ void QItemSelectionModel::emitSelectionChanged(const QItemSelection &newSelection, const QItemSelection &oldSelection) @@ -1553,7 +1562,7 @@ QDebug operator<<(QDebug dbg, const QItemSelectionRange &range) { #ifndef Q_BROKEN_DEBUG_STREAM dbg.nospace() << "QItemSelectionRange(" << range.topLeft() - << "," << range.bottomRight() << ")"; + << ',' << range.bottomRight() << ')'; return dbg.space(); #else qWarning("This compiler doesn't support streaming QItemSelectionRange to QDebug"); diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp index cc6277e..148d204 100644 --- a/src/gui/itemviews/qlistview.cpp +++ b/src/gui/itemviews/qlistview.cpp @@ -588,7 +588,7 @@ void QListView::scrollTo(const QModelIndex &index, ScrollHint hint) const QRect rect = visualRect(index); if (hint == EnsureVisible && d->viewport->rect().contains(rect)) { - d->setDirtyRegion(rect); + d->viewport->update(rect); return; } @@ -610,7 +610,7 @@ int QListViewPrivate::horizontalScrollToValue(const QModelIndex &index, const QR const bool rightOf = q->isRightToLeft() ? rect.right() > area.right() : (rect.right() > area.right()) && (rect.left() > area.left()); - int horizontalValue = q->horizontalScrollBar()->value(); + int horizontalValue = hbar->value(); // ScrollPerItem if (q->horizontalScrollMode() == QAbstractItemView::ScrollPerItem && viewMode == QListView::ListMode) { @@ -652,10 +652,10 @@ int QListViewPrivate::verticalScrollToValue(const QModelIndex &index, const QRec const bool above = (hint == QListView::EnsureVisible && rect.top() < area.top()); const bool below = (hint == QListView::EnsureVisible && rect.bottom() > area.bottom()); - int verticalValue = q->verticalScrollBar()->value(); + int verticalValue = vbar->value(); // ScrollPerItem - if (q->verticalScrollMode() == QAbstractItemView::ScrollPerItem && viewMode == QListView::ListMode) { + if (verticalScrollMode == QAbstractItemView::ScrollPerItem && viewMode == QListView::ListMode) { const QListViewItem item = indexToListViewItem(index); const QRect rect = q->visualRect(index); verticalValue = staticListView->verticalPerItemValue(itemIndex(item), @@ -709,6 +709,31 @@ void QListViewPrivate::selectAll(QItemSelectionModel::SelectionFlags command) selectionModel->select(selection, command); } +/*! + \reimp + + We have a QListView way of knowing what elements are on the viewport + through the intersectingSet function +*/ +QItemViewPaintPairs QListViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const +{ + Q_ASSERT(r); + Q_Q(const QListView); + QRect &rect = *r; + const QRect viewportRect = viewport->rect(); + QItemViewPaintPairs ret; + const QSet<QModelIndex> visibleIndexes = intersectingSet(viewportRect).toList().toSet(); + for (int i = 0; i < indexes.count(); ++i) { + const QModelIndex &index = indexes.at(i); + if (visibleIndexes.contains(index)) { + const QRect current = q->visualRect(index); + ret += qMakePair(current, index); + rect |= current; + } + } + rect &= viewportRect; + return ret; +} /*! \internal @@ -755,7 +780,7 @@ void QListView::scrollContentsBy(int dx, int dy) // update the dragged items if (d->viewMode == IconMode) // ### move to dynamic class if (!d->dynamicListView->draggedItems.isEmpty()) - d->setDirtyRegion(d->dynamicListView->draggedItemsRect().translated(dx, dy)); + d->viewport->update(d->dynamicListView->draggedItemsRect().translated(dx, dy)); } /*! @@ -837,7 +862,7 @@ void QListView::mouseMoveEvent(QMouseEvent *e) && d->selectionMode != NoSelection) { QRect rect(d->pressedPosition, e->pos() + QPoint(horizontalOffset(), verticalOffset())); rect = rect.normalized(); - d->setDirtyRegion(d->mapToViewport(rect.united(d->elasticBand), d->viewMode == QListView::ListMode)); + d->viewport->update(d->mapToViewport(rect.united(d->elasticBand), d->viewMode == QListView::ListMode)); d->elasticBand = rect; } } @@ -851,7 +876,7 @@ void QListView::mouseReleaseEvent(QMouseEvent *e) QAbstractItemView::mouseReleaseEvent(e); // #### move this implementation into a dynamic class if (d->showElasticBand && d->elasticBand.isValid()) { - d->setDirtyRegion(d->mapToViewport(d->elasticBand, d->viewMode == QListView::ListMode)); + d->viewport->update(d->mapToViewport(d->elasticBand, d->viewMode == QListView::ListMode)); d->elasticBand = QRect(); } } @@ -916,18 +941,18 @@ void QListView::dragMoveEvent(QDragMoveEvent *e) if (d->canDecode(e)) { // get old dragged items rect QRect itemsRect = d->dynamicListView->itemsRect(d->dynamicListView->draggedItems); - d->setDirtyRegion(itemsRect.translated(d->dynamicListView->draggedItemsDelta())); + d->viewport->update(itemsRect.translated(d->dynamicListView->draggedItemsDelta())); // update position d->dynamicListView->draggedItemsPos = e->pos(); // get new items rect - d->setDirtyRegion(itemsRect.translated(d->dynamicListView->draggedItemsDelta())); + d->viewport->update(itemsRect.translated(d->dynamicListView->draggedItemsDelta())); // set the item under the cursor to current QModelIndex index; if (d->movement == Snap) { QRect rect(d->dynamicListView->snapToGrid(e->pos() + d->offset()), d->gridSize()); - d->intersectingSet(rect); - index = d->intersectVector.count() > 0 - ? d->intersectVector.last() : QModelIndex(); + const QVector<QModelIndex> intersectVector = d->intersectingSet(rect); + index = intersectVector.count() > 0 + ? intersectVector.last() : QModelIndex(); } else { index = indexAt(e->pos()); } @@ -1009,12 +1034,12 @@ void QListView::internalDrop(QDropEvent *event) for (int i = 0; i < indexes.count(); ++i) { QModelIndex index = indexes.at(i); QRect rect = rectForIndex(index); - d->setDirtyRegion(d->mapToViewport(rect, d->viewMode == QListView::ListMode)); + d->viewport->update(d->mapToViewport(rect, d->viewMode == QListView::ListMode)); QPoint dest = rect.topLeft() + delta; if (isRightToLeft()) dest.setX(d->flipX(dest.x()) - rect.width()); d->dynamicListView->moveItem(index.row(), dest); - d->setDirtyRegion(visualRect(index)); + update(index); } stopAutoScroll(); d->dynamicListView->draggedItems.clear(); @@ -1100,16 +1125,8 @@ void QListView::paintEvent(QPaintEvent *e) return; QStyleOptionViewItemV4 option = d->viewOptionsV4(); QPainter painter(d->viewport); - QRect area = e->rect(); - QVector<QModelIndex> toBeRendered; -// QVector<QRect> rects = e->region().rects(); -// for (int i = 0; i < rects.size(); ++i) { -// d->intersectingSet(rects.at(i).translated(horizontalOffset(), verticalOffset())); -// toBeRendered += d->intersectVector; -// } - d->intersectingSet(e->rect().translated(horizontalOffset(), verticalOffset()), false); - toBeRendered = d->intersectVector; + const QVector<QModelIndex> toBeRendered = d->intersectingSet(e->rect().translated(horizontalOffset(), verticalOffset()), false); const QModelIndex current = currentIndex(); const QModelIndex hover = d->hover; @@ -1231,9 +1248,9 @@ QModelIndex QListView::indexAt(const QPoint &p) const { Q_D(const QListView); QRect rect(p.x() + horizontalOffset(), p.y() + verticalOffset(), 1, 1); - d->intersectingSet(rect); - QModelIndex index = d->intersectVector.count() > 0 - ? d->intersectVector.last() : QModelIndex(); + const QVector<QModelIndex> intersectVector = d->intersectingSet(rect); + QModelIndex index = intersectVector.count() > 0 + ? intersectVector.last() : QModelIndex(); if (index.isValid() && visualRect(index).contains(p)) return index; return QModelIndex(); @@ -1331,38 +1348,38 @@ QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie if (d->gridSize().isValid()) rect.setSize(d->gridSize()); QSize contents = d->contentsSize(); - d->intersectVector.clear(); + QVector<QModelIndex> intersectVector; switch (cursorAction) { case MoveLeft: - while (d->intersectVector.isEmpty()) { + while (intersectVector.isEmpty()) { rect.translate(-rect.width(), 0); if (rect.right() <= 0) return current; if (rect.left() < 0) rect.setLeft(0); - d->intersectingSet(rect); - d->removeCurrentAndDisabled(&d->intersectVector, current); + intersectVector = d->intersectingSet(rect); + d->removeCurrentAndDisabled(&intersectVector, current); } - return d->closestIndex(initialRect, d->intersectVector); + return d->closestIndex(initialRect, intersectVector); case MoveRight: - while (d->intersectVector.isEmpty()) { + while (intersectVector.isEmpty()) { rect.translate(rect.width(), 0); if (rect.left() >= contents.width()) return current; if (rect.right() > contents.width()) rect.setRight(contents.width()); - d->intersectingSet(rect); - d->removeCurrentAndDisabled(&d->intersectVector, current); + intersectVector = d->intersectingSet(rect); + d->removeCurrentAndDisabled(&intersectVector, current); } - return d->closestIndex(initialRect, d->intersectVector); + return d->closestIndex(initialRect, intersectVector); case MovePageUp: rect.moveTop(rect.top() - d->viewport->height()); if (rect.top() < rect.height()) rect.moveTop(rect.height()); case MovePrevious: case MoveUp: - while (d->intersectVector.isEmpty()) { + while (intersectVector.isEmpty()) { rect.translate(0, -rect.height()); if (rect.bottom() <= 0) { #ifdef QT_KEYPAD_NAVIGATION @@ -1378,17 +1395,17 @@ QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie } if (rect.top() < 0) rect.setTop(0); - d->intersectingSet(rect); - d->removeCurrentAndDisabled(&d->intersectVector, current); + intersectVector = d->intersectingSet(rect); + d->removeCurrentAndDisabled(&intersectVector, current); } - return d->closestIndex(initialRect, d->intersectVector); + return d->closestIndex(initialRect, intersectVector); case MovePageDown: rect.moveTop(rect.top() + d->viewport->height()); if (rect.bottom() > contents.height() - rect.height()) rect.moveBottom(contents.height() - rect.height()); case MoveNext: case MoveDown: - while (d->intersectVector.isEmpty()) { + while (intersectVector.isEmpty()) { rect.translate(0, rect.height()); if (rect.top() >= contents.height()) { #ifdef QT_KEYPAD_NAVIGATION @@ -1405,10 +1422,10 @@ QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie } if (rect.bottom() > contents.height()) rect.setBottom(contents.height()); - d->intersectingSet(rect); - d->removeCurrentAndDisabled(&d->intersectVector, current); + intersectVector = d->intersectingSet(rect); + d->removeCurrentAndDisabled(&intersectVector, current); } - return d->closestIndex(initialRect, d->intersectVector); + return d->closestIndex(initialRect, intersectVector); case MoveHome: return d->model->index(0, d->column, d->root); case MoveEnd: @@ -1457,9 +1474,9 @@ void QListView::setPositionForIndex(const QPoint &position, const QModelIndex &i if (index.row() >= d->dynamicListView->items.count()) return; const QSize oldContents = d->contentsSize(); - d->setDirtyRegion(visualRect(index)); // update old position + update(index); // update old position d->dynamicListView->moveItem(index.row(), position); - d->setDirtyRegion(visualRect(index)); // update new position + update(index); // update new position if (d->contentsSize() != oldContents) updateGeometries(); // update the scroll bars @@ -1483,10 +1500,10 @@ void QListView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFl QItemSelection selection; if (rect.width() == 1 && rect.height() == 1) { - d->intersectingSet(rect.translated(horizontalOffset(), verticalOffset())); + const QVector<QModelIndex> intersectVector = d->intersectingSet(rect.translated(horizontalOffset(), verticalOffset())); QModelIndex tl; - if (!d->intersectVector.isEmpty()) - tl = d->intersectVector.last(); // special case for mouse press; only select the top item + if (!intersectVector.isEmpty()) + tl = intersectVector.last(); // special case for mouse press; only select the top item if (tl.isValid() && d->isIndexEnabled(tl)) selection.select(tl, tl); } else { @@ -1496,14 +1513,14 @@ void QListView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFl QModelIndex tl, br; // get the first item const QRect topLeft(rect.left() + horizontalOffset(), rect.top() + verticalOffset(), 1, 1); - d->intersectingSet(topLeft); - if (!d->intersectVector.isEmpty()) - tl = d->intersectVector.last(); + QVector<QModelIndex> intersectVector = d->intersectingSet(topLeft); + if (!intersectVector.isEmpty()) + tl = intersectVector.last(); // get the last item const QRect bottomRight(rect.right() + horizontalOffset(), rect.bottom() + verticalOffset(), 1, 1); - d->intersectingSet(bottomRight); - if (!d->intersectVector.isEmpty()) - br = d->intersectVector.last(); + intersectVector = d->intersectingSet(bottomRight); + if (!intersectVector.isEmpty()) + br = intersectVector.last(); // get the ranges if (tl.isValid() && br.isValid() @@ -1546,7 +1563,10 @@ void QListView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFl } // middle rectangle if (top.bottom() < bottom.top()) { - middle.setTop(top.bottom() + 1); + if (gridSize().isValid() && !gridSize().isNull()) + middle.setTop(top.top() + gridSize().height()); + else + middle.setTop(top.bottom() + 1); middle.setLeft(qMin(top.left(), bottom.left())); middle.setBottom(bottom.top() - 1); middle.setRight(qMax(top.right(), bottom.right())); @@ -1573,7 +1593,10 @@ void QListView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFl // only set middle if the middle.setTop(0); middle.setBottom(ch); - middle.setLeft(left.right() + 1); + if (gridSize().isValid() && !gridSize().isNull()) + middle.setLeft(left.left() + gridSize().width()); + else + middle.setLeft(left.right() + 1); middle.setRight(right.left() - 1); } else if (left.bottom() < right.top()) { left.setBottom(right.top() - 1); @@ -1610,6 +1633,10 @@ QRegion QListView::visualRegionForSelection(const QItemSelection &selection) con if (!selection.at(i).isValid()) continue; QModelIndex parent = selection.at(i).topLeft().parent(); + //we only display the children of the root in a listview + //we're not interested in the other model indexes + if (parent != d->root) + continue; int t = selection.at(i).topLeft().row(); int b = selection.at(i).bottomRight().row(); if (d->viewMode == IconMode || d->isWrapping()) { // in non-static mode, we have to go through all selected items @@ -1618,8 +1645,8 @@ QRegion QListView::visualRegionForSelection(const QItemSelection &selection) con } else { // in static mode, we can optimize a bit while (t <= b && d->isHidden(t)) ++t; while (b >= t && d->isHidden(b)) --b; - const QModelIndex top = d->model->index(t, c, d->root); - const QModelIndex bottom = d->model->index(b, c, d->root); + const QModelIndex top = d->model->index(t, c, parent); + const QModelIndex bottom = d->model->index(b, c, parent); QRect rect(visualRect(top).topLeft(), visualRect(bottom).bottomRight()); selectionRegion += QRegion(rect); @@ -1635,14 +1662,16 @@ QRegion QListView::visualRegionForSelection(const QItemSelection &selection) con QModelIndexList QListView::selectedIndexes() const { Q_D(const QListView); - QModelIndexList viewSelected; - QModelIndexList modelSelected; - if (d->selectionModel) - modelSelected = d->selectionModel->selectedIndexes(); - for (int i = 0; i < modelSelected.count(); ++i) { - QModelIndex index = modelSelected.at(i); + if (!d->selectionModel) + return QModelIndexList(); + + QModelIndexList viewSelected = d->selectionModel->selectedIndexes(); + for (int i = 0; i < viewSelected.count(); ++i) { + const QModelIndex &index = viewSelected.at(i); if (!isIndexHidden(index) && index.parent() == d->root && index.column() == d->column) - viewSelected.append(index); + ++i; + else + viewSelected.removeAt(i); } return viewSelected; } @@ -1971,10 +2000,16 @@ void QListViewPrivate::prepareItemsLayout() int frameAroundContents = 0; if (q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents)) frameAroundContents = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth) * 2; - int verticalMargin = vbarpolicy==Qt::ScrollBarAlwaysOff ? 0 : - q->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, q->verticalScrollBar()) + frameAroundContents; - int horizontalMargin = hbarpolicy==Qt::ScrollBarAlwaysOff ? 0 : - q->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, q->horizontalScrollBar()) + frameAroundContents; + + // maximumViewportSize() already takes scrollbar into account if policy is + // Qt::ScrollBarAlwaysOn but scrollbar extent must be deduced if policy + // is Qt::ScrollBarAsNeeded + int verticalMargin = vbarpolicy==Qt::ScrollBarAsNeeded + ? q->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, vbar) + frameAroundContents + : 0; + int horizontalMargin = hbarpolicy==Qt::ScrollBarAsNeeded + ? q->style()->pixelMetric(QStyle::PM_ScrollBarExtent, 0, hbar) + frameAroundContents + : 0; layoutBounds.adjust(0, 0, -verticalMargin, -horizontalMargin); @@ -2112,8 +2147,8 @@ QItemSelection QListViewPrivate::selection(const QRect &rect) const { QItemSelection selection; QModelIndex tl, br; - intersectingSet(rect); - QVector<QModelIndex>::iterator it = intersectVector.begin(); + const QVector<QModelIndex> intersectVector = intersectingSet(rect); + QVector<QModelIndex>::const_iterator it = intersectVector.begin(); for (; it != intersectVector.end(); ++it) { if (!tl.isValid() && !br.isValid()) { tl = br = *it; @@ -2404,9 +2439,9 @@ void QStaticListViewBase::doStaticLayout(const QListViewLayoutInfo &info) Finds the set of items intersecting with \a area. In this function, itemsize is counted from topleft to the start of the next item. */ -void QStaticListViewBase::intersectingStaticSet(const QRect &area) const +QVector<QModelIndex> QStaticListViewBase::intersectingStaticSet(const QRect &area) const { - clearIntersections(); + QVector<QModelIndex> ret; int segStartPosition; int segEndPosition; int flowStartPosition; @@ -2423,7 +2458,7 @@ void QStaticListViewBase::intersectingStaticSet(const QRect &area) const flowEndPosition = area.bottom(); } if (segmentPositions.count() < 2 || flowPositions.isEmpty()) - return; + return ret; // the last segment position is actually the edge of the last segment const int segLast = segmentPositions.count() - 2; int seg = qBinarySearch<int>(segmentPositions, segStartPosition, 0, segLast + 1); @@ -2438,13 +2473,14 @@ void QStaticListViewBase::intersectingStaticSet(const QRect &area) const continue; QModelIndex index = modelIndex(row); if (index.isValid()) - appendToIntersections(index); + ret += index; #if 0 // for debugging else qWarning("intersectingStaticSet: row %d was invalid", row); #endif } } + return ret; } int QStaticListViewBase::itemIndex(const QListViewItem &item) const @@ -2765,12 +2801,15 @@ void QDynamicListViewBase::doDynamicLayout(const QListViewLayoutInfo &info) viewport()->update(); } -void QDynamicListViewBase::intersectingDynamicSet(const QRect &area) const +QVector<QModelIndex> QDynamicListViewBase::intersectingDynamicSet(const QRect &area) const { - clearIntersections(); - QListViewPrivate *that = const_cast<QListViewPrivate*>(dd); + QDynamicListViewBase *that = const_cast<QDynamicListViewBase*>(this); QBspTree::Data data(static_cast<void*>(that)); - that->dynamicListView->tree.climbTree(area, &QDynamicListViewBase::addLeaf, data); + QVector<QModelIndex> res; + that->interSectingVector = &res; + that->tree.climbTree(area, &QDynamicListViewBase::addLeaf, data); + that->interSectingVector = 0; + return res; } void QDynamicListViewBase::createItems(int to) @@ -2847,20 +2886,20 @@ int QDynamicListViewBase::itemIndex(const QListViewItem &item) const } void QDynamicListViewBase::addLeaf(QVector<int> &leaf, const QRect &area, - uint visited, QBspTree::Data data) + uint visited, QBspTree::Data data) { QListViewItem *vi; - QListViewPrivate *_this = static_cast<QListViewPrivate *>(data.ptr); + QDynamicListViewBase *_this = static_cast<QDynamicListViewBase *>(data.ptr); for (int i = 0; i < leaf.count(); ++i) { int idx = leaf.at(i); - if (idx < 0 || idx >= _this->dynamicListView->items.count()) + if (idx < 0 || idx >= _this->items.count()) continue; - vi = &_this->dynamicListView->items[idx]; + vi = &_this->items[idx]; Q_ASSERT(vi); if (vi->isValid() && vi->rect().intersects(area) && vi->visited != visited) { - QModelIndex index = _this->listViewItemToIndex(*vi); + QModelIndex index = _this->dd->listViewItemToIndex(*vi); Q_ASSERT(index.isValid()); - _this->intersectVector.append(index); + _this->interSectingVector->append(index); vi->visited = visited; } } diff --git a/src/gui/itemviews/qlistview_p.h b/src/gui/itemviews/qlistview_p.h index c3e8966..1727ba4 100644 --- a/src/gui/itemviews/qlistview_p.h +++ b/src/gui/itemviews/qlistview_p.h @@ -84,7 +84,7 @@ public: inline bool operator!=(const QListViewItem &other) const { return !(*this == other); } inline bool isValid() const - { return (x > -1) && (y > -1) && (w > 0) && (h > 0) && (indexHint > -1); } + { return rect().isValid() && (indexHint > -1); } inline void invalidate() { x = -1; y = -1; w = 0; h = 0; } inline void resize(const QSize &size) @@ -153,9 +153,6 @@ public: inline bool isHidden(int row) const; inline int hiddenCount() const; - inline void clearIntersections() const; - inline void appendToIntersections(const QModelIndex &idx) const; - inline bool isRightToLeft() const; QListViewPrivate *dd; @@ -186,7 +183,7 @@ public: QPoint initStaticLayout(const QListViewLayoutInfo &info); void doStaticLayout(const QListViewLayoutInfo &info); - void intersectingStaticSet(const QRect &area) const; + QVector<QModelIndex> intersectingStaticSet(const QRect &area) const; int itemIndex(const QListViewItem &item) const; @@ -216,7 +213,7 @@ class QDynamicListViewBase : public QCommonListViewBase friend class QListViewPrivate; public: QDynamicListViewBase(QListView *q, QListViewPrivate *d) : QCommonListViewBase(q, d), - batchStartRow(0), batchSavedDeltaSeg(0) {} + batchStartRow(0), batchSavedDeltaSeg(0), interSectingVector(0) {} QBspTree tree; QVector<QListViewItem> items; @@ -230,6 +227,7 @@ public: // used when laying out in batches int batchStartRow; int batchSavedDeltaSeg; + QVector<QModelIndex> *interSectingVector; //used from within intersectingDynamicSet void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); bool doBatchedItemLayout(const QListViewLayoutInfo &info, int max); @@ -237,7 +235,7 @@ public: void initBspTree(const QSize &contents); QPoint initDynamicLayout(const QListViewLayoutInfo &info); void doDynamicLayout(const QListViewLayoutInfo &info); - void intersectingDynamicSet(const QRect &area) const; + QVector<QModelIndex> intersectingDynamicSet(const QRect &area) const; static void addLeaf(QVector<int> &leaf, const QRect &area, uint visited, QBspTree::Data data); @@ -277,11 +275,11 @@ public: bool doItemsLayout(int num); - inline void intersectingSet(const QRect &area, bool doLayout = true) const { + inline QVector<QModelIndex> intersectingSet(const QRect &area, bool doLayout = true) const { if (doLayout) executePostedLayout(); QRect a = (q_func()->isRightToLeft() ? flipX(area.normalized()) : area.normalized()); - if (viewMode == QListView::ListMode) staticListView->intersectingStaticSet(a); - else dynamicListView->intersectingDynamicSet(a); + return (viewMode == QListView::ListMode) ? staticListView->intersectingStaticSet(a) + : dynamicListView->intersectingDynamicSet(a); } // ### FIXME: @@ -351,6 +349,8 @@ public: void scrollElasticBandBy(int dx, int dy); + QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const; + // ### FIXME: we only need one at a time QDynamicListViewBase *dynamicListView; QStaticListViewBase *staticListView; @@ -383,9 +383,6 @@ public: QRect layoutBounds; - // used for intersecting set - mutable QVector<QModelIndex> intersectVector; - // timers QBasicTimer batchLayoutTimer; @@ -438,9 +435,6 @@ inline QAbstractItemDelegate *QCommonListViewBase::delegate(const QModelIndex &i inline bool QCommonListViewBase::isHidden(int row) const { return dd->isHidden(row); } inline int QCommonListViewBase::hiddenCount() const { return dd->hiddenRows.count(); } -inline void QCommonListViewBase::clearIntersections() const { dd->intersectVector.clear(); } -inline void QCommonListViewBase::appendToIntersections(const QModelIndex &idx) const { dd->intersectVector.append(idx); } - inline bool QCommonListViewBase::isRightToLeft() const { return qq->isRightToLeft(); } QT_END_NAMESPACE diff --git a/src/gui/itemviews/qlistwidget.cpp b/src/gui/itemviews/qlistwidget.cpp index cae3b98..2565657 100644 --- a/src/gui/itemviews/qlistwidget.cpp +++ b/src/gui/itemviews/qlistwidget.cpp @@ -561,6 +561,13 @@ Qt::DropActions QListModel::supportedDropActions() const given \a parent. If the parent is not specified, the item will need to be inserted into a list widget with QListWidget::insertItem(). + + \note that this constructor inserts this same object into the model of + the parent that is passed to the constructor. If the model is sorted then + the behavior of the insert is undetermined since the model will call + the '<' operator method on this object which has still not yet been + constructed. In this case it would be better not to specify the parent + and use the QListWidget::insertItem method to insert the item instead. \sa type() */ @@ -582,6 +589,13 @@ QListWidgetItem::QListWidgetItem(QListWidget *view, int type) given \a text and \a parent. If the parent is not specified, the item will need to be inserted into a list widget with QListWidget::insertItem(). + + \note that this constructor inserts this same object into the model of + the parent that is passed to the constructor. If the model is sorted then + the behavior of the insert is undetermined since the model will call + the '<' operator method on this object which has still not yet been + constructed. In this case it would be better not to specify the parent + and use the QListWidget::insertItem method to insert the item instead. \sa type() */ @@ -605,7 +619,14 @@ QListWidgetItem::QListWidgetItem(const QString &text, QListWidget *view, int typ given \a icon, \a text and \a parent. If the parent is not specified, the item will need to be inserted into a list widget with QListWidget::insertItem(). - + + \note that this constructor inserts this same object into the model of + the parent that is passed to the constructor. If the model is sorted then + the behavior of the insert is undetermined since the model will call + the '<' operator method on this object which has still not yet been + constructed. In this case it would be better not to specify the parent + and use the QListWidget::insertItem method to insert the item instead. + \sa type() */ QListWidgetItem::QListWidgetItem(const QIcon &icon,const QString &text, @@ -687,7 +708,10 @@ QVariant QListWidgetItem::data(int role) const */ bool QListWidgetItem::operator<(const QListWidgetItem &other) const { - return text() < other.text(); + const QVariant v1 = data(Qt::DisplayRole), v2 = other.data(Qt::DisplayRole); + if (QAbstractItemModelPrivate::canConvertToDouble(v1) && QAbstractItemModelPrivate::canConvertToDouble(v2)) + return v1.toDouble() < v2.toDouble(); + return v1.toString() < v2.toString(); } #ifndef QT_NO_DATASTREAM @@ -711,6 +735,7 @@ void QListWidgetItem::write(QDataStream &out) const { out << d->values; } +#endif // QT_NO_DATASTREAM /*! \since 4.1 @@ -745,6 +770,8 @@ QListWidgetItem &QListWidgetItem::operator=(const QListWidgetItem &other) return *this; } +#ifndef QT_NO_DATASTREAM + /*! \relates QListWidgetItem @@ -1014,51 +1041,51 @@ void QListWidgetPrivate::setup() QObject::connect(q, SIGNAL(activated(QModelIndex)), q, SLOT(_q_emitItemActivated(QModelIndex))); QObject::connect(q, SIGNAL(entered(QModelIndex)), q, SLOT(_q_emitItemEntered(QModelIndex))); - QObject::connect(model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), + QObject::connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), q, SLOT(_q_emitItemChanged(QModelIndex))); QObject::connect(q->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), q, SLOT(_q_emitCurrentItemChanged(QModelIndex,QModelIndex))); QObject::connect(q->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), q, SIGNAL(itemSelectionChanged())); - QObject::connect(model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), + QObject::connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), q, SLOT(_q_dataChanged(QModelIndex,QModelIndex))); - QObject::connect(model(), SIGNAL(columnsRemoved(QModelIndex,int,int)), q, SLOT(_q_sort())); + QObject::connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)), q, SLOT(_q_sort())); } void QListWidgetPrivate::_q_emitItemPressed(const QModelIndex &index) { Q_Q(QListWidget); - emit q->itemPressed(model()->at(index.row())); + emit q->itemPressed(listModel()->at(index.row())); } void QListWidgetPrivate::_q_emitItemClicked(const QModelIndex &index) { Q_Q(QListWidget); - emit q->itemClicked(model()->at(index.row())); + emit q->itemClicked(listModel()->at(index.row())); } void QListWidgetPrivate::_q_emitItemDoubleClicked(const QModelIndex &index) { Q_Q(QListWidget); - emit q->itemDoubleClicked(model()->at(index.row())); + emit q->itemDoubleClicked(listModel()->at(index.row())); } void QListWidgetPrivate::_q_emitItemActivated(const QModelIndex &index) { Q_Q(QListWidget); - emit q->itemActivated(model()->at(index.row())); + emit q->itemActivated(listModel()->at(index.row())); } void QListWidgetPrivate::_q_emitItemEntered(const QModelIndex &index) { Q_Q(QListWidget); - emit q->itemEntered(model()->at(index.row())); + emit q->itemEntered(listModel()->at(index.row())); } void QListWidgetPrivate::_q_emitItemChanged(const QModelIndex &index) { Q_Q(QListWidget); - emit q->itemChanged(model()->at(index.row())); + emit q->itemChanged(listModel()->at(index.row())); } void QListWidgetPrivate::_q_emitCurrentItemChanged(const QModelIndex ¤t, @@ -1066,8 +1093,8 @@ void QListWidgetPrivate::_q_emitCurrentItemChanged(const QModelIndex ¤t, { Q_Q(QListWidget); QPersistentModelIndex persistentCurrent = current; - QListWidgetItem *currentItem = model()->at(persistentCurrent.row()); - emit q->currentItemChanged(currentItem, model()->at(previous.row())); + QListWidgetItem *currentItem = listModel()->at(persistentCurrent.row()); + emit q->currentItemChanged(currentItem, listModel()->at(previous.row())); //persistentCurrent is invalid if something changed the model in response //to the currentItemChanged signal emission and the item was removed @@ -1082,14 +1109,14 @@ void QListWidgetPrivate::_q_emitCurrentItemChanged(const QModelIndex ¤t, void QListWidgetPrivate::_q_sort() { if (sortingEnabled) - model()->sort(0, sortOrder); + model->sort(0, sortOrder); } void QListWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) { if (sortingEnabled && topLeft.isValid() && bottomRight.isValid()) - model()->ensureSorted(topLeft.column(), sortOrder, + listModel()->ensureSorted(topLeft.column(), sortOrder, topLeft.row(), bottomRight.row()); } @@ -1262,7 +1289,7 @@ void QListWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, This signal is emitted whenever the selection changes. - \sa selectedItems() isItemSelected() currentItemChanged() + \sa selectedItems() QListWidgetItem::isSelected() currentItemChanged() */ /*! @@ -1302,9 +1329,9 @@ QListWidget::~QListWidget() QListWidgetItem *QListWidget::item(int row) const { Q_D(const QListWidget); - if (row < 0 || row >= d->model()->rowCount()) + if (row < 0 || row >= d->model->rowCount()) return 0; - return d->model()->at(row); + return d->listModel()->at(row); } /*! @@ -1316,7 +1343,7 @@ QListWidgetItem *QListWidget::item(int row) const int QListWidget::row(const QListWidgetItem *item) const { Q_D(const QListWidget); - return d->model()->index(const_cast<QListWidgetItem*>(item)).row(); + return d->listModel()->index(const_cast<QListWidgetItem*>(item)).row(); } @@ -1330,7 +1357,7 @@ void QListWidget::insertItem(int row, QListWidgetItem *item) { Q_D(QListWidget); if (item && !item->view) - d->model()->insert(row, item); + d->listModel()->insert(row, item); } /*! @@ -1343,7 +1370,7 @@ void QListWidget::insertItem(int row, QListWidgetItem *item) void QListWidget::insertItem(int row, const QString &label) { Q_D(QListWidget); - d->model()->insert(row, new QListWidgetItem(label)); + d->listModel()->insert(row, new QListWidgetItem(label)); } /*! @@ -1356,7 +1383,7 @@ void QListWidget::insertItem(int row, const QString &label) void QListWidget::insertItems(int row, const QStringList &labels) { Q_D(QListWidget); - d->model()->insert(row, labels); + d->listModel()->insert(row, labels); } /*! @@ -1372,9 +1399,9 @@ void QListWidget::insertItems(int row, const QStringList &labels) QListWidgetItem *QListWidget::takeItem(int row) { Q_D(QListWidget); - if (row < 0 || row >= d->model()->rowCount()) + if (row < 0 || row >= d->model->rowCount()) return 0; - return d->model()->take(row); + return d->listModel()->take(row); } /*! @@ -1385,7 +1412,7 @@ QListWidgetItem *QListWidget::takeItem(int row) int QListWidget::count() const { Q_D(const QListWidget); - return d->model()->rowCount(); + return d->model->rowCount(); } /*! @@ -1394,7 +1421,7 @@ int QListWidget::count() const QListWidgetItem *QListWidget::currentItem() const { Q_D(const QListWidget); - return d->model()->at(currentIndex().row()); + return d->listModel()->at(currentIndex().row()); } @@ -1432,7 +1459,7 @@ int QListWidget::currentRow() const void QListWidget::setCurrentRow(int row) { Q_D(QListWidget); - QModelIndex index = d->model()->index(row); + QModelIndex index = d->listModel()->index(row); if (d->selectionMode == SingleSelection) selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect); else if (d->selectionMode == NoSelection) @@ -1449,7 +1476,7 @@ void QListWidget::setCurrentRow(int row) void QListWidget::setCurrentRow(int row, QItemSelectionModel::SelectionFlags command) { Q_D(QListWidget); - d->selectionModel->setCurrentIndex(d->model()->index(row), command); + d->selectionModel->setCurrentIndex(d->listModel()->index(row), command); } /*! @@ -1458,7 +1485,7 @@ void QListWidget::setCurrentRow(int row, QItemSelectionModel::SelectionFlags com QListWidgetItem *QListWidget::itemAt(const QPoint &p) const { Q_D(const QListWidget); - return d->model()->at(indexAt(p).row()); + return d->listModel()->at(indexAt(p).row()); } @@ -1476,7 +1503,7 @@ QListWidgetItem *QListWidget::itemAt(const QPoint &p) const QRect QListWidget::visualItemRect(const QListWidgetItem *item) const { Q_D(const QListWidget); - QModelIndex index = d->model()->index(const_cast<QListWidgetItem*>(item)); + QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item)); return visualRect(index); } @@ -1487,7 +1514,7 @@ void QListWidget::sortItems(Qt::SortOrder order) { Q_D(QListWidget); d->sortOrder = order; - d->model()->sort(0, order); + d->listModel()->sort(0, order); } /*! @@ -1526,7 +1553,7 @@ Qt::SortOrder QListWidget::sortOrder() const void QListWidget::editItem(QListWidgetItem *item) { Q_D(QListWidget); - edit(d->model()->index(item)); + edit(d->listModel()->index(item)); } /*! @@ -1537,7 +1564,7 @@ void QListWidget::editItem(QListWidgetItem *item) void QListWidget::openPersistentEditor(QListWidgetItem *item) { Q_D(QListWidget); - QModelIndex index = d->model()->index(item); + QModelIndex index = d->listModel()->index(item); QAbstractItemView::openPersistentEditor(index); } @@ -1549,7 +1576,7 @@ void QListWidget::openPersistentEditor(QListWidgetItem *item) void QListWidget::closePersistentEditor(QListWidgetItem *item) { Q_D(QListWidget); - QModelIndex index = d->model()->index(item); + QModelIndex index = d->listModel()->index(item); QAbstractItemView::closePersistentEditor(index); } @@ -1561,7 +1588,7 @@ void QListWidget::closePersistentEditor(QListWidgetItem *item) QWidget *QListWidget::itemWidget(QListWidgetItem *item) const { Q_D(const QListWidget); - QModelIndex index = d->model()->index(item); + QModelIndex index = d->listModel()->index(item); return QAbstractItemView::indexWidget(index); } @@ -1579,7 +1606,7 @@ QWidget *QListWidget::itemWidget(QListWidgetItem *item) const void QListWidget::setItemWidget(QListWidgetItem *item, QWidget *widget) { Q_D(QListWidget); - QModelIndex index = d->model()->index(item); + QModelIndex index = d->listModel()->index(item); QAbstractItemView::setIndexWidget(index, widget); } @@ -1593,7 +1620,7 @@ void QListWidget::setItemWidget(QListWidgetItem *item, QWidget *widget) bool QListWidget::isItemSelected(const QListWidgetItem *item) const { Q_D(const QListWidget); - QModelIndex index = d->model()->index(const_cast<QListWidgetItem*>(item)); + QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item)); return selectionModel()->isSelected(index); } @@ -1608,7 +1635,7 @@ bool QListWidget::isItemSelected(const QListWidgetItem *item) const void QListWidget::setItemSelected(const QListWidgetItem *item, bool select) { Q_D(QListWidget); - QModelIndex index = d->model()->index(const_cast<QListWidgetItem*>(item)); + QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item)); if (d->selectionMode == SingleSelection) { selectionModel()->select(index, select @@ -1632,7 +1659,7 @@ QList<QListWidgetItem*> QListWidget::selectedItems() const QModelIndexList indexes = selectionModel()->selectedIndexes(); QList<QListWidgetItem*> items; for (int i = 0; i < indexes.count(); ++i) - items.append(d->model()->at(indexes.at(i).row())); + items.append(d->listModel()->at(indexes.at(i).row())); return items; } @@ -1643,11 +1670,11 @@ QList<QListWidgetItem*> QListWidget::selectedItems() const QList<QListWidgetItem*> QListWidget::findItems(const QString &text, Qt::MatchFlags flags) const { Q_D(const QListWidget); - QModelIndexList indexes = d->model()->match(model()->index(0, 0, QModelIndex()), + QModelIndexList indexes = d->listModel()->match(model()->index(0, 0, QModelIndex()), Qt::DisplayRole, text, -1, flags); QList<QListWidgetItem*> items; for (int i = 0; i < indexes.size(); ++i) - items.append(d->model()->at(indexes.at(i).row())); + items.append(d->listModel()->at(indexes.at(i).row())); return items; } @@ -1684,7 +1711,7 @@ void QListWidget::setItemHidden(const QListWidgetItem *item, bool hide) void QListWidget::scrollToItem(const QListWidgetItem *item, QAbstractItemView::ScrollHint hint) { Q_D(QListWidget); - QModelIndex index = d->model()->index(const_cast<QListWidgetItem*>(item)); + QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item)); QListView::scrollTo(index, hint); } @@ -1697,7 +1724,7 @@ void QListWidget::clear() { Q_D(QListWidget); selectionModel()->clear(); - d->model()->clear(); + d->listModel()->clear(); } /*! @@ -1708,7 +1735,7 @@ void QListWidget::clear() */ QStringList QListWidget::mimeTypes() const { - return d_func()->model()->QAbstractListModel::mimeTypes(); + return d_func()->listModel()->QAbstractListModel::mimeTypes(); } /*! @@ -1721,7 +1748,7 @@ QStringList QListWidget::mimeTypes() const */ QMimeData *QListWidget::mimeData(const QList<QListWidgetItem*>) const { - return d_func()->model()->internalMimeData(); + return d_func()->listModel()->internalMimeData(); } #ifndef QT_NO_DRAGANDDROP @@ -1744,7 +1771,7 @@ bool QListWidget::dropMimeData(int index, const QMimeData *data, Qt::DropAction row = -1; column = -1; } - return d_func()->model()->QAbstractListModel::dropMimeData(data, action , row, column, idx); + return d_func()->listModel()->QAbstractListModel::dropMimeData(data, action , row, column, idx); } /*! \reimp */ @@ -1803,7 +1830,7 @@ void QListWidget::dropEvent(QDropEvent *event) { Qt::DropActions QListWidget::supportedDropActions() const { Q_D(const QListWidget); - return d->model()->QAbstractListModel::supportedDropActions() | Qt::MoveAction; + return d->listModel()->QAbstractListModel::supportedDropActions() | Qt::MoveAction; } #endif // QT_NO_DRAGANDDROP @@ -1827,7 +1854,7 @@ QList<QListWidgetItem*> QListWidget::items(const QMimeData *data) const QModelIndex QListWidget::indexFromItem(QListWidgetItem *item) const { Q_D(const QListWidget); - return d->model()->index(item); + return d->listModel()->index(item); } /*! @@ -1838,7 +1865,7 @@ QListWidgetItem *QListWidget::itemFromIndex(const QModelIndex &index) const { Q_D(const QListWidget); if (d->isIndexValid(index)) - return d->model()->at(index.row()); + return d->listModel()->at(index.row()); return 0; } diff --git a/src/gui/itemviews/qlistwidget_p.h b/src/gui/itemviews/qlistwidget_p.h index eabfb64..755a672 100644 --- a/src/gui/itemviews/qlistwidget_p.h +++ b/src/gui/itemviews/qlistwidget_p.h @@ -143,7 +143,7 @@ class QListWidgetPrivate : public QListViewPrivate Q_DECLARE_PUBLIC(QListWidget) public: QListWidgetPrivate() : QListViewPrivate(), sortOrder(Qt::AscendingOrder), sortingEnabled(false) {} - inline QListModel *model() const { return qobject_cast<QListModel*>(q_func()->model()); } + inline QListModel *listModel() const { return qobject_cast<QListModel*>(model); } void setup(); void _q_emitItemPressed(const QModelIndex &index); void _q_emitItemClicked(const QModelIndex &index); diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp index b69b94e..fdc09ca 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.cpp +++ b/src/gui/itemviews/qsortfilterproxymodel.cpp @@ -56,6 +56,15 @@ QT_BEGIN_NAMESPACE typedef QList<QPair<QModelIndex, QPersistentModelIndex> > QModelIndexPairList; +static inline QSet<int> qVectorToSet(const QVector<int> &vector) +{ + QSet<int> set; + set.reserve(vector.size()); + for(int i=0; i < vector.size(); ++i) + set << vector.at(i); + return set; +} + class QSortFilterProxyModelLessThan { public: @@ -137,6 +146,7 @@ public: const QModelIndex &source_parent) const; QModelIndex proxy_to_source(const QModelIndex &proxyIndex) const; QModelIndex source_to_proxy(const QModelIndex &sourceIndex) const; + bool can_create_mapping(const QModelIndex &source_parent) const; void remove_from_mapping(const QModelIndex &source_parent); @@ -224,8 +234,8 @@ public: QModelIndexPairList store_persistent_indexes(); void update_persistent_indexes(const QModelIndexPairList &source_indexes); - void filter_changed(); - void handle_filter_changed( + void filter_changed(const QModelIndex &source_parent = QModelIndex()); + QSet<int> handle_filter_changed( QVector<int> &source_to_proxy, QVector<int> &proxy_to_source, const QModelIndex &source_parent, Qt::Orientation orient); @@ -345,6 +355,25 @@ QModelIndex QSortFilterProxyModelPrivate::source_to_proxy(const QModelIndex &sou return create_index(proxy_row, proxy_column, it); } +bool QSortFilterProxyModelPrivate::can_create_mapping(const QModelIndex &source_parent) const +{ + if (source_parent.isValid()) { + QModelIndex source_grand_parent = source_parent.parent(); + IndexMap::const_iterator it = source_index_mapping.constFind(source_grand_parent); + if (it == source_index_mapping.constEnd()) { + // Don't care, since we don't have mapping for the grand parent + return false; + } + Mapping *gm = it.value(); + if (gm->proxy_rows.at(source_parent.row()) == -1 || + gm->proxy_columns.at(source_parent.column()) == -1) { + // Don't care, since parent is filtered + return false; + } + } + return true; +} + /*! \internal @@ -650,20 +679,8 @@ void QSortFilterProxyModelPrivate::source_items_inserted( return; IndexMap::const_iterator it = source_index_mapping.constFind(source_parent); if (it == source_index_mapping.constEnd()) { - if (source_parent.isValid()) { - QModelIndex source_grand_parent = source_parent.parent(); - it = source_index_mapping.constFind(source_grand_parent); - if (it == source_index_mapping.constEnd()) { - // Don't care, since we don't have mapping for the grand parent - return; - } - Mapping *gm = it.value(); - if (gm->proxy_rows.at(source_parent.row()) == -1 || - gm->proxy_columns.at(source_parent.column()) == -1) { - // Don't care, since parent is filtered - return; - } - } + if (!can_create_mapping(source_parent)) + return; it = create_mapping(source_parent); Mapping *m = it.value(); QModelIndex proxy_parent = q->mapFromSource(source_parent); @@ -875,8 +892,8 @@ void QSortFilterProxyModelPrivate::proxy_item_range( { proxy_low = INT_MAX; proxy_high = INT_MIN; - foreach (int source_item, source_items) { - int proxy_item = source_to_proxy.at(source_item); + for (int i = 0; i < source_items.count(); ++i) { + int proxy_item = source_to_proxy.at(source_items.at(i)); Q_ASSERT(proxy_item != -1); if (proxy_item < proxy_low) proxy_low = proxy_item; @@ -937,34 +954,47 @@ void QSortFilterProxyModelPrivate::update_persistent_indexes( q->changePersistentIndexList(from, to); } + /*! \internal Updates the proxy model (adds/removes rows) based on the new filter. */ -void QSortFilterProxyModelPrivate::filter_changed() +void QSortFilterProxyModelPrivate::filter_changed(const QModelIndex &source_parent) { - QMap<QModelIndex, Mapping *>::const_iterator it; - for (it = source_index_mapping.constBegin(); it != source_index_mapping.constEnd(); ++it) { - QModelIndex source_parent = it.key(); - Mapping *m = it.value(); - handle_filter_changed(m->proxy_rows, m->source_rows, source_parent, Qt::Vertical); - handle_filter_changed(m->proxy_columns, m->source_columns, source_parent, Qt::Horizontal); + IndexMap::const_iterator it = source_index_mapping.constFind(source_parent); + if (it == source_index_mapping.constEnd()) + return; + Mapping *m = it.value(); + QSet<int> rows_removed = handle_filter_changed(m->proxy_rows, m->source_rows, source_parent, Qt::Vertical); + QSet<int> columns_removed = handle_filter_changed(m->proxy_columns, m->source_columns, source_parent, Qt::Horizontal); + QVector<QModelIndex>::iterator it2 = m->mapped_children.end(); + while (it2 != m->mapped_children.begin()) { + --it2; + const QModelIndex source_child_index = *it2; + if (rows_removed.contains(source_child_index.row()) || columns_removed.contains(source_child_index.column())) { + it2 = m->mapped_children.erase(it2); + remove_from_mapping(source_child_index); + } else { + filter_changed(source_child_index); + } } } /*! \internal + returns the removed items indexes */ -void QSortFilterProxyModelPrivate::handle_filter_changed( +QSet<int> QSortFilterProxyModelPrivate::handle_filter_changed( QVector<int> &source_to_proxy, QVector<int> &proxy_to_source, const QModelIndex &source_parent, Qt::Orientation orient) { Q_Q(QSortFilterProxyModel); // Figure out which mapped items to remove QVector<int> source_items_remove; - foreach (int source_item, proxy_to_source) { + for (int i = 0; i < proxy_to_source.count(); ++i) { + const int source_item = proxy_to_source.at(i); if ((orient == Qt::Vertical) ? !q->filterAcceptsRow(source_item, source_parent) : !q->filterAcceptsColumn(source_item, source_parent)) { @@ -994,6 +1024,7 @@ void QSortFilterProxyModelPrivate::handle_filter_changed( insert_source_items(source_to_proxy, proxy_to_source, source_items_insert, source_parent, orient); } + return qVectorToSet(source_items_remove); } void QSortFilterProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &source_top_left, @@ -1044,15 +1075,14 @@ void QSortFilterProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &sourc if (!source_rows_remove.isEmpty()) { remove_source_items(m->proxy_rows, m->source_rows, source_rows_remove, source_parent, Qt::Vertical); - QSet<int> source_rows_remove_set = source_rows_remove.toList().toSet(); - QVector<QModelIndex>::iterator it = m->mapped_children.begin(); - while (it != m->mapped_children.end()) { + QSet<int> source_rows_remove_set = qVectorToSet(source_rows_remove); + QVector<QModelIndex>::iterator it = m->mapped_children.end(); + while (it != m->mapped_children.begin()) { + --it; const QModelIndex source_child_index = *it; if (source_rows_remove_set.contains(source_child_index.row())) { it = m->mapped_children.erase(it); remove_from_mapping(source_child_index); - } else { - ++it; } } } @@ -1164,7 +1194,8 @@ void QSortFilterProxyModelPrivate::_q_sourceRowsAboutToBeInserted( Q_UNUSED(end); //Force the creation of a mapping now, even if its empty. //We need it because the proxy can be acessed at the moment it emits rowsAboutToBeInserted in insert_source_items - create_mapping(source_parent); + if (can_create_mapping(source_parent)) + create_mapping(source_parent); } void QSortFilterProxyModelPrivate::_q_sourceRowsInserted( @@ -1195,7 +1226,8 @@ void QSortFilterProxyModelPrivate::_q_sourceColumnsAboutToBeInserted( Q_UNUSED(end); //Force the creation of a mapping now, even if its empty. //We need it because the proxy can be acessed at the moment it emits columnsAboutToBeInserted in insert_source_items - create_mapping(source_parent); + if (can_create_mapping(source_parent)) + create_mapping(source_parent); } void QSortFilterProxyModelPrivate::_q_sourceColumnsInserted( diff --git a/src/gui/itemviews/qstandarditemmodel.cpp b/src/gui/itemviews/qstandarditemmodel.cpp index 19d5728..e71d8f9 100644 --- a/src/gui/itemviews/qstandarditemmodel.cpp +++ b/src/gui/itemviews/qstandarditemmodel.cpp @@ -1742,18 +1742,21 @@ QList<QStandardItem*> QStandardItem::takeRow(int row) Q_D(QStandardItem); if ((row < 0) || (row >= rowCount())) return QList<QStandardItem*>(); + if (d->model) + d->model->d_func()->rowsAboutToBeRemoved(this, row, row); QList<QStandardItem*> items; int index = d->childIndex(row, 0); - for (int column = 0; column < d->columnCount(); ++column) { - QStandardItem *ch = d->children.at(index); - if (ch) { + int col_count = d->columnCount(); + for (int column = 0; column < col_count; ++column) { + QStandardItem *ch = d->children.at(index + column); + if (ch) ch->d_func()->setParentAndModel(0, 0); - d->children.replace(index, 0); - } items.append(ch); - ++index; } - removeRow(row); + d->children.remove(index, col_count); + d->rows--; + if (d->model) + d->model->d_func()->rowsRemoved(this, row, 1); return items; } @@ -1769,18 +1772,21 @@ QList<QStandardItem*> QStandardItem::takeColumn(int column) Q_D(QStandardItem); if ((column < 0) || (column >= columnCount())) return QList<QStandardItem*>(); + if (d->model) + d->model->d_func()->columnsAboutToBeRemoved(this, column, column); QList<QStandardItem*> items; - int index = d->childIndex(0, column); - for (int row = 0; row < d->rowCount(); ++row) { + + for (int row = d->rowCount() - 1; row >= 0; --row) { + int index = d->childIndex(row, column); QStandardItem *ch = d->children.at(index); - if (ch) { + if (ch) ch->d_func()->setParentAndModel(0, 0); - d->children.replace(index, 0); - } - items.append(ch); - index += d->columnCount(); + d->children.remove(index); + items.prepend(ch); } - removeColumn(column); + d->columns--; + if (d->model) + d->model->d_func()->columnsRemoved(this, column, 1); return items; } @@ -1938,7 +1944,7 @@ QDataStream &operator<<(QDataStream &out, const QStandardItem &item) return out; } -#endif // !QT_NO_DATASTREAM +#endif // QT_NO_DATASTREAM /*! \class QStandardItemModel @@ -2907,8 +2913,8 @@ QMimeData *QStandardItemModel::mimeData(const QModelIndexList &indexes) const QStack<QStandardItem*> stack; itemsSet.reserve(indexes.count()); stack.reserve(indexes.count()); - foreach (const QModelIndex &index, indexes) { - QStandardItem *item = itemFromIndex(index); + for (int i = 0; i < indexes.count(); ++i) { + QStandardItem *item = itemFromIndex(indexes.at(i)); itemsSet << item; stack.push(item); } diff --git a/src/gui/itemviews/qstyleditemdelegate.cpp b/src/gui/itemviews/qstyleditemdelegate.cpp index edca724..34667ee 100644 --- a/src/gui/itemviews/qstyleditemdelegate.cpp +++ b/src/gui/itemviews/qstyleditemdelegate.cpp @@ -671,7 +671,7 @@ bool QStyledItemDelegate::eventFilter(QObject *object, QEvent *event) if (editor->parentWidget()) editor->parentWidget()->setFocus(); return true; - } else if (event->type() == QEvent::FocusOut || event->type() == QEvent::Hide) { + } else if (event->type() == QEvent::FocusOut || (event->type() == QEvent::Hide && editor->isWindow())) { //the Hide event will take care of he editors that are in fact complete dialogs if (!editor->isActiveWindow() || (QApplication::focusWidget() != editor)) { QWidget *w = QApplication::focusWidget(); @@ -686,13 +686,7 @@ bool QStyledItemDelegate::eventFilter(QObject *object, QEvent *event) if (QDragManager::self() && QDragManager::self()->object != 0) return false; #endif - // Opening a modal dialog will start a new eventloop - // that will process the deleteLater event. - QWidget *activeModalWidget = QApplication::activeModalWidget(); - if (activeModalWidget - && !activeModalWidget->isAncestorOf(editor) - && qobject_cast<QDialog*>(activeModalWidget)) - return false; + emit commitData(editor); emit closeEditor(editor, NoHint); } @@ -752,8 +746,13 @@ bool QStyledItemDelegate::editorEvent(QEvent *event, return false; } - Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked + Qt::CheckState state; + if ( flags & Qt::ItemIsTristate ) { + state = static_cast<Qt::CheckState>( (value.toInt() + 1) % 3 ); + } else { + state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked ? Qt::Unchecked : Qt::Checked); + } return model->setData(index, state, Qt::CheckStateRole); } diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp index 597ce04..2009499 100644 --- a/src/gui/itemviews/qtableview.cpp +++ b/src/gui/itemviews/qtableview.cpp @@ -59,6 +59,138 @@ QT_BEGIN_NAMESPACE +/** \internal + Add a span to the collection. the collection takes the ownership. + */ +void QSpanCollection::addSpan(QSpanCollection::Span *span) +{ + spans.append(span); + Index::iterator it_y = index.lowerBound(-span->top()); + if (it_y == index.end() || it_y.key() != -span->top()) { + //there is no spans that starts with the row in the index, so create a sublist for it. + SubIndex sub_index; + if (it_y != index.end()) { + //the previouslist is the list of spans that sarts _before_ the row of the span. + // and which may intersect this row. + const SubIndex previousList = it_y.value(); + foreach(Span *s, previousList) { + //If a subspans intersect the row, we need to split it into subspans + if(s->bottom() >= span->top()) + sub_index.insert(-s->left(), s); + } + } + it_y = index.insert(-span->top(), sub_index); + //we will insert span to *it_y in the later loop + } + + //insert the span as supspan in all the lists that intesects the span + while(-it_y.key() <= span->bottom()) { + (*it_y).insert(-span->left(), span); + if(it_y == index.begin()) + break; + --it_y; + } +} + + +/** \internal +* Has to be called after the height and width of a span is changed. +* +* old_height is the height before the change +* +* if the size of the span is now 0x0 the span will be deleted. +*/ +void QSpanCollection::updateSpan(QSpanCollection::Span *span, int old_height) +{ + if (old_height < span->height()) { + //add the span as subspan in all the lists that intersect the new covered columns + Index::iterator it_y = index.lowerBound(-(span->top() + old_height - 1)); + Q_ASSERT(it_y != index.end()); //it_y must exist since the span is in the list + while (-it_y.key() <= span->bottom()) { + (*it_y).insert(-span->left(), span); + if(it_y == index.begin()) + break; + --it_y; + } + } else if (old_height > span->height()) { + //remove the span from all the subspans lists that intersect the columns not covered anymore + Index::iterator it_y = index.lowerBound(-span->bottom()); + Q_ASSERT(it_y != index.end()); //it_y must exist since the span is in the list + while (-it_y.key() <= span->top() + old_height -1) { + if(-it_y.key() != span->bottom()) { + (*it_y).remove(-span->left()); + if (it_y->isEmpty()) { + it_y = index.erase(it_y) - 1; + } + } + if(it_y == index.begin()) + break; + --it_y; + } + } + + if (span->width() == 0 && span->height() == 0) { + spans.removeOne(span); + delete span; + } +} + +/** \internal + * \return a spans that spans over cell x,y (column,row) or 0 if there is none. + */ +QSpanCollection::Span *QSpanCollection::spanAt(int x, int y) const +{ + Index::const_iterator it_y = index.lowerBound(-y); + if (it_y == index.end()) + return 0; + SubIndex::const_iterator it_x = (*it_y).lowerBound(-x); + if (it_x == (*it_y).end()) + return 0; + Span *span = *it_x; + if (span->right() >= x && span->bottom() >= y) + return span; + return 0; +} + + +/** \internal +* remove and deletes all spans inside the collection +*/ +void QSpanCollection::clear() +{ + qDeleteAll(spans); + index.clear(); + spans.clear(); +} + +/** \internal + * return a list to all the spans that spans over cells in the given rectangle + */ +QList<QSpanCollection::Span *> QSpanCollection::spansInRect(int x, int y, int w, int h) const +{ + QSet<Span *> list; + Index::const_iterator it_y = index.lowerBound(-y); + if(it_y == index.end()) + --it_y; + while(-it_y.key() <= y + h) { + SubIndex::const_iterator it_x = (*it_y).lowerBound(-x); + if (it_x == (*it_y).end()) + --it_x; + while(-it_x.key() <= x + w) { + Span *s = *it_x; + if (s->bottom() >= y && s->right() >= x) + list << s; + if (it_x == (*it_y).begin()) + break; + --it_x; + } + if(it_y == index.begin()) + break; + --it_y; + } + return list.toList(); +} + class QTableCornerButton : public QAbstractButton { Q_OBJECT @@ -149,35 +281,40 @@ void QTableViewPrivate::trimHiddenSelections(QItemSelectionRange *range) const */ void QTableViewPrivate::setSpan(int row, int column, int rowSpan, int columnSpan) { - if (row < 0 || column < 0 || rowSpan < 0 || columnSpan < 0) + if (row < 0 || column < 0 || rowSpan <= 0 || columnSpan <= 0) { + qWarning() << "QTableView::setSpan: invalid span given: (" << row << ',' << column << ',' << rowSpan << ',' << columnSpan << ')'; return; - Span sp(row, column, rowSpan, columnSpan); - QList<Span>::iterator it; - for (it = spans.begin(); it != spans.end(); ++it) { - if (((*it).top() == sp.top()) && ((*it).left() == sp.left())) { - if ((sp.height() == 1) && (sp.width() == 1)) - spans.erase(it); // "Implicit" span (1, 1), no need to store it - else - *it = sp; // Replace + } + QSpanCollection::Span *sp = spans.spanAt(column, row); + if (sp) { + if (sp->top() != row || sp->left() != column) { + qWarning() << "QTableView::setSpan: span cannot overlap"; return; } + if (rowSpan == 1 && columnSpan == 1) { + rowSpan = columnSpan = 0; + } + const int old_height = sp->height(); + sp->m_bottom = row + rowSpan - 1; + sp->m_right = column + columnSpan - 1; + spans.updateSpan(sp, old_height); + return; } - spans.append(sp); + sp = new QSpanCollection::Span(row, column, rowSpan, columnSpan); + spans.addSpan(sp); } /*! \internal Gets the span information for the cell at (\a row, \a column). */ -QTableViewPrivate::Span QTableViewPrivate::span(int row, int column) const +QSpanCollection::Span QTableViewPrivate::span(int row, int column) const { - QList<Span>::const_iterator it; - for (it = spans.constBegin(); it != spans.constEnd(); ++it) { - Span span = *it; - if (isInSpan(row, column, span)) - return span; - } - return Span(row, column, 1, 1); + QSpanCollection::Span *sp = spans.spanAt(column, row); + if (sp) + return *sp; + + return QSpanCollection::Span(row, column, 1, 1); } /*! @@ -233,67 +370,9 @@ bool QTableViewPrivate::spanContainsSection(const QHeaderView *header, int logic /*! \internal - Returns true if one or more spans intersect column \a column. -*/ -bool QTableViewPrivate::spansIntersectColumn(int column) const -{ - QList<Span>::const_iterator it; - for (it = spans.constBegin(); it != spans.constEnd(); ++it) { - Span span = *it; - if (spanContainsColumn(column, span.left(), span.width())) - return true; - } - return false; -} - -/*! - \internal - Returns true if one or more spans intersect row \a row. -*/ -bool QTableViewPrivate::spansIntersectRow(int row) const -{ - QList<Span>::const_iterator it; - for (it = spans.constBegin(); it != spans.constEnd(); ++it) { - Span span = *it; - if (spanContainsRow(row, span.top(), span.height())) - return true; - } - return false; -} - -/*! - \internal - Returns true if one or more spans intersect one or more columns. -*/ -bool QTableViewPrivate::spansIntersectColumns(const QList<int> &columns) const -{ - QList<int>::const_iterator it; - for (it = columns.constBegin(); it != columns.constEnd(); ++it) { - if (spansIntersectColumn(*it)) - return true; - } - return false; -} - -/*! - \internal - Returns true if one or more spans intersect one or more rows. -*/ -bool QTableViewPrivate::spansIntersectRows(const QList<int> &rows) const -{ - QList<int>::const_iterator it; - for (it = rows.constBegin(); it != rows.constEnd(); ++it) { - if (spansIntersectRow(*it)) - return true; - } - return false; -} - -/*! - \internal Returns the visual rect for the given \a span. */ -QRect QTableViewPrivate::visualSpanRect(const Span &span) const +QRect QTableViewPrivate::visualSpanRect(const QSpanCollection::Span &span) const { Q_Q(const QTableView); // vertical @@ -319,42 +398,54 @@ QRect QTableViewPrivate::visualSpanRect(const Span &span) const preparation for the main drawing loop. \a drawn is a QBitArray of visualRowCountxvisualCoulumnCount which say if particular cell has been drawn */ -void QTableViewPrivate::drawAndClipSpans(const QRect &area, QPainter *painter, +void QTableViewPrivate::drawAndClipSpans(const QRegion &area, QPainter *painter, const QStyleOptionViewItemV4 &option, QBitArray *drawn, int firstVisualRow, int lastVisualRow, int firstVisualColumn, int lastVisualColumn) { bool alternateBase = false; QRegion region = viewport->rect(); - QList<Span>::const_iterator it; - for (it = spans.constBegin(); it != spans.constEnd(); ++it) { - Span span = *it; + QList<QSpanCollection::Span *> visibleSpans; + bool sectionMoved = verticalHeader->sectionsMoved() || horizontalHeader->sectionsMoved(); + + if (!sectionMoved) { + visibleSpans = spans.spansInRect(logicalColumn(firstVisualColumn), logicalRow(firstVisualRow), + lastVisualColumn - firstVisualColumn + 1, lastVisualRow - firstVisualRow + 1); + } else { + QSet<QSpanCollection::Span *> set; + for(int x = firstVisualColumn; x <= lastVisualColumn; x++) + for(int y = firstVisualRow; y <= lastVisualRow; y++) + set.insert(spans.spanAt(x,y)); + set.remove(0); + visibleSpans = set.toList(); + } - int row = span.top(); - int col = span.left(); + foreach (QSpanCollection::Span *span, visibleSpans) { + int row = span->top(); + int col = span->left(); if (isHidden(row, col)) continue; QModelIndex index = model->index(row, col, root); if (!index.isValid()) continue; - QRect rect = visualSpanRect(span); + QRect rect = visualSpanRect(*span); rect.translate(scrollDelayOffset); - if (!rect.intersects(area)) + if (!area.intersects(rect)) continue; QStyleOptionViewItemV4 opt = option; opt.rect = rect; - alternateBase = alternatingColors && (span.top() & 1); + alternateBase = alternatingColors && (span->top() & 1); if (alternateBase) opt.features |= QStyleOptionViewItemV2::Alternate; else opt.features &= ~QStyleOptionViewItemV2::Alternate; drawCell(painter, opt, index); region -= rect; - for (int r = span.top(); r <= span.bottom(); ++r) { + for (int r = span->top(); r <= span->bottom(); ++r) { const int vr = visualRow(r); if (vr < firstVisualRow || vr > lastVisualRow) continue; - for (int c = span.left(); c <= span.right(); ++c) { + for (int c = span->left(); c <= span->right(); ++c) { const int vc = visualColumn(c); if (vc < firstVisualColumn || vc > lastVisualColumn) continue; @@ -397,8 +488,7 @@ void QTableViewPrivate::drawCell(QPainter *painter, const QStyleOptionViewItemV4 opt.state |= QStyle::State_HasFocus; } - if (opt.features & QStyleOptionViewItemV2::Alternate) - painter->fillRect(opt.rect, opt.palette.brush(QPalette::AlternateBase)); + q->style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, q); if (const QWidget *widget = editorForIndex(index).editor) { painter->save(); @@ -753,7 +843,8 @@ void QTableView::paintEvent(QPaintEvent *event) uint x = horizontalHeader->length() - horizontalHeader->offset() - (rightToLeft ? 0 : 1); uint y = verticalHeader->length() - verticalHeader->offset() - 1; - QVector<QRect> rects = event->region().rects(); + const QRegion region = event->region().translated(offset); + const QVector<QRect> rects = region.rects(); //firstVisualRow is the visual index of the first visible row. lastVisualRow is the visual index of the last visible Row. //same goes for ...VisualColumn @@ -773,9 +864,13 @@ void QTableView::paintEvent(QPaintEvent *event) QBitArray drawn((lastVisualRow - firstVisualRow + 1) * (lastVisualColumn - firstVisualColumn + 1)); + if (d->hasSpans()) { + d->drawAndClipSpans(region, &painter, option, &drawn, + firstVisualRow, lastVisualRow, firstVisualColumn, lastVisualColumn); + } + for (int i = 0; i < rects.size(); ++i) { QRect dirtyArea = rects.at(i); - dirtyArea.translate(offset); dirtyArea.setBottom(qMin(dirtyArea.bottom(), int(y))); if (rightToLeft) { dirtyArea.setLeft(qMax(dirtyArea.left(), d->viewport->width() - int(x))); @@ -783,10 +878,6 @@ void QTableView::paintEvent(QPaintEvent *event) dirtyArea.setRight(qMin(dirtyArea.right(), int(x))); } - if (d->hasSpans()) - d->drawAndClipSpans(dirtyArea, &painter, option, &drawn, - firstVisualRow, lastVisualRow, firstVisualColumn, lastVisualColumn); - // get the horizontal start and end visual sections int left = horizontalHeader->visualIndexAt(dirtyArea.left()); int right = horizontalHeader->visualIndexAt(dirtyArea.right()); @@ -913,7 +1004,7 @@ QModelIndex QTableView::indexAt(const QPoint &pos) const int c = columnAt(pos.x()); if (r >= 0 && c >= 0) { if (d->hasSpans()) { - QTableViewPrivate::Span span = d->span(r, c); + QSpanCollection::Span span = d->span(r, c); r = span.top(); c = span.left(); } @@ -1011,14 +1102,14 @@ QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifi --visualRow; if (d->hasSpans()) { int row = d->logicalRow(visualRow); - QTableViewPrivate::Span span = d->span(row, current.column()); + QSpanCollection::Span span = d->span(row, current.column()); visualRow = d->visualRow(span.top()); visualColumn = d->visualColumn(span.left()); } break; case MoveDown: if (d->hasSpans()) { - QTableViewPrivate::Span span = d->span(current.row(), current.column()); + QSpanCollection::Span span = d->span(current.row(), current.column()); visualRow = d->visualRow(d->rowSpanEndLogical(span.top(), span.height())); } #ifdef QT_KEYPAD_NAVIGATION @@ -1030,7 +1121,7 @@ QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifi ++visualRow; if (d->hasSpans()) { int row = d->logicalRow(visualRow); - QTableViewPrivate::Span span = d->span(row, current.column()); + QSpanCollection::Span span = d->span(row, current.column()); visualColumn = d->visualColumn(span.left()); } break; @@ -1058,7 +1149,7 @@ QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifi --visualColumn; if (d->hasSpans()) { int column = d->logicalColumn(visualColumn); - QTableViewPrivate::Span span = d->span(current.row(), column); + QSpanCollection::Span span = d->span(current.row(), column); visualRow = d->visualRow(span.top()); visualColumn = d->visualColumn(span.left()); } @@ -1078,7 +1169,7 @@ QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifi } // else MoveRight case MoveRight: if (d->hasSpans()) { - QTableViewPrivate::Span span = d->span(current.row(), current.column()); + QSpanCollection::Span span = d->span(current.row(), current.column()); visualColumn = d->visualColumn(d->columnSpanEndLogical(span.left(), span.width())); } ++visualColumn; @@ -1086,7 +1177,7 @@ QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifi ++visualColumn; if (d->hasSpans()) { int column = d->logicalColumn(visualColumn); - QTableViewPrivate::Span span = d->span(current.row(), column); + QSpanCollection::Span span = d->span(current.row(), column); visualRow = d->visualRow(span.top()); } break; @@ -1161,9 +1252,8 @@ void QTableView::setSelection(const QRect &rect, QItemSelectionModel::SelectionF int right = qMax(d->visualColumn(tl.column()), d->visualColumn(br.column())); do { expanded = false; - QList<QTableViewPrivate::Span>::const_iterator it; - for (it = d->spans.constBegin(); it != d->spans.constEnd(); ++it) { - QTableViewPrivate::Span span = *it; + foreach (QSpanCollection::Span *it, d->spans.spans) { + const QSpanCollection::Span &span = *it; int t = d->visualRow(span.top()); int l = d->visualColumn(span.left()); int b = d->visualRow(d->rowSpanEndLogical(span.top(), span.height())); @@ -1253,7 +1343,7 @@ QRegion QTableView::visualRegionForSelection(const QItemSelection &selection) co bool verticalMoved = verticalHeader()->sectionsMoved(); bool horizontalMoved = horizontalHeader()->sectionsMoved(); - if ((verticalMoved && horizontalMoved) || d->hasSpans()) { + if ((verticalMoved && horizontalMoved) || (d->hasSpans() && (verticalMoved || horizontalMoved))) { for (int i = 0; i < selection.count(); ++i) { QItemSelectionRange range = selection.at(i); if (range.parent() != d->root || !range.isValid()) @@ -1296,9 +1386,19 @@ QRegion QTableView::visualRegionForSelection(const QItemSelection &selection) co if (range.parent() != d->root || !range.isValid()) continue; d->trimHiddenSelections(&range); - QRect tl = visualRect(range.topLeft()); - QRect br = visualRect(range.bottomRight()); - selectionRegion += QRegion(tl|br); + + const int rtop = rowViewportPosition(range.top()); + const int rbottom = rowViewportPosition(range.bottom()) + rowHeight(range.bottom()); + const int rleft = columnViewportPosition(range.left()); + const int rright = columnViewportPosition(range.right()) + columnWidth(range.right()); + selectionRegion += QRect(QPoint(rleft, rtop), QPoint(rright, rbottom)); + if (d->hasSpans()) { + foreach (QSpanCollection::Span *s, + d->spans.spansInRect(range.left(), range.top(), range.width(), range.height())) { + if (range.contains(s->top(), s->left(), range.parent())) + selectionRegion += d->visualSpanRect(*s); + } + } } } @@ -1428,6 +1528,8 @@ void QTableView::updateGeometries() ++columnsInViewport; } } + columnsInViewport = qMax(columnsInViewport, 1); //there must be always at least 1 column + if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) { const int visibleColumns = columnCount - d->horizontalHeader->hiddenSectionCount(); horizontalScrollBar()->setRange(0, visibleColumns - columnsInViewport); @@ -1454,6 +1556,8 @@ void QTableView::updateGeometries() ++rowsInViewport; } } + rowsInViewport = qMax(rowsInViewport, 1); //there must be always at least 1 row + if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) { const int visibleRows = rowCount - d->verticalHeader->hiddenSectionCount(); verticalScrollBar()->setRange(0, visibleRows - rowsInViewport); @@ -1743,14 +1847,14 @@ void QTableView::setSortingEnabled(bool enable) disconnect(horizontalHeader(), SIGNAL(sectionPressed(int)), this, SLOT(selectColumn(int))); connect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), - this, SLOT(sortByColumn(int))); + this, SLOT(sortByColumn(int)), Qt::UniqueConnection); sortByColumn(horizontalHeader()->sortIndicatorSection(), horizontalHeader()->sortIndicatorOrder()); } else { connect(d->horizontalHeader, SIGNAL(sectionEntered(int)), - this, SLOT(_q_selectColumn(int))); + this, SLOT(_q_selectColumn(int)), Qt::UniqueConnection); connect(horizontalHeader(), SIGNAL(sectionPressed(int)), - this, SLOT(selectColumn(int))); + this, SLOT(selectColumn(int)), Qt::UniqueConnection); disconnect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(sortByColumn(int))); } @@ -1874,7 +1978,7 @@ QRect QTableView::visualRect(const QModelIndex &index) const d->executePostedLayout(); if (d->hasSpans()) { - QTableViewPrivate::Span span = d->span(index.row(), index.column()); + QSpanCollection::Span span = d->span(index.row(), index.column()); return d->visualSpanRect(span); } @@ -1903,7 +2007,7 @@ void QTableView::scrollTo(const QModelIndex &index, ScrollHint hint) || isIndexHidden(index)) return; - QTableViewPrivate::Span span; + QSpanCollection::Span span; if (d->hasSpans()) span = d->span(index.row(), index.column()); @@ -1936,7 +2040,7 @@ void QTableView::scrollTo(const QModelIndex &index, ScrollHint hint) if (positionAtRight || hint == PositionAtCenter || positionAtLeft) { int hiddenSections = 0; if (d->horizontalHeader->sectionsHidden()) { - for (int s = horizontalIndex; s >= 0; --s) { + for (int s = horizontalIndex - 1; s >= 0; --s) { int column = d->horizontalHeader->logicalIndex(s); if (d->horizontalHeader->isSectionHidden(column)) ++hiddenSections; @@ -1991,7 +2095,7 @@ void QTableView::scrollTo(const QModelIndex &index, ScrollHint hint) if (hint == PositionAtBottom || hint == PositionAtCenter || hint == PositionAtTop) { int hiddenSections = 0; if (d->verticalHeader->sectionsHidden()) { - for (int s = verticalIndex; s >= 0; --s) { + for (int s = verticalIndex - 1; s >= 0; --s) { int row = d->verticalHeader->logicalIndex(s); if (d->verticalHeader->isSectionHidden(row)) ++hiddenSections; @@ -2010,7 +2114,7 @@ void QTableView::scrollTo(const QModelIndex &index, ScrollHint hint) } } - d->setDirtyRegion(visualRect(index)); + update(index); } /*! @@ -2058,7 +2162,7 @@ void QTableView::timerEvent(QTimerEvent *event) QRect rect; int viewportHeight = d->viewport->height(); int viewportWidth = d->viewport->width(); - if (d->hasSpans() && d->spansIntersectColumns(d->columnsToUpdate)) { + if (d->hasSpans()) { rect = QRect(0, 0, viewportWidth, viewportHeight); } else { for (int i = d->columnsToUpdate.size()-1; i >= 0; --i) { @@ -2083,7 +2187,7 @@ void QTableView::timerEvent(QTimerEvent *event) int viewportHeight = d->viewport->height(); int viewportWidth = d->viewport->width(); int top; - if (d->hasSpans() && d->spansIntersectRows(d->rowsToUpdate)) { + if (d->hasSpans()) { top = 0; } else { top = viewportHeight; @@ -2114,7 +2218,7 @@ void QTableView::rowMoved(int, int oldIndex, int newIndex) updateGeometries(); int logicalOldIndex = d->verticalHeader->logicalIndex(oldIndex); int logicalNewIndex = d->verticalHeader->logicalIndex(newIndex); - if (d->hasSpans() && (d->spansIntersectRow(logicalOldIndex) || d->spansIntersectRow(logicalNewIndex))) { + if (d->hasSpans()) { d->viewport->update(); } else { int oldTop = rowViewportPosition(logicalOldIndex); @@ -2142,7 +2246,7 @@ void QTableView::columnMoved(int, int oldIndex, int newIndex) updateGeometries(); int logicalOldIndex = d->horizontalHeader->logicalIndex(oldIndex); int logicalNewIndex = d->horizontalHeader->logicalIndex(newIndex); - if (d->hasSpans() && (d->spansIntersectColumn(logicalOldIndex) || d->spansIntersectColumn(logicalNewIndex))) { + if (d->hasSpans()) { d->viewport->update(); } else { int oldLeft = columnViewportPosition(logicalOldIndex); @@ -2325,7 +2429,7 @@ bool QTableView::isIndexHidden(const QModelIndex &index) const if (isRowHidden(index.row()) || isColumnHidden(index.column())) return true; if (d->hasSpans()) { - QTableViewPrivate::Span span = d->span(index.row(), index.column()); + QSpanCollection::Span span = d->span(index.row(), index.column()); return !((span.top() == index.row()) && (span.left() == index.column())); } return false; diff --git a/src/gui/itemviews/qtableview_p.h b/src/gui/itemviews/qtableview_p.h index ef1ae7a..acfd5ec 100644 --- a/src/gui/itemviews/qtableview_p.h +++ b/src/gui/itemviews/qtableview_p.h @@ -53,12 +53,69 @@ // We mean it. // +#include <QtCore/QList> +#include <QtCore/QMap> +#include <QtCore/QSet> +#include <QtCore/QDebug> #include "private/qabstractitemview_p.h" #ifndef QT_NO_TABLEVIEW QT_BEGIN_NAMESPACE +/** \internal +* +* This is a list of span with a binary index to look up quickly a span at a certain index. +* +* The index is a map of map. +* spans are mentaly divided into sub spans so that the start of any subspans doesn't overlap +* with any other subspans. There is no real representation of the subspans. +* The key of the first map is the row where the subspan starts, the value of the first map is +* a list (map) of all subspans that starts at the same row. It is indexed with its row +*/ +class QSpanCollection +{ +public: + struct Span + { + int m_top; + int m_left; + int m_bottom; + int m_right; + Span() + : m_top(-1), m_left(-1), m_bottom(-1), m_right(-1) { } + Span(int row, int column, int rowCount, int columnCount) + : m_top(row), m_left(column), m_bottom(row+rowCount-1), m_right(column+columnCount-1) { } + inline int top() const { return m_top; } + inline int left() const { return m_left; } + inline int bottom() const { return m_bottom; } + inline int right() const { return m_right; } + inline int height() const { return m_bottom - m_top + 1; } + inline int width() const { return m_right - m_left + 1; } + }; + + ~QSpanCollection() + { + qDeleteAll(spans); + } + + void addSpan(Span *span); + void updateSpan(Span *span, int old_height); + Span *spanAt(int x, int y) const; + void clear(); + QList<Span *> spansInRect(int x, int y, int w, int h) const; + + QList<Span *> spans; //lists of all spans +private: + //the indexes are negative so the QMap::lowerBound do what i need. + typedef QMap<int, Span *> SubIndex; + typedef QMap<int, SubIndex> Index; + Index index; +}; + +Q_DECLARE_TYPEINFO ( QSpanCollection::Span, Q_MOVABLE_TYPE); + + class QTableViewPrivate : public QAbstractItemViewPrivate { Q_DECLARE_PUBLIC(QTableView) @@ -98,11 +155,7 @@ public: int sectionSpanEndLogical(const QHeaderView *header, int logical, int span) const; int sectionSpanSize(const QHeaderView *header, int logical, int span) const; bool spanContainsSection(const QHeaderView *header, int logical, int spanLogical, int span) const; - bool spansIntersectColumn(int column) const; - bool spansIntersectRow(int row) const; - bool spansIntersectColumns(const QList<int> &columns) const; - bool spansIntersectRows(const QList<int> &rows) const; - void drawAndClipSpans(const QRect &area, QPainter *painter, + void drawAndClipSpans(const QRegion &area, QPainter *painter, const QStyleOptionViewItemV4 &option, QBitArray *drawn, int firstVisualRow, int lastVisualRow, int firstVisualColumn, int lastVisualColumn); void drawCell(QPainter *painter, const QStyleOptionViewItemV4 &option, const QModelIndex &index); @@ -121,27 +174,10 @@ public: bool sortingEnabled; bool geometryRecursionBlock; - struct Span - { - int m_top; - int m_left; - int m_bottom; - int m_right; - Span() - : m_top(-1), m_left(-1), m_bottom(-1), m_right(-1) { } - Span(int row, int column, int rowCount, int columnCount) - : m_top(row), m_left(column), m_bottom(row+rowCount-1), m_right(column+columnCount-1) { } - inline int top() const { return m_top; } - inline int left() const { return m_left; } - inline int bottom() const { return m_bottom; } - inline int right() const { return m_right; } - inline int height() const { return m_bottom - m_top + 1; } - inline int width() const { return m_right - m_left + 1; } - }; - QList<Span> spans; + QSpanCollection spans; void setSpan(int row, int column, int rowSpan, int columnSpan); - Span span(int row, int column) const; + QSpanCollection::Span span(int row, int column) const; inline int rowSpan(int row, int column) const { return span(row, column).height(); } @@ -149,17 +185,7 @@ public: return span(row, column).width(); } inline bool hasSpans() const { - return !spans.isEmpty(); - } - inline bool spanContainsRow(int row, int spanRow, int span) const { - return spanContainsSection(verticalHeader, row, spanRow, span); - } - inline bool spanContainsColumn(int column, int spanColumn, int span) const { - return spanContainsSection(horizontalHeader, column, spanColumn, span); - } - inline bool isInSpan(int row, int column, const Span &span) const { - return spanContainsRow(row, span.top(), span.height()) - && spanContainsColumn(column, span.left(), span.width()); + return !spans.spans.isEmpty(); } inline int rowSpanHeight(int row, int span) const { return sectionSpanSize(verticalHeader, row, span); @@ -194,7 +220,7 @@ public: return isColumnHidden(c) || !isCellEnabled(r, c); } - QRect visualSpanRect(const Span &span) const; + QRect visualSpanRect(const QSpanCollection::Span &span) const; void _q_selectRow(int row); void _q_selectColumn(int column); diff --git a/src/gui/itemviews/qtablewidget.cpp b/src/gui/itemviews/qtablewidget.cpp index 5957d5c..5756f35 100644 --- a/src/gui/itemviews/qtablewidget.cpp +++ b/src/gui/itemviews/qtablewidget.cpp @@ -530,24 +530,6 @@ void QTableModel::sort(int column, Qt::SortOrder order) emit layoutChanged(); } -bool QTableModel::canConvertToDouble(const QVariant &value) -{ - switch (value.type()) { - case QVariant::Bool: - case QVariant::Int: - case QVariant::UInt: - case QVariant::LongLong: - case QVariant::ULongLong: - case QVariant::Double: - case QVariant::Char: - return true; - default: - return false; - } - return false; -} - - /* \internal @@ -1410,7 +1392,7 @@ QVariant QTableWidgetItem::data(int role) const bool QTableWidgetItem::operator<(const QTableWidgetItem &other) const { const QVariant v1 = data(Qt::DisplayRole), v2 = other.data(Qt::DisplayRole); - if (QTableModel::canConvertToDouble(v1) && QTableModel::canConvertToDouble(v2)) + if (QAbstractItemModelPrivate::canConvertToDouble(v1) && QAbstractItemModelPrivate::canConvertToDouble(v2)) return v1.toDouble() < v2.toDouble(); return v1.toString() < v2.toString(); } @@ -1588,7 +1570,7 @@ void QTableWidgetPrivate::setup() QObject::connect(q, SIGNAL(activated(QModelIndex)), q, SLOT(_q_emitItemActivated(QModelIndex))); QObject::connect(q, SIGNAL(entered(QModelIndex)), q, SLOT(_q_emitItemEntered(QModelIndex))); // model signals - QObject::connect(model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), + QObject::connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), q, SLOT(_q_emitItemChanged(QModelIndex))); // selection signals QObject::connect(q->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), @@ -1596,15 +1578,15 @@ void QTableWidgetPrivate::setup() QObject::connect(q->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), q, SIGNAL(itemSelectionChanged())); // sorting - QObject::connect(model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), + QObject::connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), q, SLOT(_q_dataChanged(QModelIndex,QModelIndex))); - QObject::connect(model(), SIGNAL(columnsRemoved(QModelIndex,int,int)), q, SLOT(_q_sort())); + QObject::connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)), q, SLOT(_q_sort())); } void QTableWidgetPrivate::_q_emitItemPressed(const QModelIndex &index) { Q_Q(QTableWidget); - if (QTableWidgetItem *item = model()->item(index)) + if (QTableWidgetItem *item = tableModel()->item(index)) emit q->itemPressed(item); emit q->cellPressed(index.row(), index.column()); } @@ -1612,7 +1594,7 @@ void QTableWidgetPrivate::_q_emitItemPressed(const QModelIndex &index) void QTableWidgetPrivate::_q_emitItemClicked(const QModelIndex &index) { Q_Q(QTableWidget); - if (QTableWidgetItem *item = model()->item(index)) + if (QTableWidgetItem *item = tableModel()->item(index)) emit q->itemClicked(item); emit q->cellClicked(index.row(), index.column()); } @@ -1620,7 +1602,7 @@ void QTableWidgetPrivate::_q_emitItemClicked(const QModelIndex &index) void QTableWidgetPrivate::_q_emitItemDoubleClicked(const QModelIndex &index) { Q_Q(QTableWidget); - if (QTableWidgetItem *item = model()->item(index)) + if (QTableWidgetItem *item = tableModel()->item(index)) emit q->itemDoubleClicked(item); emit q->cellDoubleClicked(index.row(), index.column()); } @@ -1628,7 +1610,7 @@ void QTableWidgetPrivate::_q_emitItemDoubleClicked(const QModelIndex &index) void QTableWidgetPrivate::_q_emitItemActivated(const QModelIndex &index) { Q_Q(QTableWidget); - if (QTableWidgetItem *item = model()->item(index)) + if (QTableWidgetItem *item = tableModel()->item(index)) emit q->itemActivated(item); emit q->cellActivated(index.row(), index.column()); } @@ -1636,7 +1618,7 @@ void QTableWidgetPrivate::_q_emitItemActivated(const QModelIndex &index) void QTableWidgetPrivate::_q_emitItemEntered(const QModelIndex &index) { Q_Q(QTableWidget); - if (QTableWidgetItem *item = model()->item(index)) + if (QTableWidgetItem *item = tableModel()->item(index)) emit q->itemEntered(item); emit q->cellEntered(index.row(), index.column()); } @@ -1644,7 +1626,7 @@ void QTableWidgetPrivate::_q_emitItemEntered(const QModelIndex &index) void QTableWidgetPrivate::_q_emitItemChanged(const QModelIndex &index) { Q_Q(QTableWidget); - if (QTableWidgetItem *item = model()->item(index)) + if (QTableWidgetItem *item = tableModel()->item(index)) emit q->itemChanged(item); emit q->cellChanged(index.row(), index.column()); } @@ -1653,8 +1635,8 @@ void QTableWidgetPrivate::_q_emitCurrentItemChanged(const QModelIndex ¤t, const QModelIndex &previous) { Q_Q(QTableWidget); - QTableWidgetItem *currentItem = model()->item(current); - QTableWidgetItem *previousItem = model()->item(previous); + QTableWidgetItem *currentItem = tableModel()->item(current); + QTableWidgetItem *previousItem = tableModel()->item(previous); if (currentItem || previousItem) emit q->currentItemChanged(currentItem, previousItem); emit q->currentCellChanged(current.row(), current.column(), previous.row(), previous.column()); @@ -1662,23 +1644,21 @@ void QTableWidgetPrivate::_q_emitCurrentItemChanged(const QModelIndex ¤t, void QTableWidgetPrivate::_q_sort() { - Q_Q(QTableWidget); if (sortingEnabled) { - int column = q->horizontalHeader()->sortIndicatorSection(); - Qt::SortOrder order = q->horizontalHeader()->sortIndicatorOrder(); - model()->sort(column, order); + int column = horizontalHeader->sortIndicatorSection(); + Qt::SortOrder order = horizontalHeader->sortIndicatorOrder(); + model->sort(column, order); } } void QTableWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) { - Q_Q(QTableWidget); if (sortingEnabled && topLeft.isValid() && bottomRight.isValid()) { - int column = q->horizontalHeader()->sortIndicatorSection(); + int column = horizontalHeader->sortIndicatorSection(); if (column >= topLeft.column() && column <= bottomRight.column()) { - Qt::SortOrder order = q->horizontalHeader()->sortIndicatorOrder(); - model()->ensureSorted(column, order, topLeft.row(), bottomRight.row()); + Qt::SortOrder order = horizontalHeader->sortIndicatorOrder(); + tableModel()->ensureSorted(column, order, topLeft.row(), bottomRight.row()); } } } @@ -1739,7 +1719,7 @@ void QTableWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, This signal is emitted whenever the selection changes. - \sa selectedItems() isItemSelected() + \sa selectedItems() QTableWidgetItem::isSelected() */ @@ -1882,7 +1862,7 @@ QTableWidget::~QTableWidget() void QTableWidget::setRowCount(int rows) { Q_D(QTableWidget); - d->model()->setRowCount(rows); + d->tableModel()->setRowCount(rows); } /*! @@ -1892,7 +1872,7 @@ void QTableWidget::setRowCount(int rows) int QTableWidget::rowCount() const { Q_D(const QTableWidget); - return d->model()->rowCount(); + return d->model->rowCount(); } /*! @@ -1905,7 +1885,7 @@ int QTableWidget::rowCount() const void QTableWidget::setColumnCount(int columns) { Q_D(QTableWidget); - d->model()->setColumnCount(columns); + d->tableModel()->setColumnCount(columns); } /*! @@ -1915,7 +1895,7 @@ void QTableWidget::setColumnCount(int columns) int QTableWidget::columnCount() const { Q_D(const QTableWidget); - return d->model()->columnCount(); + return d->model->columnCount(); } /*! @@ -1924,7 +1904,7 @@ int QTableWidget::columnCount() const int QTableWidget::row(const QTableWidgetItem *item) const { Q_D(const QTableWidget); - return d->model()->index(item).row(); + return d->tableModel()->index(item).row(); } /*! @@ -1933,7 +1913,7 @@ int QTableWidget::row(const QTableWidgetItem *item) const int QTableWidget::column(const QTableWidgetItem *item) const { Q_D(const QTableWidget); - return d->model()->index(item).column(); + return d->tableModel()->index(item).column(); } @@ -1946,7 +1926,7 @@ int QTableWidget::column(const QTableWidgetItem *item) const QTableWidgetItem *QTableWidget::item(int row, int column) const { Q_D(const QTableWidget); - return d->model()->item(row, column); + return d->tableModel()->item(row, column); } /*! @@ -1975,7 +1955,7 @@ void QTableWidget::setItem(int row, int column, QTableWidgetItem *item) qWarning("QTableWidget: cannot insert an item that is already owned by another QTableWidget"); } else { item->view = this; - d->model()->setItem(row, column, item); + d->tableModel()->setItem(row, column, item); } } else { delete takeItem(row, column); @@ -1988,7 +1968,7 @@ void QTableWidget::setItem(int row, int column, QTableWidgetItem *item) QTableWidgetItem *QTableWidget::takeItem(int row, int column) { Q_D(QTableWidget); - QTableWidgetItem *item = d->model()->takeItem(row, column); + QTableWidgetItem *item = d->tableModel()->takeItem(row, column); if (item) item->view = 0; return item; @@ -2000,7 +1980,7 @@ QTableWidgetItem *QTableWidget::takeItem(int row, int column) QTableWidgetItem *QTableWidget::verticalHeaderItem(int row) const { Q_D(const QTableWidget); - return d->model()->verticalHeaderItem(row); + return d->tableModel()->verticalHeaderItem(row); } /*! @@ -2011,7 +1991,7 @@ void QTableWidget::setVerticalHeaderItem(int row, QTableWidgetItem *item) Q_D(QTableWidget); if (item) { item->view = this; - d->model()->setVerticalHeaderItem(row, item); + d->tableModel()->setVerticalHeaderItem(row, item); } else { delete takeVerticalHeaderItem(row); } @@ -2024,7 +2004,7 @@ void QTableWidget::setVerticalHeaderItem(int row, QTableWidgetItem *item) QTableWidgetItem *QTableWidget::takeVerticalHeaderItem(int row) { Q_D(QTableWidget); - QTableWidgetItem *itm = d->model()->takeVerticalHeaderItem(row); + QTableWidgetItem *itm = d->tableModel()->takeVerticalHeaderItem(row); if (itm) itm->view = 0; return itm; @@ -2037,7 +2017,7 @@ QTableWidgetItem *QTableWidget::takeVerticalHeaderItem(int row) QTableWidgetItem *QTableWidget::horizontalHeaderItem(int column) const { Q_D(const QTableWidget); - return d->model()->horizontalHeaderItem(column); + return d->tableModel()->horizontalHeaderItem(column); } /*! @@ -2048,7 +2028,7 @@ void QTableWidget::setHorizontalHeaderItem(int column, QTableWidgetItem *item) Q_D(QTableWidget); if (item) { item->view = this; - d->model()->setHorizontalHeaderItem(column, item); + d->tableModel()->setHorizontalHeaderItem(column, item); } else { delete takeHorizontalHeaderItem(column); } @@ -2061,7 +2041,7 @@ void QTableWidget::setHorizontalHeaderItem(int column, QTableWidgetItem *item) QTableWidgetItem *QTableWidget::takeHorizontalHeaderItem(int column) { Q_D(QTableWidget); - QTableWidgetItem *itm = d->model()->takeHorizontalHeaderItem(column); + QTableWidgetItem *itm = d->tableModel()->takeHorizontalHeaderItem(column); if (itm) itm->view = 0; return itm; @@ -2073,7 +2053,7 @@ QTableWidgetItem *QTableWidget::takeHorizontalHeaderItem(int column) void QTableWidget::setVerticalHeaderLabels(const QStringList &labels) { Q_D(QTableWidget); - QTableModel *model = d->model(); + QTableModel *model = d->tableModel(); QTableWidgetItem *item = 0; for (int i = 0; i < model->rowCount() && i < labels.count(); ++i) { item = model->verticalHeaderItem(i); @@ -2091,7 +2071,7 @@ void QTableWidget::setVerticalHeaderLabels(const QStringList &labels) void QTableWidget::setHorizontalHeaderLabels(const QStringList &labels) { Q_D(QTableWidget); - QTableModel *model = d->model(); + QTableModel *model = d->tableModel(); QTableWidgetItem *item = 0; for (int i = 0; i < model->columnCount() && i < labels.count(); ++i) { item = model->horizontalHeaderItem(i); @@ -2131,7 +2111,7 @@ int QTableWidget::currentColumn() const QTableWidgetItem *QTableWidget::currentItem() const { Q_D(const QTableWidget); - return d->model()->item(currentIndex()); + return d->tableModel()->item(currentIndex()); } /*! @@ -2145,7 +2125,7 @@ QTableWidgetItem *QTableWidget::currentItem() const void QTableWidget::setCurrentItem(QTableWidgetItem *item) { Q_D(QTableWidget); - setCurrentIndex(d->model()->index(item)); + setCurrentIndex(d->tableModel()->index(item)); } /*! @@ -2158,7 +2138,7 @@ void QTableWidget::setCurrentItem(QTableWidgetItem *item) void QTableWidget::setCurrentItem(QTableWidgetItem *item, QItemSelectionModel::SelectionFlags command) { Q_D(QTableWidget); - d->selectionModel->setCurrentIndex(d->model()->index(item), command); + d->selectionModel->setCurrentIndex(d->tableModel()->index(item), command); } /*! @@ -2197,7 +2177,7 @@ void QTableWidget::setCurrentCell(int row, int column, QItemSelectionModel::Sele void QTableWidget::sortItems(int column, Qt::SortOrder order) { Q_D(QTableWidget); - d->model()->sort(column, order); + d->model->sort(column, order); horizontalHeader()->setSortIndicator(column, order); } @@ -2226,7 +2206,7 @@ void QTableWidget::editItem(QTableWidgetItem *item) Q_D(QTableWidget); if (!item) return; - edit(d->model()->index(item)); + edit(d->tableModel()->index(item)); } /*! @@ -2239,7 +2219,7 @@ void QTableWidget::openPersistentEditor(QTableWidgetItem *item) Q_D(QTableWidget); if (!item) return; - QModelIndex index = d->model()->index(item); + QModelIndex index = d->tableModel()->index(item); QAbstractItemView::openPersistentEditor(index); } @@ -2253,7 +2233,7 @@ void QTableWidget::closePersistentEditor(QTableWidgetItem *item) Q_D(QTableWidget); if (!item) return; - QModelIndex index = d->model()->index(item); + QModelIndex index = d->tableModel()->index(item); QAbstractItemView::closePersistentEditor(index); } @@ -2303,7 +2283,7 @@ void QTableWidget::setCellWidget(int row, int column, QWidget *widget) bool QTableWidget::isItemSelected(const QTableWidgetItem *item) const { Q_D(const QTableWidget); - QModelIndex index = d->model()->index(item); + QModelIndex index = d->tableModel()->index(item); return selectionModel()->isSelected(index); } @@ -2317,7 +2297,7 @@ bool QTableWidget::isItemSelected(const QTableWidgetItem *item) const void QTableWidget::setItemSelected(const QTableWidgetItem *item, bool select) { Q_D(QTableWidget); - QModelIndex index = d->model()->index(item); + QModelIndex index = d->tableModel()->index(item); selectionModel()->select(index, select ? QItemSelectionModel::Select : QItemSelectionModel::Deselect); } @@ -2374,7 +2354,7 @@ QList<QTableWidgetItem*> QTableWidget::selectedItems() QModelIndex index = indexes.at(i); if (isIndexHidden(index)) continue; - QTableWidgetItem *item = d->model()->item(index); + QTableWidgetItem *item = d->tableModel()->item(index); if (item) items.append(item); } @@ -2390,11 +2370,11 @@ QList<QTableWidgetItem*> QTableWidget::findItems(const QString &text, Qt::MatchF Q_D(const QTableWidget); QModelIndexList indexes; for (int column = 0; column < columnCount(); ++column) - indexes += d->model()->match(model()->index(0, column, QModelIndex()), + indexes += d->model->match(model()->index(0, column, QModelIndex()), Qt::DisplayRole, text, -1, flags); QList<QTableWidgetItem*> items; for (int i = 0; i < indexes.size(); ++i) - items.append(d->model()->item(indexes.at(i))); + items.append(d->tableModel()->item(indexes.at(i))); return items; } @@ -2428,7 +2408,7 @@ int QTableWidget::visualColumn(int logicalColumn) const QTableWidgetItem *QTableWidget::itemAt(const QPoint &p) const { Q_D(const QTableWidget); - return d->model()->item(indexAt(p)); + return d->tableModel()->item(indexAt(p)); } /*! @@ -2439,7 +2419,7 @@ QRect QTableWidget::visualItemRect(const QTableWidgetItem *item) const Q_D(const QTableWidget); if (!item) return QRect(); - QModelIndex index = d->model()->index(const_cast<QTableWidgetItem*>(item)); + QModelIndex index = d->tableModel()->index(const_cast<QTableWidgetItem*>(item)); Q_ASSERT(index.isValid()); return visualRect(index); } @@ -2455,7 +2435,7 @@ void QTableWidget::scrollToItem(const QTableWidgetItem *item, QAbstractItemView: Q_D(QTableWidget); if (!item) return; - QModelIndex index = d->model()->index(const_cast<QTableWidgetItem*>(item)); + QModelIndex index = d->tableModel()->index(const_cast<QTableWidgetItem*>(item)); Q_ASSERT(index.isValid()); QTableView::scrollTo(index, hint); } @@ -2468,7 +2448,7 @@ void QTableWidget::scrollToItem(const QTableWidgetItem *item, QAbstractItemView: const QTableWidgetItem *QTableWidget::itemPrototype() const { Q_D(const QTableWidget); - return d->model()->itemPrototype(); + return d->tableModel()->itemPrototype(); } /*! @@ -2487,7 +2467,7 @@ const QTableWidgetItem *QTableWidget::itemPrototype() const void QTableWidget::setItemPrototype(const QTableWidgetItem *item) { Q_D(QTableWidget); - d->model()->setItemPrototype(item); + d->tableModel()->setItemPrototype(item); } /*! @@ -2496,7 +2476,7 @@ void QTableWidget::setItemPrototype(const QTableWidgetItem *item) void QTableWidget::insertRow(int row) { Q_D(QTableWidget); - d->model()->insertRows(row); + d->tableModel()->insertRows(row); } /*! @@ -2505,7 +2485,7 @@ void QTableWidget::insertRow(int row) void QTableWidget::insertColumn(int column) { Q_D(QTableWidget); - d->model()->insertColumns(column); + d->tableModel()->insertColumns(column); } /*! @@ -2514,7 +2494,7 @@ void QTableWidget::insertColumn(int column) void QTableWidget::removeRow(int row) { Q_D(QTableWidget); - d->model()->removeRows(row); + d->tableModel()->removeRows(row); } /*! @@ -2523,7 +2503,7 @@ void QTableWidget::removeRow(int row) void QTableWidget::removeColumn(int column) { Q_D(QTableWidget); - d->model()->removeColumns(column); + d->tableModel()->removeColumns(column); } /*! @@ -2536,7 +2516,7 @@ void QTableWidget::clear() { Q_D(QTableWidget); selectionModel()->clear(); - d->model()->clear(); + d->tableModel()->clear(); } /*! @@ -2550,7 +2530,7 @@ void QTableWidget::clearContents() { Q_D(QTableWidget); selectionModel()->clear(); - d->model()->clearContents(); + d->tableModel()->clearContents(); } /*! @@ -2561,7 +2541,7 @@ void QTableWidget::clearContents() */ QStringList QTableWidget::mimeTypes() const { - return d_func()->model()->QAbstractTableModel::mimeTypes(); + return d_func()->tableModel()->QAbstractTableModel::mimeTypes(); } /*! @@ -2574,7 +2554,7 @@ QStringList QTableWidget::mimeTypes() const */ QMimeData *QTableWidget::mimeData(const QList<QTableWidgetItem*>) const { - return d_func()->model()->internalMimeData(); + return d_func()->tableModel()->internalMimeData(); } /*! @@ -2596,7 +2576,7 @@ bool QTableWidget::dropMimeData(int row, int column, const QMimeData *data, Qt:: column = -1; } #endif - return d_func()->model()->QAbstractTableModel::dropMimeData(data, action , row, column, idx); + return d_func()->tableModel()->QAbstractTableModel::dropMimeData(data, action , row, column, idx); } /*! @@ -2606,7 +2586,7 @@ bool QTableWidget::dropMimeData(int row, int column, const QMimeData *data, Qt:: */ Qt::DropActions QTableWidget::supportedDropActions() const { - return d_func()->model()->QAbstractTableModel::supportedDropActions() | Qt::MoveAction; + return d_func()->tableModel()->QAbstractTableModel::supportedDropActions() | Qt::MoveAction; } /*! @@ -2630,7 +2610,7 @@ QList<QTableWidgetItem*> QTableWidget::items(const QMimeData *data) const QModelIndex QTableWidget::indexFromItem(QTableWidgetItem *item) const { Q_D(const QTableWidget); - return d->model()->index(item); + return d->tableModel()->index(item); } /*! @@ -2640,7 +2620,7 @@ QModelIndex QTableWidget::indexFromItem(QTableWidgetItem *item) const QTableWidgetItem *QTableWidget::itemFromIndex(const QModelIndex &index) const { Q_D(const QTableWidget); - return d->model()->item(index); + return d->tableModel()->item(index); } /*! diff --git a/src/gui/itemviews/qtablewidget_p.h b/src/gui/itemviews/qtablewidget_p.h index 6e7f3a3..596988a 100644 --- a/src/gui/itemviews/qtablewidget_p.h +++ b/src/gui/itemviews/qtablewidget_p.h @@ -144,7 +144,6 @@ public: const QPair<QTableWidgetItem*,int> &right); static bool itemGreaterThan(const QPair<QTableWidgetItem*,int> &left, const QPair<QTableWidgetItem*,int> &right); - static bool canConvertToDouble(const QVariant &value); void ensureSorted(int column, Qt::SortOrder order, int start, int end); QVector<QTableWidgetItem*> columnItems(int column) const; @@ -190,7 +189,7 @@ class QTableWidgetPrivate : public QTableViewPrivate Q_DECLARE_PUBLIC(QTableWidget) public: QTableWidgetPrivate() : QTableViewPrivate() {} - inline QTableModel *model() const { return qobject_cast<QTableModel*>(q_func()->model()); } + inline QTableModel *tableModel() const { return qobject_cast<QTableModel*>(model); } void setup(); // view signals diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index cdcce83..7536d72 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -238,11 +238,6 @@ void QTreeView::setModel(QAbstractItemModel *model) connect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(rowsRemoved(QModelIndex,int,int))); - connect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)), - this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int))); - connect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)), - this, SLOT(_q_columnsRemoved(QModelIndex,int,int))); - connect(d->model, SIGNAL(modelAboutToBeReset()), SLOT(_q_modelAboutToBeReset())); if (d->sortingEnabled) @@ -267,10 +262,6 @@ void QTreeView::setSelectionModel(QItemSelectionModel *selectionModel) Q_D(QTreeView); Q_ASSERT(selectionModel); if (d->selectionModel) { - if (d->allColumnsShowFocus) { - QObject::disconnect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)), - this, SLOT(_q_currentChanged(QModelIndex,QModelIndex))); - } // support row editing disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)), d->model, SLOT(submit())); @@ -280,10 +271,6 @@ void QTreeView::setSelectionModel(QItemSelectionModel *selectionModel) QAbstractItemView::setSelectionModel(selectionModel); if (d->selectionModel) { - if (d->allColumnsShowFocus) { - QObject::connect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)), - this, SLOT(_q_currentChanged(QModelIndex,QModelIndex))); - } // support row editing connect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)), d->model, SLOT(submit())); @@ -680,10 +667,9 @@ void QTreeView::dataChanged(const QModelIndex &topLeft, const QModelIndex &botto // refresh the height cache here; we don't really lose anything by getting the size hint, // since QAbstractItemView::dataChanged() will get the visualRect for the items anyway - QModelIndex top = topLeft.sibling(topLeft.row(), 0); - int topViewIndex = d->viewIndex(top); + int topViewIndex = d->viewIndex(topLeft); if (topViewIndex == 0) - d->defaultItemHeight = indexRowSizeHint(top); + d->defaultItemHeight = indexRowSizeHint(topLeft); bool sizeChanged = false; if (topViewIndex != -1) { if (topLeft == bottomRight) { @@ -691,8 +677,7 @@ void QTreeView::dataChanged(const QModelIndex &topLeft, const QModelIndex &botto d->invalidateHeightCache(topViewIndex); sizeChanged = (oldHeight != d->itemHeight(topViewIndex)); } else { - QModelIndex bottom = bottomRight.sibling(bottomRight.row(), 0); - int bottomViewIndex = d->viewIndex(bottom); + int bottomViewIndex = d->viewIndex(bottomRight); for (int i = topViewIndex; i <= bottomViewIndex; ++i) { int oldHeight = d->itemHeight(i); d->invalidateHeightCache(i); @@ -853,7 +838,7 @@ void QTreeView::setSortingEnabled(bool enable) // because otherwise it will not call sort on the model. sortByColumn(header()->sortIndicatorSection(), header()->sortIndicatorOrder()); connect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), - this, SLOT(_q_sortIndicatorChanged(int, Qt::SortOrder))); + this, SLOT(_q_sortIndicatorChanged(int, Qt::SortOrder)), Qt::UniqueConnection); } else { disconnect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(_q_sortIndicatorChanged(int, Qt::SortOrder))); @@ -908,15 +893,6 @@ void QTreeView::setAllColumnsShowFocus(bool enable) Q_D(QTreeView); if (d->allColumnsShowFocus == enable) return; - if (d->selectionModel) { - if (enable) { - QObject::connect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)), - this, SLOT(_q_currentChanged(QModelIndex,QModelIndex))); - } else { - QObject::disconnect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)), - this, SLOT(_q_currentChanged(QModelIndex,QModelIndex))); - } - } d->allColumnsShowFocus = enable; d->viewport->update(); } @@ -1119,18 +1095,22 @@ void QTreeView::scrollTo(const QModelIndex &index, ScrollHint hint) } else if (hint == PositionAtTop || (hint == EnsureVisible && item < top)) { verticalScrollBar()->setValue(item); } else { // PositionAtBottom or PositionAtCenter - int itemLocation = item; + const int currentItemHeight = d->itemHeight(item); int y = (hint == PositionAtCenter - ? area.height() / 2 + //we center on the current item with a preference to the top item (ie. -1) + ? area.height() / 2 + currentItemHeight - 1 + //otherwise we simply take the whole space : area.height()); - while (y > 0 && item > 0) - y -= d->itemHeight(item--); - // end up half over the top of the area - if (y < 0 && item < itemLocation) - ++item; - // end up half over the bottom of the area - if (item >= 0 && item < itemLocation) - ++item; + if (y > currentItemHeight) { + while (item >= 0) { + y -= d->itemHeight(item); + if (y < 0) { //there is no more space left + item++; + break; + } + item--; + } + } verticalScrollBar()->setValue(item); } } else { // ScrollPerPixel @@ -1142,7 +1122,7 @@ void QTreeView::scrollTo(const QModelIndex &index, ScrollHint hint) if (rect.isEmpty()) { // nothing to do } else if (hint == EnsureVisible && area.contains(rect)) { - d->setDirtyRegion(rect); + d->viewport->update(rect); // nothing to do } else { bool above = (hint == EnsureVisible @@ -1274,10 +1254,13 @@ void QTreeView::paintEvent(QPaintEvent *event) Q_D(QTreeView); d->executePostedLayout(); QPainter painter(viewport()); +#ifndef QT_NO_ANIMATION if (d->isAnimating()) { - drawTree(&painter, event->region() - d->animationRect()); + drawTree(&painter, event->region() - d->animatedOperation.rect()); d->drawAnimatedOperation(&painter); - } else { + } else +#endif //QT_NO_ANIMATION + { drawTree(&painter, event->region()); #ifndef QT_NO_DRAGANDDROP d->paintDropIndicator(&painter); @@ -1313,20 +1296,20 @@ bool QTreeViewPrivate::expandOrCollapseItemAtPos(const QPoint &pos) { Q_Q(QTreeView); // we want to handle mousePress in EditingState (persistent editors) - if ((q->state() != QAbstractItemView::NoState - && q->state() != QAbstractItemView::EditingState) + if ((state != QAbstractItemView::NoState + && state != QAbstractItemView::EditingState) || !viewport->rect().contains(pos)) return true; int i = itemDecorationAt(pos); - if ((i != -1) && q->itemsExpandable() && hasVisibleChildren(viewItems.at(i).index)) { + if ((i != -1) && itemsExpandable && hasVisibleChildren(viewItems.at(i).index)) { if (viewItems.at(i).expanded) collapse(i, true); else expand(i, true); if (!isAnimating()) { q->updateGeometries(); - q->viewport()->update(); + viewport->update(); } return true; } @@ -1342,6 +1325,50 @@ void QTreeViewPrivate::_q_modelDestroyed() } /*! + \reimp + + We have a QTreeView way of knowing what elements are on the viewport +*/ +QItemViewPaintPairs QTreeViewPrivate::draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const +{ + Q_ASSERT(r); + return QAbstractItemViewPrivate::draggablePaintPairs(indexes, r); + Q_Q(const QTreeView); + QRect &rect = *r; + const QRect viewportRect = viewport->rect(); + int itemOffset = 0; + int row = firstVisibleItem(&itemOffset); + QPair<int, int> startEnd = startAndEndColumns(viewportRect); + QVector<int> columns; + for (int i = startEnd.first; i <= startEnd.second; ++i) { + int logical = header->logicalIndex(i); + if (!header->isSectionHidden(logical)) + columns += logical; + } + QSet<QModelIndex> visibleIndexes; + for (; itemOffset < viewportRect.bottom() && row < viewItems.count(); ++row) { + const QModelIndex &index = viewItems.at(row).index; + for (int colIndex = 0; colIndex < columns.count(); ++colIndex) + visibleIndexes += index.sibling(index.row(), columns.at(colIndex)); + itemOffset += itemHeight(row); + } + + //now that we have the visible indexes, we can try to find those which are selected + QItemViewPaintPairs ret; + for (int i = 0; i < indexes.count(); ++i) { + const QModelIndex &index = indexes.at(i); + if (visibleIndexes.contains(index)) { + const QRect current = q->visualRect(index); + ret += qMakePair(current, index); + rect |= current; + } + } + rect &= viewportRect; + return ret; +} + + +/*! \since 4.2 Draws the part of the tree intersecting the given \a region using the specified \a painter. @@ -1548,7 +1575,7 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option, ? logicalIndexBeforeLeft : logicalIndices.at(currentLogicalSection - 1); if (columnCount == 1 || (nextLogicalSection == 0 && prevLogicalSection == -1) - || (headerSection == 0 && nextLogicalSection == -1)) + || (headerSection == 0 && nextLogicalSection == -1) || spanning) opt.viewItemPosition = QStyleOptionViewItemV4::OnlyOne; else if (headerSection == 0 || (nextLogicalSection != 0 && prevLogicalSection == -1)) opt.viewItemPosition = QStyleOptionViewItemV4::Beginning; @@ -1817,10 +1844,10 @@ void QTreeView::mouseDoubleClickEvent(QMouseEvent *event) if (i == -1) return; // user clicked outside the items - const QModelIndex &index = d->viewItems.at(i).index; + const QPersistentModelIndex firstColumnIndex = d->viewItems.at(i).index; int column = d->header->logicalIndexAt(event->x()); - QPersistentModelIndex persistent = index.sibling(index.row(), column); + QPersistentModelIndex persistent = firstColumnIndex.sibling(firstColumnIndex.row(), column); if (d->pressedIndex != persistent) { mousePressEvent(event); @@ -1843,10 +1870,10 @@ void QTreeView::mouseDoubleClickEvent(QMouseEvent *event) if (d->itemsExpandable && d->expandsOnDoubleClick && d->hasVisibleChildren(persistent)) { - if (!((i < d->viewItems.count()) && (d->viewItems.at(i).index == persistent))) { + if (!((i < d->viewItems.count()) && (d->viewItems.at(i).index == firstColumnIndex))) { // find the new index of the item for (i = 0; i < d->viewItems.count(); ++i) { - if (d->viewItems.at(i).index == persistent) + if (d->viewItems.at(i).index == firstColumnIndex) break; } if (i == d->viewItems.count()) @@ -2074,7 +2101,8 @@ QModelIndex QTreeView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie const bool useTopIndex = (cursorAction == MoveUp || cursorAction == MovePrevious); int index = useTopIndex ? INT_MAX : INT_MIN; const QItemSelection selection = d->selectionModel->selection(); - foreach (const QItemSelectionRange &range, selection) { + for (int i = 0; i < selection.count(); ++i) { + const QItemSelectionRange &range = selection.at(i); int candidate = d->viewIndex(useTopIndex ? range.topLeft() : range.bottomRight()); if (candidate >= 0) index = useTopIndex ? qMin(index, candidate) : qMax(index, candidate); @@ -2424,14 +2452,10 @@ void QTreeView::rowsInserted(const QModelIndex &parent, int start, int end) ? d->viewItems.count() : d->viewItems.at(parentItem).total) - 1; - int firstColumn = 0; - while (isColumnHidden(firstColumn) && firstColumn < header()->count() - 1) - ++firstColumn; - const int delta = end - start + 1; QVector<QTreeViewItem> insertedItems(delta); for (int i = 0; i < delta; ++i) { - insertedItems[i].index = d->model->index(i + start, firstColumn, parent); + insertedItems[i].index = d->model->index(i + start, 0, parent); insertedItems[i].level = childLevel; } if (d->viewItems.isEmpty()) @@ -2614,7 +2638,7 @@ void QTreeView::expandAll() d->viewItems[i].expanded = true; d->layout(i); QModelIndex idx = d->viewItems.at(i).index; - d->expandedIndexes.insert(idx.sibling(idx.row(), 0)); + d->expandedIndexes.insert(idx); } updateGeometries(); d->viewport->update(); @@ -2829,7 +2853,7 @@ int QTreeView::rowHeight(const QModelIndex &index) const } /*! - \reimp + \internal */ void QTreeView::horizontalScrollbarAction(int action) { @@ -2861,10 +2885,9 @@ void QTreeViewPrivate::initialize() header->setStretchLastSection(true); header->setDefaultAlignment(Qt::AlignLeft|Qt::AlignVCenter); q->setHeader(header); - - // animation - QObject::connect(&timeline, SIGNAL(frameChanged(int)), q, SLOT(_q_animate())); - QObject::connect(&timeline, SIGNAL(finished()), q, SLOT(_q_endAnimatedOperation()), Qt::QueuedConnection); +#ifndef QT_NO_ANIMATION + QObject::connect(&animatedOperation, SIGNAL(finished()), q, SLOT(_q_endAnimatedOperation())); +#endif //QT_NO_ANIMATION } void QTreeViewPrivate::expand(int item, bool emitSignal) @@ -2874,10 +2897,11 @@ void QTreeViewPrivate::expand(int item, bool emitSignal) if (item == -1 || viewItems.at(item).expanded) return; +#ifndef QT_NO_ANIMATION if (emitSignal && animationsEnabled) - prepareAnimatedOperation(item, AnimatedOperation::Expand); - - QAbstractItemView::State oldState = q->state(); + prepareAnimatedOperation(item, QVariantAnimation::Forward); +#endif //QT_NO_ANIMATION + QAbstractItemView::State oldState = state; q->setState(QAbstractItemView::ExpandingState); const QModelIndex index = viewItems.at(item).index; storeExpanded(index); @@ -2887,8 +2911,10 @@ void QTreeViewPrivate::expand(int item, bool emitSignal) if (emitSignal) { emit q->expanded(index); +#ifndef QT_NO_ANIMATION if (animationsEnabled) beginAnimatedOperation(); +#endif //QT_NO_ANIMATION } if (model->canFetchMore(index)) model->fetchMore(index); @@ -2912,10 +2938,12 @@ void QTreeViewPrivate::collapse(int item, bool emitSignal) if (it == expandedIndexes.end() || viewItems.at(item).expanded == false) return; // nothing to do +#ifndef QT_NO_ANIMATION if (emitSignal && animationsEnabled) - prepareAnimatedOperation(item, AnimatedOperation::Collapse); + prepareAnimatedOperation(item, QVariantAnimation::Backward); +#endif //QT_NO_ANIMATION - QAbstractItemView::State oldState = q->state(); + QAbstractItemView::State oldState = state; q->setState(QAbstractItemView::CollapsingState); expandedIndexes.erase(it); viewItems[item].expanded = false; @@ -2932,29 +2960,33 @@ void QTreeViewPrivate::collapse(int item, bool emitSignal) if (emitSignal) { emit q->collapsed(modelIndex); +#ifndef QT_NO_ANIMATION if (animationsEnabled) beginAnimatedOperation(); +#endif //QT_NO_ANIMATION } } -void QTreeViewPrivate::prepareAnimatedOperation(int item, AnimatedOperation::Type type) +#ifndef QT_NO_ANIMATION +void QTreeViewPrivate::prepareAnimatedOperation(int item, QVariantAnimation::Direction direction) { animatedOperation.item = item; - animatedOperation.type = type; + animatedOperation.viewport = viewport; + animatedOperation.setDirection(direction); int top = coordinateForItem(item) + itemHeight(item); QRect rect = viewport->rect(); rect.setTop(top); - if (type == AnimatedOperation::Collapse) { + if (direction == QVariantAnimation::Backward) { const int limit = rect.height() * 2; int h = 0; int c = item + viewItems.at(item).total + 1; for (int i = item + 1; i < c && h < limit; ++i) h += itemHeight(i); rect.setHeight(h); - animatedOperation.duration = h; + animatedOperation.setEndValue(top + h); } - animatedOperation.top = top; + animatedOperation.setStartValue(top); animatedOperation.before = renderTreeToPixmapForAnimation(rect); } @@ -2963,50 +2995,29 @@ void QTreeViewPrivate::beginAnimatedOperation() Q_Q(QTreeView); QRect rect = viewport->rect(); - rect.setTop(animatedOperation.top); - if (animatedOperation.type == AnimatedOperation::Expand) { + rect.setTop(animatedOperation.top()); + if (animatedOperation.direction() == QVariantAnimation::Forward) { const int limit = rect.height() * 2; int h = 0; int c = animatedOperation.item + viewItems.at(animatedOperation.item).total + 1; for (int i = animatedOperation.item + 1; i < c && h < limit; ++i) h += itemHeight(i); rect.setHeight(h); - animatedOperation.duration = h; + animatedOperation.setEndValue(animatedOperation.top() + h); } animatedOperation.after = renderTreeToPixmapForAnimation(rect); q->setState(QAbstractItemView::AnimatingState); - - timeline.stop(); - timeline.setDuration(250); - timeline.setFrameRange(animatedOperation.top, animatedOperation.top + animatedOperation.duration); - timeline.start(); -} - -void QTreeViewPrivate::_q_endAnimatedOperation() -{ - Q_Q(QTreeView); - animatedOperation.before = QPixmap(); - animatedOperation.after = QPixmap(); - q->setState(QAbstractItemView::NoState); - q->updateGeometries(); - viewport->update(); -} - -void QTreeViewPrivate::_q_animate() -{ - QRect rect = viewport->rect(); - rect.moveTop(animatedOperation.top); - viewport->repaint(rect); + animatedOperation.start(); //let's start the animation } void QTreeViewPrivate::drawAnimatedOperation(QPainter *painter) const { - int start = timeline.startFrame(); - int end = timeline.endFrame(); - bool collapsing = animatedOperation.type == AnimatedOperation::Collapse; - int current = collapsing ? end - timeline.currentFrame() + start : timeline.currentFrame(); + const int start = animatedOperation.startValue().toInt(), + end = animatedOperation.endValue().toInt(), + current = animatedOperation.currentValue().toInt(); + bool collapsing = animatedOperation.direction() == QVariantAnimation::Backward; const QPixmap top = collapsing ? animatedOperation.before : animatedOperation.after; painter->drawPixmap(0, start, top, 0, end - current - 1, top.width(), top.height()); const QPixmap bottom = collapsing ? animatedOperation.after : animatedOperation.before; @@ -3049,26 +3060,14 @@ QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) cons return pixmap; } -void QTreeViewPrivate::_q_currentChanged(const QModelIndex ¤t, const QModelIndex &previous) +void QTreeViewPrivate::_q_endAnimatedOperation() { Q_Q(QTreeView); - if (previous.isValid()) { - QRect previousRect = q->visualRect(previous); - if (allColumnsShowFocus) { - previousRect.setX(0); - previousRect.setWidth(viewport->width()); - } - viewport->update(previousRect); - } - if (current.isValid()) { - QRect currentRect = q->visualRect(current); - if (allColumnsShowFocus) { - currentRect.setX(0); - currentRect.setWidth(viewport->width()); - } - viewport->update(currentRect); - } + q->setState(QAbstractItemView::NoState); + q->updateGeometries(); + viewport->update(); } +#endif //QT_NO_ANIMATION void QTreeViewPrivate::_q_modelAboutToBeReset() { @@ -3077,16 +3076,16 @@ void QTreeViewPrivate::_q_modelAboutToBeReset() void QTreeViewPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end) { - Q_UNUSED(parent); if (start <= 0 && 0 <= end) viewItems.clear(); + QAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(parent, start, end); } void QTreeViewPrivate::_q_columnsRemoved(const QModelIndex &parent, int start, int end) { - Q_UNUSED(parent); if (start <= 0 && 0 <= end) doDelayedItemsLayout(); + QAbstractItemViewPrivate::_q_columnsRemoved(parent, start, end); } void QTreeViewPrivate::layout(int i) @@ -3094,10 +3093,6 @@ void QTreeViewPrivate::layout(int i) Q_Q(QTreeView); QModelIndex current; QModelIndex parent = (i < 0) ? (QModelIndex)root : modelIndex(i); - // modelIndex() will return an index that don't have a parent if column 0 is hidden, - // so we must make sure that parent points to the actual parent that has children. - if (parent != root) - parent = model->index(parent.row(), 0, parent.parent()); if (i>=0 && !parent.isValid()) { //modelIndex() should never return something invalid for the real items. @@ -3132,13 +3127,9 @@ void QTreeViewPrivate::layout(int i) int last = 0; int children = 0; - int firstColumn = 0; - while (header->isSectionHidden(firstColumn) && firstColumn < header->count()) - ++firstColumn; - for (int j = first; j < first + count; ++j) { - current = model->index(j - first, firstColumn, parent); - if (isRowHidden(current.sibling(current.row(), 0))) { + current = model->index(j - first, 0, parent); + if (isRowHidden(current)) { ++hidden; last = j - hidden + children; } else { @@ -3219,19 +3210,18 @@ int QTreeViewPrivate::itemHeight(int item) const */ int QTreeViewPrivate::coordinateForItem(int item) const { - Q_Q(const QTreeView); if (verticalScrollMode == QAbstractItemView::ScrollPerPixel) { if (uniformRowHeights) - return (item * defaultItemHeight) - q->verticalScrollBar()->value(); + return (item * defaultItemHeight) - vbar->value(); // ### optimize (spans or caching) int y = 0; for (int i = 0; i < viewItems.count(); ++i) { if (i == item) - return y - q->verticalScrollBar()->value(); + return y - vbar->value(); y += itemHeight(i); } } else { // ScrollPerItem - int topViewItemIndex = q->verticalScrollBar()->value(); + int topViewItemIndex = vbar->value(); if (uniformRowHeights) return defaultItemHeight * (item - topViewItemIndex); if (item >= topViewItemIndex) { @@ -3271,7 +3261,6 @@ int QTreeViewPrivate::coordinateForItem(int item) const */ int QTreeViewPrivate::itemAtCoordinate(int coordinate) const { - Q_Q(const QTreeView); const int itemCount = viewItems.count(); if (itemCount == 0) return -1; @@ -3279,19 +3268,19 @@ int QTreeViewPrivate::itemAtCoordinate(int coordinate) const return -1; if (verticalScrollMode == QAbstractItemView::ScrollPerPixel) { if (uniformRowHeights) { - const int viewItemIndex = (coordinate + q->verticalScrollBar()->value()) / defaultItemHeight; + const int viewItemIndex = (coordinate + vbar->value()) / defaultItemHeight; return ((viewItemIndex >= itemCount || viewItemIndex < 0) ? -1 : viewItemIndex); } // ### optimize int viewItemCoordinate = 0; - const int contentsCoordinate = coordinate + q->verticalScrollBar()->value(); + const int contentsCoordinate = coordinate + vbar->value(); for (int viewItemIndex = 0; viewItemIndex < viewItems.count(); ++viewItemIndex) { viewItemCoordinate += itemHeight(viewItemIndex); if (viewItemCoordinate >= contentsCoordinate) return (viewItemIndex >= itemCount ? -1 : viewItemIndex); } } else { // ScrollPerItem - int topViewItemIndex = q->verticalScrollBar()->value(); + int topViewItemIndex = vbar->value(); if (uniformRowHeights) { if (coordinate < 0) coordinate -= defaultItemHeight - 1; @@ -3321,15 +3310,11 @@ int QTreeViewPrivate::itemAtCoordinate(int coordinate) const int QTreeViewPrivate::viewIndex(const QModelIndex &_index) const { - Q_Q(const QTreeView); if (!_index.isValid() || viewItems.isEmpty()) return -1; const int totalCount = viewItems.count(); - int firstColumn = 0; - while (q->isColumnHidden(firstColumn) && firstColumn < header->count()) - ++firstColumn; - const QModelIndex index = _index.sibling(_index.row(), firstColumn); + const QModelIndex index = _index.sibling(_index.row(), 0); // A quick check near the last item to see if we are just incrementing @@ -3387,8 +3372,7 @@ QModelIndex QTreeViewPrivate::modelIndex(int i, int column) const int QTreeViewPrivate::firstVisibleItem(int *offset) const { - Q_Q(const QTreeView); - const int value = q->verticalScrollBar()->value(); + const int value = vbar->value(); if (verticalScrollMode == QAbstractItemView::ScrollPerItem) { if (offset) *offset = 0; @@ -3465,9 +3449,9 @@ void QTreeViewPrivate::updateScrollBars() if (verticalScrollMode == QAbstractItemView::ScrollPerItem) { if (!viewItems.isEmpty()) itemsInViewport = qMax(1, itemsInViewport); - q->verticalScrollBar()->setRange(0, viewItems.count() - itemsInViewport); - q->verticalScrollBar()->setPageStep(itemsInViewport); - q->verticalScrollBar()->setSingleStep(1); + vbar->setRange(0, viewItems.count() - itemsInViewport); + vbar->setPageStep(itemsInViewport); + vbar->setSingleStep(1); } else { // scroll per pixel int contentsHeight = 0; if (uniformRowHeights) { @@ -3476,9 +3460,9 @@ void QTreeViewPrivate::updateScrollBars() for (int i = 0; i < viewItems.count(); ++i) contentsHeight += itemHeight(i); } - q->verticalScrollBar()->setRange(0, contentsHeight - viewportSize.height()); - q->verticalScrollBar()->setPageStep(viewportSize.height()); - q->verticalScrollBar()->setSingleStep(qMax(viewportSize.height() / (itemsInViewport + 1), 2)); + vbar->setRange(0, contentsHeight - viewportSize.height()); + vbar->setPageStep(viewportSize.height()); + vbar->setSingleStep(qMax(viewportSize.height() / (itemsInViewport + 1), 2)); } const int columnCount = header->count(); @@ -3494,23 +3478,23 @@ void QTreeViewPrivate::updateScrollBars() if (columnCount > 0) columnsInViewport = qMax(1, columnsInViewport); if (horizontalScrollMode == QAbstractItemView::ScrollPerItem) { - q->horizontalScrollBar()->setRange(0, columnCount - columnsInViewport); - q->horizontalScrollBar()->setPageStep(columnsInViewport); - q->horizontalScrollBar()->setSingleStep(1); + hbar->setRange(0, columnCount - columnsInViewport); + hbar->setPageStep(columnsInViewport); + hbar->setSingleStep(1); } else { // scroll per pixel const int horizontalLength = header->length(); const QSize maxSize = q->maximumViewportSize(); - if (maxSize.width() >= horizontalLength && q->verticalScrollBar()->maximum() <= 0) + if (maxSize.width() >= horizontalLength && vbar->maximum() <= 0) viewportSize = maxSize; - q->horizontalScrollBar()->setPageStep(viewportSize.width()); - q->horizontalScrollBar()->setRange(0, qMax(horizontalLength - viewportSize.width(), 0)); - q->horizontalScrollBar()->setSingleStep(qMax(viewportSize.width() / (columnsInViewport + 1), 2)); + hbar->setPageStep(viewportSize.width()); + hbar->setRange(0, qMax(horizontalLength - viewportSize.width(), 0)); + hbar->setSingleStep(qMax(viewportSize.width() / (columnsInViewport + 1), 2)); } } int QTreeViewPrivate::itemDecorationAt(const QPoint &pos) const { - const_cast<QTreeView *>(q_func())->executeDelayedItemsLayout(); + executePostedLayout(); int x = pos.x(); int column = header->logicalIndexAt(x); if (column != 0) @@ -3576,7 +3560,8 @@ QList<QPair<int, int> > QTreeViewPrivate::columnRanges(const QModelIndex &topInd QPair<int, int> current; current.first = -2; // -1 is not enough because -1+1 = 0 current.second = -2; - foreach (int logicalColumn, logicalIndexes) { + for(int i = 0; i < logicalIndexes.count(); ++i) { + const int logicalColumn = logicalIndexes.at(i); if (current.second + 1 != logicalColumn) { if (current.first != -2) { //let's save the current one @@ -3811,6 +3796,21 @@ void QTreeView::currentChanged(const QModelIndex ¤t, const QModelIndex &pr } #endif QAbstractItemView::currentChanged(current, previous); + + if (allColumnsShowFocus()) { + if (previous.isValid()) { + QRect previousRect = visualRect(previous); + previousRect.setX(0); + previousRect.setWidth(viewport()->width()); + viewport()->update(previousRect); + } + if (current.isValid()) { + QRect currentRect = visualRect(current); + currentRect.setX(0); + currentRect.setWidth(viewport()->width()); + viewport()->update(currentRect); + } + } } /*! diff --git a/src/gui/itemviews/qtreeview.h b/src/gui/itemviews/qtreeview.h index 35a205c..4411781 100644 --- a/src/gui/itemviews/qtreeview.h +++ b/src/gui/itemviews/qtreeview.h @@ -144,19 +144,20 @@ public: void sortByColumn(int column, Qt::SortOrder order); + void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); + void selectAll(); + Q_SIGNALS: void expanded(const QModelIndex &index); void collapsed(const QModelIndex &index); public Q_SLOTS: - void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); void hideColumn(int column); void showColumn(int column); void expand(const QModelIndex &index); void collapse(const QModelIndex &index); void resizeColumnToContents(int column); void sortByColumn(int column); - void selectAll(); void expandAll(); void collapseAll(); void expandToDepth(int depth); @@ -222,14 +223,11 @@ private: Q_DECLARE_PRIVATE(QTreeView) Q_DISABLE_COPY(QTreeView) +#ifndef QT_NO_ANIMATION Q_PRIVATE_SLOT(d_func(), void _q_endAnimatedOperation()) - Q_PRIVATE_SLOT(d_func(), void _q_animate()) - Q_PRIVATE_SLOT(d_func(), void _q_currentChanged(const QModelIndex&, const QModelIndex &)) - Q_PRIVATE_SLOT(d_func(), void _q_columnsAboutToBeRemoved(const QModelIndex &, int, int)) - Q_PRIVATE_SLOT(d_func(), void _q_columnsRemoved(const QModelIndex &, int, int)) +#endif //QT_NO_ANIMATION Q_PRIVATE_SLOT(d_func(), void _q_modelAboutToBeReset()) Q_PRIVATE_SLOT(d_func(), void _q_sortIndicatorChanged(int column, Qt::SortOrder order)) - Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed()) }; #endif // QT_NO_TREEVIEW diff --git a/src/gui/itemviews/qtreeview_p.h b/src/gui/itemviews/qtreeview_p.h index 6a1dfe5..546dc75 100644 --- a/src/gui/itemviews/qtreeview_p.h +++ b/src/gui/itemviews/qtreeview_p.h @@ -54,6 +54,7 @@ // #include "private/qabstractitemview_p.h" +#include <QtCore/qvariantanimation.h> #ifndef QT_NO_TREEVIEW @@ -81,42 +82,41 @@ public: uniformRowHeights(false), rootDecoration(true), itemsExpandable(true), sortingEnabled(false), expandsOnDoubleClick(true), - allColumnsShowFocus(false), + allColumnsShowFocus(false), current(0), animationsEnabled(false), columnResizeTimerID(0), autoExpandDelay(-1), hoverBranch(-1), geometryRecursionBlock(false) {} ~QTreeViewPrivate() {} void initialize(); - struct AnimatedOperation + QItemViewPaintPairs draggablePaintPairs(const QModelIndexList &indexes, QRect *r) const; + +#ifndef QT_NO_ANIMATION + struct AnimatedOperation : public QVariantAnimation { - enum Type { Expand, Collapse }; int item; - int top; - int duration; - Type type; QPixmap before; QPixmap after; - }; - - void expand(int item, bool emitSignal); - void collapse(int item, bool emitSignal); - - void prepareAnimatedOperation(int item, AnimatedOperation::Type type); + QWidget *viewport; + AnimatedOperation() : item(0) { setEasingCurve(QEasingCurve::InOutQuad); } + int top() const { return startValue().toInt(); } + QRect rect() const { QRect rect = viewport->rect(); rect.moveTop(top()); return rect; } + void updateCurrentValue(const QVariant &) { viewport->update(rect()); } + void updateState(State, State state) { if (state == Stopped) before = after = QPixmap(); } + } animatedOperation; + void prepareAnimatedOperation(int item, QVariantAnimation::Direction d); void beginAnimatedOperation(); - void _q_endAnimatedOperation(); void drawAnimatedOperation(QPainter *painter) const; QPixmap renderTreeToPixmapForAnimation(const QRect &rect) const; + void _q_endAnimatedOperation(); +#endif //QT_NO_ANIMATION - inline QRect animationRect() const - { return QRect(0, animatedOperation.top, viewport->width(), - viewport->height() - animatedOperation.top); } + void expand(int item, bool emitSignal); + void collapse(int item, bool emitSignal); - void _q_currentChanged(const QModelIndex&, const QModelIndex&); void _q_columnsAboutToBeRemoved(const QModelIndex &, int, int); void _q_columnsRemoved(const QModelIndex &, int, int); void _q_modelAboutToBeReset(); - void _q_animate(); void _q_sortIndicatorChanged(int column, Qt::SortOrder order); void _q_modelDestroyed(); @@ -177,8 +177,6 @@ public: // used when expanding and collapsing items QSet<QPersistentModelIndex> expandedIndexes; - QStack<bool> expandParent; - AnimatedOperation animatedOperation; bool animationsEnabled; inline bool storeExpanded(const QPersistentModelIndex &idx) { diff --git a/src/gui/itemviews/qtreewidget.cpp b/src/gui/itemviews/qtreewidget.cpp index 19cd22c..e724a7d 100644 --- a/src/gui/itemviews/qtreewidget.cpp +++ b/src/gui/itemviews/qtreewidget.cpp @@ -577,7 +577,7 @@ void QTreeModel::sort(int column, Qt::SortOrder order) if (column < 0 || column >= columnCount()) return; - //layoutAboutToBeChanged and layoutChanged will be called by sortChildren + //layoutAboutToBeChanged and layoutChanged will be called by sortChildren rootItem->sortChildren(column, order, true); } @@ -1787,7 +1787,11 @@ QVariant QTreeWidgetItem::data(int column, int role) const bool QTreeWidgetItem::operator<(const QTreeWidgetItem &other) const { int column = view ? view->sortColumn() : 0; - return text(column) < other.text(column); + const QVariant v1 = data(column, Qt::DisplayRole); + const QVariant v2 = other.data(column, Qt::DisplayRole); + if (QAbstractItemModelPrivate::canConvertToDouble(v1) && QAbstractItemModelPrivate::canConvertToDouble(v2)) + return v1.toDouble() < v2.toDouble(); + return v1.toString() < v2.toString(); } #ifndef QT_NO_DATASTREAM @@ -1827,6 +1831,7 @@ void QTreeWidgetItem::write(QDataStream &out) const { out << values << d->display; } +#endif // QT_NO_DATASTREAM /*! \since 4.1 @@ -1863,8 +1868,6 @@ QTreeWidgetItem &QTreeWidgetItem::operator=(const QTreeWidgetItem &other) return *this; } -#endif // QT_NO_DATASTREAM - /*! Appends the \a child item to the list of children. @@ -2075,7 +2078,7 @@ void QTreeWidgetItemPrivate::sortChildren(int column, Qt::SortOrder order, bool if (climb) { QList<QTreeWidgetItem*>::iterator it = q->children.begin(); for (; it != q->children.end(); ++it) { - //here we call the private object's method to avoid emitting + //here we call the private object's method to avoid emitting //the layoutAboutToBeChanged and layoutChanged signals (*it)->d->sortChildren(column, order, climb); } @@ -2277,11 +2280,10 @@ void QTreeWidgetPrivate::_q_emitCurrentItemChanged(const QModelIndex ¤t, void QTreeWidgetPrivate::_q_sort() { - Q_Q(QTreeWidget); if (sortingEnabled) { - int column = q->header()->sortIndicatorSection(); - Qt::SortOrder order = q->header()->sortIndicatorOrder(); - model()->sort(column, order); + int column = header->sortIndicatorSection(); + Qt::SortOrder order = header->sortIndicatorOrder(); + treeModel()->sort(column, order); } } @@ -2290,7 +2292,7 @@ void QTreeWidgetPrivate::_q_selectionChanged(const QItemSelection &selected, con Q_Q(QTreeWidget); QModelIndexList indices = selected.indexes(); int i; - QTreeModel *m = model(); + QTreeModel *m = treeModel(); for (i = 0; i < indices.count(); ++i) { QTreeWidgetItem *item = m->item(indices.at(i)); item->d->selected = true; @@ -2308,13 +2310,12 @@ void QTreeWidgetPrivate::_q_selectionChanged(const QItemSelection &selected, con void QTreeWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) { - Q_Q(QTreeWidget); if (sortingEnabled && topLeft.isValid() && bottomRight.isValid() - && !model()->sortPendingTimer.isActive()) { - int column = q->header()->sortIndicatorSection(); + && !treeModel()->sortPendingTimer.isActive()) { + int column = header->sortIndicatorSection(); if (column >= topLeft.column() && column <= bottomRight.column()) { - Qt::SortOrder order = q->header()->sortIndicatorOrder(); - model()->ensureSorted(column, order, topLeft.row(), + Qt::SortOrder order = header->sortIndicatorOrder(); + treeModel()->ensureSorted(column, order, topLeft.row(), bottomRight.row(), topLeft.parent()); } } @@ -2436,7 +2437,7 @@ void QTreeWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, \note This signal will not be emitted if an item changes its state when expandAll() is invoked. - \sa isItemExpanded(), itemCollapsed(), expandItem() + \sa QTreeWidgetItem::isExpanded(), itemCollapsed(), expandItem() */ /*! @@ -2448,7 +2449,7 @@ void QTreeWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft, \note This signal will not be emitted if an item changes its state when collapseAll() is invoked. - \sa isItemExpanded(), itemExpanded(), collapseItem() + \sa QTreeWidgetItem::isExpanded(), itemExpanded(), collapseItem() */ /*! @@ -2542,7 +2543,7 @@ QTreeWidget::~QTreeWidget() int QTreeWidget::columnCount() const { Q_D(const QTreeWidget); - return d->model()->columnCount(); + return d->model->columnCount(); } /* @@ -2554,7 +2555,7 @@ void QTreeWidget::setColumnCount(int columns) Q_D(QTreeWidget); if (columns < 0) return; - d->model()->setColumnCount(columns); + d->treeModel()->setColumnCount(columns); } /*! @@ -2571,7 +2572,7 @@ void QTreeWidget::setColumnCount(int columns) QTreeWidgetItem *QTreeWidget::invisibleRootItem() const { Q_D(const QTreeWidget); - return d->model()->rootItem; + return d->treeModel()->rootItem; } /*! @@ -2584,7 +2585,7 @@ QTreeWidgetItem *QTreeWidget::invisibleRootItem() const QTreeWidgetItem *QTreeWidget::topLevelItem(int index) const { Q_D(const QTreeWidget); - return d->model()->rootItem->child(index); + return d->treeModel()->rootItem->child(index); } /*! @@ -2599,7 +2600,7 @@ QTreeWidgetItem *QTreeWidget::topLevelItem(int index) const int QTreeWidget::topLevelItemCount() const { Q_D(const QTreeWidget); - return d->model()->rootItem->childCount(); + return d->treeModel()->rootItem->childCount(); } /*! @@ -2613,7 +2614,7 @@ int QTreeWidget::topLevelItemCount() const void QTreeWidget::insertTopLevelItem(int index, QTreeWidgetItem *item) { Q_D(QTreeWidget); - d->model()->rootItem->insertChild(index, item); + d->treeModel()->rootItem->insertChild(index, item); } /*! @@ -2638,7 +2639,7 @@ void QTreeWidget::addTopLevelItem(QTreeWidgetItem *item) QTreeWidgetItem *QTreeWidget::takeTopLevelItem(int index) { Q_D(QTreeWidget); - return d->model()->rootItem->takeChild(index); + return d->treeModel()->rootItem->takeChild(index); } /*! @@ -2647,8 +2648,8 @@ QTreeWidgetItem *QTreeWidget::takeTopLevelItem(int index) int QTreeWidget::indexOfTopLevelItem(QTreeWidgetItem *item) { Q_D(QTreeWidget); - d->model()->executePendingSort(); - return d->model()->rootItem->children.indexOf(item); + d->treeModel()->executePendingSort(); + return d->treeModel()->rootItem->children.indexOf(item); } /*! @@ -2660,8 +2661,8 @@ int QTreeWidget::indexOfTopLevelItem(QTreeWidgetItem *item) int QTreeWidget::indexOfTopLevelItem(QTreeWidgetItem *item) const { Q_D(const QTreeWidget); - d->model()->executePendingSort(); - return d->model()->rootItem->children.indexOf(item); + d->treeModel()->executePendingSort(); + return d->treeModel()->rootItem->children.indexOf(item); } /*! @@ -2676,7 +2677,7 @@ int QTreeWidget::indexOfTopLevelItem(QTreeWidgetItem *item) const void QTreeWidget::insertTopLevelItems(int index, const QList<QTreeWidgetItem*> &items) { Q_D(QTreeWidget); - d->model()->rootItem->insertChildren(index, items); + d->treeModel()->rootItem->insertChildren(index, items); } /*! @@ -2698,7 +2699,7 @@ void QTreeWidget::addTopLevelItems(const QList<QTreeWidgetItem*> &items) QTreeWidgetItem *QTreeWidget::headerItem() const { Q_D(const QTreeWidget); - return d->model()->headerItem; + return d->treeModel()->headerItem; } /*! @@ -2719,16 +2720,16 @@ void QTreeWidget::setHeaderItem(QTreeWidgetItem *item) int oldCount = columnCount(); if (oldCount < item->columnCount()) - d->model()->beginInsertColumns(QModelIndex(), oldCount, item->columnCount()); + d->treeModel()->beginInsertColumns(QModelIndex(), oldCount, item->columnCount()); else - d->model()->beginRemoveColumns(QModelIndex(), item->columnCount(), oldCount); - delete d->model()->headerItem; - d->model()->headerItem = item; + d->treeModel()->beginRemoveColumns(QModelIndex(), item->columnCount(), oldCount); + delete d->treeModel()->headerItem; + d->treeModel()->headerItem = item; if (oldCount < item->columnCount()) - d->model()->endInsertColumns(); + d->treeModel()->endInsertColumns(); else - d->model()->endRemoveColumns(); - d->model()->headerDataChanged(Qt::Horizontal, 0, oldCount); + d->treeModel()->endRemoveColumns(); + d->treeModel()->headerDataChanged(Qt::Horizontal, 0, oldCount); } @@ -2745,8 +2746,7 @@ void QTreeWidget::setHeaderLabels(const QStringList &labels) Q_D(QTreeWidget); if (columnCount() < labels.count()) setColumnCount(labels.count()); - QTreeModel *model = d->model(); - QTreeWidgetItem *item = model->headerItem; + QTreeWidgetItem *item = d->treeModel()->headerItem; for (int i = 0; i < labels.count(); ++i) item->setText(i, labels.at(i)); } @@ -2874,7 +2874,7 @@ void QTreeWidget::sortItems(int column, Qt::SortOrder order) { Q_D(QTreeWidget); header()->setSortIndicator(column, order); - d->model()->sort(column, order); + d->model->sort(column, order); } /*! @@ -3041,7 +3041,7 @@ QList<QTreeWidgetItem*> QTreeWidget::selectedItems() const QList<QTreeWidgetItem*> QTreeWidget::findItems(const QString &text, Qt::MatchFlags flags, int column) const { Q_D(const QTreeWidget); - QModelIndexList indexes = d->model()->match(model()->index(0, column, QModelIndex()), + QModelIndexList indexes = d->model->match(model()->index(0, column, QModelIndex()), Qt::DisplayRole, text, -1, flags); QList<QTreeWidgetItem*> items; for (int i = 0; i < indexes.size(); ++i) @@ -3059,11 +3059,11 @@ QList<QTreeWidgetItem*> QTreeWidget::findItems(const QString &text, Qt::MatchFla bool QTreeWidget::isItemHidden(const QTreeWidgetItem *item) const { Q_D(const QTreeWidget); - if (item == d->model()->headerItem) + if (item == d->treeModel()->headerItem) return header()->isHidden(); if (d->hiddenIndexes.isEmpty()) return false; - QTreeModel::SkipSorting skipSorting(d->model()); + QTreeModel::SkipSorting skipSorting(d->treeModel()); return d->isRowHidden(d->index(item)); } @@ -3079,7 +3079,7 @@ bool QTreeWidget::isItemHidden(const QTreeWidgetItem *item) const void QTreeWidget::setItemHidden(const QTreeWidgetItem *item, bool hide) { Q_D(QTreeWidget); - if (item == d->model()->headerItem) { + if (item == d->treeModel()->headerItem) { header()->setHidden(hide); } else { const QModelIndex index = d->index(item); @@ -3099,7 +3099,7 @@ void QTreeWidget::setItemHidden(const QTreeWidgetItem *item, bool hide) bool QTreeWidget::isItemExpanded(const QTreeWidgetItem *item) const { Q_D(const QTreeWidget); - QTreeModel::SkipSorting skipSorting(d->model()); + QTreeModel::SkipSorting skipSorting(d->treeModel()); return isExpanded(d->index(item)); } @@ -3109,14 +3109,14 @@ bool QTreeWidget::isItemExpanded(const QTreeWidgetItem *item) const \sa expandItem(), collapseItem(), itemExpanded() - \obsolete + \obsolete - This function is deprecated. Use \l{QTreeWidgetItem::setExpanded()} instead. + This function is deprecated. Use \l{QTreeWidgetItem::setExpanded()} instead. */ void QTreeWidget::setItemExpanded(const QTreeWidgetItem *item, bool expand) { Q_D(QTreeWidget); - QTreeModel::SkipSorting skipSorting(d->model()); + QTreeModel::SkipSorting skipSorting(d->treeModel()); setExpanded(d->index(item), expand); } @@ -3131,7 +3131,7 @@ void QTreeWidget::setItemExpanded(const QTreeWidgetItem *item, bool expand) bool QTreeWidget::isFirstItemColumnSpanned(const QTreeWidgetItem *item) const { Q_D(const QTreeWidget); - if (item == d->model()->headerItem) + if (item == d->treeModel()->headerItem) return false; // We can't set the header items to spanning const QModelIndex index = d->index(item); return isFirstColumnSpanned(index.row(), index.parent()); @@ -3148,7 +3148,7 @@ bool QTreeWidget::isFirstItemColumnSpanned(const QTreeWidgetItem *item) const void QTreeWidget::setFirstItemColumnSpanned(const QTreeWidgetItem *item, bool span) { Q_D(QTreeWidget); - if (item == d->model()->headerItem) + if (item == d->treeModel()->headerItem) return; // We can't set header items to spanning const QModelIndex index = d->index(item); setFirstColumnSpanned(index.row(), index.parent(), span); @@ -3162,7 +3162,7 @@ void QTreeWidget::setFirstItemColumnSpanned(const QTreeWidgetItem *item, bool sp QTreeWidgetItem *QTreeWidget::itemAbove(const QTreeWidgetItem *item) const { Q_D(const QTreeWidget); - if (item == d->model()->headerItem) + if (item == d->treeModel()->headerItem) return 0; const QModelIndex index = d->index(item); const QModelIndex above = indexAbove(index); @@ -3177,7 +3177,7 @@ QTreeWidgetItem *QTreeWidget::itemAbove(const QTreeWidgetItem *item) const QTreeWidgetItem *QTreeWidget::itemBelow(const QTreeWidgetItem *item) const { Q_D(const QTreeWidget); - if (item == d->model()->headerItem) + if (item == d->treeModel()->headerItem) return 0; const QModelIndex index = d->index(item); const QModelIndex below = indexBelow(index); @@ -3217,7 +3217,7 @@ void QTreeWidget::scrollToItem(const QTreeWidgetItem *item, QAbstractItemView::S void QTreeWidget::expandItem(const QTreeWidgetItem *item) { Q_D(QTreeWidget); - QTreeModel::SkipSorting skipSorting(d->model()); + QTreeModel::SkipSorting skipSorting(d->treeModel()); expand(d->index(item)); } @@ -3230,7 +3230,7 @@ void QTreeWidget::expandItem(const QTreeWidgetItem *item) void QTreeWidget::collapseItem(const QTreeWidgetItem *item) { Q_D(QTreeWidget); - QTreeModel::SkipSorting skipSorting(d->model()); + QTreeModel::SkipSorting skipSorting(d->treeModel()); collapse(d->index(item)); } @@ -3247,7 +3247,7 @@ void QTreeWidget::clear() { Q_D(QTreeWidget); selectionModel()->clear(); - d->model()->clear(); + d->treeModel()->clear(); } /*! @@ -3272,7 +3272,7 @@ QStringList QTreeWidget::mimeTypes() const QMimeData *QTreeWidget::mimeData(const QList<QTreeWidgetItem*> items) const { Q_D(const QTreeWidget); - if (d->model()->cachedIndexes.isEmpty()) { + if (d->treeModel()->cachedIndexes.isEmpty()) { QList<QModelIndex> indexes; for (int i = 0; i < items.count(); ++i) { QTreeWidgetItem *item = items.at(i); @@ -3280,9 +3280,9 @@ QMimeData *QTreeWidget::mimeData(const QList<QTreeWidgetItem*> items) const indexes << indexFromItem(item, c); } } - return model()->QAbstractItemModel::mimeData(indexes); + return d->model->QAbstractItemModel::mimeData(indexes); } - return d->model()->internalMimeData(); + return d->treeModel()->internalMimeData(); } /*! @@ -3426,7 +3426,7 @@ bool QTreeWidget::event(QEvent *e) { Q_D(QTreeWidget); if (e->type() == QEvent::Polish) - d->model()->executePendingSort(); + d->treeModel()->executePendingSort(); return QTreeView::event(e); } diff --git a/src/gui/itemviews/qtreewidget_p.h b/src/gui/itemviews/qtreewidget_p.h index 4d0acac..145916a 100644 --- a/src/gui/itemviews/qtreewidget_p.h +++ b/src/gui/itemviews/qtreewidget_p.h @@ -219,12 +219,11 @@ class QTreeWidgetPrivate : public QTreeViewPrivate Q_DECLARE_PUBLIC(QTreeWidget) public: QTreeWidgetPrivate() : QTreeViewPrivate(), explicitSortColumn(-1) {} - inline QTreeModel *model() const - { return qobject_cast<QTreeModel*>(q_func()->model()); } + inline QTreeModel *treeModel() const { return qobject_cast<QTreeModel*>(model); } inline QModelIndex index(const QTreeWidgetItem *item, int column = 0) const - { return model()->index(item, column); } + { return treeModel()->index(item, column); } inline QTreeWidgetItem *item(const QModelIndex &index) const - { return model()->item(index); } + { return treeModel()->item(index); } void _q_emitItemPressed(const QModelIndex &index); void _q_emitItemClicked(const QModelIndex &index); void _q_emitItemDoubleClicked(const QModelIndex &index); |