/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore 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 "qabstractproxymodel.h"
#include "qitemselectionmodel.h"
#include <private/qabstractproxymodel_p.h>
#include <QtCore/QSize>
#include <QtCore/QStringList>


QT_BEGIN_NAMESPACE

/*!
    \since 4.1
    \class QAbstractProxyModel
    \brief The QAbstractProxyModel class provides a base class for proxy item
    models that can do sorting, filtering or other data processing tasks.
    \ingroup model-view
    \inmodule QtCore

    This class defines the standard interface that proxy models must use to be
    able to interoperate correctly with other model/view components. It is not
    supposed to be instantiated directly.

    All standard proxy models are derived from the QAbstractProxyModel class.
    If you need to create a new proxy model class, it is usually better to
    subclass an existing class that provides the closest behavior to the one
    you want to provide.

    Proxy models that filter or sort items of data from a source model should
    be created by using or subclassing QSortFilterProxyModel.

    To subclass QAbstractProxyModel, you need to implement mapFromSource() and
    mapToSource(). The mapSelectionFromSource() and mapSelectionToSource()
    functions only need to be reimplemented if you need a behavior different
    from the default behavior.

    \note If the source model is deleted or no source model is specified, the
    proxy model operates on a empty placeholder model.

    \sa QSortFilterProxyModel, QAbstractItemModel, {Model/View Programming}
*/

/*!
    \property QAbstractProxyModel::sourceModel

    \brief the source model of this proxy model.
*/

//detects the deletion of the source model
void QAbstractProxyModelPrivate::_q_sourceModelDestroyed()
{
    invalidatePersistentIndexes();
    model = QAbstractItemModelPrivate::staticEmptyModel();
}

/*!
    Constructs a proxy model with the given \a parent.
*/

QAbstractProxyModel::QAbstractProxyModel(QObject *parent)
    :QAbstractItemModel(*new QAbstractProxyModelPrivate, parent)
{
    setSourceModel(QAbstractItemModelPrivate::staticEmptyModel());
}

/*!
    \internal
*/

QAbstractProxyModel::QAbstractProxyModel(QAbstractProxyModelPrivate &dd, QObject *parent)
    : QAbstractItemModel(dd, parent)
{
    setSourceModel(QAbstractItemModelPrivate::staticEmptyModel());
}

/*!
    Destroys the proxy model.
*/
QAbstractProxyModel::~QAbstractProxyModel()
{

}

/*!
    Sets the given \a sourceModel to be processed by the proxy model.

    Subclasses should call beginResetModel() at the beginning of the method,
    disconnect from the old model, call this method, connect to the new model,
    and call endResetModel().
*/
void QAbstractProxyModel::setSourceModel(QAbstractItemModel *sourceModel)
{
    Q_D(QAbstractProxyModel);
    if (sourceModel != d->model) {
        if (d->model)
            disconnect(d->model, SIGNAL(destroyed()), this, SLOT(_q_sourceModelDestroyed()));

        if (sourceModel) {
            d->model = sourceModel;
            connect(d->model, SIGNAL(destroyed()), this, SLOT(_q_sourceModelDestroyed()));
        } else {
            d->model = QAbstractItemModelPrivate::staticEmptyModel();
        }
        d->roleNames = d->model->roleNames();
        emit sourceModelChanged(QPrivateSignal());
    }
}

/*!
    Clears the roleNames of this proxy model.
*/
void QAbstractProxyModel::resetInternalData()
{
    Q_D(QAbstractProxyModel);
    d->roleNames = d->model->roleNames();
}

/*!
    Returns the model that contains the data that is available through the proxy model.
*/
QAbstractItemModel *QAbstractProxyModel::sourceModel() const
{
    Q_D(const QAbstractProxyModel);
    if (d->model == QAbstractItemModelPrivate::staticEmptyModel())
        return 0;
    return d->model;
}

/*!
    \reimp
 */
bool QAbstractProxyModel::submit()
{
    Q_D(QAbstractProxyModel);
    return d->model->submit();
}

/*!
    \reimp
 */
void QAbstractProxyModel::revert()
{
    Q_D(QAbstractProxyModel);
    d->model->revert();
}


/*!
  \fn QModelIndex QAbstractProxyModel::mapToSource(const QModelIndex &proxyIndex) const

  Reimplement this function to return the model index in the source model that
  corresponds to the \a proxyIndex in the proxy model.

  \sa mapFromSource()
*/

