diff options
Diffstat (limited to 'src/widgets/itemviews/qlistwidget.cpp')
-rw-r--r-- | src/widgets/itemviews/qlistwidget.cpp | 638 |
1 files changed, 277 insertions, 361 deletions
diff --git a/src/widgets/itemviews/qlistwidget.cpp b/src/widgets/itemviews/qlistwidget.cpp index b9c0e0a4b7..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,10 +35,10 @@ 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 = 0; + items.at(i)->view = nullptr; delete items.at(i); } } @@ -96,7 +59,7 @@ void QListModel::remove(QListWidgetItem *item) Q_ASSERT(row != -1); beginRemoveRows(QModelIndex(), row, row); items.at(row)->d->theid = -1; - items.at(row)->view = 0; + items.at(row)->view = nullptr; items.removeAt(row); endRemoveRows(); } @@ -112,12 +75,12 @@ void QListModel::insert(int row, QListWidgetItem *item) QList<QListWidgetItem*>::iterator it; it = sortedInsertionIterator(items.begin(), items.end(), item->view->sortOrder(), item); - row = qMax(it - items.begin(), 0); + row = qMax<qsizetype>(it - items.begin(), 0); } 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,12 +118,12 @@ void QListModel::insert(int row, const QStringList &labels) QListWidgetItem *QListModel::take(int row) { - if (row < 0 || row >= items.count()) - return 0; + if (row < 0 || row >= items.size()) + return nullptr; beginRemoveRows(QModelIndex(), row, row); items.at(row)->d->theid = -1; - items.at(row)->view = 0; + items.at(row)->view = nullptr; QListWidgetItem *item = items.takeAt(row); endRemoveRows(); return item; @@ -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,26 +177,40 @@ 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; } +bool QListModel::clearItemData(const QModelIndex &index) +{ + if (!checkIndex(index, CheckIndexOption::IndexIsValid)) + return false; + QListWidgetItem *item = items.at(index.row()); + const auto beginIter = item->d->values.cbegin(); + const auto endIter = item->d->values.cend(); + if (std::all_of(beginIter, endIter, [](const QWidgetItemData& data) -> bool { return !data.value.isValid(); })) + return true; //it's already cleared + item->d->values.clear(); + emit dataChanged(index, index, QList<int> {}); + return true; +} + 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); } @@ -247,7 +224,7 @@ bool QListModel::insertRows(int row, int count, const QModelIndex &parent) beginInsertRows(QModelIndex(), row, row + count - 1); QListWidget *view = qobject_cast<QListWidget*>(QObject::parent()); - QListWidgetItem *itm = 0; + QListWidgetItem *itm = nullptr; for (int r = row; r < row + count; ++r) { itm = new QListWidgetItem; @@ -266,10 +243,10 @@ bool QListModel::removeRows(int row, int count, const QModelIndex &parent) return false; beginRemoveRows(QModelIndex(), row, row + count - 1); - QListWidgetItem *itm = 0; + QListWidgetItem *itm = nullptr; for (int r = row; r < row + count; ++r) { itm = items.takeAt(row); - itm->view = 0; + itm->view = nullptr; itm->d->theid = -1; delete itm; } @@ -277,9 +254,40 @@ bool QListModel::removeRows(int row, int count, const QModelIndex &parent) return true; } +/*! + \since 5.13 + \reimp +*/ +bool QListModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) +{ + if (sourceRow < 0 + || sourceRow + count - 1 >= rowCount(sourceParent) + || destinationChild < 0 + || destinationChild > rowCount(destinationParent) + || sourceRow == destinationChild + || sourceRow == destinationChild - 1 + || count <= 0 + || sourceParent.isValid() + || destinationParent.isValid()) { + return false; + } + if (!beginMoveRows(QModelIndex(), sourceRow, sourceRow + count - 1, QModelIndex(), destinationChild)) + return false; + + int fromRow = sourceRow; + if (destinationChild < sourceRow) + fromRow += count - 1; + else + destinationChild--; + while (count--) + items.move(fromRow, destinationChild); + endMoveRows(); + return true; +} + 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(); } @@ -289,20 +297,20 @@ void QListModel::sort(int column, Qt::SortOrder order) if (column != 0) return; - emit layoutAboutToBeChanged(); + emit layoutAboutToBeChanged({}, QAbstractItemModel::VerticalSortHint); - QVector < 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) { @@ -313,78 +321,40 @@ void QListModel::sort(int column, Qt::SortOrder order) } changePersistentIndexList(fromIndexes, toIndexes); - emit layoutChanged(); + emit layoutChanged({}, QAbstractItemModel::VerticalSortHint); } /** * 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; - int count = end - start + 1; - QVector < 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(lit - tmp.begin(), 0); - lit = tmp.insert(lit, item); - if (newRow != oldRow) { - 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) { - emit layoutAboutToBeChanged(); - items = tmp; - changePersistentIndexList(oldPersistentIndexes, newPersistentIndexes); - emit layoutChanged(); - } + /** 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, @@ -409,7 +379,7 @@ QList<QListWidgetItem*>::iterator QListModel::sortedInsertionIterator( return std::lower_bound(begin, end, item, QListModelGreaterThan()); } -void QListModel::itemChanged(QListWidgetItem *item, const QVector<int> &roles) +void QListModel::itemChanged(QListWidgetItem *item, const QList<int> &roles) { const QModelIndex idx = index(item); emit dataChanged(idx, idx, roles); @@ -418,7 +388,9 @@ void QListModel::itemChanged(QListWidgetItem *item, const QVector<int> &roles) QStringList QListModel::mimeTypes() const { const QListWidget *view = qobject_cast<const QListWidget*>(QObject::parent()); - return view->mimeTypes(); + if (view) + return view->mimeTypes(); + return {}; } QMimeData *QListModel::internalMimeData() const @@ -429,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()); @@ -450,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); } @@ -543,24 +515,6 @@ Qt::DropActions QListModel::supportedDropActions() const */ /*! - \fn void QListWidgetItem::setSelected(bool select) - \since 4.2 - - Sets the selected state of the item to \a select. - - \sa isSelected() -*/ - -/*! - \fn bool QListWidgetItem::isSelected() const - \since 4.2 - - Returns \c true if the item is selected; otherwise returns \c false. - - \sa setSelected() -*/ - -/*! \fn void QListWidgetItem::setHidden(bool hide) \since 4.2 @@ -594,14 +548,14 @@ Qt::DropActions QListModel::supportedDropActions() const \sa type() */ -QListWidgetItem::QListWidgetItem(QListWidget *view, int type) - : rtti(type), view(view), d(new QListWidgetItemPrivate(this)), +QListWidgetItem::QListWidgetItem(QListWidget *listview, int type) + : rtti(type), view(listview), d(new QListWidgetItemPrivate(this)), itemFlags(Qt::ItemIsSelectable |Qt::ItemIsUserCheckable |Qt::ItemIsEnabled |Qt::ItemIsDragEnabled) { - if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : 0)) + if (QListModel *model = listModel()) model->insert(model->rowCount(), this); } @@ -621,16 +575,20 @@ QListWidgetItem::QListWidgetItem(QListWidget *view, int type) \sa type() */ -QListWidgetItem::QListWidgetItem(const QString &text, QListWidget *view, int type) - : rtti(type), view(0), d(new QListWidgetItemPrivate(this)), +QListWidgetItem::QListWidgetItem(const QString &text, QListWidget *listview, int type) + : rtti(type), view(listview), d(new QListWidgetItemPrivate(this)), itemFlags(Qt::ItemIsSelectable |Qt::ItemIsUserCheckable |Qt::ItemIsEnabled |Qt::ItemIsDragEnabled) { - setData(Qt::DisplayRole, text); - this->view = view; - if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : 0)) + QListModel *model = listModel(); + { + QSignalBlocker b(view); + QSignalBlocker bm(model); + setData(Qt::DisplayRole, text); + } + if (model) model->insert(model->rowCount(), this); } @@ -652,17 +610,21 @@ QListWidgetItem::QListWidgetItem(const QString &text, QListWidget *view, int typ \sa type() */ QListWidgetItem::QListWidgetItem(const QIcon &icon,const QString &text, - QListWidget *view, int type) - : rtti(type), view(0), d(new QListWidgetItemPrivate(this)), + QListWidget *listview, int type) + : rtti(type), view(listview), d(new QListWidgetItemPrivate(this)), itemFlags(Qt::ItemIsSelectable |Qt::ItemIsUserCheckable |Qt::ItemIsEnabled |Qt::ItemIsDragEnabled) { - setData(Qt::DisplayRole, text); - setData(Qt::DecorationRole, icon); - this->view = view; - if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : 0)) + QListModel *model = listModel(); + { + QSignalBlocker b(view); + QSignalBlocker bm(model); + setData(Qt::DisplayRole, text); + setData(Qt::DecorationRole, icon); + } + if (model) model->insert(model->rowCount(), this); } @@ -671,7 +633,7 @@ QListWidgetItem::QListWidgetItem(const QIcon &icon,const QString &text, */ QListWidgetItem::~QListWidgetItem() { - if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : 0)) + if (QListModel *model = listModel()) model->remove(this); delete d; } @@ -697,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; @@ -708,10 +670,10 @@ void QListWidgetItem::setData(int role, const QVariant &value) } if (!found) d->values.append(QWidgetItemData(role, value)); - if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : nullptr)) { - const QVector<int> roles((role == Qt::DisplayRole) ? - QVector<int>({Qt::DisplayRole, Qt::EditRole}) : - QVector<int>({role})); + if (QListModel *model = listModel()) { + const QList<int> roles((role == Qt::DisplayRole) + ? QList<int>({ Qt::DisplayRole, Qt::EditRole }) + : QList<int>({ role })); model->itemChanged(this, roles); } } @@ -725,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(); @@ -775,7 +737,7 @@ void QListWidgetItem::write(QDataStream &out) const \sa data(), flags() */ QListWidgetItem::QListWidgetItem(const QListWidgetItem &other) - : rtti(Type), view(0), + : rtti(Type), view(nullptr), d(new QListWidgetItemPrivate(this)), itemFlags(other.itemFlags) { @@ -797,6 +759,15 @@ QListWidgetItem &QListWidgetItem::operator=(const QListWidgetItem &other) return *this; } +/*! + \internal + returns the QListModel if a view is set + */ +QListModel *QListWidgetItem::listModel() const +{ + return (view ? qobject_cast<QListModel*>(view->model()) : nullptr); +} + #ifndef QT_NO_DATASTREAM /*! @@ -884,18 +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. -/*! - \fn QColor QListWidgetItem::backgroundColor() const - \obsolete + \sa Qt::Alignment - This function is deprecated. Use background() instead. + \endif */ /*! @@ -908,15 +885,6 @@ QDataStream &operator>>(QDataStream &in, QListWidgetItem &item) */ /*! - \fn QColor QListWidgetItem::textColor() const - \obsolete - - Returns the color used to display the list item's text. - - This function is deprecated. Use foreground() instead. -*/ - -/*! \fn QBrush QListWidgetItem::foreground() const \since 4.2 @@ -944,9 +912,54 @@ QDataStream &operator>>(QDataStream &in, QListWidgetItem &item) \fn void QListWidgetItem::setSizeHint(const QSize &size) \since 4.1 - Sets the size hint for the list item to be \a size. If no size hint is set, - the item delegate will compute the size hint based on the item data. + Sets the size hint for the list item to be \a size. + If no size hint is set or \a size is invalid, the item + delegate will compute the size hint based on the item data. +*/ + +/*! + \fn void QListWidgetItem::setSelected(bool select) + \since 4.2 + + Sets the selected state of the item to \a select. + + \sa isSelected() +*/ +void QListWidgetItem::setSelected(bool select) +{ + const QListModel *model = listModel(); + if (!model || !view->selectionModel()) + return; + const QAbstractItemView::SelectionMode selectionMode = view->selectionMode(); + if (selectionMode == QAbstractItemView::NoSelection) + return; + const QModelIndex index = model->index(this); + if (selectionMode == QAbstractItemView::SingleSelection) + view->selectionModel()->select(index, select + ? QItemSelectionModel::ClearAndSelect + : QItemSelectionModel::Deselect); + else + view->selectionModel()->select(index, select + ? QItemSelectionModel::Select + : QItemSelectionModel::Deselect); +} + +/*! + \fn bool QListWidgetItem::isSelected() const + \since 4.2 + + Returns \c true if the item is selected; otherwise returns \c false. + + \sa setSelected() */ +bool QListWidgetItem::isSelected() const +{ + const QListModel *model = listModel(); + if (!model || !view->selectionModel()) + return false; + const QModelIndex index = model->index(this); + return view->selectionModel()->isSelected(index); +} /*! \fn void QListWidgetItem::setFlags(Qt::ItemFlags flags) @@ -958,7 +971,7 @@ QDataStream &operator>>(QDataStream &in, QListWidgetItem &item) void QListWidgetItem::setFlags(Qt::ItemFlags aflags) { itemFlags = aflags; - if (QListModel *model = (view ? qobject_cast<QListModel*>(view->model()) : 0)) + if (QListModel *model = listModel()) model->itemChanged(this); } @@ -1013,18 +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 */ /*! - \fn void QListWidgetItem::setBackgroundColor(const QColor &color) - \obsolete + \since 6.4 - This function is deprecated. Use setBackground() instead. + \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 */ /*! @@ -1032,22 +1053,19 @@ void QListWidgetItem::setFlags(Qt::ItemFlags aflags) \since 4.2 Sets the background brush of the list item to the given \a brush. + Setting a default-constructed brush will let the view use the + default color from the style. \sa background(), setForeground() */ /*! - \fn void QListWidgetItem::setTextColor(const QColor &color) - \obsolete - - This function is deprecated. Use setForeground() instead. -*/ - -/*! \fn void QListWidgetItem::setForeground(const QBrush &brush) \since 4.2 Sets the foreground brush of the list item to the given \a brush. + Setting a default-constructed brush will let the view use the + default color from the style. \sa foreground(), setBackground() */ @@ -1065,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 ¤t, +void QListWidgetPrivate::emitCurrentItemChanged(const QModelIndex ¤t, const QModelIndex &previous) { Q_Q(QListWidget); @@ -1126,21 +1158,21 @@ void QListWidgetPrivate::_q_emitCurrentItemChanged(const QModelIndex ¤t, //persistentCurrent is invalid if something changed the model in response //to the currentItemChanged signal emission and the item was removed if (!persistentCurrent.isValid()) { - currentItem = 0; + currentItem = nullptr; } emit q->currentTextChanged(currentItem ? currentItem->text() : QString()); 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, @@ -1346,6 +1378,8 @@ QListWidget::QListWidget(QWidget *parent) QListWidget::~QListWidget() { + Q_D(QListWidget); + d->clearConnections(); } /*! @@ -1356,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) + }; } } @@ -1384,7 +1416,7 @@ QListWidgetItem *QListWidget::item(int row) const { Q_D(const QListWidget); if (row < 0 || row >= d->model->rowCount()) - return 0; + return nullptr; return d->listModel()->at(row); } @@ -1454,7 +1486,7 @@ QListWidgetItem *QListWidget::takeItem(int row) { Q_D(QListWidget); if (row < 0 || row >= d->model->rowCount()) - return 0; + return nullptr; return d->listModel()->take(row); } @@ -1678,7 +1710,7 @@ QWidget *QListWidget::itemWidget(QListWidgetItem *item) const This function should only be used to display static content in the place of a list widget item. If you want to display custom dynamic content or - implement a custom editor widget, use QListView and subclass QItemDelegate + implement a custom editor widget, use QListView and subclass QStyledItemDelegate instead. \sa itemWidget(), removeItemWidget(), {Delegate Classes} @@ -1691,45 +1723,6 @@ void QListWidget::setItemWidget(QListWidgetItem *item, QWidget *widget) } /*! - Returns \c true if \a item is selected; otherwise returns \c false. - - \obsolete - - This function is deprecated. Use QListWidgetItem::isSelected() instead. -*/ -bool QListWidget::isItemSelected(const QListWidgetItem *item) const -{ - Q_D(const QListWidget); - QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item)); - return selectionModel()->isSelected(index); -} - -/*! - Selects or deselects the given \a item depending on whether \a select is - true of false. - - \obsolete - - This function is deprecated. Use QListWidgetItem::setSelected() instead. -*/ -void QListWidget::setItemSelected(const QListWidgetItem *item, bool select) -{ - Q_D(QListWidget); - QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item)); - - if (d->selectionMode == SingleSelection) { - selectionModel()->select(index, select - ? QItemSelectionModel::ClearAndSelect - : QItemSelectionModel::Deselect); - } else if (d->selectionMode != NoSelection) { - selectionModel()->select(index, select - ? QItemSelectionModel::Select - : QItemSelectionModel::Deselect); - } - -} - -/*! Returns a list of all selected items in the list widget. */ @@ -1738,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())); @@ -1764,30 +1757,6 @@ QList<QListWidgetItem*> QListWidget::findItems(const QString &text, Qt::MatchFla } /*! - Returns \c true if the \a item is explicitly hidden; otherwise returns \c false. - - \obsolete - - This function is deprecated. Use QListWidgetItem::isHidden() instead. -*/ -bool QListWidget::isItemHidden(const QListWidgetItem *item) const -{ - return isRowHidden(row(item)); -} - -/*! - If \a hide is true, the \a item will be hidden; otherwise it will be shown. - - \obsolete - - This function is deprecated. Use QListWidgetItem::setHidden() instead. -*/ -void QListWidget::setItemHidden(const QListWidgetItem *item, bool hide) -{ - setRowHidden(row(item), hide); -} - -/*! Scrolls the view if necessary to ensure that the \a item is visible. \a hint specifies where the \a item should be located after the operation. @@ -1828,14 +1797,10 @@ QStringList QListWidget::mimeTypes() const \a items. The format used to describe the items is obtained from the mimeTypes() function. - If the list of items is empty, 0 is returned instead of a serialized empty - list. + If the list of items is empty, \nullptr is returned instead of a + serialized empty list. */ -#if QT_VERSION >= QT_VERSION_CHECK(6,0,0) QMimeData *QListWidget::mimeData(const QList<QListWidgetItem *> &items) const -#else -QMimeData *QListWidget::mimeData(const QList<QListWidgetItem*> items) const -#endif { Q_D(const QListWidget); @@ -1843,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); @@ -1879,45 +1844,8 @@ bool QListWidget::dropMimeData(int index, const QMimeData *data, Qt::DropAction } /*! \reimp */ -void QListWidget::dropEvent(QDropEvent *event) { - Q_D(QListWidget); - if (event->source() == this && d->movement != Static) { - QListView::dropEvent(event); - return; - } - - if (event->source() == this && (event->dropAction() == Qt::MoveAction || - dragDropMode() == QAbstractItemView::InternalMove)) { - QModelIndex topIndex; - int col = -1; - int row = -1; - if (d->dropOn(event, &row, &col, &topIndex)) { - QList<QModelIndex> selIndexes = selectedIndexes(); - QList<QPersistentModelIndex> persIndexes; - const int selIndexesCount = selIndexes.count(); - persIndexes.reserve(selIndexesCount); - for (int i = 0; i < selIndexesCount; i++) - persIndexes.append(selIndexes.at(i)); - - if (persIndexes.contains(topIndex)) - return; - std::sort(persIndexes.begin(), persIndexes.end()); // The dropped items will remain in the same visual order. - - QPersistentModelIndex dropRow = model()->index(row, col, topIndex); - - int r = row == -1 ? count() : (dropRow.row() >= 0 ? dropRow.row() : row); - for (int i = 0; i < persIndexes.count(); ++i) { - const QPersistentModelIndex &pIndex = persIndexes.at(i); - d->listModel()->move(pIndex.row(), r); - r = pIndex.row() + 1; // Dropped items are inserted contiguously and in the right order. - } - - event->accept(); - // Don't want QAbstractItemView to delete it because it was "moved" we already did it - event->setDropAction(Qt::CopyAction); - } - } - +void QListWidget::dropEvent(QDropEvent *event) +{ QListView::dropEvent(event); } @@ -1958,18 +1886,6 @@ QModelIndex QListWidget::indexFromItem(const QListWidgetItem *item) const return d->listModel()->index(item); } -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -/*! - \internal - \obsolete - \overload -*/ -QModelIndex QListWidget::indexFromItem(QListWidgetItem *item) const -{ - return indexFromItem(const_cast<const QListWidgetItem *>(item)); -} -#endif - /*! Returns a pointer to the QListWidgetItem associated with the given \a index. */ @@ -1979,7 +1895,7 @@ QListWidgetItem *QListWidget::itemFromIndex(const QModelIndex &index) const Q_D(const QListWidget); if (d->isIndexValid(index)) return d->listModel()->at(index.row()); - return 0; + return nullptr; } /*! |