KD Chart API Documentation  3.1
KDChartDatasetProxyModel.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** This file is part of the KD Chart library.
4 **
5 ** SPDX-FileCopyrightText: 2001 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
6 **
7 ** SPDX-License-Identifier: MIT
8 **
9 ****************************************************************************/
10 
12 
13 #include <QtDebug>
14 
15 #include <KDABLibFakes>
16 
17 using namespace KDChart;
18 
20  : QSortFilterProxyModel(parent)
21 {
22 }
23 
24 QModelIndex DatasetProxyModel::buddy(const QModelIndex &index) const
25 {
26  return index;
27 }
28 
29 Qt::ItemFlags DatasetProxyModel::flags(const QModelIndex &index) const
30 {
31  return sourceModel()->flags(mapToSource(index));
32 }
33 
35  const DatasetDescriptionVector &configuration)
36 {
37  Q_ASSERT_X(sourceModel(), "DatasetProxyModel::setDatasetRowDescriptionVector",
38  "A source model must be set before the selection can be configured.");
39  initializeDatasetDecriptors(configuration, sourceModel()->rowCount(mRootIndex),
40  mRowSrcToProxyMap, mRowProxyToSrcMap);
41  invalidate();
42 }
43 
45  const DatasetDescriptionVector &configuration)
46 {
47  Q_ASSERT_X(sourceModel(), "DatasetProxyModel::setDatasetColumnDescriptionVector",
48  "A source model must be set before the selection can be configured.");
49  initializeDatasetDecriptors(configuration, sourceModel()->columnCount(mRootIndex),
50  mColSrcToProxyMap, mColProxyToSrcMap);
51  invalidate();
52 }
53 
55  const DatasetDescriptionVector &rowConfig,
56  const DatasetDescriptionVector &columnConfig)
57 {
60 }
61 
62 QModelIndex DatasetProxyModel::index(int row, int column,
63  const QModelIndex &parent) const
64 {
65  return mapFromSource(sourceModel()->index(mapProxyRowToSource(row),
66  mapProxyColumnToSource(column),
67  parent));
68 }
69 
70 QModelIndex DatasetProxyModel::parent(const QModelIndex &child) const
71 {
72  // return mapFromSource( sourceModel()->parent( child ) );
73  return mapFromSource(sourceModel()->parent(mapToSource(child)));
74 }
75 
76 QModelIndex DatasetProxyModel::mapFromSource(const QModelIndex &sourceIndex) const
77 {
78  Q_ASSERT_X(sourceModel(), "DatasetProxyModel::mapFromSource", "A source "
79  "model must be set before the selection can be configured.");
80 
81  if (!sourceIndex.isValid())
82  return sourceIndex;
83 
84  if (mRowSrcToProxyMap.isEmpty() && mColSrcToProxyMap.isEmpty()) {
85  return createIndex(sourceIndex.row(), sourceIndex.column(),
86  sourceIndex.internalPointer());
87  } else {
88  int row = mapSourceRowToProxy(sourceIndex.row());
89  int column = mapSourceColumnToProxy(sourceIndex.column());
90  return createIndex(row, column, sourceIndex.internalPointer());
91  }
92 }
93 
94 QModelIndex DatasetProxyModel::mapToSource(const QModelIndex &proxyIndex) const
95 {
96  Q_ASSERT_X(sourceModel(), "DatasetProxyModel::mapToSource", "A source "
97  "model must be set before the selection can be configured.");
98 
99  if (!proxyIndex.isValid())
100  return proxyIndex;
101  if (mRowSrcToProxyMap.isEmpty() && mColSrcToProxyMap.isEmpty()) {
102  return sourceModel()->index(proxyIndex.row(), proxyIndex.column(), mRootIndex);
103  } else {
104  int row = mapProxyRowToSource(proxyIndex.row());
105  int column = mapProxyColumnToSource(proxyIndex.column());
106  return sourceModel()->index(row, column, mRootIndex);
107  }
108 }
109 
111  const QModelIndex &) const
112 {
113  if (mRowSrcToProxyMap.isEmpty()) { // no row mapping set, all rows are passed down:
114  return true;
115  } else {
116  Q_ASSERT(sourceModel());
117  Q_ASSERT(mRowSrcToProxyMap.size() == sourceModel()->rowCount(mRootIndex));
118  if (mRowSrcToProxyMap[sourceRow] == -1) { // this row is explicitly not accepted:
119  return false;
120  } else {
121  Q_ASSERT(mRowSrcToProxyMap[sourceRow] >= 0
122  && mRowSrcToProxyMap[sourceRow] < mRowSrcToProxyMap.size());
123  return true;
124  }
125  }
126 }
127 
129  const QModelIndex &) const
130 {
131  if (mColSrcToProxyMap.isEmpty()) { // no column mapping set up yet, all columns are passed down:
132  return true;
133  } else {
134  Q_ASSERT(sourceModel());
135  Q_ASSERT(mColSrcToProxyMap.size() == sourceModel()->columnCount(mRootIndex));
136  if (mColSrcToProxyMap[sourceColumn] == -1) { // this column is explicitly not accepted:
137  return false;
138  } else {
139  Q_ASSERT(mColSrcToProxyMap[sourceColumn] >= 0
140  && mColSrcToProxyMap[sourceColumn] < mColSrcToProxyMap.size());
141  return true;
142  }
143  }
144 }
145 
146 int DatasetProxyModel::mapProxyRowToSource(const int &proxyRow) const
147 {
148  if (mRowProxyToSrcMap.isEmpty()) { // if no row mapping is set, we pass down the row:
149  return proxyRow;
150  } else {
151  Q_ASSERT(proxyRow >= 0 && proxyRow < mRowProxyToSrcMap.size());
152  return mRowProxyToSrcMap[proxyRow];
153  }
154 }
155 
156 int DatasetProxyModel::mapProxyColumnToSource(const int &proxyColumn) const
157 {
158  if (mColProxyToSrcMap.isEmpty()) { // if no column mapping is set, we pass down the column:
159  return proxyColumn;
160  } else {
161  Q_ASSERT(proxyColumn >= 0 && proxyColumn < mColProxyToSrcMap.size());
162  return mColProxyToSrcMap[proxyColumn];
163  }
164 }
165 
166 int DatasetProxyModel::mapSourceRowToProxy(const int &sourceRow) const
167 {
168  if (mRowSrcToProxyMap.isEmpty()) {
169  return sourceRow;
170  } else {
171  Q_ASSERT(sourceRow >= 0 && sourceRow < mRowSrcToProxyMap.size());
172  return mRowSrcToProxyMap[sourceRow];
173  }
174 }
175 
176 int DatasetProxyModel::mapSourceColumnToProxy(const int &sourceColumn) const
177 {
178  if (mColSrcToProxyMap.isEmpty()) {
179  return sourceColumn;
180  } else {
181  Q_ASSERT(sourceColumn >= 0 && sourceColumn < mColSrcToProxyMap.size());
182  return mColSrcToProxyMap.at(sourceColumn);
183  }
184 }
185 
187 {
188  mRowSrcToProxyMap.clear();
189  mRowProxyToSrcMap.clear();
190  mColSrcToProxyMap.clear();
191  mColProxyToSrcMap.clear();
192  invalidate();
193 }
194 
195 QVariant DatasetProxyModel::data(const QModelIndex &index, int role) const
196 {
197  return sourceModel()->data(mapToSource(index), role);
198 }
199 
200 bool DatasetProxyModel::setData(const QModelIndex &index, const QVariant &value, int role)
201 {
202  return sourceModel()->setData(mapToSource(index), value, role);
203 }
204 
205 QVariant DatasetProxyModel::headerData(int section, Qt::Orientation orientation, int role) const
206 {
207  if (orientation == Qt::Horizontal) {
208  if (mapProxyColumnToSource(section) == -1) {
209  return QVariant();
210  } else {
211  return sourceModel()->headerData(mapProxyColumnToSource(section), orientation, role);
212  }
213  } else {
214  if (mapProxyRowToSource(section) == -1) {
215  return QVariant();
216  } else {
217  return sourceModel()->headerData(mapProxyRowToSource(section), orientation, role);
218  }
219  }
220 }
221 
222 void DatasetProxyModel::initializeDatasetDecriptors(
223  const DatasetDescriptionVector &inConfiguration,
224  const int sourceCount,
225  DatasetDescriptionVector &outSourceToProxyMap,
226  DatasetDescriptionVector &outProxyToSourceMap)
227 {
228  // in the current mapping implementation, the proxy-to-source map is
229  // identical to the configuration vector:
230  outProxyToSourceMap = inConfiguration;
231  outSourceToProxyMap.fill(-1, sourceCount);
232 
233  for (int index = 0; index < inConfiguration.size(); ++index) {
234  // make sure the values in inConfiguration point to columns in the
235  // source model:
236 
237  if (inConfiguration[index] == -1) {
238  continue;
239  }
240 
241  Q_ASSERT_X(inConfiguration[index] >= 0 && inConfiguration[index] < sourceCount,
242  "DatasetProxyModel::initializeDatasetDecriptors",
243  "column index outside of source model");
244  Q_ASSERT_X(outSourceToProxyMap[inConfiguration[index]] == -1,
245  "DatasetProxyModel::initializeDatasetDecriptors",
246  "no duplicates allowed in mapping configuration, mapping has to be reversible");
247 
248  outSourceToProxyMap[inConfiguration[index]] = index;
249  }
250 }
251 
252 void DatasetProxyModel::setSourceModel(QAbstractItemModel *m)
253 {
254  if (sourceModel()) {
255  disconnect(sourceModel(), &QAbstractItemModel::layoutChanged,
257  }
258  QSortFilterProxyModel::setSourceModel(m);
259  mRootIndex = QModelIndex();
260  if (m) {
261  connect(m, &QAbstractItemModel::layoutChanged,
263  connect(m, &QAbstractItemModel::layoutChanged, this, &DatasetProxyModel::layoutChanged);
264  }
266 }
267 
268 void DatasetProxyModel::setSourceRootIndex(const QModelIndex &rootIdx)
269 {
270  mRootIndex = rootIdx;
272 }
Qt::ItemFlags flags(const QModelIndex &index) const override
QModelIndex parent(const QModelIndex &child) const override
QVariant data(const QModelIndex &index, int role) const override
void setDatasetRowDescriptionVector(const DatasetDescriptionVector &rowConfig)
QModelIndex mapToSource(const QModelIndex &proxyIndex) const override
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
bool filterAcceptsColumn(int sourceColumn, const QModelIndex &) const override
DatasetProxyModel(QObject *parent=nullptr)
void setSourceRootIndex(const QModelIndex &rootIdx)
void setSourceModel(QAbstractItemModel *sourceModel) override
bool setData(const QModelIndex &index, const QVariant &value, int role) override
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
QModelIndex buddy(const QModelIndex &index) const override
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override
void setDatasetDescriptionVectors(const DatasetDescriptionVector &rowConfig, const DatasetDescriptionVector &columnConfig)
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
void setDatasetColumnDescriptionVector(const DatasetDescriptionVector &columnConfig)
QVector< int > DatasetDescriptionVector

© 2001 Klarälvdalens Datakonsult AB (KDAB)
"The Qt, C++ and OpenGL Experts"
https://www.kdab.com/
https://www.kdab.com/development-resources/qt-tools/kd-chart/
Generated by doxygen 1.9.1