/****************************************************************************
**
** 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$
**
****************************************************************************/

#include "qlistwidget.h"

#include <qitemdelegate.h>
#include <private/qlistview_p.h>
#include <private/qwidgetitemdata_p.h>
#include <private/qlistwidget_p.h>

#include <algorithm>

QT_BEGIN_NAMESPACE

class QListWidgetMimeData : public QMimeData
{
    Q_OBJECT
public:
    QList<QListWidgetItem*> items;
};

QT_BEGIN_INCLUDE_NAMESPACE
#include "qlistwidget.moc"
QT_END_INCLUDE_NAMESPACE

QListModel::QListModel(QListWidget *parent)
    : QAbstractListModel(parent)
{
}

QListModel::~QListModel()
{
    clear();
}

void QListModel::clear()
{
    beginResetModel();
    for (int i = 0; i < items.count(); ++i) {
        if (items.at(i)) {
            items.at(i)->d->theid = -1;
            items.at(i)->view = nullptr;
            delete items.at(i);
        }
    }
    items.clear();
    endResetModel();
}

QListWidgetItem *QListModel::at(int row) const
{
    return items.value(row);
}

void QListModel::remove(QListWidgetItem *item)
{
    if (!item)
        return;
    int row = items.indexOf(item); // ### use index(item) - it's faster
    Q_ASSERT(row != -1);
    beginRemoveRows(QModelIndex(), row, row);
    items.at(row)->d->theid = -1;
    items.at(row)->view = nullptr;
    items.removeAt(row);
    endRemoveRows();
}

void QListModel::insert(int row, QListWidgetItem *item)
{
    if (!item)
        return;

    item->view = qobject_cast<QListWidget*>(QObject::parent());
    if (item->view && item->view->isSortingEnabled()) {
        // sorted insertion
        QList<QListWidgetItem*>::iterator it;
        it = sortedInsertionIterator(items.begin(), items.end(),
                                     item->view->sortOrder(), item);
        row = qMax(it - items.begin(), 0);
    } else {
        if (row < 0)
            row = 0;
        else if (row > items.count())
            row = items.count();
    }
    beginInsertRows(QModelIndex(), row, row);
    items.insert(row, item);
    item->d->theid = row;
    endInsertRows();
}

void QListModel::insert(int row, const QStringList &labels)
{
    const int count = labels.count();
    if (count <= 0)
        return;
    QListWidget *view = qobject_cast<QListWidget*>(QObject::parent());
    if (view && view->isSortingEnabled()) {
        // sorted insertion
        for (int i = 0; i < count; ++i) {
            QListWidgetItem *item = new QListWidgetItem(labels.at(i));
            insert(row, item);
        }
    } else {
        if (row < 0)
            row = 0;
        else if (row > items.count())
            row = items.count();
        beginInsertRows(QModelIndex(), row, row + count - 1);
        for (int i = 0; i < count; ++i) {
            QListWidgetItem *item = new QListWidgetItem(labels.at(i));
            item->d->theid = row;
            item->view = qobject_cast<QListWidget*>(QObject::parent());
            items.insert(row++, item);
        }
        endInsertRows();
    }
}

QListWidgetItem *QListModel::take(int row)
{
    if (row < 0 || row >= items.count())
        return nullptr;

    beginRemoveRows(QModelIndex(), row, row);
    items.at(row)->d->theid = -1;
    items.at(row)->view = nullptr;
    QListWidgetItem *item = items.takeAt(row);
    endRemoveRows();
    return item;
}

void QListModel::move(int srcRow, int dstRow)
{
    if (srcRow == dstRow
        || srcRow < 0 || srcRow >= items.count()
        || dstRow < 0 || dstRow > items.count())
        return;

    if (!beginMoveRows(QModelIndex(), srcRow, srcRow, QModelIndex(), dstRow))
        return;
    if (srcRow < dstRow)
        --dstRow;
    items.move(srcRow, dstRow);
    endMoveRows();
}

int QListModel::rowCount(const QModelIndex &parent) const
{
    return parent.isValid() ? 0 : items.count();
}

QModelIndex QListModel::index(const QListWidgetItem *item_) const
{
    QListWidgetItem *item = const_cast<QListWidgetItem *>(item_);
    if (!item || !item->view || static_cast<const QListModel *>(item->view->model()) != this
        || items.isEmpty())
        return QModelIndex();
    int row;
    const int theid = item->d->theid;
    if (theid >= 0 && theid < items.count() && 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
        if (row == -1) // not found
            return QModelIndex();
        item->d->theid = row;
    }
    return createIndex(row, 0, item);
}

QModelIndex QListModel::index(int row, int column, const QModelIndex &parent) const
{
    if (hasIndex(row, column, parent))
        return createIndex(row, column, items.at(row));
    return QModelIndex();
}

QVariant QListModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid() || index.row() >= items.count())
        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())
        return false;
    items.at(index.row())->setData(role, value);
    return true;
}

#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
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, QVector<int>{});
    return true;
}
#endif

QMap<int, QVariant> QListModel::itemData(const QModelIndex &index) const
{
    QMap<int, QVariant> roles;
    if (!index.isValid() || index.row() >= items.count())
        return roles;
    QListWidgetItem *itm = items.at(index.row());
    for (int i = 0; i < itm->d->values.count(); ++i) {
        roles.insert(itm->d->values.at(i).role,
                     itm->d->values.at(i).value);
    }
    return roles;
}