/*!
  \fn QModelIndex QAbstractProxyModel::mapFromSource(const QModelIndex &sourceIndex) const

  Reimplement this function to return the model index in the proxy model that
  corresponds to the \a sourceIndex from the source model.

  \sa mapToSource()
*/

/*!
  Returns a source selection mapped from the specified \a proxySelection.

  Reimplement this method to map proxy selections to source selections.
 */
QItemSelection QAbstractProxyModel::mapSelectionToSource(const QItemSelection &proxySelection) const
{
    QModelIndexList proxyIndexes = proxySelection.indexes();
    QItemSelection sourceSelection;
    for (int i = 0; i < proxyIndexes.size(); ++i) {
        const QModelIndex proxyIdx = mapToSource(proxyIndexes.at(i));
        if (!proxyIdx.isValid())
            continue;
        sourceSelection << QItemSelectionRange(proxyIdx);
    }
    return sourceSelection;
}

/*!
  Returns a proxy selection mapped from the specified \a sourceSelection.

  Reimplement this method to map source selections to proxy selections.
*/
QItemSelection QAbstractProxyModel::mapSelectionFromSource(const QItemSelection &sourceSelection) const
{
    QModelIndexList sourceIndexes = sourceSelection.indexes();
    QItemSelection proxySelection;
    for (int i = 0; i < sourceIndexes.size(); ++i) {
        const QModelIndex srcIdx = mapFromSource(sourceIndexes.at(i));
        if (!srcIdx.isValid())
            continue;
        proxySelection << QItemSelectionRange(srcIdx);
    }
    return proxySelection;
}

/*!
    \reimp
 */
QVariant QAbstractProxyModel::data(const QModelIndex &proxyIndex, int role) const
{
    Q_D(const QAbstractProxyModel);
    return d->model->data(mapToSource(proxyIndex), role);
}

/*!
    \reimp
 */
QVariant QAbstractProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    Q_D(const QAbstractProxyModel);
    int sourceSection;
    if (orientation == Qt::Horizontal) {
        const QModelIndex proxyIndex = index(0, section);
        sourceSection = mapToSource(proxyIndex).column();
    } else {
        const QModelIndex proxyIndex = index(section, 0);
        sourceSection = mapToSource(proxyIndex).row();
    }
    return d->model->headerData(sourceSection, orientation, role);
}

/*!
    \reimp
 */
QMap<int, QVariant> QAbstractProxyModel::itemData(const QModelIndex &proxyIndex) const
{
    return QAbstractItemModel::itemData(proxyIndex);
}

/*!
    \reimp
 */
Qt::ItemFlags QAbstractProxyModel::flags(const QModelIndex &index) const
{
    Q_D(const QAbstractProxyModel);
    return d->model->flags(mapToSource(index));
}

/*!
    \reimp
 */
bool QAbstractProxyModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    Q_D(QAbstractProxyModel);
    return d->model->setData(mapToSource(index), value, role);
}

/*!
    \reimp
 */
bool QAbstractProxyModel::setItemData(const QModelIndex &index, const QMap< int, QVariant >& roles)
{
    return QAbstractItemModel::setItemData(index, roles);
}

/*!
    \reimp
 */
bool QAbstractProxyModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role)
{
    Q_D(QAbstractProxyModel);
    int sourceSection;
    if (orientation == Qt::Horizontal) {
        const QModelIndex proxyIndex = index(0, section);
        sourceSection = mapToSource(proxyIndex).column();
    } else {
        const QModelIndex proxyIndex = index(section, 0);
        sourceSection = mapToSource(proxyIndex).row();
    }
    return d->model->setHeaderData(sourceSection, orientation, value, role);
}

#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
/*!
    \reimp
    \since 6.0
 */
bool QAbstractProxyModel::clearItemData(const QModelIndex &index)
{
    Q_D(QAbstractProxyModel);
    return d->model->clearItemData(mapToSource(index));
}
#endif

/*!
    \reimp
 */
QModelIndex QAbstractProxyModel::buddy(const QModelIndex &index) const
{
    Q_D(const QAbstractProxyModel);
    return mapFromSource(d->model->buddy(mapToSource(index)));
}

/*!
    \reimp
 */
