KChart

KChartDatasetProxyModel.cpp
1 /*
2  * Copyright (C) 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved.
3  *
4  * This file is part of the KD Chart library.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 #include "KChartDatasetProxyModel.h"
21 
22 #include "KChartMath_p.h"
23 
24 #include <QtDebug>
25 
26 
27 using namespace KChart;
28 
30  : QSortFilterProxyModel( parent )
31 {
32 }
33 
34 QModelIndex DatasetProxyModel::buddy( const QModelIndex& index ) const
35 {
36  return index;
37 }
38 
39 Qt::ItemFlags DatasetProxyModel::flags( const QModelIndex& index ) const
40 {
41  return sourceModel()->flags( mapToSource( index ) );
42 }
43 
45  const DatasetDescriptionVector& configuration )
46 {
47  Q_ASSERT_X( sourceModel(), "DatasetProxyModel::setDatasetRowDescriptionVector",
48  "A source model must be set before the selection can be configured." );
49  initializeDatasetDecriptors( configuration, sourceModel()->rowCount(mRootIndex),
50  mRowSrcToProxyMap, mRowProxyToSrcMap );
51  invalidate(); // clear emits layoutChanged()
52 }
53 
55  const DatasetDescriptionVector& configuration )
56 {
57  Q_ASSERT_X( sourceModel(), "DatasetProxyModel::setDatasetColumnDescriptionVector",
58  "A source model must be set before the selection can be configured." );
59  initializeDatasetDecriptors( configuration, sourceModel()->columnCount(mRootIndex),
60  mColSrcToProxyMap, mColProxyToSrcMap );
61  invalidate(); // clear emits layoutChanged()
62 }
63 
65  const DatasetDescriptionVector& rowConfig,
66  const DatasetDescriptionVector& columnConfig )
67 {
68  setDatasetRowDescriptionVector( rowConfig );
69  setDatasetColumnDescriptionVector( columnConfig );
70 }
71 
72 QModelIndex DatasetProxyModel::index( int row, int column,
73  const QModelIndex &parent ) const
74 {
75  return mapFromSource( sourceModel()->index( mapProxyRowToSource(row),
76  mapProxyColumnToSource(column),
77  parent ) );
78 }
79 
81 {
82 // return mapFromSource( sourceModel()->parent( child ) );
83  return mapFromSource( sourceModel()->parent( mapToSource( child ) ) );
84 }
85 
87 {
88  Q_ASSERT_X( sourceModel(), "DatasetProxyModel::mapFromSource", "A source "
89  "model must be set before the selection can be configured." );
90 
91  if ( !sourceIndex.isValid() ) return sourceIndex;
92 
93  if ( mRowSrcToProxyMap.isEmpty() && mColSrcToProxyMap.isEmpty() )
94  {
95  return createIndex( sourceIndex.row(), sourceIndex.column(),
96  sourceIndex.internalPointer() );
97  } else {
98  int row = mapSourceRowToProxy( sourceIndex.row() );
99  int column = mapSourceColumnToProxy( sourceIndex.column() );
100  return createIndex( row, column, sourceIndex.internalPointer() );
101  }
102 }
103 
105 {
106  Q_ASSERT_X( sourceModel(), "DatasetProxyModel::mapToSource", "A source "
107  "model must be set before the selection can be configured." );
108 
109  if ( !proxyIndex.isValid() ) return proxyIndex;
110  if ( mRowSrcToProxyMap.isEmpty() && mColSrcToProxyMap.isEmpty() )
111  {
112  return sourceModel()->index( proxyIndex.row(), proxyIndex.column(), mRootIndex );
113  } else {
114  int row = mapProxyRowToSource( proxyIndex.row() );
115  int column = mapProxyColumnToSource( proxyIndex.column() );
116  return sourceModel()->index( row, column, mRootIndex );
117  }
118 }
119 
121  const QModelIndex & ) const
122 {
123  if ( mRowSrcToProxyMap.isEmpty() )
124  { // no row mapping set, all rows are passed down:
125  return true;
126  } else {
127  Q_ASSERT( sourceModel() );
128  Q_ASSERT( mRowSrcToProxyMap.size() == sourceModel()->rowCount(mRootIndex) );
129  if ( mRowSrcToProxyMap[sourceRow] == -1 )
130  { // this row is explicitly not accepted:
131  return false;
132  } else {
133  Q_ASSERT( mRowSrcToProxyMap[sourceRow] >= 0
134  && mRowSrcToProxyMap[sourceRow] < mRowSrcToProxyMap.size() );
135  return true;
136  }
137  }
138 }
139 
141  const QModelIndex & ) const
142 {
143  if ( mColSrcToProxyMap.isEmpty() )
144  { // no column mapping set up yet, all columns are passed down:
145  return true;
146  } else {
147  Q_ASSERT( sourceModel() );
148  Q_ASSERT( mColSrcToProxyMap.size() == sourceModel()->columnCount(mRootIndex) );
149  if ( mColSrcToProxyMap[sourceColumn] == -1 )
150  { // this column is explicitly not accepted:
151  return false;
152  } else {
153  Q_ASSERT( mColSrcToProxyMap[sourceColumn] >= 0
154  && mColSrcToProxyMap[sourceColumn] < mColSrcToProxyMap.size() );
155  return true;
156  }
157  }
158 }
159 
160 int DatasetProxyModel::mapProxyRowToSource( const int& proxyRow ) const
161 {
162  if ( mRowProxyToSrcMap.isEmpty() )
163  { // if no row mapping is set, we pass down the row:
164  return proxyRow;
165  } else {
166  Q_ASSERT( proxyRow >= 0 && proxyRow < mRowProxyToSrcMap.size() );
167  return mRowProxyToSrcMap[ proxyRow ];
168  }
169 }
170 
171 int DatasetProxyModel::mapProxyColumnToSource( const int& proxyColumn ) const
172 {
173  if ( mColProxyToSrcMap.isEmpty() )
174  { // if no column mapping is set, we pass down the column:
175  return proxyColumn;
176  } else {
177  Q_ASSERT( proxyColumn >= 0 && proxyColumn < mColProxyToSrcMap.size() );
178  return mColProxyToSrcMap[ proxyColumn ];
179  }
180 }
181 
182 int DatasetProxyModel::mapSourceRowToProxy( const int& sourceRow ) const
183 {
184  if ( mRowSrcToProxyMap.isEmpty() )
185  {
186  return sourceRow;
187  } else {
188  Q_ASSERT( sourceRow >= 0 && sourceRow < mRowSrcToProxyMap.size() );
189  return mRowSrcToProxyMap[sourceRow];
190  }
191 }
192 
193 int DatasetProxyModel::mapSourceColumnToProxy( const int& sourceColumn ) const
194 {
195  if ( mColSrcToProxyMap.isEmpty() )
196  {
197  return sourceColumn;
198  } else {
199  Q_ASSERT( sourceColumn >= 0 && sourceColumn < mColSrcToProxyMap.size() );
200  return mColSrcToProxyMap.at( sourceColumn ) ;
201  }
202 }
203 
205 {
206  mRowSrcToProxyMap.clear();
207  mRowProxyToSrcMap.clear();
208  mColSrcToProxyMap.clear();
209  mColProxyToSrcMap.clear();
210  invalidate();
211 }
212 
213 QVariant DatasetProxyModel::data(const QModelIndex &index, int role) const
214 {
215  return sourceModel()->data( mapToSource( index ), role );
216 }
217 
218 bool DatasetProxyModel::setData( const QModelIndex& index, const QVariant& value, int role )
219 {
220  return sourceModel()->setData( mapToSource( index ), value, role );
221 }
222 
223 QVariant DatasetProxyModel::headerData( int section, Qt::Orientation orientation, int role ) const
224 {
225  if ( orientation == Qt::Horizontal )
226  {
227  if ( mapProxyColumnToSource ( section ) == -1 )
228  {
229  return QVariant();
230  } else {
231  return sourceModel()->headerData( mapProxyColumnToSource( section ), orientation, role );
232  }
233  } else {
234  if ( mapProxyRowToSource ( section ) == -1 )
235  {
236  return QVariant();
237  } else {
238  return sourceModel()->headerData( mapProxyRowToSource ( section ), orientation, role );
239  }
240  }
241 }
242 
243 void DatasetProxyModel::initializeDatasetDecriptors(
244  const DatasetDescriptionVector& inConfiguration,
245  const int sourceCount,
246  DatasetDescriptionVector& outSourceToProxyMap,
247  DatasetDescriptionVector& outProxyToSourceMap )
248 {
249  // in the current mapping implementation, the proxy-to-source map is
250  // identical to the configuration vector:
251  outProxyToSourceMap = inConfiguration;
252  outSourceToProxyMap.fill( -1, sourceCount );
253 
254  for ( int index = 0; index < inConfiguration.size(); ++index ) {
255  // make sure the values in inConfiguration point to columns in the
256  // source model:
257 
258  if ( inConfiguration[index] == -1 ) {
259  continue;
260  }
261 
262  Q_ASSERT_X( inConfiguration[ index ] >= 0 && inConfiguration[ index ] < sourceCount,
263  "DatasetProxyModel::initializeDatasetDecriptors",
264  "column index outside of source model" );
265  Q_ASSERT_X( outSourceToProxyMap[ inConfiguration[ index ] ] == -1 ,
266  "DatasetProxyModel::initializeDatasetDecriptors",
267  "no duplicates allowed in mapping configuration, mapping has to be reversible" );
268 
269  outSourceToProxyMap[ inConfiguration[ index ] ] = index;
270  }
271 }
272 
274 {
275  if ( sourceModel() ) {
276  disconnect( sourceModel(), SIGNAL(layoutChanged()),
277  this, SLOT(resetDatasetDescriptions()) );
278  }
280  mRootIndex = QModelIndex();
281  if ( m ) {
282  connect( m, SIGNAL(layoutChanged()),
283  this, SLOT(resetDatasetDescriptions()) );
284  connect( m, SIGNAL(layoutChanged()), this, SIGNAL(layoutChanged()) );
285  }
287 }
288 
290 {
291  mRootIndex = rootIdx;
293 }
294 
virtual int rowCount(const QModelIndex &parent) const const =0
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const =0
void layoutChanged(const QList< QPersistentModelIndex > &parents, QAbstractItemModel::LayoutChangeHint hint)
QVariant data(const QModelIndex &index, int role) const override
Overloaded from base class.
virtual void setSourceModel(QAbstractItemModel *sourceModel) override
QVector< T > & fill(const T &value, int size)
bool setData(const QModelIndex &index, const QVariant &value, int role) override
Overloaded from base class.
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
virtual int rowCount(const QModelIndex &parent) const const override
void resetDatasetDescriptions()
Reset all dataset description.
void clear()
bool isValid() const const
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
Overloaded from base class.
void setSourceRootIndex(const QModelIndex &rootIdx)
Set the root index of the table in the source model.
Class only listed here to document inheritance of some KChart classes.
int row() const const
virtual int columnCount(const QModelIndex &parent) const const override
void * internalPointer() const const
virtual QVariant data(const QModelIndex &index, int role) const const =0
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override
Implements the mapping from the source to the proxy indexes.
void setDatasetRowDescriptionVector(const DatasetDescriptionVector &rowConfig)
Configure the dataset selection for the rows.
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const const
DatasetProxyModel(QObject *parent=nullptr)
Create a DatasetProxyModel.
QModelIndex createIndex(int row, int column, void *ptr) const const
bool filterAcceptsColumn(int sourceColumn, const QModelIndex &) const override
Decide whether the column is accepted.
Class only listed here to document inheritance of some KChart classes.
void setDatasetColumnDescriptionVector(const DatasetDescriptionVector &columnConfig)
Configure the dataset selection for the columns.
const T & at(int i) const const
QAbstractItemModel * sourceModel() const const
bool isEmpty() const const
virtual int columnCount(const QModelIndex &parent) const const =0
int column() const const
void setDatasetDescriptionVectors(const DatasetDescriptionVector &rowConfig, const DatasetDescriptionVector &columnConfig)
Convenience method to configure rows and columns in one step.
virtual bool setData(const QModelIndex &index, const QVariant &value, int role)
virtual Qt::ItemFlags flags(const QModelIndex &index) const const
Orientation
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
Decide whether the row is accepted.
Global namespace.
void setSourceModel(QAbstractItemModel *sourceModel) override
Overloaded from base class.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
int size() const const
QModelIndex mapToSource(const QModelIndex &proxyIndex) const override
Implements the mapping from the proxy to the source indexes.
typedef ItemFlags
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Thu Jan 14 2021 22:38:05 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.