bool QListModel::insertRows(int row, int count, const QModelIndex &parent)
{
    if (count < 1 || row < 0 || row > rowCount() || parent.isValid())
        return false;

    beginInsertRows(QModelIndex(), row, row + count - 1);
    QListWidget *view = qobject_cast<QListWidget*>(QObject::parent());
    QListWidgetItem *itm = nullptr;

    for (int r = row; r < row + count; ++r) {
        itm = new QListWidgetItem;
        itm->view = view;
        itm->d->theid = r;
        items.insert(r, itm);
    }

    endInsertRows();
    return true;
}

bool QListModel::removeRows(int row, int count, const QModelIndex &parent)
{
    if (count < 1 || row < 0 || (row + count) > rowCount() || parent.isValid())
        return false;

    beginRemoveRows(QModelIndex(), row, row + count - 1);
    QListWidgetItem *itm = nullptr;
    for (int r = row; r < row + count; ++r) {
        itm = items.takeAt(row);
        itm->view = nullptr;
        itm->d->theid = -1;
        delete itm;
    }
    endRemoveRows();
    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)
        return Qt::ItemIsDropEnabled; // we allow drops outside the items
    return items.at(index.row())->flags();
}

void QListModel::sort(int column, Qt::SortOrder order)
{
    if (column != 0)
        return;

    emit layoutAboutToBeChanged({}, QAbstractItemModel::VerticalSortHint);

    QVector < QPair<QListWidgetItem*,int> > sorting(items.count());
    for (int i = 0; i < items.count(); ++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);
    QModelIndexList fromIndexes;
    QModelIndexList toIndexes;
    const int sortingCount = sorting.count();
    fromIndexes.reserve(sortingCount);
    toIndexes.reserve(sortingCount);
    for (int r = 0; r < sortingCount; ++r) {
        QListWidgetItem *item = sorting.at(r).first;
        toIndexes.append(createIndex(r, 0, item));
        fromIndexes.append(createIndex(sorting.at(r).second, 0, sorting.at(r).first));
        items[r] = sorting.at(r).first;
    }
    changePersistentIndexList(fromIndexes, toIndexes);

    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 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());
            }
        }
    }

    if (changed) {
        emit layoutAboutToBeChanged();
        items = tmp;
        changePersistentIndexList(oldPersistentIndexes, newPersistentIndexes);
        emit layoutChanged();
    }
}

bool QListModel::itemLessThan(const QPair<QListWidgetItem*,int> &left,
                              const QPair<QListWidgetItem*,int> &right)
{
    return (*left.first) < (*right.first);
}

bool QListModel::itemGreaterThan(const QPair<QListWidgetItem*,int> &left,
                                 const QPair<QListWidgetItem*,int> &right)
{
    return (*right.first) < (*left.first);
}

QList<QListWidgetItem*>::iterator QListModel::sortedInsertionIterator(
    const QList<QListWidgetItem*>::iterator &begin,
    const QList<QListWidgetItem*>::iterator &end,
    Qt::SortOrder order, QListWidgetItem *item)
{
    if (order == Qt::AscendingOrder)
        return std::lower_bound(begin, end, item, QListModelLessThan());
    return std::lower_bound(begin, end, item, QListModelGreaterThan());
}

void QListModel::itemChanged(QListWidgetItem *item, const QVector<int> &roles)
{
    const QModelIndex idx = index(item);
    emit dataChanged(idx, idx, roles);
}

QStringList QListModel::mimeTypes() const
{
    const QListWidget *view = qobject_cast<const QListWidget*>(QObject::parent());
    if (view)
        return view->mimeTypes();
    return {};
}

QMimeData *QListModel::internalMimeData()  const
{
    return QAbstractItemModel::mimeData(cachedIndexes);
}

QMimeData *QListModel::mimeData(const QModelIndexList &indexes) const
{
    QList<QListWidgetItem*> itemlist;
    const int indexesCount = indexes.count();
    itemlist.reserve(indexesCount);
    for (int i = 0; i < indexesCount; ++i)
        itemlist << at(indexes.at(i).row());
    const QListWidget *view = qobject_cast<const QListWidget*>(QObject::parent());

    cachedIndexes = indexes;
    QMimeData *mimeData = view->mimeData(itemlist);
    cachedIndexes.clear();
    return mimeData;
}

#if QT_CONFIG(draganddrop)
bool QListModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
                              int row, int column, const QModelIndex &index)
{
    Q_UNUSED(column);
    QListWidget *view = qobject_cast<QListWidget*>(QObject::parent());
    if (index.isValid())
        row = index.row();
    else if (row == -1)
        row = items.count();

    return view->dropMimeData(row, data, action);
}

Qt::DropActions QListModel::supportedDropActions() const
{
    const QListWidget *view = qobject_cast<const QListWidget*>(QObject::parent());
    return view->supportedDropActions();
}
#endif // QT_CONFIG(draganddrop)

/*!
    \class QListWidgetItem
    \brief The QListWidgetItem class provides an item for use with the
    QListWidget item view class.

    \ingroup model-view
    \inmodule QtWidgets

    A QListWidgetItem represents a single item in a QListWidget. Each item can
    hold several pieces of information, and will display them appropriately.

    The item view convenience classes use a classic item-based interface rather
    than a pure model/view approach. For a more flexible list view widget,
    consider using the QListView class with a standard model.

    List items can be inserted automatically into a list, when they are
    constructed, by specifying the list widget:

    \snippet qlistwidget-using/mainwindow.cpp 2

    Alternatively, list items can also be created without a parent widget, and
    later inserted into a list using QListWidget::insertItem().

    List items are typically used to display text() and an icon(). These are
    set with the setText() and setIcon() functions. The appearance of the text
    can be customized with setFont(), setForeground(), and setBackground().
    Text in list items can be aligned using the setTextAlignment() function.
    Tooltips, status tips and "What's This?" help can be added to list items
    with setToolTip(), setStatusTip(), and setWhatsThis().

    By default, items are enabled, selectable, checkable, and can be the source
    of drag and drop operations.

    Each item's flags can be changed by calling setFlags() with the appropriate
    value (see Qt::ItemFlags). Checkable items can be checked, unchecked and
    partially checked with the setCheckState() function. The corresponding
    checkState() function indicates the item's current check state.

    The isHidden() function can be used to determine whether the item is
    hidden. To hide an item, use setHidden().


    \section1 Subclassing

    When subclassing QListWidgetItem to provide custom items, it is possible to
    define new types for them enabling them to be distinguished from standard
    items. For subclasses that require this feature, ensure that you call the
    base class constructor with a new type value equal to or greater than
    \l UserType, within \e your constructor.

    \sa QListWidget, {Model/View Programming}, QTreeWidgetItem, QTableWidgetItem
*/