bool QAbstractProxyModel::canFetchMore(const QModelIndex &parent) const
{
    Q_D(const QAbstractProxyModel);
    return d->model->canFetchMore(mapToSource(parent));
}

/*!
    \reimp
 */
void QAbstractProxyModel::fetchMore(const QModelIndex &parent)
{
    Q_D(QAbstractProxyModel);
    d->model->fetchMore(mapToSource(parent));
}

/*!
    \reimp
 */
void QAbstractProxyModel::sort(int column, Qt::SortOrder order)
{
    Q_D(QAbstractProxyModel);
    d->model->sort(column, order);
}

/*!
    \reimp
 */
QSize QAbstractProxyModel::span(const QModelIndex &index) const
{
    Q_D(const QAbstractProxyModel);
    return d->model->span(mapToSource(index));
}

/*!
    \reimp
 */
bool QAbstractProxyModel::hasChildren(const QModelIndex &parent) const
{
    Q_D(const QAbstractProxyModel);
    return d->model->hasChildren(mapToSource(parent));
}

/*!
    \reimp
 */
QModelIndex QAbstractProxyModel::sibling(int row, int column, const QModelIndex &idx) const
{
    return index(row, column, idx.parent());
}

/*!
    \reimp
 */
QMimeData* QAbstractProxyModel::mimeData(const QModelIndexList &indexes) const
{
    Q_D(const QAbstractProxyModel);
    QModelIndexList list;
    list.reserve(indexes.count());
    for (const QModelIndex &index : indexes)
        list << mapToSource(index);
    return d->model->mimeData(list);
}

void QAbstractProxyModelPrivate::mapDropCoordinatesToSource(int row, int column, const QModelIndex &parent,
                                                            int *sourceRow, int *sourceColumn, QModelIndex *sourceParent) const
{
    Q_Q(const QAbstractProxyModel);
    *sourceRow = -1;
    *sourceColumn = -1;
    if (row == -1 && column == -1) {
        *sourceParent = q->mapToSource(parent);
    } else if (row == q->rowCount(parent)) {
        *sourceParent = q->mapToSource(parent);
        *sourceRow = model->rowCount(*sourceParent);
    } else {
        QModelIndex proxyIndex = q->index(row, column, parent);
        QModelIndex sourceIndex = q->mapToSource(proxyIndex);
        *sourceRow = sourceIndex.row();
        *sourceColumn = sourceIndex.column();
        *sourceParent = sourceIndex.parent();
    }
}

/*!
    \reimp
    \since 5.4
 */
bool QAbstractProxyModel::canDropMimeData(const QMimeData *data, Qt::DropAction action,
                                          int row, int column, const QModelIndex &parent) const
{
    Q_D(const QAbstractProxyModel);
    int sourceDestinationRow;
    int sourceDestinationColumn;
    QModelIndex sourceParent;
    d->mapDropCoordinatesToSource(row, column, parent, &sourceDestinationRow, &sourceDestinationColumn, &sourceParent);
    return d->model->canDropMimeData(data, action, sourceDestinationRow, sourceDestinationColumn, sourceParent);
}

/*!
    \reimp
    \since 5.4
 */
bool QAbstractProxyModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
                                       int row, int column, const QModelIndex &parent)
{
    Q_D(QAbstractProxyModel);
    int sourceDestinationRow;
    int sourceDestinationColumn;
    QModelIndex sourceParent;
    d->mapDropCoordinatesToSource(row, column, parent, &sourceDestinationRow, &sourceDestinationColumn, &sourceParent);
    return d->model->dropMimeData(data, action, sourceDestinationRow, sourceDestinationColumn, sourceParent);
}

/*!
    \reimp
 */
QStringList QAbstractProxyModel::mimeTypes() const
{
    Q_D(const QAbstractProxyModel);
    return d->model->mimeTypes();
}

/*!
    \reimp
 */
Qt::DropActions QAbstractProxyModel::supportedDragActions() const
{
    Q_D(const QAbstractProxyModel);
    return d->model->supportedDragActions();
}

/*!
    \reimp
 */
Qt::DropActions QAbstractProxyModel::supportedDropActions() const
{
    Q_D(const QAbstractProxyModel);
    return d->model->supportedDropActions();
}

QT_END_NAMESPACE

#include "moc_qabstractproxymodel.cpp"
