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:
Qt Continuous Integration System 2011-05-12 01:42:31 +10:00
commit ca724e095b
9 changed files with 1103 additions and 1 deletions

View File

@ -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]

View File

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

View File

@ -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 \

View 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

View 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

View File

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

View File

@ -84,6 +84,7 @@ SUBDIRS=\
qheaderview \
qicoimageformat \
qicon \
qidentityproxymodel \
qimageiohandler \
qimagereader \
qimagewriter \

View 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

View 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"