/*!
    \enum QListWidgetItem::ItemType

    This enum describes the types that are used to describe list widget items.

    \value Type     The default type for list widget items.
    \value UserType The minimum value for custom types. Values below UserType are
                    reserved by Qt.

    You can define new user types in QListWidgetItem subclasses to ensure that
    custom items are treated specially.

    \sa type()
*/

/*!
    \fn int QListWidgetItem::type() const

    Returns the type passed to the QListWidgetItem constructor.
*/

/*!
    \fn QListWidget *QListWidgetItem::listWidget() const

    Returns the list widget containing the item.
*/

/*!
    \fn void QListWidgetItem::setHidden(bool hide)
    \since 4.2

    Hides the item if \a hide is true; otherwise shows the item.

    \sa isHidden()
*/

/*!
    \fn bool QListWidgetItem::isHidden() const
    \since 4.2

    Returns \c true if the item is hidden; otherwise returns \c false.

    \sa setHidden()
*/

/*!
    \fn QListWidgetItem::QListWidgetItem(QListWidget *parent, int type)

    Constructs an empty list widget item of the specified \a type with the
    given \a parent. If \a parent is not specified, the item will need to be
    inserted into a list widget with QListWidget::insertItem().

    This constructor inserts the item into the model of the parent that is
    passed to the constructor. If the model is sorted then the behavior of the
    insert is undetermined since the model will call the \c '<' operator method
    on the item which, at this point, is not yet constructed. To avoid the
    undetermined behavior, we recommend not to specify the parent and use
    QListWidget::insertItem() instead.

    \sa type()
*/
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 = listModel())
        model->insert(model->rowCount(), this);
}

/*!
    \fn QListWidgetItem::QListWidgetItem(const QString &text, QListWidget *parent, int type)

    Constructs an empty list widget item of the specified \a type with the
    given \a text and \a parent. If the parent is not specified, the item will
    need to be inserted into a list widget with QListWidget::insertItem().

    This constructor inserts the item into the model of the parent that is
    passed to the constructor. If the model is sorted then the behavior of the
    insert is undetermined since the model will call the \c '<' operator method
    on the item which, at this point, is not yet constructed. To avoid the
    undetermined behavior, we recommend not to specify the parent and use
    QListWidget::insertItem() instead.

    \sa type()
*/
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)
{
    QListModel *model = listModel();
    {
        QSignalBlocker b(view);
        QSignalBlocker bm(model);
        setData(Qt::DisplayRole, text);
    }
    if (model)
        model->insert(model->rowCount(), this);
}

/*!
    \fn QListWidgetItem::QListWidgetItem(const QIcon &icon, const QString &text, QListWidget *parent, int type)

    Constructs an empty list widget item of the specified \a type with the
    given \a icon, \a text and \a parent. If the parent is not specified, the
    item will need to be inserted into a list widget with
    QListWidget::insertItem().

    This constructor inserts the item into the model of the parent that is
    passed to the constructor. If the model is sorted then the behavior of the
    insert is undetermined since the model will call the \c '<' operator method
    on the item which, at this point, is not yet constructed. To avoid the
    undetermined behavior, we recommend not to specify the parent and use
    QListWidget::insertItem() instead.

    \sa type()
*/
QListWidgetItem::QListWidgetItem(const QIcon &icon,const QString &text,
                                 QListWidget *listview, int type)
    : rtti(type), view(listview), d(new QListWidgetItemPrivate(this)),
      itemFlags(Qt::ItemIsSelectable
                |Qt::ItemIsUserCheckable
                |Qt::ItemIsEnabled
                |Qt::ItemIsDragEnabled)
{
    QListModel *model = listModel();
    {
        QSignalBlocker b(view);
        QSignalBlocker bm(model);
        setData(Qt::DisplayRole, text);
        setData(Qt::DecorationRole, icon);
    }
    if (model)
        model->insert(model->rowCount(), this);
}

/*!
    Destroys the list item.
*/
QListWidgetItem::~QListWidgetItem()
{
    if (QListModel *model = listModel())
        model->remove(this);
    delete d;
}

/*!
    Creates an exact copy of the item.
*/
QListWidgetItem *QListWidgetItem::clone() const
{
    return new QListWidgetItem(*this);
}

/*!
    Sets the data for a given \a role to the given \a value. Reimplement this
    function if you need extra roles or special behavior for certain roles.

    \note The default implementation treats Qt::EditRole and Qt::DisplayRole as
    referring to the same data.

    \sa Qt::ItemDataRole, data()
*/
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) {
        if (d->values.at(i).role == role) {
            if (d->values.at(i).value == value)
                return;
            d->values[i].value = value;
            found = true;
            break;
        }
    }
    if (!found)
        d->values.append(QWidgetItemData(role, value));
    if (QListModel *model = listModel()) {
        const QVector<int> roles((role == Qt::DisplayRole) ?
                                    QVector<int>({Qt::DisplayRole, Qt::EditRole}) :
                                    QVector<int>({role}));
        model->itemChanged(this, roles);
    }
}

