summaryrefslogtreecommitdiffstats
path: root/src/widgets/itemviews/qabstractitemview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/itemviews/qabstractitemview.cpp')
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp406
1 files changed, 231 insertions, 175 deletions
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index 0401379c38..85e478a71e 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -102,15 +102,16 @@ void QAbstractItemViewPrivate::init()
vbar->setRange(0, 0);
hbar->setRange(0, 0);
- QObject::connect(vbar, SIGNAL(actionTriggered(int)),
- q, SLOT(verticalScrollbarAction(int)));
- QObject::connect(hbar, SIGNAL(actionTriggered(int)),
- q, SLOT(horizontalScrollbarAction(int)));
- QObject::connect(vbar, SIGNAL(valueChanged(int)),
- q, SLOT(verticalScrollbarValueChanged(int)));
- QObject::connect(hbar, SIGNAL(valueChanged(int)),
- q, SLOT(horizontalScrollbarValueChanged(int)));
-
+ scrollbarConnections = {
+ QObject::connect(vbar, &QScrollBar::actionTriggered,
+ q, &QAbstractItemView::verticalScrollbarAction),
+ QObject::connect(hbar, &QScrollBar::actionTriggered,
+ q, &QAbstractItemView::horizontalScrollbarAction),
+ QObject::connect(vbar, &QScrollBar::valueChanged,
+ q, &QAbstractItemView::verticalScrollbarValueChanged),
+ QObject::connect(hbar, &QScrollBar::valueChanged,
+ q, &QAbstractItemView::horizontalScrollbarValueChanged)
+ };
viewport->setBackgroundRole(QPalette::Base);
q->setAttribute(Qt::WA_InputMethodEnabled);
@@ -129,8 +130,8 @@ void QAbstractItemViewPrivate::setHoverIndex(const QPersistentModelIndex &index)
q->update(hover); //update the old one
q->update(index); //update the new one
} else {
- QRect oldHoverRect = q->visualRect(hover);
- QRect newHoverRect = q->visualRect(index);
+ const QRect oldHoverRect = visualRect(hover);
+ const QRect newHoverRect = visualRect(index);
viewport->update(QRect(0, newHoverRect.y(), viewport->width(), newHoverRect.height()));
viewport->update(QRect(0, oldHoverRect.y(), viewport->width(), oldHoverRect.height()));
}
@@ -172,7 +173,7 @@ void QAbstractItemViewPrivate::checkMouseMove(const QPersistentModelIndex &index
#if QT_CONFIG(gestures) && QT_CONFIG(scroller)
// stores and restores the selection and current item when flicking
-void QAbstractItemViewPrivate::_q_scrollerStateChanged()
+void QAbstractItemViewPrivate::scrollerStateChanged()
{
Q_Q(QAbstractItemView);
@@ -208,7 +209,7 @@ void QAbstractItemViewPrivate::_q_scrollerStateChanged()
#endif // QT_NO_GESTURES
-void QAbstractItemViewPrivate::_q_delegateSizeHintChanged(const QModelIndex &index)
+void QAbstractItemViewPrivate::delegateSizeHintChanged(const QModelIndex &index)
{
Q_Q(QAbstractItemView);
if (model) {
@@ -218,6 +219,63 @@ void QAbstractItemViewPrivate::_q_delegateSizeHintChanged(const QModelIndex &ind
QMetaObject::invokeMethod(q, &QAbstractItemView::doItemsLayout, Qt::QueuedConnection);
}
+void QAbstractItemViewPrivate::connectDelegate(QAbstractItemDelegate *delegate)
+{
+ if (!delegate)
+ return;
+ Q_Q(QAbstractItemView);
+ QObject::connect(delegate, &QAbstractItemDelegate::closeEditor,
+ q, &QAbstractItemView::closeEditor);
+ QObject::connect(delegate, &QAbstractItemDelegate::commitData,
+ q, &QAbstractItemView::commitData);
+ QObjectPrivate::connect(delegate, &QAbstractItemDelegate::sizeHintChanged,
+ this, &QAbstractItemViewPrivate::delegateSizeHintChanged);
+}
+
+void QAbstractItemViewPrivate::disconnectDelegate(QAbstractItemDelegate *delegate)
+{
+ if (!delegate)
+ return;
+ Q_Q(QAbstractItemView);
+ QObject::disconnect(delegate, &QAbstractItemDelegate::closeEditor,
+ q, &QAbstractItemView::closeEditor);
+ QObject::disconnect(delegate, &QAbstractItemDelegate::commitData,
+ q, &QAbstractItemView::commitData);
+ QObjectPrivate::disconnect(delegate, &QAbstractItemDelegate::sizeHintChanged,
+ this, &QAbstractItemViewPrivate::delegateSizeHintChanged);
+}
+
+void QAbstractItemViewPrivate::disconnectAll()
+{
+ Q_Q(QAbstractItemView);
+ for (const QMetaObject::Connection &connection : modelConnections)
+ QObject::disconnect(connection);
+ for (const QMetaObject::Connection &connection : scrollbarConnections)
+ QObject::disconnect(connection);
+ disconnectDelegate(itemDelegate);
+ for (QAbstractItemDelegate *delegate : std::as_const(rowDelegates))
+ disconnectDelegate(delegate);
+ for (QAbstractItemDelegate *delegate : std::as_const(columnDelegates))
+ disconnectDelegate(delegate);
+ if (model && selectionModel) {
+ QObject::disconnect(model, &QAbstractItemModel::destroyed,
+ selectionModel, &QItemSelectionModel::deleteLater);
+ }
+ if (selectionModel) {
+ QObject::disconnect(selectionModel, &QItemSelectionModel::selectionChanged,
+ q, &QAbstractItemView::selectionChanged);
+ QObject::disconnect(selectionModel, &QItemSelectionModel::currentChanged,
+ q, &QAbstractItemView::currentChanged);
+ }
+ for (const auto &info : std::as_const(indexEditorHash)) {
+ if (!info.isStatic && info.widget)
+ QObject::disconnect(info.widget, &QWidget::destroyed, q, &QAbstractItemView::editorDestroyed);
+ }
+#if QT_CONFIG(gestures) && QT_CONFIG(scroller)
+ QObject::disconnect(scollerConnection);
+#endif
+}
+
/*!
\class QAbstractItemView
@@ -318,7 +376,7 @@ void QAbstractItemViewPrivate::_q_delegateSizeHintChanged(const QModelIndex &ind
\l{QWidget::update()}{update()} as all painting operations take place on the
viewport.
- \sa {View Classes}, {Model/View Programming}, QAbstractItemModel, {Chart Example}
+ \sa {View Classes}, {Model/View Programming}, QAbstractItemModel
*/
/*!
@@ -631,6 +689,7 @@ QAbstractItemView::~QAbstractItemView()
d->autoScrollTimer.stop();
d->delayedLayout.stop();
d->fetchMoreTimer.stop();
+ d->disconnectAll();
}
/*!
@@ -659,68 +718,47 @@ void QAbstractItemView::setModel(QAbstractItemModel *model)
if (model == d->model)
return;
if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
- disconnect(d->model, SIGNAL(destroyed()),
- this, SLOT(_q_modelDestroyed()));
- disconnect(d->model, SIGNAL(dataChanged(QModelIndex, QModelIndex, QList<int>)), this,
- SLOT(dataChanged(QModelIndex, QModelIndex, QList<int>)));
- disconnect(d->model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
- this, SLOT(_q_headerDataChanged()));
- disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(rowsInserted(QModelIndex,int,int)));
- disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
- this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)));
- disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
- disconnect(d->model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
- this, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int)));
- disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
- disconnect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
- this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int)));
- disconnect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_columnsRemoved(QModelIndex,int,int)));
- disconnect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)),
- this, SLOT(_q_columnsInserted(QModelIndex,int,int)));
- disconnect(d->model, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)),
- this, SLOT(_q_columnsMoved(QModelIndex,int,int,QModelIndex,int)));
-
- disconnect(d->model, SIGNAL(modelReset()), this, SLOT(reset()));
- disconnect(d->model, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged()));
+ for (const QMetaObject::Connection &connection : d->modelConnections)
+ disconnect(connection);
}
d->model = (model ? model : QAbstractItemModelPrivate::staticEmptyModel());
if (d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
- connect(d->model, SIGNAL(destroyed()),
- this, SLOT(_q_modelDestroyed()));
- connect(d->model, SIGNAL(dataChanged(QModelIndex, QModelIndex, QList<int>)), this,
- SLOT(dataChanged(QModelIndex, QModelIndex, QList<int>)));
- connect(d->model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
- this, SLOT(_q_headerDataChanged()));
- connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(rowsInserted(QModelIndex,int,int)));
- connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
- connect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
- this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)));
- connect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
- connect(d->model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
- this, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int)));
- connect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
- this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int)));
- connect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_columnsRemoved(QModelIndex,int,int)));
- connect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)),
- this, SLOT(_q_columnsInserted(QModelIndex,int,int)));
- connect(d->model, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)),
- this, SLOT(_q_columnsMoved(QModelIndex,int,int,QModelIndex,int)));
-
- connect(d->model, SIGNAL(modelReset()), this, SLOT(reset()));
- connect(d->model, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged()));
+ d->modelConnections = {
+ QObjectPrivate::connect(d->model, &QAbstractItemModel::destroyed,
+ d, &QAbstractItemViewPrivate::modelDestroyed),
+ QObject::connect(d->model, &QAbstractItemModel::dataChanged,
+ this, &QAbstractItemView::dataChanged),
+ QObjectPrivate::connect(d->model, &QAbstractItemModel::headerDataChanged,
+ d, &QAbstractItemViewPrivate::headerDataChanged),
+ QObject::connect(d->model, &QAbstractItemModel::rowsInserted,
+ this, &QAbstractItemView::rowsInserted),
+ QObjectPrivate::connect(d->model, &QAbstractItemModel::rowsInserted,
+ d, &QAbstractItemViewPrivate::rowsInserted),
+ QObject::connect(d->model, &QAbstractItemModel::rowsAboutToBeRemoved,
+ this, &QAbstractItemView::rowsAboutToBeRemoved),
+ QObjectPrivate::connect(d->model, &QAbstractItemModel::rowsRemoved,
+ d, &QAbstractItemViewPrivate::rowsRemoved),
+ QObjectPrivate::connect(d->model, &QAbstractItemModel::rowsMoved,
+ d, &QAbstractItemViewPrivate::rowsMoved),
+ QObjectPrivate::connect(d->model, &QAbstractItemModel::columnsAboutToBeRemoved,
+ d, &QAbstractItemViewPrivate::columnsAboutToBeRemoved),
+ QObjectPrivate::connect(d->model, &QAbstractItemModel::columnsRemoved,
+ d, &QAbstractItemViewPrivate::columnsRemoved),
+ QObjectPrivate::connect(d->model, &QAbstractItemModel::columnsInserted,
+ d, &QAbstractItemViewPrivate::columnsInserted),
+ QObjectPrivate::connect(d->model, &QAbstractItemModel::columnsMoved,
+ d, &QAbstractItemViewPrivate::columnsMoved),
+ QObject::connect(d->model, &QAbstractItemModel::modelReset,
+ this, &QAbstractItemView::reset),
+ QObjectPrivate::connect(d->model, &QAbstractItemModel::layoutChanged,
+ d, &QAbstractItemViewPrivate::layoutChanged),
+ };
}
QItemSelectionModel *selection_model = new QItemSelectionModel(d->model, this);
- connect(d->model, SIGNAL(destroyed()), selection_model, SLOT(deleteLater()));
+ connect(d->model, &QAbstractItemModel::destroyed,
+ selection_model, &QItemSelectionModel::deleteLater);
setSelectionModel(selection_model);
reset(); // kill editors, set new root and do layout
@@ -770,20 +808,19 @@ void QAbstractItemView::setSelectionModel(QItemSelectionModel *selectionModel)
oldSelection = d->selectionModel->selection();
oldCurrentIndex = d->selectionModel->currentIndex();
}
-
- disconnect(d->selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
- this, SLOT(selectionChanged(QItemSelection,QItemSelection)));
- disconnect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- this, SLOT(currentChanged(QModelIndex,QModelIndex)));
+ disconnect(d->selectionModel, &QItemSelectionModel::selectionChanged,
+ this, &QAbstractItemView::selectionChanged);
+ disconnect(d->selectionModel, &QItemSelectionModel::currentChanged,
+ this, &QAbstractItemView::currentChanged);
}
d->selectionModel = selectionModel;
if (d->selectionModel) {
- connect(d->selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
- this, SLOT(selectionChanged(QItemSelection,QItemSelection)));
- connect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- this, SLOT(currentChanged(QModelIndex,QModelIndex)));
+ connect(d->selectionModel, &QItemSelectionModel::selectionChanged,
+ this, &QAbstractItemView::selectionChanged);
+ connect(d->selectionModel, &QItemSelectionModel::currentChanged,
+ this, &QAbstractItemView::currentChanged);
selectionChanged(d->selectionModel->selection(), oldSelection);
currentChanged(d->selectionModel->currentIndex(), oldCurrentIndex);
@@ -823,21 +860,13 @@ void QAbstractItemView::setItemDelegate(QAbstractItemDelegate *delegate)
return;
if (d->itemDelegate) {
- if (d->delegateRefCount(d->itemDelegate) == 1) {
- disconnect(d->itemDelegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
- this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
- disconnect(d->itemDelegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
- disconnect(d->itemDelegate, SIGNAL(sizeHintChanged(QModelIndex)), this, SLOT(_q_delegateSizeHintChanged(QModelIndex)));
- }
+ if (d->delegateRefCount(d->itemDelegate) == 1)
+ d->disconnectDelegate(delegate);
}
if (delegate) {
- if (d->delegateRefCount(delegate) == 0) {
- connect(delegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
- this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
- connect(delegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
- connect(delegate, SIGNAL(sizeHintChanged(QModelIndex)), this, SLOT(_q_delegateSizeHintChanged(QModelIndex)));
- }
+ if (d->delegateRefCount(delegate) == 0)
+ d->connectDelegate(delegate);
}
d->itemDelegate = delegate;
viewport()->update();
@@ -907,21 +936,13 @@ void QAbstractItemView::setItemDelegateForRow(int row, QAbstractItemDelegate *de
{
Q_D(QAbstractItemView);
if (QAbstractItemDelegate *rowDelegate = d->rowDelegates.value(row, nullptr)) {
- if (d->delegateRefCount(rowDelegate) == 1) {
- disconnect(rowDelegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
- this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
- disconnect(rowDelegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
- disconnect(rowDelegate, SIGNAL(sizeHintChanged(QModelIndex)), this, SLOT(_q_delegateSizeHintChanged(QModelIndex)));
- }
+ if (d->delegateRefCount(rowDelegate) == 1)
+ d->disconnectDelegate(rowDelegate);
d->rowDelegates.remove(row);
}
if (delegate) {
- if (d->delegateRefCount(delegate) == 0) {
- connect(delegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
- this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
- connect(delegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
- connect(delegate, SIGNAL(sizeHintChanged(QModelIndex)), this, SLOT(_q_delegateSizeHintChanged(QModelIndex)));
- }
+ if (d->delegateRefCount(delegate) == 0)
+ d->connectDelegate(delegate);
d->rowDelegates.insert(row, delegate);
}
viewport()->update();
@@ -967,21 +988,13 @@ void QAbstractItemView::setItemDelegateForColumn(int column, QAbstractItemDelega
{
Q_D(QAbstractItemView);
if (QAbstractItemDelegate *columnDelegate = d->columnDelegates.value(column, nullptr)) {
- if (d->delegateRefCount(columnDelegate) == 1) {
- disconnect(columnDelegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
- this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
- disconnect(columnDelegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
- disconnect(columnDelegate, SIGNAL(sizeHintChanged(QModelIndex)), this, SLOT(_q_delegateSizeHintChanged(QModelIndex)));
- }
+ if (d->delegateRefCount(columnDelegate) == 1)
+ d->disconnectDelegate(columnDelegate);
d->columnDelegates.remove(column);
}
if (delegate) {
- if (d->delegateRefCount(delegate) == 0) {
- connect(delegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
- this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
- connect(delegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
- connect(delegate, SIGNAL(sizeHintChanged(QModelIndex)), this, SLOT(_q_delegateSizeHintChanged(QModelIndex)));
- }
+ if (d->delegateRefCount(delegate) == 0)
+ d->connectDelegate(delegate);
d->columnDelegates.insert(column, delegate);
}
viewport()->update();
@@ -1119,7 +1132,11 @@ void QAbstractItemView::reset()
{
Q_D(QAbstractItemView);
d->delayedReset.stop(); //make sure we stop the timer
- foreach (const QEditorInfo &info, d->indexEditorHash) {
+ // Taking a copy because releaseEditor() eventurally calls deleteLater() on the
+ // editor, which calls QCoreApplication::postEvent(), the latter may invoke unknown
+ // code that may modify d->indexEditorHash.
+ const auto copy = d->indexEditorHash;
+ for (const auto &[index, info] : copy.asKeyValueRange()) {
if (info.widget)
d->releaseEditor(info.widget.data(), d->indexForEditor(info.widget.data()));
}
@@ -1153,6 +1170,12 @@ void QAbstractItemView::setRootIndex(const QModelIndex &index)
return;
}
d->root = index;
+#if QT_CONFIG(accessibility)
+ if (QAccessible::isActive()) {
+ QAccessibleTableModelChangeEvent accessibleEvent(this, QAccessibleTableModelChangeEvent::ModelReset);
+ QAccessible::updateAccessibility(&accessibleEvent);
+ }
+#endif
d->doDelayedItemsLayout();
d->updateGeometry();
}
@@ -1545,7 +1568,7 @@ QAbstractItemView::DragDropMode QAbstractItemView::dragDropMode() const
/*!
\property QAbstractItemView::defaultDropAction
- \brief the drop action that will be used by default in QAbstractItemView::drag()
+ \brief the drop action that will be used by default in QAbstractItemView::drag().
If the property is not set, the drop action is CopyAction when the supported
actions support CopyAction.
@@ -1638,7 +1661,7 @@ Qt::TextElideMode QAbstractItemView::textElideMode() const
bool QAbstractItemView::focusNextPrevChild(bool next)
{
Q_D(QAbstractItemView);
- if (d->tabKeyNavigation && isEnabled() && d->viewport->isEnabled()) {
+ if (d->tabKeyNavigation && isVisible() && isEnabled() && d->viewport->isEnabled()) {
QKeyEvent event(QEvent::KeyPress, next ? Qt::Key_Tab : Qt::Key_Backtab, Qt::NoModifier);
keyPressEvent(&event);
if (event.isAccepted())
@@ -1762,7 +1785,10 @@ bool QAbstractItemView::viewportEvent(QEvent *event)
case QEvent::ScrollPrepare:
executeDelayedItemsLayout();
#if QT_CONFIG(gestures) && QT_CONFIG(scroller)
- connect(QScroller::scroller(d->viewport), SIGNAL(stateChanged(QScroller::State)), this, SLOT(_q_scrollerStateChanged()), Qt::UniqueConnection);
+ d->scollerConnection = QObjectPrivate::connect(
+ QScroller::scroller(d->viewport), &QScroller::stateChanged,
+ d, &QAbstractItemViewPrivate::scrollerStateChanged,
+ Qt::UniqueConnection);
#endif
break;
@@ -1857,7 +1883,6 @@ void QAbstractItemView::mousePressEvent(QMouseEvent *event)
void QAbstractItemView::mouseMoveEvent(QMouseEvent *event)
{
Q_D(QAbstractItemView);
- QPoint topLeft;
QPoint bottomRight = event->position().toPoint();
d->draggedPosition = bottomRight + d->offset();
@@ -1867,13 +1892,7 @@ void QAbstractItemView::mouseMoveEvent(QMouseEvent *event)
#if QT_CONFIG(draganddrop)
if (state() == DraggingState) {
- topLeft = d->pressedPosition - d->offset();
- if ((topLeft - bottomRight).manhattanLength() > QApplication::startDragDistance()) {
- d->pressedIndex = QModelIndex();
- startDrag(d->model->supportedDragActions());
- setState(NoState); // the startDrag will return when the dnd operation is done
- stopAutoScroll();
- }
+ d->maybeStartDrag(bottomRight);
return;
}
#endif // QT_CONFIG(draganddrop)
@@ -1884,10 +1903,8 @@ void QAbstractItemView::mouseMoveEvent(QMouseEvent *event)
|| edit(index, NoEditTriggers, event))
return;
- if (d->selectionMode != SingleSelection)
- topLeft = d->pressedPosition - d->offset();
- else
- topLeft = bottomRight;
+ const QPoint topLeft =
+ d->selectionMode != SingleSelection ? d->pressedPosition - d->offset() : bottomRight;
d->checkMouseMove(index);
@@ -1898,6 +1915,7 @@ void QAbstractItemView::mouseMoveEvent(QMouseEvent *event)
&& (event->buttons() != Qt::NoButton)
&& !d->selectedDraggableIndexes().isEmpty()) {
setState(DraggingState);
+ d->maybeStartDrag(bottomRight);
return;
}
#endif
@@ -2918,41 +2936,50 @@ void QAbstractItemView::closeEditor(QWidget *editor, QAbstractItemDelegate::EndE
// Close the editor
if (editor) {
- bool isPersistent = d->persistent.contains(editor);
- bool hadFocus = editor->hasFocus();
- QModelIndex index = d->indexForEditor(editor);
+ const bool isPersistent = d->persistent.contains(editor);
+ const QModelIndex index = d->indexForEditor(editor);
if (!index.isValid()) {
- qWarning("QAbstractItemView::closeEditor called with an editor that does not belong to this view");
- return; // the editor was not registered
- }
-
- // start a timer that expires immediately when we return to the event loop
- // to identify whether this close was triggered by a mousepress-initiated
- // focus event
- d->pressClosedEditorWatcher.start(0, this);
- d->lastEditedIndex = index;
-
- if (!isPersistent) {
- setState(NoState);
- QModelIndex index = d->indexForEditor(editor);
- editor->removeEventFilter(itemDelegateForIndex(index));
- d->removeEditor(editor);
- }
- if (hadFocus) {
- if (focusPolicy() != Qt::NoFocus)
- setFocus(); // this will send a focusLost event to the editor
- else
- editor->clearFocus();
+ if (!editor->isVisible()) {
+ // The commit might have removed the index (e.g. it might get filtered), in
+ // which case the editor is already hidden and scheduled for deletion. We
+ // don't have to do anything, except reset the state, and continue with
+ // EndEditHint processing.
+ if (!isPersistent)
+ setState(NoState);
+ } else {
+ qWarning("QAbstractItemView::closeEditor called with an editor that does not belong to this view");
+ return;
+ }
} else {
- d->checkPersistentEditorFocus();
- }
+ const bool hadFocus = editor->hasFocus();
+ // start a timer that expires immediately when we return to the event loop
+ // to identify whether this close was triggered by a mousepress-initiated
+ // focus event
+ d->pressClosedEditorWatcher.start(0, this);
+ d->lastEditedIndex = index;
+
+ if (!isPersistent) {
+ setState(NoState);
+ QModelIndex index = d->indexForEditor(editor);
+ editor->removeEventFilter(itemDelegateForIndex(index));
+ d->removeEditor(editor);
+ }
+ if (hadFocus) {
+ if (focusPolicy() != Qt::NoFocus)
+ setFocus(); // this will send a focusLost event to the editor
+ else
+ editor->clearFocus();
+ } else {
+ d->checkPersistentEditorFocus();
+ }
- QPointer<QWidget> ed = editor;
- QCoreApplication::sendPostedEvents(editor, 0);
- editor = ed;
+ QPointer<QWidget> ed = editor;
+ QCoreApplication::sendPostedEvents(editor, 0);
+ editor = ed;
- if (!isPersistent && editor)
- d->releaseEditor(editor, index);
+ if (!isPersistent && editor)
+ d->releaseEditor(editor, index);
+ }
}
// The EndEditHint part
@@ -3354,7 +3381,7 @@ void QAbstractItemView::update(const QModelIndex &index)
{
Q_D(QAbstractItemView);
if (index.isValid()) {
- const QRect rect = visualRect(index);
+ const QRect rect = d->visualRect(index);
//this test is important for performance reason
//For example in dataChanged we simply update all the cells without checking
//it can be a major bottleneck to update rects that aren't even part of the viewport
@@ -3505,10 +3532,21 @@ void QAbstractItemView::rowsAboutToBeRemoved(const QModelIndex &parent, int star
}
// Remove all affected editors; this is more efficient than waiting for updateGeometries() to clean out editors for invalid indexes
+ const auto findDirectChildOf = [](const QModelIndex &parent, QModelIndex child)
+ {
+ while (child.isValid()) {
+ const auto parentIndex = child.parent();
+ if (parentIndex == parent)
+ return child;
+ child = parentIndex;
+ }
+ return QModelIndex();
+ };
QEditorIndexHash::iterator i = d->editorIndexHash.begin();
while (i != d->editorIndexHash.end()) {
const QModelIndex index = i.value();
- if (index.row() >= start && index.row() <= end && d->model->parent(index) == parent) {
+ const QModelIndex directChild = findDirectChildOf(parent, index);
+ if (directChild.isValid() && directChild.row() >= start && directChild.row() <= end) {
QWidget *editor = i.key();
QEditorInfo info = d->indexEditorHash.take(index);
i = d->editorIndexHash.erase(i);
@@ -3527,7 +3565,7 @@ void QAbstractItemView::rowsAboutToBeRemoved(const QModelIndex &parent, int star
rows are those under the given \a parent from \a start to \a end
inclusive.
*/
-void QAbstractItemViewPrivate::_q_rowsRemoved(const QModelIndex &index, int start, int end)
+void QAbstractItemViewPrivate::rowsRemoved(const QModelIndex &index, int start, int end)
{
Q_UNUSED(index);
Q_UNUSED(start);
@@ -3555,7 +3593,7 @@ void QAbstractItemViewPrivate::_q_rowsRemoved(const QModelIndex &index, int star
columns are those under the given \a parent from \a start to \a end
inclusive.
*/
-void QAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
+void QAbstractItemViewPrivate::columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
{
Q_Q(QAbstractItemView);
@@ -3618,7 +3656,7 @@ void QAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &par
rows are those under the given \a parent from \a start to \a end
inclusive.
*/
-void QAbstractItemViewPrivate::_q_columnsRemoved(const QModelIndex &index, int start, int end)
+void QAbstractItemViewPrivate::columnsRemoved(const QModelIndex &index, int start, int end)
{
Q_UNUSED(index);
Q_UNUSED(start);
@@ -3645,7 +3683,7 @@ void QAbstractItemViewPrivate::_q_columnsRemoved(const QModelIndex &index, int s
This slot is called when rows have been inserted.
*/
-void QAbstractItemViewPrivate::_q_rowsInserted(const QModelIndex &index, int start, int end)
+void QAbstractItemViewPrivate::rowsInserted(const QModelIndex &index, int start, int end)
{
Q_UNUSED(index);
Q_UNUSED(start);
@@ -3668,7 +3706,7 @@ void QAbstractItemViewPrivate::_q_rowsInserted(const QModelIndex &index, int sta
This slot is called when columns have been inserted.
*/
-void QAbstractItemViewPrivate::_q_columnsInserted(const QModelIndex &index, int start, int end)
+void QAbstractItemViewPrivate::columnsInserted(const QModelIndex &index, int start, int end)
{
Q_UNUSED(index);
Q_UNUSED(start);
@@ -3691,7 +3729,7 @@ void QAbstractItemViewPrivate::_q_columnsInserted(const QModelIndex &index, int
/*!
\internal
*/
-void QAbstractItemViewPrivate::_q_modelDestroyed()
+void QAbstractItemViewPrivate::modelDestroyed()
{
model = QAbstractItemModelPrivate::staticEmptyModel();
doDelayedReset();
@@ -3702,7 +3740,7 @@ void QAbstractItemViewPrivate::_q_modelDestroyed()
This slot is called when the layout is changed.
*/
-void QAbstractItemViewPrivate::_q_layoutChanged()
+void QAbstractItemViewPrivate::layoutChanged()
{
doDelayedItemsLayout();
#if QT_CONFIG(accessibility)
@@ -3714,14 +3752,14 @@ void QAbstractItemViewPrivate::_q_layoutChanged()
#endif
}
-void QAbstractItemViewPrivate::_q_rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)
+void QAbstractItemViewPrivate::rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)
{
- _q_layoutChanged();
+ layoutChanged();
}
-void QAbstractItemViewPrivate::_q_columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int)
+void QAbstractItemViewPrivate::columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int)
{
- _q_layoutChanged();
+ layoutChanged();
}
QRect QAbstractItemViewPrivate::intersectedRect(const QRect rect, const QModelIndex &topLeft, const QModelIndex &bottomRight) const
@@ -4263,6 +4301,7 @@ QItemSelectionModel::SelectionFlags QAbstractItemViewPrivate::extendedSelectionC
default:
break;
}
+ break;
}
default:
break;
@@ -4431,7 +4470,7 @@ QWidget *QAbstractItemViewPrivate::editor(const QModelIndex &index,
w = delegate->createEditor(viewport, options, index);
if (w) {
w->installEventFilter(delegate);
- QObject::connect(w, SIGNAL(destroyed(QObject*)), q, SLOT(editorDestroyed(QObject*)));
+ QObject::connect(w, &QWidget::destroyed, q, &QAbstractItemView::editorDestroyed);
delegate->updateEditorGeometry(w, options, index);
delegate->setEditorData(w, index);
addEditor(index, w, false);
@@ -4568,6 +4607,9 @@ QModelIndex QAbstractItemViewPrivate::indexForEditor(QWidget *editor) const
void QAbstractItemViewPrivate::removeEditor(QWidget *editor)
{
+ Q_Q(QAbstractItemView);
+ if (editor)
+ QObject::disconnect(editor, &QWidget::destroyed, q, &QAbstractItemView::editorDestroyed);
const auto it = editorIndexHash.constFind(editor);
if (it != editorIndexHash.cend()) {
indexEditorHash.remove(it.value());
@@ -4701,6 +4743,20 @@ QModelIndexList QAbstractItemViewPrivate::selectedDraggableIndexes() const
indexes.removeIf(isNotDragEnabled);
return indexes;
}
+
+void QAbstractItemViewPrivate::maybeStartDrag(QPoint eventPosition)
+{
+ Q_Q(QAbstractItemView);
+
+ const QPoint topLeft = pressedPosition - offset();
+ if ((topLeft - eventPosition).manhattanLength() > QApplication::startDragDistance()) {
+ pressedIndex = QModelIndex();
+ q->startDrag(model->supportedDragActions());
+ q->setState(QAbstractItemView::NoState); // the startDrag will return when the dnd operation
+ // is done
+ q->stopAutoScroll();
+ }
+}
#endif
/*!