mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-24 02:42:48 +00:00
758 lines
28 KiB
C++
758 lines
28 KiB
C++
![]() |
/*
|
||
|
Copyright (C) 2010 Klarälvdalens Datakonsult AB,
|
||
|
a KDAB Group company, info@kdab.net,
|
||
|
author Stephen Kelly <stephen@kdab.com>
|
||
|
|
||
|
This library is free software; you can redistribute it and/or modify it
|
||
|
under the terms of the GNU Library General Public License as published by
|
||
|
the Free Software Foundation; either version 2 of the License, or (at your
|
||
|
option) any later version.
|
||
|
|
||
|
This library is distributed in the hope that it will be useful, but WITHOUT
|
||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
|
||
|
License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU Library General Public License
|
||
|
along with this library; see the file COPYING.LIB. If not, write to the
|
||
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||
|
02110-1301, USA.
|
||
|
*/
|
||
|
|
||
|
#include "kidentityproxymodel.h"
|
||
|
|
||
|
#include <QtGui/QItemSelection>
|
||
|
#include <QtCore/QStringList>
|
||
|
#include <kdebug.h>
|
||
|
|
||
|
class KIdentityProxyModelPrivate
|
||
|
{
|
||
|
KIdentityProxyModelPrivate(KIdentityProxyModel *qq)
|
||
|
: q_ptr(qq)
|
||
|
// ignoreNextLayoutAboutToBeChanged(false),
|
||
|
// ignoreNextLayoutChanged(false)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
Q_DECLARE_PUBLIC(KIdentityProxyModel)
|
||
|
KIdentityProxyModel * const q_ptr;
|
||
|
|
||
|
// bool ignoreNextLayoutAboutToBeChanged;
|
||
|
// bool ignoreNextLayoutChanged;
|
||
|
QList<QPersistentModelIndex> layoutChangePersistentIndexes;
|
||
|
QModelIndexList proxyIndexes;
|
||
|
|
||
|
void _k_sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end);
|
||
|
void _k_sourceRowsInserted(const QModelIndex &parent, int start, int end);
|
||
|
void _k_sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
|
||
|
void _k_sourceRowsRemoved(const QModelIndex &parent, int start, int end);
|
||
|
void _k_sourceRowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest);
|
||
|
void _k_sourceRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest);
|
||
|
|
||
|
void _k_sourceColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end);
|
||
|
void _k_sourceColumnsInserted(const QModelIndex &parent, int start, int end);
|
||
|
void _k_sourceColumnsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
|
||
|
void _k_sourceColumnsRemoved(const QModelIndex &parent, int start, int end);
|
||
|
void _k_sourceColumnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest);
|
||
|
void _k_sourceColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest);
|
||
|
|
||
|
void _k_sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
|
||
|
void _k_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last);
|
||
|
|
||
|
void _k_sourceLayoutAboutToBeChanged();
|
||
|
void _k_sourceLayoutChanged();
|
||
|
// void _k_sourceChildrenLayoutsAboutToBeChanged(const QModelIndex &parent1, const QModelIndex &parent2);
|
||
|
// void _k_sourceChildrenLayoutsChanged(const QModelIndex &parent1, const QModelIndex &parent2);
|
||
|
void _k_sourceModelAboutToBeReset();
|
||
|
void _k_sourceModelReset();
|
||
|
void _k_sourceModelDestroyed();
|
||
|
|
||
|
};
|
||
|
|
||
|
/*!
|
||
|
\since 4.6
|
||
|
\class KIdentityProxyModel
|
||
|
\brief The KIdentityProxyModel class proxies its source model unmodified
|
||
|
|
||
|
\ingroup model-view
|
||
|
|
||
|
KIdentityProxyModel 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.
|
||
|
|
||
|
\code
|
||
|
class DateFormatProxyModel : public KIdentityProxyModel
|
||
|
{
|
||
|
// ...
|
||
|
|
||
|
void setDateFormatString(const QString &formatString)
|
||
|
{
|
||
|
m_formatString = formatString;
|
||
|
}
|
||
|
|
||
|
QVariant data(const QModelIndex &index, int role)
|
||
|
{
|
||
|
if (role != Qt::DisplayRole)
|
||
|
return KIdentityProxyModel::data(index, role);
|
||
|
|
||
|
const QDateTime dateTime = sourceModel()->data(SourceClass::DateRole).toDateTime();
|
||
|
|
||
|
return dateTime.toString(m_formatString);
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
QString m_formatString;
|
||
|
};
|
||
|
\endcode
|
||
|
|
||
|
\since 4.6
|
||
|
\author Stephen Kelly <stephen@kdab.com>
|
||
|
|
||
|
*/
|
||
|
|
||
|
/*!
|
||
|
Constructs an identity model with the given \a parent.
|
||
|
*/
|
||
|
KIdentityProxyModel::KIdentityProxyModel(QObject* parent)
|
||
|
: QAbstractProxyModel(parent), d_ptr(new KIdentityProxyModelPrivate(this))
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
/*! \internal
|
||
|
*/
|
||
|
KIdentityProxyModel::KIdentityProxyModel(KIdentityProxyModelPrivate* privateClass, QObject* parent)
|
||
|
: QAbstractProxyModel(parent), d_ptr(privateClass)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
Destroys this identity model.
|
||
|
*/
|
||
|
KIdentityProxyModel::~KIdentityProxyModel()
|
||
|
{
|
||
|
delete d_ptr;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\reimp
|
||
|
*/
|
||
|
bool KIdentityProxyModel::canFetchMore(const QModelIndex& parent) const
|
||
|
{
|
||
|
if (!sourceModel())
|
||
|
return 0;
|
||
|
Q_ASSERT(parent.isValid() ? parent.model() == this : true);
|
||
|
return sourceModel()->canFetchMore(mapToSource(parent));
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\\reimp
|
||
|
*/
|
||
|
int KIdentityProxyModel::columnCount(const QModelIndex& parent) const
|
||
|
{
|
||
|
if (!sourceModel())
|
||
|
return 0;
|
||
|
Q_ASSERT(parent.isValid() ? parent.model() == this : true);
|
||
|
return sourceModel()->columnCount(mapToSource(parent));
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\reimp
|
||
|
*/
|
||
|
void KIdentityProxyModel::fetchMore(const QModelIndex& parent)
|
||
|
{
|
||
|
if (!sourceModel())
|
||
|
return;
|
||
|
Q_ASSERT(parent.isValid() ? parent.model() == this : true);
|
||
|
sourceModel()->fetchMore(mapToSource(parent));
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\\reimp
|
||
|
*/
|
||
|
bool KIdentityProxyModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent)
|
||
|
{
|
||
|
if (!sourceModel())
|
||
|
return false;
|
||
|
Q_ASSERT(parent.isValid() ? parent.model() == this : true);
|
||
|
return sourceModel()->dropMimeData(data, action, row, column, mapToSource(parent));
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\reimp
|
||
|
*/
|
||
|
QModelIndex KIdentityProxyModel::index(int row, int column, const QModelIndex& parent) const
|
||
|
{
|
||
|
if (!sourceModel())
|
||
|
return QModelIndex();
|
||
|
Q_ASSERT(parent.isValid() ? parent.model() == this : true);
|
||
|
const QModelIndex sourceParent = mapToSource(parent);
|
||
|
const QModelIndex sourceIndex = sourceModel()->index(row, column, sourceParent);
|
||
|
return mapFromSource(sourceIndex);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\reimp
|
||
|
*/
|
||
|
bool KIdentityProxyModel::insertColumns(int column, int count, const QModelIndex& parent)
|
||
|
{
|
||
|
if (!sourceModel())
|
||
|
return false;
|
||
|
Q_ASSERT(parent.isValid() ? parent.model() == this : true);
|
||
|
return sourceModel()->insertColumns(column, count, mapToSource(parent));
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\reimp
|
||
|
*/
|
||
|
bool KIdentityProxyModel::insertRows(int row, int count, const QModelIndex& parent)
|
||
|
{
|
||
|
if (!sourceModel())
|
||
|
return false;
|
||
|
Q_ASSERT(parent.isValid() ? parent.model() == this : true);
|
||
|
return sourceModel()->insertRows(row, count, mapToSource(parent));
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\reimp
|
||
|
*/
|
||
|
QModelIndex KIdentityProxyModel::mapFromSource(const QModelIndex& sourceIndex) const
|
||
|
{
|
||
|
if (!sourceModel() || !sourceIndex.isValid())
|
||
|
return QModelIndex();
|
||
|
|
||
|
Q_ASSERT(sourceIndex.model() == sourceModel());
|
||
|
return createIndex(sourceIndex.row(), sourceIndex.column(), sourceIndex.internalPointer());
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\reimp
|
||
|
*/
|
||
|
QItemSelection KIdentityProxyModel::mapSelectionFromSource(const QItemSelection& selection) const
|
||
|
{
|
||
|
QItemSelection proxySelection;
|
||
|
|
||
|
if (!sourceModel())
|
||
|
return proxySelection;
|
||
|
|
||
|
QItemSelection::const_iterator it = selection.constBegin();
|
||
|
const QItemSelection::const_iterator end = selection.constEnd();
|
||
|
for ( ; it != end; ++it) {
|
||
|
Q_ASSERT(it->model() == sourceModel());
|
||
|
const QItemSelectionRange range(mapFromSource(it->topLeft()), mapFromSource(it->bottomRight()));
|
||
|
proxySelection.append(range);
|
||
|
}
|
||
|
|
||
|
return proxySelection;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\reimp
|
||
|
*/
|
||
|
QItemSelection KIdentityProxyModel::mapSelectionToSource(const QItemSelection& selection) const
|
||
|
{
|
||
|
QItemSelection sourceSelection;
|
||
|
|
||
|
if (!sourceModel())
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
struct SourceModelIndex
|
||
|
{
|
||
|
SourceModelIndex(int _r, int _c, void *_p, QAbstractItemModel *_m)
|
||
|
: r(_r), c(_c), p(_p), m(_m)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
operator QModelIndex() { return reinterpret_cast<QModelIndex&>(*this); }
|
||
|
|
||
|
int r, c;
|
||
|
void *p;
|
||
|
const QAbstractItemModel *m;
|
||
|
};
|
||
|
|
||
|
/*!
|
||
|
\reimp
|
||
|
*/
|
||
|
QModelIndex KIdentityProxyModel::mapToSource(const QModelIndex& proxyIndex) const
|
||
|
{
|
||
|
if (!sourceModel() || !proxyIndex.isValid())
|
||
|
return QModelIndex();
|
||
|
Q_ASSERT(proxyIndex.model() == this);
|
||
|
return SourceModelIndex(proxyIndex.row(), proxyIndex.column(), proxyIndex.internalPointer(), sourceModel());
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\reimp
|
||
|
*/
|
||
|
QModelIndexList KIdentityProxyModel::match(const QModelIndex& start, int role, const QVariant& value, int hits, Qt::MatchFlags flags) const
|
||
|
{
|
||
|
Q_ASSERT(start.isValid() ? start.model() == this : true);
|
||
|
if (!sourceModel())
|
||
|
return QModelIndexList();
|
||
|
|
||
|
const QModelIndexList sourceList = sourceModel()->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
|
||
|
*/
|
||
|
QStringList KIdentityProxyModel::mimeTypes() const
|
||
|
{
|
||
|
if (sourceModel())
|
||
|
return sourceModel()->mimeTypes();
|
||
|
else
|
||
|
return QAbstractProxyModel::mimeTypes();
|
||
|
}
|
||
|
|
||
|
QMimeData* KIdentityProxyModel::mimeData(const QModelIndexList& indexes) const
|
||
|
{
|
||
|
if (!sourceModel())
|
||
|
return QAbstractProxyModel::mimeData(indexes);
|
||
|
|
||
|
QModelIndexList proxyIndexes;
|
||
|
foreach(const QModelIndex &index, indexes)
|
||
|
proxyIndexes.append(mapToSource(index));
|
||
|
|
||
|
return sourceModel()->mimeData(proxyIndexes);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*!
|
||
|
\\reimp
|
||
|
*/
|
||
|
QModelIndex KIdentityProxyModel::parent(const QModelIndex& child) const
|
||
|
{
|
||
|
if (!sourceModel())
|
||
|
return QModelIndex();
|
||
|
|
||
|
Q_ASSERT(child.isValid() ? child.model() == this : true);
|
||
|
const QModelIndex sourceIndex = mapToSource(child);
|
||
|
const QModelIndex sourceParent = sourceIndex.parent();
|
||
|
return mapFromSource(sourceParent);
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\reimp
|
||
|
*/
|
||
|
bool KIdentityProxyModel::removeColumns(int column, int count, const QModelIndex& parent)
|
||
|
{
|
||
|
if (!sourceModel())
|
||
|
return false;
|
||
|
|
||
|
Q_ASSERT(parent.isValid() ? parent.model() == this : true);
|
||
|
return sourceModel()->removeColumns(column, count, mapToSource(parent));
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\reimp
|
||
|
*/
|
||
|
bool KIdentityProxyModel::removeRows(int row, int count, const QModelIndex& parent)
|
||
|
{
|
||
|
if (!sourceModel())
|
||
|
return false;
|
||
|
|
||
|
Q_ASSERT(parent.isValid() ? parent.model() == this : true);
|
||
|
return sourceModel()->removeRows(row, count, mapToSource(parent));
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\reimp
|
||
|
*/
|
||
|
int KIdentityProxyModel::rowCount(const QModelIndex& parent) const
|
||
|
{
|
||
|
if (!sourceModel())
|
||
|
return 0;
|
||
|
Q_ASSERT(parent.isValid() ? parent.model() == this : true);
|
||
|
return sourceModel()->rowCount(mapToSource(parent));
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
\reimp
|
||
|
*/
|
||
|
void KIdentityProxyModel::setSourceModel(QAbstractItemModel* sourceModel)
|
||
|
{
|
||
|
beginResetModel();
|
||
|
|
||
|
if (sourceModel) {
|
||
|
disconnect(sourceModel, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
|
||
|
this, SLOT(_k_sourceRowsAboutToBeInserted(QModelIndex,int,int)));
|
||
|
disconnect(sourceModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
|
||
|
this, SLOT(_k_sourceRowsInserted(QModelIndex,int,int)));
|
||
|
disconnect(sourceModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
|
||
|
this, SLOT(_k_sourceRowsAboutToBeRemoved(QModelIndex,int,int)));
|
||
|
disconnect(sourceModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
|
||
|
this, SLOT(_k_sourceRowsRemoved(QModelIndex,int,int)));
|
||
|
disconnect(sourceModel, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
|
||
|
this, SLOT(_k_sourceRowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
|
||
|
disconnect(sourceModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
|
||
|
this, SLOT(_k_sourceRowsMoved(QModelIndex,int,int,QModelIndex,int)));
|
||
|
disconnect(sourceModel, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)),
|
||
|
this, SLOT(_k_sourceColumnsAboutToBeInserted(QModelIndex,int,int)));
|
||
|
disconnect(sourceModel, SIGNAL(columnsInserted(QModelIndex,int,int)),
|
||
|
this, SLOT(_k_sourceColumnsInserted(QModelIndex,int,int)));
|
||
|
disconnect(sourceModel, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
|
||
|
this, SLOT(_k_sourceColumnsAboutToBeRemoved(QModelIndex,int,int)));
|
||
|
disconnect(sourceModel, SIGNAL(columnsRemoved(QModelIndex,int,int)),
|
||
|
this, SLOT(_k_sourceColumnsRemoved(QModelIndex,int,int)));
|
||
|
disconnect(sourceModel, SIGNAL(columnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
|
||
|
this, SLOT(_k_sourceColumnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
|
||
|
disconnect(sourceModel, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)),
|
||
|
this, SLOT(_k_sourceColumnsMoved(QModelIndex,int,int,QModelIndex,int)));
|
||
|
disconnect(sourceModel, SIGNAL(modelAboutToBeReset()),
|
||
|
this, SLOT(_k_sourceModelAboutToBeReset()));
|
||
|
// disconnect(sourceModel, SIGNAL(internalDataReset()),
|
||
|
// this, SLOT(resetInternalData()));
|
||
|
disconnect(sourceModel, SIGNAL(modelReset()),
|
||
|
this, SLOT(_k_sourceModelReset()));
|
||
|
disconnect(sourceModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
|
||
|
this, SLOT(_k_sourceDataChanged(QModelIndex,QModelIndex)));
|
||
|
disconnect(sourceModel, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
|
||
|
this, SLOT(_k_sourceHeaderDataChanged(Qt::Orientation,int,int)));
|
||
|
disconnect(sourceModel, SIGNAL(layoutAboutToBeChanged()),
|
||
|
this, SLOT(_k_sourceLayoutAboutToBeChanged()));
|
||
|
disconnect(sourceModel, SIGNAL(layoutChanged()),
|
||
|
this, SLOT(_k_sourceLayoutChanged()));
|
||
|
// disconnect(sourceModel, SIGNAL(childrenLayoutsAboutToBeChanged(QModelIndex,QModelIndex)),
|
||
|
// this, SLOT(_k_sourceChildrenLayoutsAboutToBeChanged(QModelIndex,QModelIndex)));
|
||
|
// disconnect(sourceModel, SIGNAL(childrenLayoutsChanged(QModelIndex,QModelIndex)),
|
||
|
// this, SLOT(_k_sourceChildrenLayoutsChanged(QModelIndex,QModelIndex)));
|
||
|
disconnect(sourceModel, SIGNAL(destroyed()),
|
||
|
this, SLOT(_k_sourceModelDestroyed()));
|
||
|
}
|
||
|
|
||
|
QAbstractProxyModel::setSourceModel(sourceModel);
|
||
|
|
||
|
if (sourceModel) {
|
||
|
connect(sourceModel, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
|
||
|
SLOT(_k_sourceRowsAboutToBeInserted(QModelIndex,int,int)));
|
||
|
connect(sourceModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
|
||
|
SLOT(_k_sourceRowsInserted(QModelIndex,int,int)));
|
||
|
connect(sourceModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
|
||
|
SLOT(_k_sourceRowsAboutToBeRemoved(QModelIndex,int,int)));
|
||
|
connect(sourceModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
|
||
|
SLOT(_k_sourceRowsRemoved(QModelIndex,int,int)));
|
||
|
connect(sourceModel, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
|
||
|
SLOT(_k_sourceRowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
|
||
|
connect(sourceModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
|
||
|
SLOT(_k_sourceRowsMoved(QModelIndex,int,int,QModelIndex,int)));
|
||
|
connect(sourceModel, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)),
|
||
|
SLOT(_k_sourceColumnsAboutToBeInserted(QModelIndex,int,int)));
|
||
|
connect(sourceModel, SIGNAL(columnsInserted(QModelIndex,int,int)),
|
||
|
SLOT(_k_sourceColumnsInserted(QModelIndex,int,int)));
|
||
|
connect(sourceModel, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
|
||
|
SLOT(_k_sourceColumnsAboutToBeRemoved(QModelIndex,int,int)));
|
||
|
connect(sourceModel, SIGNAL(columnsRemoved(QModelIndex,int,int)),
|
||
|
SLOT(_k_sourceColumnsRemoved(QModelIndex,int,int)));
|
||
|
connect(sourceModel, SIGNAL(columnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)),
|
||
|
SLOT(_k_sourceColumnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)));
|
||
|
connect(sourceModel, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)),
|
||
|
SLOT(_k_sourceColumnsMoved(QModelIndex,int,int,QModelIndex,int)));
|
||
|
connect(sourceModel, SIGNAL(modelAboutToBeReset()),
|
||
|
SLOT(_k_sourceModelAboutToBeReset()));
|
||
|
// connect(sourceModel, SIGNAL(internalDataReset()),
|
||
|
// SLOT(resetInternalData()));
|
||
|
connect(sourceModel, SIGNAL(modelReset()),
|
||
|
SLOT(_k_sourceModelReset()));
|
||
|
connect(sourceModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
|
||
|
SLOT(_k_sourceDataChanged(QModelIndex,QModelIndex)));
|
||
|
connect(sourceModel, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
|
||
|
SLOT(_k_sourceHeaderDataChanged(Qt::Orientation,int,int)));
|
||
|
connect(sourceModel, SIGNAL(layoutAboutToBeChanged()),
|
||
|
SLOT(_k_sourceLayoutAboutToBeChanged()));
|
||
|
connect(sourceModel, SIGNAL(layoutChanged()),
|
||
|
SLOT(_k_sourceLayoutChanged()));
|
||
|
// Hopefully this will be in Qt4.8
|
||
|
// connect(sourceModel, SIGNAL(childrenLayoutsAboutToBeChanged(QModelIndex,QModelIndex)),
|
||
|
// SLOT(_k_sourceChildrenLayoutsAboutToBeChanged(QModelIndex,QModelIndex)));
|
||
|
// connect(sourceModel, SIGNAL(childrenLayoutsChanged(QModelIndex,QModelIndex)),
|
||
|
// SLOT(_k_sourceChildrenLayoutsChanged(QModelIndex,QModelIndex)));
|
||
|
connect(sourceModel, SIGNAL(destroyed()),
|
||
|
SLOT(_k_sourceModelDestroyed()));
|
||
|
}
|
||
|
|
||
|
endResetModel();
|
||
|
}
|
||
|
|
||
|
Qt::DropActions KIdentityProxyModel::supportedDropActions() const
|
||
|
{
|
||
|
if (sourceModel())
|
||
|
return sourceModel()->supportedDropActions();
|
||
|
else
|
||
|
return QAbstractProxyModel::supportedDropActions();
|
||
|
}
|
||
|
|
||
|
void KIdentityProxyModelPrivate::_k_sourceColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end)
|
||
|
{
|
||
|
Q_Q(KIdentityProxyModel);
|
||
|
Q_ASSERT(parent.isValid() ? parent.model() == q->sourceModel() : true);
|
||
|
q->beginInsertColumns(q->mapFromSource(parent), start, end);
|
||
|
}
|
||
|
|
||
|
void KIdentityProxyModelPrivate::_k_sourceColumnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest)
|
||
|
{
|
||
|
Q_Q(KIdentityProxyModel);
|
||
|
Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == q->sourceModel() : true);
|
||
|
Q_ASSERT(destParent.isValid() ? destParent.model() == q->sourceModel() : true);
|
||
|
q->beginMoveColumns(q->mapFromSource(sourceParent), sourceStart, sourceEnd, q->mapFromSource(destParent), dest);
|
||
|
}
|
||
|
|
||
|
void KIdentityProxyModelPrivate::_k_sourceColumnsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
|
||
|
{
|
||
|
Q_Q(KIdentityProxyModel);
|
||
|
Q_ASSERT(parent.isValid() ? parent.model() == q->sourceModel() : true);
|
||
|
q->beginRemoveColumns(q->mapFromSource(parent), start, end);
|
||
|
}
|
||
|
|
||
|
void KIdentityProxyModelPrivate::_k_sourceColumnsInserted(const QModelIndex &parent, int start, int end)
|
||
|
{
|
||
|
Q_Q(KIdentityProxyModel);
|
||
|
Q_ASSERT(parent.isValid() ? parent.model() == q->sourceModel() : true);
|
||
|
Q_UNUSED(parent)
|
||
|
Q_UNUSED(start)
|
||
|
Q_UNUSED(end)
|
||
|
q->endInsertColumns();
|
||
|
}
|
||
|
|
||
|
void KIdentityProxyModelPrivate::_k_sourceColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest)
|
||
|
{
|
||
|
Q_Q(KIdentityProxyModel);
|
||
|
Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == q->sourceModel() : true);
|
||
|
Q_ASSERT(destParent.isValid() ? destParent.model() == q->sourceModel() : true);
|
||
|
Q_UNUSED(sourceParent)
|
||
|
Q_UNUSED(sourceStart)
|
||
|
Q_UNUSED(sourceEnd)
|
||
|
Q_UNUSED(destParent)
|
||
|
Q_UNUSED(dest)
|
||
|
q->endMoveColumns();
|
||
|
}
|
||
|
|
||
|
void KIdentityProxyModelPrivate::_k_sourceColumnsRemoved(const QModelIndex &parent, int start, int end)
|
||
|
{
|
||
|
Q_Q(KIdentityProxyModel);
|
||
|
Q_ASSERT(parent.isValid() ? parent.model() == q->sourceModel() : true);
|
||
|
Q_UNUSED(parent)
|
||
|
Q_UNUSED(start)
|
||
|
Q_UNUSED(end)
|
||
|
q->endRemoveColumns();
|
||
|
}
|
||
|
|
||
|
void KIdentityProxyModelPrivate::_k_sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
|
||
|
{
|
||
|
Q_Q(KIdentityProxyModel);
|
||
|
Q_ASSERT(topLeft.model() == q->sourceModel());
|
||
|
Q_ASSERT(bottomRight.model() == q->sourceModel());
|
||
|
q->dataChanged(q->mapFromSource(topLeft), q->mapFromSource(bottomRight));
|
||
|
}
|
||
|
|
||
|
void KIdentityProxyModelPrivate::_k_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last)
|
||
|
{
|
||
|
Q_Q(KIdentityProxyModel);
|
||
|
q->headerDataChanged(orientation, first, last);
|
||
|
}
|
||
|
|
||
|
void KIdentityProxyModelPrivate::_k_sourceLayoutAboutToBeChanged()
|
||
|
{
|
||
|
//if (ignoreNextLayoutAboutToBeChanged)
|
||
|
// return;
|
||
|
|
||
|
Q_Q(KIdentityProxyModel);
|
||
|
|
||
|
q->layoutAboutToBeChanged();
|
||
|
|
||
|
Q_FOREACH(const QModelIndex &proxyPersistentIndex, q->persistentIndexList()) {
|
||
|
Q_ASSERT(proxyPersistentIndex.isValid());
|
||
|
const QPersistentModelIndex srcPersistentIndex = q->mapToSource(proxyPersistentIndex);
|
||
|
if (!srcPersistentIndex.isValid()) // can happen with extra columns, e.g. KPIM::StatisticsProxyModel
|
||
|
continue;
|
||
|
proxyIndexes << proxyPersistentIndex;
|
||
|
layoutChangePersistentIndexes << srcPersistentIndex;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void KIdentityProxyModelPrivate::_k_sourceLayoutChanged()
|
||
|
{
|
||
|
//if (ignoreNextLayoutChanged)
|
||
|
// return;
|
||
|
|
||
|
Q_Q(KIdentityProxyModel);
|
||
|
|
||
|
for (int i = 0; i < proxyIndexes.size(); ++i) {
|
||
|
const QModelIndex oldProxyIndex = proxyIndexes.at(i);
|
||
|
const QModelIndex newProxyIndex = q->mapFromSource(layoutChangePersistentIndexes.at(i));
|
||
|
if (oldProxyIndex != newProxyIndex)
|
||
|
q->changePersistentIndex(oldProxyIndex, newProxyIndex);
|
||
|
}
|
||
|
|
||
|
layoutChangePersistentIndexes.clear();
|
||
|
proxyIndexes.clear();
|
||
|
|
||
|
q->layoutChanged();
|
||
|
}
|
||
|
|
||
|
#if 0 // this code was for the stuff that never went into Qt-4.8. We are keeping it for the Qt5 QIPM sourceLayoutChanged(QModelIndex) future code.
|
||
|
void KIdentityProxyModelPrivate::_k_sourceChildrenLayoutsAboutToBeChanged(const QModelIndex &parent1, const QModelIndex &parent2)
|
||
|
{
|
||
|
Q_Q(KIdentityProxyModel);
|
||
|
Q_ASSERT(parent1.isValid() ? parent1.model() == q->sourceModel() : true);
|
||
|
Q_ASSERT(parent2.isValid() ? parent2.model() == q->sourceModel() : true);
|
||
|
|
||
|
|
||
|
ignoreNextLayoutAboutToBeChanged = true;
|
||
|
|
||
|
const QModelIndex proxyParent1 = q->mapFromSource(parent1);
|
||
|
const QModelIndex proxyParent2 = q->mapFromSource(parent2);
|
||
|
//emit q->childrenLayoutsAboutToBeChanged(proxyParent1, proxyParent2);
|
||
|
emit q->layoutAboutToBeChanged();
|
||
|
|
||
|
if (q->persistentIndexList().isEmpty())
|
||
|
return;
|
||
|
|
||
|
Q_FOREACH(const QModelIndex &proxyPersistentIndex, q->persistentIndexList()) {
|
||
|
const QPersistentModelIndex srcPersistentIndex = q->mapToSource(proxyPersistentIndex);
|
||
|
Q_ASSERT(proxyPersistentIndex.isValid());
|
||
|
Q_ASSERT(srcPersistentIndex.isValid());
|
||
|
const QModelIndex idxParent = srcPersistentIndex.parent();
|
||
|
if (idxParent != parent1 && idxParent != parent2)
|
||
|
continue;
|
||
|
proxyIndexes << proxyPersistentIndex;
|
||
|
layoutChangePersistentIndexes << srcPersistentIndex;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void KIdentityProxyModelPrivate::_k_sourceChildrenLayoutsChanged(const QModelIndex &parent1, const QModelIndex &parent2)
|
||
|
{
|
||
|
Q_Q(KIdentityProxyModel);
|
||
|
Q_ASSERT(parent1.isValid() ? parent1.model() == q->sourceModel() : true);
|
||
|
Q_ASSERT(parent2.isValid() ? parent2.model() == q->sourceModel() : true);
|
||
|
|
||
|
ignoreNextLayoutChanged = true;
|
||
|
|
||
|
QModelIndexList oldList, newList;
|
||
|
for( int i = 0; i < layoutChangePersistentIndexes.size(); ++i) {
|
||
|
const QModelIndex srcIdx = layoutChangePersistentIndexes.at(i);
|
||
|
const QModelIndex oldProxyIdx = proxyIndexes.at(i);
|
||
|
oldList << oldProxyIdx;
|
||
|
newList << q->mapFromSource(srcIdx);
|
||
|
}
|
||
|
q->changePersistentIndexList(oldList, newList);
|
||
|
layoutChangePersistentIndexes.clear();
|
||
|
proxyIndexes.clear();
|
||
|
|
||
|
const QModelIndex proxyParent1 = q->mapFromSource(parent1);
|
||
|
const QModelIndex proxyParent2 = q->mapFromSource(parent2);
|
||
|
// emit q->childrenLayoutsChanged(proxyParent1, proxyParent2);
|
||
|
emit q->layoutChanged();
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
void KIdentityProxyModelPrivate::_k_sourceModelAboutToBeReset()
|
||
|
{
|
||
|
Q_Q(KIdentityProxyModel);
|
||
|
q->beginResetModel();
|
||
|
}
|
||
|
|
||
|
void KIdentityProxyModelPrivate::_k_sourceModelReset()
|
||
|
{
|
||
|
Q_Q(KIdentityProxyModel);
|
||
|
q->endResetModel();
|
||
|
}
|
||
|
|
||
|
void KIdentityProxyModelPrivate::_k_sourceModelDestroyed()
|
||
|
{
|
||
|
// Q_Q(KIdentityProxyModel);
|
||
|
// q->endResetModel();
|
||
|
}
|
||
|
|
||
|
void KIdentityProxyModelPrivate::_k_sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end)
|
||
|
{
|
||
|
Q_Q(KIdentityProxyModel);
|
||
|
Q_ASSERT(parent.isValid() ? parent.model() == q->sourceModel() : true);
|
||
|
q->beginInsertRows(q->mapFromSource(parent), start, end);
|
||
|
}
|
||
|
|
||
|
void KIdentityProxyModelPrivate::_k_sourceRowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest)
|
||
|
{
|
||
|
Q_Q(KIdentityProxyModel);
|
||
|
Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == q->sourceModel() : true);
|
||
|
Q_ASSERT(destParent.isValid() ? destParent.model() == q->sourceModel() : true);
|
||
|
q->beginMoveRows(q->mapFromSource(sourceParent), sourceStart, sourceEnd, q->mapFromSource(destParent), dest);
|
||
|
}
|
||
|
|
||
|
void KIdentityProxyModelPrivate::_k_sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end)
|
||
|
{
|
||
|
Q_Q(KIdentityProxyModel);
|
||
|
Q_ASSERT(parent.isValid() ? parent.model() == q->sourceModel() : true);
|
||
|
q->beginRemoveRows(q->mapFromSource(parent), start, end);
|
||
|
}
|
||
|
|
||
|
void KIdentityProxyModelPrivate::_k_sourceRowsInserted(const QModelIndex &parent, int start, int end)
|
||
|
{
|
||
|
Q_Q(KIdentityProxyModel);
|
||
|
Q_ASSERT(parent.isValid() ? parent.model() == q->sourceModel() : true);
|
||
|
Q_UNUSED(parent)
|
||
|
Q_UNUSED(start)
|
||
|
Q_UNUSED(end)
|
||
|
q->endInsertRows();
|
||
|
}
|
||
|
|
||
|
void KIdentityProxyModelPrivate::_k_sourceRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest)
|
||
|
{
|
||
|
Q_Q(KIdentityProxyModel);
|
||
|
Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == q->sourceModel() : true);
|
||
|
Q_ASSERT(destParent.isValid() ? destParent.model() == q->sourceModel() : true);
|
||
|
Q_UNUSED(sourceParent)
|
||
|
Q_UNUSED(sourceStart)
|
||
|
Q_UNUSED(sourceEnd)
|
||
|
Q_UNUSED(destParent)
|
||
|
Q_UNUSED(dest)
|
||
|
q->endMoveRows();
|
||
|
}
|
||
|
|
||
|
void KIdentityProxyModelPrivate::_k_sourceRowsRemoved(const QModelIndex &parent, int start, int end)
|
||
|
{
|
||
|
Q_Q(KIdentityProxyModel);
|
||
|
Q_ASSERT(parent.isValid() ? parent.model() == q->sourceModel() : true);
|
||
|
Q_UNUSED(parent)
|
||
|
Q_UNUSED(start)
|
||
|
Q_UNUSED(end)
|
||
|
q->endRemoveRows();
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
This slot is automatically invoked when the model is reset. It can be used to clear any data internal to the proxy at the appropriate time.
|
||
|
|
||
|
\sa QAbstractItemModel::internalDataReset()
|
||
|
*/
|
||
|
void KIdentityProxyModel::resetInternalData()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
#include "kidentityproxymodel.moc"
|