/*!
    Returns the item's data for a given \a role. Reimplement this function if
    you need extra roles or special behavior for certain roles.

    \sa Qt::ItemDataRole, setData()
*/
QVariant QListWidgetItem::data(int role) const
{
    role = (role == Qt::EditRole ? Qt::DisplayRole : role);
    for (int i = 0; i < d->values.count(); ++i)
        if (d->values.at(i).role == role)
            return d->values.at(i).value;
    return QVariant();
}

/*!
    Returns \c true if this item's text is less then \a other item's text;
    otherwise returns \c false.
*/
bool QListWidgetItem::operator<(const QListWidgetItem &other) const
{
    const QVariant v1 = data(Qt::DisplayRole), v2 = other.data(Qt::DisplayRole);
    return QAbstractItemModelPrivate::variantLessThan(v1, v2);
}

#ifndef QT_NO_DATASTREAM

/*!
    Reads the item from stream \a in.

    \sa write()
*/
void QListWidgetItem::read(QDataStream &in)
{
    in >> d->values;
}

/*!
    Writes the item to stream \a out.

    \sa read()
*/
void QListWidgetItem::write(QDataStream &out) const
{
    out << d->values;
}
#endif // QT_NO_DATASTREAM

/*!
    \since 4.1

    Constructs a copy of \a other. Note that type() and listWidget() are not
    copied.

    This function is useful when reimplementing clone().

    \sa data(), flags()
*/
QListWidgetItem::QListWidgetItem(const QListWidgetItem &other)
    : rtti(Type), view(nullptr),
      d(new QListWidgetItemPrivate(this)),
      itemFlags(other.itemFlags)
{
    d->values = other.d->values;
}

/*!
    Assigns \a other's data and flags to this item. Note that type() and
    listWidget() are not copied.

    This function is useful when reimplementing clone().

    \sa data(), flags()
*/
QListWidgetItem &QListWidgetItem::operator=(const QListWidgetItem &other)
{
    d->values = other.d->values;
    itemFlags = other.itemFlags;
    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

/*!
    \relates QListWidgetItem

    Writes the list widget item \a item to stream \a out.

    This operator uses QListWidgetItem::write().

    \sa {Serializing Qt Data Types}
*/
QDataStream &operator<<(QDataStream &out, const QListWidgetItem &item)
{
    item.write(out);
    return out;
}

/*!
    \relates QListWidgetItem

    Reads a list widget item from stream \a in into \a item.

    This operator uses QListWidgetItem::read().

    \sa {Serializing Qt Data Types}
*/
QDataStream &operator>>(QDataStream &in, QListWidgetItem &item)
{
    item.read(in);
    return in;
}

#endif // QT_NO_DATASTREAM

/*!
    \fn Qt::ItemFlags QListWidgetItem::flags() const

    Returns the item flags for this item (see \l{Qt::ItemFlags}).
*/

/*!
    \fn QString QListWidgetItem::text() const

    Returns the list item's text.

    \sa setText()
*/

/*!
    \fn QIcon QListWidgetItem::icon() const

    Returns the list item's icon.

    \sa setIcon(), {QAbstractItemView::iconSize}{iconSize}
*/

/*!
    \fn QString QListWidgetItem::statusTip() const

    Returns the list item's status tip.

    \sa setStatusTip()
*/

/*!
    \fn QString QListWidgetItem::toolTip() const

    Returns the list item's tooltip.

    \sa setToolTip(), statusTip(), whatsThis()
*/

/*!
    \fn QString QListWidgetItem::whatsThis() const

    Returns the list item's "What's This?" help text.

    \sa setWhatsThis(), statusTip(), toolTip()
*/

/*!
    \fn QFont QListWidgetItem::font() const

    Returns the font used to display this list item's text.
*/

/*!
    \fn int QListWidgetItem::textAlignment() const

    Returns the text alignment for the list item.

    \sa Qt::AlignmentFlag
*/

#if QT_DEPRECATED_SINCE(5, 13)
/*!
    \fn QColor QListWidgetItem::backgroundColor() const
    \obsolete

    This function is deprecated. Use background() instead.
*/
#endif

/*!
    \fn QBrush QListWidgetItem::background() const
    \since 4.2

    Returns the brush used to display the list item's background.

    \sa setBackground(), foreground()
*/

#if QT_DEPRECATED_SINCE(5, 13)
/*!
    \fn QColor QListWidgetItem::textColor() const
    \obsolete

    Returns the color used to display the list item's text.

    This function is deprecated. Use foreground() instead.
*/
#endif

/*!
    \fn QBrush QListWidgetItem::foreground() const
    \since 4.2

    Returns the brush used to display the list item's foreground (e.g. text).

    \sa setForeground(), background()
*/

/*!
    \fn Qt::CheckState QListWidgetItem::checkState() const

    Returns the checked state of the list item (see \l{Qt::CheckState}).

    \sa flags()
*/

/*!
    \fn QSize QListWidgetItem::sizeHint() const
    \since 4.1

    Returns the size hint set for the list 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 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)

    Sets the item flags for the list item to \a flags.

    \sa Qt::ItemFlags
*/
void QListWidgetItem::setFlags(Qt::ItemFlags aflags)
{
    itemFlags = aflags;
    if (QListModel *model = listModel())
        model->itemChanged(this);
}


/*!
    \fn void QListWidgetItem::setText(const QString &text)

    Sets the text for the list widget item's to the given \a text.

    \sa text()
*/

/*!
    \fn void QListWidgetItem::setIcon(const QIcon &icon)

    Sets the icon for the list item to the given \a icon.

    \sa icon(), text(), {QAbstractItemView::iconSize}{iconSize}
*/

/*!
    \fn void QListWidgetItem::setStatusTip(const QString &statusTip)

    Sets the status tip for the list item to the text specified by
    \a statusTip. QListWidget mouseTracking needs to be enabled for this
    feature to work.

    \sa statusTip(), setToolTip(), setWhatsThis(), QWidget::setMouseTracking()
*/

/*!
    \fn void QListWidgetItem::setToolTip(const QString &toolTip)

    Sets the tooltip for the list item to the text specified by \a toolTip.

    \sa toolTip(), setStatusTip(), setWhatsThis()
*/

/*!
    \fn void QListWidgetItem::setWhatsThis(const QString &whatsThis)

    Sets the "What's This?" help for the list item to the text specified by
    \a whatsThis.

    \sa whatsThis(), setStatusTip(), setToolTip()
*/

/*!
    \fn void QListWidgetItem::setFont(const QFont &font)

    Sets the font used when painting the item to the given \a font.
*/

/*!
    \fn void QListWidgetItem::setTextAlignment(int alignment)

    Sets the list item's text alignment to \a alignment.

    \sa Qt::AlignmentFlag
*/

/*!
    \fn void QListWidgetItem::setBackgroundColor(const QColor &color)
    \obsolete

    This function is deprecated. Use setBackground() instead.
*/

/*!
    \fn void QListWidgetItem::setBackground(const QBrush &brush)
    \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()
*/

#if QT_DEPRECATED_SINCE(5, 13)
/*!
    \fn void QListWidgetItem::setTextColor(const QColor &color)
    \obsolete

    This function is deprecated. Use setForeground() instead.
*/
#endif

/*!
    \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()
*/

/*!
    \fn void QListWidgetItem::setCheckState(Qt::CheckState state)

    Sets the check state of the list item to \a state.

    \sa checkState()
*/

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)
{
    Q_Q(QListWidget);
    emit q->itemPressed(listModel()->at(index.row()));
}

