summaryrefslogtreecommitdiffstats
path: root/src/widgets/itemviews
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/itemviews')
-rw-r--r--src/widgets/itemviews/qabstractitemdelegate.cpp66
-rw-r--r--src/widgets/itemviews/qabstractitemdelegate.h40
-rw-r--r--src/widgets/itemviews/qabstractitemdelegate_p.h43
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp846
-rw-r--r--src/widgets/itemviews/qabstractitemview.h53
-rw-r--r--src/widgets/itemviews/qabstractitemview_p.h95
-rw-r--r--src/widgets/itemviews/qbsptree.cpp44
-rw-r--r--src/widgets/itemviews/qbsptree_p.h42
-rw-r--r--src/widgets/itemviews/qcolumnview.cpp150
-rw-r--r--src/widgets/itemviews/qcolumnview.h43
-rw-r--r--src/widgets/itemviews/qcolumnview_p.h57
-rw-r--r--src/widgets/itemviews/qcolumnviewgrip.cpp40
-rw-r--r--src/widgets/itemviews/qcolumnviewgrip_p.h40
-rw-r--r--src/widgets/itemviews/qdatawidgetmapper.cpp113
-rw-r--r--src/widgets/itemviews/qdatawidgetmapper.h46
-rw-r--r--src/widgets/itemviews/qfileiconprovider.cpp40
-rw-r--r--src/widgets/itemviews/qfileiconprovider.h40
-rw-r--r--src/widgets/itemviews/qfileiconprovider_p.h40
-rw-r--r--src/widgets/itemviews/qheaderview.cpp353
-rw-r--r--src/widgets/itemviews/qheaderview.h50
-rw-r--r--src/widgets/itemviews/qheaderview_p.h84
-rw-r--r--src/widgets/itemviews/qitemdelegate.cpp96
-rw-r--r--src/widgets/itemviews/qitemdelegate.h40
-rw-r--r--src/widgets/itemviews/qitemeditorfactory.cpp50
-rw-r--r--src/widgets/itemviews/qitemeditorfactory.h40
-rw-r--r--src/widgets/itemviews/qitemeditorfactory_p.h40
-rw-r--r--src/widgets/itemviews/qlistview.cpp206
-rw-r--r--src/widgets/itemviews/qlistview.h40
-rw-r--r--src/widgets/itemviews/qlistview_p.h43
-rw-r--r--src/widgets/itemviews/qlistwidget.cpp289
-rw-r--r--src/widgets/itemviews/qlistwidget.h64
-rw-r--r--src/widgets/itemviews/qlistwidget_p.h65
-rw-r--r--src/widgets/itemviews/qstyleditemdelegate.cpp101
-rw-r--r--src/widgets/itemviews/qstyleditemdelegate.h40
-rw-r--r--src/widgets/itemviews/qtableview.cpp343
-rw-r--r--src/widgets/itemviews/qtableview.h47
-rw-r--r--src/widgets/itemviews/qtableview_p.h74
-rw-r--r--src/widgets/itemviews/qtablewidget.cpp251
-rw-r--r--src/widgets/itemviews/qtablewidget.h74
-rw-r--r--src/widgets/itemviews/qtablewidget_p.h72
-rw-r--r--src/widgets/itemviews/qtreeview.cpp437
-rw-r--r--src/widgets/itemviews/qtreeview.h45
-rw-r--r--src/widgets/itemviews/qtreeview_p.h88
-rw-r--r--src/widgets/itemviews/qtreewidget.cpp285
-rw-r--r--src/widgets/itemviews/qtreewidget.h73
-rw-r--r--src/widgets/itemviews/qtreewidget_p.h69
-rw-r--r--src/widgets/itemviews/qtreewidgetitemiterator.cpp44
-rw-r--r--src/widgets/itemviews/qtreewidgetitemiterator.h40
-rw-r--r--src/widgets/itemviews/qtreewidgetitemiterator_p.h41
-rw-r--r--src/widgets/itemviews/qwidgetitemdata_p.h41
50 files changed, 2136 insertions, 3327 deletions
diff --git a/src/widgets/itemviews/qabstractitemdelegate.cpp b/src/widgets/itemviews/qabstractitemdelegate.cpp
index f675092bd0..23e8ef0901 100644
--- a/src/widgets/itemviews/qabstractitemdelegate.cpp
+++ b/src/widgets/itemviews/qabstractitemdelegate.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qabstractitemdelegate.h"
@@ -117,8 +81,8 @@ QT_BEGIN_NAMESPACE
The second approach is to handle user events directly by reimplementing
editorEvent().
- \sa {model-view-programming}{Model/View Programming}, QStyledItemDelegate,
- {Pixelator Example}, QStyledItemDelegate, QStyle
+ \sa {model-view-programming}{Model/View Programming},
+ QStyledItemDelegate, QStyle
*/
/*!
@@ -380,12 +344,7 @@ bool QAbstractItemDelegate::helpEvent(QHelpEvent *event,
const QString tooltip = index.isValid() ?
d->textForRole(Qt::ToolTipRole, index.data(Qt::ToolTipRole), option.locale, precision) :
QString();
- QRect rect;
- if (index.isValid()) {
- const QRect r = view->visualRect(index);
- rect = QRect(view->mapToGlobal(r.topLeft()), r.size());
- }
- QToolTip::showText(he->globalPos(), tooltip, view, rect);
+ QToolTip::showText(he->globalPos(), tooltip, view->viewport(), option.rect);
event->setAccepted(!tooltip.isEmpty());
break;
}
@@ -521,12 +480,13 @@ bool QAbstractItemDelegatePrivate::editorEventFilter(QObject *object, QEvent *ev
// If the application loses focus while editing, then the focus needs to go back
// to the itemview when the editor closes. This ensures that when the application
// is active again it will have the focus on the itemview as expected.
+ QWidget *editorParent = editor->parentWidget();
const bool manuallyFixFocus = (event->type() == QEvent::FocusOut) && !editor->hasFocus() &&
- editor->parentWidget() &&
+ editorParent &&
(static_cast<QFocusEvent *>(event)->reason() == Qt::ActiveWindowFocusReason);
emit q->closeEditor(editor, QAbstractItemDelegate::NoHint);
if (manuallyFixFocus)
- editor->parentWidget()->setFocus();
+ editorParent->setFocus();
}
#ifndef QT_NO_SHORTCUT
} else if (event->type() == QEvent::ShortcutOverride) {
@@ -554,6 +514,14 @@ bool QAbstractItemDelegatePrivate::tryFixup(QWidget *editor)
return e->hasAcceptableInput();
}
}
+#endif
+#if QT_CONFIG(spinbox)
+ // Give a chance to the spinbox to interpret the text and emit
+ // the appropriate signals before committing data.
+ if (QAbstractSpinBox *sb = qobject_cast<QAbstractSpinBox *>(editor)) {
+ if (!sb->keyboardTracking())
+ sb->interpretText();
+ }
#else
Q_UNUSED(editor);
#endif // QT_CONFIG(lineedit)
@@ -605,7 +573,7 @@ QString QAbstractItemDelegatePrivate::textForRole(Qt::ItemDataRole role, const Q
default: {
text = value.toString();
if (role == Qt::DisplayRole)
- text.replace(QLatin1Char('\n'), QChar::LineSeparator);
+ text.replace(u'\n', QChar::LineSeparator);
break;
}
}
diff --git a/src/widgets/itemviews/qabstractitemdelegate.h b/src/widgets/itemviews/qabstractitemdelegate.h
index 8a4d57fa22..b28a1c4f80 100644
--- a/src/widgets/itemviews/qabstractitemdelegate.h
+++ b/src/widgets/itemviews/qabstractitemdelegate.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QABSTRACTITEMDELEGATE_H
#define QABSTRACTITEMDELEGATE_H
diff --git a/src/widgets/itemviews/qabstractitemdelegate_p.h b/src/widgets/itemviews/qabstractitemdelegate_p.h
index da76d31e8b..e720f4d105 100644
--- a/src/widgets/itemviews/qabstractitemdelegate_p.h
+++ b/src/widgets/itemviews/qabstractitemdelegate_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QABSTRACTITEMDELEGATE_P_H
#define QABSTRACTITEMDELEGATE_P_H
@@ -55,6 +19,9 @@
#include "qabstractitemdelegate.h"
#include <private/qobject_p.h>
+#include <qvariant.h>
+#include <qmetatype.h>
+
QT_REQUIRE_CONFIG(itemviews);
QT_BEGIN_NAMESPACE
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index 6ee9c2c7d1..85e478a71e 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qabstractitemview.h"
@@ -66,7 +30,7 @@
#include <private/qapplication_p.h>
#include <private/qguiapplication_p.h>
#include <private/qscrollbar_p.h>
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
#include <qaccessible.h>
#endif
#if QT_CONFIG(gestures) && QT_CONFIG(scroller)
@@ -87,6 +51,7 @@ QAbstractItemViewPrivate::QAbstractItemViewPrivate()
selectionBehavior(QAbstractItemView::SelectItems),
currentlyCommittingEditor(nullptr),
pressClosedEditor(false),
+ waitForIMCommit(false),
pressedModifiers(Qt::NoModifier),
pressedPosition(QPoint(-1, -1)),
pressedAlreadySelected(false),
@@ -137,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);
@@ -164,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()));
}
@@ -207,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);
@@ -243,6 +209,73 @@ void QAbstractItemViewPrivate::_q_scrollerStateChanged()
#endif // QT_NO_GESTURES
+void QAbstractItemViewPrivate::delegateSizeHintChanged(const QModelIndex &index)
+{
+ Q_Q(QAbstractItemView);
+ if (model) {
+ if (!model->checkIndex(index))
+ qWarning("Delegate size hint changed for a model index that does not belong to this view");
+ }
+ 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
@@ -343,7 +376,7 @@ void QAbstractItemViewPrivate::_q_scrollerStateChanged()
\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
*/
/*!
@@ -656,6 +689,7 @@ QAbstractItemView::~QAbstractItemView()
d->autoScrollTimer.stop();
d->delayedLayout.stop();
d->fetchMoreTimer.stop();
+ d->disconnectAll();
}
/*!
@@ -684,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
@@ -795,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);
@@ -848,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(doItemsLayout()));
- }
+ 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(doItemsLayout()), Qt::QueuedConnection);
- }
+ if (d->delegateRefCount(delegate) == 0)
+ d->connectDelegate(delegate);
}
d->itemDelegate = delegate;
viewport()->update();
@@ -885,10 +889,26 @@ QAbstractItemDelegate *QAbstractItemView::itemDelegate() const
*/
QVariant QAbstractItemView::inputMethodQuery(Qt::InputMethodQuery query) const
{
+ Q_D(const QAbstractItemView);
const QModelIndex current = currentIndex();
- if (!current.isValid() || query != Qt::ImCursorRectangle)
- return QAbstractScrollArea::inputMethodQuery(query);
- return visualRect(current);
+ QVariant result;
+ if (current.isValid()) {
+ if (QWidget *currentEditor;
+ d->waitForIMCommit && (currentEditor = d->editorForIndex(current).widget)) {
+ // An editor is open but the initial preedit is still ongoing. Delegate
+ // queries to the editor and map coordinates from editor to this view.
+ result = currentEditor->inputMethodQuery(query);
+ if (result.typeId() == QMetaType::QRect) {
+ const QRect editorRect = result.value<QRect>();
+ result = QRect(currentEditor->mapTo(this, editorRect.topLeft()), editorRect.size());
+ }
+ } else if (query == Qt::ImCursorRectangle) {
+ result = visualRect(current);
+ }
+ }
+ if (!result.isValid())
+ result = QAbstractScrollArea::inputMethodQuery(query);
+ return result;
}
/*!
@@ -916,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(doItemsLayout()));
- }
+ 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(doItemsLayout()), Qt::QueuedConnection);
- }
+ if (d->delegateRefCount(delegate) == 0)
+ d->connectDelegate(delegate);
d->rowDelegates.insert(row, delegate);
}
viewport()->update();
@@ -976,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(doItemsLayout()));
- }
+ 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(doItemsLayout()), Qt::QueuedConnection);
- }
+ if (d->delegateRefCount(delegate) == 0)
+ d->connectDelegate(delegate);
d->columnDelegates.insert(column, delegate);
}
viewport()->update();
@@ -1128,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()));
}
@@ -1140,7 +1148,7 @@ void QAbstractItemView::reset()
setRootIndex(QModelIndex());
if (d->selectionModel)
d->selectionModel->reset();
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
if (QAccessible::isActive()) {
QAccessibleTableModelChangeEvent accessibleEvent(this, QAccessibleTableModelChangeEvent::ModelReset);
QAccessible::updateAccessibility(&accessibleEvent);
@@ -1162,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();
}
@@ -1187,12 +1201,21 @@ QModelIndex QAbstractItemView::rootIndex() const
void QAbstractItemView::selectAll()
{
Q_D(QAbstractItemView);
- SelectionMode mode = d->selectionMode;
- if (mode == MultiSelection || mode == ExtendedSelection)
+ const SelectionMode mode = d->selectionMode;
+ switch (mode) {
+ case MultiSelection:
+ case ExtendedSelection:
d->selectAll(QItemSelectionModel::ClearAndSelect
- |d->selectionBehaviorFlags());
- else if (mode != SingleSelection)
- d->selectAll(selectionCommand(d->model->index(0, 0, d->root)));
+ | d->selectionBehaviorFlags());
+ break;
+ case NoSelection:
+ case ContiguousSelection:
+ if (d->model->hasChildren(d->root))
+ d->selectAll(selectionCommand(d->model->index(0, 0, d->root)));
+ break;
+ case SingleSelection:
+ break;
+ }
}
/*!
@@ -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())
@@ -1709,6 +1732,12 @@ bool QAbstractItemView::viewportEvent(QEvent *event)
{
Q_D(QAbstractItemView);
switch (event->type()) {
+ case QEvent::Paint:
+ // Similar to pre-painting in QAbstractItemView::event to update scrollbar
+ // visibility, make sure that all pending layout requests have been executed
+ // so that the view's data structures are up-to-date before rendering.
+ d->executePostedLayout();
+ break;
case QEvent::HoverMove:
case QEvent::HoverEnter:
d->setHoverIndex(indexAt(static_cast<QHoverEvent*>(event)->position().toPoint()));
@@ -1756,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;
@@ -1774,6 +1806,7 @@ bool QAbstractItemView::viewportEvent(QEvent *event)
void QAbstractItemView::mousePressEvent(QMouseEvent *event)
{
Q_D(QAbstractItemView);
+ d->releaseFromDoubleClick = false;
d->delayedAutoScroll.stop(); //any interaction with the view cancel the auto scrolling
QPoint pos = event->position().toPoint();
QPersistentModelIndex index = indexAt(pos);
@@ -1781,8 +1814,7 @@ void QAbstractItemView::mousePressEvent(QMouseEvent *event)
// this is the mouse press event that closed the last editor (via focus event)
d->pressClosedEditor = d->pressClosedEditorWatcher.isActive() && d->lastEditedIndex == index;
- if (!d->selectionModel
- || (d->state == EditingState && d->hasEditor(index)))
+ if (!d->selectionModel || (d->state == EditingState && d->hasEditor(index)))
return;
d->pressedAlreadySelected = d->selectionModel->isSelected(index);
@@ -1791,8 +1823,16 @@ void QAbstractItemView::mousePressEvent(QMouseEvent *event)
QItemSelectionModel::SelectionFlags command = selectionCommand(index, event);
d->noSelectionOnMousePress = command == QItemSelectionModel::NoUpdate || !index.isValid();
QPoint offset = d->offset();
- d->pressedPosition = pos + offset;
- if ((command & QItemSelectionModel::Current) == 0) {
+ d->draggedPosition = pos + offset;
+
+#if QT_CONFIG(draganddrop)
+ // update the pressed position when drag was enable
+ if (d->dragEnabled)
+ d->pressedPosition = d->draggedPosition;
+#endif
+
+ if (!(command & QItemSelectionModel::Current)) {
+ d->pressedPosition = pos + offset;
d->currentSelectionStartIndex = index;
}
else if (!d->currentSelectionStartIndex.isValid())
@@ -1814,7 +1854,7 @@ void QAbstractItemView::mousePressEvent(QMouseEvent *event)
command |= d->ctrlDragSelectionFlag;
}
- if ((command & QItemSelectionModel::Current) == 0) {
+ if (!(command & QItemSelectionModel::Current)) {
setSelection(QRect(pos, QSize(1, 1)), command);
} else {
QRect rect(visualRect(d->currentSelectionStartIndex).center(), pos);
@@ -1843,21 +1883,16 @@ 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();
+
if (state() == ExpandingState || state() == CollapsingState)
return;
#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)
@@ -1868,16 +1903,8 @@ void QAbstractItemView::mouseMoveEvent(QMouseEvent *event)
|| edit(index, NoEditTriggers, event))
return;
- if (d->selectionMode != SingleSelection) {
- // Use the current selection start index if it is valid as this will be based on the
- // start of the selection and not the last item being pressed which can be different
- // when in extended selection
- topLeft = d->currentSelectionStartIndex.isValid()
- ? visualRect(d->currentSelectionStartIndex).center()
- : d->pressedPosition - d->offset();
- } else {
- topLeft = bottomRight;
- }
+ const QPoint topLeft =
+ d->selectionMode != SingleSelection ? d->pressedPosition - d->offset() : bottomRight;
d->checkMouseMove(index);
@@ -1888,6 +1915,7 @@ void QAbstractItemView::mouseMoveEvent(QMouseEvent *event)
&& (event->buttons() != Qt::NoButton)
&& !d->selectedDraggableIndexes().isEmpty()) {
setState(DraggingState);
+ d->maybeStartDrag(bottomRight);
return;
}
#endif
@@ -1905,10 +1933,10 @@ void QAbstractItemView::mouseMoveEvent(QMouseEvent *event)
setSelection(selectionRect, command);
// set at the end because it might scroll the view
- if (index.isValid()
- && (index != d->selectionModel->currentIndex())
- && d->isIndexEnabled(index))
+ if (index.isValid() && (index != d->selectionModel->currentIndex()) && d->isIndexEnabled(index))
d->selectionModel->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
+ else if (d->shouldAutoScroll(event->pos()) && !d->autoScrollTimer.isActive())
+ startAutoScroll();
}
}
@@ -1937,7 +1965,9 @@ void QAbstractItemView::mouseReleaseEvent(QMouseEvent *event)
}
bool click = (index == d->pressedIndex && index.isValid() && !releaseFromDoubleClick);
- bool selectedClicked = click && (event->button() == Qt::LeftButton) && d->pressedAlreadySelected;
+ bool selectedClicked = click && d->pressedAlreadySelected
+ && (event->button() == Qt::LeftButton)
+ && (event->modifiers() == Qt::NoModifier);
EditTrigger trigger = (selectedClicked ? SelectedClicked : NoEditTriggers);
const bool edited = click && !d->pressClosedEditor ? edit(index, trigger, event) : false;
@@ -1945,7 +1975,7 @@ void QAbstractItemView::mouseReleaseEvent(QMouseEvent *event)
if (d->selectionModel && d->noSelectionOnMousePress) {
d->noSelectionOnMousePress = false;
- if (!edited && !d->pressClosedEditor)
+ if (!d->pressClosedEditor)
d->selectionModel->select(index, selectionCommand(index, event));
}
@@ -2030,6 +2060,7 @@ void QAbstractItemView::dragEnterEvent(QDragEnterEvent *event)
void QAbstractItemView::dragMoveEvent(QDragMoveEvent *event)
{
Q_D(QAbstractItemView);
+ d->draggedPosition = event->position().toPoint() + d->offset();
if (dragDropMode() == InternalMove
&& (event->source() != this || !(event->possibleActions() & Qt::MoveAction)))
return;
@@ -2363,11 +2394,12 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event)
#if !defined(QT_NO_CLIPBOARD) && !defined(QT_NO_SHORTCUT)
if (event == QKeySequence::Copy) {
- QVariant variant;
- if (d->model)
- variant = d->model->data(currentIndex(), Qt::DisplayRole);
- if (variant.canConvert<QString>())
- QGuiApplication::clipboard()->setText(variant.toString());
+ const QModelIndex index = currentIndex();
+ if (index.isValid() && d->model) {
+ const QVariant variant = d->model->data(index, Qt::DisplayRole);
+ if (variant.canConvert<QString>())
+ QGuiApplication::clipboard()->setText(variant.toString());
+ }
event->accept();
}
#endif
@@ -2506,7 +2538,7 @@ void QAbstractItemView::keyPressEvent(QKeyEvent *event)
break;
case Qt::Key_Enter:
case Qt::Key_Return:
- // ### we can't open the editor on enter, becuse
+ // ### we can't open the editor on enter, because
// some widgets will forward the enter event back
// to the viewport, starting an endless loop
if (state() != EditingState || hasFocus()) {
@@ -2599,14 +2631,53 @@ void QAbstractItemView::timerEvent(QTimerEvent *event)
*/
void QAbstractItemView::inputMethodEvent(QInputMethodEvent *event)
{
- if (event->commitString().isEmpty() && event->preeditString().isEmpty()) {
+ Q_D(QAbstractItemView);
+ // When QAbstractItemView::AnyKeyPressed is used, a new IM composition might
+ // start before the editor widget acquires focus. Changing focus would interrupt
+ // the composition, so we keep focus on the view until that first composition
+ // is complete, and pass QInputMethoEvents on to the editor widget so that the
+ // user gets the expected feedback. See also inputMethodQuery, which redirects
+ // calls to the editor widget during that period.
+ bool forwardEventToEditor = false;
+ const bool commit = !event->commitString().isEmpty();
+ const bool preediting = !event->preeditString().isEmpty();
+ if (QWidget *currentEditor = d->editorForIndex(currentIndex()).widget) {
+ if (d->waitForIMCommit) {
+ if (commit || !preediting) {
+ // commit or cancel
+ d->waitForIMCommit = false;
+ QApplication::sendEvent(currentEditor, event);
+ if (!commit) {
+ QAbstractItemDelegate *delegate = itemDelegateForIndex(currentIndex());
+ if (delegate)
+ delegate->setEditorData(currentEditor, currentIndex());
+ d->selectAllInEditor(currentEditor);
+ }
+ if (currentEditor->focusPolicy() != Qt::NoFocus)
+ currentEditor->setFocus();
+ } else {
+ // more pre-editing
+ QApplication::sendEvent(currentEditor, event);
+ }
+ return;
+ }
+ } else if (preediting) {
+ // don't set focus when the editor opens
+ d->waitForIMCommit = true;
+ // but pass preedit on to editor
+ forwardEventToEditor = true;
+ } else if (!commit) {
event->ignore();
return;
}
if (!edit(currentIndex(), AnyKeyPressed, event)) {
- if (!event->commitString().isEmpty())
+ d->waitForIMCommit = false;
+ if (commit)
keyboardSearch(event->commitString());
event->ignore();
+ } else if (QWidget *currentEditor; forwardEventToEditor
+ && (currentEditor = d->editorForIndex(currentIndex()).widget)) {
+ QApplication::sendEvent(currentEditor, event);
}
}
@@ -2685,7 +2756,10 @@ bool QAbstractItemView::edit(const QModelIndex &index, EditTrigger trigger, QEve
if (QWidget *w = (d->persistent.isEmpty() ? static_cast<QWidget*>(nullptr) : d->editorForIndex(index).widget.data())) {
if (w->focusPolicy() == Qt::NoFocus)
return false;
- w->setFocus();
+ if (!d->waitForIMCommit)
+ w->setFocus();
+ else
+ updateMicroFocus();
return true;
}
@@ -2696,16 +2770,23 @@ bool QAbstractItemView::edit(const QModelIndex &index, EditTrigger trigger, QEve
d->delayedEditing.stop();
}
+ // in case e.g. setData() triggers a reset()
+ QPersistentModelIndex safeIndex(index);
+
if (d->sendDelegateEvent(index, event)) {
- update(index);
+ update(safeIndex);
return true;
}
+ if (!safeIndex.isValid()) {
+ return false;
+ }
+
// save the previous trigger before updating
EditTriggers lastTrigger = d->lastTrigger;
d->lastTrigger = trigger;
- if (!d->shouldEdit(trigger, d->model->buddy(index)))
+ if (!d->shouldEdit(trigger, d->model->buddy(safeIndex)))
return false;
if (d->delayedEditing.isActive())
@@ -2720,7 +2801,7 @@ bool QAbstractItemView::edit(const QModelIndex &index, EditTrigger trigger, QEve
if (trigger == SelectedClicked)
d->delayedEditing.start(QApplication::doubleClickInterval(), this);
else
- d->openEditor(index, d->shouldForwardEvent(trigger, event) ? event : nullptr);
+ d->openEditor(safeIndex, d->shouldForwardEvent(trigger, event) ? event : nullptr);
return true;
}
@@ -2777,10 +2858,10 @@ void QAbstractItemView::updateEditorGeometries()
//we hide and release the editor outside of the loop because it might change the focus and try
//to change the editors hashes.
- for (int i = 0; i < editorsToHide.count(); ++i) {
+ for (int i = 0; i < editorsToHide.size(); ++i) {
editorsToHide.at(i)->hide();
}
- for (int i = 0; i < editorsToRelease.count(); ++i) {
+ for (int i = 0; i < editorsToRelease.size(); ++i) {
d->releaseEditor(editorsToRelease.at(i));
}
}
@@ -2855,39 +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);
- if (!index.isValid())
- 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();
+ const bool isPersistent = d->persistent.contains(editor);
+ const QModelIndex index = d->indexForEditor(editor);
+ if (!index.isValid()) {
+ 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
@@ -2937,8 +3029,10 @@ void QAbstractItemView::commitData(QWidget *editor)
if (!editor || !d->itemDelegate || d->currentlyCommittingEditor)
return;
QModelIndex index = d->indexForEditor(editor);
- if (!index.isValid())
+ if (!index.isValid()) {
+ qWarning("QAbstractItemView::commitData called with an editor that does not belong to this view");
return;
+ }
d->currentlyCommittingEditor = editor;
QAbstractItemDelegate *delegate = itemDelegateForIndex(index);
editor->removeEventFilter(delegate);
@@ -2997,9 +3091,9 @@ void QAbstractItemView::keyboardSearch(const QString &search)
// special case for searches with same key like 'aaaaa'
bool sameKey = false;
- if (d->keyboardInput.length() > 1) {
- int c = d->keyboardInput.count(d->keyboardInput.at(d->keyboardInput.length() - 1));
- sameKey = (c == d->keyboardInput.length());
+ if (d->keyboardInput.size() > 1) {
+ int c = d->keyboardInput.count(d->keyboardInput.at(d->keyboardInput.size() - 1));
+ sameKey = (c == d->keyboardInput.size());
if (sameKey)
skipRow = true;
}
@@ -3287,8 +3381,8 @@ void QAbstractItemView::update(const QModelIndex &index)
{
Q_D(QAbstractItemView);
if (index.isValid()) {
- const QRect rect = visualRect(index);
- //this test is important for peformance reason
+ 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
if (d->viewport->rect().intersects(rect))
@@ -3342,7 +3436,7 @@ void QAbstractItemView::dataChanged(const QModelIndex &topLeft, const QModelInde
}
}
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
if (QAccessible::isActive()) {
QAccessibleTableModelChangeEvent accessibleEvent(this, QAccessibleTableModelChangeEvent::DataChanged);
accessibleEvent.setFirstRow(topLeft.row());
@@ -3400,24 +3494,59 @@ void QAbstractItemView::rowsAboutToBeRemoved(const QModelIndex &parent, int star
} else {
int row = end + 1;
QModelIndex next;
- do { // find the next visible and enabled item
+ const int rowCount = d->model->rowCount(parent);
+ bool found = false;
+ // find the next visible and enabled item
+ while (row < rowCount && !found) {
next = d->model->index(row++, current.column(), current.parent());
- } while (next.isValid() && (isIndexHidden(next) || !d->isIndexEnabled(next)));
- if (row > d->model->rowCount(parent)) {
+#ifdef QT_DEBUG
+ if (!next.isValid()) {
+ qWarning("Model unexpectedly returned an invalid index");
+ break;
+ }
+#endif
+ if (!isIndexHidden(next) && d->isIndexEnabled(next)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
row = start - 1;
- do { // find the previous visible and enabled item
+ // find the previous visible and enabled item
+ while (row >= 0) {
next = d->model->index(row--, current.column(), current.parent());
- } while (next.isValid() && (isIndexHidden(next) || !d->isIndexEnabled(next)));
+#ifdef QT_DEBUG
+ if (!next.isValid()) {
+ qWarning("Model unexpectedly returned an invalid index");
+ break;
+ }
+#endif
+ if (!isIndexHidden(next) && d->isIndexEnabled(next))
+ break;
+ }
}
+
setCurrentIndex(next);
}
}
// 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);
@@ -3436,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);
@@ -3446,7 +3575,7 @@ void QAbstractItemViewPrivate::_q_rowsRemoved(const QModelIndex &index, int star
if (q->isVisible())
q->updateEditorGeometries();
q->setState(QAbstractItemView::NoState);
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
if (QAccessible::isActive()) {
QAccessibleTableModelChangeEvent accessibleEvent(q, QAccessibleTableModelChangeEvent::RowsRemoved);
accessibleEvent.setFirstRow(start);
@@ -3464,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);
@@ -3486,9 +3615,19 @@ void QAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &par
} else {
int column = end;
QModelIndex next;
- do { // find the next visible and enabled item
+ const int columnCount = model->columnCount(current.parent());
+ // find the next visible and enabled item
+ while (column < columnCount) {
next = model->index(current.row(), column++, current.parent());
- } while (next.isValid() && (q->isIndexHidden(next) || !isIndexEnabled(next)));
+#ifdef QT_DEBUG
+ if (!next.isValid()) {
+ qWarning("Model unexpectedly returned an invalid index");
+ break;
+ }
+#endif
+ if (!q->isIndexHidden(next) && isIndexEnabled(next))
+ break;
+ }
q->setCurrentIndex(next);
}
}
@@ -3517,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);
@@ -3527,7 +3666,7 @@ void QAbstractItemViewPrivate::_q_columnsRemoved(const QModelIndex &index, int s
if (q->isVisible())
q->updateEditorGeometries();
q->setState(QAbstractItemView::NoState);
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
if (QAccessible::isActive()) {
QAccessibleTableModelChangeEvent accessibleEvent(q, QAccessibleTableModelChangeEvent::ColumnsRemoved);
accessibleEvent.setFirstColumn(start);
@@ -3544,13 +3683,13 @@ 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);
Q_UNUSED(end);
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
Q_Q(QAbstractItemView);
if (QAccessible::isActive()) {
QAccessibleTableModelChangeEvent accessibleEvent(q, QAccessibleTableModelChangeEvent::RowsInserted);
@@ -3567,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);
@@ -3576,7 +3715,7 @@ void QAbstractItemViewPrivate::_q_columnsInserted(const QModelIndex &index, int
Q_Q(QAbstractItemView);
if (q->isVisible())
q->updateEditorGeometries();
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
if (QAccessible::isActive()) {
QAccessibleTableModelChangeEvent accessibleEvent(q, QAccessibleTableModelChangeEvent::ColumnsInserted);
accessibleEvent.setFirstColumn(start);
@@ -3590,7 +3729,7 @@ void QAbstractItemViewPrivate::_q_columnsInserted(const QModelIndex &index, int
/*!
\internal
*/
-void QAbstractItemViewPrivate::_q_modelDestroyed()
+void QAbstractItemViewPrivate::modelDestroyed()
{
model = QAbstractItemModelPrivate::staticEmptyModel();
doDelayedReset();
@@ -3601,10 +3740,10 @@ void QAbstractItemViewPrivate::_q_modelDestroyed()
This slot is called when the layout is changed.
*/
-void QAbstractItemViewPrivate::_q_layoutChanged()
+void QAbstractItemViewPrivate::layoutChanged()
{
doDelayedItemsLayout();
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
Q_Q(QAbstractItemView);
if (QAccessible::isActive()) {
QAccessibleTableModelChangeEvent accessibleEvent(q, QAccessibleTableModelChangeEvent::ModelReset);
@@ -3613,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
@@ -3703,7 +3842,7 @@ void QAbstractItemView::startDrag(Qt::DropActions supportedActions)
{
Q_D(QAbstractItemView);
QModelIndexList indexes = d->selectedDraggableIndexes();
- if (indexes.count() > 0) {
+ if (indexes.size() > 0) {
QMimeData *data = d->model->mimeData(indexes);
if (!data)
return;
@@ -3914,17 +4053,17 @@ void QAbstractItemView::doAutoScroll()
}
}
- int verticalStep = verticalScroll->pageStep();
- int horizontalStep = horizontalScroll->pageStep();
+ const int verticalStep = verticalScroll->pageStep();
+ const int horizontalStep = horizontalScroll->pageStep();
if (d->autoScrollCount < qMax(verticalStep, horizontalStep))
++d->autoScrollCount;
- int margin = d->autoScrollMargin;
- int verticalValue = verticalScroll->value();
- int horizontalValue = horizontalScroll->value();
+ const int margin = d->autoScrollMargin;
+ const int verticalValue = verticalScroll->value();
+ const int horizontalValue = horizontalScroll->value();
- QPoint pos = d->viewport->mapFromGlobal(QCursor::pos());
- QRect area = QWidgetPrivate::get(d->viewport)->clipRect();
+ const QPoint pos = d->draggedPosition - d->offset();
+ const QRect area = QWidgetPrivate::get(d->viewport)->clipRect();
// do the scrolling if we are in the scroll margins
if (pos.y() - area.top() < margin)
@@ -3936,8 +4075,8 @@ void QAbstractItemView::doAutoScroll()
else if (area.right() - pos.x() < margin)
horizontalScroll->setValue(horizontalValue + d->autoScrollCount);
// if nothing changed, stop scrolling
- bool verticalUnchanged = (verticalValue == verticalScroll->value());
- bool horizontalUnchanged = (horizontalValue == horizontalScroll->value());
+ const bool verticalUnchanged = (verticalValue == verticalScroll->value());
+ const bool horizontalUnchanged = (horizontalValue == horizontalScroll->value());
if (verticalUnchanged && horizontalUnchanged) {
stopAutoScroll();
} else {
@@ -3945,14 +4084,39 @@ void QAbstractItemView::doAutoScroll()
d->dropIndicatorRect = QRect();
d->dropIndicatorPosition = QAbstractItemView::OnViewport;
#endif
+ switch (state()) {
+ case QAbstractItemView::DragSelectingState: {
+ // mouseMoveEvent updates the drag-selection rectangle, so fake an event. This also
+ // updates draggedPosition taking the now scrolled viewport into account.
+ const QPoint globalPos = d->viewport->mapToGlobal(pos);
+ const QPoint windowPos = window()->mapFromGlobal(globalPos);
+ QMouseEvent mm(QEvent::MouseMove, pos, windowPos, globalPos,
+ Qt::NoButton, Qt::LeftButton, d->pressedModifiers,
+ Qt::MouseEventSynthesizedByQt);
+ QApplication::sendEvent(viewport(), &mm);
+ break;
+ }
+ case QAbstractItemView::DraggingState: {
+ // we can't simulate mouse (it would throw off the drag'n'drop state logic) or drag
+ // (we don't have the mime data or the actions) move events during drag'n'drop, so
+ // update our dragged position manually after the scroll. "pos" is the old
+ // draggedPosition - d->offset(), and d->offset() is now updated after scrolling, so
+ // pos + d->offset() gives us the new position.
+ d->draggedPosition = pos + d->offset();
+ break;
+ }
+ default:
+ break;
+ }
d->viewport->update();
}
}
/*!
- Returns the SelectionFlags to be used when updating a selection with
- to include the \a index specified. The \a event is a user input event,
- such as a mouse or keyboard event.
+ Returns the SelectionFlags to be used when updating a selection model
+ for the specified \a index. The result depends on the current
+ selectionMode(), and on the user input event \a event, which can be
+ \nullptr.
Reimplement this function to define your own selection behavior.
@@ -3969,12 +4133,28 @@ QItemSelectionModel::SelectionFlags QAbstractItemView::selectionCommand(const QM
case NoSelection: // Never update selection model
return QItemSelectionModel::NoUpdate;
case SingleSelection: // ClearAndSelect on valid index otherwise NoUpdate
- if (event && event->type() == QEvent::MouseButtonRelease)
- return QItemSelectionModel::NoUpdate;
- if ((keyModifiers & Qt::ControlModifier) && d->selectionModel->isSelected(index) && event->type() != QEvent::MouseMove)
- return QItemSelectionModel::Deselect | d->selectionBehaviorFlags();
- else
- return QItemSelectionModel::ClearAndSelect | d->selectionBehaviorFlags();
+ if (event) {
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ // press with any modifiers on a selected item does nothing
+ if (d->pressedAlreadySelected)
+ return QItemSelectionModel::NoUpdate;
+ break;
+ case QEvent::MouseButtonRelease:
+ // clicking into area with no items does nothing
+ if (!index.isValid())
+ return QItemSelectionModel::NoUpdate;
+ Q_FALLTHROUGH();
+ case QEvent::KeyPress:
+ // ctrl-release on selected item deselects
+ if ((keyModifiers & Qt::ControlModifier) && d->selectionModel->isSelected(index))
+ return QItemSelectionModel::Deselect | d->selectionBehaviorFlags();
+ break;
+ default:
+ break;
+ }
+ }
+ return QItemSelectionModel::ClearAndSelect | d->selectionBehaviorFlags();
case MultiSelection:
return d->multiSelectionCommand(index, event);
case ExtendedSelection:
@@ -4000,13 +4180,21 @@ QItemSelectionModel::SelectionFlags QAbstractItemViewPrivate::multiSelectionComm
case QEvent::MouseButtonPress:
if (static_cast<const QMouseEvent*>(event)->button() == Qt::LeftButton) {
// since the press might start a drag, deselect only on release
- if (!pressedAlreadySelected || !dragEnabled || !isIndexDragEnabled(index))
+ if (!pressedAlreadySelected
+#if QT_CONFIG(draganddrop)
+ || !dragEnabled || !isIndexDragEnabled(index)
+#endif
+ )
return QItemSelectionModel::Toggle|selectionBehaviorFlags(); // toggle
}
break;
case QEvent::MouseButtonRelease:
if (static_cast<const QMouseEvent*>(event)->button() == Qt::LeftButton) {
- if (pressedAlreadySelected && dragEnabled && isIndexDragEnabled(index) && index == pressedIndex)
+ if (pressedAlreadySelected
+#if QT_CONFIG(draganddrop)
+ && dragEnabled && isIndexDragEnabled(index)
+#endif
+ && index == pressedIndex)
return QItemSelectionModel::Toggle|selectionBehaviorFlags();
return QItemSelectionModel::NoUpdate|selectionBehaviorFlags(); // finalize
}
@@ -4054,7 +4242,10 @@ QItemSelectionModel::SelectionFlags QAbstractItemViewPrivate::extendedSelectionC
return QItemSelectionModel::NoUpdate;
// since the press might start a drag, deselect only on release
if (controlKeyPressed && !rightButtonPressed && pressedAlreadySelected
- && dragEnabled && isIndexDragEnabled(index)) {
+#if QT_CONFIG(draganddrop)
+ && dragEnabled && isIndexDragEnabled(index)
+#endif
+ ) {
return QItemSelectionModel::NoUpdate;
}
break;
@@ -4070,7 +4261,10 @@ QItemSelectionModel::SelectionFlags QAbstractItemViewPrivate::extendedSelectionC
&& !shiftKeyPressed && !controlKeyPressed && (!rightButtonPressed || !index.isValid()))
return QItemSelectionModel::ClearAndSelect|selectionBehaviorFlags();
if (index == pressedIndex && controlKeyPressed && !rightButtonPressed
- && dragEnabled && isIndexDragEnabled(index)) {
+#if QT_CONFIG(draganddrop)
+ && dragEnabled && isIndexDragEnabled(index)
+#endif
+ ) {
break;
}
return QItemSelectionModel::NoUpdate;
@@ -4107,6 +4301,7 @@ QItemSelectionModel::SelectionFlags QAbstractItemViewPrivate::extendedSelectionC
default:
break;
}
+ break;
}
default:
break;
@@ -4241,6 +4436,28 @@ void QAbstractItemViewPrivate::updateGeometry()
q->updateGeometry();
}
+/*
+ Handles selection of content for some editors containing QLineEdit.
+
+ ### Qt 7 This should be done by a virtual method in QAbstractItemDelegate.
+*/
+void QAbstractItemViewPrivate::selectAllInEditor(QWidget *editor)
+{
+ while (QWidget *fp = editor->focusProxy())
+ editor = fp;
+
+#if QT_CONFIG(lineedit)
+ if (QLineEdit *le = qobject_cast<QLineEdit*>(editor))
+ le->selectAll();
+#endif
+#if QT_CONFIG(spinbox)
+ if (QSpinBox *sb = qobject_cast<QSpinBox*>(editor))
+ sb->selectAll();
+ else if (QDoubleSpinBox *dsb = qobject_cast<QDoubleSpinBox*>(editor))
+ dsb->selectAll();
+#endif
+}
+
QWidget *QAbstractItemViewPrivate::editor(const QModelIndex &index,
const QStyleOptionViewItem &options)
{
@@ -4253,27 +4470,14 @@ 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);
if (w->parent() == viewport)
QWidget::setTabOrder(q, w);
- // Special cases for some editors containing QLineEdit
- QWidget *focusWidget = w;
- while (QWidget *fp = focusWidget->focusProxy())
- focusWidget = fp;
-#if QT_CONFIG(lineedit)
- if (QLineEdit *le = qobject_cast<QLineEdit*>(focusWidget))
- le->selectAll();
-#endif
-#if QT_CONFIG(spinbox)
- if (QSpinBox *sb = qobject_cast<QSpinBox*>(focusWidget))
- sb->selectAll();
- else if (QDoubleSpinBox *dsb = qobject_cast<QDoubleSpinBox*>(focusWidget))
- dsb->selectAll();
-#endif
+ selectAllInEditor(w);
}
}
@@ -4313,7 +4517,7 @@ void QAbstractItemViewPrivate::updateEditorData(const QModelIndex &tl, const QMo
In DND if something has been moved then this is called.
Typically this means you should "remove" the selected item or row,
- but the behavior is view dependant (table just clears the selected indexes for example).
+ but the behavior is view-dependent (table just clears the selected indexes for example).
Either remove the selected rows or clear them
*/
@@ -4403,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());
@@ -4444,7 +4651,10 @@ bool QAbstractItemViewPrivate::openEditor(const QModelIndex &index, QEvent *even
q->setState(QAbstractItemView::EditingState);
w->show();
- w->setFocus();
+ if (!waitForIMCommit)
+ w->setFocus();
+ else
+ q->updateMicroFocus();
if (event)
QCoreApplication::sendEvent(w->focusProxy() ? w->focusProxy() : w, event);
@@ -4497,7 +4707,7 @@ QPixmap QAbstractItemViewPrivate::renderToPixmap(const QModelIndexList &indexes,
QStyleOptionViewItem option;
q->initViewItemOption(&option);
option.state |= QStyle::State_Selected;
- for (int j = 0; j < paintPairs.count(); ++j) {
+ for (int j = 0; j < paintPairs.size(); ++j) {
option.rect = paintPairs.at(j).rect.translated(-r->topLeft());
const QModelIndex &current = paintPairs.at(j).index;
adjustViewOptionsForIndex(&option, current);
@@ -4510,6 +4720,8 @@ void QAbstractItemViewPrivate::selectAll(QItemSelectionModel::SelectionFlags com
{
if (!selectionModel)
return;
+ if (!model->hasChildren(root))
+ return;
QItemSelection selection;
QModelIndex tl = model->index(0, 0, root);
@@ -4520,6 +4732,7 @@ void QAbstractItemViewPrivate::selectAll(QItemSelectionModel::SelectionFlags com
selectionModel->select(selection, command);
}
+#if QT_CONFIG(draganddrop)
QModelIndexList QAbstractItemViewPrivate::selectedDraggableIndexes() const
{
Q_Q(const QAbstractItemView);
@@ -4531,6 +4744,21 @@ QModelIndexList QAbstractItemViewPrivate::selectedDraggableIndexes() const
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
+
/*!
\reimp
*/
diff --git a/src/widgets/itemviews/qabstractitemview.h b/src/widgets/itemviews/qabstractitemview.h
index a33aff2e2d..837419100a 100644
--- a/src/widgets/itemviews/qabstractitemview.h
+++ b/src/widgets/itemviews/qabstractitemview.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QABSTRACTITEMVIEW_H
#define QABSTRACTITEMVIEW_H
@@ -362,19 +326,6 @@ protected:
private:
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))
- Q_PRIVATE_SLOT(d_func(), void _q_columnsInserted(const QModelIndex&, int, int))
- Q_PRIVATE_SLOT(d_func(), void _q_rowsInserted(const QModelIndex&, int, int))
- Q_PRIVATE_SLOT(d_func(), void _q_rowsRemoved(const QModelIndex&, int, int))
- Q_PRIVATE_SLOT(d_func(), void _q_columnsMoved(const QModelIndex&, int, int, const QModelIndex&, int))
- Q_PRIVATE_SLOT(d_func(), void _q_rowsMoved(const QModelIndex&, int, int, const QModelIndex&, int))
- Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed())
- Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged())
- Q_PRIVATE_SLOT(d_func(), void _q_headerDataChanged())
-#if QT_CONFIG(gestures) && QT_CONFIG(scroller)
- Q_PRIVATE_SLOT(d_func(), void _q_scrollerStateChanged())
-#endif
friend class ::tst_QAbstractItemView;
friend class ::tst_QTreeView;
diff --git a/src/widgets/itemviews/qabstractitemview_p.h b/src/widgets/itemviews/qabstractitemview_p.h
index f45d642dcf..433429f48b 100644
--- a/src/widgets/itemviews/qabstractitemview_p.h
+++ b/src/widgets/itemviews/qabstractitemview_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QABSTRACTITEMVIEW_P_H
#define QABSTRACTITEMVIEW_P_H
@@ -52,17 +16,22 @@
//
#include <QtWidgets/private/qtwidgetsglobal_p.h>
+#include "qabstractitemview.h"
#include "private/qabstractscrollarea_p.h"
#include "private/qabstractitemmodel_p.h"
#include "QtWidgets/qapplication.h"
#include "QtGui/qevent.h"
#include "QtCore/qmimedata.h"
#include "QtGui/qpainter.h"
-#include "QtCore/qpair.h"
#include "QtGui/qregion.h"
+
#include "QtCore/qdebug.h"
#include "QtCore/qbasictimer.h"
#include "QtCore/qelapsedtimer.h"
+#include <QtCore/qpointer.h>
+
+
+#include <array>
QT_REQUIRE_CONFIG(itemviews);
@@ -99,19 +68,20 @@ public:
void init();
- virtual void _q_rowsRemoved(const QModelIndex &parent, int start, int end);
- virtual void _q_rowsInserted(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();
- virtual void _q_rowsMoved(const QModelIndex &source, int sourceStart, int sourceEnd, const QModelIndex &destination, int destinationStart);
- virtual void _q_columnsMoved(const QModelIndex &source, int sourceStart, int sourceEnd, const QModelIndex &destination, int destinationStart);
+ virtual void rowsRemoved(const QModelIndex &parent, int start, int end);
+ virtual void rowsInserted(const QModelIndex &parent, int start, int end);
+ virtual void columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
+ virtual void columnsRemoved(const QModelIndex &parent, int start, int end);
+ virtual void columnsInserted(const QModelIndex &parent, int start, int end);
+ virtual void modelDestroyed();
+ virtual void layoutChanged();
+ virtual void rowsMoved(const QModelIndex &source, int sourceStart, int sourceEnd, const QModelIndex &destination, int destinationStart);
+ virtual void columnsMoved(const QModelIndex &source, int sourceStart, int sourceEnd, const QModelIndex &destination, int destinationStart);
virtual QRect intersectedRect(const QRect rect, const QModelIndex &topLeft, const QModelIndex &bottomRight) const;
- void _q_headerDataChanged() { doDelayedItemsLayout(); }
- void _q_scrollerStateChanged();
+ void headerDataChanged() { doDelayedItemsLayout(); }
+ void scrollerStateChanged();
+ void delegateSizeHintChanged(const QModelIndex &index);
void fetchMore();
@@ -140,6 +110,7 @@ public:
bool sendDelegateEvent(const QModelIndex &index, QEvent *event) const;
bool openEditor(const QModelIndex &index, QEvent *event);
void updateEditorData(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ void selectAllInEditor(QWidget *w);
QItemSelectionModel::SelectionFlags multiSelectionCommand(const QModelIndex &index,
const QEvent *event) const;
@@ -212,8 +183,8 @@ public:
inline void releaseEditor(QWidget *editor, const QModelIndex &index = QModelIndex()) const {
if (editor) {
Q_Q(const QAbstractItemView);
- QObject::disconnect(editor, SIGNAL(destroyed(QObject*)),
- q_func(), SLOT(editorDestroyed(QObject*)));
+ QObject::disconnect(editor, &QWidget::destroyed,
+ q, &QAbstractItemView::editorDestroyed);
editor->removeEventFilter(itemDelegate);
editor->hide();
QAbstractItemDelegate *delegate = q->itemDelegateForIndex(index);
@@ -286,12 +257,14 @@ public:
inline bool isIndexEnabled(const QModelIndex &index) const {
return (model->flags(index) & Qt::ItemIsEnabled);
}
+#if QT_CONFIG(draganddrop)
inline bool isIndexDropEnabled(const QModelIndex &index) const {
return (model->flags(index) & Qt::ItemIsDropEnabled);
}
inline bool isIndexDragEnabled(const QModelIndex &index) const {
return (model->flags(index) & Qt::ItemIsDragEnabled);
}
+#endif
virtual bool selectionAllowed(const QModelIndex &index) const {
// in some views we want to go ahead with selections, even if the index is invalid
@@ -338,13 +311,16 @@ public:
return static_cast<QAbstractItemModelPrivate *>(model->d_ptr.data())->persistent.indexes.contains(index);
}
+#if QT_CONFIG(draganddrop)
QModelIndexList selectedDraggableIndexes() const;
+ void maybeStartDrag(QPoint eventPoint);
+#endif
void doDelayedReset()
{
//we delay the reset of the timer because some views (QTableView)
//with headers can't handle the fact that the model has been destroyed
- //all _q_modelDestroyed slots must have been called
+ //all modelDestroyed() slots must have been called
if (!delayedReset.isActive())
delayedReset.start(0, q_func());
}
@@ -367,12 +343,14 @@ public:
QBasicTimer pressClosedEditorWatcher;
QPersistentModelIndex lastEditedIndex;
bool pressClosedEditor;
+ bool waitForIMCommit;
QPersistentModelIndex enteredIndex;
QPersistentModelIndex pressedIndex;
QPersistentModelIndex currentSelectionStartIndex;
Qt::KeyboardModifiers pressedModifiers;
QPoint pressedPosition;
+ QPoint draggedPosition;
bool pressedAlreadySelected;
bool releaseFromDoubleClick;
@@ -443,7 +421,18 @@ public:
bool verticalScrollModeSet;
bool horizontalScrollModeSet;
+ virtual QRect visualRect(const QModelIndex &index) const { return q_func()->visualRect(index); }
+
+ std::array<QMetaObject::Connection, 14> modelConnections;
+ std::array<QMetaObject::Connection, 4> scrollbarConnections;
+#if QT_CONFIG(gestures) && QT_CONFIG(scroller)
+ QMetaObject::Connection scollerConnection;
+#endif
+
private:
+ void connectDelegate(QAbstractItemDelegate *delegate);
+ void disconnectDelegate(QAbstractItemDelegate *delegate);
+ void disconnectAll();
inline QAbstractItemDelegate *delegateForIndex(const QModelIndex &index) const {
QMap<int, QPointer<QAbstractItemDelegate> >::ConstIterator it;
diff --git a/src/widgets/itemviews/qbsptree.cpp b/src/widgets/itemviews/qbsptree.cpp
index 3f21ad8baa..d75144b1a8 100644
--- a/src/widgets/itemviews/qbsptree.cpp
+++ b/src/widgets/itemviews/qbsptree.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qbsptree_p.h"
@@ -76,9 +40,9 @@ void QBspTree::climbTree(const QRect &rect, callback *function, QBspTreeData dat
void QBspTree::climbTree(const QRect &area, callback *function, QBspTreeData data, int index)
{
- if (index >= nodes.count()) { // the index points to a leaf
+ if (index >= nodes.size()) { // the index points to a leaf
Q_ASSERT(!nodes.isEmpty());
- function(leaf(index - nodes.count()), area, visited, data);
+ function(leaf(index - nodes.size()), area, visited, data);
return;
}
diff --git a/src/widgets/itemviews/qbsptree_p.h b/src/widgets/itemviews/qbsptree_p.h
index 58481491f1..1f00616e87 100644
--- a/src/widgets/itemviews/qbsptree_p.h
+++ b/src/widgets/itemviews/qbsptree_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QBSPTREE_P_H
#define QBSPTREE_P_H
@@ -91,7 +55,7 @@ public:
void climbTree(const QRect &rect, callback *function, QBspTreeData data);
- inline int leafCount() const { return leaves.count(); }
+ inline int leafCount() const { return leaves.size(); }
inline QList<int> &leaf(int i) { return leaves[i]; }
inline void insertLeaf(const QRect &r, int i) { climbTree(r, &insert, i, 0); }
inline void removeLeaf(const QRect &r, int i) { climbTree(r, &remove, i, 0); }
diff --git a/src/widgets/itemviews/qcolumnview.cpp b/src/widgets/itemviews/qcolumnview.cpp
index c09563c375..04bc8f5f88 100644
--- a/src/widgets/itemviews/qcolumnview.cpp
+++ b/src/widgets/itemviews/qcolumnview.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <qglobal.h>
#include "qcolumnview.h"
@@ -104,7 +68,9 @@ void QColumnViewPrivate::initialize()
Q_Q(QColumnView);
q->setTextElideMode(Qt::ElideMiddle);
#if QT_CONFIG(animation)
- QObject::connect(&currentAnimation, SIGNAL(finished()), q, SLOT(_q_changeCurrentColumn()));
+ animationConnection =
+ QObjectPrivate::connect(&currentAnimation, &QPropertyAnimation::finished,
+ this, &QColumnViewPrivate::changeCurrentColumn);
currentAnimation.setTargetObject(hbar);
currentAnimation.setPropertyName("value");
currentAnimation.setEasingCurve(QEasingCurve::InOutQuad);
@@ -113,11 +79,26 @@ void QColumnViewPrivate::initialize()
q->setItemDelegate(new QColumnViewDelegate(q));
}
+void QColumnViewPrivate::clearConnections()
+{
+#if QT_CONFIG(animation)
+ QObject::disconnect(animationConnection);
+#endif
+ for (const QMetaObject::Connection &connection : gripConnections)
+ QObject::disconnect(connection);
+ const auto copy = viewConnections; // disconnectView modifies this container
+ for (auto it = copy.keyBegin(); it != copy.keyEnd(); ++it)
+ disconnectView(*it);
+}
+
+
/*!
Destroys the column view.
*/
QColumnView::~QColumnView()
{
+ Q_D(QColumnView);
+ d->clearConnections();
}
/*!
@@ -134,12 +115,15 @@ void QColumnView::setResizeGripsVisible(bool visible)
if (d->showResizeGrips == visible)
return;
d->showResizeGrips = visible;
- for (int i = 0; i < d->columns.count(); ++i) {
- QAbstractItemView *view = d->columns[i];
+ d->gripConnections.clear();
+ for (QAbstractItemView *view : std::as_const(d->columns)) {
if (visible) {
QColumnViewGrip *grip = new QColumnViewGrip(view);
view->setCornerWidget(grip);
- connect(grip, SIGNAL(gripMoved(int)), this, SLOT(_q_gripMoved(int)));
+ d->gripConnections.push_back(
+ QObjectPrivate::connect(grip, &QColumnViewGrip::gripMoved,
+ d, &QColumnViewPrivate::gripMoved)
+ );
} else {
QWidget *widget = view->cornerWidget();
view->setCornerWidget(nullptr);
@@ -176,7 +160,7 @@ void QColumnView::setRootIndex(const QModelIndex &index)
return;
d->closeColumns();
- Q_ASSERT(d->columns.count() == 0);
+ Q_ASSERT(d->columns.size() == 0);
QAbstractItemView *view = d->createColumn(index, true);
if (view->selectionModel())
@@ -242,7 +226,7 @@ void QColumnView::scrollContentsBy(int dx, int dy)
return;
dx = isRightToLeft() ? -dx : dx;
- for (int i = 0; i < d->columns.count(); ++i)
+ for (int i = 0; i < d->columns.size(); ++i)
d->columns.at(i)->move(d->columns.at(i)->x() + dx, 0);
d->offset += dx;
QAbstractItemView::scrollContentsBy(dx, dy);
@@ -303,7 +287,7 @@ void QColumnView::scrollTo(const QModelIndex &index, ScrollHint hint)
if (leftEdge > -horizontalOffset()
&& rightEdge <= ( -horizontalOffset() + viewport()->size().width())) {
d->columns.at(indexColumn)->scrollTo(index);
- d->_q_changeCurrentColumn();
+ d->changeCurrentColumn();
return;
}
@@ -456,7 +440,7 @@ int QColumnView::verticalOffset() const
*/
QRegion QColumnView::visualRegionForSelection(const QItemSelection &selection) const
{
- int ranges = selection.count();
+ int ranges = selection.size();
if (ranges == 0)
return QRect();
@@ -522,7 +506,7 @@ QSize QColumnView::sizeHint() const
\internal
Move all widgets from the corner grip and to the right
*/
-void QColumnViewPrivate::_q_gripMoved(int offset)
+void QColumnViewPrivate::gripMoved(int offset)
{
Q_Q(QColumnView);
@@ -614,8 +598,10 @@ void QColumnViewPrivate::closeColumns(const QModelIndex &parent, bool build)
QAbstractItemView* notShownAnymore = columns.at(i);
columns.removeAt(i);
notShownAnymore->setVisible(false);
- if (notShownAnymore != previewColumn)
+ if (notShownAnymore != previewColumn) {
notShownAnymore->deleteLater();
+ disconnectView(notShownAnymore);
+ }
}
if (columns.isEmpty()) {
@@ -634,12 +620,22 @@ void QColumnViewPrivate::closeColumns(const QModelIndex &parent, bool build)
createColumn(parent, false);
}
-void QColumnViewPrivate::_q_clicked(const QModelIndex &index)
+void QColumnViewPrivate::disconnectView(QAbstractItemView *view)
+{
+ const auto it = viewConnections.find(view);
+ if (it == viewConnections.end())
+ return;
+ for (const QMetaObject::Connection &connection : it.value())
+ QObject::disconnect(connection);
+ viewConnections.erase(it);
+}
+
+void QColumnViewPrivate::clicked(const QModelIndex &index)
{
Q_Q(QColumnView);
QModelIndex parent = index.parent();
QAbstractItemView *columnClicked = nullptr;
- for (int column = 0; column < columns.count(); ++column) {
+ for (int column = 0; column < columns.size(); ++column) {
if (columns.at(column)->rootIndex() == parent) {
columnClicked = columns[column];
break;
@@ -667,10 +663,11 @@ QAbstractItemView *QColumnViewPrivate::createColumn(const QModelIndex &index, bo
{
Q_Q(QColumnView);
QAbstractItemView *view = nullptr;
+ QMetaObject::Connection clickedConnection;
if (model->hasChildren(index)) {
view = q->createColumn(index);
- q->connect(view, SIGNAL(clicked(QModelIndex)),
- q, SLOT(_q_clicked(QModelIndex)));
+ clickedConnection = QObjectPrivate::connect(view, &QAbstractItemView::clicked,
+ this, &QColumnViewPrivate::clicked);
} else {
if (!previewColumn)
setPreviewWidget(new QWidget(q));
@@ -678,16 +675,14 @@ QAbstractItemView *QColumnViewPrivate::createColumn(const QModelIndex &index, bo
view->setMinimumWidth(qMax(view->minimumWidth(), previewWidget->minimumWidth()));
}
- q->connect(view, SIGNAL(activated(QModelIndex)),
- q, SIGNAL(activated(QModelIndex)));
- q->connect(view, SIGNAL(clicked(QModelIndex)),
- q, SIGNAL(clicked(QModelIndex)));
- q->connect(view, SIGNAL(doubleClicked(QModelIndex)),
- q, SIGNAL(doubleClicked(QModelIndex)));
- q->connect(view, SIGNAL(entered(QModelIndex)),
- q, SIGNAL(entered(QModelIndex)));
- q->connect(view, SIGNAL(pressed(QModelIndex)),
- q, SIGNAL(pressed(QModelIndex)));
+ viewConnections[view] = {
+ QObject::connect(view, &QAbstractItemView::activated, q, &QColumnView::activated),
+ QObject::connect(view, &QAbstractItemView::clicked, q, &QColumnView::clicked),
+ QObject::connect(view, &QAbstractItemView::doubleClicked, q, &QColumnView::doubleClicked),
+ QObject::connect(view, &QAbstractItemView::entered, q, &QColumnView::entered),
+ QObject::connect(view, &QAbstractItemView::pressed, q, &QColumnView::pressed),
+ clickedConnection
+ };
view->setFocusPolicy(Qt::NoFocus);
view->setParent(viewport);
@@ -697,19 +692,22 @@ QAbstractItemView *QColumnViewPrivate::createColumn(const QModelIndex &index, bo
if (showResizeGrips) {
QColumnViewGrip *grip = new QColumnViewGrip(view);
view->setCornerWidget(grip);
- q->connect(grip, SIGNAL(gripMoved(int)), q, SLOT(_q_gripMoved(int)));
+ gripConnections.push_back(
+ QObjectPrivate::connect(grip, &QColumnViewGrip::gripMoved,
+ this, &QColumnViewPrivate::gripMoved)
+ );
}
- if (columnSizes.count() > columns.count()) {
- view->setGeometry(0, 0, columnSizes.at(columns.count()), viewport->height());
+ if (columnSizes.size() > columns.size()) {
+ view->setGeometry(0, 0, columnSizes.at(columns.size()), viewport->height());
} else {
int initialWidth = view->sizeHint().width();
if (q->isRightToLeft())
view->setGeometry(viewport->width() - initialWidth, 0, initialWidth, viewport->height());
else
view->setGeometry(0, 0, initialWidth, viewport->height());
- columnSizes.resize(qMax(columnSizes.count(), columns.count() + 1));
- columnSizes[columns.count()] = initialWidth;
+ columnSizes.resize(qMax(columnSizes.size(), columns.size() + 1));
+ columnSizes[columns.size()] = initialWidth;
}
if (!columns.isEmpty() && columns.constLast()->isHidden())
columns.constLast()->setVisible(true);
@@ -862,8 +860,8 @@ void QColumnView::setColumnWidths(const QList<int> &list)
{
Q_D(QColumnView);
int i = 0;
- const int listCount = list.count();
- const int count = qMin(listCount, d->columns.count());
+ const int listCount = list.size();
+ const int count = qMin(listCount, d->columns.size());
for (; i < count; ++i) {
d->columns.at(i)->resize(list.at(i), d->columns.at(i)->height());
d->columnSizes[i] = list.at(i);
@@ -883,7 +881,7 @@ QList<int> QColumnView::columnWidths() const
{
Q_D(const QColumnView);
QList<int> list;
- const int columnCount = d->columns.count();
+ const int columnCount = d->columns.size();
list.reserve(columnCount);
for (int i = 0; i < columnCount; ++i)
list.append(d->columnSizes.at(i));
@@ -951,7 +949,7 @@ void QColumnView::currentChanged(const QModelIndex &current, const QModelIndex &
We have change the current column and need to update focus and selection models
on the new current column.
*/
-void QColumnViewPrivate::_q_changeCurrentColumn()
+void QColumnViewPrivate::changeCurrentColumn()
{
Q_Q(QColumnView);
if (columns.isEmpty())
@@ -1020,9 +1018,9 @@ void QColumnView::selectAll()
QModelIndexList indexList = selectionModel()->selectedIndexes();
QModelIndex parent = rootIndex();
QItemSelection selection;
- if (indexList.count() >= 1)
+ if (indexList.size() >= 1)
parent = indexList.at(0).parent();
- if (indexList.count() == 1) {
+ if (indexList.size() == 1) {
parent = indexList.at(0);
if (!model()->hasChildren(parent))
parent = parent.parent();
@@ -1058,9 +1056,9 @@ QColumnViewPrivate::~QColumnViewPrivate()
\internal
*/
-void QColumnViewPrivate::_q_columnsInserted(const QModelIndex &parent, int start, int end)
+void QColumnViewPrivate::columnsInserted(const QModelIndex &parent, int start, int end)
{
- QAbstractItemViewPrivate::_q_columnsInserted(parent, start, end);
+ QAbstractItemViewPrivate::columnsInserted(parent, start, end);
checkColumnCreation(parent);
}
@@ -1075,7 +1073,7 @@ 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) {
+ for (int i = 0; i < columns.size(); ++i) {
QAbstractItemView *view = columns.at(i);
if (view->rootIndex() == parent) {
if (view == previewColumn) {
diff --git a/src/widgets/itemviews/qcolumnview.h b/src/widgets/itemviews/qcolumnview.h
index 5c62f9c9af..c0c1398692 100644
--- a/src/widgets/itemviews/qcolumnview.h
+++ b/src/widgets/itemviews/qcolumnview.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QCOLUMNVIEW_H
#define QCOLUMNVIEW_H
@@ -103,9 +67,6 @@ protected:
private:
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())
- Q_PRIVATE_SLOT(d_func(), void _q_clicked(const QModelIndex &))
};
QT_END_NAMESPACE
diff --git a/src/widgets/itemviews/qcolumnview_p.h b/src/widgets/itemviews/qcolumnview_p.h
index 25170251f5..f9b2f3baa4 100644
--- a/src/widgets/itemviews/qcolumnview_p.h
+++ b/src/widgets/itemviews/qcolumnview_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QCOLUMNVIEW_P_H
#define QCOLUMNVIEW_P_H
@@ -67,6 +31,8 @@
#include <qevent.h>
#include <qscrollbar.h>
+#include <vector>
+
QT_REQUIRE_CONFIG(columnview);
QT_BEGIN_NAMESPACE
@@ -152,20 +118,22 @@ public:
QColumnViewPrivate();
~QColumnViewPrivate();
void initialize();
+ void clearConnections();
QAbstractItemView *createColumn(const QModelIndex &index, bool show);
void updateScrollbars();
void closeColumns(const QModelIndex &parent = QModelIndex(), bool build = false);
+ void disconnectView(QAbstractItemView *view);
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) override;
+ void gripMoved(int offset);
+ void changeCurrentColumn();
+ void clicked(const QModelIndex &index);
+ void columnsInserted(const QModelIndex &parent, int start, int end) override;
QList<QAbstractItemView*> columns;
QList<int> columnSizes; // used during init and corner moving
@@ -173,7 +141,12 @@ public:
int offset;
#if QT_CONFIG(animation)
QPropertyAnimation currentAnimation;
+ QMetaObject::Connection animationConnection;
#endif
+ std::vector<QMetaObject::Connection> gripConnections;
+ using ViewConnections = std::vector<QMetaObject::Connection>;
+ QHash<QAbstractItemView *, ViewConnections> viewConnections;
+
QWidget *previewWidget;
QAbstractItemView *previewColumn;
};
diff --git a/src/widgets/itemviews/qcolumnviewgrip.cpp b/src/widgets/itemviews/qcolumnviewgrip.cpp
index 424839d396..22becae872 100644
--- a/src/widgets/itemviews/qcolumnviewgrip.cpp
+++ b/src/widgets/itemviews/qcolumnviewgrip.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qcolumnviewgrip_p.h"
#include <qstyleoption.h>
diff --git a/src/widgets/itemviews/qcolumnviewgrip_p.h b/src/widgets/itemviews/qcolumnviewgrip_p.h
index 13e4c764e8..30e8ce0f79 100644
--- a/src/widgets/itemviews/qcolumnviewgrip_p.h
+++ b/src/widgets/itemviews/qcolumnviewgrip_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QCOLUMNVIEWGRIP_P_H
#define QCOLUMNVIEWGRIP_P_H
diff --git a/src/widgets/itemviews/qdatawidgetmapper.cpp b/src/widgets/itemviews/qdatawidgetmapper.cpp
index 19e216789c..3b7e97eed9 100644
--- a/src/widgets/itemviews/qdatawidgetmapper.cpp
+++ b/src/widgets/itemviews/qdatawidgetmapper.cpp
@@ -1,52 +1,18 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qdatawidgetmapper.h"
#include "qabstractitemmodel.h"
-#include "qitemdelegate.h"
#include "qmetaobject.h"
#include "qwidget.h"
#include "qstyleditemdelegate.h"
+
#include "private/qobject_p.h"
#include "private/qabstractitemmodel_p.h"
+#include <QtCore/qpointer.h>
+#include <array>
#include <iterator>
QT_BEGIN_NAMESPACE
@@ -103,11 +69,22 @@ public:
void populate();
// private slots
- void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
- const QList<int> &);
- void _q_commitData(QWidget *);
- void _q_closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint);
- void _q_modelDestroyed();
+ void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
+ const QList<int> &);
+ void commitData(QWidget *);
+ void closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint);
+ void modelDestroyed();
+
+ void disconnectModel()
+ {
+ for (const QMetaObject::Connection &connection : modelConnections)
+ QObject::disconnect(connection);
+ }
+ void disconnectDelegate()
+ {
+ for (const QMetaObject::Connection &connection : delegateConnections)
+ QObject::disconnect(connection);
+ }
struct WidgetMapper
{
@@ -123,6 +100,8 @@ public:
bool commit(const WidgetMapper &m);
std::vector<WidgetMapper> widgetMap;
+ std::array<QMetaObject::Connection, 2> modelConnections;
+ std::array<QMetaObject::Connection, 2> delegateConnections;
};
Q_DECLARE_TYPEINFO(QDataWidgetMapperPrivate::WidgetMapper, Q_RELOCATABLE_TYPE);
@@ -178,8 +157,8 @@ static bool qContainsIndex(const QModelIndex &idx, const QModelIndex &topLeft,
&& idx.column() >= topLeft.column() && idx.column() <= bottomRight.column();
}
-void QDataWidgetMapperPrivate::_q_dataChanged(const QModelIndex &topLeft,
- const QModelIndex &bottomRight, const QList<int> &)
+void QDataWidgetMapperPrivate::dataChanged(const QModelIndex &topLeft,
+ const QModelIndex &bottomRight, const QList<int> &)
{
if (topLeft.parent() != rootIndex)
return; // not in our hierarchy
@@ -190,7 +169,7 @@ void QDataWidgetMapperPrivate::_q_dataChanged(const QModelIndex &topLeft,
}
}
-void QDataWidgetMapperPrivate::_q_commitData(QWidget *w)
+void QDataWidgetMapperPrivate::commitData(QWidget *w)
{
if (submitPolicy == QDataWidgetMapper::ManualSubmit)
return;
@@ -202,7 +181,7 @@ void QDataWidgetMapperPrivate::_q_commitData(QWidget *w)
commit(widgetMap[idx]);
}
-void QDataWidgetMapperPrivate::_q_closeEditor(QWidget *w, QAbstractItemDelegate::EndEditHint hint)
+void QDataWidgetMapperPrivate::closeEditor(QWidget *w, QAbstractItemDelegate::EndEditHint hint)
{
int idx = findWidget(w);
if (idx == -1)
@@ -225,7 +204,7 @@ void QDataWidgetMapperPrivate::_q_closeEditor(QWidget *w, QAbstractItemDelegate:
}
}
-void QDataWidgetMapperPrivate::_q_modelDestroyed()
+void QDataWidgetMapperPrivate::modelDestroyed()
{
Q_Q(QDataWidgetMapper);
@@ -256,7 +235,7 @@ void QDataWidgetMapperPrivate::_q_modelDestroyed()
instead of the default user property.
It is possible to set an item delegate to support custom widgets. By default,
- a QItemDelegate is used to synchronize the model with the widgets.
+ a QStyledItemDelegate is used to synchronize the model with the widgets.
Let us assume that we have an item model named \c{model} with the following contents:
@@ -335,6 +314,9 @@ QDataWidgetMapper::QDataWidgetMapper(QObject *parent)
*/
QDataWidgetMapper::~QDataWidgetMapper()
{
+ Q_D(QDataWidgetMapper);
+ d->disconnectModel();
+ d->disconnectDelegate();
}
/*!
@@ -350,21 +332,19 @@ void QDataWidgetMapper::setModel(QAbstractItemModel *model)
if (d->model == model)
return;
- if (d->model) {
- disconnect(d->model, SIGNAL(dataChanged(QModelIndex, QModelIndex, QList<int>)), this,
- SLOT(_q_dataChanged(QModelIndex, QModelIndex, QList<int>)));
- disconnect(d->model, SIGNAL(destroyed()), this,
- SLOT(_q_modelDestroyed()));
- }
+ d->disconnectModel();
clearMapping();
d->rootIndex = QModelIndex();
d->currentTopLeft = QModelIndex();
d->model = model;
- connect(model, SIGNAL(dataChanged(QModelIndex, QModelIndex, QList<int>)),
- SLOT(_q_dataChanged(QModelIndex, QModelIndex, QList<int>)));
- connect(model, SIGNAL(destroyed()), SLOT(_q_modelDestroyed()));
+ d->modelConnections = {
+ QObjectPrivate::connect(model, &QAbstractItemModel::dataChanged,
+ d, &QDataWidgetMapperPrivate::dataChanged),
+ QObjectPrivate::connect(model, &QAbstractItemModel::destroyed,
+ d, &QDataWidgetMapperPrivate::modelDestroyed)
+ };
}
/*!
@@ -400,18 +380,17 @@ void QDataWidgetMapper::setItemDelegate(QAbstractItemDelegate *delegate)
{
Q_D(QDataWidgetMapper);
QAbstractItemDelegate *oldDelegate = d->delegate;
- if (oldDelegate) {
- disconnect(oldDelegate, SIGNAL(commitData(QWidget*)), this, SLOT(_q_commitData(QWidget*)));
- disconnect(oldDelegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
- this, SLOT(_q_closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
- }
+ d->disconnectDelegate();
d->delegate = delegate;
if (delegate) {
- connect(delegate, SIGNAL(commitData(QWidget*)), SLOT(_q_commitData(QWidget*)));
- connect(delegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
- SLOT(_q_closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
+ d->delegateConnections = {
+ QObjectPrivate::connect(delegate, &QAbstractItemDelegate::commitData,
+ d, &QDataWidgetMapperPrivate::commitData),
+ QObjectPrivate::connect(delegate, &QAbstractItemDelegate::closeEditor,
+ d, &QDataWidgetMapperPrivate::closeEditor)
+ };
}
d->flipEventFilters(oldDelegate, delegate);
diff --git a/src/widgets/itemviews/qdatawidgetmapper.h b/src/widgets/itemviews/qdatawidgetmapper.h
index c8406f82fb..6c7beff7fc 100644
--- a/src/widgets/itemviews/qdatawidgetmapper.h
+++ b/src/widgets/itemviews/qdatawidgetmapper.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QDATAWIDGETMAPPER_H
#define QDATAWIDGETMAPPER_H
@@ -108,12 +72,6 @@ Q_SIGNALS:
private:
Q_DECLARE_PRIVATE(QDataWidgetMapper)
Q_DISABLE_COPY(QDataWidgetMapper)
- Q_PRIVATE_SLOT(d_func(),
- void _q_dataChanged(const QModelIndex &, const QModelIndex &,
- const QList<int> &))
- Q_PRIVATE_SLOT(d_func(), void _q_commitData(QWidget *))
- Q_PRIVATE_SLOT(d_func(), void _q_closeEditor(QWidget *, QAbstractItemDelegate::EndEditHint))
- Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed())
};
QT_END_NAMESPACE
diff --git a/src/widgets/itemviews/qfileiconprovider.cpp b/src/widgets/itemviews/qfileiconprovider.cpp
index 0530621cae..003fef4224 100644
--- a/src/widgets/itemviews/qfileiconprovider.cpp
+++ b/src/widgets/itemviews/qfileiconprovider.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qfileiconprovider.h"
#include "qfileiconprovider_p.h"
diff --git a/src/widgets/itemviews/qfileiconprovider.h b/src/widgets/itemviews/qfileiconprovider.h
index 35db39bfd8..3cc481b756 100644
--- a/src/widgets/itemviews/qfileiconprovider.h
+++ b/src/widgets/itemviews/qfileiconprovider.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QFILEICONPROVIDER_H
#define QFILEICONPROVIDER_H
diff --git a/src/widgets/itemviews/qfileiconprovider_p.h b/src/widgets/itemviews/qfileiconprovider_p.h
index 6a9a1f2e0e..e94980066f 100644
--- a/src/widgets/itemviews/qfileiconprovider_p.h
+++ b/src/widgets/itemviews/qfileiconprovider_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QFILEICONPROVIDER_P_H
#define QFILEICONPROVIDER_P_H
diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index 27866ecbb0..9ce09dbacc 100644
--- a/src/widgets/itemviews/qheaderview.cpp
+++ b/src/widgets/itemviews/qheaderview.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qheaderview.h"
@@ -60,6 +24,7 @@
#endif
#include <private/qheaderview_p.h>
#include <private/qabstractitemmodel_p.h>
+#include <private/qabstractitemdelegate_p.h>
#ifndef QT_NO_DATASTREAM
#include <qdatastream.h>
@@ -330,6 +295,8 @@ QHeaderView::QHeaderView(QHeaderViewPrivate &dd,
QHeaderView::~QHeaderView()
{
+ Q_D(QHeaderView);
+ d->disconnectModel();
}
/*!
@@ -357,68 +324,35 @@ void QHeaderView::setModel(QAbstractItemModel *model)
return;
Q_D(QHeaderView);
d->layoutChangePersistentSections.clear();
- if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
- if (d->orientation == Qt::Horizontal) {
- QObject::disconnect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)),
- this, SLOT(sectionsInserted(QModelIndex,int,int)));
- QObject::disconnect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
- this, SLOT(sectionsAboutToBeRemoved(QModelIndex,int,int)));
- QObject::disconnect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_sectionsRemoved(QModelIndex,int,int)));
- QObject::disconnect(d->model, SIGNAL(columnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
- this, SLOT(_q_sectionsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
- QObject::disconnect(d->model, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)),
- this, SLOT(_q_sectionsMoved(QModelIndex,int,int,QModelIndex,int)));
- } else {
- QObject::disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(sectionsInserted(QModelIndex,int,int)));
- QObject::disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
- this, SLOT(sectionsAboutToBeRemoved(QModelIndex,int,int)));
- QObject::disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_sectionsRemoved(QModelIndex,int,int)));
- QObject::disconnect(d->model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
- this, SLOT(_q_sectionsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
- QObject::disconnect(d->model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
- this, SLOT(_q_sectionsMoved(QModelIndex,int,int,QModelIndex,int)));
- }
- QObject::disconnect(d->model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
- this, SLOT(headerDataChanged(Qt::Orientation,int,int)));
- QObject::disconnect(d->model, SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
- this, SLOT(_q_sectionsAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
- QObject::disconnect(d->model, SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
- this, SLOT(_q_sectionsChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
- }
+ if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel())
+ d->disconnectModel();
if (model && model != QAbstractItemModelPrivate::staticEmptyModel()) {
- if (d->orientation == Qt::Horizontal) {
- QObject::connect(model, SIGNAL(columnsInserted(QModelIndex,int,int)),
- this, SLOT(sectionsInserted(QModelIndex,int,int)));
- QObject::connect(model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
- this, SLOT(sectionsAboutToBeRemoved(QModelIndex,int,int)));
- QObject::connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_sectionsRemoved(QModelIndex,int,int)));
- QObject::connect(model, SIGNAL(columnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
- this, SLOT(_q_sectionsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
- QObject::connect(model, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)),
- this, SLOT(_q_sectionsMoved(QModelIndex,int,int,QModelIndex,int)));
- } else {
- QObject::connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(sectionsInserted(QModelIndex,int,int)));
- QObject::connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
- this, SLOT(sectionsAboutToBeRemoved(QModelIndex,int,int)));
- QObject::connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_sectionsRemoved(QModelIndex,int,int)));
- QObject::connect(model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
- this, SLOT(_q_sectionsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
- QObject::connect(model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
- this, SLOT(_q_sectionsMoved(QModelIndex,int,int,QModelIndex,int)));
- }
- QObject::connect(model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
- this, SLOT(headerDataChanged(Qt::Orientation,int,int)));
- QObject::connect(model, SIGNAL(layoutAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
- this, SLOT(_q_sectionsAboutToBeChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
- QObject::connect(model, SIGNAL(layoutChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)),
- this, SLOT(_q_sectionsChanged(QList<QPersistentModelIndex>,QAbstractItemModel::LayoutChangeHint)));
+ const bool hor = d->orientation == Qt::Horizontal;
+ d->modelConnections = {
+ QObject::connect(model, hor ? &QAbstractItemModel::columnsInserted
+ : &QAbstractItemModel::rowsInserted,
+ this, &QHeaderView::sectionsInserted),
+ QObject::connect(model, hor ? &QAbstractItemModel::columnsAboutToBeRemoved
+ : &QAbstractItemModel::rowsAboutToBeRemoved,
+ this, &QHeaderView::sectionsAboutToBeRemoved),
+ QObjectPrivate::connect(model, hor ? &QAbstractItemModel::columnsRemoved
+ : &QAbstractItemModel::rowsRemoved,
+ d, &QHeaderViewPrivate::sectionsRemoved),
+ QObjectPrivate::connect(model, hor ? &QAbstractItemModel::columnsAboutToBeMoved
+ : &QAbstractItemModel::rowsAboutToBeMoved,
+ d, &QHeaderViewPrivate::sectionsAboutToBeMoved),
+ QObjectPrivate::connect(model, hor ? &QAbstractItemModel::columnsMoved
+ : &QAbstractItemModel::rowsMoved,
+ d, &QHeaderViewPrivate::sectionsMoved),
+
+ QObject::connect(model, &QAbstractItemModel::headerDataChanged,
+ this, &QHeaderView::headerDataChanged),
+ QObjectPrivate::connect(model, &QAbstractItemModel::layoutAboutToBeChanged,
+ d, &QHeaderViewPrivate::sectionsAboutToBeChanged),
+ QObjectPrivate::connect(model, &QAbstractItemModel::layoutChanged,
+ d, &QHeaderViewPrivate::sectionsChanged)
+ };
}
d->state = QHeaderViewPrivate::NoClear;
@@ -453,7 +387,7 @@ Qt::Orientation QHeaderView::orientation() const
int QHeaderView::offset() const
{
Q_D(const QHeaderView);
- return d->offset;
+ return d->headerOffset;
}
/*!
@@ -467,10 +401,10 @@ int QHeaderView::offset() const
void QHeaderView::setOffset(int newOffset)
{
Q_D(QHeaderView);
- if (d->offset == (int)newOffset)
+ if (d->headerOffset == newOffset)
return;
- int ndelta = d->offset - newOffset;
- d->offset = newOffset;
+ int ndelta = d->headerOffset - newOffset;
+ d->headerOffset = newOffset;
if (d->orientation == Qt::Horizontal)
d->viewport->scroll(isRightToLeft() ? -ndelta : ndelta, 0);
else
@@ -626,7 +560,7 @@ int QHeaderView::visualIndexAt(int position) const
if (d->reverse())
vposition = d->viewport->width() - vposition - 1;
- vposition += d->offset;
+ vposition += d->headerOffset;
if (vposition > d->length)
return -1;
@@ -716,7 +650,7 @@ int QHeaderView::sectionViewportPosition(int logicalIndex) const
int position = sectionPosition(logicalIndex);
if (position < 0)
return position; // the section was hidden
- int offsetPosition = position - d->offset;
+ int offsetPosition = position - d->headerOffset;
if (d->reverse())
return d->viewport->width() - (offsetPosition + sectionSize(logicalIndex));
return offsetPosition;
@@ -1015,7 +949,7 @@ bool QHeaderView::isSectionHidden(int logicalIndex) const
int QHeaderView::hiddenSectionCount() const
{
Q_D(const QHeaderView);
- return d->hiddenSectionSize.count();
+ return d->hiddenSectionSize.size();
}
/*!
@@ -1096,7 +1030,7 @@ int QHeaderView::visualIndex(int logicalIndex) const
if (d->visualIndices.isEmpty()) { // nothing has been moved, so we have no mapping
if (logicalIndex < d->sectionCount())
return logicalIndex;
- } else if (logicalIndex < d->visualIndices.count()) {
+ } else if (logicalIndex < d->visualIndices.size()) {
int visual = d->visualIndices.at(logicalIndex);
Q_ASSERT(visual < d->sectionCount());
return visual;
@@ -1122,19 +1056,22 @@ int QHeaderView::logicalIndex(int visualIndex) const
}
/*!
- \since 5.0
+ \property QHeaderView::sectionsMovable
- If \a movable is true, the header sections may be moved by the user;
+ If \a sectionsMovable is true, the header sections may be moved by the user;
otherwise they are fixed in place.
When used in combination with QTreeView, the first column is not
movable (since it contains the tree structure), by default.
You can make it movable with setFirstSectionMovable(true).
- \sa sectionsMovable(), sectionMoved()
+ \sa sectionMoved()
\sa setFirstSectionMovable()
*/
+/*!
+ Sets \l sectionsMovable to \a movable.
+ */
void QHeaderView::setSectionsMovable(bool movable)
{
Q_D(QHeaderView);
@@ -1142,17 +1079,8 @@ void QHeaderView::setSectionsMovable(bool movable)
}
/*!
- \since 5.0
-
- Returns \c true if the header can be moved by the user; otherwise returns
- false.
-
- By default, sections are movable in QTreeView (except for the first one),
- and not movable in QTableView.
-
- \sa setSectionsMovable()
+ Returns \l sectionsMovable.
*/
-
bool QHeaderView::sectionsMovable() const
{
Q_D(const QHeaderView);
@@ -1172,6 +1100,11 @@ bool QHeaderView::sectionsMovable() const
In such a scenario, it is recommended to call QTreeView::setRootIsDecorated(false)
as well.
+ \code
+ treeView->setRootIsDecorated(false);
+ treeView->header()->setFirstSectionMovable(true);
+ \endcode
+
Setting it to true has no effect unless setSectionsMovable(true) is called
as well.
@@ -1191,14 +1124,17 @@ bool QHeaderView::isFirstSectionMovable() const
}
/*!
- \since 5.0
+ \property QHeaderView::sectionsClickable
- If \a clickable is true, the header will respond to single clicks.
+ Holds \c true if the header is clickable; otherwise \c false. A
+ clickable header could be set up to allow the user to change the
+ representation of the data in the view related to the header.
- \sa sectionsClickable(), sectionClicked(), sectionPressed(),
- setSortIndicatorShown()
+ \sa sectionPressed(), setSortIndicatorShown()
+*/
+/*!
+ Set \l sectionsClickable to \a clickable.
*/
-
void QHeaderView::setSectionsClickable(bool clickable)
{
Q_D(QHeaderView);
@@ -1206,15 +1142,8 @@ void QHeaderView::setSectionsClickable(bool clickable)
}
/*!
- \since 5.0
-
- Returns \c true if the header is clickable; otherwise returns \c false. A
- clickable header could be set up to allow the user to change the
- representation of the data in the view related to the header.
-
- \sa setSectionsClickable()
+ Returns \l sectionsClickable.
*/
-
bool QHeaderView::sectionsClickable() const
{
Q_D(const QHeaderView);
@@ -1777,6 +1706,7 @@ QByteArray QHeaderView::saveState() const
Q_D(const QHeaderView);
QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly);
+ stream.setVersion(QDataStream::Qt_5_0);
stream << QHeaderViewPrivate::VersionMarker;
stream << 0; // current version is 0
d->write(stream);
@@ -1796,21 +1726,27 @@ bool QHeaderView::restoreState(const QByteArray &state)
Q_D(QHeaderView);
if (state.isEmpty())
return false;
- QByteArray data = state;
- QDataStream stream(&data, QIODevice::ReadOnly);
- int marker;
- int ver;
- stream >> marker;
- stream >> ver;
- if (stream.status() != QDataStream::Ok
+
+ for (const auto dataStreamVersion : {QDataStream::Qt_5_0, QDataStream::Qt_6_0}) {
+
+ QByteArray data = state;
+ QDataStream stream(&data, QIODevice::ReadOnly);
+ stream.setVersion(dataStreamVersion);
+ int marker;
+ int ver;
+ stream >> marker;
+ stream >> ver;
+ if (stream.status() != QDataStream::Ok
|| marker != QHeaderViewPrivate::VersionMarker
- || ver != 0) // current version is 0
- return false;
+ || ver != 0) { // current version is 0
+ return false;
+ }
- if (d->read(stream)) {
- emit sortIndicatorChanged(d->sortIndicatorSection, d->sortIndicatorOrder );
- d->viewport->update();
- return true;
+ if (d->read(stream)) {
+ emit sortIndicatorChanged(d->sortIndicatorSection, d->sortIndicatorOrder );
+ d->viewport->update();
+ return true;
+ }
}
return false;
}
@@ -1908,8 +1844,9 @@ void QHeaderView::sectionsInserted(const QModelIndex &parent,
int logicalFirst, int logicalLast)
{
Q_D(QHeaderView);
- if (parent != d->root)
- return; // we only handle changes in the root level
+ // only handle root level changes and return on no-op
+ if (parent != d->root || d->modelSectionCount() == d->sectionCount())
+ return;
int oldCount = d->sectionCount();
d->invalidateCachedSizeHint();
@@ -1939,10 +1876,10 @@ void QHeaderView::sectionsInserted(const QModelIndex &parent,
QHeaderViewPrivate::SectionItem section(d->defaultSectionSize, d->globalResizeMode);
d->sectionStartposRecalc = true;
- if (d->sectionItems.isEmpty() || insertAt >= d->sectionItems.count()) {
+ if (d->sectionItems.isEmpty() || insertAt >= d->sectionItems.size()) {
int insertLength = d->defaultSectionSize * insertCount;
d->length += insertLength;
- d->sectionItems.insert(d->sectionItems.count(), insertCount, section); // append
+ d->sectionItems.insert(d->sectionItems.size(), insertCount, section); // append
} else {
// separate them out into their own sections
int insertLength = d->defaultSectionSize * insertCount;
@@ -1965,8 +1902,8 @@ void QHeaderView::sectionsInserted(const QModelIndex &parent,
// update mapping
if (!d->visualIndices.isEmpty() && !d->logicalIndices.isEmpty()) {
- Q_ASSERT(d->visualIndices.count() == d->logicalIndices.count());
- int mappingCount = d->visualIndices.count();
+ Q_ASSERT(d->visualIndices.size() == d->logicalIndices.size());
+ int mappingCount = d->visualIndices.size();
for (int i = 0; i < mappingCount; ++i) {
if (d->visualIndices.at(i) >= logicalFirst)
d->visualIndices[i] += insertCount;
@@ -2032,8 +1969,8 @@ void QHeaderViewPrivate::updateHiddenSections(int logicalFirst, int logicalLast)
hiddenSectionSize = newHiddenSectionSize;
}
-void QHeaderViewPrivate::_q_sectionsRemoved(const QModelIndex &parent,
- int logicalFirst, int logicalLast)
+void QHeaderViewPrivate::sectionsRemoved(const QModelIndex &parent,
+ int logicalFirst, int logicalLast)
{
Q_Q(QHeaderView);
if (parent != root)
@@ -2056,7 +1993,7 @@ void QHeaderViewPrivate::_q_sectionsRemoved(const QModelIndex &parent,
if (logicalFirst == logicalLast) { // Remove just one index.
int l = logicalFirst;
int visual = visualIndices.at(l);
- Q_ASSERT(sectionCount() == logicalIndices.count());
+ Q_ASSERT(sectionCount() == logicalIndices.size());
for (int v = 0; v < sectionCount(); ++v) {
if (v > visual) {
int logical = logicalIndices.at(v);
@@ -2071,17 +2008,17 @@ void QHeaderViewPrivate::_q_sectionsRemoved(const QModelIndex &parent,
removeSectionsFromSectionItems(visual, visual);
} else {
sectionStartposRecalc = true; // We will need to recalc positions after removing items
- for (int u = 0; u < sectionItems.count(); ++u) // Store section info
+ for (int u = 0; u < sectionItems.size(); ++u) // Store section info
sectionItems.at(u).tmpLogIdx = logicalIndices.at(u);
- for (int v = sectionItems.count() - 1; v >= 0; --v) { // Remove the sections
+ for (int v = sectionItems.size() - 1; v >= 0; --v) { // Remove the sections
if (logicalFirst <= sectionItems.at(v).tmpLogIdx && sectionItems.at(v).tmpLogIdx <= logicalLast)
removeSectionsFromSectionItems(v, v);
}
- visualIndices.resize(sectionItems.count());
- logicalIndices.resize(sectionItems.count());
+ visualIndices.resize(sectionItems.size());
+ logicalIndices.resize(sectionItems.size());
int* visual_data = visualIndices.data();
int* logical_data = logicalIndices.data();
- for (int w = 0; w < sectionItems.count(); ++w) { // Restore visual and logical indexes
+ for (int w = 0; w < sectionItems.size(); ++w) { // Restore visual and logical indexes
int logindex = sectionItems.at(w).tmpLogIdx;
if (logindex > logicalFirst)
logindex -= changeCount;
@@ -2118,28 +2055,32 @@ void QHeaderViewPrivate::_q_sectionsRemoved(const QModelIndex &parent,
viewport->update();
}
-void QHeaderViewPrivate::_q_sectionsAboutToBeMoved(const QModelIndex &sourceParent, int logicalStart, int logicalEnd, const QModelIndex &destinationParent, int logicalDestination)
+void QHeaderViewPrivate::sectionsAboutToBeMoved(const QModelIndex &sourceParent, int logicalStart,
+ int logicalEnd, const QModelIndex &destinationParent,
+ int logicalDestination)
{
if (sourceParent != root || destinationParent != root)
return; // we only handle changes in the root level
Q_UNUSED(logicalStart);
Q_UNUSED(logicalEnd);
Q_UNUSED(logicalDestination);
- _q_sectionsAboutToBeChanged();
+ sectionsAboutToBeChanged();
}
-void QHeaderViewPrivate::_q_sectionsMoved(const QModelIndex &sourceParent, int logicalStart, int logicalEnd, const QModelIndex &destinationParent, int logicalDestination)
+void QHeaderViewPrivate::sectionsMoved(const QModelIndex &sourceParent, int logicalStart,
+ int logicalEnd, const QModelIndex &destinationParent,
+ int logicalDestination)
{
if (sourceParent != root || destinationParent != root)
return; // we only handle changes in the root level
Q_UNUSED(logicalStart);
Q_UNUSED(logicalEnd);
Q_UNUSED(logicalDestination);
- _q_sectionsChanged();
+ sectionsChanged();
}
-void QHeaderViewPrivate::_q_sectionsAboutToBeChanged(const QList<QPersistentModelIndex> &,
- QAbstractItemModel::LayoutChangeHint hint)
+void QHeaderViewPrivate::sectionsAboutToBeChanged(const QList<QPersistentModelIndex> &,
+ QAbstractItemModel::LayoutChangeHint hint)
{
if ((hint == QAbstractItemModel::VerticalSortHint && orientation == Qt::Horizontal) ||
(hint == QAbstractItemModel::HorizontalSortHint && orientation == Qt::Vertical))
@@ -2154,9 +2095,9 @@ void QHeaderViewPrivate::_q_sectionsAboutToBeChanged(const QList<QPersistentMode
return;
layoutChangePersistentSections.clear();
- layoutChangePersistentSections.reserve(std::min(10, int(sectionItems.count())));
+ layoutChangePersistentSections.reserve(std::min(10, int(sectionItems.size())));
// after layoutChanged another section can be last stretched section
- if (stretchLastSection && lastSectionLogicalIdx >= 0 && lastSectionLogicalIdx < sectionItems.count()) {
+ if (stretchLastSection && lastSectionLogicalIdx >= 0 && lastSectionLogicalIdx < sectionItems.size()) {
const int visual = visualIndex(lastSectionLogicalIdx);
if (visual >= 0 && visual < sectionItems.size()) {
auto &itemRef = sectionItems[visual];
@@ -2184,8 +2125,8 @@ void QHeaderViewPrivate::_q_sectionsAboutToBeChanged(const QList<QPersistentMode
}
}
-void QHeaderViewPrivate::_q_sectionsChanged(const QList<QPersistentModelIndex> &,
- QAbstractItemModel::LayoutChangeHint hint)
+void QHeaderViewPrivate::sectionsChanged(const QList<QPersistentModelIndex> &,
+ QAbstractItemModel::LayoutChangeHint hint)
{
if ((hint == QAbstractItemModel::VerticalSortHint && orientation == Qt::Horizontal) ||
(hint == QAbstractItemModel::HorizontalSortHint && orientation == Qt::Vertical))
@@ -2215,7 +2156,7 @@ void QHeaderViewPrivate::_q_sectionsChanged(const QList<QPersistentModelIndex> &
}
// Though far from perfect we here try to retain earlier/existing behavior
- // ### See QHeaderViewPrivate::_q_layoutAboutToBeChanged()
+ // ### See QHeaderViewPrivate::layoutAboutToBeChanged()
// When we don't have valid hasPersistantIndexes it can be due to
// - all sections are default sections
// - the row/column 0 which is used for persistent indexes is gone
@@ -2251,7 +2192,7 @@ void QHeaderViewPrivate::_q_sectionsChanged(const QList<QPersistentModelIndex> &
: index.row());
// the new visualIndices are already adjusted / reset by initializeSections()
const int newVisualIndex = visualIndex(newLogicalIndex);
- if (newVisualIndex < sectionItems.count()) {
+ if (newVisualIndex < sectionItems.size()) {
auto &newSection = sectionItems[newVisualIndex];
newSection = item.section;
@@ -2316,7 +2257,7 @@ void QHeaderView::initializeSections(int start, int end)
int newCount = end + 1;
d->removeSectionsFromSectionItems(newCount, d->sectionCount() - 1);
if (!d->hiddenSectionSize.isEmpty()) {
- if (oldCount - newCount > d->hiddenSectionSize.count()) {
+ if (oldCount - newCount > d->hiddenSectionSize.size()) {
for (int i = end + 1; i < d->sectionCount(); ++i)
d->hiddenSectionSize.remove(i);
} else {
@@ -2541,9 +2482,9 @@ void QHeaderView::paintEvent(QPaintEvent *e)
for (int a = 0, i = 0; i < d->sectionItems.count(); ++i) {
QColor color((i & 4 ? 255 : 0), (i & 2 ? 255 : 0), (i & 1 ? 255 : 0));
if (d->orientation == Qt::Horizontal)
- painter.fillRect(a - d->offset, 0, d->sectionItems.at(i).size, 4, color);
+ painter.fillRect(a - d->headerOffset, 0, d->sectionItems.at(i).size, 4, color);
else
- painter.fillRect(0, a - d->offset, 4, d->sectionItems.at(i).size, color);
+ painter.fillRect(0, a - d->headerOffset, 4, d->sectionItems.at(i).size, color);
a += d->sectionItems.at(i).size;
}
@@ -2602,7 +2543,7 @@ void QHeaderView::mousePressEvent(QMouseEvent *e)
void QHeaderView::mouseMoveEvent(QMouseEvent *e)
{
Q_D(QHeaderView);
- int pos = d->orientation == Qt::Horizontal ? e->position().toPoint().x() : e->position().toPoint().y();
+ const int pos = d->orientation == Qt::Horizontal ? e->position().toPoint().x() : e->position().toPoint().y();
if (pos < 0 && d->state != QHeaderViewPrivate::SelectSections)
return;
if (e->buttons() == Qt::NoButton) {
@@ -2630,8 +2571,10 @@ void QHeaderView::mouseMoveEvent(QMouseEvent *e)
return;
}
case QHeaderViewPrivate::MoveSection: {
- if (d->shouldAutoScroll(e->position().toPoint()))
+ if (d->shouldAutoScroll(e->position().toPoint())) {
+ d->draggedPosition = e->pos() + d->offset();
d->startAutoScroll();
+ }
if (qAbs(pos - d->firstPos) >= QApplication::startDragDistance()
#if QT_CONFIG(label)
|| !d->sectionIndicator->isHidden()
@@ -2643,7 +2586,7 @@ void QHeaderView::mouseMoveEvent(QMouseEvent *e)
if (visual == 0 && logicalIndex(0) == 0 && !d->allowUserMoveOfSection0)
return;
- const int posThreshold = d->headerSectionPosition(visual) - d->offset + d->headerSectionSize(visual) / 2;
+ const int posThreshold = d->headerSectionPosition(visual) - d->headerOffset + d->headerSectionSize(visual) / 2;
const int checkPos = d->reverse() ? d->viewport->width() - pos : pos;
int moving = visualIndex(d->section);
int oldTarget = d->target;
@@ -2667,7 +2610,7 @@ void QHeaderView::mouseMoveEvent(QMouseEvent *e)
return;
}
case QHeaderViewPrivate::SelectSections: {
- int logical = logicalIndexAt(qMax(-d->offset, pos));
+ int logical = logicalIndexAt(qMax(-d->headerOffset, pos));
if (logical == -1 && pos > 0)
logical = logicalIndex(d->lastVisibleVisualIndex());
if (logical == d->pressed)
@@ -2936,9 +2879,9 @@ void QHeaderView::initStyleOptionForIndex(QStyleOptionHeader *option, int logica
Qt::TextAlignmentRole);
opt.section = logicalIndex;
opt.state |= state;
- opt.textAlignment = Qt::Alignment(textAlignment.isValid()
- ? Qt::Alignment(textAlignment.toInt())
- : d->defaultAlignment);
+ opt.textAlignment = textAlignment.isValid()
+ ? QtPrivate::legacyFlagValueFromModelData<Qt::Alignment>(textAlignment)
+ : d->defaultAlignment;
opt.iconAlignment = Qt::AlignVCenter;
opt.text = d->model->headerData(logicalIndex, d->orientation,
@@ -3089,7 +3032,7 @@ int QHeaderView::horizontalOffset() const
{
Q_D(const QHeaderView);
if (d->orientation == Qt::Horizontal)
- return d->offset;
+ return d->headerOffset;
return 0;
}
@@ -3104,7 +3047,7 @@ int QHeaderView::verticalOffset() const
{
Q_D(const QHeaderView);
if (d->orientation == Qt::Vertical)
- return d->offset;
+ return d->headerOffset;
return 0;
}
@@ -3481,7 +3424,7 @@ void QHeaderView::initStyleOption(QStyleOptionFrame *option) const
bool QHeaderViewPrivate::isSectionSelected(int section) const
{
int i = section * 2;
- if (i < 0 || i >= sectionSelected.count())
+ if (i < 0 || i >= sectionSelected.size())
return false;
if (sectionSelected.testBit(i)) // if the value was cached
return sectionSelected.testBit(i + 1);
@@ -3705,7 +3648,7 @@ void QHeaderViewPrivate::resizeSections(QHeaderView::ResizeMode globalMode, bool
void QHeaderViewPrivate::createSectionItems(int start, int end, int sizePerSection, QHeaderView::ResizeMode mode)
{
- if (end >= sectionItems.count()) {
+ if (end >= sectionItems.size()) {
sectionItems.resize(end + 1);
sectionStartposRecalc = true;
}
@@ -3721,7 +3664,7 @@ void QHeaderViewPrivate::createSectionItems(int start, int end, int sizePerSecti
void QHeaderViewPrivate::removeSectionsFromSectionItems(int start, int end)
{
// remove sections
- sectionStartposRecalc |= (end != sectionItems.count() - 1);
+ sectionStartposRecalc |= (end != sectionItems.size() - 1);
int removedlength = 0;
for (int u = start; u <= end; ++u)
removedlength += sectionItems.at(u).size;
@@ -3751,8 +3694,7 @@ static Qt::SortOrder flipOrder(Qt::SortOrder order)
case Qt::DescendingOrder:
return Qt::AscendingOrder;
};
- Q_UNREACHABLE();
- return Qt::AscendingOrder;
+ Q_UNREACHABLE_RETURN(Qt::AscendingOrder);
};
void QHeaderViewPrivate::flipSortIndicator(int section)
@@ -3829,12 +3771,9 @@ void QHeaderViewPrivate::cascadingResize(int visual, int newSize)
if (currentSectionSize <= minimumSize)
continue;
int newSectionSize = qMax(currentSectionSize - delta, minimumSize);
- //qDebug() << "### cascading to" << i << newSectionSize - currentSectionSize << delta;
resizeSectionItem(i, currentSectionSize, newSectionSize);
saveCascadingSectionSize(i, currentSectionSize);
delta = delta - (currentSectionSize - newSectionSize);
- //qDebug() << "new delta" << delta;
- //if (newSectionSize != minimumSize)
if (delta <= 0)
break;
}
@@ -3852,7 +3791,6 @@ void QHeaderViewPrivate::cascadingResize(int visual, int newSize)
int newSectionSize = currentSectionSize - delta;
resizeSectionItem(i, currentSectionSize, newSectionSize);
if (newSectionSize >= originalSectionSize && false) {
- //qDebug() << "section" << i << "restored to" << originalSectionSize;
cascadingSectionSize.remove(i); // the section is now restored
}
sectionResized = true;
@@ -3909,7 +3847,7 @@ void QHeaderViewPrivate::setDefaultSectionSize(int size)
customDefaultSectionSize = true;
if (state == QHeaderViewPrivate::ResizeSection)
preventCursorChangeInSetOffset = true;
- for (int i = 0; i < sectionItems.count(); ++i) {
+ for (int i = 0; i < sectionItems.size(); ++i) {
QHeaderViewPrivate::SectionItem &section = sectionItems[i];
if (hiddenSectionSize.isEmpty() || !isVisualIndexHidden(i)) { // resize on not hidden.
const int newSize = size;
@@ -3978,7 +3916,7 @@ int QHeaderViewPrivate::headerVisualIndexAt(int position) const
if (sectionStartposRecalc)
recalcSectionStartPos();
int startidx = 0;
- int endidx = sectionItems.count() - 1;
+ int endidx = sectionItems.size() - 1;
while (startidx <= endidx) {
int middle = (endidx + startidx) / 2;
if (sectionItems.at(middle).calculated_startpos > position) {
@@ -4001,7 +3939,7 @@ void QHeaderViewPrivate::setHeaderSectionResizeMode(int visual, QHeaderView::Res
QHeaderView::ResizeMode QHeaderViewPrivate::headerSectionResizeMode(int visual) const
{
- if (visual < 0 || visual >= sectionItems.count())
+ if (visual < 0 || visual >= sectionItems.size())
return globalResizeMode;
return static_cast<QHeaderView::ResizeMode>(sectionItems.at(visual).resizeMode);
}
@@ -4009,7 +3947,7 @@ QHeaderView::ResizeMode QHeaderViewPrivate::headerSectionResizeMode(int visual)
void QHeaderViewPrivate::setGlobalHeaderResizeMode(QHeaderView::ResizeMode mode)
{
globalResizeMode = mode;
- for (int i = 0; i < sectionItems.count(); ++i)
+ for (int i = 0; i < sectionItems.size(); ++i)
sectionItems[i].resizeMode = mode;
}
@@ -4028,7 +3966,7 @@ int QHeaderViewPrivate::adjustedVisualIndex(int visualIndex) const
if (!hiddenSectionSize.isEmpty()) {
int adjustedVisualIndex = visualIndex;
int currentVisualIndex = 0;
- for (int i = 0; i < sectionItems.count(); ++i) {
+ for (int i = 0; i < sectionItems.size(); ++i) {
if (isVisualIndexHidden(i))
++adjustedVisualIndex;
else
@@ -4164,12 +4102,21 @@ bool QHeaderViewPrivate::read(QDataStream &in)
in >> global;
+ // Check parameter consistency
+ // Global orientation out of bounds?
+ if (global < 0 || global > QHeaderView::ResizeToContents)
+ return false;
+
+ // Alignment out of bounds?
+ if (align < 0 || align > Qt::AlignVertical_Mask)
+ return false;
+
in >> sectionItemsIn;
// In Qt4 we had a vector of spans where one span could hold information on more sections.
// Now we have an itemvector where one items contains information about one section
// For backward compatibility with Qt4 we do the following
QList<SectionItem> newSectionItems;
- for (int u = 0; u < sectionItemsIn.count(); ++u) {
+ for (int u = 0; u < sectionItemsIn.size(); ++u) {
int count = sectionItemsIn.at(u).tmpDataStreamSectionCount;
if (count > 1)
sectionItemsIn[u].size /= count;
@@ -4178,25 +4125,25 @@ bool QHeaderViewPrivate::read(QDataStream &in)
}
int sectionItemsLengthTotal = 0;
- for (const SectionItem &section : qAsConst(newSectionItems))
+ for (const SectionItem &section : std::as_const(newSectionItems))
sectionItemsLengthTotal += section.size;
if (sectionItemsLengthTotal != lengthIn)
return false;
const int currentCount = (orient == Qt::Horizontal ? model->columnCount(root) : model->rowCount(root));
- if (newSectionItems.count() < currentCount) {
+ if (newSectionItems.size() < currentCount) {
// we have sections not in the saved state, give them default settings
if (!visualIndicesIn.isEmpty() && !logicalIndicesIn.isEmpty()) {
- for (int i = newSectionItems.count(); i < currentCount; ++i) {
+ for (int i = newSectionItems.size(); i < currentCount; ++i) {
visualIndicesIn.append(i);
logicalIndicesIn.append(i);
}
}
- const int insertCount = currentCount - newSectionItems.count();
+ const int insertCount = currentCount - newSectionItems.size();
const int insertLength = defaultSectionSizeIn * insertCount;
lengthIn += insertLength;
SectionItem section(defaultSectionSizeIn, globalResizeMode);
- newSectionItems.insert(newSectionItems.count(), insertCount, section); // append
+ newSectionItems.insert(newSectionItems.size(), insertCount, section); // append
}
orientation = static_cast<Qt::Orientation>(orient);
diff --git a/src/widgets/itemviews/qheaderview.h b/src/widgets/itemviews/qheaderview.h
index a18ea3fad3..bd0050df5e 100644
--- a/src/widgets/itemviews/qheaderview.h
+++ b/src/widgets/itemviews/qheaderview.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QHEADERVIEW_H
#define QHEADERVIEW_H
@@ -55,6 +19,8 @@ class Q_WIDGETS_EXPORT QHeaderView : public QAbstractItemView
Q_OBJECT
Q_PROPERTY(bool firstSectionMovable READ isFirstSectionMovable WRITE setFirstSectionMovable)
Q_PROPERTY(bool showSortIndicator READ isSortIndicatorShown WRITE setSortIndicatorShown)
+ Q_PROPERTY(bool sectionsMovable READ sectionsMovable WRITE setSectionsMovable)
+ Q_PROPERTY(bool sectionsClickable READ sectionsClickable WRITE setSectionsClickable)
Q_PROPERTY(bool highlightSections READ highlightSections WRITE setHighlightSections)
Q_PROPERTY(bool stretchLastSection READ stretchLastSection WRITE setStretchLastSection)
Q_PROPERTY(bool cascadingSectionResizes READ cascadingSectionResizes
@@ -247,14 +213,6 @@ protected:
private:
void initStyleOption(QStyleOptionFrame *option) const override;
- // ### Qt6: make them protected slots in QHeaderViewPrivate
- Q_PRIVATE_SLOT(d_func(), void _q_sectionsRemoved(const QModelIndex &parent, int logicalFirst, int logicalLast))
- Q_PRIVATE_SLOT(d_func(), void _q_sectionsAboutToBeMoved(const QModelIndex &sourceParent, int logicalStart, int logicalEnd, const QModelIndex &destinationParent, int logicalDestination))
- Q_PRIVATE_SLOT(d_func(), void _q_sectionsMoved(const QModelIndex &sourceParent, int logicalStart, int logicalEnd, const QModelIndex &destinationParent, int logicalDestination))
- Q_PRIVATE_SLOT(d_func(), void _q_sectionsAboutToBeChanged(const QList<QPersistentModelIndex> &parents = QList<QPersistentModelIndex>(),
- QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint))
- Q_PRIVATE_SLOT(d_func(), void _q_sectionsChanged(const QList<QPersistentModelIndex> &parents = QList<QPersistentModelIndex>(),
- QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint))
Q_DECLARE_PRIVATE(QHeaderView)
Q_DISABLE_COPY(QHeaderView)
};
diff --git a/src/widgets/itemviews/qheaderview_p.h b/src/widgets/itemviews/qheaderview_p.h
index 130220523f..8b214e1d03 100644
--- a/src/widgets/itemviews/qheaderview_p.h
+++ b/src/widgets/itemviews/qheaderview_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QHEADERVIEW_P_H
#define QHEADERVIEW_P_H
@@ -52,6 +16,7 @@
//
#include <QtWidgets/private/qtwidgetsglobal_p.h>
+#include "qheaderview.h"
#include "private/qabstractitemview_p.h"
#include "QtCore/qbitarray.h"
@@ -60,6 +25,8 @@
#include "QtWidgets/qlabel.h"
#endif
+#include <array>
+
QT_REQUIRE_CONFIG(itemviews);
QT_BEGIN_NAMESPACE
@@ -73,7 +40,7 @@ public:
QHeaderViewPrivate()
: state(NoState),
- offset(0),
+ headerOffset(0),
sortIndicatorOrder(Qt::DescendingOrder),
sortIndicatorSection(0),
sortIndicatorShown(false),
@@ -121,13 +88,17 @@ public:
void updateSectionIndicator(int section, int position);
void updateHiddenSections(int logicalFirst, int logicalLast);
void resizeSections(QHeaderView::ResizeMode globalMode, bool useGlobalMode = false);
- void _q_sectionsRemoved(const QModelIndex &,int,int);
- void _q_sectionsAboutToBeMoved(const QModelIndex &sourceParent, int logicalStart, int logicalEnd, const QModelIndex &destinationParent, int logicalDestination);
- void _q_sectionsMoved(const QModelIndex &sourceParent, int logicalStart, int logicalEnd, const QModelIndex &destinationParent, int logicalDestination);
- void _q_sectionsAboutToBeChanged(const QList<QPersistentModelIndex> &parents = QList<QPersistentModelIndex>(),
- QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint);
- void _q_sectionsChanged(const QList<QPersistentModelIndex> &parents = QList<QPersistentModelIndex>(),
- QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint);
+ void sectionsRemoved(const QModelIndex &,int,int);
+ void sectionsAboutToBeMoved(const QModelIndex &sourceParent, int logicalStart,
+ int logicalEnd, const QModelIndex &destinationParent,
+ int logicalDestination);
+ void sectionsMoved(const QModelIndex &sourceParent, int logicalStart,
+ int logicalEnd, const QModelIndex &destinationParent,
+ int logicalDestination);
+ void sectionsAboutToBeChanged(const QList<QPersistentModelIndex> &parents = QList<QPersistentModelIndex>(),
+ QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint);
+ void sectionsChanged(const QList<QPersistentModelIndex> &parents = QList<QPersistentModelIndex>(),
+ QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint);
bool isSectionSelected(int section) const;
bool isFirstVisibleSection(int section) const;
@@ -156,12 +127,12 @@ public:
inline void prepareSectionSelected() {
if (!selectionModel || !selectionModel->hasSelection())
sectionSelected.clear();
- else if (sectionSelected.count() != sectionCount() * 2)
+ else if (sectionSelected.size() != sectionCount() * 2)
sectionSelected.fill(false, sectionCount() * 2);
else sectionSelected.fill(false);
}
- inline int sectionCount() const {return sectionItems.count();}
+ inline int sectionCount() const {return sectionItems.size();}
inline bool reverse() const {
return orientation == Qt::Horizontal && q_func()->isRightToLeft();
@@ -202,8 +173,8 @@ public:
}
inline void initializeIndexMapping() const {
- if (visualIndices.count() != sectionCount()
- || logicalIndices.count() != sectionCount()) {
+ if (visualIndices.size() != sectionCount()
+ || logicalIndices.size() != sectionCount()) {
visualIndices.resize(sectionCount());
logicalIndices.resize(sectionCount());
for (int s = 0; s < sectionCount(); ++s) {
@@ -214,7 +185,7 @@ public:
}
inline void clearCascadingSections() {
- firstCascadingSection = sectionItems.count();
+ firstCascadingSection = sectionItems.size();
lastCascadingSection = 0;
cascadingSectionSize.clear();
}
@@ -248,6 +219,12 @@ public:
}
}
+ inline void disconnectModel()
+ {
+ for (const QMetaObject::Connection &connection : modelConnections)
+ QObject::disconnect(connection);
+ }
+
void clear();
void flipSortIndicator(int section);
Qt::SortOrder defaultSortOrderForSection(int section) const;
@@ -255,7 +232,7 @@ public:
enum State { NoState, ResizeSection, MoveSection, SelectSections, NoClear } state;
- int offset;
+ int headerOffset;
Qt::Orientation orientation;
Qt::SortOrder sortIndicatorOrder;
int sortIndicatorSection;
@@ -340,6 +317,7 @@ public:
SectionItem section;
};
QList<LayoutChangeItem> layoutChangePersistentSections;
+ std::array<QMetaObject::Connection, 8> modelConnections;
void createSectionItems(int start, int end, int sectionSize, QHeaderView::ResizeMode mode);
void removeSectionsFromSectionItems(int start, int end);
@@ -368,7 +346,7 @@ public:
void setHiddenSectionsFromBitVector(const QBitArray &sectionHidden) {
SectionItem *sectionData = sectionItems.data();
- for (int i = 0; i < sectionHidden.count(); ++i)
+ for (int i = 0; i < sectionHidden.size(); ++i)
sectionData[i].isHidden = sectionHidden.at(i);
}
diff --git a/src/widgets/itemviews/qitemdelegate.cpp b/src/widgets/itemviews/qitemdelegate.cpp
index 9d755c0b55..d1c7bb3d58 100644
--- a/src/widgets/itemviews/qitemdelegate.cpp
+++ b/src/widgets/itemviews/qitemdelegate.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qitemdelegate.h"
@@ -58,6 +22,7 @@
#include <qmetaobject.h>
#include <qtextlayout.h>
#include <private/qabstractitemdelegate_p.h>
+#include <private/qabstractitemmodel_p.h>
#include <private/qtextengine_p.h>
#include <qdebug.h>
#include <qlocale.h>
@@ -94,7 +59,7 @@ public:
inline static QString replaceNewLine(QString text)
{
- text.replace(QLatin1Char('\n'), QChar::LineSeparator);
+ text.replace(u'\n', QChar::LineSeparator);
return text;
}
@@ -292,17 +257,27 @@ QSizeF QItemDelegatePrivate::doTextLayout(int lineWidth) const
When subclassing QItemDelegate to create a delegate that displays items
using a custom renderer, it is important to ensure that the delegate can
- render items suitably for all the required states; e.g. selected,
+ render items suitably for all the required states; such as selected,
disabled, checked. The documentation for the paint() function contains
some hints to show how this can be achieved.
- You can provide custom editors by using a QItemEditorFactory. The
- \l{Color Editor Factory Example} shows how a custom editor can be
- made available to delegates with the default item editor
- factory. This way, there is no need to subclass QItemDelegate. An
- alternative is to reimplement createEditor(), setEditorData(),
- setModelData(), and updateEditorGeometry(). This process is
- described in the \l{Spin Box Delegate Example}.
+ You can provide custom editors by using a QItemEditorFactory. The following
+ code shows how a custom editor can be made available to delegates with the
+ default item editor factory.
+
+ \snippet code/src_gui_itemviews_qitemeditorfactory.cpp setDefaultFactory
+
+ After the default factory has been set, all standard item delegates
+ will use it (also the delegates that were created before setting the
+ default factory).
+
+ This way, you can avoid subclassing QItemDelegate, and all values of the
+ specified type (for example QMetaType::QDateTime) will be edited using the
+ provided editor (like \c{MyFancyDateTimeEdit} in the above example).
+
+ An alternative is to reimplement createEditor(), setEditorData(),
+ setModelData(), and updateEditorGeometry(). This process is described
+ in the \l{A simple delegate}{Model/View Programming overview documentation}.
\section1 QStyledItemDelegate vs. QItemDelegate
@@ -316,9 +291,7 @@ QSizeF QItemDelegatePrivate::doTextLayout(int lineWidth) const
for either class should be equal unless the custom delegate needs to use
the style for drawing.
- \sa {Delegate Classes}, QStyledItemDelegate, QAbstractItemDelegate,
- {Spin Box Delegate Example}, {Settings Editor Example},
- {Icons Example}
+ \sa {Delegate Classes}, QStyledItemDelegate, QAbstractItemDelegate
*/
/*!
@@ -378,8 +351,10 @@ QString QItemDelegatePrivate::valueToText(const QVariant &value, const QStyleOpt
For example, a selected item may need to be displayed differently to
unselected items, as shown in the following code:
- \snippet itemviews/pixelator/pixeldelegate.cpp 2
- \dots
+ \code
+ if (option.state & QStyle::State_Selected)
+ painter->fillRect(option.rect, option.palette.highlight());
+ \endcode
After painting, you should ensure that the painter is returned to its
the state it was supplied in when this function was called. For example,
@@ -432,7 +407,7 @@ void QItemDelegate::paint(QPainter *painter,
Qt::CheckState checkState = Qt::Unchecked;
value = index.data(Qt::CheckStateRole);
if (value.isValid()) {
- checkState = static_cast<Qt::CheckState>(value.toInt());
+ checkState = QtPrivate::legacyEnumValueFromModelData<Qt::CheckState>(value);
checkRect = doCheck(opt, opt.rect, value);
}
@@ -522,10 +497,6 @@ QWidget *QItemDelegate::createEditor(QWidget *parent,
void QItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
-#ifdef QT_NO_PROPERTIES
- Q_UNUSED(editor);
- Q_UNUSED(index);
-#else
QVariant v = index.data(Qt::EditRole);
QByteArray n = editor->metaObject()->userProperty().name();
@@ -534,7 +505,6 @@ void QItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) con
v = QVariant(editor->property(n).metaType());
editor->setProperty(n, v);
}
-#endif
}
/*!
@@ -552,11 +522,6 @@ void QItemDelegate::setModelData(QWidget *editor,
QAbstractItemModel *model,
const QModelIndex &index) const
{
-#ifdef QT_NO_PROPERTIES
- Q_UNUSED(model);
- Q_UNUSED(editor);
- Q_UNUSED(index);
-#else
Q_D(const QItemDelegate);
Q_ASSERT(model);
Q_ASSERT(editor);
@@ -566,7 +531,6 @@ void QItemDelegate::setModelData(QWidget *editor,
model->data(index, Qt::EditRole).userType());
if (!n.isEmpty())
model->setData(index, editor->property(n), Qt::EditRole);
-#endif
}
/*!
@@ -1193,7 +1157,7 @@ bool QItemDelegate::editorEvent(QEvent *event,
return false;
}
- Qt::CheckState state = static_cast<Qt::CheckState>(value.toInt());
+ Qt::CheckState state = QtPrivate::legacyEnumValueFromModelData<Qt::CheckState>(value);
if (flags & Qt::ItemIsUserTristate)
state = ((Qt::CheckState)((state + 1) % 3));
else
@@ -1220,7 +1184,7 @@ QStyleOptionViewItem QItemDelegate::setOptions(const QModelIndex &index,
// set text alignment
value = index.data(Qt::TextAlignmentRole);
if (value.isValid())
- opt.displayAlignment = Qt::Alignment(value.toInt());
+ opt.displayAlignment = QtPrivate::legacyFlagValueFromModelData<Qt::Alignment>(value);
// set foreground brush
value = index.data(Qt::ForegroundRole);
diff --git a/src/widgets/itemviews/qitemdelegate.h b/src/widgets/itemviews/qitemdelegate.h
index bbc088eebc..5ad32e663e 100644
--- a/src/widgets/itemviews/qitemdelegate.h
+++ b/src/widgets/itemviews/qitemdelegate.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QITEMDELEGATE_H
#define QITEMDELEGATE_H
diff --git a/src/widgets/itemviews/qitemeditorfactory.cpp b/src/widgets/itemviews/qitemeditorfactory.cpp
index 4811d32ed0..70d11e1b38 100644
--- a/src/widgets/itemviews/qitemeditorfactory.cpp
+++ b/src/widgets/itemviews/qitemeditorfactory.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <qplatformdefs.h>
#include "qitemeditorfactory.h"
@@ -156,7 +120,7 @@ Q_SIGNALS:
Additional editors can be registered with the registerEditor() function.
- \sa QStyledItemDelegate, {Model/View Programming}, {Color Editor Factory Example}
+ \sa QStyledItemDelegate, {Model/View Programming}
*/
/*!
@@ -399,7 +363,7 @@ void QItemEditorFactory::setDefaultFactory(QItemEditorFactory *factory)
to register widgets without the need to subclass QItemEditorCreatorBase.
\sa QStandardItemEditorCreator, QItemEditorFactory,
- {Model/View Programming}, {Color Editor Factory Example}
+ {Model/View Programming}
*/
/*!
@@ -468,7 +432,7 @@ QItemEditorCreatorBase::~QItemEditorCreatorBase()
property, you should use QStandardItemEditorCreator instead.
\sa QItemEditorCreatorBase, QStandardItemEditorCreator,
- QItemEditorFactory, {Color Editor Factory Example}
+ QItemEditorFactory
*/
/*!
@@ -524,7 +488,7 @@ QItemEditorCreatorBase::~QItemEditorCreatorBase()
\snippet code/src_gui_itemviews_qitemeditorfactory.cpp 3
\sa QItemEditorCreatorBase, QItemEditorCreator,
- QItemEditorFactory, QStyledItemDelegate, {Color Editor Factory Example}
+ QItemEditorFactory, QStyledItemDelegate
*/
/*!
@@ -591,7 +555,7 @@ void QExpandingLineEdit::resizeToContents()
int hintWidth = minimumWidth() + fontMetrics().horizontalAdvance(displayText());
int parentWidth = parent->width();
int maxWidth = isRightToLeft() ? position.x() + oldWidth : parentWidth - position.x();
- int newWidth = qBound(originalWidth, hintWidth, maxWidth);
+ int newWidth = qBound(qMin(originalWidth, maxWidth), hintWidth, maxWidth);
if (widgetOwnsGeometry)
setMaximumWidth(newWidth);
if (isRightToLeft())
diff --git a/src/widgets/itemviews/qitemeditorfactory.h b/src/widgets/itemviews/qitemeditorfactory.h
index 118f6e45e8..2c8ed301cd 100644
--- a/src/widgets/itemviews/qitemeditorfactory.h
+++ b/src/widgets/itemviews/qitemeditorfactory.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QITEMEDITORFACTORY_H
#define QITEMEDITORFACTORY_H
diff --git a/src/widgets/itemviews/qitemeditorfactory_p.h b/src/widgets/itemviews/qitemeditorfactory_p.h
index e78f42b729..4f4252a7c4 100644
--- a/src/widgets/itemviews/qitemeditorfactory_p.h
+++ b/src/widgets/itemviews/qitemeditorfactory_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QITEMEDITORFACTORY_P_H
#define QITEMEDITORFACTORY_P_H
diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp
index f9e3082962..a7f1931947 100644
--- a/src/widgets/itemviews/qlistview.cpp
+++ b/src/widgets/itemviews/qlistview.cpp
@@ -1,51 +1,15 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Copyright (C) 2013 Samuel Gaist <samuel.gaist@deltech.ch>
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// Copyright (C) 2013 Samuel Gaist <samuel.gaist@deltech.ch>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qlistview.h"
#include <qabstractitemdelegate.h>
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
#include <qaccessible.h>
#endif
#include <qapplication.h>
-#include <qpainter.h>
+#include <qstylepainter.h>
#include <qbitmap.h>
#include <qdebug.h>
#if QT_CONFIG(draganddrop)
@@ -124,7 +88,7 @@ extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event);
that can be taken for views that are intended to display items with equal sizes
is to set the \l uniformItemSizes property to true.
- \sa {View Classes}, {Item Views Puzzle Example}, QTreeView, QTableView, QListWidget
+ \sa {View Classes}, QTreeView, QTableView, QListWidget
*/
/*!
@@ -388,7 +352,7 @@ int QListView::spacing() const
/*!
\property QListView::batchSize
\brief the number of items laid out in each batch if \l layoutMode is
- set to \l Batched
+ set to \l Batched.
The default value is 100.
@@ -690,7 +654,7 @@ void QListView::reset()
void QListView::setRootIndex(const QModelIndex &index)
{
Q_D(QListView);
- d->column = qBound(0, d->column, d->model->columnCount(index) - 1);
+ d->column = qMax(0, qMin(d->column, d->model->columnCount(index) - 1));
QAbstractItemView::setRootIndex(index);
// sometimes we get an update before reset() is called
d->clear();
@@ -791,7 +755,10 @@ void QListView::mouseMoveEvent(QMouseEvent *e)
&& d->selectionMode != NoSelection) {
QRect rect(d->pressedPosition, e->position().toPoint() + QPoint(horizontalOffset(), verticalOffset()));
rect = rect.normalized();
- d->viewport->update(d->mapToViewport(rect.united(d->elasticBand)));
+ const int margin = 2 * style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
+ const QRect viewPortRect = rect.united(d->elasticBand)
+ .adjusted(-margin, -margin, margin, margin);
+ d->viewport->update(d->mapToViewport(viewPortRect));
d->elasticBand = rect;
}
}
@@ -805,7 +772,9 @@ void QListView::mouseReleaseEvent(QMouseEvent *e)
QAbstractItemView::mouseReleaseEvent(e);
// #### move this implementation into a dynamic class
if (d->showElasticBand && d->elasticBand.isValid()) {
- d->viewport->update(d->mapToViewport(d->elasticBand));
+ const int margin = 2 * style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
+ const QRect viewPortRect = d->elasticBand.adjusted(-margin, -margin, margin, margin);
+ d->viewport->update(d->mapToViewport(viewPortRect));
d->elasticBand = QRect();
}
}
@@ -927,7 +896,7 @@ void QListView::dropEvent(QDropEvent *event)
if (!event->isAccepted() && d->dropOn(event, &row, &col, &topIndex)) {
const QList<QModelIndex> selIndexes = selectedIndexes();
QList<QPersistentModelIndex> persIndexes;
- persIndexes.reserve(selIndexes.count());
+ persIndexes.reserve(selIndexes.size());
for (const auto &index : selIndexes) {
persIndexes.append(index);
@@ -944,9 +913,10 @@ void QListView::dropEvent(QDropEvent *event)
int r = row == -1 ? model()->rowCount() : (dropRow.row() >= 0 ? dropRow.row() : row);
bool dataMoved = false;
- for (int i = 0; i < persIndexes.count(); ++i) {
+ for (int i = 0; i < persIndexes.size(); ++i) {
const QPersistentModelIndex &pIndex = persIndexes.at(i);
- if (r != pIndex.row()) {
+ // only generate a move when not same row or behind itself
+ if (r != pIndex.row() && r != pIndex.row() + 1) {
// try to move (preserves selection)
dataMoved |= model()->moveRow(QModelIndex(), pIndex.row(), QModelIndex(), r);
if (!dataMoved) // can't move - abort and let QAbstractItemView handle this
@@ -1024,7 +994,7 @@ void QListView::paintEvent(QPaintEvent *e)
return;
QStyleOptionViewItem option;
initViewItemOption(&option);
- QPainter painter(d->viewport);
+ QStylePainter painter(d->viewport);
const QList<QModelIndex> toBeRendered =
d->intersectingSet(e->rect().translated(horizontalOffset(), verticalOffset()), false);
@@ -1095,7 +1065,7 @@ void QListView::paintEvent(QPaintEvent *e)
// is provided by the delegate
QStyle::State oldState = option.state;
option.state &= ~QStyle::State_Selected;
- style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &option, &painter, this);
+ painter.drawPrimitive(QStyle::PE_PanelItemViewRow, option);
option.state = oldState;
alternateBase = !alternateBase;
@@ -1119,7 +1089,7 @@ void QListView::paintEvent(QPaintEvent *e)
opt.rect = d->mapToViewport(d->elasticBand, false).intersected(
d->viewport->rect().adjusted(-16, -16, 16, 16));
painter.save();
- style()->drawControl(QStyle::CE_RubberBand, &opt, &painter);
+ painter.drawControl(QStyle::CE_RubberBand, opt);
painter.restore();
}
#endif
@@ -1133,7 +1103,7 @@ QModelIndex QListView::indexAt(const QPoint &p) const
Q_D(const QListView);
QRect rect(p.x() + horizontalOffset(), p.y() + verticalOffset(), 1, 1);
const QList<QModelIndex> intersectVector = d->intersectingSet(rect);
- QModelIndex index = intersectVector.count() > 0
+ QModelIndex index = intersectVector.size() > 0
? intersectVector.last() : QModelIndex();
if (index.isValid() && visualRect(index).contains(p))
return index;
@@ -1237,7 +1207,10 @@ QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie
}
return d->closestIndex(initialRect, intersectVector);
case MovePageUp: {
- rect.moveTop(rect.top() - d->viewport->height() + 1 );
+ if (rect.height() >= d->viewport->height())
+ return moveCursor(QAbstractItemView::MoveUp, modifiers);
+
+ rect.moveTop(rect.top() - d->viewport->height() + 1);
if (rect.top() < rect.height()) {
rect.setTop(0);
rect.setBottom(1);
@@ -1278,8 +1251,11 @@ QModelIndex QListView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie
}
return d->closestIndex(initialRect, intersectVector);
case MovePageDown: {
- rect.moveTop(rect.top() + d->viewport->height() - 1 );
- if (rect.bottom() > contents.height() - rect.height()){
+ if (rect.height() >= d->viewport->height())
+ return moveCursor(QAbstractItemView::MoveDown, modifiers);
+
+ rect.moveTop(rect.top() + d->viewport->height() - 1);
+ if (rect.bottom() > contents.height() - rect.height()) {
rect.setTop(contents.height() - 1);
rect.setBottom(contents.height());
}
@@ -1369,7 +1345,7 @@ void QListView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFl
if (!d->selectionModel)
return;
- // if we are wrapping, we can only selecte inside the contents rectangle
+ // if we are wrapping, we can only select inside the contents rectangle
int w = qMax(d->contentsSize().width(), d->viewport->width());
int h = qMax(d->contentsSize().height(), d->viewport->height());
if (d->wrap && !QRect(0, 0, w, h).intersects(rect))
@@ -1417,7 +1393,7 @@ void QListView::setSelection(const QRect &rect, QItemSelectionModel::SelectionFl
top = bottom;
bottom = tmp;
}
- // if the rect are on differnet lines, expand
+ // if the rect are on different lines, expand
if (top.top() != bottom.top()) {
// top rectangle
if (isRightToLeft())
@@ -1651,6 +1627,12 @@ void QListView::setModelColumn(int column)
return;
d->column = column;
d->doDelayedItemsLayout();
+#if QT_CONFIG(accessibility)
+ if (QAccessible::isActive()) {
+ QAccessibleTableModelChangeEvent event(this, QAccessibleTableModelChangeEvent::ModelReset);
+ QAccessible::updateAccessibility(&event);
+ }
+#endif
}
int QListView::modelColumn() const
@@ -1820,7 +1802,7 @@ void QListViewPrivate::prepareItemsLayout()
if (q->style()->styleHint(QStyle::SH_ScrollView_FrameOnlyAroundContents)) {
QStyleOption option;
option.initFrom(q);
- frameAroundContents = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, &option) * 2;
+ frameAroundContents = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth, &option, q) * 2;
}
// maximumViewportSize() already takes scrollbar into account if policy is
@@ -1934,7 +1916,7 @@ QSize QListViewPrivate::itemSize(const QStyleOptionViewItem &option, const QMode
const QAbstractItemDelegate *delegate = q->itemDelegateForIndex(index);
return delegate ? delegate->sizeHint(option, index) : QSize();
}
- if (!cachedItemSize.isValid()) { // the last item is probaly the largest, so we use its size
+ if (!cachedItemSize.isValid()) { // the last item is probably the largest, so we use its size
int row = model->rowCount(root) - 1;
QModelIndex sample = model->index(row, column, root);
const QAbstractItemDelegate *delegate = q->itemDelegateForIndex(sample);
@@ -2189,7 +2171,7 @@ void QListModeViewBase::dragMoveEvent(QDragMoveEvent *event)
QRect rect(p.x() + horizontalOffset(), p.y() + verticalOffset(), 1, 1);
rect.adjust(-dd->spacing(), -dd->spacing(), dd->spacing(), dd->spacing());
const QList<QModelIndex> intersectVector = dd->intersectingSet(rect);
- QModelIndex index = intersectVector.count() > 0
+ QModelIndex index = intersectVector.size() > 0
? intersectVector.last() : QModelIndex();
dd->hover = index;
if (!dd->droppingOnItself(event, index)
@@ -2268,7 +2250,7 @@ bool QListModeViewBase::dropOn(QDropEvent *event, int *dropRow, int *dropCol, QM
QRect rect(p.x() + horizontalOffset(), p.y() + verticalOffset(), 1, 1);
rect.adjust(-dd->spacing(), -dd->spacing(), dd->spacing(), dd->spacing());
const QList<QModelIndex> intersectVector = dd->intersectingSet(rect);
- index = intersectVector.count() > 0
+ index = intersectVector.size() > 0
? intersectVector.last() : QModelIndex();
if (!index.isValid())
index = dd->root;
@@ -2314,7 +2296,7 @@ void QListModeViewBase::updateVerticalScrollBar(const QSize &step)
if (verticalScrollMode() == QAbstractItemView::ScrollPerItem
&& ((flow() == QListView::TopToBottom && !isWrapping())
|| (flow() == QListView::LeftToRight && isWrapping()))) {
- const int steps = (flow() == QListView::TopToBottom ? scrollValueMap : segmentPositions).count() - 1;
+ const int steps = (flow() == QListView::TopToBottom ? scrollValueMap : segmentPositions).size() - 1;
if (steps > 0) {
const int pageSteps = perItemScrollingPageSteps(viewport()->height(), contentsSize.height(), isWrapping());
verticalScrollBar()->setSingleStep(1);
@@ -2335,7 +2317,7 @@ void QListModeViewBase::updateHorizontalScrollBar(const QSize &step)
if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem
&& ((flow() == QListView::TopToBottom && isWrapping())
|| (flow() == QListView::LeftToRight && !isWrapping()))) {
- int steps = (flow() == QListView::TopToBottom ? segmentPositions : scrollValueMap).count() - 1;
+ int steps = (flow() == QListView::TopToBottom ? segmentPositions : scrollValueMap).size() - 1;
if (steps > 0) {
const int pageSteps = perItemScrollingPageSteps(viewport()->width(), contentsSize.width(), isWrapping());
horizontalScrollBar()->setSingleStep(1);
@@ -2359,10 +2341,10 @@ int QListModeViewBase::verticalScrollToValue(int index, QListView::ScrollHint hi
} else {
int scrollBarValue = verticalScrollBar()->value();
int numHidden = 0;
- for (const auto &idx : qAsConst(dd->hiddenRows))
+ for (const auto &idx : std::as_const(dd->hiddenRows))
if (idx.row() <= scrollBarValue)
++numHidden;
- value = qBound(0, scrollValueMap.at(verticalScrollBar()->value()) - numHidden, flowPositions.count() - 1);
+ value = qBound(0, scrollValueMap.at(verticalScrollBar()->value()) - numHidden, flowPositions.size() - 1);
}
if (above)
hint = QListView::PositionAtTop;
@@ -2382,7 +2364,7 @@ int QListModeViewBase::horizontalOffset() const
if (horizontalScrollMode() == QAbstractItemView::ScrollPerItem) {
if (isWrapping()) {
if (flow() == QListView::TopToBottom && !segmentPositions.isEmpty()) {
- const int max = segmentPositions.count() - 1;
+ const int max = segmentPositions.size() - 1;
int currentValue = qBound(0, horizontalScrollBar()->value(), max);
int position = segmentPositions.at(currentValue);
int maximumValue = qBound(0, horizontalScrollBar()->maximum(), max);
@@ -2404,13 +2386,13 @@ int QListModeViewBase::verticalOffset() const
if (isWrapping()) {
if (flow() == QListView::LeftToRight && !segmentPositions.isEmpty()) {
int value = verticalScrollBar()->value();
- if (value >= segmentPositions.count())
+ if (value >= segmentPositions.size())
return 0;
return segmentPositions.at(value) - spacing();
}
} else if (flow() == QListView::TopToBottom && !flowPositions.isEmpty()) {
int value = verticalScrollBar()->value();
- if (value > scrollValueMap.count())
+ if (value > scrollValueMap.size())
return 0;
return flowPositions.at(scrollValueMap.at(value)) - spacing();
}
@@ -2428,7 +2410,7 @@ int QListModeViewBase::horizontalScrollToValue(int index, QListView::ScrollHint
if (scrollValueMap.isEmpty())
value = 0;
else
- value = qBound(0, scrollValueMap.at(horizontalScrollBar()->value()), flowPositions.count() - 1);
+ value = qBound(0, scrollValueMap.at(horizontalScrollBar()->value()), flowPositions.size() - 1);
if (leftOf)
hint = QListView::PositionAtTop;
else if (rightOf)
@@ -2450,7 +2432,7 @@ void QListModeViewBase::scrollContentsBy(int dx, int dy, bool scrollElasticBand)
if (isWrapping()) {
if (segmentPositions.isEmpty())
return;
- const int max = segmentPositions.count() - 1;
+ const int max = segmentPositions.size() - 1;
if (horizontal && flow() == QListView::TopToBottom && dx != 0) {
int currentValue = qBound(0, horizontalValue, max);
int previousValue = qBound(0, currentValue + dx, max);
@@ -2467,7 +2449,7 @@ void QListModeViewBase::scrollContentsBy(int dx, int dy, bool scrollElasticBand)
} else {
if (flowPositions.isEmpty())
return;
- const int max = scrollValueMap.count() - 1;
+ const int max = scrollValueMap.size() - 1;
if (vertical && flow() == QListView::TopToBottom && dy != 0) {
int currentValue = qBound(0, verticalValue, max);
int previousValue = qBound(0, currentValue + dy, max);
@@ -2495,11 +2477,11 @@ QListViewItem QListModeViewBase::indexToListViewItem(const QModelIndex &index) c
{
if (flowPositions.isEmpty()
|| segmentPositions.isEmpty()
- || index.row() >= flowPositions.count() - 1)
+ || index.row() >= flowPositions.size() - 1)
return QListViewItem();
const int segment = qBinarySearch<int>(segmentStartRows, index.row(),
- 0, segmentStartRows.count() - 1);
+ 0, segmentStartRows.size() - 1);
QStyleOptionViewItem options;
@@ -2517,7 +2499,7 @@ QListViewItem QListModeViewBase::indexToListViewItem(const QModelIndex &index) c
pos.setY(flowPositions.at(index.row()));
pos.setX(segmentPositions.at(segment));
if (isWrapping()) { // make the items as wide as the segment
- int right = (segment + 1 >= segmentPositions.count()
+ int right = (segment + 1 >= segmentPositions.size()
? contentsSize.width()
: segmentPositions.at(segment + 1));
cellSize.setWidth(right - pos.x());
@@ -2641,7 +2623,7 @@ void QListModeViewBase::doStaticLayout(const QListViewLayoutInfo &info)
deltaSegPosition = 0;
}
// save the flow position of this item
- scrollValueMap.append(flowPositions.count());
+ scrollValueMap.append(flowPositions.size());
flowPositions.append(flowPosition);
// prepare for the next item
deltaSegPosition = qMax(deltaSegHint, deltaSegPosition);
@@ -2657,21 +2639,21 @@ void QListModeViewBase::doStaticLayout(const QListViewLayoutInfo &info)
// set the contents size
QRect rect = info.bounds;
if (info.flow == QListView::LeftToRight) {
- rect.setRight(segmentPositions.count() == 1 ? flowPosition : info.bounds.right());
+ rect.setRight(segmentPositions.size() == 1 ? flowPosition : info.bounds.right());
rect.setBottom(segPosition + deltaSegPosition);
} else { // TopToBottom
rect.setRight(segPosition + deltaSegPosition);
- rect.setBottom(segmentPositions.count() == 1 ? flowPosition : info.bounds.bottom());
+ rect.setBottom(segmentPositions.size() == 1 ? flowPosition : info.bounds.bottom());
}
contentsSize = QSize(rect.right(), rect.bottom());
// if it is the last batch, save the end of the segments
if (info.last == info.max) {
segmentExtents.append(flowPosition);
- scrollValueMap.append(flowPositions.count());
+ scrollValueMap.append(flowPositions.size());
flowPositions.append(flowPosition);
segmentPositions.append(info.wrap ? segPosition + deltaSegPosition : INT_MAX);
}
- // if the new items are visble, update the viewport
+ // if the new items are visible, update the viewport
QRect changedRect(topLeft, rect.bottomRight());
if (clipRect().intersects(changedRect))
viewport()->update();
@@ -2700,10 +2682,10 @@ QList<QModelIndex> QListModeViewBase::intersectingSet(const QRect &area) const
flowStartPosition = area.top();
flowEndPosition = area.bottom();
}
- if (segmentPositions.count() < 2 || flowPositions.isEmpty())
+ if (segmentPositions.size() < 2 || flowPositions.isEmpty())
return ret;
// the last segment position is actually the edge of the last segment
- const int segLast = segmentPositions.count() - 2;
+ const int segLast = segmentPositions.size() - 2;
int seg = qBinarySearch<int>(segmentPositions, segStartPosition, 0, segLast + 1);
for (; seg <= segLast && segmentPositions.at(seg) <= segEndPosition; ++seg) {
int first = segmentStartRows.at(seg);
@@ -2770,15 +2752,15 @@ int QListModeViewBase::perItemScrollingPageSteps(int length, int bounds, bool wr
positions.append(flowPositions.at(itemShown));
}
if (positions.isEmpty() || bounds <= length)
- return positions.count();
+ return positions.size();
if (uniformItemSizes()) {
- for (int i = 1; i < positions.count(); ++i)
+ for (int i = 1; i < positions.size(); ++i)
if (positions.at(i) > 0)
return length / positions.at(i);
return 0; // all items had height 0
}
int pageSteps = 0;
- int steps = positions.count() - 1;
+ int steps = positions.size() - 1;
int max = qMax(length, bounds);
int min = qMin(length, bounds);
int pos = min - (max - positions.constLast());
@@ -2840,7 +2822,7 @@ int QListModeViewBase::perItemScrollToValue(int index, int scrollValue, int view
// ### wrapped scrolling in the flow direction
return flowPositions.at(index + hiddenRowsBefore); // ### always pixel based for now
} else if (!segmentStartRows.isEmpty()) { // we are scrolling in the "segment" direction
- int segment = qBinarySearch<int>(segmentStartRows, index, 0, segmentStartRows.count() - 1);
+ int segment = qBinarySearch<int>(segmentStartRows, index, 0, segmentStartRows.size() - 1);
int leftSegment = segment;
const int rightSegment = leftSegment;
const int bottomCoordinate = segmentPositions.at(segment);
@@ -2883,7 +2865,7 @@ void QListModeViewBase::clear()
void QIconModeViewBase::setPositionForIndex(const QPoint &position, const QModelIndex &index)
{
- if (index.row() >= items.count())
+ if (index.row() >= items.size())
return;
const QSize oldContents = contentsSize;
qq->update(index); // update old position
@@ -2896,7 +2878,7 @@ void QIconModeViewBase::setPositionForIndex(const QPoint &position, const QModel
void QIconModeViewBase::appendHiddenRow(int row)
{
- if (row >= 0 && row < items.count()) //remove item
+ if (row >= 0 && row < items.size()) //remove item
tree.removeLeaf(items.at(row).rect(), row);
QCommonListViewBase::appendHiddenRow(row);
}
@@ -2904,7 +2886,7 @@ void QIconModeViewBase::appendHiddenRow(int row)
void QIconModeViewBase::removeHiddenRow(int row)
{
QCommonListViewBase::removeHiddenRow(row);
- if (row >= 0 && row < items.count()) //insert item
+ if (row >= 0 && row < items.size()) //insert item
tree.insertLeaf(items.at(row).rect(), row);
}
@@ -2915,7 +2897,7 @@ bool QIconModeViewBase::filterStartDrag(Qt::DropActions supportedActions)
// plus adding viewitems to the draggedItems list.
// We need these items to draw the drag items
QModelIndexList indexes = dd->selectionModel->selectedIndexes();
- if (indexes.count() > 0 ) {
+ if (indexes.size() > 0 ) {
if (viewport()->acceptDrops()) {
QModelIndexList::ConstIterator it = indexes.constBegin();
for (; it != indexes.constEnd(); ++it)
@@ -2977,7 +2959,7 @@ bool QIconModeViewBase::filterDropEvent(QDropEvent *e)
// do not delete item on internal move, see filterStartDrag()
dd->dropEventMoved = true;
e->accept(); // we have handled the event
- // if the size has not grown, we need to check if it has shrinked
+ // if the size has not grown, we need to check if it has shrunk
if (contentsSize != contents) {
if ((contentsSize.width() <= contents.width()
|| contentsSize.height() <= contents.height())) {
@@ -3020,7 +3002,7 @@ bool QIconModeViewBase::filterDragMoveEvent(QDragMoveEvent *e)
if (movement() == QListView::Snap) {
QRect rect(snapToGrid(e->position().toPoint() + offset()), gridSize());
const QList<QModelIndex> intersectVector = intersectingSet(rect);
- index = intersectVector.count() > 0 ? intersectVector.last() : QModelIndex();
+ index = intersectVector.size() > 0 ? intersectVector.last() : QModelIndex();
} else {
index = qq->indexAt(e->position().toPoint());
}
@@ -3059,7 +3041,7 @@ void QIconModeViewBase::dataChanged(const QModelIndex &topLeft, const QModelInde
if (column() >= topLeft.column() && column() <= bottomRight.column()) {
QStyleOptionViewItem option;
initViewItemOption(&option);
- const int bottom = qMin(items.count(), bottomRight.row() + 1);
+ const int bottom = qMin(items.size(), bottomRight.row() + 1);
const bool useItemSize = !dd->grid.isValid();
for (int row = topLeft.row(); row < bottom; ++row)
{
@@ -3076,11 +3058,11 @@ void QIconModeViewBase::dataChanged(const QModelIndex &topLeft, const QModelInde
bool QIconModeViewBase::doBatchedItemLayout(const QListViewLayoutInfo &info, int max)
{
- if (info.last >= items.count()) {
+ if (info.last >= items.size()) {
//first we create the items
QStyleOptionViewItem option;
initViewItemOption(&option);
- for (int row = items.count(); row <= info.last; ++row) {
+ for (int row = items.size(); row <= info.last; ++row) {
QSize size = itemSize(option, modelIndex(row));
QListViewItem item(QRect(0, 0, size.width(), size.height()), row); // default pos
items.append(item);
@@ -3092,7 +3074,7 @@ bool QIconModeViewBase::doBatchedItemLayout(const QListViewLayoutInfo &info, int
QListViewItem QIconModeViewBase::indexToListViewItem(const QModelIndex &index) const
{
- if (index.isValid() && index.row() < items.count())
+ if (index.isValid() && index.row() < items.size())
return items.at(index.row());
return QListViewItem();
}
@@ -3170,8 +3152,8 @@ void QIconModeViewBase::doDynamicLayout(const QListViewLayoutInfo &info)
segPosition = topLeft.x();
}
- if (moved.count() != items.count())
- moved.resize(items.count());
+ if (moved.size() != items.size())
+ moved.resize(items.size());
QRect rect(QPoint(), topLeft);
QListViewItem *item = nullptr;
@@ -3269,7 +3251,7 @@ void QIconModeViewBase::doDynamicLayout(const QListViewLayoutInfo &info)
// insert items in tree
for (int row = insertFrom; row <= info.last; ++row)
tree.insertLeaf(items.at(row).rect(), row);
- // if the new items are visble, update the viewport
+ // if the new items are visible, update the viewport
QRect changedRect(topLeft, rect.bottomRight());
if (clipRect().intersects(changedRect))
viewport()->update();
@@ -3299,15 +3281,15 @@ int QIconModeViewBase::itemIndex(const QListViewItem &item) const
if (!item.isValid())
return -1;
int i = item.indexHint;
- if (i < items.count()) {
+ if (i < items.size()) {
if (items.at(i) == item)
return i;
} else {
- i = items.count() - 1;
+ i = items.size() - 1;
}
int j = i;
- int c = items.count();
+ int c = items.size();
bool a = true;
bool b = true;
@@ -3335,9 +3317,9 @@ void QIconModeViewBase::addLeaf(QList<int> &leaf, const QRect &area, uint visite
{
QListViewItem *vi;
QIconModeViewBase *_this = static_cast<QIconModeViewBase *>(data.ptr);
- for (int i = 0; i < leaf.count(); ++i) {
+ for (int i = 0; i < leaf.size(); ++i) {
int idx = leaf.at(i);
- if (idx < 0 || idx >= _this->items.count())
+ if (idx < 0 || idx >= _this->items.size())
continue;
vi = &_this->items[idx];
Q_ASSERT(vi);
@@ -3365,8 +3347,8 @@ void QIconModeViewBase::moveItem(int index, const QPoint &dest)
contentsSize = (QRect(QPoint(0, 0), contentsSize)|QRect(dest, rect.size())).size();
// mark the item as moved
- if (moved.count() != items.count())
- moved.resize(items.count());
+ if (moved.size() != items.size())
+ moved.resize(items.size());
moved.setBit(index, true);
}
@@ -3418,7 +3400,7 @@ void QIconModeViewBase::clear()
void QIconModeViewBase::updateContentsSize()
{
QRect bounding;
- for (int i = 0; i < items.count(); ++i)
+ for (int i = 0; i < items.size(); ++i)
bounding |= items.at(i).rect();
contentsSize = bounding.size();
}
@@ -3428,9 +3410,10 @@ void QIconModeViewBase::updateContentsSize()
*/
void QListView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
{
-#ifndef QT_NO_ACCESSIBILITY
+ QAbstractItemView::currentChanged(current, previous);
+#if QT_CONFIG(accessibility)
if (QAccessible::isActive()) {
- if (current.isValid()) {
+ if (current.isValid() && hasFocus()) {
int entry = visualIndex(current);
QAccessibleEvent event(this, QAccessible::Focus);
event.setChild(entry);
@@ -3438,7 +3421,6 @@ void QListView::currentChanged(const QModelIndex &current, const QModelIndex &pr
}
}
#endif
- QAbstractItemView::currentChanged(current, previous);
}
/*!
@@ -3447,7 +3429,7 @@ void QListView::currentChanged(const QModelIndex &current, const QModelIndex &pr
void QListView::selectionChanged(const QItemSelection &selected,
const QItemSelection &deselected)
{
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
if (QAccessible::isActive()) {
// ### does not work properly for selection ranges.
QModelIndex sel = selected.indexes().value(0);
@@ -3475,7 +3457,7 @@ int QListView::visualIndex(const QModelIndex &index) const
d->executePostedLayout();
QListViewItem itm = d->indexToListViewItem(index);
int visualIndex = d->commonListView->itemIndex(itm);
- for (const auto &idx : qAsConst(d->hiddenRows)) {
+ for (const auto &idx : std::as_const(d->hiddenRows)) {
if (idx.row() <= index.row())
--visualIndex;
}
diff --git a/src/widgets/itemviews/qlistview.h b/src/widgets/itemviews/qlistview.h
index 31b9958770..31b02d660e 100644
--- a/src/widgets/itemviews/qlistview.h
+++ b/src/widgets/itemviews/qlistview.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QLISTVIEW_H
#define QLISTVIEW_H
diff --git a/src/widgets/itemviews/qlistview_p.h b/src/widgets/itemviews/qlistview_p.h
index 085c4866b1..40dabf5656 100644
--- a/src/widgets/itemviews/qlistview_p.h
+++ b/src/widgets/itemviews/qlistview_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QLISTVIEW_P_H
#define QLISTVIEW_P_H
@@ -52,6 +16,7 @@
//
#include <QtWidgets/private/qtwidgetsglobal_p.h>
+#include "qlistview.h"
#include "private/qabstractitemview_p.h"
#include "qbitarray.h"
#include "qbsptree_p.h"
@@ -496,7 +461,7 @@ inline QAbstractItemDelegate *QCommonListViewBase::delegate(const QModelIndex &i
{ return qq->itemDelegateForIndex(idx); }
inline bool QCommonListViewBase::isHidden(int row) const { return dd->isHidden(row); }
-inline int QCommonListViewBase::hiddenCount() const { return dd->hiddenRows.count(); }
+inline int QCommonListViewBase::hiddenCount() const { return dd->hiddenRows.size(); }
inline bool QCommonListViewBase::isRightToLeft() const { return qq->isRightToLeft(); }
diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp
index f04cfe45d9..a91902813a 100644
--- a/src/widgets/itemviews/qlistwidget.cpp
+++ b/src/widgets/itemviews/qlistwidget.cpp
@@ -1,45 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qlistwidget.h"
-#include <qitemdelegate.h>
#include <private/qlistview_p.h>
#include <private/qwidgetitemdata_p.h>
#include <private/qlistwidget_p.h>
@@ -72,7 +35,7 @@ QListModel::~QListModel()
void QListModel::clear()
{
beginResetModel();
- for (int i = 0; i < items.count(); ++i) {
+ for (int i = 0; i < items.size(); ++i) {
if (items.at(i)) {
items.at(i)->d->theid = -1;
items.at(i)->view = nullptr;
@@ -116,8 +79,8 @@ void QListModel::insert(int row, QListWidgetItem *item)
} else {
if (row < 0)
row = 0;
- else if (row > items.count())
- row = items.count();
+ else if (row > items.size())
+ row = items.size();
}
beginInsertRows(QModelIndex(), row, row);
items.insert(row, item);
@@ -127,7 +90,7 @@ void QListModel::insert(int row, QListWidgetItem *item)
void QListModel::insert(int row, const QStringList &labels)
{
- const int count = labels.count();
+ const int count = labels.size();
if (count <= 0)
return;
QListWidget *view = qobject_cast<QListWidget*>(QObject::parent());
@@ -140,8 +103,8 @@ void QListModel::insert(int row, const QStringList &labels)
} else {
if (row < 0)
row = 0;
- else if (row > items.count())
- row = items.count();
+ else if (row > items.size())
+ row = items.size();
beginInsertRows(QModelIndex(), row, row + count - 1);
for (int i = 0; i < count; ++i) {
QListWidgetItem *item = new QListWidgetItem(labels.at(i));
@@ -155,7 +118,7 @@ void QListModel::insert(int row, const QStringList &labels)
QListWidgetItem *QListModel::take(int row)
{
- if (row < 0 || row >= items.count())
+ if (row < 0 || row >= items.size())
return nullptr;
beginRemoveRows(QModelIndex(), row, row);
@@ -169,8 +132,8 @@ QListWidgetItem *QListModel::take(int row)
void QListModel::move(int srcRow, int dstRow)
{
if (srcRow == dstRow
- || srcRow < 0 || srcRow >= items.count()
- || dstRow < 0 || dstRow > items.count())
+ || srcRow < 0 || srcRow >= items.size()
+ || dstRow < 0 || dstRow > items.size())
return;
if (!beginMoveRows(QModelIndex(), srcRow, srcRow, QModelIndex(), dstRow))
@@ -183,7 +146,7 @@ void QListModel::move(int srcRow, int dstRow)
int QListModel::rowCount(const QModelIndex &parent) const
{
- return parent.isValid() ? 0 : items.count();
+ return parent.isValid() ? 0 : items.size();
}
QModelIndex QListModel::index(const QListWidgetItem *item_) const
@@ -194,7 +157,7 @@ QModelIndex QListModel::index(const QListWidgetItem *item_) const
return QModelIndex();
int row;
const int theid = item->d->theid;
- if (theid >= 0 && theid < items.count() && items.at(theid) == item) {
+ if (theid >= 0 && theid < items.size() && items.at(theid) == item) {
row = theid;
} else { // we need to search for the item
row = items.lastIndexOf(item); // lastIndexOf is an optimization in favor of indexOf
@@ -214,14 +177,14 @@ QModelIndex QListModel::index(int row, int column, const QModelIndex &parent) co
QVariant QListModel::data(const QModelIndex &index, int role) const
{
- if (!index.isValid() || index.row() >= items.count())
+ if (!index.isValid() || index.row() >= items.size())
return QVariant();
return items.at(index.row())->data(role);
}
bool QListModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
- if (!index.isValid() || index.row() >= items.count())
+ if (!index.isValid() || index.row() >= items.size())
return false;
items.at(index.row())->setData(role, value);
return true;
@@ -244,10 +207,10 @@ bool QListModel::clearItemData(const QModelIndex &index)
QMap<int, QVariant> QListModel::itemData(const QModelIndex &index) const
{
QMap<int, QVariant> roles;
- if (!index.isValid() || index.row() >= items.count())
+ if (!index.isValid() || index.row() >= items.size())
return roles;
QListWidgetItem *itm = items.at(index.row());
- for (int i = 0; i < itm->d->values.count(); ++i) {
+ for (int i = 0; i < itm->d->values.size(); ++i) {
roles.insert(itm->d->values.at(i).role,
itm->d->values.at(i).value);
}
@@ -324,7 +287,7 @@ bool QListModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int co
Qt::ItemFlags QListModel::flags(const QModelIndex &index) const
{
- if (!index.isValid() || index.row() >= items.count() || index.model() != this)
+ if (!index.isValid() || index.row() >= items.size() || index.model() != this)
return Qt::ItemIsDropEnabled; // we allow drops outside the items
return items.at(index.row())->flags();
}
@@ -336,18 +299,18 @@ void QListModel::sort(int column, Qt::SortOrder order)
emit layoutAboutToBeChanged({}, QAbstractItemModel::VerticalSortHint);
- QList<QPair<QListWidgetItem *, int>> sorting(items.count());
- for (int i = 0; i < items.count(); ++i) {
+ QList<QPair<QListWidgetItem *, int>> sorting(items.size());
+ for (int i = 0; i < items.size(); ++i) {
QListWidgetItem *item = items.at(i);
sorting[i].first = item;
sorting[i].second = i;
}
const auto compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
- std::sort(sorting.begin(), sorting.end(), compare);
+ std::stable_sort(sorting.begin(), sorting.end(), compare);
QModelIndexList fromIndexes;
QModelIndexList toIndexes;
- const int sortingCount = sorting.count();
+ const int sortingCount = sorting.size();
fromIndexes.reserve(sortingCount);
toIndexes.reserve(sortingCount);
for (int r = 0; r < sortingCount; ++r) {
@@ -364,76 +327,34 @@ void QListModel::sort(int column, Qt::SortOrder order)
/**
* This function assumes that all items in the model except the items that are between
* (inclusive) start and end are sorted.
- * With these assumptions, this function can ensure that the model is sorted in a
- * much more efficient way than doing a naive 'sort everything'.
- * (provided that the range is relatively small compared to the total number of items)
*/
void QListModel::ensureSorted(int column, Qt::SortOrder order, int start, int end)
{
if (column != 0)
return;
- const int count = end - start + 1;
- QList<QPair<QListWidgetItem *, int>> sorting(count);
- for (int i = 0; i < count; ++i) {
- sorting[i].first = items.at(start + i);
- sorting[i].second = start + i;
- }
+ const auto compareLt = [](const QListWidgetItem *left, const QListWidgetItem *right) -> bool {
+ return *left < *right;
+ };
- const auto compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
- std::sort(sorting.begin(), sorting.end(), compare);
-
- QModelIndexList oldPersistentIndexes = persistentIndexList();
- QModelIndexList newPersistentIndexes = oldPersistentIndexes;
- QList<QListWidgetItem*> tmp = items;
- QList<QListWidgetItem*>::iterator lit = tmp.begin();
- bool changed = false;
- for (int i = 0; i < count; ++i) {
- int oldRow = sorting.at(i).second;
- int tmpitepos = lit - tmp.begin();
- QListWidgetItem *item = tmp.takeAt(oldRow);
- if (tmpitepos > tmp.size())
- --tmpitepos;
- lit = tmp.begin() + tmpitepos;
- lit = sortedInsertionIterator(lit, tmp.end(), order, item);
- int newRow = qMax<qsizetype>(lit - tmp.begin(), 0);
- lit = tmp.insert(lit, item);
- if (newRow != oldRow) {
- if (!changed) {
- emit layoutAboutToBeChanged({}, QAbstractItemModel::VerticalSortHint);
- oldPersistentIndexes = persistentIndexList();
- newPersistentIndexes = oldPersistentIndexes;
- changed = true;
- }
- for (int j = i + 1; j < count; ++j) {
- int otherRow = sorting.at(j).second;
- if (oldRow < otherRow && newRow >= otherRow)
- --sorting[j].second;
- else if (oldRow > otherRow && newRow <= otherRow)
- ++sorting[j].second;
- }
- for (int k = 0; k < newPersistentIndexes.count(); ++k) {
- QModelIndex pi = newPersistentIndexes.at(k);
- int oldPersistentRow = pi.row();
- int newPersistentRow = oldPersistentRow;
- if (oldPersistentRow == oldRow)
- newPersistentRow = newRow;
- else if (oldRow < oldPersistentRow && newRow >= oldPersistentRow)
- newPersistentRow = oldPersistentRow - 1;
- else if (oldRow > oldPersistentRow && newRow <= oldPersistentRow)
- newPersistentRow = oldPersistentRow + 1;
- if (newPersistentRow != oldPersistentRow)
- newPersistentIndexes[k] = createIndex(newPersistentRow,
- pi.column(), pi.internalPointer());
- }
- }
- }
+ const auto compareGt = [](const QListWidgetItem *left, const QListWidgetItem *right) -> bool {
+ return *right < *left;
+ };
- if (changed) {
- items = tmp;
- changePersistentIndexList(oldPersistentIndexes, newPersistentIndexes);
- emit layoutChanged({}, QAbstractItemModel::VerticalSortHint);
- }
+ /** Check if range [start,end] is already in sorted position in list.
+ * Take for this the assumption, that outside [start,end] the list
+ * is already sorted. Therefore the sorted check has to be extended
+ * to the first element that is known to be sorted before the range
+ * [start, end], which is (start-1) and the first element after the
+ * range [start, end], which is (end+2) due to end being included.
+ */
+ const auto beginChangedIterator = items.constBegin() + qMax(start - 1, 0);
+ const auto endChangedIterator = items.constBegin() + qMin(end + 2, items.size());
+ const bool needsSorting = !std::is_sorted(beginChangedIterator, endChangedIterator,
+ order == Qt::AscendingOrder ? compareLt : compareGt);
+
+ if (needsSorting)
+ sort(column, order);
}
bool QListModel::itemLessThan(const QPair<QListWidgetItem*,int> &left,
@@ -480,7 +401,7 @@ QMimeData *QListModel::internalMimeData() const
QMimeData *QListModel::mimeData(const QModelIndexList &indexes) const
{
QList<QListWidgetItem*> itemlist;
- const int indexesCount = indexes.count();
+ const int indexesCount = indexes.size();
itemlist.reserve(indexesCount);
for (int i = 0; i < indexesCount; ++i)
itemlist << at(indexes.at(i).row());
@@ -501,7 +422,7 @@ bool QListModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
if (index.isValid())
row = index.row();
else if (row == -1)
- row = items.count();
+ row = items.size();
return view->dropMimeData(row, data, action);
}
@@ -738,7 +659,7 @@ void QListWidgetItem::setData(int role, const QVariant &value)
{
bool found = false;
role = (role == Qt::EditRole ? Qt::DisplayRole : role);
- for (int i = 0; i < d->values.count(); ++i) {
+ for (int i = 0; i < d->values.size(); ++i) {
if (d->values.at(i).role == role) {
if (d->values.at(i).value == value)
return;
@@ -766,7 +687,7 @@ void QListWidgetItem::setData(int role, const QVariant &value)
QVariant QListWidgetItem::data(int role) const
{
role = (role == Qt::EditRole ? Qt::DisplayRole : role);
- for (int i = 0; i < d->values.count(); ++i)
+ for (int i = 0; i < d->values.size(); ++i)
if (d->values.at(i).role == role)
return d->values.at(i).value;
return QVariant();
@@ -934,11 +855,24 @@ QDataStream &operator>>(QDataStream &in, QListWidgetItem &item)
*/
/*!
+ \if defined(qt7)
+
+ \fn Qt::Alignment QListWidgetItem::textAlignment() const
+
+ Returns the text alignment for the list item.
+
+ \else
+
\fn int QListWidgetItem::textAlignment() const
Returns the text alignment for the list item.
- \sa Qt::AlignmentFlag
+ \note This function returns an int for historical reasons. It will
+ be corrected to return Qt::Alignment in Qt 7.
+
+ \sa Qt::Alignment
+
+ \endif
*/
/*!
@@ -1092,11 +1026,26 @@ void QListWidgetItem::setFlags(Qt::ItemFlags aflags)
*/
/*!
+ \obsolete [6.4] Use the overload that takes a Qt::Alignment argument.
+
\fn void QListWidgetItem::setTextAlignment(int alignment)
Sets the list item's text alignment to \a alignment.
- \sa Qt::AlignmentFlag
+ \sa Qt::Alignment
+*/
+
+/*!
+ \since 6.4
+
+ \fn void QListWidgetItem::setTextAlignment(Qt::Alignment alignment)
+
+ Sets the list item's text alignment to \a alignment.
+*/
+
+/*!
+ \fn void QListWidgetItem::setTextAlignment(Qt::AlignmentFlag alignment)
+ \internal
*/
/*!
@@ -1134,57 +1083,71 @@ void QListWidgetPrivate::setup()
Q_Q(QListWidget);
q->QListView::setModel(new QListModel(q));
// view signals
- QObject::connect(q, SIGNAL(pressed(QModelIndex)), q, SLOT(_q_emitItemPressed(QModelIndex)));
- QObject::connect(q, SIGNAL(clicked(QModelIndex)), q, SLOT(_q_emitItemClicked(QModelIndex)));
- QObject::connect(q, SIGNAL(doubleClicked(QModelIndex)),
- q, SLOT(_q_emitItemDoubleClicked(QModelIndex)));
- QObject::connect(q, SIGNAL(activated(QModelIndex)),
- q, SLOT(_q_emitItemActivated(QModelIndex)));
- QObject::connect(q, SIGNAL(entered(QModelIndex)), q, SLOT(_q_emitItemEntered(QModelIndex)));
- QObject::connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
- q, SLOT(_q_emitItemChanged(QModelIndex)));
- QObject::connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
- q, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
- QObject::connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)), q, SLOT(_q_sort()));
-}
-
-void QListWidgetPrivate::_q_emitItemPressed(const QModelIndex &index)
+ connections = {
+ QObjectPrivate::connect(q, &QListWidget::pressed,
+ this, &QListWidgetPrivate::emitItemPressed),
+ QObjectPrivate::connect(q, &QListWidget::clicked,
+ this, &QListWidgetPrivate::emitItemClicked),
+ QObjectPrivate::connect(q, &QListWidget::doubleClicked,
+ this, &QListWidgetPrivate::emitItemDoubleClicked),
+ QObjectPrivate::connect(q, &QListWidget::activated,
+ this, &QListWidgetPrivate::emitItemActivated),
+ QObjectPrivate::connect(q, &QListWidget::entered,
+ this, &QListWidgetPrivate::emitItemEntered),
+ QObjectPrivate::connect(model, &QAbstractItemModel::dataChanged,
+ this, &QListWidgetPrivate::emitItemChanged),
+ QObjectPrivate::connect(model, &QAbstractItemModel::dataChanged,
+ this, &QListWidgetPrivate::dataChanged),
+ QObjectPrivate::connect(model, &QAbstractItemModel::columnsRemoved,
+ this, &QListWidgetPrivate::sort)
+ };
+}
+
+void QListWidgetPrivate::clearConnections()
+{
+ for (const QMetaObject::Connection &connection : connections)
+ QObject::disconnect(connection);
+ for (const QMetaObject::Connection &connection : selectionModelConnections)
+ QObject::disconnect(connection);
+}
+
+void QListWidgetPrivate::emitItemPressed(const QModelIndex &index)
{
Q_Q(QListWidget);
emit q->itemPressed(listModel()->at(index.row()));
}
-void QListWidgetPrivate::_q_emitItemClicked(const QModelIndex &index)
+void QListWidgetPrivate::emitItemClicked(const QModelIndex &index)
{
Q_Q(QListWidget);
emit q->itemClicked(listModel()->at(index.row()));
}
-void QListWidgetPrivate::_q_emitItemDoubleClicked(const QModelIndex &index)
+void QListWidgetPrivate::emitItemDoubleClicked(const QModelIndex &index)
{
Q_Q(QListWidget);
emit q->itemDoubleClicked(listModel()->at(index.row()));
}
-void QListWidgetPrivate::_q_emitItemActivated(const QModelIndex &index)
+void QListWidgetPrivate::emitItemActivated(const QModelIndex &index)
{
Q_Q(QListWidget);
emit q->itemActivated(listModel()->at(index.row()));
}
-void QListWidgetPrivate::_q_emitItemEntered(const QModelIndex &index)
+void QListWidgetPrivate::emitItemEntered(const QModelIndex &index)
{
Q_Q(QListWidget);
emit q->itemEntered(listModel()->at(index.row()));
}
-void QListWidgetPrivate::_q_emitItemChanged(const QModelIndex &index)
+void QListWidgetPrivate::emitItemChanged(const QModelIndex &index)
{
Q_Q(QListWidget);
emit q->itemChanged(listModel()->at(index.row()));
}
-void QListWidgetPrivate::_q_emitCurrentItemChanged(const QModelIndex &current,
+void QListWidgetPrivate::emitCurrentItemChanged(const QModelIndex &current,
const QModelIndex &previous)
{
Q_Q(QListWidget);
@@ -1202,14 +1165,14 @@ void QListWidgetPrivate::_q_emitCurrentItemChanged(const QModelIndex &current,
emit q->currentRowChanged(persistentCurrent.row());
}
-void QListWidgetPrivate::_q_sort()
+void QListWidgetPrivate::sort()
{
if (sortingEnabled)
model->sort(0, sortOrder);
}
-void QListWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft,
- const QModelIndex &bottomRight)
+void QListWidgetPrivate::dataChanged(const QModelIndex &topLeft,
+ const QModelIndex &bottomRight)
{
if (sortingEnabled && topLeft.isValid() && bottomRight.isValid())
listModel()->ensureSorted(topLeft.column(), sortOrder,
@@ -1415,6 +1378,8 @@ QListWidget::QListWidget(QWidget *parent)
QListWidget::~QListWidget()
{
+ Q_D(QListWidget);
+ d->clearConnections();
}
/*!
@@ -1425,20 +1390,18 @@ void QListWidget::setSelectionModel(QItemSelectionModel *selectionModel)
{
Q_D(QListWidget);
- if (d->selectionModel) {
- QObject::disconnect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- this, SLOT(_q_emitCurrentItemChanged(QModelIndex,QModelIndex)));
- QObject::disconnect(d->selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
- this, SIGNAL(itemSelectionChanged()));
- }
+ for (const QMetaObject::Connection &connection : d->selectionModelConnections)
+ disconnect(connection);
QListView::setSelectionModel(selectionModel);
if (d->selectionModel) {
- QObject::connect(d->selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- this, SLOT(_q_emitCurrentItemChanged(QModelIndex,QModelIndex)));
- QObject::connect(d->selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
- this, SIGNAL(itemSelectionChanged()));
+ d->selectionModelConnections = {
+ QObjectPrivate::connect(d->selectionModel, &QItemSelectionModel::currentChanged,
+ d, &QListWidgetPrivate::emitCurrentItemChanged),
+ QObject::connect(d->selectionModel, &QItemSelectionModel::selectionChanged,
+ this, &QListWidget::itemSelectionChanged)
+ };
}
}
@@ -1768,7 +1731,7 @@ QList<QListWidgetItem*> QListWidget::selectedItems() const
Q_D(const QListWidget);
QModelIndexList indexes = selectionModel()->selectedIndexes();
QList<QListWidgetItem*> items;
- const int numIndexes = indexes.count();
+ const int numIndexes = indexes.size();
items.reserve(numIndexes);
for (int i = 0; i < numIndexes; ++i)
items.append(d->listModel()->at(indexes.at(i).row()));
@@ -1845,7 +1808,7 @@ QMimeData *QListWidget::mimeData(const QList<QListWidgetItem *> &items) const
// if non empty, it's called from the model's own mimeData
if (cachedIndexes.isEmpty()) {
- cachedIndexes.reserve(items.count());
+ cachedIndexes.reserve(items.size());
for (QListWidgetItem *item : items)
cachedIndexes << indexFromItem(item);
diff --git a/src/widgets/itemviews/qlistwidget.h b/src/widgets/itemviews/qlistwidget.h
index 594266d71b..c6ba714c43 100644
--- a/src/widgets/itemviews/qlistwidget.h
+++ b/src/widgets/itemviews/qlistwidget.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QLISTWIDGET_H
#define QLISTWIDGET_H
@@ -109,10 +73,22 @@ public:
{ return qvariant_cast<QFont>(data(Qt::FontRole)); }
inline void setFont(const QFont &font);
+#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
inline int textAlignment() const
{ return data(Qt::TextAlignmentRole).toInt(); }
+#else
+ inline Qt::Alignment textAlignment() const
+ { return qvariant_cast<Qt::Alignment>(data(Qt::TextAlignmentRole)); }
+#endif
+#if QT_DEPRECATED_SINCE(6, 4)
+ QT_DEPRECATED_VERSION_X_6_4("Use the overload taking Qt::Alignment")
inline void setTextAlignment(int alignment)
{ setData(Qt::TextAlignmentRole, alignment); }
+ inline void setTextAlignment(Qt::AlignmentFlag alignment)
+ { setData(Qt::TextAlignmentRole, QVariant::fromValue(Qt::Alignment(alignment))); }
+#endif
+ inline void setTextAlignment(Qt::Alignment alignment)
+ { setData(Qt::TextAlignmentRole, QVariant::fromValue(alignment)); }
inline QBrush background() const
{ return qvariant_cast<QBrush>(data(Qt::BackgroundRole)); }
@@ -125,7 +101,7 @@ public:
{ setData(Qt::ForegroundRole, brush.style() != Qt::NoBrush ? QVariant(brush) : QVariant()); }
inline Qt::CheckState checkState() const
- { return static_cast<Qt::CheckState>(data(Qt::CheckStateRole).toInt()); }
+ { return qvariant_cast<Qt::CheckState>(data(Qt::CheckStateRole)); }
inline void setCheckState(Qt::CheckState state)
{ setData(Qt::CheckStateRole, static_cast<int>(state)); }
@@ -282,16 +258,6 @@ private:
Q_DECLARE_PRIVATE(QListWidget)
Q_DISABLE_COPY(QListWidget)
-
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemPressed(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemClicked(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemDoubleClicked(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemActivated(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemEntered(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemChanged(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitCurrentItemChanged(const QModelIndex &previous, const QModelIndex &current))
- Q_PRIVATE_SLOT(d_func(), void _q_sort())
- Q_PRIVATE_SLOT(d_func(), void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight))
};
inline void QListWidget::removeItemWidget(QListWidgetItem *aItem)
diff --git a/src/widgets/itemviews/qlistwidget_p.h b/src/widgets/itemviews/qlistwidget_p.h
index ec5afa7f8d..1007542ddc 100644
--- a/src/widgets/itemviews/qlistwidget_p.h
+++ b/src/widgets/itemviews/qlistwidget_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QLISTWIDGET_P_H
#define QLISTWIDGET_P_H
@@ -54,10 +18,11 @@
#include <QtCore/qabstractitemmodel.h>
#include <QtWidgets/qabstractitemview.h>
#include <QtWidgets/qlistwidget.h>
-#include <qitemdelegate.h>
#include <private/qlistview_p.h>
#include <private/qwidgetitemdata_p.h>
+#include <array>
+
QT_REQUIRE_CONFIG(listwidget);
QT_BEGIN_NAMESPACE
@@ -149,17 +114,21 @@ public:
QListWidgetPrivate() : QListViewPrivate(), sortOrder(Qt::AscendingOrder), sortingEnabled(false) {}
inline QListModel *listModel() const { return qobject_cast<QListModel*>(model); }
void setup();
- void _q_emitItemPressed(const QModelIndex &index);
- void _q_emitItemClicked(const QModelIndex &index);
- void _q_emitItemDoubleClicked(const QModelIndex &index);
- void _q_emitItemActivated(const QModelIndex &index);
- void _q_emitItemEntered(const QModelIndex &index);
- void _q_emitItemChanged(const QModelIndex &index);
- void _q_emitCurrentItemChanged(const QModelIndex &current, const QModelIndex &previous);
- void _q_sort();
- void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ void clearConnections();
+ void emitItemPressed(const QModelIndex &index);
+ void emitItemClicked(const QModelIndex &index);
+ void emitItemDoubleClicked(const QModelIndex &index);
+ void emitItemActivated(const QModelIndex &index);
+ void emitItemEntered(const QModelIndex &index);
+ void emitItemChanged(const QModelIndex &index);
+ void emitCurrentItemChanged(const QModelIndex &current, const QModelIndex &previous);
+ void sort();
+ void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
Qt::SortOrder sortOrder;
bool sortingEnabled;
+
+ std::array<QMetaObject::Connection, 8> connections;
+ std::array<QMetaObject::Connection, 2> selectionModelConnections;
};
class QListWidgetItemPrivate
diff --git a/src/widgets/itemviews/qstyleditemdelegate.cpp b/src/widgets/itemviews/qstyleditemdelegate.cpp
index 975735eb15..54c1fb4f52 100644
--- a/src/widgets/itemviews/qstyleditemdelegate.cpp
+++ b/src/widgets/itemviews/qstyleditemdelegate.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qstyleditemdelegate.h"
@@ -66,6 +30,7 @@
#include <qmetaobject.h>
#include <qtextlayout.h>
#include <private/qabstractitemdelegate_p.h>
+#include <private/qabstractitemmodel_p.h>
#include <private/qtextengine_p.h>
#include <private/qlayoutengine_p.h>
#include <qdebug.h>
@@ -150,7 +115,7 @@ public:
\row \li \l Qt::AccessibleDescriptionRole \li QString
\row \li \l Qt::AccessibleTextRole \li QString
\endomit
- \row \li \l Qt::BackgroundRole \li QBrush (\since 4.2)
+ \row \li \l Qt::BackgroundRole \li QBrush \since 4.2
\row \li \l Qt::CheckStateRole \li Qt::CheckState
\row \li \l Qt::DecorationRole \li QIcon, QPixmap, QImage and QColor
\row \li \l Qt::DisplayRole \li QString and types with a string representation
@@ -161,7 +126,7 @@ public:
\row \li \l Qt::StatusTipRole \li
\endomit
\row \li \l Qt::TextAlignmentRole \li Qt::Alignment
- \row \li \l Qt::ForegroundRole \li QBrush (\since 4.2)
+ \row \li \l Qt::ForegroundRole \li QBrush \since 4.2
\omit
\row \li \l Qt::ToolTipRole
\row \li \l Qt::WhatsThisRole
@@ -172,12 +137,17 @@ public:
instance provided by QItemEditorFactory is installed on all item
delegates. You can set a custom factory using
setItemEditorFactory() or set a new default factory with
- QItemEditorFactory::setDefaultFactory(). It is the data stored in
- the item model with the \l{Qt::}{EditRole} that is edited. See the
- QItemEditorFactory class for a more high-level introduction to
- item editor factories. The \l{Color Editor Factory Example}{Color
- Editor Factory} example shows how to create custom editors with a
- factory.
+ QItemEditorFactory::setDefaultFactory().
+
+ \snippet code/src_gui_itemviews_qitemeditorfactory.cpp setDefaultFactory
+
+ After the new factory has been set, all standard item delegates
+ will use it (i.e, also delegates that were created before the new
+ default factory was set).
+
+ It is the data stored in the item model with the \l{Qt::}{EditRole}
+ that is edited. See the QItemEditorFactory class for a more
+ high-level introduction to item editor factories.
\section1 Subclassing QStyledItemDelegate
@@ -239,8 +209,7 @@ public:
documentation for details.
\sa {Delegate Classes}, QItemDelegate, QAbstractItemDelegate, QStyle,
- {Spin Box Delegate Example}, {Star Delegate Example}, {Color
- Editor Factory Example}
+ {Star Delegate Example}
*/
@@ -302,7 +271,7 @@ void QStyledItemDelegate::initStyleOption(QStyleOptionViewItem *option,
value = modelRoleDataSpan.dataForRole(Qt::TextAlignmentRole);
if (value->isValid() && !value->isNull())
- option->displayAlignment = Qt::Alignment(value->toInt());
+ option->displayAlignment = QtPrivate::legacyFlagValueFromModelData<Qt::Alignment>(*value);
value = modelRoleDataSpan.dataForRole(Qt::ForegroundRole);
if (value->canConvert<QBrush>())
@@ -311,7 +280,7 @@ void QStyledItemDelegate::initStyleOption(QStyleOptionViewItem *option,
value = modelRoleDataSpan.dataForRole(Qt::CheckStateRole);
if (value->isValid() && !value->isNull()) {
option->features |= QStyleOptionViewItem::HasCheckIndicator;
- option->checkState = static_cast<Qt::CheckState>(value->toInt());
+ option->checkState = QtPrivate::legacyEnumValueFromModelData<Qt::CheckState>(*value);
}
value = modelRoleDataSpan.dataForRole(Qt::DecorationRole);
@@ -320,6 +289,10 @@ void QStyledItemDelegate::initStyleOption(QStyleOptionViewItem *option,
switch (value->userType()) {
case QMetaType::QIcon: {
option->icon = qvariant_cast<QIcon>(*value);
+ if (option->icon.isNull()) {
+ option->features &= ~QStyleOptionViewItem::HasDecoration;
+ break;
+ }
QIcon::Mode mode;
if (!(option->state & QStyle::State_Enabled))
mode = QIcon::Disabled;
@@ -458,10 +431,6 @@ QWidget *QStyledItemDelegate::createEditor(QWidget *parent,
*/
void QStyledItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
-#ifdef QT_NO_PROPERTIES
- Q_UNUSED(editor);
- Q_UNUSED(index);
-#else
QVariant v = index.data(Qt::EditRole);
QByteArray n = editor->metaObject()->userProperty().name();
@@ -470,7 +439,6 @@ void QStyledItemDelegate::setEditorData(QWidget *editor, const QModelIndex &inde
v = QVariant(editor->property(n).metaType());
editor->setProperty(n, v);
}
-#endif
}
/*!
@@ -487,11 +455,6 @@ void QStyledItemDelegate::setModelData(QWidget *editor,
QAbstractItemModel *model,
const QModelIndex &index) const
{
-#ifdef QT_NO_PROPERTIES
- Q_UNUSED(model);
- Q_UNUSED(editor);
- Q_UNUSED(index);
-#else
Q_D(const QStyledItemDelegate);
Q_ASSERT(model);
Q_ASSERT(editor);
@@ -501,7 +464,6 @@ void QStyledItemDelegate::setModelData(QWidget *editor,
model->data(index, Qt::EditRole).userType());
if (!n.isEmpty())
model->setData(index, editor->property(n), Qt::EditRole);
-#endif
}
/*!
@@ -519,15 +481,7 @@ void QStyledItemDelegate::updateEditorGeometry(QWidget *editor,
QStyleOptionViewItem opt = option;
initStyleOption(&opt, index);
- // let the editor take up all available space
- //if the editor is not a QLineEdit
- //or it is in a QTableView
-#if QT_CONFIG(tableview) && QT_CONFIG(lineedit)
- if (qobject_cast<QExpandingLineEdit*>(editor) && !qobject_cast<const QTableView*>(widget))
- opt.showDecorationSelected = editor->style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, nullptr, editor);
- else
-#endif
- opt.showDecorationSelected = true;
+ opt.showDecorationSelected = editor->style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, nullptr, editor);
QStyle *style = widget ? widget->style() : QApplication::style();
QRect geom = style->subElementRect(QStyle::SE_ItemViewItemText, &opt, widget);
@@ -575,8 +529,9 @@ void QStyledItemDelegate::setItemEditorFactory(QItemEditorFactory *factory)
\li \uicontrol Esc
\endlist
- If the \a editor's type is QTextEdit or QPlainTextEdit then \uicontrol Enter and
- \uicontrol Return keys are \e not handled.
+ If the \a editor's type is QTextEdit or QPlainTextEdit then \uicontrol Tab,
+ \uicontrol Backtab, \uicontrol Enter and \uicontrol Return keys are \e not
+ handled.
In the case of \uicontrol Tab, \uicontrol Backtab, \uicontrol Enter and \uicontrol Return
key press events, the \a editor's data is committed to the model
@@ -644,7 +599,7 @@ bool QStyledItemDelegate::editorEvent(QEvent *event,
return false;
}
- Qt::CheckState state = static_cast<Qt::CheckState>(value.toInt());
+ Qt::CheckState state = QtPrivate::legacyEnumValueFromModelData<Qt::CheckState>(value);
if (flags & Qt::ItemIsUserTristate)
state = ((Qt::CheckState)((state + 1) % 3));
else
diff --git a/src/widgets/itemviews/qstyleditemdelegate.h b/src/widgets/itemviews/qstyleditemdelegate.h
index 2df2450f07..23f059355d 100644
--- a/src/widgets/itemviews/qstyleditemdelegate.h
+++ b/src/widgets/itemviews/qstyleditemdelegate.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QSTYLEDITEMDELEGATE_H
#define QSTYLEDITEMDELEGATE_H
diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp
index d1793a3049..5726348bc5 100644
--- a/src/widgets/itemviews/qtableview.cpp
+++ b/src/widgets/itemviews/qtableview.cpp
@@ -1,46 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qtableview.h"
#include <qheaderview.h>
-#include <qitemdelegate.h>
+#include <qabstractitemdelegate.h>
#include <qapplication.h>
#include <qpainter.h>
#include <qstyle.h>
@@ -55,7 +19,7 @@
#include <private/qtableview_p.h>
#include <private/qheaderview_p.h>
#include <private/qscrollbar_p.h>
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
#include <qaccessible.h>
#endif
@@ -206,6 +170,13 @@ QDebug operator<<(QDebug str, const QSpanCollection::Span &span)
str << '(' << span.top() << ',' << span.left() << ',' << span.bottom() << ',' << span.right() << ')';
return str;
}
+
+QDebug operator<<(QDebug debug, const QSpanCollection::SpanList &spans)
+{
+ for (const auto *span : spans)
+ debug << span << *span;
+ return debug;
+}
#endif
/** \internal
@@ -236,8 +207,7 @@ void QSpanCollection::updateInsertedRows(int start, int end)
#ifdef DEBUG_SPAN_UPDATE
qDebug("After");
- foreach (QSpanCollection::Span *span, spans)
- qDebug() << span << *span;
+ qDebug() << spans;
#endif
for (Index::iterator it_y = index.begin(); it_y != index.end(); ) {
@@ -283,8 +253,7 @@ void QSpanCollection::updateInsertedColumns(int start, int end)
#ifdef DEBUG_SPAN_UPDATE
qDebug("After");
- foreach (QSpanCollection::Span *span, spans)
- qDebug() << span << *span;
+ qDebug() << spans;
#endif
for (Index::iterator it_y = index.begin(); it_y != index.end(); ++it_y) {
@@ -388,8 +357,7 @@ void QSpanCollection::updateRemovedRows(int start, int end)
#ifdef DEBUG_SPAN_UPDATE
qDebug("After");
- foreach (QSpanCollection::Span *span, spans)
- qDebug() << span << *span;
+ qDebug() << spans;
#endif
if (spans.empty()) {
qDeleteAll(spansToBeDeleted);
@@ -456,8 +424,7 @@ void QSpanCollection::updateRemovedRows(int start, int end)
#ifdef DEBUG_SPAN_UPDATE
qDebug() << index;
qDebug("Deleted");
- foreach (QSpanCollection::Span *span, spansToBeDeleted)
- qDebug() << span << *span;
+ qDebug() << spansToBeDeleted;
#endif
qDeleteAll(spansToBeDeleted);
}
@@ -515,8 +482,7 @@ void QSpanCollection::updateRemovedColumns(int start, int end)
#ifdef DEBUG_SPAN_UPDATE
qDebug("After");
- foreach (QSpanCollection::Span *span, spans)
- qDebug() << span << *span;
+ qDebug() << spans;
#endif
if (spans.empty()) {
qDeleteAll(toBeDeleted);
@@ -535,8 +501,7 @@ void QSpanCollection::updateRemovedColumns(int start, int end)
#ifdef DEBUG_SPAN_UPDATE
qDebug() << index;
qDebug("Deleted");
- foreach (QSpanCollection::Span *span, toBeDeleted)
- qDebug() << span << *span;
+ qDebug() << toBeDeleted;
#endif
qDeleteAll(toBeDeleted);
}
@@ -628,7 +593,25 @@ void QTableViewPrivate::init()
#if QT_CONFIG(abstractbutton)
cornerWidget = new QTableCornerButton(q);
cornerWidget->setFocusPolicy(Qt::NoFocus);
- QObject::connect(cornerWidget, SIGNAL(clicked()), q, SLOT(selectAll()));
+ cornerWidgetConnection = QObject::connect(
+ cornerWidget, &QTableCornerButton::clicked,
+ q, &QTableView::selectAll);
+#endif
+}
+
+void QTableViewPrivate::clearConnections()
+{
+ for (const QMetaObject::Connection &connection : modelConnections)
+ QObject::disconnect(connection);
+ for (const QMetaObject::Connection &connection : verHeaderConnections)
+ QObject::disconnect(connection);
+ for (const QMetaObject::Connection &connection : horHeaderConnections)
+ QObject::disconnect(connection);
+ for (const QMetaObject::Connection &connection : dynHorHeaderConnections)
+ QObject::disconnect(connection);
+ QObject::disconnect(selectionmodelConnection);
+#if QT_CONFIG(abstractbutton)
+ QObject::disconnect(cornerWidgetConnection);
#endif
}
@@ -918,13 +901,32 @@ void QTableViewPrivate::drawAndClipSpans(const QRegion &area, QPainter *painter,
visibleSpans = spans.spansInRect(logicalColumn(firstVisualColumn), logicalRow(firstVisualRow),
lastVisualColumn - firstVisualColumn + 1, lastVisualRow - firstVisualRow + 1);
} else {
- for(int x = firstVisualColumn; x <= lastVisualColumn; x++)
- for(int y = firstVisualRow; y <= lastVisualRow; y++)
- visibleSpans.insert(spans.spanAt(x,y));
- visibleSpans.remove(nullptr);
- }
-
- for (QSpanCollection::Span *span : qAsConst(visibleSpans)) {
+ // Any cell outside the viewport, on the top or left, can still end up visible inside the
+ // viewport if is has a span. Calculating if a spanned cell overlaps with the viewport is
+ // "easy" enough when the columns (or rows) in the view are aligned with the columns
+ // in the model; In that case you know that if a column is outside the viewport on the
+ // right, it cannot affect the drawing of the cells inside the viewport, even with a span.
+ // And under that assumption, the spansInRect() function can be used (which is optimized
+ // to only iterate the spans that are close to the viewport).
+ // But when the view has rearranged the columns (or rows), this is no longer true. In that
+ // case, even if a column, according to the model, is outside the viewport on the right, it
+ // can still overlap with the viewport. This can happen if it was moved to the left of the
+ // viewport and one of its cells has a span. In that case we need to take the theoretically
+ // slower route and iterate through all the spans, and check if any of them overlaps with
+ // the viewport.
+ const auto spanList = spans.spans;
+ for (QSpanCollection::Span *span : spanList) {
+ const int spanVisualLeft = visualColumn(span->left());
+ const int spanVisualTop = visualRow(span->top());
+ const int spanVisualRight = spanVisualLeft + span->width() - 1;
+ const int spanVisualBottom = spanVisualTop + span->height() - 1;
+ if ((spanVisualLeft <= lastVisualColumn && spanVisualRight >= firstVisualColumn)
+ && (spanVisualTop <= lastVisualRow && spanVisualBottom >= firstVisualRow))
+ visibleSpans.insert(span);
+ }
+ }
+
+ for (QSpanCollection::Span *span : std::as_const(visibleSpans)) {
int row = span->top();
int col = span->left();
QModelIndex index = model->index(row, col, root);
@@ -973,7 +975,7 @@ void QTableViewPrivate::drawAndClipSpans(const QRegion &area, QPainter *painter,
\internal
Updates spans after row insertion.
*/
-void QTableViewPrivate::_q_updateSpanInsertedRows(const QModelIndex &parent, int start, int end)
+void QTableViewPrivate::updateSpanInsertedRows(const QModelIndex &parent, int start, int end)
{
Q_UNUSED(parent);
spans.updateInsertedRows(start, end);
@@ -983,7 +985,7 @@ void QTableViewPrivate::_q_updateSpanInsertedRows(const QModelIndex &parent, int
\internal
Updates spans after column insertion.
*/
-void QTableViewPrivate::_q_updateSpanInsertedColumns(const QModelIndex &parent, int start, int end)
+void QTableViewPrivate::updateSpanInsertedColumns(const QModelIndex &parent, int start, int end)
{
Q_UNUSED(parent);
spans.updateInsertedColumns(start, end);
@@ -993,7 +995,7 @@ void QTableViewPrivate::_q_updateSpanInsertedColumns(const QModelIndex &parent,
\internal
Updates spans after row removal.
*/
-void QTableViewPrivate::_q_updateSpanRemovedRows(const QModelIndex &parent, int start, int end)
+void QTableViewPrivate::updateSpanRemovedRows(const QModelIndex &parent, int start, int end)
{
Q_UNUSED(parent);
spans.updateRemovedRows(start, end);
@@ -1003,7 +1005,7 @@ void QTableViewPrivate::_q_updateSpanRemovedRows(const QModelIndex &parent, int
\internal
Updates spans after column removal.
*/
-void QTableViewPrivate::_q_updateSpanRemovedColumns(const QModelIndex &parent, int start, int end)
+void QTableViewPrivate::updateSpanRemovedColumns(const QModelIndex &parent, int start, int end)
{
Q_UNUSED(parent);
spans.updateRemovedColumns(start, end);
@@ -1013,7 +1015,7 @@ void QTableViewPrivate::_q_updateSpanRemovedColumns(const QModelIndex &parent, i
\internal
Sort the model when the header sort indicator changed
*/
-void QTableViewPrivate::_q_sortIndicatorChanged(int column, Qt::SortOrder order)
+void QTableViewPrivate::sortIndicatorChanged(int column, Qt::SortOrder order)
{
model->sort(column, order);
}
@@ -1165,6 +1167,8 @@ int QTableViewPrivate::heightHintForIndex(const QModelIndex &index, int hint, QS
table can be found by using rowHeight(); similarly, the width of
columns can be found using columnWidth(). Since both of these are plain
widgets, you can hide either of them using their hide() functions.
+ Each header is configured with its \l{QHeaderView::}{highlightSections}
+ and \l{QHeaderView::}{sectionsClickable} properties set to \c true.
Rows and columns can be hidden and shown with hideRow(), hideColumn(),
showRow(), and showColumn(). They can be selected with selectRow()
@@ -1203,7 +1207,7 @@ int QTableViewPrivate::heightHintForIndex(const QModelIndex &index, int hint, QS
operations between x-coordinates and column indexes.
\sa QTableWidget, {View Classes}, QAbstractItemModel, QAbstractItemView,
- {Chart Example}, {Pixelator Example}, {Table Model Example}
+ {Table Model Example}
*/
/*!
@@ -1234,6 +1238,8 @@ QTableView::QTableView(QTableViewPrivate &dd, QWidget *parent)
*/
QTableView::~QTableView()
{
+ Q_D(QTableView);
+ d->clearConnections();
}
/*!
@@ -1257,28 +1263,23 @@ void QTableView::setModel(QAbstractItemModel *model)
return;
//let's disconnect from the old model
if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
- disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(_q_updateSpanInsertedRows(QModelIndex,int,int)));
- disconnect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)),
- this, SLOT(_q_updateSpanInsertedColumns(QModelIndex,int,int)));
- disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_updateSpanRemovedRows(QModelIndex,int,int)));
- disconnect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_updateSpanRemovedColumns(QModelIndex,int,int)));
+ for (const QMetaObject::Connection &connection : d->modelConnections)
+ disconnect(connection);
}
if (d->selectionModel) { // support row editing
- disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
- d->model, SLOT(submit()));
+ disconnect(d->selectionmodelConnection);
}
if (model) { //and connect to the new one
- connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(_q_updateSpanInsertedRows(QModelIndex,int,int)));
- connect(model, SIGNAL(columnsInserted(QModelIndex,int,int)),
- this, SLOT(_q_updateSpanInsertedColumns(QModelIndex,int,int)));
- connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_updateSpanRemovedRows(QModelIndex,int,int)));
- connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_updateSpanRemovedColumns(QModelIndex,int,int)));
+ d->modelConnections = {
+ QObjectPrivate::connect(model, &QAbstractItemModel::rowsInserted,
+ d, &QTableViewPrivate::updateSpanInsertedRows),
+ QObjectPrivate::connect(model, &QAbstractItemModel::columnsInserted,
+ d, &QTableViewPrivate::updateSpanInsertedColumns),
+ QObjectPrivate::connect(model, &QAbstractItemModel::rowsRemoved,
+ d, &QTableViewPrivate::updateSpanRemovedRows),
+ QObjectPrivate::connect(model, &QAbstractItemModel::columnsRemoved,
+ d, &QTableViewPrivate::updateSpanRemovedColumns)
+ };
}
d->verticalHeader->setModel(model);
d->horizontalHeader->setModel(model);
@@ -1320,8 +1321,7 @@ void QTableView::setSelectionModel(QItemSelectionModel *selectionModel)
Q_ASSERT(selectionModel);
if (d->selectionModel) {
// support row editing
- disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
- d->model, SLOT(submit()));
+ disconnect(d->selectionmodelConnection);
}
d->verticalHeader->setSelectionModel(selectionModel);
@@ -1330,8 +1330,9 @@ void QTableView::setSelectionModel(QItemSelectionModel *selectionModel)
if (d->selectionModel) {
// support row editing
- connect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
- d->model, SLOT(submit()));
+ d->selectionmodelConnection =
+ connect(d->selectionModel, &QItemSelectionModel::currentRowChanged,
+ d->model, &QAbstractItemModel::submit);
}
}
@@ -1368,6 +1369,8 @@ void QTableView::setHorizontalHeader(QHeaderView *header)
if (!header || header == d->horizontalHeader)
return;
+ for (const QMetaObject::Connection &connection : d->horHeaderConnections)
+ disconnect(connection);
if (d->horizontalHeader && d->horizontalHeader->parent() == this)
delete d->horizontalHeader;
d->horizontalHeader = header;
@@ -1379,18 +1382,18 @@ void QTableView::setHorizontalHeader(QHeaderView *header)
d->horizontalHeader->setSelectionModel(d->selectionModel);
}
- connect(d->horizontalHeader,SIGNAL(sectionResized(int,int,int)),
- this, SLOT(columnResized(int,int,int)));
- connect(d->horizontalHeader, SIGNAL(sectionMoved(int,int,int)),
- this, SLOT(columnMoved(int,int,int)));
- connect(d->horizontalHeader, SIGNAL(sectionCountChanged(int,int)),
- this, SLOT(columnCountChanged(int,int)));
- connect(d->horizontalHeader, SIGNAL(sectionPressed(int)), this, SLOT(selectColumn(int)));
- connect(d->horizontalHeader, SIGNAL(sectionEntered(int)), this, SLOT(_q_selectColumn(int)));
- connect(d->horizontalHeader, SIGNAL(sectionHandleDoubleClicked(int)),
- this, SLOT(resizeColumnToContents(int)));
- connect(d->horizontalHeader, SIGNAL(geometriesChanged()), this, SLOT(updateGeometries()));
-
+ d->horHeaderConnections = {
+ connect(d->horizontalHeader,&QHeaderView::sectionResized,
+ this, &QTableView::columnResized),
+ connect(d->horizontalHeader, &QHeaderView::sectionMoved,
+ this, &QTableView::columnMoved),
+ connect(d->horizontalHeader, &QHeaderView::sectionCountChanged,
+ this, &QTableView::columnCountChanged),
+ connect(d->horizontalHeader, &QHeaderView::sectionHandleDoubleClicked,
+ this, &QTableView::resizeColumnToContents),
+ connect(d->horizontalHeader, &QHeaderView::geometriesChanged,
+ this, &QTableView::updateGeometries),
+ };
//update the sorting enabled states on the new header
setSortingEnabled(d->sortingEnabled);
}
@@ -1406,6 +1409,8 @@ void QTableView::setVerticalHeader(QHeaderView *header)
if (!header || header == d->verticalHeader)
return;
+ for (const QMetaObject::Connection &connection : d->verHeaderConnections)
+ disconnect(connection);
if (d->verticalHeader && d->verticalHeader->parent() == this)
delete d->verticalHeader;
d->verticalHeader = header;
@@ -1417,17 +1422,22 @@ void QTableView::setVerticalHeader(QHeaderView *header)
d->verticalHeader->setSelectionModel(d->selectionModel);
}
- connect(d->verticalHeader, SIGNAL(sectionResized(int,int,int)),
- this, SLOT(rowResized(int,int,int)));
- connect(d->verticalHeader, SIGNAL(sectionMoved(int,int,int)),
- this, SLOT(rowMoved(int,int,int)));
- connect(d->verticalHeader, SIGNAL(sectionCountChanged(int,int)),
- this, SLOT(rowCountChanged(int,int)));
- connect(d->verticalHeader, SIGNAL(sectionPressed(int)), this, SLOT(selectRow(int)));
- connect(d->verticalHeader, SIGNAL(sectionEntered(int)), this, SLOT(_q_selectRow(int)));
- connect(d->verticalHeader, SIGNAL(sectionHandleDoubleClicked(int)),
- this, SLOT(resizeRowToContents(int)));
- connect(d->verticalHeader, SIGNAL(geometriesChanged()), this, SLOT(updateGeometries()));
+ d->verHeaderConnections = {
+ connect(d->verticalHeader, &QHeaderView::sectionResized,
+ this, &QTableView::rowResized),
+ connect(d->verticalHeader, &QHeaderView::sectionMoved,
+ this, &QTableView::rowMoved),
+ connect(d->verticalHeader, &QHeaderView::sectionCountChanged,
+ this, &QTableView::rowCountChanged),
+ connect(d->verticalHeader, &QHeaderView::sectionPressed,
+ this, &QTableView::selectRow),
+ connect(d->verticalHeader, &QHeaderView::sectionHandleDoubleClicked,
+ this, &QTableView::resizeRowToContents),
+ connect(d->verticalHeader, &QHeaderView::geometriesChanged,
+ this, &QTableView::updateGeometries),
+ connect(d->verticalHeader, &QHeaderView::sectionEntered,
+ this, [d](int row) { d->selectRow(row, false); })
+ };
}
/*!
@@ -1496,7 +1506,7 @@ void QTableView::paintEvent(QPaintEvent *event)
const int gridSize = showGrid ? 1 : 0;
const int gridHint = style()->styleHint(QStyle::SH_Table_GridLineColor, &option, this);
const QColor gridColor = QColor::fromRgba(static_cast<QRgb>(gridHint));
- const QPen gridPen = QPen(gridColor, 0, d->gridStyle);
+ const QPen gridPen = QPen(gridColor, 1, d->gridStyle);
const QHeaderView *verticalHeader = d->verticalHeader;
const QHeaderView *horizontalHeader = d->horizontalHeader;
const bool alternate = d->alternatingColors;
@@ -1630,7 +1640,8 @@ void QTableView::paintEvent(QPaintEvent *event)
int rowY = rowViewportPosition(row);
rowY += offset.y();
int rowh = rowHeight(row) - gridSize;
- painter.drawLine(dirtyArea.left(), rowY + rowh, dirtyArea.right(), rowY + rowh);
+ QLineF line(dirtyArea.left(), rowY + rowh, dirtyArea.right(), rowY + rowh);
+ painter.drawLine(line.translated(0.5, 0.5));
}
// Paint each column
@@ -1642,7 +1653,8 @@ void QTableView::paintEvent(QPaintEvent *event)
colp += offset.x();
if (!rightToLeft)
colp += columnWidth(col) - gridSize;
- painter.drawLine(colp, dirtyArea.top(), colp, dirtyArea.bottom());
+ QLineF line(colp, dirtyArea.top(), colp, dirtyArea.bottom());
+ painter.drawLine(line.translated(0.5, 0.5));
}
const bool drawWhenHidden = style()->styleHint(QStyle::SH_Table_AlwaysDrawLeftTopGridLines,
&option, this);
@@ -2004,6 +2016,9 @@ void QTableView::setSelection(const QRect &rect, QItemSelectionModel::SelectionF
if (d->hasSpans()) {
bool expanded;
+ // when the current selection does not intersect with any spans of merged cells,
+ // the range of selected cells must be the same as if there were no merged cells
+ bool intersectsSpan = false;
int top = qMin(d->visualRow(tl.row()), d->visualRow(br.row()));
int left = qMin(d->visualColumn(tl.column()), d->visualColumn(br.column()));
int bottom = qMax(d->visualRow(tl.row()), d->visualRow(br.row()));
@@ -2018,6 +2033,7 @@ void QTableView::setSelection(const QRect &rect, QItemSelectionModel::SelectionF
int r = d->visualColumn(d->columnSpanEndLogical(span.left(), span.width()));
if ((t > bottom) || (l > right) || (top > b) || (left > r))
continue; // no intersect
+ intersectsSpan = true;
if (t < top) {
top = t;
expanded = true;
@@ -2038,14 +2054,20 @@ void QTableView::setSelection(const QRect &rect, QItemSelectionModel::SelectionF
break;
}
} while (expanded);
- selection.reserve((right - left + 1) * (bottom - top + 1));
- for (int horizontal = left; horizontal <= right; ++horizontal) {
- int column = d->logicalColumn(horizontal);
- for (int vertical = top; vertical <= bottom; ++vertical) {
- int row = d->logicalRow(vertical);
- QModelIndex index = d->model->index(row, column, d->root);
- selection.append(QItemSelectionRange(index));
+ if (intersectsSpan) {
+ selection.reserve((right - left + 1) * (bottom - top + 1));
+ for (int horizontal = left; horizontal <= right; ++horizontal) {
+ int column = d->logicalColumn(horizontal);
+ for (int vertical = top; vertical <= bottom; ++vertical) {
+ int row = d->logicalRow(vertical);
+ QModelIndex index = d->model->index(row, column, d->root);
+ selection.append(QItemSelectionRange(index));
+ }
}
+ } else {
+ QItemSelectionRange range(tl, br);
+ if (!range.isEmpty())
+ selection.append(range);
}
} else if (verticalMoved && horizontalMoved) {
int top = d->visualRow(tl.row());
@@ -2200,7 +2222,7 @@ QModelIndexList QTableView::selectedIndexes() const
QModelIndexList modelSelected;
if (d->selectionModel)
modelSelected = d->selectionModel->selectedIndexes();
- for (int i = 0; i < modelSelected.count(); ++i) {
+ for (int i = 0; i < modelSelected.size(); ++i) {
QModelIndex index = modelSelected.at(i);
if (!isIndexHidden(index) && index.parent() == d->root)
viewSelected.append(index);
@@ -2410,12 +2432,12 @@ int QTableView::sizeHintForRow(int row) const
break;
}
- int actualRight = d->model->columnCount(d->root) - 1;
+ const int actualRight = d->model->columnCount(d->root) - 1;
int idxLeft = left;
int idxRight = column - 1;
- if (maximumProcessCols == 0)
- columnsProcessed = 0; // skip the while loop
+ if (maximumProcessCols == 0 || actualRight < idxLeft)
+ columnsProcessed = maximumProcessCols; // skip the while loop
while (columnsProcessed != maximumProcessCols && (idxLeft > 0 || idxRight < actualRight)) {
int logicalIdx = -1;
@@ -2439,11 +2461,10 @@ int QTableView::sizeHintForRow(int row) const
break;
}
}
- if (logicalIdx < 0)
- continue;
-
- index = d->model->index(row, logicalIdx, d->root);
- hint = d->heightHintForIndex(index, hint, option);
+ if (logicalIdx >= 0) {
+ index = d->model->index(row, logicalIdx, d->root);
+ hint = d->heightHintForIndex(index, hint, option);
+ }
++columnsProcessed;
}
@@ -2499,12 +2520,12 @@ int QTableView::sizeHintForColumn(int column) const
break;
}
- int actualBottom = d->model->rowCount(d->root) - 1;
+ const int actualBottom = d->model->rowCount(d->root) - 1;
int idxTop = top;
int idxBottom = row - 1;
- if (maximumProcessRows == 0)
- rowsProcessed = 0; // skip the while loop
+ if (maximumProcessRows == 0 || actualBottom < idxTop)
+ rowsProcessed = maximumProcessRows; // skip the while loop
while (rowsProcessed != maximumProcessRows && (idxTop > 0 || idxBottom < actualBottom)) {
int logicalIdx = -1;
@@ -2528,11 +2549,10 @@ int QTableView::sizeHintForColumn(int column) const
break;
}
}
- if (logicalIdx < 0)
- continue;
-
- index = d->model->index(logicalIdx, column, d->root);
- hint = d->widthHintForIndex(index, hint, option);
+ if (logicalIdx >= 0) {
+ index = d->model->index(logicalIdx, column, d->root);
+ hint = d->widthHintForIndex(index, hint, option);
+ }
++rowsProcessed;
}
@@ -2707,24 +2727,25 @@ void QTableView::setSortingEnabled(bool enable)
{
Q_D(QTableView);
horizontalHeader()->setSortIndicatorShown(enable);
+ for (const QMetaObject::Connection &connection : d->dynHorHeaderConnections)
+ disconnect(connection);
+ d->dynHorHeaderConnections.clear();
if (enable) {
- disconnect(d->horizontalHeader, SIGNAL(sectionEntered(int)),
- this, SLOT(_q_selectColumn(int)));
- disconnect(horizontalHeader(), SIGNAL(sectionPressed(int)),
- this, SLOT(selectColumn(int)));
//sortByColumn has to be called before we connect or set the sortingEnabled flag
// because otherwise it will not call sort on the model.
- sortByColumn(horizontalHeader()->sortIndicatorSection(),
- horizontalHeader()->sortIndicatorOrder());
- connect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
- this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)), Qt::UniqueConnection);
+ sortByColumn(d->horizontalHeader->sortIndicatorSection(),
+ d->horizontalHeader->sortIndicatorOrder());
+ d->dynHorHeaderConnections = {
+ QObjectPrivate::connect(d->horizontalHeader, &QHeaderView::sortIndicatorChanged,
+ d, &QTableViewPrivate::sortIndicatorChanged)
+ };
} else {
- connect(d->horizontalHeader, SIGNAL(sectionEntered(int)),
- this, SLOT(_q_selectColumn(int)), Qt::UniqueConnection);
- connect(horizontalHeader(), SIGNAL(sectionPressed(int)),
- this, SLOT(selectColumn(int)), Qt::UniqueConnection);
- disconnect(horizontalHeader(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
- this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)));
+ d->dynHorHeaderConnections = {
+ connect(d->horizontalHeader, &QHeaderView::sectionPressed,
+ this, &QTableView::selectColumn),
+ connect(d->horizontalHeader, &QHeaderView::sectionEntered,
+ this, [d](int column) {d->selectColumn(column, false); })
+ };
}
d->sortingEnabled = enable;
}
@@ -3384,16 +3405,6 @@ void QTableView::clearSpans()
d->viewport->update();
}
-void QTableViewPrivate::_q_selectRow(int row)
-{
- selectRow(row, false);
-}
-
-void QTableViewPrivate::_q_selectColumn(int column)
-{
- selectColumn(column, false);
-}
-
void QTableViewPrivate::selectRow(int row, bool anchor)
{
Q_Q(QTableView);
@@ -3455,7 +3466,7 @@ void QTableViewPrivate::selectColumn(int column, bool anchor)
if (q->selectionMode() != QTableView::SingleSelection
&& command.testFlag(QItemSelectionModel::Toggle)) {
if (anchor)
- ctrlDragSelectionFlag = horizontalHeader->selectionModel()->selectedColumns().contains(index)
+ ctrlDragSelectionFlag = horizontalHeader->selectionModel()->selectedColumns(row).contains(index)
? QItemSelectionModel::Deselect : QItemSelectionModel::Select;
command &= ~QItemSelectionModel::Toggle;
command |= ctrlDragSelectionFlag;
@@ -3479,9 +3490,9 @@ void QTableViewPrivate::selectColumn(int column, bool anchor)
*/
void QTableView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
{
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
if (QAccessible::isActive()) {
- if (current.isValid()) {
+ if (current.isValid() && hasFocus()) {
Q_D(QTableView);
int entry = d->accessibleTable2Index(current);
QAccessibleEvent event(this, QAccessible::Focus);
@@ -3501,7 +3512,7 @@ void QTableView::selectionChanged(const QItemSelection &selected,
{
Q_D(QTableView);
Q_UNUSED(d);
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
if (QAccessible::isActive()) {
// ### does not work properly for selection ranges.
QModelIndex sel = selected.indexes().value(0);
diff --git a/src/widgets/itemviews/qtableview.h b/src/widgets/itemviews/qtableview.h
index 71caa37872..eff0ea3502 100644
--- a/src/widgets/itemviews/qtableview.h
+++ b/src/widgets/itemviews/qtableview.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTABLEVIEW_H
#define QTABLEVIEW_H
@@ -181,13 +145,6 @@ private:
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))
- Q_PRIVATE_SLOT(d_func(), void _q_updateSpanInsertedRows(QModelIndex,int,int))
- Q_PRIVATE_SLOT(d_func(), void _q_updateSpanInsertedColumns(QModelIndex,int,int))
- Q_PRIVATE_SLOT(d_func(), void _q_updateSpanRemovedRows(QModelIndex,int,int))
- Q_PRIVATE_SLOT(d_func(), void _q_updateSpanRemovedColumns(QModelIndex,int,int))
- Q_PRIVATE_SLOT(d_func(), void _q_sortIndicatorChanged(int column, Qt::SortOrder order))
};
QT_END_NAMESPACE
diff --git a/src/widgets/itemviews/qtableview_p.h b/src/widgets/itemviews/qtableview_p.h
index 23095c0087..862a016d5f 100644
--- a/src/widgets/itemviews/qtableview_p.h
+++ b/src/widgets/itemviews/qtableview_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTABLEVIEW_P_H
#define QTABLEVIEW_P_H
@@ -52,13 +16,18 @@
//
#include <QtWidgets/private/qtwidgetsglobal_p.h>
+#include "qtableview.h"
+#include "qheaderview.h"
+
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QSet>
#include <QtCore/QDebug>
#include "private/qabstractitemview_p.h"
+#include <array>
#include <list>
+#include <vector>
QT_REQUIRE_CONFIG(tableview);
@@ -129,8 +98,10 @@ private:
Q_DECLARE_TYPEINFO ( QSpanCollection::Span, Q_RELOCATABLE_TYPE);
-
-class QTableViewPrivate : public QAbstractItemViewPrivate
+#if QT_CONFIG(abstractbutton)
+class QTableCornerButton;
+#endif
+class Q_AUTOTEST_EXPORT QTableViewPrivate : public QAbstractItemViewPrivate
{
Q_DECLARE_PUBLIC(QTableView)
public:
@@ -147,6 +118,7 @@ public:
#endif
}
void init();
+ void clearConnections();
void trimHiddenSelections(QItemSelectionRange *range) const;
QRect intersectedRect(const QRect rect, const QModelIndex &topLeft, const QModelIndex &bottomRight) const override;
@@ -192,8 +164,15 @@ public:
QHeaderView *horizontalHeader;
QHeaderView *verticalHeader;
#if QT_CONFIG(abstractbutton)
- QWidget *cornerWidget;
+ QTableCornerButton *cornerWidget;
+ QMetaObject::Connection cornerWidgetConnection;
#endif
+ QMetaObject::Connection selectionmodelConnection;
+ std::array<QMetaObject::Connection, 4> modelConnections;
+ std::array<QMetaObject::Connection, 7> verHeaderConnections;
+ std::array<QMetaObject::Connection, 5> horHeaderConnections;
+ std::vector<QMetaObject::Connection> dynHorHeaderConnections;
+
bool sortingEnabled;
bool geometryRecursionBlock;
QPoint visualCursor; // (Row,column) cell coordinates to track through span navigation.
@@ -246,17 +225,14 @@ public:
QRect visualSpanRect(const QSpanCollection::Span &span) const;
- void _q_selectRow(int row);
- void _q_selectColumn(int column);
-
void selectRow(int row, bool anchor);
void selectColumn(int column, bool anchor);
- void _q_updateSpanInsertedRows(const QModelIndex &parent, int start, int end);
- void _q_updateSpanInsertedColumns(const QModelIndex &parent, int start, int end);
- void _q_updateSpanRemovedRows(const QModelIndex &parent, int start, int end);
- void _q_updateSpanRemovedColumns(const QModelIndex &parent, int start, int end);
- void _q_sortIndicatorChanged(int column, Qt::SortOrder order);
+ void updateSpanInsertedRows(const QModelIndex &parent, int start, int end);
+ void updateSpanInsertedColumns(const QModelIndex &parent, int start, int end);
+ void updateSpanRemovedRows(const QModelIndex &parent, int start, int end);
+ void updateSpanRemovedColumns(const QModelIndex &parent, int start, int end);
+ void sortIndicatorChanged(int column, Qt::SortOrder order);
};
QT_END_NAMESPACE
diff --git a/src/widgets/itemviews/qtablewidget.cpp b/src/widgets/itemviews/qtablewidget.cpp
index 5072cc9240..6dd812f6fb 100644
--- a/src/widgets/itemviews/qtablewidget.cpp
+++ b/src/widgets/itemviews/qtablewidget.cpp
@@ -1,45 +1,8 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qtablewidget.h"
-#include <qitemdelegate.h>
#include <qpainter.h>
#include <private/qtablewidget_p.h>
@@ -63,12 +26,12 @@ QTableModel::~QTableModel()
bool QTableModel::insertRows(int row, int count, const QModelIndex &)
{
- if (count < 1 || row < 0 || row > verticalHeaderItems.count())
+ if (count < 1 || row < 0 || row > verticalHeaderItems.size())
return false;
beginInsertRows(QModelIndex(), row, row + count - 1);
- int rc = verticalHeaderItems.count();
- int cc = horizontalHeaderItems.count();
+ int rc = verticalHeaderItems.size();
+ int cc = horizontalHeaderItems.size();
verticalHeaderItems.insert(row, count, 0);
if (rc == 0)
tableItems.resize(cc * count);
@@ -80,12 +43,12 @@ bool QTableModel::insertRows(int row, int count, const QModelIndex &)
bool QTableModel::insertColumns(int column, int count, const QModelIndex &)
{
- if (count < 1 || column < 0 || column > horizontalHeaderItems.count())
+ if (count < 1 || column < 0 || column > horizontalHeaderItems.size())
return false;
beginInsertColumns(QModelIndex(), column, column + count - 1);
- int rc = verticalHeaderItems.count();
- int cc = horizontalHeaderItems.count();
+ int rc = verticalHeaderItems.size();
+ int cc = horizontalHeaderItems.size();
horizontalHeaderItems.insert(column, count, 0);
if (cc == 0)
tableItems.resize(rc * count);
@@ -98,7 +61,7 @@ bool QTableModel::insertColumns(int column, int count, const QModelIndex &)
bool QTableModel::removeRows(int row, int count, const QModelIndex &)
{
- if (count < 1 || row < 0 || row + count > verticalHeaderItems.count())
+ if (count < 1 || row < 0 || row + count > verticalHeaderItems.size())
return false;
beginRemoveRows(QModelIndex(), row, row + count - 1);
@@ -125,7 +88,7 @@ bool QTableModel::removeRows(int row, int count, const QModelIndex &)
bool QTableModel::removeColumns(int column, int count, const QModelIndex &)
{
- if (count < 1 || column < 0 || column + count > horizontalHeaderItems.count())
+ if (count < 1 || column < 0 || column + count > horizontalHeaderItems.size())
return false;
beginRemoveColumns(QModelIndex(), column, column + count - 1);
@@ -154,7 +117,7 @@ bool QTableModel::removeColumns(int column, int count, const QModelIndex &)
void QTableModel::setItem(int row, int column, QTableWidgetItem *item)
{
int i = tableIndex(row, column);
- if (i < 0 || i >= tableItems.count())
+ if (i < 0 || i >= tableItems.size())
return;
QTableWidgetItem *oldItem = tableItems.at(i);
if (item == oldItem)
@@ -177,12 +140,12 @@ void QTableModel::setItem(int row, int column, QTableWidgetItem *item)
// sorted insertion
Qt::SortOrder order = view->horizontalHeader()->sortIndicatorOrder();
QList<QTableWidgetItem *> colItems = columnItems(column);
- if (row < colItems.count())
+ if (row < colItems.size())
colItems.remove(row);
int sortedRow;
if (item == nullptr) {
// move to after all non-0 (sortable) items
- sortedRow = colItems.count();
+ sortedRow = colItems.size();
} else {
QList<QTableWidgetItem *>::iterator it;
it = sortedInsertionIterator(colItems.begin(), colItems.end(), order, item);
@@ -270,7 +233,7 @@ void QTableModel::removeItem(QTableWidgetItem *item)
void QTableModel::setHorizontalHeaderItem(int section, QTableWidgetItem *item)
{
- if (section < 0 || section >= horizontalHeaderItems.count())
+ if (section < 0 || section >= horizontalHeaderItems.size())
return;
QTableWidgetItem *oldItem = horizontalHeaderItems.at(section);
if (item == oldItem)
@@ -284,7 +247,7 @@ void QTableModel::setHorizontalHeaderItem(int section, QTableWidgetItem *item)
if (item) {
item->view = view;
- item->itemFlags = Qt::ItemFlags(int(item->itemFlags)|ItemIsHeaderItem);
+ item->d->headerItem = true;
}
horizontalHeaderItems[section] = item;
emit headerDataChanged(Qt::Horizontal, section, section);
@@ -292,7 +255,7 @@ void QTableModel::setHorizontalHeaderItem(int section, QTableWidgetItem *item)
void QTableModel::setVerticalHeaderItem(int section, QTableWidgetItem *item)
{
- if (section < 0 || section >= verticalHeaderItems.count())
+ if (section < 0 || section >= verticalHeaderItems.size())
return;
QTableWidgetItem *oldItem = verticalHeaderItems.at(section);
if (item == oldItem)
@@ -306,7 +269,7 @@ void QTableModel::setVerticalHeaderItem(int section, QTableWidgetItem *item)
if (item) {
item->view = view;
- item->itemFlags = Qt::ItemFlags(int(item->itemFlags)|ItemIsHeaderItem);
+ item->d->headerItem = true;
}
verticalHeaderItems[section] = item;
emit headerDataChanged(Qt::Vertical, section, section);
@@ -314,12 +277,12 @@ void QTableModel::setVerticalHeaderItem(int section, QTableWidgetItem *item)
QTableWidgetItem *QTableModel::takeHorizontalHeaderItem(int section)
{
- if (section < 0 || section >= horizontalHeaderItems.count())
+ if (section < 0 || section >= horizontalHeaderItems.size())
return nullptr;
QTableWidgetItem *itm = horizontalHeaderItems.at(section);
if (itm) {
itm->view = nullptr;
- itm->itemFlags &= ~ItemIsHeaderItem;
+ itm->d->headerItem = false;
horizontalHeaderItems[section] = 0;
}
return itm;
@@ -327,12 +290,12 @@ QTableWidgetItem *QTableModel::takeHorizontalHeaderItem(int section)
QTableWidgetItem *QTableModel::takeVerticalHeaderItem(int section)
{
- if (section < 0 || section >= verticalHeaderItems.count())
+ if (section < 0 || section >= verticalHeaderItems.size())
return nullptr;
QTableWidgetItem *itm = verticalHeaderItems.at(section);
if (itm) {
itm->view = nullptr;
- itm->itemFlags &= ~ItemIsHeaderItem;
+ itm->d->headerItem = false;
verticalHeaderItems[section] = 0;
}
return itm;
@@ -354,7 +317,7 @@ QModelIndex QTableModel::index(const QTableWidgetItem *item) const
return QModelIndex();
int i = -1;
const int id = item->d->id;
- if (id >= 0 && id < tableItems.count() && tableItems.at(id) == item) {
+ if (id >= 0 && id < tableItems.size() && tableItems.at(id) == item) {
i = id;
} else { // we need to search for the item
i = tableItems.indexOf(const_cast<QTableWidgetItem*>(item));
@@ -368,7 +331,7 @@ QModelIndex QTableModel::index(const QTableWidgetItem *item) const
void QTableModel::setRowCount(int rows)
{
- int rc = verticalHeaderItems.count();
+ int rc = verticalHeaderItems.size();
if (rows < 0 || rc == rows)
return;
if (rc < rows)
@@ -379,7 +342,7 @@ void QTableModel::setRowCount(int rows)
void QTableModel::setColumnCount(int columns)
{
- int cc = horizontalHeaderItems.count();
+ int cc = horizontalHeaderItems.size();
if (columns < 0 || cc == columns)
return;
if (cc < columns)
@@ -390,12 +353,12 @@ void QTableModel::setColumnCount(int columns)
int QTableModel::rowCount(const QModelIndex &parent) const
{
- return parent.isValid() ? 0 : verticalHeaderItems.count();
+ return parent.isValid() ? 0 : verticalHeaderItems.size();
}
int QTableModel::columnCount(const QModelIndex &parent) const
{
- return parent.isValid() ? 0 : horizontalHeaderItems.count();
+ return parent.isValid() ? 0 : horizontalHeaderItems.size();
}
QVariant QTableModel::data(const QModelIndex &index, int role) const
@@ -436,7 +399,7 @@ QMap<int, QVariant> QTableModel::itemData(const QModelIndex &index) const
QMap<int, QVariant> roles;
QTableWidgetItem *itm = item(index);
if (itm) {
- for (int i = 0; i < itm->values.count(); ++i) {
+ for (int i = 0; i < itm->values.size(); ++i) {
roles.insert(itm->values.at(i).role,
itm->values.at(i).value);
}
@@ -528,7 +491,7 @@ void QTableModel::sort(int column, Qt::SortOrder order)
const auto compare = (order == Qt::AscendingOrder ? &itemLessThan : &itemGreaterThan);
std::stable_sort(sortable.begin(), sortable.end(), compare);
- QList<QTableWidgetItem *> sorted_table(tableItems.count());
+ QList<QTableWidgetItem *> sorted_table(tableItems.size());
QModelIndexList from;
QModelIndexList to;
const int numRows = rowCount();
@@ -536,9 +499,9 @@ void QTableModel::sort(int column, Qt::SortOrder order)
from.reserve(numRows * numColumns);
to.reserve(numRows * numColumns);
for (int i = 0; i < numRows; ++i) {
- int r = (i < sortable.count()
+ int r = (i < sortable.size()
? sortable.at(i).second
- : unsortable.at(i - sortable.count()));
+ : unsortable.at(i - sortable.size()));
for (int c = 0; c < numColumns; ++c) {
sorted_table[tableIndex(i, c)] = item(r, c);
from.append(createIndex(r, c));
@@ -586,7 +549,7 @@ void QTableModel::ensureSorted(int column, Qt::SortOrder order,
QList<QTableWidgetItem *>::iterator vit = colItems.begin();
qsizetype distanceFromBegin = 0;
bool changed = false;
- for (int i = 0; i < sorting.count(); ++i) {
+ for (int i = 0; i < sorting.size(); ++i) {
distanceFromBegin = std::distance(colItems.begin(), vit);
int oldRow = sorting.at(i).second;
QTableWidgetItem *item = colItems.at(oldRow);
@@ -619,7 +582,7 @@ void QTableModel::ensureSorted(int column, Qt::SortOrder order,
// update persistent indexes
updateRowIndexes(newPersistentIndexes, oldRow, newRow);
// the index of the remaining rows may have changed
- for (int j = i + 1; j < sorting.count(); ++j) {
+ for (int j = i + 1; j < sorting.size(); ++j) {
int otherRow = sorting.at(j).second;
if (oldRow < otherRow && newRow >= otherRow)
--sorting[j].second;
@@ -720,9 +683,9 @@ QVariant QTableModel::headerData(int section, Qt::Orientation orientation, int r
return QVariant();
QTableWidgetItem *itm = nullptr;
- if (orientation == Qt::Horizontal && section < horizontalHeaderItems.count())
+ if (orientation == Qt::Horizontal && section < horizontalHeaderItems.size())
itm = horizontalHeaderItems.at(section);
- else if (orientation == Qt::Vertical && section < verticalHeaderItems.count())
+ else if (orientation == Qt::Vertical && section < verticalHeaderItems.size())
itm = verticalHeaderItems.at(section);
else
return QVariant(); // section is out of bounds
@@ -757,20 +720,20 @@ bool QTableModel::setHeaderData(int section, Qt::Orientation orientation,
bool QTableModel::isValid(const QModelIndex &index) const
{
return (index.isValid()
- && index.row() < verticalHeaderItems.count()
- && index.column() < horizontalHeaderItems.count());
+ && index.row() < verticalHeaderItems.size()
+ && index.column() < horizontalHeaderItems.size());
}
void QTableModel::clear()
{
- for (int j = 0; j < verticalHeaderItems.count(); ++j) {
+ for (int j = 0; j < verticalHeaderItems.size(); ++j) {
if (verticalHeaderItems.at(j)) {
verticalHeaderItems.at(j)->view = nullptr;
delete verticalHeaderItems.at(j);
verticalHeaderItems[j] = 0;
}
}
- for (int k = 0; k < horizontalHeaderItems.count(); ++k) {
+ for (int k = 0; k < horizontalHeaderItems.size(); ++k) {
if (horizontalHeaderItems.at(k)) {
horizontalHeaderItems.at(k)->view = nullptr;
delete horizontalHeaderItems.at(k);
@@ -783,7 +746,7 @@ void QTableModel::clear()
void QTableModel::clearContents()
{
beginResetModel();
- for (int i = 0; i < tableItems.count(); ++i) {
+ for (int i = 0; i < tableItems.size(); ++i) {
if (tableItems.at(i)) {
tableItems.at(i)->view = nullptr;
delete tableItems.at(i);
@@ -797,7 +760,7 @@ void QTableModel::itemChanged(QTableWidgetItem *item, const QList<int> &roles)
{
if (!item)
return;
- if (item->flags() & ItemIsHeaderItem) {
+ if (item->d->headerItem) {
int row = verticalHeaderItems.indexOf(item);
if (row >= 0) {
emit headerDataChanged(Qt::Vertical, row, row);
@@ -845,7 +808,7 @@ QMimeData *QTableModel::internalMimeData() const
QMimeData *QTableModel::mimeData(const QModelIndexList &indexes) const
{
QList<QTableWidgetItem*> items;
- const int indexesCount = indexes.count();
+ const int indexesCount = indexes.size();
items.reserve(indexesCount);
for (int i = 0; i < indexesCount; ++i)
items << item(indexes.at(i));
@@ -919,6 +882,20 @@ Qt::DropActions QTableModel::supportedDropActions() const
*/
/*!
+ \fn bool QTableWidgetSelectionRange::operator==(const QTableWidgetSelectionRange &lhs, const QTableWidgetSelectionRange &rhs)
+ \since 6.3
+
+ Returns true if \a lhs and \a rhs are equal, otherwise returns false.
+*/
+
+/*!
+ \fn bool QTableWidgetSelectionRange::operator!=(const QTableWidgetSelectionRange &lhs, const QTableWidgetSelectionRange &rhs)
+ \since 6.3
+
+ Returns true if \a lhs and \a rhs are not equal, otherwise returns false.
+*/
+
+/*!
\fn int QTableWidgetSelectionRange::topRow() const
Returns the top row of the range.
@@ -1275,14 +1252,29 @@ void QTableWidgetItem::setFlags(Qt::ItemFlags aflags)
*/
/*!
+ \if defined(qt7)
+
+ \fn Qt::Alignment QTableWidgetItem::textAlignment() const
+
+ Returns the text alignment for the list item.
+
+ \else
+
\fn int QTableWidgetItem::textAlignment() const
Returns the text alignment for the item's text.
+ \note This function returns an int for historical reasons. It will
+ be corrected to return Qt::Alignment in Qt 7.
+
\sa Qt::Alignment
+
+ \endif
*/
/*!
+ \obsolete [6.4] Use the overload that takes a Qt::Alignment argument.
+
\fn void QTableWidgetItem::setTextAlignment(int alignment)
Sets the text alignment for the item's text to the \a alignment
@@ -1292,6 +1284,20 @@ void QTableWidgetItem::setFlags(Qt::ItemFlags aflags)
*/
/*!
+ \since 6.4
+
+ \fn void QTableWidgetItem::setTextAlignment(Qt::Alignment alignment)
+
+ Sets the text alignment for the item's text to the \a alignment
+ specified.
+*/
+
+/*!
+ \fn void QTableWidgetItem::setTextAlignment(Qt::AlignmentFlag alignment)
+ \internal
+*/
+
+/*!
Constructs a table item of the specified \a type that does not belong
to any table.
@@ -1373,7 +1379,7 @@ void QTableWidgetItem::setData(int role, const QVariant &value)
{
bool found = false;
role = (role == Qt::EditRole ? Qt::DisplayRole : role);
- for (int i = 0; i < values.count(); ++i) {
+ for (int i = 0; i < values.size(); ++i) {
if (values.at(i).role == role) {
if (values[i].value == value)
return;
@@ -1585,28 +1591,41 @@ QTableWidgetItem &QTableWidgetItem::operator=(const QTableWidgetItem &other)
void QTableWidgetPrivate::setup()
{
Q_Q(QTableWidget);
- // view signals
- QObject::connect(q, SIGNAL(pressed(QModelIndex)), q, SLOT(_q_emitItemPressed(QModelIndex)));
- QObject::connect(q, SIGNAL(clicked(QModelIndex)), q, SLOT(_q_emitItemClicked(QModelIndex)));
- QObject::connect(q, SIGNAL(doubleClicked(QModelIndex)),
- q, SLOT(_q_emitItemDoubleClicked(QModelIndex)));
- QObject::connect(q, SIGNAL(activated(QModelIndex)), q, SLOT(_q_emitItemActivated(QModelIndex)));
- QObject::connect(q, SIGNAL(entered(QModelIndex)), q, SLOT(_q_emitItemEntered(QModelIndex)));
- // model signals
- QObject::connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
- q, SLOT(_q_emitItemChanged(QModelIndex)));
- // selection signals
- QObject::connect(q->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- q, SLOT(_q_emitCurrentItemChanged(QModelIndex,QModelIndex)));
- QObject::connect(q->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
- q, SIGNAL(itemSelectionChanged()));
- // sorting
- QObject::connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
- q, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
- QObject::connect(model, SIGNAL(columnsRemoved(QModelIndex,int,int)), q, SLOT(_q_sort()));
-}
-
-void QTableWidgetPrivate::_q_emitItemPressed(const QModelIndex &index)
+ connections = {
+ // view signals
+ QObjectPrivate::connect(q, &QTableWidget::pressed,
+ this, &QTableWidgetPrivate::emitItemPressed),
+ QObjectPrivate::connect(q, &QTableWidget::clicked,
+ this, &QTableWidgetPrivate::emitItemClicked),
+ QObjectPrivate::connect(q, &QTableWidget::doubleClicked,
+ this, &QTableWidgetPrivate::emitItemDoubleClicked),
+ QObjectPrivate::connect(q, &QTableWidget::activated,
+ this, &QTableWidgetPrivate::emitItemActivated),
+ QObjectPrivate::connect(q, &QTableWidget::entered,
+ this, &QTableWidgetPrivate::emitItemEntered),
+ // model signals
+ QObjectPrivate::connect(model, &QAbstractItemModel::dataChanged,
+ this, &QTableWidgetPrivate::emitItemChanged),
+ // selection signals
+ QObjectPrivate::connect(q->selectionModel(), &QItemSelectionModel::currentChanged,
+ this, &QTableWidgetPrivate::emitCurrentItemChanged),
+ QObject::connect(q->selectionModel(), &QItemSelectionModel::selectionChanged,
+ q, &QTableWidget::itemSelectionChanged),
+ // sorting
+ QObjectPrivate::connect(model, &QAbstractItemModel::dataChanged,
+ this, &QTableWidgetPrivate::dataChanged),
+ QObjectPrivate::connect(model, &QAbstractItemModel::columnsRemoved,
+ this, &QTableWidgetPrivate::sort)
+ };
+}
+
+void QTableWidgetPrivate::clearConnections()
+{
+ for (const QMetaObject::Connection &connection : connections)
+ QObject::disconnect(connection);
+}
+
+void QTableWidgetPrivate::emitItemPressed(const QModelIndex &index)
{
Q_Q(QTableWidget);
if (QTableWidgetItem *item = tableModel()->item(index))
@@ -1614,7 +1633,7 @@ void QTableWidgetPrivate::_q_emitItemPressed(const QModelIndex &index)
emit q->cellPressed(index.row(), index.column());
}
-void QTableWidgetPrivate::_q_emitItemClicked(const QModelIndex &index)
+void QTableWidgetPrivate::emitItemClicked(const QModelIndex &index)
{
Q_Q(QTableWidget);
if (QTableWidgetItem *item = tableModel()->item(index))
@@ -1622,7 +1641,7 @@ void QTableWidgetPrivate::_q_emitItemClicked(const QModelIndex &index)
emit q->cellClicked(index.row(), index.column());
}
-void QTableWidgetPrivate::_q_emitItemDoubleClicked(const QModelIndex &index)
+void QTableWidgetPrivate::emitItemDoubleClicked(const QModelIndex &index)
{
Q_Q(QTableWidget);
if (QTableWidgetItem *item = tableModel()->item(index))
@@ -1630,7 +1649,7 @@ void QTableWidgetPrivate::_q_emitItemDoubleClicked(const QModelIndex &index)
emit q->cellDoubleClicked(index.row(), index.column());
}
-void QTableWidgetPrivate::_q_emitItemActivated(const QModelIndex &index)
+void QTableWidgetPrivate::emitItemActivated(const QModelIndex &index)
{
Q_Q(QTableWidget);
if (QTableWidgetItem *item = tableModel()->item(index))
@@ -1638,7 +1657,7 @@ void QTableWidgetPrivate::_q_emitItemActivated(const QModelIndex &index)
emit q->cellActivated(index.row(), index.column());
}
-void QTableWidgetPrivate::_q_emitItemEntered(const QModelIndex &index)
+void QTableWidgetPrivate::emitItemEntered(const QModelIndex &index)
{
Q_Q(QTableWidget);
if (QTableWidgetItem *item = tableModel()->item(index))
@@ -1646,7 +1665,7 @@ void QTableWidgetPrivate::_q_emitItemEntered(const QModelIndex &index)
emit q->cellEntered(index.row(), index.column());
}
-void QTableWidgetPrivate::_q_emitItemChanged(const QModelIndex &index)
+void QTableWidgetPrivate::emitItemChanged(const QModelIndex &index)
{
Q_Q(QTableWidget);
if (QTableWidgetItem *item = tableModel()->item(index))
@@ -1654,7 +1673,7 @@ void QTableWidgetPrivate::_q_emitItemChanged(const QModelIndex &index)
emit q->cellChanged(index.row(), index.column());
}
-void QTableWidgetPrivate::_q_emitCurrentItemChanged(const QModelIndex &current,
+void QTableWidgetPrivate::emitCurrentItemChanged(const QModelIndex &current,
const QModelIndex &previous)
{
Q_Q(QTableWidget);
@@ -1665,7 +1684,7 @@ void QTableWidgetPrivate::_q_emitCurrentItemChanged(const QModelIndex &current,
emit q->currentCellChanged(current.row(), current.column(), previous.row(), previous.column());
}
-void QTableWidgetPrivate::_q_sort()
+void QTableWidgetPrivate::sort()
{
if (sortingEnabled) {
int column = horizontalHeader->sortIndicatorSection();
@@ -1674,8 +1693,8 @@ void QTableWidgetPrivate::_q_sort()
}
}
-void QTableWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft,
- const QModelIndex &bottomRight)
+void QTableWidgetPrivate::dataChanged(const QModelIndex &topLeft,
+ const QModelIndex &bottomRight)
{
if (sortingEnabled && topLeft.isValid() && bottomRight.isValid()) {
int column = horizontalHeader->sortIndicatorSection();
@@ -1873,6 +1892,8 @@ QTableWidget::QTableWidget(int rows, int columns, QWidget *parent)
*/
QTableWidget::~QTableWidget()
{
+ Q_D(QTableWidget);
+ d->clearConnections();
}
/*!
@@ -2080,7 +2101,7 @@ void QTableWidget::setVerticalHeaderLabels(const QStringList &labels)
Q_D(QTableWidget);
QTableModel *model = d->tableModel();
QTableWidgetItem *item = nullptr;
- for (int i = 0; i < model->rowCount() && i < labels.count(); ++i) {
+ for (int i = 0; i < model->rowCount() && i < labels.size(); ++i) {
item = model->verticalHeaderItem(i);
if (!item) {
item = model->createItem();
@@ -2098,7 +2119,7 @@ void QTableWidget::setHorizontalHeaderLabels(const QStringList &labels)
Q_D(QTableWidget);
QTableModel *model = d->tableModel();
QTableWidgetItem *item = nullptr;
- for (int i = 0; i < model->columnCount() && i < labels.count(); ++i) {
+ for (int i = 0; i < model->columnCount() && i < labels.size(); ++i) {
item = model->horizontalHeaderItem(i);
if (!item) {
item = model->createItem();
@@ -2337,7 +2358,7 @@ QList<QTableWidgetSelectionRange> QTableWidget::selectedRanges() const
{
const QList<QItemSelectionRange> ranges = selectionModel()->selection();
QList<QTableWidgetSelectionRange> result;
- const int rangesCount = ranges.count();
+ const int rangesCount = ranges.size();
result.reserve(rangesCount);
for (int i = 0; i < rangesCount; ++i)
result.append({ranges.at(i).top(),
@@ -2575,7 +2596,7 @@ QMimeData *QTableWidget::mimeData(const QList<QTableWidgetItem *> &items) const
// if non empty, it's called from the model's own mimeData
if (cachedIndexes.isEmpty()) {
- cachedIndexes.reserve(items.count());
+ cachedIndexes.reserve(items.size());
for (QTableWidgetItem *item : items)
cachedIndexes << indexFromItem(item);
@@ -2690,7 +2711,7 @@ void QTableWidget::dropEvent(QDropEvent *event) {
}
QList<QTableWidgetItem *> taken;
- const int indexesCount = indexes.count();
+ const int indexesCount = indexes.size();
taken.reserve(indexesCount);
for (const auto &index : indexes)
taken.append(takeItem(index.row(), index.column()));
diff --git a/src/widgets/itemviews/qtablewidget.h b/src/widgets/itemviews/qtablewidget.h
index 8f3a36daf1..303f4d5f5b 100644
--- a/src/widgets/itemviews/qtablewidget.h
+++ b/src/widgets/itemviews/qtablewidget.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTABLEWIDGET_H
#define QTABLEWIDGET_H
@@ -57,6 +21,16 @@ public:
: m_top(top), m_left(left), m_bottom(bottom), m_right(right)
{}
+ friend bool operator==(const QTableWidgetSelectionRange &lhs,
+ const QTableWidgetSelectionRange &rhs) noexcept
+ {
+ return lhs.m_top == rhs.m_top && lhs.m_left == rhs.m_left && lhs.m_bottom == rhs.m_bottom
+ && lhs.m_right == rhs.m_right;
+ }
+ friend bool operator!=(const QTableWidgetSelectionRange &lhs,
+ const QTableWidgetSelectionRange &rhs) noexcept
+ { return !(lhs == rhs); }
+
inline int topRow() const { return m_top; }
inline int bottomRow() const { return m_bottom; }
inline int leftColumn() const { return m_left; }
@@ -125,10 +99,22 @@ public:
{ return qvariant_cast<QFont>(data(Qt::FontRole)); }
inline void setFont(const QFont &font);
+#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
inline int textAlignment() const
{ return data(Qt::TextAlignmentRole).toInt(); }
+#else
+ inline Qt::Alignment textAlignment() const
+ { return qvariant_cast<Qt::Alignment>(data(Qt::TextAlignmentRole)); }
+#endif
+#if QT_DEPRECATED_SINCE(6, 4)
+ QT_DEPRECATED_VERSION_X_6_4("Use the overload taking Qt::Alignment")
inline void setTextAlignment(int alignment)
{ setData(Qt::TextAlignmentRole, alignment); }
+ inline void setTextAlignment(Qt::AlignmentFlag alignment)
+ { setData(Qt::TextAlignmentRole, QVariant::fromValue(Qt::Alignment(alignment))); }
+#endif
+ inline void setTextAlignment(Qt::Alignment alignment)
+ { setData(Qt::TextAlignmentRole, QVariant::fromValue(alignment)); }
inline QBrush background() const
{ return qvariant_cast<QBrush>(data(Qt::BackgroundRole)); }
@@ -141,7 +127,7 @@ public:
{ setData(Qt::ForegroundRole, brush.style() != Qt::NoBrush ? QVariant(brush) : QVariant()); }
inline Qt::CheckState checkState() const
- { return static_cast<Qt::CheckState>(data(Qt::CheckStateRole).toInt()); }
+ { return qvariant_cast<Qt::CheckState>(data(Qt::CheckStateRole)); }
inline void setCheckState(Qt::CheckState state)
{ setData(Qt::CheckStateRole, state); }
@@ -326,16 +312,6 @@ private:
Q_DECLARE_PRIVATE(QTableWidget)
Q_DISABLE_COPY(QTableWidget)
-
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemPressed(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemClicked(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemDoubleClicked(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemActivated(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemEntered(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemChanged(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitCurrentItemChanged(const QModelIndex &previous, const QModelIndex &current))
- Q_PRIVATE_SLOT(d_func(), void _q_sort())
- Q_PRIVATE_SLOT(d_func(), void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight))
};
inline void QTableWidget::removeCellWidget(int arow, int acolumn)
diff --git a/src/widgets/itemviews/qtablewidget_p.h b/src/widgets/itemviews/qtablewidget_p.h
index 0117247635..210910fc52 100644
--- a/src/widgets/itemviews/qtablewidget_p.h
+++ b/src/widgets/itemviews/qtablewidget_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTABLEWIDGET_P_H
#define QTABLEWIDGET_P_H
@@ -58,6 +22,8 @@
#include <private/qtableview_p.h>
#include <private/qwidgetitemdata_p.h>
+#include <array>
+
QT_REQUIRE_CONFIG(tablewidget);
QT_BEGIN_NAMESPACE
@@ -89,10 +55,6 @@ class QTableModel : public QAbstractTableModel
friend class QTableWidget;
public:
- enum ItemFlagsExtension {
- ItemIsHeaderItem = 128
- }; // we need this to separate header items from other items
-
QTableModel(int rows, int columns, QTableWidget *parent);
~QTableModel();
@@ -154,7 +116,7 @@ public:
bool isValid(const QModelIndex &index) const;
inline long tableIndex(int row, int column) const
- { return (row * horizontalHeaderItems.count()) + column; }
+ { return (row * horizontalHeaderItems.size()) + column; }
void clear();
void clearContents();
@@ -190,28 +152,32 @@ public:
QTableWidgetPrivate() : QTableViewPrivate() {}
inline QTableModel *tableModel() const { return qobject_cast<QTableModel*>(model); }
void setup();
+ void clearConnections();
// view signals
- void _q_emitItemPressed(const QModelIndex &index);
- void _q_emitItemClicked(const QModelIndex &index);
- void _q_emitItemDoubleClicked(const QModelIndex &index);
- void _q_emitItemActivated(const QModelIndex &index);
- void _q_emitItemEntered(const QModelIndex &index);
+ void emitItemPressed(const QModelIndex &index);
+ void emitItemClicked(const QModelIndex &index);
+ void emitItemDoubleClicked(const QModelIndex &index);
+ void emitItemActivated(const QModelIndex &index);
+ void emitItemEntered(const QModelIndex &index);
// model signals
- void _q_emitItemChanged(const QModelIndex &index);
+ void emitItemChanged(const QModelIndex &index);
// selection signals
- void _q_emitCurrentItemChanged(const QModelIndex &previous, const QModelIndex &current);
+ void emitCurrentItemChanged(const QModelIndex &previous, const QModelIndex &current);
// sorting
- void _q_sort();
- void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ void sort();
+ void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+
+ std::array<QMetaObject::Connection, 10> connections;
};
class QTableWidgetItemPrivate
{
public:
- QTableWidgetItemPrivate(QTableWidgetItem *item) : q(item), id(-1) {}
+ QTableWidgetItemPrivate(QTableWidgetItem *item) : q(item), id(-1), headerItem(false) {}
QTableWidgetItem *q;
int id;
+ bool headerItem; // Qt 7 TODO: inline this stuff in the public class.
};
QT_END_NAMESPACE
diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp
index 500a6152d8..744f29ca17 100644
--- a/src/widgets/itemviews/qtreeview.cpp
+++ b/src/widgets/itemviews/qtreeview.cpp
@@ -1,45 +1,9 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qtreeview.h"
#include <qheaderview.h>
-#include <qitemdelegate.h>
+#include <qabstractitemdelegate.h>
#include <qapplication.h>
#include <qscrollbar.h>
#include <qpainter.h>
@@ -51,7 +15,7 @@
#include <qdebug.h>
#include <QMetaMethod>
#include <private/qscrollbar_p.h>
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
#include <qaccessible.h>
#endif
@@ -160,8 +124,7 @@ QT_BEGIN_NAMESPACE
that can be taken for views that are intended to display items with equal heights
is to set the \l uniformRowHeights property to true.
- \sa QListView, QTreeWidget, {View Classes}, QAbstractItemModel, QAbstractItemView,
- {Dir View Example}
+ \sa QListView, QTreeWidget, {View Classes}, QAbstractItemModel, QAbstractItemView
*/
@@ -206,6 +169,8 @@ QTreeView::QTreeView(QTreeViewPrivate &dd, QWidget *parent)
*/
QTreeView::~QTreeView()
{
+ Q_D(QTreeView);
+ d->clearConnections();
}
/*!
@@ -217,18 +182,12 @@ void QTreeView::setModel(QAbstractItemModel *model)
if (model == d->model)
return;
if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
- disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(rowsRemoved(QModelIndex,int,int)));
-
- disconnect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_modelAboutToBeReset()));
+ for (const QMetaObject::Connection &connection : d->modelConnections)
+ QObject::disconnect(connection);
}
if (d->selectionModel) { // support row editing
- disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
- d->model, SLOT(submit()));
- disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(rowsRemoved(QModelIndex,int,int)));
- disconnect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_modelAboutToBeReset()));
+ QObject::disconnect(d->selectionmodelConnection);
}
d->viewItems.clear();
d->expandedIndexes.clear();
@@ -238,20 +197,24 @@ void QTreeView::setModel(QAbstractItemModel *model)
d->geometryRecursionBlock = false;
QAbstractItemView::setModel(model);
- // QAbstractItemView connects to a private slot
- disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
- // do header layout after the tree
- disconnect(d->model, SIGNAL(layoutChanged()),
- d->header, SLOT(_q_layoutChanged()));
- // QTreeView has a public slot for this
- connect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(rowsRemoved(QModelIndex,int,int)));
-
- connect(d->model, SIGNAL(modelAboutToBeReset()), SLOT(_q_modelAboutToBeReset()));
-
+ if (d->model) {
+ // QAbstractItemView connects to a private slot
+ QObjectPrivate::disconnect(d->model, &QAbstractItemModel::rowsRemoved,
+ d, &QAbstractItemViewPrivate::rowsRemoved);
+ // do header layout after the tree
+ QObjectPrivate::disconnect(d->model, &QAbstractItemModel::layoutChanged,
+ d->header->d_func(), &QAbstractItemViewPrivate::layoutChanged);
+
+ d->modelConnections = {
+ // QTreeView has a public slot for this
+ QObject::connect(d->model, &QAbstractItemModel::rowsRemoved,
+ this, &QTreeView::rowsRemoved),
+ QObjectPrivate::connect(d->model, &QAbstractItemModel::modelAboutToBeReset,
+ d, &QTreeViewPrivate::modelAboutToBeReset)
+ };
+ }
if (d->sortingEnabled)
- d->_q_sortIndicatorChanged(header()->sortIndicatorSection(), header()->sortIndicatorOrder());
+ d->sortIndicatorChanged(header()->sortIndicatorSection(), header()->sortIndicatorOrder());
}
/*!
@@ -273,8 +236,7 @@ void QTreeView::setSelectionModel(QItemSelectionModel *selectionModel)
Q_ASSERT(selectionModel);
if (d->selectionModel) {
// support row editing
- disconnect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
- d->model, SLOT(submit()));
+ QObject::disconnect(d->selectionmodelConnection);
}
d->header->setSelectionModel(selectionModel);
@@ -282,8 +244,9 @@ void QTreeView::setSelectionModel(QItemSelectionModel *selectionModel)
if (d->selectionModel) {
// support row editing
- connect(d->selectionModel, SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
- d->model, SLOT(submit()));
+ d->selectionmodelConnection =
+ connect(d->selectionModel, &QItemSelectionModel::currentRowChanged,
+ d->model, &QAbstractItemModel::submit);
}
}
@@ -323,16 +286,18 @@ void QTreeView::setHeader(QHeaderView *header)
d->header->setSelectionModel(d->selectionModel);
}
- connect(d->header, SIGNAL(sectionResized(int,int,int)),
- this, SLOT(columnResized(int,int,int)));
- connect(d->header, SIGNAL(sectionMoved(int,int,int)),
- this, SLOT(columnMoved()));
- connect(d->header, SIGNAL(sectionCountChanged(int,int)),
- this, SLOT(columnCountChanged(int,int)));
- connect(d->header, SIGNAL(sectionHandleDoubleClicked(int)),
- this, SLOT(resizeColumnToContents(int)));
- connect(d->header, SIGNAL(geometriesChanged()),
- this, SLOT(updateGeometries()));
+ d->headerConnections = {
+ connect(d->header, &QHeaderView::sectionResized,
+ this, &QTreeView::columnResized),
+ connect(d->header, &QHeaderView::sectionMoved,
+ this, &QTreeView::columnMoved),
+ connect(d->header, &QHeaderView::sectionCountChanged,
+ this, &QTreeView::columnCountChanged),
+ connect(d->header, &QHeaderView::sectionHandleDoubleClicked,
+ this, &QTreeView::resizeColumnToContents),
+ connect(d->header, &QHeaderView::geometriesChanged,
+ this, &QTreeView::updateGeometries)
+ };
setSortingEnabled(d->sortingEnabled);
d->updateGeometry();
@@ -876,11 +841,12 @@ void QTreeView::setSortingEnabled(bool enable)
//sortByColumn has to be called before we connect or set the sortingEnabled flag
// because otherwise it will not call sort on the model.
sortByColumn(header()->sortIndicatorSection(), header()->sortIndicatorOrder());
- connect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
- this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)), Qt::UniqueConnection);
+ d->sortHeaderConnection =
+ QObjectPrivate::connect(header(), &QHeaderView::sortIndicatorChanged,
+ d, &QTreeViewPrivate::sortIndicatorChanged,
+ Qt::UniqueConnection);
} else {
- disconnect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)),
- this, SLOT(_q_sortIndicatorChanged(int,Qt::SortOrder)));
+ QObject::disconnect(d->sortHeaderConnection);
}
d->sortingEnabled = enable;
}
@@ -1038,9 +1004,9 @@ void QTreeView::keyboardSearch(const QString &search)
// special case for searches with same key like 'aaaaa'
bool sameKey = false;
- if (d->keyboardInput.length() > 1) {
- int c = d->keyboardInput.count(d->keyboardInput.at(d->keyboardInput.length() - 1));
- sameKey = (c == d->keyboardInput.length());
+ if (d->keyboardInput.size() > 1) {
+ int c = d->keyboardInput.count(d->keyboardInput.at(d->keyboardInput.size() - 1));
+ sameKey = (c == d->keyboardInput.size());
if (sameKey)
skipRow = true;
}
@@ -1065,7 +1031,7 @@ void QTreeView::keyboardSearch(const QString &search)
int bestAbove = -1;
int bestBelow = -1;
QString searchString = sameKey ? QString(d->keyboardInput.at(0)) : d->keyboardInput;
- for (int i = 0; i < d->viewItems.count(); ++i) {
+ for (int i = 0; i < d->viewItems.size(); ++i) {
if ((int)d->viewItems.at(i).level > previousLevel) {
QModelIndex searchFrom = d->viewItems.at(i).index;
if (start.column() > 0)
@@ -1073,7 +1039,7 @@ void QTreeView::keyboardSearch(const QString &search)
if (searchFrom.parent() == start.parent())
searchFrom = start;
QModelIndexList match = d->model->match(searchFrom, Qt::DisplayRole, searchString);
- if (match.count()) {
+ if (match.size()) {
int hitIndex = d->viewIndex(match.at(0));
if (hitIndex >= 0 && hitIndex < startIndex)
bestAbove = bestAbove == -1 ? hitIndex : qMin(hitIndex, bestAbove);
@@ -1104,33 +1070,64 @@ void QTreeView::keyboardSearch(const QString &search)
QRect QTreeView::visualRect(const QModelIndex &index) const
{
Q_D(const QTreeView);
+ return d->visualRect(index, QTreeViewPrivate::SingleSection);
+}
- if (!d->isIndexValid(index) || isIndexHidden(index))
+/*!
+ \internal
+ \return the visual rectangle at \param index, according to \param rule.
+ \list
+ \li SingleSection
+ The return value matches the section, which \a index points to.
+ \li FullRow
+ Return the rectangle of the entire row, no matter which section
+ \a index points to.
+ \li AddRowIndicatorToFirstSection
+ Like SingleSection. If \index points to the first section, add the
+ row indicator and its margins.
+ \endlist
+ */
+QRect QTreeViewPrivate::visualRect(const QModelIndex &index, RectRule rule) const
+{
+ Q_Q(const QTreeView);
+
+ if (!isIndexValid(index))
return QRect();
- d->executePostedLayout();
+ // Calculate the entire row's rectangle, even if one of the elements is hidden
+ if (q->isIndexHidden(index) && rule != FullRow)
+ return QRect();
+
+ executePostedLayout();
- int vi = d->viewIndex(index);
- if (vi < 0)
+ const int viewIndex = this->viewIndex(index);
+ if (viewIndex < 0)
return QRect();
- bool spanning = d->viewItems.at(vi).spanning;
+ const bool spanning = viewItems.at(viewIndex).spanning;
+ const int column = index.column();
// if we have a spanning item, make the selection stretch from left to right
- int x = (spanning ? 0 : columnViewportPosition(index.column()));
- int w = (spanning ? d->header->length() : columnWidth(index.column()));
- // handle indentation
- if (d->isTreePosition(index.column())) {
- int i = d->indentationForItem(vi);
- w -= i;
- if (!isRightToLeft())
- x += i;
+ int x = (spanning ? 0 : q->columnViewportPosition(column));
+ int width = (spanning ? header->length() : q->columnWidth(column));
+
+ const bool addIndentation = isTreePosition(column) && (column > 0 || rule == SingleSection);
+
+ if (rule == FullRow) {
+ x = 0;
+ width = q->viewport()->width();
+ } else if (addIndentation) {
+ // calculate indentation
+ const int indentation = indentationForItem(viewIndex);
+ width -= indentation;
+ if (!q->isRightToLeft())
+ x += indentation;
}
- int y = d->coordinateForItem(vi);
- int h = d->itemHeight(vi);
+ const int y = coordinateForItem(viewIndex);
+ const int height = itemHeight(viewIndex);
- return QRect(x, y, w, h);
+ return QRect(x, y, width, height);
}
/*!
@@ -1313,16 +1310,13 @@ bool QTreeView::viewportEvent(QEvent *event)
case QEvent::HoverLeave:
case QEvent::HoverMove: {
QHoverEvent *he = static_cast<QHoverEvent*>(event);
- int oldBranch = d->hoverBranch;
+ const int oldBranch = d->hoverBranch;
d->hoverBranch = d->itemDecorationAt(he->position().toPoint());
QModelIndex newIndex = indexAt(he->position().toPoint());
if (d->hover != newIndex || d->hoverBranch != oldBranch) {
// Update the whole hovered over row. No need to update the old hovered
// row, that is taken care in superclass hover handling.
- QRect rect = visualRect(newIndex);
- rect.setX(0);
- rect.setWidth(viewport()->width());
- viewport()->update(rect);
+ viewport()->update(d->visualRect(newIndex, QTreeViewPrivate::FullRow));
}
break; }
default:
@@ -1405,18 +1399,16 @@ bool QTreeViewPrivate::expandOrCollapseItemAtPos(const QPoint &pos)
return false;
}
-void QTreeViewPrivate::_q_modelDestroyed()
+void QTreeViewPrivate::modelDestroyed()
{
//we need to clear the viewItems because it contains QModelIndexes to
//the model currently being destroyed
viewItems.clear();
- QAbstractItemViewPrivate::_q_modelDestroyed();
+ QAbstractItemViewPrivate::modelDestroyed();
}
QRect QTreeViewPrivate::intersectedRect(const QRect rect, const QModelIndex &topLeft, const QModelIndex &bottomRight) const
{
- Q_Q(const QTreeView);
-
const auto parentIdx = topLeft.parent();
executePostedLayout();
QRect updateRect;
@@ -1425,7 +1417,7 @@ QRect QTreeViewPrivate::intersectedRect(const QRect rect, const QModelIndex &top
continue;
for (int c = topLeft.column(); c <= bottomRight.column(); ++c) {
const QModelIndex idx(model->index(r, c, parentIdx));
- updateRect |= q->visualRect(idx);
+ updateRect |= visualRect(idx, SingleSection);
}
}
return rect.intersected(updateRect);
@@ -1494,7 +1486,7 @@ void QTreeView::drawTree(QPainter *painter, const QRegion &region) const
const QStyle::State state = option.state;
d->current = 0;
- if (viewItems.count() == 0 || d->header->count() == 0 || !d->itemDelegate) {
+ if (viewItems.size() == 0 || d->header->count() == 0 || !d->itemDelegate) {
d->paintAlternatingRowColors(painter, &option, 0, region.boundingRect().bottom()+1);
return;
}
@@ -1523,7 +1515,7 @@ void QTreeView::drawTree(QPainter *painter, const QRegion &region) const
int y = firstVisibleItemOffset; // we may only see part of the first item
// start at the top of the viewport and iterate down to the update area
- for (; i < viewItems.count(); ++i) {
+ for (; i < viewItems.size(); ++i) {
const int itemHeight = d->itemHeight(i);
if (y + itemHeight > area.top())
break;
@@ -1531,9 +1523,10 @@ void QTreeView::drawTree(QPainter *painter, const QRegion &region) const
}
// paint the visible rows
- for (; i < viewItems.count() && y <= area.bottom(); ++i) {
+ for (; i < viewItems.size() && y <= area.bottom(); ++i) {
+ const QModelIndex &index = viewItems.at(i).index;
const int itemHeight = d->itemHeight(i);
- option.rect.setRect(0, y, viewportWidth, itemHeight);
+ option.rect = d->visualRect(index, QTreeViewPrivate::FullRow);
option.state = state | (viewItems.at(i).expanded ? QStyle::State_Open : QStyle::State_None)
| (viewItems.at(i).hasChildren ? QStyle::State_Children : QStyle::State_None)
| (viewItems.at(i).hasMoreSiblings ? QStyle::State_Sibling : QStyle::State_None);
@@ -1592,11 +1585,11 @@ void QTreeViewPrivate::calcLogicalIndices(
}
}
- itemPositions->resize(logicalIndices->count());
- for (int currentLogicalSection = 0; currentLogicalSection < logicalIndices->count(); ++currentLogicalSection) {
+ itemPositions->resize(logicalIndices->size());
+ for (int currentLogicalSection = 0; currentLogicalSection < logicalIndices->size(); ++currentLogicalSection) {
const int headerSection = logicalIndices->at(currentLogicalSection);
// determine the viewItemPosition depending on the position of column 0
- int nextLogicalSection = currentLogicalSection + 1 >= logicalIndices->count()
+ int nextLogicalSection = currentLogicalSection + 1 >= logicalIndices->size()
? logicalIndexAfterRight
: logicalIndices->at(currentLogicalSection + 1);
int prevLogicalSection = currentLogicalSection - 1 < 0
@@ -1695,8 +1688,11 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option,
}
}
- // ### special case: treeviews with multiple columns draw
- // the selections differently than with only one column
+ // ### special case: if we select entire rows, then we need to draw the
+ // selection in the first column all the way to the second column, rather
+ // than just around the item text. We abuse showDecorationSelected to
+ // indicate this to the style. Below we will reset this value temporarily
+ // to only respect the styleHint while we are rendering the decoration.
opt.showDecorationSelected = (d->selectionBehavior & SelectRows)
|| option.showDecorationSelected;
@@ -1712,7 +1708,7 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option,
viewItemPosList; // vector of left/middle/end for each logicalIndex
d->calcLogicalIndices(&logicalIndices, &viewItemPosList, left, right);
- for (int currentLogicalSection = 0; currentLogicalSection < logicalIndices.count(); ++currentLogicalSection) {
+ for (int currentLogicalSection = 0; currentLogicalSection < logicalIndices.size(); ++currentLogicalSection) {
int headerSection = logicalIndices.at(currentLogicalSection);
position = columnViewportPosition(headerSection) + offset.x();
width = header->sectionSize(headerSection);
@@ -1781,8 +1777,16 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option,
}
// draw background for the branch (selection + alternate row)
opt.rect = branches;
- if (style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected, &opt, this))
- style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, this);
+
+ // We use showDecorationSelected both to store the style hint, and to indicate
+ // that the entire row has to be selected (see overrides of the value if
+ // selectionBehavior == SelectRow).
+ // While we are only painting the background we don't care for the
+ // selectionBehavior factor, so respect only the style value, and reset later.
+ const bool oldShowDecorationSelected = opt.showDecorationSelected;
+ opt.showDecorationSelected = style()->styleHint(QStyle::SH_ItemView_ShowDecorationSelected,
+ &opt, this);
+ style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, this);
// draw background of the item (only alternate row). rest of the background
// is provided by the delegate
@@ -1791,6 +1795,7 @@ void QTreeView::drawRow(QPainter *painter, const QStyleOptionViewItem &option,
opt.rect.setRect(reverse ? position : i + position, y, width - i, height);
style()->drawPrimitive(QStyle::PE_PanelItemViewRow, &opt, painter, this);
opt.state = oldState;
+ opt.showDecorationSelected = oldShowDecorationSelected;
if (d->indent != 0)
drawBranches(painter, branches, index);
@@ -1997,13 +2002,13 @@ void QTreeView::mouseDoubleClickEvent(QMouseEvent *event)
if (d->itemsExpandable
&& d->expandsOnDoubleClick
&& d->hasVisibleChildren(persistent)) {
- if (!((i < d->viewItems.count()) && (d->viewItems.at(i).index == firstColumnIndex))) {
+ if (!((i < d->viewItems.size()) && (d->viewItems.at(i).index == firstColumnIndex))) {
// find the new index of the item
- for (i = 0; i < d->viewItems.count(); ++i) {
+ for (i = 0; i < d->viewItems.size(); ++i) {
if (d->viewItems.at(i).index == firstColumnIndex)
break;
}
- if (i == d->viewItems.count())
+ if (i == d->viewItems.size())
return;
}
if (d->viewItems.at(i).expanded)
@@ -2101,7 +2106,7 @@ QModelIndex QTreeView::indexBelow(const QModelIndex &index) const
return QModelIndex();
d->executePostedLayout();
int i = d->viewIndex(index);
- if (++i >= d->viewItems.count())
+ if (++i >= d->viewItems.size())
return QModelIndex();
const QModelIndex firstColumnIndex = d->viewItems.at(i).index;
return firstColumnIndex.sibling(firstColumnIndex.row(), index.column());
@@ -2140,6 +2145,7 @@ void QTreeView::doItemsLayout()
}
QAbstractItemView::doItemsLayout();
d->header->doItemsLayout();
+ d->updateAccessibility();
}
/*!
@@ -2185,7 +2191,7 @@ int QTreeView::verticalOffset() const
// ### find a faster way to do this
d->executePostedLayout();
int offset = 0;
- const int cnt = qMin(d->viewItems.count(), verticalScrollBar()->value());
+ const int cnt = qMin(d->viewItems.size(), verticalScrollBar()->value());
for (int i = 0; i < cnt; ++i)
offset += d->itemHeight(i);
return offset;
@@ -2211,14 +2217,13 @@ QModelIndex QTreeView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie
int c = 0;
while (c < d->header->count() && d->header->isSectionHidden(d->header->logicalIndex(c)))
++c;
- if (i < d->viewItems.count() && c < d->header->count()) {
+ if (i < d->viewItems.size() && c < d->header->count()) {
return d->modelIndex(i, d->header->logicalIndex(c));
}
return QModelIndex();
}
- int vi = -1;
- if (vi < 0)
- vi = qMax(0, d->viewIndex(current));
+
+ const int vi = qMax(0, d->viewIndex(current));
if (isRightToLeft()) {
if (cursorAction == MoveRight)
@@ -2243,7 +2248,7 @@ QModelIndex QTreeView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie
return d->modelIndex(d->above(vi), current.column());
case MoveLeft: {
QScrollBar *sb = horizontalScrollBar();
- if (vi < d->viewItems.count() && d->viewItems.at(vi).expanded && d->itemsExpandable && sb->value() == sb->minimum()) {
+ if (vi < d->viewItems.size() && d->viewItems.at(vi).expanded && d->itemsExpandable && sb->value() == sb->minimum()) {
d->collapse(vi, true);
d->moveCursorUpdatedView = true;
} else {
@@ -2278,7 +2283,7 @@ QModelIndex QTreeView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifie
break;
}
case MoveRight:
- if (vi < d->viewItems.count() && !d->viewItems.at(vi).expanded && d->itemsExpandable
+ if (vi < d->viewItems.size() && !d->viewItems.at(vi).expanded && d->itemsExpandable
&& d->hasVisibleChildren(d->viewItems.at(vi).index)) {
d->expand(vi, true);
d->moveCursorUpdatedView = true;
@@ -2392,7 +2397,7 @@ QRegion QTreeView::visualRegionForSelection(const QItemSelection &selection) con
}
if (!leftIndex.isValid())
continue;
- const QRect leftRect = visualRect(leftIndex);
+ const QRect leftRect = d->visualRect(leftIndex, QTreeViewPrivate::SingleSection);
int top = leftRect.top();
QModelIndex rightIndex = range.bottomRight();
while (rightIndex.isValid() && isIndexHidden(rightIndex)) {
@@ -2403,7 +2408,7 @@ QRegion QTreeView::visualRegionForSelection(const QItemSelection &selection) con
}
if (!rightIndex.isValid())
continue;
- const QRect rightRect = visualRect(rightIndex);
+ const QRect rightRect = d->visualRect(rightIndex, QTreeViewPrivate::SingleSection);
int bottom = rightRect.bottom();
if (top > bottom)
qSwap<int>(top, bottom);
@@ -2433,7 +2438,7 @@ QModelIndexList QTreeView::selectedIndexes() const
QModelIndexList modelSelected;
if (selectionModel())
modelSelected = selectionModel()->selectedIndexes();
- for (int i = 0; i < modelSelected.count(); ++i) {
+ for (int i = 0; i < modelSelected.size(); ++i) {
// check that neither the parents nor the index is hidden before we add
QModelIndex index = modelSelected.at(i);
while (index.isValid() && !isIndexHidden(index))
@@ -2470,7 +2475,7 @@ void QTreeView::scrollContentsBy(int dx, int dy)
// guestimate the number of items in the viewport
int viewCount = d->viewport->height() / itemHeight;
- int maxDeltaY = qMin(d->viewItems.count(), viewCount);
+ int maxDeltaY = qMin(d->viewItems.size(), viewCount);
// no need to do a lot of work if we are going to redraw the whole thing anyway
if (qAbs(dy) > qAbs(maxDeltaY) && d->editorIndexHash.isEmpty()) {
verticalScrollBar()->update();
@@ -2486,12 +2491,12 @@ void QTreeView::scrollContentsBy(int dx, int dy)
dy = 0;
if (previousViewIndex < currentViewIndex) { // scrolling down
for (int i = previousViewIndex; i < currentViewIndex; ++i) {
- if (i < d->viewItems.count())
+ if (i < d->viewItems.size())
dy -= d->itemHeight(i);
}
} else if (previousViewIndex > currentViewIndex) { // scrolling up
for (int i = previousViewIndex - 1; i >= currentViewIndex; --i) {
- if (i < d->viewItems.count())
+ if (i < d->viewItems.size())
dy += d->itemHeight(i);
}
}
@@ -2579,7 +2584,7 @@ void QTreeView::rowsRemoved(const QModelIndex &parent, int start, int end)
d->viewItems.clear();
d->doDelayedItemsLayout();
d->hasRemovedItems = true;
- d->_q_rowsRemoved(parent, start, end);
+ d->rowsRemoved(parent, start, end);
}
/*!
@@ -2670,7 +2675,8 @@ QSize QTreeView::viewportSizeHint() const
return QAbstractItemView::viewportSizeHint();
// Get rect for last item
- const QRect deepestRect = visualRect(d->viewItems.last().index);
+ const QRect deepestRect = d->visualRect(d->viewItems.last().index,
+ QTreeViewPrivate::SingleSection);
if (!deepestRect.isValid())
return QAbstractItemView::viewportSizeHint();
@@ -2703,6 +2709,7 @@ void QTreeView::expandAll()
d->layout(-1, true);
updateGeometries();
d->viewport->update();
+ d->updateAccessibility();
}
/*!
@@ -2794,7 +2801,7 @@ void QTreeView::expandToDepth(int depth)
d->expandedIndexes.clear();
d->interruptDelayedItemsLayout();
d->layout(-1);
- for (int i = 0; i < d->viewItems.count(); ++i) {
+ for (int i = 0; i < d->viewItems.size(); ++i) {
if (d->viewItems.at(i).level <= (uint)depth) {
d->viewItems[i].expanded = true;
d->layout(i);
@@ -2826,6 +2833,7 @@ void QTreeView::expandToDepth(int depth)
updateGeometries();
d->viewport->update();
+ d->updateAccessibility();
}
/*!
@@ -3086,10 +3094,25 @@ void QTreeViewPrivate::initialize()
q->setHeader(header);
#if QT_CONFIG(animation)
animationsEnabled = q->style()->styleHint(QStyle::SH_Widget_Animation_Duration, nullptr, q) > 0;
- QObject::connect(&animatedOperation, SIGNAL(finished()), q, SLOT(_q_endAnimatedOperation()));
+ animationConnection =
+ QObjectPrivate::connect(&animatedOperation, &QVariantAnimation::finished,
+ this, &QTreeViewPrivate::endAnimatedOperation);
#endif // animation
}
+void QTreeViewPrivate::clearConnections()
+{
+ for (const QMetaObject::Connection &connection : modelConnections)
+ QObject::disconnect(connection);
+ for (const QMetaObject::Connection &connection : headerConnections)
+ QObject::disconnect(connection);
+ QObject::disconnect(selectionmodelConnection);
+ QObject::disconnect(sortHeaderConnection);
+#if QT_CONFIG(animation)
+ QObject::disconnect(animationConnection);
+#endif
+}
+
void QTreeViewPrivate::expand(int item, bool emitSignal)
{
Q_Q(QTreeView);
@@ -3122,13 +3145,14 @@ void QTreeViewPrivate::expand(int item, bool emitSignal)
beginAnimatedOperation();
#endif // animation
}
+ updateAccessibility();
}
void QTreeViewPrivate::insertViewItems(int pos, int count, const QTreeViewItem &viewItem)
{
viewItems.insert(pos, count, viewItem);
QTreeViewItem *items = viewItems.data();
- for (int i = pos + count; i < viewItems.count(); i++)
+ for (int i = pos + count; i < viewItems.size(); i++)
if (items[i].parentItem >= pos)
items[i].parentItem += count;
}
@@ -3137,7 +3161,7 @@ void QTreeViewPrivate::removeViewItems(int pos, int count)
{
viewItems.remove(pos, count);
QTreeViewItem *items = viewItems.data();
- for (int i = pos; i < viewItems.count(); i++)
+ for (int i = pos; i < viewItems.size(); i++)
if (items[i].parentItem >= pos)
items[i].parentItem -= count;
}
@@ -3282,7 +3306,7 @@ QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) cons
for (QEditorIndexHash::const_iterator it = editorIndexHash.constBegin(); it != editorIndexHash.constEnd(); ++it) {
QWidget *editor = it.key();
const QModelIndex &index = it.value();
- option.rect = q->visualRect(index);
+ option.rect = visualRect(index, SingleSection);
if (option.rect.isValid()) {
if (QAbstractItemDelegate *delegate = q->itemDelegateForIndex(index))
@@ -3302,7 +3326,7 @@ QPixmap QTreeViewPrivate::renderTreeToPixmapForAnimation(const QRect &rect) cons
return pixmap;
}
-void QTreeViewPrivate::_q_endAnimatedOperation()
+void QTreeViewPrivate::endAnimatedOperation()
{
Q_Q(QTreeView);
q->setState(stateBeforeAnimation);
@@ -3311,25 +3335,40 @@ void QTreeViewPrivate::_q_endAnimatedOperation()
}
#endif // animation
-void QTreeViewPrivate::_q_modelAboutToBeReset()
+void QTreeViewPrivate::modelAboutToBeReset()
{
viewItems.clear();
}
-void QTreeViewPrivate::_q_columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
+void QTreeViewPrivate::columnsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
{
if (start <= 0 && 0 <= end)
viewItems.clear();
- QAbstractItemViewPrivate::_q_columnsAboutToBeRemoved(parent, start, end);
+ QAbstractItemViewPrivate::columnsAboutToBeRemoved(parent, start, end);
}
-void QTreeViewPrivate::_q_columnsRemoved(const QModelIndex &parent, int start, int end)
+void QTreeViewPrivate::columnsRemoved(const QModelIndex &parent, int start, int end)
{
if (start <= 0 && 0 <= end)
doDelayedItemsLayout();
- QAbstractItemViewPrivate::_q_columnsRemoved(parent, start, end);
+ QAbstractItemViewPrivate::columnsRemoved(parent, start, end);
+}
+
+void QTreeViewPrivate::updateAccessibility()
+{
+#if QT_CONFIG(accessibility)
+ Q_Q(QTreeView);
+ if (pendingAccessibilityUpdate) {
+ pendingAccessibilityUpdate = false;
+ if (QAccessible::isActive()) {
+ QAccessibleTableModelChangeEvent event(q, QAccessibleTableModelChangeEvent::ModelReset);
+ QAccessible::updateAccessibility(&event);
+ }
+ }
+#endif
}
+
/** \internal
creates and initialize the viewItem structure of the children of the element \li
@@ -3350,6 +3389,15 @@ void QTreeViewPrivate::layout(int i, bool recursiveExpanding, bool afterIsUninit
return;
}
+#if QT_CONFIG(accessibility)
+ // QAccessibleTree's rowCount implementation uses viewItems.size(), so
+ // we need to invalidate any cached accessibility data structures if
+ // that value changes during the run of this function.
+ const auto resetModelIfNeeded = qScopeGuard([oldViewItemsSize = viewItems.size(), this]{
+ pendingAccessibilityUpdate |= oldViewItemsSize != viewItems.size();
+ });
+#endif
+
int count = 0;
if (model->hasChildren(parent)) {
if (model->canFetchMore(parent)) {
@@ -3381,7 +3429,7 @@ void QTreeViewPrivate::layout(int i, bool recursiveExpanding, bool afterIsUninit
if (!afterIsUninitialized)
insertViewItems(i + 1, count, QTreeViewItem()); // expand
else if (count > 0)
- viewItems.resize(viewItems.count() + count);
+ viewItems.resize(viewItems.size() + count);
} else {
expanding = false;
}
@@ -3451,7 +3499,7 @@ int QTreeViewPrivate::pageUp(int i) const
index = 0;
while (isItemHiddenOrDisabled(index))
index++;
- return index >= viewItems.count() ? 0 : index;
+ return index >= viewItems.size() ? 0 : index;
}
int QTreeViewPrivate::pageDown(int i) const
@@ -3459,11 +3507,11 @@ int QTreeViewPrivate::pageDown(int i) const
int index = itemAtCoordinate(coordinateForItem(i) + viewport->height());
while (isItemHiddenOrDisabled(index))
index++;
- if (index == -1 || index >= viewItems.count())
- index = viewItems.count() - 1;
+ if (index == -1 || index >= viewItems.size())
+ index = viewItems.size() - 1;
while (isItemHiddenOrDisabled(index))
index--;
- return index == -1 ? viewItems.count() - 1 : index;
+ return index == -1 ? viewItems.size() - 1 : index;
}
int QTreeViewPrivate::itemForKeyHome() const
@@ -3471,20 +3519,20 @@ int QTreeViewPrivate::itemForKeyHome() const
int index = 0;
while (isItemHiddenOrDisabled(index))
index++;
- return index >= viewItems.count() ? 0 : index;
+ return index >= viewItems.size() ? 0 : index;
}
int QTreeViewPrivate::itemForKeyEnd() const
{
- int index = viewItems.count() - 1;
+ int index = viewItems.size() - 1;
while (isItemHiddenOrDisabled(index))
index--;
- return index == -1 ? viewItems.count() - 1 : index;
+ return index == -1 ? viewItems.size() - 1 : index;
}
int QTreeViewPrivate::indentationForItem(int item) const
{
- if (item < 0 || item >= viewItems.count())
+ if (item < 0 || item >= viewItems.size())
return 0;
int level = viewItems.at(item).level;
if (rootDecoration)
@@ -3494,7 +3542,7 @@ int QTreeViewPrivate::indentationForItem(int item) const
int QTreeViewPrivate::itemHeight(int item) const
{
- Q_ASSERT(item < viewItems.count());
+ Q_ASSERT(item < viewItems.size());
if (uniformRowHeights)
return defaultItemHeight;
if (viewItems.isEmpty())
@@ -3522,7 +3570,7 @@ int QTreeViewPrivate::coordinateForItem(int item) const
return (item * defaultItemHeight) - vbar->value();
// ### optimize (maybe do like QHeaderView by letting items have startposition)
int y = 0;
- for (int i = 0; i < viewItems.count(); ++i) {
+ for (int i = 0; i < viewItems.size(); ++i) {
if (i == item)
return y - vbar->value();
y += itemHeight(i);
@@ -3536,7 +3584,7 @@ int QTreeViewPrivate::coordinateForItem(int item) const
// ### slow if the item is not visible
int viewItemCoordinate = 0;
int viewItemIndex = topViewItemIndex;
- while (viewItemIndex < viewItems.count()) {
+ while (viewItemIndex < viewItems.size()) {
if (viewItemIndex == item)
return viewItemCoordinate;
viewItemCoordinate += itemHeight(viewItemIndex);
@@ -3568,7 +3616,7 @@ int QTreeViewPrivate::coordinateForItem(int item) const
*/
int QTreeViewPrivate::itemAtCoordinate(int coordinate) const
{
- const int itemCount = viewItems.count();
+ const int itemCount = viewItems.size();
if (itemCount == 0)
return -1;
if (uniformRowHeights && defaultItemHeight <= 0)
@@ -3581,7 +3629,7 @@ int QTreeViewPrivate::itemAtCoordinate(int coordinate) const
// ### optimize
int viewItemCoordinate = 0;
const int contentsCoordinate = coordinate + vbar->value();
- for (int viewItemIndex = 0; viewItemIndex < viewItems.count(); ++viewItemIndex) {
+ for (int viewItemIndex = 0; viewItemIndex < viewItems.size(); ++viewItemIndex) {
viewItemCoordinate += itemHeight(viewItemIndex);
if (viewItemCoordinate > contentsCoordinate)
return (viewItemIndex >= itemCount ? -1 : viewItemIndex);
@@ -3597,7 +3645,7 @@ int QTreeViewPrivate::itemAtCoordinate(int coordinate) const
if (coordinate >= 0) {
// the coordinate is in or below the viewport
int viewItemCoordinate = 0;
- for (int viewItemIndex = topViewItemIndex; viewItemIndex < viewItems.count(); ++viewItemIndex) {
+ for (int viewItemIndex = topViewItemIndex; viewItemIndex < viewItems.size(); ++viewItemIndex) {
viewItemCoordinate += itemHeight(viewItemIndex);
if (viewItemCoordinate > coordinate)
return (viewItemIndex >= itemCount ? -1 : viewItemIndex);
@@ -3620,7 +3668,7 @@ int QTreeViewPrivate::viewIndex(const QModelIndex &_index) const
if (!_index.isValid() || viewItems.isEmpty())
return -1;
- const int totalCount = viewItems.count();
+ const int totalCount = viewItems.size();
const QModelIndex index = _index.sibling(_index.row(), 0);
const int row = index.row();
const quintptr internalId = index.internalId();
@@ -3661,7 +3709,7 @@ int QTreeViewPrivate::viewIndex(const QModelIndex &_index) const
QModelIndex QTreeViewPrivate::modelIndex(int i, int column) const
{
- if (i < 0 || i >= viewItems.count())
+ if (i < 0 || i >= viewItems.size())
return QModelIndex();
QModelIndex ret = viewItems.at(i).index;
@@ -3676,7 +3724,7 @@ int QTreeViewPrivate::firstVisibleItem(int *offset) const
if (verticalScrollMode == QAbstractItemView::ScrollPerItem) {
if (offset)
*offset = 0;
- return (value < 0 || value >= viewItems.count()) ? -1 : value;
+ return (value < 0 || value >= viewItems.size()) ? -1 : value;
}
// ScrollMode == ScrollPerPixel
if (uniformRowHeights) {
@@ -3688,7 +3736,7 @@ int QTreeViewPrivate::firstVisibleItem(int *offset) const
return value / defaultItemHeight;
}
int y = 0; // ### (maybe do like QHeaderView by letting items have startposition)
- for (int i = 0; i < viewItems.count(); ++i) {
+ for (int i = 0; i < viewItems.size(); ++i) {
y += itemHeight(i); // the height value is cached
if (y > value) {
if (offset)
@@ -3709,7 +3757,7 @@ int QTreeViewPrivate::lastVisibleItem(int firstVisual, int offset) const
int y = - offset;
int value = viewport->height();
- for (int i = firstVisual; i < viewItems.count(); ++i) {
+ for (int i = firstVisual; i < viewItems.size(); ++i) {
y += itemHeight(i); // the height value is cached
if (y > value)
return i;
@@ -3737,11 +3785,11 @@ void QTreeViewPrivate::updateScrollBars()
int itemsInViewport = 0;
if (uniformRowHeights) {
if (defaultItemHeight <= 0)
- itemsInViewport = viewItems.count();
+ itemsInViewport = viewItems.size();
else
itemsInViewport = viewportSize.height() / defaultItemHeight;
} else {
- const int itemsCount = viewItems.count();
+ const int itemsCount = viewItems.size();
const int viewportHeight = viewportSize.height();
for (int height = 0, item = itemsCount - 1; item >= 0; --item) {
height += itemHeight(item);
@@ -3753,15 +3801,15 @@ void QTreeViewPrivate::updateScrollBars()
if (verticalScrollMode == QAbstractItemView::ScrollPerItem) {
if (!viewItems.isEmpty())
itemsInViewport = qMax(1, itemsInViewport);
- vbar->setRange(0, viewItems.count() - itemsInViewport);
+ vbar->setRange(0, viewItems.size() - itemsInViewport);
vbar->setPageStep(itemsInViewport);
vbar->setSingleStep(1);
} else { // scroll per pixel
int contentsHeight = 0;
if (uniformRowHeights) {
- contentsHeight = defaultItemHeight * viewItems.count();
+ contentsHeight = defaultItemHeight * viewItems.size();
} else { // ### (maybe do like QHeaderView by letting items have startposition)
- for (int i = 0; i < viewItems.count(); ++i)
+ for (int i = 0; i < viewItems.size(); ++i)
contentsHeight += itemHeight(i);
}
vbar->setRange(0, contentsHeight - viewportSize.height());
@@ -3870,7 +3918,7 @@ QList<QPair<int, int>> QTreeViewPrivate::columnRanges(const QModelIndex &topInde
QPair<int, int> current;
current.first = -2; // -1 is not enough because -1+1 = 0
current.second = -2;
- for(int i = 0; i < logicalIndexes.count(); ++i) {
+ for(int i = 0; i < logicalIndexes.size(); ++i) {
const int logicalColumn = logicalIndexes.at(i);
if (current.second + 1 != logicalColumn) {
if (current.first != -2) {
@@ -3946,7 +3994,7 @@ void QTreeViewPrivate::select(const QModelIndex &topIndex, const QModelIndex &bo
}
if (currentRange.isValid())
selection.append(currentRange);
- for (int i = 0; i < rangeStack.count(); ++i)
+ for (int i = 0; i < rangeStack.size(); ++i)
selection.append(rangeStack.at(i));
}
q->selectionModel()->select(selection, command);
@@ -3988,7 +4036,7 @@ bool QTreeViewPrivate::hasVisibleChildren(const QModelIndex& parent) const
return false;
}
-void QTreeViewPrivate::_q_sortIndicatorChanged(int column, Qt::SortOrder order)
+void QTreeViewPrivate::sortIndicatorChanged(int column, Qt::SortOrder order)
{
model->sort(column, order);
}
@@ -4012,24 +4060,17 @@ void QTreeViewPrivate::updateIndentationFromStyle()
*/
void QTreeView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
{
+ Q_D(QTreeView);
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);
- }
+ if (previous.isValid())
+ viewport()->update(d->visualRect(previous, QTreeViewPrivate::FullRow));
+ if (current.isValid())
+ viewport()->update(d->visualRect(current, QTreeViewPrivate::FullRow));
}
-#ifndef QT_NO_ACCESSIBILITY
- if (QAccessible::isActive() && current.isValid()) {
+#if QT_CONFIG(accessibility)
+ if (QAccessible::isActive() && current.isValid() && hasFocus()) {
Q_D(QTreeView);
QAccessibleEvent event(this, QAccessible::Focus);
@@ -4046,7 +4087,7 @@ void QTreeView::selectionChanged(const QItemSelection &selected,
const QItemSelection &deselected)
{
QAbstractItemView::selectionChanged(selected, deselected);
-#ifndef QT_NO_ACCESSIBILITY
+#if QT_CONFIG(accessibility)
if (QAccessible::isActive()) {
Q_D(QTreeView);
diff --git a/src/widgets/itemviews/qtreeview.h b/src/widgets/itemviews/qtreeview.h
index f424088c91..1dd4650c5d 100644
--- a/src/widgets/itemviews/qtreeview.h
+++ b/src/widgets/itemviews/qtreeview.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTREEVIEW_H
#define QTREEVIEW_H
@@ -231,11 +195,6 @@ private:
Q_DECLARE_PRIVATE(QTreeView)
Q_DISABLE_COPY(QTreeView)
-#if QT_CONFIG(animation)
- Q_PRIVATE_SLOT(d_func(), void _q_endAnimatedOperation())
-#endif // animation
- Q_PRIVATE_SLOT(d_func(), void _q_modelAboutToBeReset())
- Q_PRIVATE_SLOT(d_func(), void _q_sortIndicatorChanged(int column, Qt::SortOrder order))
};
QT_END_NAMESPACE
diff --git a/src/widgets/itemviews/qtreeview_p.h b/src/widgets/itemviews/qtreeview_p.h
index 57ec3caed0..d0afdf1223 100644
--- a/src/widgets/itemviews/qtreeview_p.h
+++ b/src/widgets/itemviews/qtreeview_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTREEVIEW_P_H
#define QTREEVIEW_P_H
@@ -59,6 +23,8 @@
#include <QtCore/qvariantanimation.h>
#endif
+#include <array>
+
QT_REQUIRE_CONFIG(treeview);
QT_BEGIN_NAMESPACE
@@ -98,6 +64,7 @@ public:
~QTreeViewPrivate() {}
void initialize();
+ void clearConnections();
int logicalIndexForTree() const;
inline bool isTreePosition(int logicalIndex) const
{
@@ -124,17 +91,17 @@ public:
void beginAnimatedOperation();
void drawAnimatedOperation(QPainter *painter) const;
QPixmap renderTreeToPixmapForAnimation(const QRect &rect) const;
- void _q_endAnimatedOperation();
+ void endAnimatedOperation();
#endif // animation
void expand(int item, bool emitSignal);
void collapse(int item, bool emitSignal);
- void _q_columnsAboutToBeRemoved(const QModelIndex &, int, int) override;
- void _q_columnsRemoved(const QModelIndex &, int, int) override;
- void _q_modelAboutToBeReset();
- void _q_sortIndicatorChanged(int column, Qt::SortOrder order);
- void _q_modelDestroyed() override;
+ void columnsAboutToBeRemoved(const QModelIndex &, int, int) override;
+ void columnsRemoved(const QModelIndex &, int, int) override;
+ void modelAboutToBeReset();
+ void sortIndicatorChanged(int column, Qt::SortOrder order);
+ void modelDestroyed() override;
QRect intersectedRect(const QRect rect, const QModelIndex &topLeft, const QModelIndex &bottomRight) const override;
void layout(int item, bool recusiveExpanding = false, bool afterIsUninitialized = false);
@@ -186,6 +153,21 @@ public:
QList<QStyleOptionViewItem::ViewItemPosition> *itemPositions, int left,
int right) const;
int widthHintForIndex(const QModelIndex &index, int hint, const QStyleOptionViewItem &option, int i) const;
+
+ enum RectRule {
+ FullRow,
+ SingleSection,
+ AddRowIndicatorToFirstSection
+ };
+
+ // Base class will get the first visual rect including row indicator
+ QRect visualRect(const QModelIndex &index) const override
+ {
+ return visualRect(index, AddRowIndicatorToFirstSection);
+ }
+
+ QRect visualRect(const QModelIndex &index, RectRule rule) const;
+
QHeaderView *header;
int indent;
@@ -232,7 +214,7 @@ public:
}
inline bool isItemHiddenOrDisabled(int i) const {
- if (i < 0 || i >= viewItems.count())
+ if (i < 0 || i >= viewItems.size())
return false;
const QModelIndex index = viewItems.at(i).index;
return isRowHidden(index) || !isIndexEnabled(index);
@@ -241,7 +223,7 @@ public:
inline int above(int item) const
{ int i = item; while (isItemHiddenOrDisabled(--item)){} return item < 0 ? i : item; }
inline int below(int item) const
- { int i = item; while (isItemHiddenOrDisabled(++item)){} return item >= viewItems.count() ? i : item; }
+ { int i = item; while (isItemHiddenOrDisabled(++item)){} return item >= viewItems.size() ? i : item; }
inline void invalidateHeightCache(int item) const
{ viewItems[item].height = 0; }
@@ -264,7 +246,7 @@ public:
int autoExpandDelay;
QBasicTimer openTimer;
- // used for drawing hilighted expand/collapse indicators
+ // used for drawing highlighted expand/collapse indicators
mutable int hoverBranch;
// used for blocking recursion when calling setViewportMargins from updateGeometries
@@ -275,6 +257,18 @@ public:
// tree position
int treePosition;
+
+ // pending accessibility update
+#if QT_CONFIG(accessibility)
+ bool pendingAccessibilityUpdate = false;
+#endif
+ void updateAccessibility();
+
+ QMetaObject::Connection animationConnection;
+ QMetaObject::Connection selectionmodelConnection;
+ std::array<QMetaObject::Connection, 2> modelConnections;
+ std::array<QMetaObject::Connection, 5> headerConnections;
+ QMetaObject::Connection sortHeaderConnection;
};
QT_END_NAMESPACE
diff --git a/src/widgets/itemviews/qtreewidget.cpp b/src/widgets/itemviews/qtreewidget.cpp
index e54bb5eea0..8e46a0efbe 100644
--- a/src/widgets/itemviews/qtreewidget.cpp
+++ b/src/widgets/itemviews/qtreewidget.cpp
@@ -1,47 +1,10 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2019 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include "qtreewidget.h"
#include <qheaderview.h>
#include <qpainter.h>
-#include <qitemdelegate.h>
#include <qstack.h>
#include <qdebug.h>
#include <private/qtreewidget_p.h>
@@ -240,7 +203,7 @@ QModelIndex QTreeModel::index(const QTreeWidgetItem *item, int column) const
int row;
int guess = item->d->rowGuess;
if (guess >= 0
- && par->children.count() > guess
+ && par->children.size() > guess
&& par->children.at(guess) == itm) {
row = guess;
} else {
@@ -417,8 +380,8 @@ QMap<int, QVariant> QTreeModel::itemData(const QModelIndex &index) const
QTreeWidgetItem *itm = item(index);
if (itm) {
int column = index.column();
- if (column < itm->values.count()) {
- for (int i = 0; i < itm->values.at(column).count(); ++i) {
+ if (column < itm->values.size()) {
+ for (int i = 0; i < itm->values.at(column).size(); ++i) {
roles.insert(itm->values.at(column).at(i).role,
itm->values.at(column).at(i).value);
}
@@ -487,9 +450,9 @@ bool QTreeModel::insertColumns(int column, int count, const QModelIndex &parent)
while (!itemstack.isEmpty()) {
QTreeWidgetItem *par = itemstack.pop();
QList<QTreeWidgetItem*> children = par ? par->children : rootItem->children;
- for (int row = 0; row < children.count(); ++row) {
+ for (int row = 0; row < children.size(); ++row) {
QTreeWidgetItem *child = children.at(row);
- if (child->children.count())
+ if (child->children.size())
itemstack.push(child);
child->values.insert(column, count, QList<QWidgetItemData>());
}
@@ -663,7 +626,7 @@ void QTreeModel::ensureSorted(int column, Qt::SortOrder order,
else if (oldRow > otherRow && newRow <= otherRow)
++sorting[j].second;
}
- for (int k = 0; k < newPersistentIndexes.count(); ++k) {
+ for (int k = 0; k < newPersistentIndexes.size(); ++k) {
QModelIndex pi = newPersistentIndexes.at(k);
if (pi.parent() != parent)
continue;
@@ -779,7 +742,7 @@ Qt::DropActions QTreeModel::supportedDropActions() const
void QTreeModel::itemChanged(QTreeWidgetItem *item)
{
- SkipSorting skipSorting(this); //this is kind of wrong, but not doing this would kill performence
+ SkipSorting skipSorting(this); //this is kind of wrong, but not doing this would kill performance
QModelIndex left = index(item, 0);
QModelIndex right = index(item, item->columnCount() - 1);
emit dataChanged(left, right);
@@ -810,7 +773,7 @@ void QTreeModel::emitDataChanged(QTreeWidgetItem *item, int column, const QList<
return;
}
- SkipSorting skipSorting(this); //This is a little bit wrong, but not doing it would kill performence
+ SkipSorting skipSorting(this); //This is a little bit wrong, but not doing it would kill performance
QModelIndex bottomRight, topLeft;
if (column == -1) {
@@ -842,7 +805,7 @@ void QTreeModel::beginRemoveItems(QTreeWidgetItem *parent, int row, int count)
if (!parent)
parent = rootItem;
// now update the iterators
- for (int i = 0; i < iterators.count(); ++i) {
+ for (int i = 0; i < iterators.size(); ++i) {
for (int j = 0; j < count; j++) {
QTreeWidgetItem *c = parent->child(row + j);
iterators[i]->d_func()->ensureValidIterator(c);
@@ -863,8 +826,8 @@ void QTreeModel::sortItems(QList<QTreeWidgetItem*> *items, int column, Qt::SortO
return;
// store the original order of indexes
- QList<QPair<QTreeWidgetItem *, int>> sorting(items->count());
- for (int i = 0; i < sorting.count(); ++i) {
+ QList<QPair<QTreeWidgetItem *, int>> sorting(items->size());
+ for (int i = 0; i < sorting.size(); ++i) {
sorting[i].first = items->at(i);
sorting[i].second = i;
}
@@ -876,7 +839,7 @@ void QTreeModel::sortItems(QList<QTreeWidgetItem*> *items, int column, Qt::SortO
QModelIndexList fromList;
QModelIndexList toList;
int colCount = columnCount();
- for (int r = 0; r < sorting.count(); ++r) {
+ for (int r = 0; r < sorting.size(); ++r) {
int oldRow = sorting.at(r).second;
if (oldRow == r)
continue;
@@ -1362,17 +1325,49 @@ bool QTreeWidgetItem::isFirstColumnSpanned() const
*/
/*!
+ \if defined(qt7)
+
+ \fn Qt::Alignment QTreeWidgetItem::textAlignment(int column) const
+
+ Returns the text alignment for the label in the given \a column.
+
+ \else
+
\fn int QTreeWidgetItem::textAlignment(int column) const
- Returns the text alignment for the label in the given \a column
- (see \l{Qt::AlignmentFlag}).
+ Returns the text alignment for the label in the given \a column.
+
+ \note This function returns an int for historical reasons. It will
+ be corrected to return Qt::Alignment in Qt 7.
+
+ \sa Qt::Alignment
+
+ \endif
*/
/*!
+ \obsolete [6.4] Use the overload that takes a Qt::Alignment argument.
+
\fn void QTreeWidgetItem::setTextAlignment(int column, int alignment)
Sets the text alignment for the label in the given \a column to
- the \a alignment specified (see \l{Qt::AlignmentFlag}).
+ the \a alignment specified.
+
+ \sa Qt::Alignment
+*/
+
+/*!
+ \since 6.4
+
+ \fn void QTreeWidgetItem::setTextAlignment(int column, Qt::Alignment alignment)
+
+ Sets the text alignment for the label in the given \a column to
+ the \a alignment specified.
+*/
+
+/*!
+ \fn void QTreeWidgetItem::setTextAlignment(int column, Qt::AlignmentFlag alignment)
+ \internal
*/
/*!
@@ -1400,7 +1395,7 @@ QTreeWidgetItem::QTreeWidgetItem(int type) : rtti(type), d(new QTreeWidgetItemPr
QTreeWidgetItem::QTreeWidgetItem(const QStringList &strings, int type)
: rtti(type), d(new QTreeWidgetItemPrivate(this))
{
- for (int i = 0; i < strings.count(); ++i)
+ for (int i = 0; i < strings.size(); ++i)
setText(i, strings.at(i));
}
@@ -1436,7 +1431,7 @@ QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *treeview, int type)
QTreeWidgetItem::QTreeWidgetItem(QTreeWidget *treeview, const QStringList &strings, int type)
: rtti(type), d(new QTreeWidgetItemPrivate(this))
{
- for (int i = 0; i < strings.count(); ++i)
+ for (int i = 0; i < strings.size(); ++i)
setText(i, strings.at(i));
// do not set this->view here otherwise insertChild() will fail
if (QTreeModel *model = treeModel(treeview)) {
@@ -1485,7 +1480,7 @@ QTreeWidgetItem::QTreeWidgetItem(QTreeWidgetItem *parent, int type)
QTreeWidgetItem::QTreeWidgetItem(QTreeWidgetItem *parent, const QStringList &strings, int type)
: rtti(type), d(new QTreeWidgetItemPrivate(this))
{
- for (int i = 0; i < strings.count(); ++i)
+ for (int i = 0; i < strings.size(); ++i)
setText(i, strings.at(i));
if (parent)
parent->addChild(this);
@@ -1548,7 +1543,7 @@ QTreeWidgetItem::~QTreeWidgetItem()
}
// at this point the persistent indexes for the children should also be invalidated
// since we invalidated the parent
- for (int i = 0; i < children.count(); ++i) {
+ for (int i = 0; i < children.size(); ++i) {
QTreeWidgetItem *child = children.at(i);
// make sure the child does not try to remove itself from our children list
child->par = nullptr;
@@ -1656,7 +1651,7 @@ void QTreeWidgetItem::setFlags(Qt::ItemFlags flags)
parents.push(this);
while (!parents.isEmpty()) {
QTreeWidgetItem *parent = parents.pop();
- for (int i = 0; i < parent->children.count(); ++i) {
+ for (int i = 0; i < parent->children.size(); ++i) {
QTreeWidgetItem *child = parent->children.at(i);
if (!child->d->disabled) { // if not explicitly disabled
parents.push(child);
@@ -1685,7 +1680,7 @@ void QTreeWidgetItemPrivate::updateHiddenStatus(QTreeWidgetItem *item, bool inse
const QModelIndex index = model->index(parent, 0);
item->view->setRowHidden(index.row(), index.parent(), inserting);
}
- for (int i = 0; i < parent->children.count(); ++i) {
+ for (int i = 0; i < parent->children.size(); ++i) {
QTreeWidgetItem *child = parent->children.at(i);
parents.push(child);
}
@@ -1711,7 +1706,7 @@ void QTreeWidgetItemPrivate::propagateDisabled(QTreeWidgetItem *item)
parent->itemChanged();
}
- for (int i = 0; i < parent->children.count(); ++i) {
+ for (int i = 0; i < parent->children.size(); ++i) {
QTreeWidgetItem *child = parent->children.at(i);
parents.push(child);
}
@@ -1753,14 +1748,14 @@ void QTreeWidgetItem::setData(int column, int role, const QVariant &value)
switch (role) {
case Qt::EditRole:
case Qt::DisplayRole: {
- if (values.count() <= column) {
+ if (values.size() <= column) {
if (model && this == model->headerItem)
model->setColumnCount(column + 1);
else
values.resize(column + 1);
}
- if (d->display.count() <= column) {
- for (int i = d->display.count() - 1; i < column - 1; ++i)
+ if (d->display.size() <= column) {
+ for (int i = d->display.size() - 1; i < column - 1; ++i)
d->display.append(QVariant());
d->display.append(value);
} else if (d->display[column] != value) {
@@ -1771,7 +1766,7 @@ void QTreeWidgetItem::setData(int column, int role, const QVariant &value)
} break;
case Qt::CheckStateRole:
if ((itemFlags & Qt::ItemIsAutoTristate) && value != Qt::PartiallyChecked) {
- for (int i = 0; i < children.count(); ++i) {
+ for (int i = 0; i < children.size(); ++i) {
QTreeWidgetItem *child = children.at(i);
if (child->data(column, role).isValid()) {// has a CheckState
Qt::ItemFlags f = itemFlags; // a little hack to avoid multiple dataChanged signals
@@ -1783,10 +1778,10 @@ void QTreeWidgetItem::setData(int column, int role, const QVariant &value)
}
Q_FALLTHROUGH();
default:
- if (column < values.count()) {
+ if (column < values.size()) {
bool found = false;
const QList<QWidgetItemData> column_values = values.at(column);
- for (int i = 0; i < column_values.count(); ++i) {
+ for (int i = 0; i < column_values.size(); ++i) {
if (column_values.at(i).role == role) {
if (column_values.at(i).value == value)
return; // value is unchanged
@@ -1827,12 +1822,12 @@ QVariant QTreeWidgetItem::data(int column, int role) const
switch (role) {
case Qt::EditRole:
case Qt::DisplayRole:
- if (column >= 0 && column < d->display.count())
+ if (column >= 0 && column < d->display.size())
return d->display.at(column);
break;
case Qt::CheckStateRole:
// special case for check state in tristate
- if (children.count() && (itemFlags & Qt::ItemIsAutoTristate))
+ if (children.size() && (itemFlags & Qt::ItemIsAutoTristate))
return childrenCheckState(column);
Q_FALLTHROUGH();
default:
@@ -1874,9 +1869,9 @@ void QTreeWidgetItem::read(QDataStream &in)
d->display.clear();
in >> values;
// move the display value over to the display string list
- for (int column = 0; column < values.count(); ++column) {
+ for (int column = 0; column < values.size(); ++column) {
d->display << QVariant();
- for (int i = 0; i < values.at(column).count(); ++i) {
+ for (int i = 0; i < values.at(column).size(); ++i) {
if (values.at(column).at(i).role == Qt::DisplayRole) {
d->display[column] = values.at(column).at(i).value;
values[column].remove(i--);
@@ -1943,8 +1938,8 @@ QTreeWidgetItem &QTreeWidgetItem::operator=(const QTreeWidgetItem &other)
void QTreeWidgetItem::addChild(QTreeWidgetItem *child)
{
if (child) {
- insertChild(children.count(), child);
- child->d->rowGuess = children.count() - 1;
+ insertChild(children.size(), child);
+ child->d->rowGuess = children.size() - 1;
}
}
@@ -1955,7 +1950,7 @@ void QTreeWidgetItem::addChild(QTreeWidgetItem *child)
*/
void QTreeWidgetItem::insertChild(int index, QTreeWidgetItem *child)
{
- if (index < 0 || index > children.count() || child == nullptr || child->view != nullptr || child->par != nullptr)
+ if (index < 0 || index > children.size() || child == nullptr || child->view != nullptr || child->par != nullptr)
return;
if (QTreeModel *model = treeModel()) {
@@ -1977,7 +1972,7 @@ void QTreeWidgetItem::insertChild(int index, QTreeWidgetItem *child)
QTreeWidgetItem *i = stack.pop();
i->view = view;
i->values.reserve(cols);
- for (int c = 0; c < i->children.count(); ++c)
+ for (int c = 0; c < i->children.size(); ++c)
stack.push(i->children.at(c));
}
children.insert(index, child);
@@ -2016,7 +2011,7 @@ QTreeWidgetItem *QTreeWidgetItem::takeChild(int index)
model->skipPendingSort = false;
model->executePendingSort();
}
- if (index >= 0 && index < children.count()) {
+ if (index >= 0 && index < children.size()) {
if (model) model->beginRemoveItems(this, index, 1);
d->updateHiddenStatus(children.at(index), false);
QTreeWidgetItem *item = children.takeAt(index);
@@ -2026,7 +2021,7 @@ QTreeWidgetItem *QTreeWidgetItem::takeChild(int index)
while (!stack.isEmpty()) {
QTreeWidgetItem *i = stack.pop();
i->view = nullptr;
- for (int c = 0; c < i->children.count(); ++c)
+ for (int c = 0; c < i->children.size(); ++c)
stack.push(i->children.at(c));
}
d->propagateDisabled(item);
@@ -2045,7 +2040,7 @@ QTreeWidgetItem *QTreeWidgetItem::takeChild(int index)
*/
void QTreeWidgetItem::addChildren(const QList<QTreeWidgetItem*> &children)
{
- insertChildren(this->children.count(), children);
+ insertChildren(this->children.size(), children);
}
/*!
@@ -2057,18 +2052,18 @@ void QTreeWidgetItem::addChildren(const QList<QTreeWidgetItem*> &children)
*/
void QTreeWidgetItem::insertChildren(int index, const QList<QTreeWidgetItem*> &children)
{
- if (index < 0 || index > this->children.count() || children.isEmpty())
+ if (index < 0 || index > this->children.size() || children.isEmpty())
return;
if (view && view->isSortingEnabled()) {
- for (int n = 0; n < children.count(); ++n)
+ for (int n = 0; n < children.size(); ++n)
insertChild(index, children.at(n));
return;
}
QTreeModel *model = treeModel();
QStack<QTreeWidgetItem*> stack;
QList<QTreeWidgetItem*> itemsToInsert;
- for (int n = 0; n < children.count(); ++n) {
+ for (int n = 0; n < children.size(); ++n) {
QTreeWidgetItem *child = children.at(n);
if (child->view || child->par)
continue;
@@ -2088,11 +2083,11 @@ void QTreeWidgetItem::insertChildren(int index, const QList<QTreeWidgetItem*> &c
while (!stack.isEmpty()) {
QTreeWidgetItem *i = stack.pop();
i->view = view;
- for (int c = 0; c < i->children.count(); ++c)
+ for (int c = 0; c < i->children.size(); ++c)
stack.push(i->children.at(c));
}
- if (model) model->beginInsertItems(this, index, itemsToInsert.count());
- for (int n = 0; n < itemsToInsert.count(); ++n) {
+ if (model) model->beginInsertItems(this, index, itemsToInsert.size());
+ for (int n = 0; n < itemsToInsert.size(); ++n) {
QTreeWidgetItem *child = itemsToInsert.at(n);
this->children.insert(index + n, child);
if (child->par)
@@ -2111,7 +2106,7 @@ void QTreeWidgetItem::insertChildren(int index, const QList<QTreeWidgetItem*> &c
QList<QTreeWidgetItem*> QTreeWidgetItem::takeChildren()
{
QList<QTreeWidgetItem*> removed;
- if (children.count() > 0) {
+ if (children.size() > 0) {
QTreeModel *model = treeModel();
if (model) {
// This will trigger a layoutChanged signal, thus we might want to optimize
@@ -2120,8 +2115,8 @@ QList<QTreeWidgetItem*> QTreeWidgetItem::takeChildren()
// is updated in case we take an item that is selected.
model->executePendingSort();
}
- if (model) model->beginRemoveItems(this, 0, children.count());
- for (int n = 0; n < children.count(); ++n) {
+ if (model) model->beginRemoveItems(this, 0, children.size());
+ for (int n = 0; n < children.size(); ++n) {
QTreeWidgetItem *item = children.at(n);
item->par = nullptr;
QStack<QTreeWidgetItem*> stack;
@@ -2129,7 +2124,7 @@ QList<QTreeWidgetItem*> QTreeWidgetItem::takeChildren()
while (!stack.isEmpty()) {
QTreeWidgetItem *i = stack.pop();
i->view = nullptr;
- for (int c = 0; c < i->children.count(); ++c)
+ for (int c = 0; c < i->children.size(); ++c)
stack.push(i->children.at(c));
}
d->propagateDisabled(item);
@@ -2305,37 +2300,43 @@ QDataStream &operator>>(QDataStream &in, QTreeWidgetItem &item)
#endif // QT_NO_DATASTREAM
-void QTreeWidgetPrivate::_q_emitItemPressed(const QModelIndex &index)
+void QTreeWidgetPrivate::clearConnections()
+{
+ for (const QMetaObject::Connection &connection : connections)
+ QObject::disconnect(connection);
+}
+
+void QTreeWidgetPrivate::emitItemPressed(const QModelIndex &index)
{
Q_Q(QTreeWidget);
emit q->itemPressed(item(index), index.column());
}
-void QTreeWidgetPrivate::_q_emitItemClicked(const QModelIndex &index)
+void QTreeWidgetPrivate::emitItemClicked(const QModelIndex &index)
{
Q_Q(QTreeWidget);
emit q->itemClicked(item(index), index.column());
}
-void QTreeWidgetPrivate::_q_emitItemDoubleClicked(const QModelIndex &index)
+void QTreeWidgetPrivate::emitItemDoubleClicked(const QModelIndex &index)
{
Q_Q(QTreeWidget);
emit q->itemDoubleClicked(item(index), index.column());
}
-void QTreeWidgetPrivate::_q_emitItemActivated(const QModelIndex &index)
+void QTreeWidgetPrivate::emitItemActivated(const QModelIndex &index)
{
Q_Q(QTreeWidget);
emit q->itemActivated(item(index), index.column());
}
-void QTreeWidgetPrivate::_q_emitItemEntered(const QModelIndex &index)
+void QTreeWidgetPrivate::emitItemEntered(const QModelIndex &index)
{
Q_Q(QTreeWidget);
emit q->itemEntered(item(index), index.column());
}
-void QTreeWidgetPrivate::_q_emitItemChanged(const QModelIndex &index)
+void QTreeWidgetPrivate::emitItemChanged(const QModelIndex &index)
{
Q_Q(QTreeWidget);
QTreeWidgetItem *indexItem = item(index);
@@ -2343,19 +2344,19 @@ void QTreeWidgetPrivate::_q_emitItemChanged(const QModelIndex &index)
emit q->itemChanged(indexItem, index.column());
}
-void QTreeWidgetPrivate::_q_emitItemExpanded(const QModelIndex &index)
+void QTreeWidgetPrivate::emitItemExpanded(const QModelIndex &index)
{
Q_Q(QTreeWidget);
emit q->itemExpanded(item(index));
}
-void QTreeWidgetPrivate::_q_emitItemCollapsed(const QModelIndex &index)
+void QTreeWidgetPrivate::emitItemCollapsed(const QModelIndex &index)
{
Q_Q(QTreeWidget);
emit q->itemCollapsed(item(index));
}
-void QTreeWidgetPrivate::_q_emitCurrentItemChanged(const QModelIndex &current,
+void QTreeWidgetPrivate::emitCurrentItemChanged(const QModelIndex &current,
const QModelIndex &previous)
{
Q_Q(QTreeWidget);
@@ -2364,7 +2365,7 @@ void QTreeWidgetPrivate::_q_emitCurrentItemChanged(const QModelIndex &current,
emit q->currentItemChanged(currentItem, previousItem);
}
-void QTreeWidgetPrivate::_q_sort()
+void QTreeWidgetPrivate::sort()
{
if (sortingEnabled) {
int column = header->sortIndicatorSection();
@@ -2373,19 +2374,19 @@ void QTreeWidgetPrivate::_q_sort()
}
}
-void QTreeWidgetPrivate::_q_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
+void QTreeWidgetPrivate::selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
{
Q_Q(QTreeWidget);
QModelIndexList indices = selected.indexes();
int i;
QTreeModel *m = treeModel();
- for (i = 0; i < indices.count(); ++i) {
+ for (i = 0; i < indices.size(); ++i) {
QTreeWidgetItem *item = m->item(indices.at(i));
item->d->selected = true;
}
indices = deselected.indexes();
- for (i = 0; i < indices.count(); ++i) {
+ for (i = 0; i < indices.size(); ++i) {
QTreeWidgetItem *item = m->item(indices.at(i));
item->d->selected = false;
}
@@ -2393,8 +2394,8 @@ void QTreeWidgetPrivate::_q_selectionChanged(const QItemSelection &selected, con
emit q->itemSelectionChanged();
}
-void QTreeWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft,
- const QModelIndex &bottomRight)
+void QTreeWidgetPrivate::dataChanged(const QModelIndex &topLeft,
+ const QModelIndex &bottomRight)
{
if (sortingEnabled && topLeft.isValid() && bottomRight.isValid()
&& !treeModel()->sortPendingTimer.isActive()) {
@@ -2452,7 +2453,7 @@ void QTreeWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft,
whether sorting is enabled.
\sa QTreeWidgetItem, QTreeWidgetItemIterator, QTreeView,
- {Model/View Programming}, {Settings Editor Example}
+ {Model/View Programming}
*/
/*!
@@ -2513,9 +2514,6 @@ void QTreeWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft,
This signal is emitted when the specified \a item is expanded so that
all of its children are displayed.
- \note This signal will not be emitted if an item changes its state when
- expandAll() is invoked.
-
\sa QTreeWidgetItem::isExpanded(), itemCollapsed(), expandItem()
*/
@@ -2577,31 +2575,34 @@ void QTreeWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft,
QTreeWidget::QTreeWidget(QWidget *parent)
: QTreeView(*new QTreeWidgetPrivate(), parent)
{
+ Q_D(QTreeWidget);
QTreeView::setModel(new QTreeModel(1, this));
- connect(this, SIGNAL(pressed(QModelIndex)),
- SLOT(_q_emitItemPressed(QModelIndex)));
- connect(this, SIGNAL(clicked(QModelIndex)),
- SLOT(_q_emitItemClicked(QModelIndex)));
- connect(this, SIGNAL(doubleClicked(QModelIndex)),
- SLOT(_q_emitItemDoubleClicked(QModelIndex)));
- connect(this, SIGNAL(activated(QModelIndex)),
- SLOT(_q_emitItemActivated(QModelIndex)));
- connect(this, SIGNAL(entered(QModelIndex)),
- SLOT(_q_emitItemEntered(QModelIndex)));
- connect(this, SIGNAL(expanded(QModelIndex)),
- SLOT(_q_emitItemExpanded(QModelIndex)));
- connect(this, SIGNAL(collapsed(QModelIndex)),
- SLOT(_q_emitItemCollapsed(QModelIndex)));
- connect(selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
- this, SLOT(_q_emitCurrentItemChanged(QModelIndex,QModelIndex)));
- connect(model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
- this, SLOT(_q_emitItemChanged(QModelIndex)));
- connect(model(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
- this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
- connect(model(), SIGNAL(columnsRemoved(QModelIndex,int,int)),
- this, SLOT(_q_sort()));
- connect(selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
- this, SLOT(_q_selectionChanged(QItemSelection,QItemSelection)));
+ d->connections = {
+ QObjectPrivate::connect(this, &QTreeWidget::pressed,
+ d, &QTreeWidgetPrivate::emitItemPressed),
+ QObjectPrivate::connect(this, &QTreeWidget::clicked,
+ d, &QTreeWidgetPrivate::emitItemClicked),
+ QObjectPrivate::connect(this, &QTreeWidget::doubleClicked,
+ d, &QTreeWidgetPrivate::emitItemDoubleClicked),
+ QObjectPrivate::connect(this, &QTreeWidget::activated,
+ d, &QTreeWidgetPrivate::emitItemActivated),
+ QObjectPrivate::connect(this, &QTreeWidget::entered,
+ d, &QTreeWidgetPrivate::emitItemEntered),
+ QObjectPrivate::connect(this, &QTreeWidget::expanded,
+ d, &QTreeWidgetPrivate::emitItemExpanded),
+ QObjectPrivate::connect(this, &QTreeWidget::collapsed,
+ d, &QTreeWidgetPrivate::emitItemCollapsed),
+ QObjectPrivate::connect(model(), &QAbstractItemModel::dataChanged,
+ d, &QTreeWidgetPrivate::emitItemChanged),
+ QObjectPrivate::connect(model(), &QAbstractItemModel::dataChanged,
+ d, &QTreeWidgetPrivate::dataChanged),
+ QObjectPrivate::connect(model(), &QAbstractItemModel::columnsRemoved,
+ d, &QTreeWidgetPrivate::sort),
+ QObjectPrivate::connect(selectionModel(), &QItemSelectionModel::currentChanged,
+ d, &QTreeWidgetPrivate::emitCurrentItemChanged),
+ QObjectPrivate::connect(selectionModel(), &QItemSelectionModel::selectionChanged,
+ d, &QTreeWidgetPrivate::selectionChanged)
+ };
header()->setSectionsClickable(false);
}
@@ -2611,10 +2612,12 @@ QTreeWidget::QTreeWidget(QWidget *parent)
QTreeWidget::~QTreeWidget()
{
+ Q_D(QTreeWidget);
+ d->clearConnections();
}
/*
- Retuns the number of header columns in the view.
+ Returns the number of header columns in the view.
\sa sortColumn(), currentColumn(), topLevelItemCount()
*/
@@ -2813,10 +2816,10 @@ void QTreeWidget::setHeaderItem(QTreeWidgetItem *item)
void QTreeWidget::setHeaderLabels(const QStringList &labels)
{
Q_D(QTreeWidget);
- if (columnCount() < labels.count())
- setColumnCount(labels.count());
+ if (columnCount() < labels.size())
+ setColumnCount(labels.size());
QTreeWidgetItem *item = d->treeModel()->headerItem;
- for (int i = 0; i < labels.count(); ++i)
+ for (int i = 0; i < labels.size(); ++i)
item->setText(i, labels.at(i));
}
@@ -3059,8 +3062,8 @@ QList<QTreeWidgetItem*> QTreeWidget::selectedItems() const
Q_D(const QTreeWidget);
const QModelIndexList indexes = selectionModel()->selectedIndexes();
QList<QTreeWidgetItem*> items;
- items.reserve(indexes.count());
- QDuplicateTracker<QTreeWidgetItem *> seen(indexes.count());
+ items.reserve(indexes.size());
+ QDuplicateTracker<QTreeWidgetItem *> seen(indexes.size());
for (const auto &index : indexes) {
QTreeWidgetItem *item = d->item(index);
if (item->isHidden() || seen.hasSeen(item))
@@ -3126,7 +3129,7 @@ void QTreeWidget::setSelectionModel(QItemSelectionModel *selectionModel)
QTreeView::setSelectionModel(selectionModel);
QItemSelection newSelection = selectionModel->selection();
if (!newSelection.isEmpty())
- d->_q_selectionChanged(newSelection, QItemSelection());
+ d->selectionChanged(newSelection, QItemSelection());
}
/*!
@@ -3213,7 +3216,7 @@ QMimeData *QTreeWidget::mimeData(const QList<QTreeWidgetItem *> &items) const
return nullptr;
}
- for (int c = 0; c < item->values.count(); ++c) {
+ for (int c = 0; c < item->values.size(); ++c) {
const QModelIndex index = indexFromItem(item, c);
if (Q_UNLIKELY(!index.isValid())) {
qWarning() << "QTreeWidget::mimeData: No index associated with item :" << item;
@@ -3292,7 +3295,7 @@ void QTreeWidget::dropEvent(QDropEvent *event) {
if (!event->isAccepted() && d->dropOn(event, &row, &col, &topIndex)) {
const QList<QModelIndex> idxs = selectedIndexes();
QList<QPersistentModelIndex> indexes;
- const int indexesCount = idxs.count();
+ const int indexesCount = idxs.size();
indexes.reserve(indexesCount);
for (const auto &idx : idxs)
indexes.append(idx);
@@ -3315,7 +3318,7 @@ void QTreeWidget::dropEvent(QDropEvent *event) {
}
// insert them back in at their new positions
- for (int i = 0; i < indexes.count(); ++i) {
+ for (int i = 0; i < indexes.size(); ++i) {
// Either at a specific point or appended
if (row == -1) {
if (topIndex.isValid()) {
diff --git a/src/widgets/itemviews/qtreewidget.h b/src/widgets/itemviews/qtreewidget.h
index 21f6883cae..992f6cdb1c 100644
--- a/src/widgets/itemviews/qtreewidget.h
+++ b/src/widgets/itemviews/qtreewidget.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTREEWIDGET_H
#define QTREEWIDGET_H
@@ -129,10 +93,22 @@ public:
{ return qvariant_cast<QFont>(data(column, Qt::FontRole)); }
inline void setFont(int column, const QFont &font);
+#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
inline int textAlignment(int column) const
{ return data(column, Qt::TextAlignmentRole).toInt(); }
+#else
+ inline Qt::Alignment textAlignment(int column) const
+ { return qvariant_cast<Qt::Alignment>(data(column, Qt::TextAlignmentRole)); }
+#endif
+#if QT_DEPRECATED_SINCE(6, 4)
+ QT_DEPRECATED_VERSION_X_6_4("Use the overload taking Qt::Alignment")
inline void setTextAlignment(int column, int alignment)
{ setData(column, Qt::TextAlignmentRole, alignment); }
+ inline void setTextAlignment(int column, Qt::AlignmentFlag alignment)
+ { setData(column, Qt::TextAlignmentRole, QVariant::fromValue(Qt::Alignment(alignment))); }
+#endif
+ inline void setTextAlignment(int column, Qt::Alignment alignment)
+ { setData(column, Qt::TextAlignmentRole, QVariant::fromValue(alignment)); }
inline QBrush background(int column) const
{ return qvariant_cast<QBrush>(data(column, Qt::BackgroundRole)); }
@@ -145,7 +121,7 @@ public:
{ setData(column, Qt::ForegroundRole, brush.style() != Qt::NoBrush ? QVariant(brush) : QVariant()); }
inline Qt::CheckState checkState(int column) const
- { return static_cast<Qt::CheckState>(data(column, Qt::CheckStateRole).toInt()); }
+ { return qvariant_cast<Qt::CheckState>(data(column, Qt::CheckStateRole)); }
inline void setCheckState(int column, Qt::CheckState state)
{ setData(column, Qt::CheckStateRole, state); }
@@ -172,8 +148,8 @@ public:
executePendingSort();
return children.at(index);
}
- inline int childCount() const { return children.count(); }
- inline int columnCount() const { return values.count(); }
+ inline int childCount() const { return int(children.size()); }
+ inline int columnCount() const { return int(values.size()); }
inline int indexOfChild(QTreeWidgetItem *child) const;
void addChild(QTreeWidgetItem *child);
@@ -237,7 +213,7 @@ inline void QTreeWidgetItem::setFont(int column, const QFont &afont)
{ setData(column, Qt::FontRole, afont); }
inline int QTreeWidgetItem::indexOfChild(QTreeWidgetItem *achild) const
-{ executePendingSort(); return children.indexOf(achild); }
+{ executePendingSort(); return int(children.indexOf(achild)); }
#ifndef QT_NO_DATASTREAM
Q_WIDGETS_EXPORT QDataStream &operator<<(QDataStream &out, const QTreeWidgetItem &item);
@@ -347,19 +323,6 @@ private:
Q_DECLARE_PRIVATE(QTreeWidget)
Q_DISABLE_COPY(QTreeWidget)
-
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemPressed(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemClicked(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemDoubleClicked(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemActivated(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemEntered(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemChanged(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemExpanded(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitItemCollapsed(const QModelIndex &index))
- Q_PRIVATE_SLOT(d_func(), void _q_emitCurrentItemChanged(const QModelIndex &previous, const QModelIndex &current))
- Q_PRIVATE_SLOT(d_func(), void _q_sort())
- Q_PRIVATE_SLOT(d_func(), void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight))
- Q_PRIVATE_SLOT(d_func(), void _q_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected))
};
inline void QTreeWidget::removeItemWidget(QTreeWidgetItem *item, int column)
diff --git a/src/widgets/itemviews/qtreewidget_p.h b/src/widgets/itemviews/qtreewidget_p.h
index 65d52bf2bc..53fdea3ca8 100644
--- a/src/widgets/itemviews/qtreewidget_p.h
+++ b/src/widgets/itemviews/qtreewidget_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTREEWIDGET_P_H
#define QTREEWIDGET_P_H
@@ -59,6 +23,8 @@
#include <private/qtreeview_p.h>
#include <QtWidgets/qheaderview.h>
+#include <array>
+
QT_REQUIRE_CONFIG(treewidget);
QT_BEGIN_NAMESPACE
@@ -222,26 +188,29 @@ class QTreeWidgetPrivate : public QTreeViewPrivate
Q_DECLARE_PUBLIC(QTreeWidget)
public:
QTreeWidgetPrivate() : QTreeViewPrivate(), explicitSortColumn(-1) {}
+ void clearConnections();
inline QTreeModel *treeModel() const { return qobject_cast<QTreeModel*>(model); }
inline QModelIndex index(const QTreeWidgetItem *item, int column = 0) const
{ return treeModel()->index(item, column); }
inline QTreeWidgetItem *item(const QModelIndex &index) const
{ return treeModel()->item(index); }
- void _q_emitItemPressed(const QModelIndex &index);
- void _q_emitItemClicked(const QModelIndex &index);
- void _q_emitItemDoubleClicked(const QModelIndex &index);
- void _q_emitItemActivated(const QModelIndex &index);
- void _q_emitItemEntered(const QModelIndex &index);
- void _q_emitItemChanged(const QModelIndex &index);
- void _q_emitItemExpanded(const QModelIndex &index);
- void _q_emitItemCollapsed(const QModelIndex &index);
- void _q_emitCurrentItemChanged(const QModelIndex &previous, const QModelIndex &index);
- void _q_sort();
- void _q_dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
- void _q_selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
+ void emitItemPressed(const QModelIndex &index);
+ void emitItemClicked(const QModelIndex &index);
+ void emitItemDoubleClicked(const QModelIndex &index);
+ void emitItemActivated(const QModelIndex &index);
+ void emitItemEntered(const QModelIndex &index);
+ void emitItemChanged(const QModelIndex &index);
+ void emitItemExpanded(const QModelIndex &index);
+ void emitItemCollapsed(const QModelIndex &index);
+ void emitCurrentItemChanged(const QModelIndex &previous, const QModelIndex &index);
+ void sort();
+ void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
// used by QTreeWidgetItem::sortChildren to make sure the column argument is used
int explicitSortColumn;
+
+ std::array<QMetaObject::Connection, 12> connections;
};
QT_END_NAMESPACE
diff --git a/src/widgets/itemviews/qtreewidgetitemiterator.cpp b/src/widgets/itemviews/qtreewidgetitemiterator.cpp
index a24106d90e..1dd677e209 100644
--- a/src/widgets/itemviews/qtreewidgetitemiterator.cpp
+++ b/src/widgets/itemviews/qtreewidgetitemiterator.cpp
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#include <private/qtreewidgetitemiterator_p.h>
#include "qtreewidget.h"
@@ -168,7 +132,7 @@ QTreeWidgetItemIterator &QTreeWidgetItemIterator::operator=(const QTreeWidgetIte
}
/*!
- The prefix ++ operator (++it) advances the iterator to the next matching item
+ The prefix \c{++} operator (\c{++it}) advances the iterator to the next matching item
and returns a reference to the resulting iterator.
Sets the current pointer to \nullptr if the current item is the last matching item.
*/
@@ -183,7 +147,7 @@ QTreeWidgetItemIterator &QTreeWidgetItemIterator::operator++()
}
/*!
- The prefix -- operator (--it) advances the iterator to the previous matching item
+ The prefix \c{--} operator (\c{--it}) advances the iterator to the previous matching item
and returns a reference to the resulting iterator.
Sets the current pointer to \nullptr if the current item is the first matching item.
*/
diff --git a/src/widgets/itemviews/qtreewidgetitemiterator.h b/src/widgets/itemviews/qtreewidgetitemiterator.h
index 39e0244776..5518b431fc 100644
--- a/src/widgets/itemviews/qtreewidgetitemiterator.h
+++ b/src/widgets/itemviews/qtreewidgetitemiterator.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTREEWIDGETITEMITERATOR_H
#define QTREEWIDGETITEMITERATOR_H
diff --git a/src/widgets/itemviews/qtreewidgetitemiterator_p.h b/src/widgets/itemviews/qtreewidgetitemiterator_p.h
index e68f6103d3..c7a04a2f9b 100644
--- a/src/widgets/itemviews/qtreewidgetitemiterator_p.h
+++ b/src/widgets/itemviews/qtreewidgetitemiterator_p.h
@@ -1,41 +1,5 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QTREEWIDGETITEMITERATOR_P_H
#define QTREEWIDGETITEMITERATOR_P_H
@@ -54,6 +18,7 @@
#include <QtCore/qstack.h>
#include "qtreewidgetitemiterator.h"
+#include "private/qglobal_p.h"
#if QT_CONFIG(treewidget)
QT_BEGIN_NAMESPACE
diff --git a/src/widgets/itemviews/qwidgetitemdata_p.h b/src/widgets/itemviews/qwidgetitemdata_p.h
index fc0ca75d18..f8c2d47085 100644
--- a/src/widgets/itemviews/qwidgetitemdata_p.h
+++ b/src/widgets/itemviews/qwidgetitemdata_p.h
@@ -1,47 +1,12 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtWidgets module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2016 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QWIDGETITEMDATA_P_H
#define QWIDGETITEMDATA_P_H
#include <QtWidgets/private/qtwidgetsglobal_p.h>
#include <QtCore/qdatastream.h>
+#include <QtCore/qvariant.h>
//
// W A R N I N G