diff options
author | mread <qt-info@nokia.com> | 2009-08-07 13:34:12 (GMT) |
---|---|---|
committer | mread <qt-info@nokia.com> | 2009-08-07 13:34:12 (GMT) |
commit | 5a72890b7ce12815f9567316da867006cff73f39 (patch) | |
tree | 46c8c793f19274f9ed19678d1732d2123adbdf34 /src/gui/itemviews | |
parent | 0f6f1f841cea61cbb6905de92c2ca63bd369d55d (diff) | |
parent | cc0a411e5e874aa224c26298a109973cb15ea291 (diff) | |
download | Qt-5a72890b7ce12815f9567316da867006cff73f39.zip Qt-5a72890b7ce12815f9567316da867006cff73f39.tar.gz Qt-5a72890b7ce12815f9567316da867006cff73f39.tar.bz2 |
Merge branch 'master' of git@scm.dev.nokia.troll.no:qt/qt-s60-public
Conflicts fixed:
src/corelib/io/qdiriterator.cpp
Diffstat (limited to 'src/gui/itemviews')
41 files changed, 828 insertions, 631 deletions
diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index a4f512b..9ad9da7 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -128,6 +128,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 @@ -821,8 +852,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 { @@ -831,14 +862,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) { @@ -853,13 +884,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) @@ -930,6 +961,7 @@ void QAbstractItemView::reset() d->currentIndexSet = false; setState(NoState); setRootIndex(QModelIndex()); + d->selectionModel->reset(); } /*! @@ -960,11 +992,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() { @@ -1193,10 +1225,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) @@ -1212,10 +1244,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) @@ -1251,11 +1283,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) { @@ -1291,14 +1323,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) { @@ -1558,7 +1590,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)) @@ -1569,36 +1601,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) @@ -1614,14 +1620,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); } } @@ -2200,6 +2205,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()) @@ -2255,8 +2262,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. */ @@ -2273,11 +2280,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 { @@ -2359,8 +2366,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() { @@ -2369,8 +2376,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() { @@ -2415,27 +2422,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())); } /*! @@ -2530,9 +2539,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) { @@ -2551,9 +2560,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) { @@ -2624,12 +2633,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) { @@ -2683,9 +2692,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()); } } while (current != start && firstMatch.isValid()); @@ -2792,9 +2801,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) { @@ -2958,7 +2967,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(); } @@ -3181,7 +3190,7 @@ void QAbstractItemView::currentChanged(const QModelIndex ¤t, const QModelI 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; } @@ -3329,14 +3338,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) { @@ -3345,13 +3354,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 { @@ -3523,7 +3532,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; @@ -3602,8 +3611,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; @@ -3754,7 +3764,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 @@ -3790,7 +3800,7 @@ void QAbstractItemViewPrivate::clearOrRemove() When persistent aeditor gets/loses focus, we need to check and setcorrectly the current index. - */ +*/ void QAbstractItemViewPrivate::checkPersistentEditorFocus() { Q_Q(QAbstractItemView); @@ -3876,30 +3886,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 19d6383..da6f0ea 100644 --- a/src/gui/itemviews/qabstractitemview.h +++ b/src/gui/itemviews/qabstractitemview.h @@ -345,7 +345,7 @@ protected: #endif private: - Q_DECLARE_SCOPED_PRIVATE(QAbstractItemView) + Q_DECLARE_PRIVATE(QAbstractItemView) Q_DISABLE_COPY(QAbstractItemView) Q_PRIVATE_SLOT(d_func(), void _q_columnsAboutToBeRemoved(const QModelIndex&, int, int)) Q_PRIVATE_SLOT(d_func(), void _q_columnsRemoved(const QModelIndex&, int, int)) @@ -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 d661c2a..f90e0fe 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: @@ -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/qabstractproxymodel.h b/src/gui/itemviews/qabstractproxymodel.h index 356d923..8a703da 100644 --- a/src/gui/itemviews/qabstractproxymodel.h +++ b/src/gui/itemviews/qabstractproxymodel.h @@ -87,7 +87,7 @@ protected: QAbstractProxyModel(QAbstractProxyModelPrivate &, QObject *parent); private: - Q_DECLARE_SCOPED_PRIVATE(QAbstractProxyModel) + Q_DECLARE_PRIVATE(QAbstractProxyModel) Q_DISABLE_COPY(QAbstractProxyModel) Q_PRIVATE_SLOT(d_func(), void _q_sourceModelDestroyed()) }; diff --git a/src/gui/itemviews/qcolumnview.cpp b/src/gui/itemviews/qcolumnview.cpp index 1662fa8..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); - QObject::connect(¤tAnimation, SIGNAL(frameChanged(int)), - hbar, SLOT(setValue(int))); +#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; @@ -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() diff --git a/src/gui/itemviews/qcolumnview.h b/src/gui/itemviews/qcolumnview.h index 96da637..f8697e9 100644 --- a/src/gui/itemviews/qcolumnview.h +++ b/src/gui/itemviews/qcolumnview.h @@ -97,18 +97,16 @@ 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_SCOPED_PRIVATE(QColumnView) + Q_DECLARE_PRIVATE(QColumnView) Q_DISABLE_COPY(QColumnView) Q_PRIVATE_SLOT(d_func(), void _q_gripMoved(int)) Q_PRIVATE_SLOT(d_func(), void _q_changeCurrentColumn()) diff --git a/src/gui/itemviews/qcolumnview_p.h b/src/gui/itemviews/qcolumnview_p.h index 904cd1d..7b4f774 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/qcolumnviewgrip_p.h b/src/gui/itemviews/qcolumnviewgrip_p.h index 8e670e9..4dc35ec 100644 --- a/src/gui/itemviews/qcolumnviewgrip_p.h +++ b/src/gui/itemviews/qcolumnviewgrip_p.h @@ -82,7 +82,7 @@ protected: void mousePressEvent(QMouseEvent *event); private: - Q_DECLARE_SCOPED_PRIVATE(QColumnViewGrip) + Q_DECLARE_PRIVATE(QColumnViewGrip) Q_DISABLE_COPY(QColumnViewGrip) }; diff --git a/src/gui/itemviews/qdatawidgetmapper.h b/src/gui/itemviews/qdatawidgetmapper.h index 2773b59..2df7b69 100644 --- a/src/gui/itemviews/qdatawidgetmapper.h +++ b/src/gui/itemviews/qdatawidgetmapper.h @@ -111,7 +111,7 @@ Q_SIGNALS: void currentIndexChanged(int index); private: - Q_DECLARE_SCOPED_PRIVATE(QDataWidgetMapper) + Q_DECLARE_PRIVATE(QDataWidgetMapper) Q_DISABLE_COPY(QDataWidgetMapper) Q_PRIVATE_SLOT(d_func(), void _q_dataChanged(const QModelIndex &, const QModelIndex &)) Q_PRIVATE_SLOT(d_func(), void _q_commitData(QWidget *)) diff --git a/src/gui/itemviews/qdirmodel.cpp b/src/gui/itemviews/qdirmodel.cpp index 076e95d..5d7d1ff 100644 --- a/src/gui/itemviews/qdirmodel.cpp +++ b/src/gui/itemviews/qdirmodel.cpp @@ -228,7 +228,10 @@ void QDirModelPrivate::invalidate() \note QDirModel requires an instance of a GUI application. - \sa nameFilters(), setFilter(), filter(), QListView, QTreeView, + \note The usage of QDirModel is not recommended anymore. The + QFileSystemModel class is a more performant alternative. + + \sa nameFilters(), setFilter(), filter(), QListView, QTreeView, QFileSystemModel {Dir View Example}, {Model Classes} */ diff --git a/src/gui/itemviews/qdirmodel.h b/src/gui/itemviews/qdirmodel.h index 1f28cc9..719d551 100644 --- a/src/gui/itemviews/qdirmodel.h +++ b/src/gui/itemviews/qdirmodel.h @@ -146,7 +146,7 @@ protected: friend class QFileDialogPrivate; private: - Q_DECLARE_SCOPED_PRIVATE(QDirModel) + Q_DECLARE_PRIVATE(QDirModel) Q_DISABLE_COPY(QDirModel) Q_PRIVATE_SLOT(d_func(), void _q_refresh()) }; diff --git a/src/gui/itemviews/qfileiconprovider.cpp b/src/gui/itemviews/qfileiconprovider.cpp index f9078b8..b9df4fc 100644 --- a/src/gui/itemviews/qfileiconprovider.cpp +++ b/src/gui/itemviews/qfileiconprovider.cpp @@ -45,18 +45,17 @@ #include <qstyle.h> #include <qapplication.h> #include <qdir.h> +#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> -#include <qpixmapcache.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 @@ -242,10 +241,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) { @@ -281,10 +280,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) { @@ -314,6 +313,31 @@ QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const QIcon QFileIconProviderPrivate::getMacIcon(const QFileInfo &fi) const { QIcon retIcon; + QString fileExtension = fi.suffix().toUpper(); + fileExtension.prepend(QLatin1String(".")); + + const QString keyBase = QLatin1String("qt_") + fileExtension; + + QPixmap pixmap; + if (fi.isFile() && !fi.isExecutable() && !fi.isSymLink()) { + QPixmapCache::find(keyBase + QLatin1String("16"), pixmap); + } + + if (!pixmap.isNull()) { + retIcon.addPixmap(pixmap); + if (QPixmapCache::find(keyBase + QLatin1String("32"), pixmap)) { + retIcon.addPixmap(pixmap); + if (QPixmapCache::find(keyBase + QLatin1String("64"), pixmap)) { + retIcon.addPixmap(pixmap); + if (QPixmapCache::find(keyBase + QLatin1String("128"), pixmap)) { + retIcon.addPixmap(pixmap); + return retIcon; + } + } + } + } + + FSRef macRef; OSStatus status = FSPathMakeRef(reinterpret_cast<const UInt8*>(fi.canonicalFilePath().toUtf8().constData()), &macRef, 0); @@ -326,12 +350,23 @@ 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); + + pixmap = retIcon.pixmap(16); + QPixmapCache::insert(keyBase + QLatin1String("16"), pixmap); + pixmap = retIcon.pixmap(32); + QPixmapCache::insert(keyBase + QLatin1String("32"), pixmap); + pixmap = retIcon.pixmap(64); + QPixmapCache::insert(keyBase + QLatin1String("64"), pixmap); + pixmap = retIcon.pixmap(128); + QPixmapCache::insert(keyBase + QLatin1String("128"), pixmap); + return retIcon; } #endif @@ -356,9 +391,7 @@ QIcon QFileIconProvider::icon(const QFileInfo &info) const if (info.isRoot()) #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: diff --git a/src/gui/itemviews/qfileiconprovider.h b/src/gui/itemviews/qfileiconprovider.h index dd1bedd..165e30f 100644 --- a/src/gui/itemviews/qfileiconprovider.h +++ b/src/gui/itemviews/qfileiconprovider.h @@ -67,7 +67,7 @@ public: virtual QString type(const QFileInfo &info) const; private: - Q_DECLARE_SCOPED_PRIVATE(QFileIconProvider) + Q_DECLARE_PRIVATE(QFileIconProvider) QScopedPointer<QFileIconProviderPrivate> d_ptr; Q_DISABLE_COPY(QFileIconProvider) }; diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp index 233150c..750e20b 100644 --- a/src/gui/itemviews/qheaderview.cpp +++ b/src/gui/itemviews/qheaderview.cpp @@ -522,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; } @@ -2540,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; diff --git a/src/gui/itemviews/qheaderview.h b/src/gui/itemviews/qheaderview.h index cdbc1e6..3a66c9a 100644 --- a/src/gui/itemviews/qheaderview.h +++ b/src/gui/itemviews/qheaderview.h @@ -221,15 +221,14 @@ 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_SCOPED_PRIVATE(QHeaderView) + Q_DECLARE_PRIVATE(QHeaderView) Q_DISABLE_COPY(QHeaderView) }; diff --git a/src/gui/itemviews/qitemdelegate.cpp b/src/gui/itemviews/qitemdelegate.cpp index 74f5da2..82d75ba 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); } diff --git a/src/gui/itemviews/qitemdelegate.h b/src/gui/itemviews/qitemdelegate.h index a6f0ba1..d46481c 100644 --- a/src/gui/itemviews/qitemdelegate.h +++ b/src/gui/itemviews/qitemdelegate.h @@ -126,7 +126,7 @@ protected: const QFont &font, const QString &text) const; private: - Q_DECLARE_SCOPED_PRIVATE(QItemDelegate) + Q_DECLARE_PRIVATE(QItemDelegate) Q_DISABLE_COPY(QItemDelegate) Q_PRIVATE_SLOT(d_func(), void _q_commitDataAndCloseEditor(QWidget*)) diff --git a/src/gui/itemviews/qitemselectionmodel.cpp b/src/gui/itemviews/qitemselectionmodel.cpp index e4cb0f0..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) diff --git a/src/gui/itemviews/qitemselectionmodel.h b/src/gui/itemviews/qitemselectionmodel.h index bc9f61c..e6a99a6 100644 --- a/src/gui/itemviews/qitemselectionmodel.h +++ b/src/gui/itemviews/qitemselectionmodel.h @@ -125,7 +125,7 @@ class QItemSelectionModelPrivate; class Q_GUI_EXPORT QItemSelectionModel : public QObject { Q_OBJECT - Q_DECLARE_SCOPED_PRIVATE(QItemSelectionModel) + Q_DECLARE_PRIVATE(QItemSelectionModel) Q_FLAGS(SelectionFlags) public: diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp index 4652b91..148d204 100644 --- a/src/gui/itemviews/qlistview.cpp +++ b/src/gui/itemviews/qlistview.cpp @@ -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 @@ -925,9 +950,9 @@ void QListView::dragMoveEvent(QDragMoveEvent *e) 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()); } @@ -1100,10 +1125,8 @@ void QListView::paintEvent(QPaintEvent *e) return; QStyleOptionViewItemV4 option = d->viewOptionsV4(); QPainter painter(d->viewport); - QRect area = e->rect(); - d->intersectingSet(e->rect().translated(horizontalOffset(), verticalOffset()), false); - const QVector<QModelIndex> toBeRendered = d->intersectVector; + const QVector<QModelIndex> toBeRendered = d->intersectingSet(e->rect().translated(horizontalOffset(), verticalOffset()), false); const QModelIndex current = currentIndex(); const QModelIndex hover = d->hover; @@ -1225,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(); @@ -1325,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 @@ -1372,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 @@ -1399,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: @@ -1477,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 { @@ -1490,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() @@ -1540,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())); @@ -1567,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); @@ -1633,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; } @@ -2116,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; @@ -2408,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; @@ -2427,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); @@ -2442,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 @@ -2769,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) @@ -2851,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.h b/src/gui/itemviews/qlistview.h index a098427..75dff40 100644 --- a/src/gui/itemviews/qlistview.h +++ b/src/gui/itemviews/qlistview.h @@ -190,7 +190,7 @@ private: friend class QAccessibleItemView; int visualIndex(const QModelIndex &index) const; - Q_DECLARE_SCOPED_PRIVATE(QListView) + Q_DECLARE_PRIVATE(QListView) Q_DISABLE_COPY(QListView) }; diff --git a/src/gui/itemviews/qlistview_p.h b/src/gui/itemviews/qlistview_p.h index a7a7000..1727ba4 100644 --- a/src/gui/itemviews/qlistview_p.h +++ b/src/gui/itemviews/qlistview_p.h @@ -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 7113217..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, @@ -1268,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() */ /*! diff --git a/src/gui/itemviews/qlistwidget.h b/src/gui/itemviews/qlistwidget.h index d2f2f06..afcc331 100644 --- a/src/gui/itemviews/qlistwidget.h +++ b/src/gui/itemviews/qlistwidget.h @@ -291,7 +291,7 @@ private: void setModel(QAbstractItemModel *model); Qt::SortOrder sortOrder() const; - Q_DECLARE_SCOPED_PRIVATE(QListWidget) + Q_DECLARE_PRIVATE(QListWidget) Q_DISABLE_COPY(QListWidget) Q_PRIVATE_SLOT(d_func(), void _q_emitItemPressed(const QModelIndex &index)) diff --git a/src/gui/itemviews/qproxymodel.h b/src/gui/itemviews/qproxymodel.h index 420753c..62cf33e 100644 --- a/src/gui/itemviews/qproxymodel.h +++ b/src/gui/itemviews/qproxymodel.h @@ -119,7 +119,7 @@ protected: void disconnectFromModel(const QAbstractItemModel *model) const; private: - Q_DECLARE_SCOPED_PRIVATE(QProxyModel) + Q_DECLARE_PRIVATE(QProxyModel) Q_DISABLE_COPY(QProxyModel) Q_PRIVATE_SLOT(d_func(), void _q_sourceDataChanged(const QModelIndex&,const QModelIndex&)) diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp index 30a8c96..fdc09ca 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.cpp +++ b/src/gui/itemviews/qsortfilterproxymodel.cpp @@ -146,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); @@ -354,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 @@ -659,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); @@ -1186,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( @@ -1217,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/qsortfilterproxymodel.h b/src/gui/itemviews/qsortfilterproxymodel.h index b179559..0bd084e 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.h +++ b/src/gui/itemviews/qsortfilterproxymodel.h @@ -172,7 +172,7 @@ public: QStringList mimeTypes() const; Qt::DropActions supportedDropActions() const; private: - Q_DECLARE_SCOPED_PRIVATE(QSortFilterProxyModel) + Q_DECLARE_PRIVATE(QSortFilterProxyModel) Q_DISABLE_COPY(QSortFilterProxyModel) Q_PRIVATE_SLOT(d_func(), void _q_sourceDataChanged(const QModelIndex &source_top_left, const QModelIndex &source_bottom_right)) diff --git a/src/gui/itemviews/qstandarditemmodel.h b/src/gui/itemviews/qstandarditemmodel.h index 7e76a4a..c470b80 100644 --- a/src/gui/itemviews/qstandarditemmodel.h +++ b/src/gui/itemviews/qstandarditemmodel.h @@ -245,7 +245,7 @@ protected: void emitDataChanged(); private: - Q_DECLARE_SCOPED_PRIVATE(QStandardItem) + Q_DECLARE_PRIVATE(QStandardItem) friend class QStandardItemModelPrivate; friend class QStandardItemModel; }; @@ -422,7 +422,7 @@ private: friend class QStandardItemPrivate; friend class QStandardItem; Q_DISABLE_COPY(QStandardItemModel) - Q_DECLARE_SCOPED_PRIVATE(QStandardItemModel) + Q_DECLARE_PRIVATE(QStandardItemModel) Q_PRIVATE_SLOT(d_func(), void _q_emitItemChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)) diff --git a/src/gui/itemviews/qstyleditemdelegate.cpp b/src/gui/itemviews/qstyleditemdelegate.cpp index e79dafe..f64a8ea 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); } diff --git a/src/gui/itemviews/qstyleditemdelegate.h b/src/gui/itemviews/qstyleditemdelegate.h index 2f31387..ccb1024 100644 --- a/src/gui/itemviews/qstyleditemdelegate.h +++ b/src/gui/itemviews/qstyleditemdelegate.h @@ -101,7 +101,7 @@ protected: const QStyleOptionViewItem &option, const QModelIndex &index); private: - Q_DECLARE_SCOPED_PRIVATE(QStyledItemDelegate) + Q_DECLARE_PRIVATE(QStyledItemDelegate) Q_DISABLE_COPY(QStyledItemDelegate) Q_PRIVATE_SLOT(d_func(), void _q_commitDataAndCloseEditor(QWidget*)) diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp index c676237..2009499 100644 --- a/src/gui/itemviews/qtableview.cpp +++ b/src/gui/itemviews/qtableview.cpp @@ -1528,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); @@ -1554,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); @@ -2036,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; @@ -2091,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; diff --git a/src/gui/itemviews/qtableview.h b/src/gui/itemviews/qtableview.h index 7e4ba54..c09186c 100644 --- a/src/gui/itemviews/qtableview.h +++ b/src/gui/itemviews/qtableview.h @@ -178,7 +178,7 @@ private: friend class QAccessibleItemView; int visualIndex(const QModelIndex &index) const; - Q_DECLARE_SCOPED_PRIVATE(QTableView) + Q_DECLARE_PRIVATE(QTableView) Q_DISABLE_COPY(QTableView) Q_PRIVATE_SLOT(d_func(), void _q_selectRow(int)) Q_PRIVATE_SLOT(d_func(), void _q_selectColumn(int)) diff --git a/src/gui/itemviews/qtablewidget.cpp b/src/gui/itemviews/qtablewidget.cpp index d975d58..5756f35 100644 --- a/src/gui/itemviews/qtablewidget.cpp +++ b/src/gui/itemviews/qtablewidget.cpp @@ -1719,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() */ diff --git a/src/gui/itemviews/qtablewidget.h b/src/gui/itemviews/qtablewidget.h index 1963df8..6c25ba0 100644 --- a/src/gui/itemviews/qtablewidget.h +++ b/src/gui/itemviews/qtablewidget.h @@ -336,7 +336,7 @@ protected: private: void setModel(QAbstractItemModel *model); - Q_DECLARE_SCOPED_PRIVATE(QTableWidget) + Q_DECLARE_PRIVATE(QTableWidget) Q_DISABLE_COPY(QTableWidget) Q_PRIVATE_SLOT(d_func(), void _q_emitItemPressed(const QModelIndex &index)) diff --git a/src/gui/itemviews/qtreeview.cpp b/src/gui/itemviews/qtreeview.cpp index 7c319dc..7536d72 100644 --- a/src/gui/itemviews/qtreeview.cpp +++ b/src/gui/itemviews/qtreeview.cpp @@ -262,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())); @@ -275,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())); @@ -901,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(); } @@ -1112,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 @@ -1267,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); @@ -1306,13 +1296,13 @@ 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 @@ -1335,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. @@ -2819,7 +2853,7 @@ int QTreeView::rowHeight(const QModelIndex &index) const } /*! - \reimp + \internal */ void QTreeView::horizontalScrollbarAction(int action) { @@ -2851,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) @@ -2864,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); @@ -2877,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); @@ -2902,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; @@ -2922,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); } @@ -2953,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; @@ -3039,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() { @@ -3787,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 f9748c6..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); @@ -220,16 +221,13 @@ private: friend class QAccessibleItemView; int visualIndex(const QModelIndex &index) const; - Q_DECLARE_SCOPED_PRIVATE(QTreeView) + 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 7dded8d..7cded49 100644 --- a/src/gui/itemviews/qtreewidget.cpp +++ b/src/gui/itemviews/qtreewidget.cpp @@ -2437,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() */ /*! @@ -2449,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() */ /*! @@ -3109,9 +3109,9 @@ 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) { diff --git a/src/gui/itemviews/qtreewidget.h b/src/gui/itemviews/qtreewidget.h index b640a7a..3266725 100644 --- a/src/gui/itemviews/qtreewidget.h +++ b/src/gui/itemviews/qtreewidget.h @@ -367,7 +367,7 @@ protected: private: void setModel(QAbstractItemModel *model); - Q_DECLARE_SCOPED_PRIVATE(QTreeWidget) + Q_DECLARE_PRIVATE(QTreeWidget) Q_DISABLE_COPY(QTreeWidget) Q_PRIVATE_SLOT(d_func(), void _q_emitItemPressed(const QModelIndex &index)) diff --git a/src/gui/itemviews/qtreewidget_p.h b/src/gui/itemviews/qtreewidget_p.h index 6d62062..145916a 100644 --- a/src/gui/itemviews/qtreewidget_p.h +++ b/src/gui/itemviews/qtreewidget_p.h @@ -162,7 +162,7 @@ private: bool isChanging() const; private: - Q_DECLARE_SCOPED_PRIVATE(QTreeModel) + Q_DECLARE_PRIVATE(QTreeModel) public: struct SkipSorting { diff --git a/src/gui/itemviews/qtreewidgetitemiterator.h b/src/gui/itemviews/qtreewidgetitemiterator.h index ce0b610..eff9fdb 100644 --- a/src/gui/itemviews/qtreewidgetitemiterator.h +++ b/src/gui/itemviews/qtreewidgetitemiterator.h @@ -109,7 +109,7 @@ private: QScopedPointer<QTreeWidgetItemIteratorPrivate> d_ptr; QTreeWidgetItem *current; IteratorFlags flags; - Q_DECLARE_SCOPED_PRIVATE(QTreeWidgetItemIterator) + Q_DECLARE_PRIVATE(QTreeWidgetItemIterator) }; inline const QTreeWidgetItemIterator QTreeWidgetItemIterator::operator++(int) |