void QListWidgetPrivate::_q_emitItemClicked(const QModelIndex &index)
{
    Q_Q(QListWidget);
    emit q->itemClicked(listModel()->at(index.row()));
}

void QListWidgetPrivate::_q_emitItemDoubleClicked(const QModelIndex &index)
{
    Q_Q(QListWidget);
    emit q->itemDoubleClicked(listModel()->at(index.row()));
}

void QListWidgetPrivate::_q_emitItemActivated(const QModelIndex &index)
{
    Q_Q(QListWidget);
    emit q->itemActivated(listModel()->at(index.row()));
}

void QListWidgetPrivate::_q_emitItemEntered(const QModelIndex &index)
{
    Q_Q(QListWidget);
    emit q->itemEntered(listModel()->at(index.row()));
}

void QListWidgetPrivate::_q_emitItemChanged(const QModelIndex &index)
{
    Q_Q(QListWidget);
    emit q->itemChanged(listModel()->at(index.row()));
}

void QListWidgetPrivate::_q_emitCurrentItemChanged(const QModelIndex &current,
                                                const QModelIndex &previous)
{
    Q_Q(QListWidget);
    QPersistentModelIndex persistentCurrent = current;
    QListWidgetItem *currentItem = listModel()->at(persistentCurrent.row());
    emit q->currentItemChanged(currentItem, listModel()->at(previous.row()));

    //persistentCurrent is invalid if something changed the model in response
    //to the currentItemChanged signal emission and the item was removed
    if (!persistentCurrent.isValid()) {
        currentItem = nullptr;
    }

    emit q->currentTextChanged(currentItem ? currentItem->text() : QString());
    emit q->currentRowChanged(persistentCurrent.row());
}

void QListWidgetPrivate::_q_sort()
{
    if (sortingEnabled)
        model->sort(0, sortOrder);
}

void QListWidgetPrivate::_q_dataChanged(const QModelIndex &topLeft,
                                        const QModelIndex &bottomRight)
{
    if (sortingEnabled && topLeft.isValid() && bottomRight.isValid())
        listModel()->ensureSorted(topLeft.column(), sortOrder,
                              topLeft.row(), bottomRight.row());
}

/*!
    \class QListWidget
    \brief The QListWidget class provides an item-based list widget.

    \ingroup model-view
    \inmodule QtWidgets

    \image windows-listview.png

    QListWidget is a convenience class that provides a list view similar to the
    one supplied by QListView, but with a classic item-based interface for
    adding and removing items. QListWidget uses an internal model to manage
    each QListWidgetItem in the list.

    For a more flexible list view widget, use the QListView class with a
    standard model.

    List widgets are constructed in the same way as other widgets:

    \snippet qlistwidget-using/mainwindow.cpp 0

    The selectionMode() of a list widget determines how many of the items in
    the list can be selected at the same time, and whether complex selections
    of items can be created. This can be set with the setSelectionMode()
    function.

    There are two ways to add items to the list: they can be constructed with
    the list widget as their parent widget, or they can be constructed with no
    parent widget and added to the list later. If a list widget already exists
    when the items are constructed, the first method is easier to use:

    \snippet qlistwidget-using/mainwindow.cpp 1

    If you need to insert a new item into the list at a particular position,
    then it should be constructed without a parent widget. The insertItem()
    function should then be used to place it within the list. The list widget
    will take ownership of the item.

    \snippet qlistwidget-using/mainwindow.cpp 6
    \snippet qlistwidget-using/mainwindow.cpp 7

    For multiple items, insertItems() can be used instead. The number of items
    in the list is found with the count() function. To remove items from the
    list, use takeItem().

    The current item in the list can be found with currentItem(), and changed
    with setCurrentItem(). The user can also change the current item by
    navigating with the keyboard or clicking on a different item. When the
    current item changes, the currentItemChanged() signal is emitted with the
    new current item and the item that was previously current.

    \sa QListWidgetItem, QListView, QTreeView, {Model/View Programming},
        {Tab Dialog Example}
*/

