It supports reordering and hiding columns from the source model. REVIEW: 124156wilder
parent
7a94f65e16
commit
71d2e8c665
6 changed files with 499 additions and 0 deletions
@ -0,0 +1,209 @@ |
|||||||
|
/*
|
||||||
|
Copyright (c) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com |
||||||
|
Authors: David Faure <david.faure@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 <QSignalSpy> |
||||||
|
#include <QSortFilterProxyModel> |
||||||
|
#include <QTest> |
||||||
|
#include <QDebug> |
||||||
|
#include <QStandardItemModel> |
||||||
|
|
||||||
|
#include <QTreeView> |
||||||
|
|
||||||
|
#include <krearrangecolumnsproxymodel.h> |
||||||
|
#include "test_model_helpers.h" |
||||||
|
using namespace TestModelHelpers; |
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(QModelIndex) |
||||||
|
|
||||||
|
class tst_KRearrangeColumnsProxyModel : public QObject |
||||||
|
{ |
||||||
|
Q_OBJECT |
||||||
|
|
||||||
|
private Q_SLOTS: |
||||||
|
|
||||||
|
void initTestCase() |
||||||
|
{ |
||||||
|
qRegisterMetaType<QModelIndex>(); |
||||||
|
} |
||||||
|
|
||||||
|
void init() |
||||||
|
{ |
||||||
|
// Prepare the source model to use later on
|
||||||
|
mod.clear(); |
||||||
|
mod.appendRow(makeStandardItems(QStringList() << "A" << "B" << "C" << "D" << "E")); |
||||||
|
mod.item(0, 0)->appendRow(makeStandardItems(QStringList() << "m" << "n" << "o" << "p" << "-")); |
||||||
|
mod.item(0, 0)->appendRow(makeStandardItems(QStringList() << "q" << "r" << "s" << "t" << "-")); |
||||||
|
mod.appendRow(makeStandardItems(QStringList() << "E" << "F" << "G" << "H" << "I")); |
||||||
|
mod.item(1, 0)->appendRow(makeStandardItems(QStringList() << "x" << "y" << "z" << "." << "-")); |
||||||
|
mod.setHorizontalHeaderLabels(QStringList() << "H1" << "H2" << "H3" << "H4" << "H5"); |
||||||
|
|
||||||
|
QCOMPARE(extractRowTexts(&mod, 0), QString("ABCDE")); |
||||||
|
QCOMPARE(extractRowTexts(&mod, 0, mod.index(0, 0)), QString("mnop-")); |
||||||
|
QCOMPARE(extractRowTexts(&mod, 1, mod.index(0, 0)), QString("qrst-")); |
||||||
|
QCOMPARE(extractRowTexts(&mod, 1), QString("EFGHI")); |
||||||
|
QCOMPARE(extractRowTexts(&mod, 0, mod.index(1, 0)), QString("xyz.-")); |
||||||
|
QCOMPARE(extractHorizontalHeaderTexts(&mod), QString("H1H2H3H4H5")); |
||||||
|
|
||||||
|
// test code to see the model
|
||||||
|
// showModel(&mod);
|
||||||
|
} |
||||||
|
|
||||||
|
void shouldShowNothingIfNoColumnSelection() |
||||||
|
{ |
||||||
|
// Given a rearrange-columns proxy
|
||||||
|
KRearrangeColumnsProxyModel pm; |
||||||
|
|
||||||
|
// When setting it to a source model
|
||||||
|
pm.setSourceModel(&mod); |
||||||
|
|
||||||
|
// Then the proxy should show nothing (no columns selected)
|
||||||
|
QCOMPARE(pm.rowCount(), mod.rowCount()); |
||||||
|
QCOMPARE(pm.columnCount(), 0); |
||||||
|
} |
||||||
|
|
||||||
|
void shouldRearrangeColumns() |
||||||
|
{ |
||||||
|
// Given a rearrange-columns proxy
|
||||||
|
KRearrangeColumnsProxyModel pm; |
||||||
|
|
||||||
|
// When setting it to a source model, with columns rearranged
|
||||||
|
setup(pm); |
||||||
|
|
||||||
|
// Then the proxy should show columns reordered
|
||||||
|
QCOMPARE(pm.rowCount(), 2); |
||||||
|
|
||||||
|
// (verify that the mapFromSource(mapToSource(x)) == x roundtrip works)
|
||||||
|
for (int row = 0; row < pm.rowCount(); ++row) { |
||||||
|
for (int col = 0; col < pm.columnCount(); ++col) { |
||||||
|
//qDebug() << "row" << row << "col" << col;
|
||||||
|
QCOMPARE(pm.mapFromSource(pm.mapToSource(pm.index(row, col))), pm.index(row, col)); |
||||||
|
} |
||||||
|
} |
||||||
|
QCOMPARE(indexRowCol(pm.index(0, 0)), QString("0,0")); |
||||||
|
|
||||||
|
QCOMPARE(pm.rowCount(pm.index(0, 0)), 2); |
||||||
|
QCOMPARE(pm.index(0, 0).parent(), QModelIndex()); |
||||||
|
|
||||||
|
QCOMPARE(pm.mapToSource(pm.index(0, 0)).column(), 2); // column 0 points to C
|
||||||
|
QCOMPARE(pm.mapToSource(pm.index(0, 1)).column(), 3); // column 1 points to D
|
||||||
|
|
||||||
|
QCOMPARE(extractRowTexts(&pm, 0), QString("CDBA")); |
||||||
|
QCOMPARE(extractRowTexts(&pm, 0, pm.index(0, 0)), QString("opnm")); |
||||||
|
QCOMPARE(extractRowTexts(&pm, 1, pm.index(0, 0)), QString("strq")); |
||||||
|
QCOMPARE(extractRowTexts(&pm, 1), QString("GHFE")); |
||||||
|
QCOMPARE(extractRowTexts(&pm, 0, pm.index(1, 0)), QString("z.yx")); |
||||||
|
QCOMPARE(extractHorizontalHeaderTexts(&pm), QString("H3H4H2H1")); |
||||||
|
|
||||||
|
// Verify tree structure of proxy
|
||||||
|
const QModelIndex secondParent = pm.index(1, 0); |
||||||
|
QVERIFY(!secondParent.parent().isValid()); |
||||||
|
QCOMPARE(indexToText(pm.index(0, 0, secondParent).parent()), indexToText(secondParent)); |
||||||
|
QCOMPARE(indexToText(pm.index(0, 3, secondParent).parent()), indexToText(secondParent)); |
||||||
|
|
||||||
|
QVERIFY(!pm.canFetchMore(QModelIndex())); |
||||||
|
} |
||||||
|
|
||||||
|
void shouldHandleDataChanged() |
||||||
|
{ |
||||||
|
// Given a rearrange-columns proxy
|
||||||
|
KRearrangeColumnsProxyModel pm; |
||||||
|
setup(pm); |
||||||
|
|
||||||
|
QSignalSpy dataChangedSpy(&pm, SIGNAL(dataChanged(QModelIndex,QModelIndex))); |
||||||
|
|
||||||
|
// When a cell in a source model changes
|
||||||
|
mod.item(0, 2)->setData("c", Qt::EditRole); |
||||||
|
mod.item(0, 3)->setData("d", Qt::EditRole); |
||||||
|
|
||||||
|
// Then the change should be notified to the proxy
|
||||||
|
QCOMPARE(dataChangedSpy.count(), 2); |
||||||
|
QCOMPARE(indexToText(dataChangedSpy.at(0).at(0).value<QModelIndex>()), indexToText(pm.index(0, 0))); |
||||||
|
QCOMPARE(indexToText(dataChangedSpy.at(1).at(0).value<QModelIndex>()), indexToText(pm.index(0, 1))); |
||||||
|
QCOMPARE(extractRowTexts(&pm, 0), QString("cdBA")); |
||||||
|
} |
||||||
|
|
||||||
|
void shouldHandleDataChangedInChild() |
||||||
|
{ |
||||||
|
// Given a rearrange-columns proxy
|
||||||
|
KRearrangeColumnsProxyModel pm; |
||||||
|
setup(pm); |
||||||
|
|
||||||
|
QSignalSpy dataChangedSpy(&pm, SIGNAL(dataChanged(QModelIndex,QModelIndex))); |
||||||
|
|
||||||
|
// When a cell in a source model changes
|
||||||
|
mod.item(1, 0)->child(0, 3)->setData(",", Qt::EditRole); |
||||||
|
|
||||||
|
// Then the change should be notified to the proxy
|
||||||
|
QCOMPARE(dataChangedSpy.count(), 1); |
||||||
|
QCOMPARE(indexToText(dataChangedSpy.at(0).at(0).value<QModelIndex>()), indexToText(pm.index(1, 0).child(0, 1))); |
||||||
|
QCOMPARE(extractRowTexts(&pm, 0, pm.index(1, 0)), QString("z,yx")); |
||||||
|
} |
||||||
|
|
||||||
|
void shouldSupportSetData() |
||||||
|
{ |
||||||
|
// Given a rearrange-columns proxy
|
||||||
|
KRearrangeColumnsProxyModel pm; |
||||||
|
setup(pm); |
||||||
|
|
||||||
|
QSignalSpy dataChangedSpy(&pm, SIGNAL(dataChanged(QModelIndex,QModelIndex))); |
||||||
|
|
||||||
|
// When changing data via the proxy
|
||||||
|
const QModelIndex idx = pm.index(0, 2); |
||||||
|
QCOMPARE(idx.data().toString(), QString("B")); |
||||||
|
pm.setData(idx, QString("Z")); |
||||||
|
QCOMPARE(idx.data().toString(), QString("Z")); |
||||||
|
QCOMPARE(extractRowTexts(&pm, 0), QString("CDZA")); |
||||||
|
QCOMPARE(extractRowTexts(&mod, 0), QString("AZCDE")); |
||||||
|
} |
||||||
|
|
||||||
|
private: |
||||||
|
|
||||||
|
// setup proxy
|
||||||
|
void setup(KRearrangeColumnsProxyModel &pm) |
||||||
|
{ |
||||||
|
pm.setSourceColumns(QVector<int>() << 2 << 3 << 1 << 0); |
||||||
|
pm.setSourceModel(&mod); |
||||||
|
pm.sort(0); // don't forget this!
|
||||||
|
} |
||||||
|
|
||||||
|
static QString indexRowCol(const QModelIndex &index) |
||||||
|
{ |
||||||
|
if (!index.isValid()) { |
||||||
|
return "invalid"; |
||||||
|
} |
||||||
|
return QString::number(index.row()) + "," + QString::number(index.column()); |
||||||
|
} |
||||||
|
|
||||||
|
static QString indexToText(const QModelIndex &index) |
||||||
|
{ |
||||||
|
if (!index.isValid()) { |
||||||
|
return "invalid"; |
||||||
|
} |
||||||
|
return QString::number(index.row()) + "," + QString::number(index.column()) + "," |
||||||
|
+ QString::number(reinterpret_cast<qulonglong>(index.internalPointer()), 16) |
||||||
|
+ " in " + QString::number(reinterpret_cast<qulonglong>(index.model()), 16); |
||||||
|
} |
||||||
|
|
||||||
|
QStandardItemModel mod; |
||||||
|
}; |
||||||
|
|
||||||
|
QTEST_MAIN(tst_KRearrangeColumnsProxyModel) |
||||||
|
|
||||||
|
#include "krearrangecolumnsproxymodeltest.moc" |
||||||
@ -0,0 +1,62 @@ |
|||||||
|
/*
|
||||||
|
Copyright (c) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com |
||||||
|
Authors: David Faure <david.faure@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 <QString> |
||||||
|
|
||||||
|
namespace TestModelHelpers |
||||||
|
{ |
||||||
|
|
||||||
|
// Prepares one row for a QStandardItemModel
|
||||||
|
inline QList<QStandardItem *> makeStandardItems(const QStringList &texts) |
||||||
|
{ |
||||||
|
QList<QStandardItem *> items; |
||||||
|
foreach (const QString &txt, texts) { |
||||||
|
items << new QStandardItem(txt); |
||||||
|
} |
||||||
|
return items; |
||||||
|
} |
||||||
|
|
||||||
|
// Extracts a full row from a model as a string
|
||||||
|
// Works best if every cell contains only one character
|
||||||
|
inline QString extractRowTexts(QAbstractItemModel *model, int row, const QModelIndex &parent = QModelIndex()) |
||||||
|
{ |
||||||
|
QString result; |
||||||
|
const int colCount = model->columnCount(); |
||||||
|
for (int col = 0; col < colCount; ++col) { |
||||||
|
const QString txt = model->index(row, col, parent).data().toString(); |
||||||
|
result += txt.isEmpty() ? QString::fromLatin1(" ") : txt; |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
// Extracts all headers
|
||||||
|
inline QString extractHorizontalHeaderTexts(QAbstractItemModel *model) |
||||||
|
{ |
||||||
|
QString result; |
||||||
|
const int colCount = model->columnCount(); |
||||||
|
for (int col = 0; col < colCount; ++col) { |
||||||
|
const QString txt = model->headerData(col, Qt::Horizontal).toString(); |
||||||
|
result += txt.isEmpty() ? QString::fromLatin1(" ") : txt; |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
@ -0,0 +1,129 @@ |
|||||||
|
/*
|
||||||
|
Copyright (c) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com |
||||||
|
Authors: David Faure <david.faure@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 "krearrangecolumnsproxymodel.h" |
||||||
|
|
||||||
|
class KRearrangeColumnsProxyModelPrivate |
||||||
|
{ |
||||||
|
public: |
||||||
|
QVector<int> m_sourceColumns; |
||||||
|
}; |
||||||
|
|
||||||
|
KRearrangeColumnsProxyModel::KRearrangeColumnsProxyModel(QObject *parent) |
||||||
|
: QIdentityProxyModel(parent), |
||||||
|
d_ptr(new KRearrangeColumnsProxyModelPrivate) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
KRearrangeColumnsProxyModel::~KRearrangeColumnsProxyModel() |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
void KRearrangeColumnsProxyModel::setSourceColumns(const QVector<int> &columns) |
||||||
|
{ |
||||||
|
d_ptr->m_sourceColumns = columns; |
||||||
|
} |
||||||
|
|
||||||
|
int KRearrangeColumnsProxyModel::columnCount(const QModelIndex &parent) const |
||||||
|
{ |
||||||
|
Q_UNUSED(parent); |
||||||
|
return d_ptr->m_sourceColumns.count(); |
||||||
|
} |
||||||
|
|
||||||
|
int KRearrangeColumnsProxyModel::rowCount(const QModelIndex &parent) const |
||||||
|
{ |
||||||
|
Q_ASSERT(parent.isValid() ? parent.model() == this : true); |
||||||
|
// The parent in the source model is on column 0, whatever swapping we are doing
|
||||||
|
const QModelIndex sourceParent = mapToSource(parent).sibling(parent.row(), 0); |
||||||
|
return sourceModel()->rowCount(sourceParent); |
||||||
|
} |
||||||
|
|
||||||
|
// We derive from QIdentityProxyModel simply to be able to use
|
||||||
|
// its mapFromSource method which has friend access to createIndex() in the source model.
|
||||||
|
|
||||||
|
QModelIndex KRearrangeColumnsProxyModel::index(int row, int column, const QModelIndex &parent) const |
||||||
|
{ |
||||||
|
Q_ASSERT(parent.isValid() ? parent.model() == this : true); |
||||||
|
Q_ASSERT(row >= 0); |
||||||
|
Q_ASSERT(column >= 0); |
||||||
|
|
||||||
|
// The parent in the source model is on column 0, whatever swapping we are doing
|
||||||
|
const QModelIndex sourceParent = mapToSource(parent).sibling(parent.row(), 0); |
||||||
|
|
||||||
|
// Find the child in the source model, we need its internal pointer
|
||||||
|
const QModelIndex sourceIndex = sourceModel()->index(row, sourceColumnForProxyColumn(column), sourceParent); |
||||||
|
Q_ASSERT(sourceIndex.isValid()); |
||||||
|
|
||||||
|
return createIndex(row, column, sourceIndex.internalPointer()); |
||||||
|
} |
||||||
|
|
||||||
|
QModelIndex KRearrangeColumnsProxyModel::parent(const QModelIndex &child) const |
||||||
|
{ |
||||||
|
Q_ASSERT(child.isValid() ? child.model() == this : true); |
||||||
|
const QModelIndex sourceIndex = mapToSource(child); |
||||||
|
const QModelIndex sourceParent = sourceIndex.parent(); |
||||||
|
if (!sourceParent.isValid()) { |
||||||
|
return QModelIndex(); |
||||||
|
} |
||||||
|
return createIndex(sourceParent.row(), 0, sourceParent.internalPointer()); |
||||||
|
} |
||||||
|
|
||||||
|
QVariant KRearrangeColumnsProxyModel::headerData(int section, Qt::Orientation orientation, int role) const |
||||||
|
{ |
||||||
|
if (orientation == Qt::Horizontal) { |
||||||
|
const int sourceCol = sourceColumnForProxyColumn(section); |
||||||
|
return sourceModel()->headerData(sourceCol, orientation, role); |
||||||
|
} else { |
||||||
|
return QIdentityProxyModel::headerData(section, orientation, role); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
QModelIndex KRearrangeColumnsProxyModel::mapFromSource(const QModelIndex &sourceIndex) const |
||||||
|
{ |
||||||
|
if (!sourceIndex.isValid()) { |
||||||
|
return QModelIndex(); |
||||||
|
} |
||||||
|
Q_ASSERT(sourceIndex.model() == sourceModel()); |
||||||
|
const int proxyColumn = proxyColumnForSourceColumn(sourceIndex.column()); |
||||||
|
return createIndex(sourceIndex.row(), proxyColumn, sourceIndex.internalPointer()); |
||||||
|
} |
||||||
|
|
||||||
|
QModelIndex KRearrangeColumnsProxyModel::mapToSource(const QModelIndex &proxyIndex) const |
||||||
|
{ |
||||||
|
if (!proxyIndex.isValid()) { |
||||||
|
return QModelIndex(); |
||||||
|
} |
||||||
|
// This is just an indirect way to call sourceModel->createIndex(row, sourceColumn, pointer)
|
||||||
|
const QModelIndex fakeIndex = createIndex(proxyIndex.row(), sourceColumnForProxyColumn(proxyIndex.column()), proxyIndex.internalPointer()); |
||||||
|
return QIdentityProxyModel::mapToSource(fakeIndex); |
||||||
|
} |
||||||
|
|
||||||
|
int KRearrangeColumnsProxyModel::proxyColumnForSourceColumn(int sourceColumn) const |
||||||
|
{ |
||||||
|
// If this is too slow, we could add a second QVector with index=logical_source_column value=desired_pos_in_proxy.
|
||||||
|
return d_ptr->m_sourceColumns.indexOf(sourceColumn); |
||||||
|
} |
||||||
|
|
||||||
|
int KRearrangeColumnsProxyModel::sourceColumnForProxyColumn(int proxyColumn) const |
||||||
|
{ |
||||||
|
Q_ASSERT(proxyColumn >= 0); |
||||||
|
Q_ASSERT(proxyColumn < d_ptr->m_sourceColumns.size()); |
||||||
|
return d_ptr->m_sourceColumns.at(proxyColumn); |
||||||
|
} |
||||||
@ -0,0 +1,96 @@ |
|||||||
|
/*
|
||||||
|
Copyright (c) 2015 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com |
||||||
|
Authors: David Faure <david.faure@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. |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef REARRANGECOLUMNSPROXYMODEL_H |
||||||
|
#define REARRANGECOLUMNSPROXYMODEL_H |
||||||
|
|
||||||
|
#include <QIdentityProxyModel> |
||||||
|
#include <QScopedPointer> |
||||||
|
#include "kitemmodels_export.h" |
||||||
|
|
||||||
|
class KRearrangeColumnsProxyModelPrivate; |
||||||
|
|
||||||
|
/**
|
||||||
|
* This proxy shows specific columns from the source model, in any order. |
||||||
|
* This allows to reorder columns, as well as not showing all of them. |
||||||
|
* |
||||||
|
* The proxy supports source models that have a tree structure. |
||||||
|
* It also supports editing, and propagating changes from the source model. |
||||||
|
* |
||||||
|
* Showing the same source column more than once is not supported. |
||||||
|
* |
||||||
|
* Author: David Faure, KDAB |
||||||
|
* @since 5.12 |
||||||
|
*/ |
||||||
|
class KITEMMODELS_EXPORT KRearrangeColumnsProxyModel : public QIdentityProxyModel |
||||||
|
{ |
||||||
|
Q_OBJECT |
||||||
|
public: |
||||||
|
/**
|
||||||
|
* Creates a KRearrangeColumnsProxyModel proxy. |
||||||
|
* Remember to call setSourceModel afterwards. |
||||||
|
*/ |
||||||
|
explicit KRearrangeColumnsProxyModel(QObject *parent = 0); |
||||||
|
/**
|
||||||
|
* Destructor. |
||||||
|
*/ |
||||||
|
~KRearrangeColumnsProxyModel(); |
||||||
|
|
||||||
|
// API
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the chosen source columns, in the desired order for the proxy columns |
||||||
|
* columns[proxyColumn=0] is the source column to show in the first proxy column, etc. |
||||||
|
* |
||||||
|
* Example: QVector<int>() << 2 << 1; |
||||||
|
* This examples configures the proxy to hide column 0, show column 2 from the source model, |
||||||
|
* then show column 1 from the source model. |
||||||
|
*/ |
||||||
|
void setSourceColumns(const QVector<int> &columns); |
||||||
|
|
||||||
|
// Implementation
|
||||||
|
|
||||||
|
/// @reimp
|
||||||
|
int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; |
||||||
|
/// @reimp
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; |
||||||
|
|
||||||
|
/// @reimp
|
||||||
|
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; |
||||||
|
/// @reimp
|
||||||
|
QModelIndex parent(const QModelIndex &child) const Q_DECL_OVERRIDE; |
||||||
|
|
||||||
|
/// @reimp
|
||||||
|
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const Q_DECL_OVERRIDE; |
||||||
|
/// @reimp
|
||||||
|
QModelIndex mapToSource(const QModelIndex &proxyIndex) const Q_DECL_OVERRIDE; |
||||||
|
|
||||||
|
/// @reimp
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; |
||||||
|
|
||||||
|
private: |
||||||
|
int proxyColumnForSourceColumn(int sourceColumn) const; |
||||||
|
int sourceColumnForProxyColumn(int proxyColumn) const; |
||||||
|
|
||||||
|
private: |
||||||
|
const QScopedPointer<KRearrangeColumnsProxyModelPrivate> d_ptr; |
||||||
|
}; |
||||||
|
|
||||||
|
#endif |
||||||
Loading…
Reference in new issue