Merge branch 'master' of git://scm.dev.nokia.troll.no/qt/qtbase-staging
* 'master' of git://scm.dev.nokia.troll.no/qt/qtbase-staging: Add the QIdentityProxyModel.
This commit is contained in:
commit
ca724e095b
@ -0,0 +1,66 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Klarälvdalens Datakonsult AB,
|
||||
** a KDAB Group company, info@kdab.com,
|
||||
** author Stephen Kelly <stephen.kelly@kdab.com>
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the QtGui module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||
** the names of its contributors may be used to endorse or promote
|
||||
** products derived from this software without specific prior written
|
||||
** permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
//! [0]
|
||||
class DateFormatProxyModel : public QIdentityProxyModel
|
||||
{
|
||||
// ...
|
||||
|
||||
void setDateFormatString(const QString &formatString)
|
||||
{
|
||||
m_formatString = formatString;
|
||||
}
|
||||
|
||||
QVariant data(const QModelIndex &index, int role)
|
||||
{
|
||||
if (role != Qt::DisplayRole)
|
||||
return QIdentityProxyModel::data(index, role);
|
||||
|
||||
const QDateTime dateTime = sourceModel()->data(SourceClass::DateRole).toDateTime();
|
||||
|
||||
return dateTime.toString(m_formatString);
|
||||
}
|
||||
|
||||
private:
|
||||
QString m_formatString;
|
||||
};
|
||||
//! [0]
|
@ -162,6 +162,7 @@ class Q_CORE_EXPORT QAbstractItemModel : public QObject
|
||||
|
||||
friend class QPersistentModelIndexData;
|
||||
friend class QAbstractItemViewPrivate;
|
||||
friend class QIdentityProxyModel;
|
||||
public:
|
||||
|
||||
explicit QAbstractItemModel(QObject *parent = 0);
|
||||
|
@ -4,6 +4,7 @@ HEADERS += \
|
||||
itemviews/qabstractitemview.h \
|
||||
itemviews/qabstractitemview_p.h \
|
||||
itemviews/qheaderview.h \
|
||||
itemviews/qidentityproxymodel.h \
|
||||
itemviews/qlistview.h \
|
||||
itemviews/qlistview_p.h \
|
||||
itemviews/qbsptree_p.h \
|
||||
@ -44,6 +45,7 @@ HEADERS += \
|
||||
SOURCES += \
|
||||
itemviews/qabstractitemview.cpp \
|
||||
itemviews/qheaderview.cpp \
|
||||
itemviews/qidentityproxymodel.cpp \
|
||||
itemviews/qlistview.cpp \
|
||||
itemviews/qbsptree.cpp \
|
||||
itemviews/qtableview.cpp \
|
||||
|
582
src/gui/itemviews/qidentityproxymodel.cpp
Normal file
582
src/gui/itemviews/qidentityproxymodel.cpp
Normal file
@ -0,0 +1,582 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Klarälvdalens Datakonsult AB,
|
||||
** a KDAB Group company, info@kdab.com,
|
||||
** author Stephen Kelly <stephen.kelly@kdab.com>
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (info@qt.nokia.com)
|
||||
**
|
||||
** This file is part of the QtGui module of the Qt Toolkit.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qidentityproxymodel.h"
|
||||
|
||||
#ifndef QT_NO_IDENTITYPROXYMODEL
|
||||
|
||||
#include "qitemselectionmodel.h"
|
||||
#include <private/qabstractproxymodel_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QIdentityProxyModelPrivate : public QAbstractProxyModelPrivate
|
||||
{
|
||||
QIdentityProxyModelPrivate()
|
||||
: ignoreNextLayoutAboutToBeChanged(false),
|
||||
ignoreNextLayoutChanged(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Q_DECLARE_PUBLIC(QIdentityProxyModel)
|
||||
|
||||
bool ignoreNextLayoutAboutToBeChanged;
|
||||
bool ignoreNextLayoutChanged;
|
||||
QList<QPersistentModelIndex> layoutChangePersistentIndexes;
|
||||
QModelIndexList proxyIndexes;
|
||||
|
||||
void _q_sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end);
|
||||
void _q_sourceRowsInserted(const QModelIndex &parent, int start, int end);
|
||||
void _q_sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
|
||||
void _q_sourceRowsRemoved(const QModelIndex &parent, int start, int end);
|
||||
void _q_sourceRowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest);
|
||||
void _q_sourceRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest);
|
||||
|
||||
void _q_sourceColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end);
|
||||
void _q_sourceColumnsInserted(const QModelIndex &parent, int start, int end);
|
||||
void _q_sourceColumnsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
|
||||
void _q_sourceColumnsRemoved(const QModelIndex &parent, int start, int end);
|
||||
void _q_sourceColumnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest);
|
||||
void _q_sourceColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest);
|
||||
|
||||
void _q_sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
|
||||
void _q_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last);
|
||||
|
||||
void _q_sourceLayoutAboutToBeChanged();
|
||||
void _q_sourceLayoutChanged();
|
||||
void _q_sourceModelAboutToBeReset();
|
||||
void _q_sourceModelReset();
|
||||
|
||||
};
|
||||
|
||||
/*!
|
||||
\since 4.8
|
||||
\class QIdentityProxyModel
|
||||
\brief The QIdentityProxyModel class proxies its source model unmodified
|
||||
|
||||
\ingroup model-view
|
||||
|
||||
QIdentityProxyModel can be used to forward the structure of a source model exactly, with no sorting, filtering or other transformation.
|
||||
This is similar in concept to an identity matrix where A.I = A.
|
||||
|
||||
Because it does no sorting or filtering, this class is most suitable to proxy models which transform the data() of the source model.
|
||||
For example, a proxy model could be created to define the font used, or the background colour, or the tooltip etc. This removes the
|
||||
need to implement all data handling in the same class that creates the structure of the model, and can also be used to create
|
||||
re-usable components.
|
||||
|
||||
This also provides a way to change the data in the case where a source model is supplied by a third party which can not be modified.
|
||||
|
||||
\snippet doc/src/snippets/code/src_gui_itemviews_qidentityproxymodel.cpp 0
|
||||
|
||||
\sa QAbstractProxyModel, {Model/View Programming}, QAbstractItemModel
|
||||
|
||||
*/
|
||||
|
||||
/*!
|
||||
Constructs an identity model with the given \a parent.
|
||||
*/
|
||||
QIdentityProxyModel::QIdentityProxyModel(QObject* parent)
|
||||
: QAbstractProxyModel(*new QIdentityProxyModelPrivate, parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*! \internal
|
||||
*/
|
||||
QIdentityProxyModel::QIdentityProxyModel(QIdentityProxyModelPrivate &dd, QObject* parent)
|
||||
: QAbstractProxyModel(dd, parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*!
|
||||
Destroys this identity model.
|
||||
*/
|
||||
QIdentityProxyModel::~QIdentityProxyModel()
|
||||
{
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
int QIdentityProxyModel::columnCount(const QModelIndex& parent) const
|
||||
{
|
||||
Q_ASSERT(parent.isValid() ? parent.model() == this : true);
|
||||
Q_D(const QIdentityProxyModel);
|
||||
return d->model->columnCount(mapToSource(parent));
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
bool QIdentityProxyModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent)
|
||||
{
|
||||
Q_ASSERT(parent.isValid() ? parent.model() == this : true);
|
||||
Q_D(QIdentityProxyModel);
|
||||
return d->model->dropMimeData(data, action, row, column, mapToSource(parent));
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
QModelIndex QIdentityProxyModel::index(int row, int column, const QModelIndex& parent) const
|
||||
{
|
||||
Q_ASSERT(parent.isValid() ? parent.model() == this : true);
|
||||
Q_D(const QIdentityProxyModel);
|
||||
if (!hasIndex(row, column, parent))
|
||||
return QModelIndex();
|
||||
const QModelIndex sourceParent = mapToSource(parent);
|
||||
const QModelIndex sourceIndex = d->model->index(row, column, sourceParent);
|
||||
Q_ASSERT(sourceIndex.isValid());
|
||||
return mapFromSource(sourceIndex);
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
bool QIdentityProxyModel::insertColumns(int column, int count, const QModelIndex& parent)
|
||||
{
|
||||
Q_ASSERT(parent.isValid() ? parent.model() == this : true);
|
||||
Q_D(QIdentityProxyModel);
|
||||
return d->model->insertColumns(column, count, mapToSource(parent));
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
bool QIdentityProxyModel::insertRows(int row, int count, const QModelIndex& parent)
|
||||
{
|
||||
Q_ASSERT(parent.isValid() ? parent.model() == this : true);
|
||||
Q_D(QIdentityProxyModel);
|
||||
return d->model->insertRows(row, count, mapToSource(parent));
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
QModelIndex QIdentityProxyModel::mapFromSource(const QModelIndex& sourceIndex) const
|
||||
{
|
||||
Q_D(const QIdentityProxyModel);
|
||||
if (!d->model || !sourceIndex.isValid())
|
||||
return QModelIndex();
|
||||
|
||||
Q_ASSERT(sourceIndex.model() == d->model);
|
||||
return createIndex(sourceIndex.row(), sourceIndex.column(), sourceIndex.internalPointer());
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
QItemSelection QIdentityProxyModel::mapSelectionFromSource(const QItemSelection& selection) const
|
||||
{
|
||||
Q_D(const QIdentityProxyModel);
|
||||
QItemSelection proxySelection;
|
||||
|
||||
if (!d->model)
|
||||
return proxySelection;
|
||||
|
||||
QItemSelection::const_iterator it = selection.constBegin();
|
||||
const QItemSelection::const_iterator end = selection.constEnd();
|
||||
for ( ; it != end; ++it) {
|
||||
Q_ASSERT(it->model() == d->model);
|
||||
const QItemSelectionRange range(mapFromSource(it->topLeft()), mapFromSource(it->bottomRight()));
|
||||
proxySelection.append(range);
|
||||
}
|
||||
|
||||
return proxySelection;
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
QItemSelection QIdentityProxyModel::mapSelectionToSource(const QItemSelection& selection) const
|
||||
{
|
||||
Q_D(const QIdentityProxyModel);
|
||||
QItemSelection sourceSelection;
|
||||
|
||||
if (!d->model)
|
||||
return sourceSelection;
|
||||
|
||||
QItemSelection::const_iterator it = selection.constBegin();
|
||||
const QItemSelection::const_iterator end = selection.constEnd();
|
||||
for ( ; it != end; ++it) {
|
||||
Q_ASSERT(it->model() == this);
|
||||
const QItemSelectionRange range(mapToSource(it->topLeft()), mapToSource(it->bottomRight()));
|
||||
sourceSelection.append(range);
|
||||
}
|
||||
|
||||
return sourceSelection;
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
QModelIndex QIdentityProxyModel::mapToSource(const QModelIndex& proxyIndex) const
|
||||
{
|
||||
Q_D(const QIdentityProxyModel);
|
||||
if (!d->model || !proxyIndex.isValid())
|
||||
return QModelIndex();
|
||||
Q_ASSERT(proxyIndex.model() == this);
|
||||
return d->model->createIndex(proxyIndex.row(), proxyIndex.column(), proxyIndex.internalPointer());
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
QModelIndexList QIdentityProxyModel::match(const QModelIndex& start, int role, const QVariant& value, int hits, Qt::MatchFlags flags) const
|
||||
{
|
||||
Q_D(const QIdentityProxyModel);
|
||||
Q_ASSERT(start.isValid() ? start.model() == this : true);
|
||||
if (!d->model)
|
||||
return QModelIndexList();
|
||||
|
||||
const QModelIndexList sourceList = d->model->match(mapToSource(start), role, value, hits, flags);
|
||||
QModelIndexList::const_iterator it = sourceList.constBegin();
|
||||
const QModelIndexList::const_iterator end = sourceList.constEnd();
|
||||
QModelIndexList proxyList;
|
||||
for ( ; it != end; ++it)
|
||||
proxyList.append(mapFromSource(*it));
|
||||
return proxyList;
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
QModelIndex QIdentityProxyModel::parent(const QModelIndex& child) const
|
||||
{
|
||||
Q_ASSERT(child.isValid() ? child.model() == this : true);
|
||||
const QModelIndex sourceIndex = mapToSource(child);
|
||||
const QModelIndex sourceParent = sourceIndex.parent();
|
||||
return mapFromSource(sourceParent);
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
bool QIdentityProxyModel::removeColumns(int column, int count, const QModelIndex& parent)
|
||||
{
|
||||
Q_ASSERT(parent.isValid() ? parent.model() == this : true);
|
||||
Q_D(QIdentityProxyModel);
|
||||
return d->model->removeColumns(column, count, mapToSource(parent));
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
bool QIdentityProxyModel::removeRows(int row, int count, const QModelIndex& parent)
|
||||
{
|
||||
Q_ASSERT(parent.isValid() ? parent.model() == this : true);
|
||||
Q_D(QIdentityProxyModel);
|
||||
return d->model->removeRows(row, count, mapToSource(parent));
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
int QIdentityProxyModel::rowCount(const QModelIndex& parent) const
|
||||
{
|
||||
Q_ASSERT(parent.isValid() ? parent.model() == this : true);
|
||||
Q_D(const QIdentityProxyModel);
|
||||
return d->model->rowCount(mapToSource(parent));
|
||||
}
|
||||
|
||||
/*!
|
||||
\reimp
|
||||
*/
|
||||
void QIdentityProxyModel::setSourceModel(QAbstractItemModel* sourceModel)
|
||||
{
|
||||
beginResetModel();
|
||||
|
||||
if (sourceModel) {
|
||||
disconnect(sourceModel, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)),
|
||||
this, SLOT(_q_sourceRowsAboutToBeInserted(const QModelIndex &, int, int)));
|
||||
disconnect(sourceModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
|
||||
this, SLOT(_q_sourceRowsInserted(const QModelIndex &, int, int)));
|
||||
disconnect(sourceModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)),
|
||||
this, SLOT(_q_sourceRowsAboutToBeRemoved(const QModelIndex &, int, int)));
|
||||
disconnect(sourceModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
|
||||
this, SLOT(_q_sourceRowsRemoved(const QModelIndex &, int, int)));
|
||||
disconnect(sourceModel, SIGNAL(rowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)),
|
||||
this, SLOT(_q_sourceRowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)));
|
||||
disconnect(sourceModel, SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)),
|
||||
this, SLOT(_q_sourceRowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)));
|
||||
disconnect(sourceModel, SIGNAL(columnsAboutToBeInserted(const QModelIndex &, int, int)),
|
||||
this, SLOT(_q_sourceColumnsAboutToBeInserted(const QModelIndex &, int, int)));
|
||||
disconnect(sourceModel, SIGNAL(columnsInserted(const QModelIndex &, int, int)),
|
||||
this, SLOT(_q_sourceColumnsInserted(const QModelIndex &, int, int)));
|
||||
disconnect(sourceModel, SIGNAL(columnsAboutToBeRemoved(const QModelIndex &, int, int)),
|
||||
this, SLOT(_q_sourceColumnsAboutToBeRemoved(const QModelIndex &, int, int)));
|
||||
disconnect(sourceModel, SIGNAL(columnsRemoved(const QModelIndex &, int, int)),
|
||||
this, SLOT(_q_sourceColumnsRemoved(const QModelIndex &, int, int)));
|
||||
disconnect(sourceModel, SIGNAL(columnsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)),
|
||||
this, SLOT(_q_sourceColumnsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)));
|
||||
disconnect(sourceModel, SIGNAL(columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int)),
|
||||
this, SLOT(_q_sourceColumnsMoved(const QModelIndex &, int, int, const QModelIndex &, int)));
|
||||
disconnect(sourceModel, SIGNAL(modelAboutToBeReset()),
|
||||
this, SLOT(_q_sourceModelAboutToBeReset()));
|
||||
disconnect(sourceModel, SIGNAL(modelReset()),
|
||||
this, SLOT(_q_sourceModelReset()));
|
||||
disconnect(sourceModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),
|
||||
this, SLOT(_q_sourceDataChanged(const QModelIndex &, const QModelIndex &)));
|
||||
disconnect(sourceModel, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
|
||||
this, SLOT(_q_sourceHeaderDataChanged(Qt::Orientation,int,int)));
|
||||
disconnect(sourceModel, SIGNAL(layoutAboutToBeChanged()),
|
||||
this, SLOT(_q_sourceLayoutAboutToBeChanged()));
|
||||
disconnect(sourceModel, SIGNAL(layoutChanged()),
|
||||
this, SLOT(_q_sourceLayoutChanged()));
|
||||
}
|
||||
|
||||
QAbstractProxyModel::setSourceModel(sourceModel);
|
||||
|
||||
if (sourceModel) {
|
||||
connect(sourceModel, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)),
|
||||
SLOT(_q_sourceRowsAboutToBeInserted(const QModelIndex &, int, int)));
|
||||
connect(sourceModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)),
|
||||
SLOT(_q_sourceRowsInserted(const QModelIndex &, int, int)));
|
||||
connect(sourceModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)),
|
||||
SLOT(_q_sourceRowsAboutToBeRemoved(const QModelIndex &, int, int)));
|
||||
connect(sourceModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)),
|
||||
SLOT(_q_sourceRowsRemoved(const QModelIndex &, int, int)));
|
||||
connect(sourceModel, SIGNAL(rowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)),
|
||||
SLOT(_q_sourceRowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)));
|
||||
connect(sourceModel, SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)),
|
||||
SLOT(_q_sourceRowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)));
|
||||
connect(sourceModel, SIGNAL(columnsAboutToBeInserted(const QModelIndex &, int, int)),
|
||||
SLOT(_q_sourceColumnsAboutToBeInserted(const QModelIndex &, int, int)));
|
||||
connect(sourceModel, SIGNAL(columnsInserted(const QModelIndex &, int, int)),
|
||||
SLOT(_q_sourceColumnsInserted(const QModelIndex &, int, int)));
|
||||
connect(sourceModel, SIGNAL(columnsAboutToBeRemoved(const QModelIndex &, int, int)),
|
||||
SLOT(_q_sourceColumnsAboutToBeRemoved(const QModelIndex &, int, int)));
|
||||
connect(sourceModel, SIGNAL(columnsRemoved(const QModelIndex &, int, int)),
|
||||
SLOT(_q_sourceColumnsRemoved(const QModelIndex &, int, int)));
|
||||
connect(sourceModel, SIGNAL(columnsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)),
|
||||
SLOT(_q_sourceColumnsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)));
|
||||
connect(sourceModel, SIGNAL(columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int)),
|
||||
SLOT(_q_sourceColumnsMoved(const QModelIndex &, int, int, const QModelIndex &, int)));
|
||||
connect(sourceModel, SIGNAL(modelAboutToBeReset()),
|
||||
SLOT(_q_sourceModelAboutToBeReset()));
|
||||
connect(sourceModel, SIGNAL(modelReset()),
|
||||
SLOT(_q_sourceModelReset()));
|
||||
connect(sourceModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)),
|
||||
SLOT(_q_sourceDataChanged(const QModelIndex &, const QModelIndex &)));
|
||||
connect(sourceModel, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
|
||||
SLOT(_q_sourceHeaderDataChanged(Qt::Orientation,int,int)));
|
||||
connect(sourceModel, SIGNAL(layoutAboutToBeChanged()),
|
||||
SLOT(_q_sourceLayoutAboutToBeChanged()));
|
||||
connect(sourceModel, SIGNAL(layoutChanged()),
|
||||
SLOT(_q_sourceLayoutChanged()));
|
||||
}
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void QIdentityProxyModelPrivate::_q_sourceColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end)
|
||||
{
|
||||
Q_ASSERT(parent.isValid() ? parent.model() == model : true);
|
||||
Q_Q(QIdentityProxyModel);
|
||||
q->beginInsertColumns(q->mapFromSource(parent), start, end);
|
||||
}
|
||||
|
||||
void QIdentityProxyModelPrivate::_q_sourceColumnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest)
|
||||
{
|
||||
Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true);
|
||||
Q_ASSERT(destParent.isValid() ? destParent.model() == model : true);
|
||||
Q_Q(QIdentityProxyModel);
|
||||
q->beginMoveColumns(q->mapFromSource(sourceParent), sourceStart, sourceEnd, q->mapFromSource(destParent), dest);
|
||||
}
|
||||
|
||||
void QIdentityProxyModelPrivate::_q_sourceColumnsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
|
||||
{
|
||||
Q_ASSERT(parent.isValid() ? parent.model() == model : true);
|
||||
Q_Q(QIdentityProxyModel);
|
||||
q->beginRemoveColumns(q->mapFromSource(parent), start, end);
|
||||
}
|
||||
|
||||
void QIdentityProxyModelPrivate::_q_sourceColumnsInserted(const QModelIndex &parent, int start, int end)
|
||||
{
|
||||
Q_ASSERT(parent.isValid() ? parent.model() == model : true);
|
||||
Q_Q(QIdentityProxyModel);
|
||||
Q_UNUSED(parent)
|
||||
Q_UNUSED(start)
|
||||
Q_UNUSED(end)
|
||||
q->endInsertColumns();
|
||||
}
|
||||
|
||||
void QIdentityProxyModelPrivate::_q_sourceColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest)
|
||||
{
|
||||
Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true);
|
||||
Q_ASSERT(destParent.isValid() ? destParent.model() == model : true);
|
||||
Q_Q(QIdentityProxyModel);
|
||||
Q_UNUSED(sourceParent)
|
||||
Q_UNUSED(sourceStart)
|
||||
Q_UNUSED(sourceEnd)
|
||||
Q_UNUSED(destParent)
|
||||
Q_UNUSED(dest)
|
||||
q->endMoveColumns();
|
||||
}
|
||||
|
||||
void QIdentityProxyModelPrivate::_q_sourceColumnsRemoved(const QModelIndex &parent, int start, int end)
|
||||
{
|
||||
Q_ASSERT(parent.isValid() ? parent.model() == model : true);
|
||||
Q_Q(QIdentityProxyModel);
|
||||
Q_UNUSED(parent)
|
||||
Q_UNUSED(start)
|
||||
Q_UNUSED(end)
|
||||
q->endRemoveColumns();
|
||||
}
|
||||
|
||||
void QIdentityProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
|
||||
{
|
||||
Q_ASSERT(topLeft.isValid() ? topLeft.model() == model : true);
|
||||
Q_ASSERT(bottomRight.isValid() ? bottomRight.model() == model : true);
|
||||
Q_Q(QIdentityProxyModel);
|
||||
q->dataChanged(q->mapFromSource(topLeft), q->mapFromSource(bottomRight));
|
||||
}
|
||||
|
||||
void QIdentityProxyModelPrivate::_q_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last)
|
||||
{
|
||||
Q_Q(QIdentityProxyModel);
|
||||
q->headerDataChanged(orientation, first, last);
|
||||
}
|
||||
|
||||
void QIdentityProxyModelPrivate::_q_sourceLayoutAboutToBeChanged()
|
||||
{
|
||||
if (ignoreNextLayoutAboutToBeChanged)
|
||||
return;
|
||||
|
||||
Q_Q(QIdentityProxyModel);
|
||||
|
||||
foreach(const QPersistentModelIndex &proxyPersistentIndex, q->persistentIndexList()) {
|
||||
proxyIndexes << proxyPersistentIndex;
|
||||
Q_ASSERT(proxyPersistentIndex.isValid());
|
||||
const QPersistentModelIndex srcPersistentIndex = q->mapToSource(proxyPersistentIndex);
|
||||
Q_ASSERT(srcPersistentIndex.isValid());
|
||||
layoutChangePersistentIndexes << srcPersistentIndex;
|
||||
}
|
||||
|
||||
q->layoutAboutToBeChanged();
|
||||
}
|
||||
|
||||
void QIdentityProxyModelPrivate::_q_sourceLayoutChanged()
|
||||
{
|
||||
if (ignoreNextLayoutChanged)
|
||||
return;
|
||||
|
||||
Q_Q(QIdentityProxyModel);
|
||||
|
||||
for (int i = 0; i < proxyIndexes.size(); ++i) {
|
||||
q->changePersistentIndex(proxyIndexes.at(i), q->mapFromSource(layoutChangePersistentIndexes.at(i)));
|
||||
}
|
||||
|
||||
layoutChangePersistentIndexes.clear();
|
||||
proxyIndexes.clear();
|
||||
|
||||
q->layoutChanged();
|
||||
}
|
||||
|
||||
void QIdentityProxyModelPrivate::_q_sourceModelAboutToBeReset()
|
||||
{
|
||||
Q_Q(QIdentityProxyModel);
|
||||
q->beginResetModel();
|
||||
}
|
||||
|
||||
void QIdentityProxyModelPrivate::_q_sourceModelReset()
|
||||
{
|
||||
Q_Q(QIdentityProxyModel);
|
||||
q->endResetModel();
|
||||
}
|
||||
|
||||
void QIdentityProxyModelPrivate::_q_sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end)
|
||||
{
|
||||
Q_ASSERT(parent.isValid() ? parent.model() == model : true);
|
||||
Q_Q(QIdentityProxyModel);
|
||||
q->beginInsertRows(q->mapFromSource(parent), start, end);
|
||||
}
|
||||
|
||||
void QIdentityProxyModelPrivate::_q_sourceRowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest)
|
||||
{
|
||||
Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true);
|
||||
Q_ASSERT(destParent.isValid() ? destParent.model() == model : true);
|
||||
Q_Q(QIdentityProxyModel);
|
||||
q->beginMoveRows(q->mapFromSource(sourceParent), sourceStart, sourceEnd, q->mapFromSource(destParent), dest);
|
||||
}
|
||||
|
||||
void QIdentityProxyModelPrivate::_q_sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
|
||||
{
|
||||
Q_ASSERT(parent.isValid() ? parent.model() == model : true);
|
||||
Q_Q(QIdentityProxyModel);
|
||||
q->beginRemoveRows(q->mapFromSource(parent), start, end);
|
||||
}
|
||||
|
||||
void QIdentityProxyModelPrivate::_q_sourceRowsInserted(const QModelIndex &parent, int start, int end)
|
||||
{
|
||||
Q_ASSERT(parent.isValid() ? parent.model() == model : true);
|
||||
Q_Q(QIdentityProxyModel);
|
||||
Q_UNUSED(parent)
|
||||
Q_UNUSED(start)
|
||||
Q_UNUSED(end)
|
||||
q->endInsertRows();
|
||||
}
|
||||
|
||||
void QIdentityProxyModelPrivate::_q_sourceRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest)
|
||||
{
|
||||
Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true);
|
||||
Q_ASSERT(destParent.isValid() ? destParent.model() == model : true);
|
||||
Q_Q(QIdentityProxyModel);
|
||||
Q_UNUSED(sourceParent)
|
||||
Q_UNUSED(sourceStart)
|
||||
Q_UNUSED(sourceEnd)
|
||||
Q_UNUSED(destParent)
|
||||
Q_UNUSED(dest)
|
||||
q->endMoveRows();
|
||||
}
|
||||
|
||||
void QIdentityProxyModelPrivate::_q_sourceRowsRemoved(const QModelIndex &parent, int start, int end)
|
||||
{
|
||||
Q_ASSERT(parent.isValid() ? parent.model() == model : true);
|
||||
Q_Q(QIdentityProxyModel);
|
||||
Q_UNUSED(parent)
|
||||
Q_UNUSED(start)
|
||||
Q_UNUSED(end)
|
||||
q->endRemoveRows();
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#include "moc_qidentityproxymodel.cpp"
|
||||
|
||||
#endif // QT_NO_IDENTITYPROXYMODEL
|
115
src/gui/itemviews/qidentityproxymodel.h
Normal file
115
src/gui/itemviews/qidentityproxymodel.h
Normal file
@ -0,0 +1,115 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Klarälvdalens Datakonsult AB,
|
||||
** a KDAB Group company, info@kdab.com,
|
||||
** author Stephen Kelly <stephen.kelly@kdab.com>
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (info@qt.nokia.com)
|
||||
**
|
||||
** This file is part of the QtGui module of the Qt Toolkit.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef QIDENTITYPROXYMODEL_H
|
||||
#define QIDENTITYPROXYMODEL_H
|
||||
|
||||
#include <QtGui/qabstractproxymodel.h>
|
||||
|
||||
#ifndef QT_NO_IDENTITYPROXYMODEL
|
||||
|
||||
QT_BEGIN_HEADER
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QT_MODULE(Gui)
|
||||
|
||||
class QIdentityProxyModelPrivate;
|
||||
|
||||
class Q_GUI_EXPORT QIdentityProxyModel : public QAbstractProxyModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QIdentityProxyModel(QObject* parent = 0);
|
||||
~QIdentityProxyModel();
|
||||
|
||||
int columnCount(const QModelIndex& parent = QModelIndex()) const;
|
||||
QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const;
|
||||
QModelIndex mapFromSource(const QModelIndex& sourceIndex) const;
|
||||
QModelIndex mapToSource(const QModelIndex& proxyIndex) const;
|
||||
QModelIndex parent(const QModelIndex& child) const;
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const;
|
||||
bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent);
|
||||
|
||||
QItemSelection mapSelectionFromSource(const QItemSelection& selection) const;
|
||||
QItemSelection mapSelectionToSource(const QItemSelection& selection) const;
|
||||
QModelIndexList match(const QModelIndex& start, int role, const QVariant& value, int hits = 1, Qt::MatchFlags flags = Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap)) const;
|
||||
void setSourceModel(QAbstractItemModel* sourceModel);
|
||||
|
||||
bool insertColumns(int column, int count, const QModelIndex& parent = QModelIndex());
|
||||
bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex());
|
||||
bool removeColumns(int column, int count, const QModelIndex& parent = QModelIndex());
|
||||
bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex());
|
||||
|
||||
protected:
|
||||
QIdentityProxyModel(QIdentityProxyModelPrivate &dd, QObject* parent);
|
||||
|
||||
private:
|
||||
Q_DECLARE_PRIVATE(QIdentityProxyModel)
|
||||
Q_DISABLE_COPY(QIdentityProxyModel)
|
||||
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeInserted(QModelIndex,int,int))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsInserted(QModelIndex,int,int))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeRemoved(QModelIndex,int,int))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsRemoved(QModelIndex,int,int))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsMoved(QModelIndex,int,int,QModelIndex,int))
|
||||
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeInserted(QModelIndex,int,int))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsInserted(QModelIndex,int,int))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeRemoved(QModelIndex,int,int))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsRemoved(QModelIndex,int,int))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsMoved(QModelIndex,int,int,QModelIndex,int))
|
||||
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceDataChanged(QModelIndex,QModelIndex))
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last))
|
||||
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutAboutToBeChanged())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutChanged())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceModelAboutToBeReset())
|
||||
Q_PRIVATE_SLOT(d_func(), void _q_sourceModelReset())
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_END_HEADER
|
||||
|
||||
#endif // QT_NO_IDENTITYPROXYMODEL
|
||||
|
||||
#endif // QIDENTITYPROXYMODEL_H
|
||||
|
@ -1502,7 +1502,7 @@ void QSortFilterProxyModelPrivate::_q_sourceColumnsRemoved(
|
||||
\l{Model Subclassing Reference}.
|
||||
|
||||
\sa QAbstractProxyModel, QAbstractItemModel, {Model/View Programming},
|
||||
{Basic Sort/Filter Model Example}, {Custom Sort/Filter Model Example}
|
||||
{Basic Sort/Filter Model Example}, {Custom Sort/Filter Model Example}, QIdentityProxyModel
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
@ -84,6 +84,7 @@ SUBDIRS=\
|
||||
qheaderview \
|
||||
qicoimageformat \
|
||||
qicon \
|
||||
qidentityproxymodel \
|
||||
qimageiohandler \
|
||||
qimagereader \
|
||||
qimagewriter \
|
||||
|
6
tests/auto/qidentityproxymodel/qidentityproxymodel.pro
Normal file
6
tests/auto/qidentityproxymodel/qidentityproxymodel.pro
Normal file
@ -0,0 +1,6 @@
|
||||
load(qttest_p4)
|
||||
|
||||
INCLUDEPATH += $$PWD/../modeltest
|
||||
|
||||
SOURCES += tst_qidentityproxymodel.cpp ../modeltest/dynamictreemodel.cpp ../modeltest/modeltest.cpp
|
||||
HEADERS += ../modeltest/dynamictreemodel.h ../modeltest/modeltest.h
|
329
tests/auto/qidentityproxymodel/tst_qidentityproxymodel.cpp
Normal file
329
tests/auto/qidentityproxymodel/tst_qidentityproxymodel.cpp
Normal file
@ -0,0 +1,329 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Klarälvdalens Datakonsult AB,
|
||||
** a KDAB Group company, info@kdab.com,
|
||||
** author Stephen Kelly <stephen.kelly@kdab.com>
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (info@qt.nokia.com)
|
||||
**
|
||||
** This file is part of the QtGui module of the Qt Toolkit.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Nokia gives you certain additional
|
||||
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU General
|
||||
** Public License version 3.0 as published by the Free Software Foundation
|
||||
** and appearing in the file LICENSE.GPL included in the packaging of this
|
||||
** file. Please review the following information to ensure the GNU General
|
||||
** Public License version 3.0 requirements will be met:
|
||||
** http://www.gnu.org/copyleft/gpl.html.
|
||||
**
|
||||
** Other Usage
|
||||
** Alternatively, this file may be used in accordance with the terms and
|
||||
** conditions contained in a signed written agreement between you and Nokia.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
#include "../../shared/util.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtGui>
|
||||
|
||||
#include "dynamictreemodel.h"
|
||||
#include "qidentityproxymodel.h"
|
||||
|
||||
//TESTED CLASS=
|
||||
//TESTED_FILES=
|
||||
|
||||
Q_DECLARE_METATYPE(QModelIndex)
|
||||
|
||||
class tst_QIdentityProxyModel : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
tst_QIdentityProxyModel();
|
||||
virtual ~tst_QIdentityProxyModel();
|
||||
|
||||
public slots:
|
||||
void initTestCase();
|
||||
void cleanupTestCase();
|
||||
void init();
|
||||
void cleanup();
|
||||
|
||||
private slots:
|
||||
void insertRows();
|
||||
void removeRows();
|
||||
void moveRows();
|
||||
void reset();
|
||||
|
||||
protected:
|
||||
void verifyIdentity(QAbstractItemModel *model, const QModelIndex &parent = QModelIndex());
|
||||
|
||||
private:
|
||||
QStandardItemModel *m_model;
|
||||
QIdentityProxyModel *m_proxy;
|
||||
};
|
||||
|
||||
tst_QIdentityProxyModel::tst_QIdentityProxyModel()
|
||||
: m_model(0), m_proxy(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
tst_QIdentityProxyModel::~tst_QIdentityProxyModel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void tst_QIdentityProxyModel::initTestCase()
|
||||
{
|
||||
qRegisterMetaType<QModelIndex>("QModelIndex");
|
||||
|
||||
m_model = new QStandardItemModel(0, 1);
|
||||
m_proxy = new QIdentityProxyModel();
|
||||
}
|
||||
|
||||
void tst_QIdentityProxyModel::cleanupTestCase()
|
||||
{
|
||||
delete m_proxy;
|
||||
delete m_model;
|
||||
}
|
||||
|
||||
void tst_QIdentityProxyModel::init()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QIdentityProxyModel::cleanup()
|
||||
{
|
||||
m_model->clear();
|
||||
m_model->insertColumns(0, 1);
|
||||
}
|
||||
|
||||
void tst_QIdentityProxyModel::verifyIdentity(QAbstractItemModel *model, const QModelIndex &parent)
|
||||
{
|
||||
const int rows = model->rowCount(parent);
|
||||
const int columns = model->columnCount(parent);
|
||||
const QModelIndex proxyParent = m_proxy->mapFromSource(parent);
|
||||
|
||||
QVERIFY(m_proxy->mapToSource(proxyParent) == parent);
|
||||
QVERIFY(rows == m_proxy->rowCount(proxyParent));
|
||||
QVERIFY(columns == m_proxy->columnCount(proxyParent));
|
||||
|
||||
for (int row = 0; row < rows; ++row) {
|
||||
for (int column = 0; column < columns; ++column) {
|
||||
const QModelIndex idx = model->index(row, column, parent);
|
||||
const QModelIndex proxyIdx = m_proxy->mapFromSource(idx);
|
||||
QVERIFY(proxyIdx.model() == m_proxy);
|
||||
QVERIFY(m_proxy->mapToSource(proxyIdx) == idx);
|
||||
QVERIFY(proxyIdx.isValid());
|
||||
QVERIFY(proxyIdx.row() == row);
|
||||
QVERIFY(proxyIdx.column() == column);
|
||||
QVERIFY(proxyIdx.parent() == proxyParent);
|
||||
QVERIFY(proxyIdx.data() == idx.data());
|
||||
QVERIFY(proxyIdx.flags() == idx.flags());
|
||||
const int childCount = m_proxy->rowCount(proxyIdx);
|
||||
const bool hasChildren = m_proxy->hasChildren(proxyIdx);
|
||||
QVERIFY(model->hasChildren(idx) == hasChildren);
|
||||
QVERIFY((childCount > 0) == hasChildren);
|
||||
|
||||
if (hasChildren)
|
||||
verifyIdentity(model, idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
tests
|
||||
*/
|
||||
|
||||
void tst_QIdentityProxyModel::insertRows()
|
||||
{
|
||||
QStandardItem *parentItem = m_model->invisibleRootItem();
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
QStandardItem *item = new QStandardItem(QString("item %0").arg(i));
|
||||
parentItem->appendRow(item);
|
||||
parentItem = item;
|
||||
}
|
||||
|
||||
m_proxy->setSourceModel(m_model);
|
||||
|
||||
verifyIdentity(m_model);
|
||||
|
||||
QSignalSpy modelBeforeSpy(m_model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
|
||||
QSignalSpy modelAfterSpy(m_model, SIGNAL(rowsInserted(QModelIndex,int,int)));
|
||||
QSignalSpy proxyBeforeSpy(m_proxy, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
|
||||
QSignalSpy proxyAfterSpy(m_proxy, SIGNAL(rowsInserted(QModelIndex,int,int)));
|
||||
|
||||
QStandardItem *item = new QStandardItem(QString("new item"));
|
||||
parentItem->appendRow(item);
|
||||
|
||||
QVERIFY(modelBeforeSpy.size() == 1 && 1 == proxyBeforeSpy.size());
|
||||
QVERIFY(modelAfterSpy.size() == 1 && 1 == proxyAfterSpy.size());
|
||||
|
||||
QVERIFY(modelBeforeSpy.first().first().value<QModelIndex>() == m_proxy->mapToSource(proxyBeforeSpy.first().first().value<QModelIndex>()));
|
||||
QVERIFY(modelBeforeSpy.first().at(1) == proxyBeforeSpy.first().at(1));
|
||||
QVERIFY(modelBeforeSpy.first().at(2) == proxyBeforeSpy.first().at(2));
|
||||
|
||||
QVERIFY(modelAfterSpy.first().first().value<QModelIndex>() == m_proxy->mapToSource(proxyAfterSpy.first().first().value<QModelIndex>()));
|
||||
QVERIFY(modelAfterSpy.first().at(1) == proxyAfterSpy.first().at(1));
|
||||
QVERIFY(modelAfterSpy.first().at(2) == proxyAfterSpy.first().at(2));
|
||||
|
||||
verifyIdentity(m_model);
|
||||
|
||||
}
|
||||
|
||||
void tst_QIdentityProxyModel::removeRows()
|
||||
{
|
||||
QStandardItem *parentItem = m_model->invisibleRootItem();
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
QStandardItem *item = new QStandardItem(QString("item %0").arg(i));
|
||||
parentItem->appendRow(item);
|
||||
parentItem = item;
|
||||
}
|
||||
|
||||
m_proxy->setSourceModel(m_model);
|
||||
|
||||
verifyIdentity(m_model);
|
||||
|
||||
QSignalSpy modelBeforeSpy(m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
|
||||
QSignalSpy modelAfterSpy(m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)));
|
||||
QSignalSpy proxyBeforeSpy(m_proxy, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
|
||||
QSignalSpy proxyAfterSpy(m_proxy, SIGNAL(rowsRemoved(QModelIndex,int,int)));
|
||||
|
||||
const QModelIndex topLevel = m_model->index(0, 0, QModelIndex());
|
||||
const QModelIndex secondLevel = m_model->index(0, 0, topLevel);
|
||||
const QModelIndex thirdLevel = m_model->index(0, 0, secondLevel);
|
||||
|
||||
QVERIFY(thirdLevel.isValid());
|
||||
|
||||
m_model->removeRow(0, secondLevel);
|
||||
|
||||
QVERIFY(modelBeforeSpy.size() == 1 && 1 == proxyBeforeSpy.size());
|
||||
QVERIFY(modelAfterSpy.size() == 1 && 1 == proxyAfterSpy.size());
|
||||
|
||||
QVERIFY(modelBeforeSpy.first().first().value<QModelIndex>() == m_proxy->mapToSource(proxyBeforeSpy.first().first().value<QModelIndex>()));
|
||||
QVERIFY(modelBeforeSpy.first().at(1) == proxyBeforeSpy.first().at(1));
|
||||
QVERIFY(modelBeforeSpy.first().at(2) == proxyBeforeSpy.first().at(2));
|
||||
|
||||
QVERIFY(modelAfterSpy.first().first().value<QModelIndex>() == m_proxy->mapToSource(proxyAfterSpy.first().first().value<QModelIndex>()));
|
||||
QVERIFY(modelAfterSpy.first().at(1) == proxyAfterSpy.first().at(1));
|
||||
QVERIFY(modelAfterSpy.first().at(2) == proxyAfterSpy.first().at(2));
|
||||
|
||||
verifyIdentity(m_model);
|
||||
}
|
||||
|
||||
void tst_QIdentityProxyModel::moveRows()
|
||||
{
|
||||
DynamicTreeModel model;
|
||||
|
||||
{
|
||||
ModelInsertCommand insertCommand(&model);
|
||||
insertCommand.setStartRow(0);
|
||||
insertCommand.setEndRow(9);
|
||||
insertCommand.doCommand();
|
||||
}
|
||||
{
|
||||
ModelInsertCommand insertCommand(&model);
|
||||
insertCommand.setAncestorRowNumbers(QList<int>() << 5);
|
||||
insertCommand.setStartRow(0);
|
||||
insertCommand.setEndRow(9);
|
||||
insertCommand.doCommand();
|
||||
}
|
||||
|
||||
m_proxy->setSourceModel(&model);
|
||||
|
||||
verifyIdentity(&model);
|
||||
|
||||
QSignalSpy modelBeforeSpy(&model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
|
||||
QSignalSpy modelAfterSpy(&model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)));
|
||||
QSignalSpy proxyBeforeSpy(m_proxy, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
|
||||
QSignalSpy proxyAfterSpy(m_proxy, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)));
|
||||
|
||||
{
|
||||
ModelMoveCommand moveCommand(&model, 0);
|
||||
moveCommand.setAncestorRowNumbers(QList<int>() << 5);
|
||||
moveCommand.setStartRow(3);
|
||||
moveCommand.setEndRow(4);
|
||||
moveCommand.setDestRow(1);
|
||||
moveCommand.doCommand();
|
||||
}
|
||||
|
||||
QVERIFY(modelBeforeSpy.size() == 1 && 1 == proxyBeforeSpy.size());
|
||||
QVERIFY(modelAfterSpy.size() == 1 && 1 == proxyAfterSpy.size());
|
||||
|
||||
QVERIFY(modelBeforeSpy.first().first().value<QModelIndex>() == m_proxy->mapToSource(proxyBeforeSpy.first().first().value<QModelIndex>()));
|
||||
QVERIFY(modelBeforeSpy.first().at(1) == proxyBeforeSpy.first().at(1));
|
||||
QVERIFY(modelBeforeSpy.first().at(2) == proxyBeforeSpy.first().at(2));
|
||||
QVERIFY(modelBeforeSpy.first().at(3).value<QModelIndex>() == m_proxy->mapToSource(proxyBeforeSpy.first().at(3).value<QModelIndex>()));
|
||||
QVERIFY(modelBeforeSpy.first().at(4) == proxyBeforeSpy.first().at(4));
|
||||
|
||||
QVERIFY(modelAfterSpy.first().first().value<QModelIndex>() == m_proxy->mapToSource(proxyAfterSpy.first().first().value<QModelIndex>()));
|
||||
QVERIFY(modelAfterSpy.first().at(1) == proxyAfterSpy.first().at(1));
|
||||
QVERIFY(modelAfterSpy.first().at(2) == proxyAfterSpy.first().at(2));
|
||||
QVERIFY(modelAfterSpy.first().at(3).value<QModelIndex>() == m_proxy->mapToSource(proxyAfterSpy.first().at(3).value<QModelIndex>()));
|
||||
QVERIFY(modelAfterSpy.first().at(4) == proxyAfterSpy.first().at(4));
|
||||
|
||||
verifyIdentity(&model);
|
||||
|
||||
m_proxy->setSourceModel(0);
|
||||
}
|
||||
|
||||
void tst_QIdentityProxyModel::reset()
|
||||
{
|
||||
DynamicTreeModel model;
|
||||
|
||||
{
|
||||
ModelInsertCommand insertCommand(&model);
|
||||
insertCommand.setStartRow(0);
|
||||
insertCommand.setEndRow(9);
|
||||
insertCommand.doCommand();
|
||||
}
|
||||
{
|
||||
ModelInsertCommand insertCommand(&model);
|
||||
insertCommand.setAncestorRowNumbers(QList<int>() << 5);
|
||||
insertCommand.setStartRow(0);
|
||||
insertCommand.setEndRow(9);
|
||||
insertCommand.doCommand();
|
||||
}
|
||||
|
||||
m_proxy->setSourceModel(&model);
|
||||
|
||||
verifyIdentity(&model);
|
||||
|
||||
QSignalSpy modelBeforeSpy(&model, SIGNAL(modelAboutToBeReset()));
|
||||
QSignalSpy modelAfterSpy(&model, SIGNAL(modelReset()));
|
||||
QSignalSpy proxyBeforeSpy(m_proxy, SIGNAL(modelAboutToBeReset()));
|
||||
QSignalSpy proxyAfterSpy(m_proxy, SIGNAL(modelReset()));
|
||||
|
||||
{
|
||||
ModelResetCommandFixed resetCommand(&model, 0);
|
||||
resetCommand.setAncestorRowNumbers(QList<int>() << 5);
|
||||
resetCommand.setStartRow(3);
|
||||
resetCommand.setEndRow(4);
|
||||
resetCommand.setDestRow(1);
|
||||
resetCommand.doCommand();
|
||||
}
|
||||
|
||||
QVERIFY(modelBeforeSpy.size() == 1 && 1 == proxyBeforeSpy.size());
|
||||
QVERIFY(modelAfterSpy.size() == 1 && 1 == proxyAfterSpy.size());
|
||||
|
||||
verifyIdentity(&model);
|
||||
m_proxy->setSourceModel(0);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QIdentityProxyModel)
|
||||
#include "tst_qidentityproxymodel.moc"
|
Loading…
Reference in New Issue
Block a user