/*!
    \fn void QListWidget::addItem(QListWidgetItem *item)

    Inserts the \a item at the end of the list widget.

    \warning A QListWidgetItem can only be added to a QListWidget once. Adding
    the same QListWidgetItem multiple times to a QListWidget will result in
    undefined behavior.

    \sa insertItem()
*/

/*!
    \fn void QListWidget::addItem(const QString &label)

    Inserts an item with the text \a label at the end of the list widget.
*/

/*!
    \fn void QListWidget::addItems(const QStringList &labels)

    Inserts items with the text \a labels at the end of the list widget.

    \sa insertItems()
*/

/*!
    \fn void QListWidget::itemPressed(QListWidgetItem *item)

    This signal is emitted with the specified \a item when a mouse button is
    pressed on an item in the widget.

    \sa itemClicked(), itemDoubleClicked()
*/

/*!
    \fn void QListWidget::itemClicked(QListWidgetItem *item)

    This signal is emitted with the specified \a item when a mouse button is
    clicked on an item in the widget.

    \sa itemPressed(), itemDoubleClicked()
*/

/*!
    \fn void QListWidget::itemDoubleClicked(QListWidgetItem *item)

    This signal is emitted with the specified \a item when a mouse button is
    double clicked on an item in the widget.

    \sa itemClicked(), itemPressed()
*/

/*!
    \fn void QListWidget::itemActivated(QListWidgetItem *item)

    This signal is emitted when the \a item is activated. The \a item is
    activated when the user clicks or double clicks on it, depending on the
    system configuration. It is also activated when the user presses the
    activation key (on Windows and X11 this is the \uicontrol Return key, on Mac OS
    X it is \uicontrol{Command+O}).
*/

/*!
    \fn void QListWidget::itemEntered(QListWidgetItem *item)

    This signal is emitted when the mouse cursor enters an item. The \a item is
    the item entered. This signal is only emitted when mouseTracking is turned
    on, or when a mouse button is pressed while moving into an item.

    \sa QWidget::setMouseTracking()
*/

/*!
    \fn void QListWidget::itemChanged(QListWidgetItem *item)

    This signal is emitted whenever the data of \a item has changed.
*/

/*!
    \fn void QListWidget::currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)

    This signal is emitted whenever the current item changes.

    \a previous is the item that previously had the focus; \a current is the
    new current item.
*/

/*!
    \fn void QListWidget::currentTextChanged(const QString &currentText)

    This signal is emitted whenever the current item changes.

    \a currentText is the text data in the current item. If there is no current
    item, the \a currentText is invalid.
*/

/*!
    \fn void QListWidget::currentRowChanged(int currentRow)

    This signal is emitted whenever the current item changes.

    \a currentRow is the row of the current item. If there is no current item,
    the \a currentRow is -1.
*/

/*!
    \fn void QListWidget::itemSelectionChanged()

    This signal is emitted whenever the selection changes.

    \sa selectedItems(), QListWidgetItem::isSelected(), currentItemChanged()
*/

/*!
    \since 4.3

    \fn void QListWidget::removeItemWidget(QListWidgetItem *item)

    Removes the widget set on the given \a item.

    To remove an item (row) from the list entirely, either delete the item or
    use takeItem().

    \sa itemWidget(), setItemWidget()
*/

/*!
    Constructs an empty QListWidget with the given \a parent.
*/

QListWidget::QListWidget(QWidget *parent)
    : QListView(*new QListWidgetPrivate(), parent)
{
    Q_D(QListWidget);
    d->setup();
}

/*!
    Destroys the list widget and all its items.
*/

QListWidget::~QListWidget()
{
}

/*!
    \reimp
*/

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()));
    }

    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()));
    }
}

/*!
    Returns the item that occupies the given \a row in the list if one has been
    set; otherwise returns \nullptr.

    \sa row()
*/

QListWidgetItem *QListWidget::item(int row) const
{
    Q_D(const QListWidget);
    if (row < 0 || row >= d->model->rowCount())
        return nullptr;
    return d->listModel()->at(row);
}

/*!
    Returns the row containing the given \a item.

    \sa item()
*/

int QListWidget::row(const QListWidgetItem *item) const
{
    Q_D(const QListWidget);
    return d->listModel()->index(const_cast<QListWidgetItem*>(item)).row();
}


/*!
    Inserts the \a item at the position in the list given by \a row.

    \sa addItem()
*/

void QListWidget::insertItem(int row, QListWidgetItem *item)
{
    Q_D(QListWidget);
    if (item && !item->view)
        d->listModel()->insert(row, item);
}

/*!
    Inserts an item with the text \a label in the list widget at the position
    given by \a row.

    \sa addItem()
*/

void QListWidget::insertItem(int row, const QString &label)
{
    Q_D(QListWidget);
    d->listModel()->insert(row, new QListWidgetItem(label));
}

/*!
    Inserts items from the list of \a labels into the list, starting at the
    given \a row.

    \sa insertItem(), addItem()
*/

void QListWidget::insertItems(int row, const QStringList &labels)
{
    Q_D(QListWidget);
    d->listModel()->insert(row, labels);
}

/*!
    Removes and returns the item from the given \a row in the list widget;
    otherwise returns \nullptr.

    Items removed from a list widget will not be managed by Qt, and will need
    to be deleted manually.

    \sa insertItem(), addItem()
*/

QListWidgetItem *QListWidget::takeItem(int row)
{
    Q_D(QListWidget);
    if (row < 0 || row >= d->model->rowCount())
        return nullptr;
    return d->listModel()->take(row);
}

/*!
    \property QListWidget::count
    \brief the number of items in the list including any hidden items.
*/

int QListWidget::count() const
{
    Q_D(const QListWidget);
    return d->model->rowCount();
}

/*!
    Returns the current item.
*/
QListWidgetItem *QListWidget::currentItem() const
{
    Q_D(const QListWidget);
    return d->listModel()->at(currentIndex().row());
}


/*!
    Sets the current item to \a item.

    Unless the selection mode is \l{QAbstractItemView::}{NoSelection},
    the item is also selected.
*/
void QListWidget::setCurrentItem(QListWidgetItem *item)
{
    setCurrentRow(row(item));
}

/*!
    \since 4.4
    Set the current item to \a item, using the given \a command.
*/
void QListWidget::setCurrentItem(QListWidgetItem *item, QItemSelectionModel::SelectionFlags command)
{
    setCurrentRow(row(item), command);
}

/*!
    \property QListWidget::currentRow
    \brief the row of the current item.

    Depending on the current selection mode, the row may also be selected.
*/

int QListWidget::currentRow() const
{
    return currentIndex().row();
}

void QListWidget::setCurrentRow(int row)
{
    Q_D(QListWidget);
    QModelIndex index = d->listModel()->index(row);
    if (d->selectionMode == SingleSelection)
        selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect);
    else if (d->selectionMode == NoSelection)
        selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
    else
        selectionModel()->setCurrentIndex(index, QItemSelectionModel::SelectCurrent);
}

/*!
    \since 4.4

    Sets the current row to be the given \a row, using the given \a command,
*/
void QListWidget::setCurrentRow(int row, QItemSelectionModel::SelectionFlags command)
{
    Q_D(QListWidget);
    d->selectionModel->setCurrentIndex(d->listModel()->index(row), command);
}

/*!
    Returns a pointer to the item at the coordinates \a p. The coordinates
    are relative to the list widget's \l{QAbstractScrollArea::}{viewport()}.

*/
QListWidgetItem *QListWidget::itemAt(const QPoint &p) const
{
    Q_D(const QListWidget);
    return d->listModel()->at(indexAt(p).row());

}

/*!
    \fn QListWidgetItem *QListWidget::itemAt(int x, int y) const
    \overload

    Returns a pointer to the item at the coordinates (\a x, \a y).
    The coordinates are relative to the list widget's
    \l{QAbstractScrollArea::}{viewport()}.

*/


/*!
    Returns the rectangle on the viewport occupied by the item at \a item.
*/
QRect QListWidget::visualItemRect(const QListWidgetItem *item) const
{
    Q_D(const QListWidget);
    QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item));
    return visualRect(index);
}

/*!
    Sorts all the items in the list widget according to the specified \a order.
*/
void QListWidget::sortItems(Qt::SortOrder order)
{
    Q_D(QListWidget);
    d->sortOrder = order;
    d->listModel()->sort(0, order);
}

/*!
    \since 4.2
    \property QListWidget::sortingEnabled
    \brief whether sorting is enabled

    If this property is \c true, sorting is enabled for the list; if the property
    is false, sorting is not enabled.

    The default value is false.
*/
void QListWidget::setSortingEnabled(bool enable)
{
    Q_D(QListWidget);
    d->sortingEnabled = enable;
}

bool QListWidget::isSortingEnabled() const
{
    Q_D(const QListWidget);
    return d->sortingEnabled;
}

/*!
    \internal
*/
Qt::SortOrder QListWidget::sortOrder() const
{
    Q_D(const QListWidget);
    return d->sortOrder;
}

/*!
    Starts editing the \a item if it is editable.
*/

void QListWidget::editItem(QListWidgetItem *item)
{
    Q_D(QListWidget);
    edit(d->listModel()->index(item));
}

/*!
    Opens an editor for the given \a item. The editor remains open after
    editing.

    \sa closePersistentEditor(), isPersistentEditorOpen()
*/
void QListWidget::openPersistentEditor(QListWidgetItem *item)
{
    Q_D(QListWidget);
    QModelIndex index = d->listModel()->index(item);
    QAbstractItemView::openPersistentEditor(index);
}

/*!
    Closes the persistent editor for the given \a item.

    \sa openPersistentEditor(), isPersistentEditorOpen()
*/
void QListWidget::closePersistentEditor(QListWidgetItem *item)
{
    Q_D(QListWidget);
    QModelIndex index = d->listModel()->index(item);
    QAbstractItemView::closePersistentEditor(index);
}

/*!
    \since 5.10

    Returns whether a persistent editor is open for item \a item.

    \sa openPersistentEditor(), closePersistentEditor()
*/
bool QListWidget::isPersistentEditorOpen(QListWidgetItem *item) const
{
    Q_D(const QListWidget);
    const QModelIndex index = d->listModel()->index(item);
    return QAbstractItemView::isPersistentEditorOpen(index);
}

/*!
    \since 4.1

    Returns the widget displayed in the given \a item.

    \sa setItemWidget(), removeItemWidget()
*/
QWidget *QListWidget::itemWidget(QListWidgetItem *item) const
{
    Q_D(const QListWidget);
    QModelIndex index = d->listModel()->index(item);
    return QAbstractItemView::indexWidget(index);
}

/*!
    \since 4.1

    Sets the \a widget to be displayed in the given \a item.

    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 QStyledItemDelegate
    instead.

    \sa itemWidget(), removeItemWidget(), {Delegate Classes}
*/
void QListWidget::setItemWidget(QListWidgetItem *item, QWidget *widget)
{
    Q_D(QListWidget);
    QModelIndex index = d->listModel()->index(item);
    QAbstractItemView::setIndexWidget(index, widget);
}

#if QT_DEPRECATED_SINCE(5, 13)
/*!
    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
{
    return ((item && item->listWidget() == this) ? item->isSelected() : false);
}

/*!
    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)
{
    if (item && item->listWidget() == this)
        const_cast<QListWidgetItem*>(item)->setSelected(select);
}
#endif

/*!
    Returns a list of all selected items in the list widget.
*/

QList<QListWidgetItem*> QListWidget::selectedItems() const
{
    Q_D(const QListWidget);
    QModelIndexList indexes = selectionModel()->selectedIndexes();
    QList<QListWidgetItem*> items;
    const int numIndexes = indexes.count();
    items.reserve(numIndexes);
    for (int i = 0; i < numIndexes; ++i)
        items.append(d->listModel()->at(indexes.at(i).row()));
    return items;
}

/*!
    Finds items with the text that matches the string \a text using the given
    \a flags.
*/

QList<QListWidgetItem*> QListWidget::findItems(const QString &text, Qt::MatchFlags flags) const
{
    Q_D(const QListWidget);
    QModelIndexList indexes = d->listModel()->match(model()->index(0, 0, QModelIndex()),
                                                Qt::DisplayRole, text, -1, flags);
    QList<QListWidgetItem*> items;
    const int indexesSize = indexes.size();
    items.reserve(indexesSize);
    for (int i = 0; i < indexesSize; ++i)
        items.append(d->listModel()->at(indexes.at(i).row()));
    return items;
}

#if QT_DEPRECATED_SINCE(5, 13)
/*!
    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);
}
#endif

/*!
    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.
*/

void QListWidget::scrollToItem(const QListWidgetItem *item, QAbstractItemView::ScrollHint hint)
{
    Q_D(QListWidget);
    QModelIndex index = d->listModel()->index(const_cast<QListWidgetItem*>(item));
    QListView::scrollTo(index, hint);
}

/*!
    Removes all items and selections in the view.

    \warning All items will be permanently deleted.
*/
void QListWidget::clear()
{
    Q_D(QListWidget);
    selectionModel()->clear();
    d->listModel()->clear();
}

/*!
    Returns a list of MIME types that can be used to describe a list of
    listwidget items.

    \sa mimeData()
*/
QStringList QListWidget::mimeTypes() const
{
    return d_func()->listModel()->QAbstractListModel::mimeTypes();
}

/*!
    Returns an object that contains a serialized description of the specified
    \a items. The format used to describe the items is obtained from the
    mimeTypes() function.

    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);

    QModelIndexList &cachedIndexes = d->listModel()->cachedIndexes;

    // if non empty, it's called from the model's own mimeData
    if (cachedIndexes.isEmpty()) {
        cachedIndexes.reserve(items.count());
        for (QListWidgetItem *item : items)
            cachedIndexes << indexFromItem(item);

        QMimeData *result = d->listModel()->internalMimeData();

        cachedIndexes.clear();
        return result;
    }

    return d->listModel()->internalMimeData();
}

#if QT_CONFIG(draganddrop)
/*!
    Handles \a data supplied by an external drag and drop operation that ended
    with the given \a action in the given \a index. Returns \c true if \a data and
    \a action can be handled by the model; otherwise returns \c false.

    \sa supportedDropActions()
*/
bool QListWidget::dropMimeData(int index, const QMimeData *data, Qt::DropAction action)
{
    QModelIndex idx;
    int row = index;
    int column = 0;
    if (dropIndicatorPosition() == QAbstractItemView::OnItem) {
        // QAbstractListModel::dropMimeData will overwrite on the index if row == -1 and column == -1
        idx = model()->index(row, column);
        row = -1;
        column = -1;
    }
    return d_func()->listModel()->QAbstractListModel::dropMimeData(data, action , row, column, idx);
}

/*! \reimp */
void QListWidget::dropEvent(QDropEvent *event)
{
    QListView::dropEvent(event);
}

/*!
    Returns the drop actions supported by this view.

    \sa Qt::DropActions
*/
Qt::DropActions QListWidget::supportedDropActions() const
{
    Q_D(const QListWidget);
    return d->listModel()->QAbstractListModel::supportedDropActions() | Qt::MoveAction;
}
#endif // QT_CONFIG(draganddrop)

/*!
    Returns a list of pointers to the items contained in the \a data object. If
    the object was not created by a QListWidget in the same process, the list
    is empty.
*/
QList<QListWidgetItem*> QListWidget::items(const QMimeData *data) const
{
    const QListWidgetMimeData *lwd = qobject_cast<const QListWidgetMimeData*>(data);
    if (lwd)
        return lwd->items;
    return QList<QListWidgetItem*>();
}

/*!
    Returns the QModelIndex associated with the given \a item.

    \note In Qt versions prior to 5.10, this function took a non-\c{const} \a item.
*/

QModelIndex QListWidget::indexFromItem(const QListWidgetItem *item) const
{
    Q_D(const QListWidget);
    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.
*/

QListWidgetItem *QListWidget::itemFromIndex(const QModelIndex &index) const
{
    Q_D(const QListWidget);
    if (d->isIndexValid(index))
        return d->listModel()->at(index.row());
    return nullptr;
}

/*!
    \internal
*/
void QListWidget::setModel(QAbstractItemModel * /*model*/)
{
    Q_ASSERT(!"QListWidget::setModel() - Changing the model of the QListWidget is not allowed.");
}

/*!
    \reimp
*/
bool QListWidget::event(QEvent *e)
{
    return QListView::event(e);
}

QT_END_NAMESPACE

#include "moc_qlistwidget.cpp"
#include "moc_qlistwidget_p.cpp"
