KChart

KChartAttributesModel.cpp
1 /*
2  * SPDX-FileCopyrightText: 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved.
3  *
4  * This file is part of the KD Chart library.
5  *
6  * SPDX-License-Identifier: GPL-2.0-or-later
7  */
8 
9 #include "KChartAttributesModel.h"
10 
11 #include "KChartPalette.h"
12 #include "KChartGlobal.h"
13 #include "KChartMath_p.h"
14 
15 #include <QDebug>
16 #include <QPen>
17 #include <QPointer>
18 
19 #include <KChartTextAttributes.h>
20 #include <KChartFrameAttributes.h>
21 #include <KChartBackgroundAttributes.h>
23 #include <KChartMarkerAttributes.h>
24 #include <KChartBarAttributes.h>
25 #include <KChartStockBarAttributes.h>
26 #include <KChartLineAttributes.h>
27 #include <KChartPieAttributes.h>
28 #include <KChartAbstractThreeDAttributes.h>
29 #include <KChartThreeDBarAttributes.h>
30 #include <KChartThreeDLineAttributes.h>
31 #include <KChartThreeDPieAttributes.h>
32 #include <KChartGridAttributes.h>
33 #include <KChartValueTrackerAttributes.h>
34 
35 
36 using namespace KChart;
37 
38 
39 class Q_DECL_HIDDEN AttributesModel::Private
40 {
41 public:
42  Private();
43 
45  QMap< int, QMap< int, QVariant > > horizontalHeaderDataMap;
46  QMap< int, QMap< int, QVariant > > verticalHeaderDataMap;
47  QMap< int, QVariant > modelDataMap;
48  QMap< int, QVariant > defaultsMap;
49  int dataDimension;
50  AttributesModel::PaletteType paletteType;
51  Palette palette;
52 };
53 
54 AttributesModel::Private::Private()
55  : dataDimension( 1 ),
56  paletteType( AttributesModel::PaletteTypeDefault ),
57  palette( Palette::defaultPalette() )
58 {
59 }
60 
61 #define d d_func()
62 
63 AttributesModel::AttributesModel( QAbstractItemModel* model, QObject * parent/* = 0 */ )
64  : AbstractProxyModel( parent ),
65  _d( new Private )
66 {
67  setSourceModel( model );
68  setDefaultForRole( KChart::DataValueLabelAttributesRole,
69  DataValueAttributes::defaultAttributesAsVariant() );
70 }
71 
72 AttributesModel::~AttributesModel()
73 {
74  delete _d;
75  _d = nullptr;
76 }
77 
79 {
80  *d = *other->d;
81 }
82 
83 bool AttributesModel::compareHeaderDataMaps( const QMap< int, QMap< int, QVariant > >& mapA,
84  const QMap< int, QMap< int, QVariant > >& mapB ) const
85 {
86  if ( mapA.count() != mapB.count() ) {
87  return false;
88  }
89  QMap< int, QMap< int, QVariant > >::const_iterator itA = mapA.constBegin();
90  QMap< int, QMap< int, QVariant > >::const_iterator itB = mapB.constBegin();
91  for ( ; itA != mapA.constEnd(); ++itA, ++itB ) {
92  if ( itA->count() != itB->count() ) {
93  return false;
94  }
95  QMap< int, QVariant >::const_iterator it2A = itA->constBegin();
96  QMap< int, QVariant >::const_iterator it2B = itB->constBegin();
97  for ( ; it2A != itA->constEnd(); ++it2A, ++it2B ) {
98  if ( it2A.key() != it2B.key() ) {
99  return false;
100  }
101  if ( !compareAttributes( it2A.key(), it2A.value(), it2B.value() ) ) {
102  return false;
103  }
104  }
105  }
106  return true;
107 }
108 
109 bool AttributesModel::compare( const AttributesModel* other ) const
110 {
111  if ( other == this ) {
112  return true;
113  }
114  if ( !other || d->paletteType != other->d->paletteType ) {
115  return false;
116  }
117 
118  {
119  if ( d->dataMap.count() != other->d->dataMap.count() ) {
120  return false;
121  }
122  QMap< int, QMap< int, QMap<int, QVariant > > >::const_iterator itA = d->dataMap.constBegin();
123  QMap< int, QMap< int, QMap<int, QVariant > > >::const_iterator itB = other->d->dataMap.constBegin();
124  for ( ; itA != d->dataMap.constEnd(); ++itA, ++itB ) {
125  if ( itA->count() != itB->count() ) {
126  return false;
127  }
128  QMap< int, QMap< int, QVariant > >::const_iterator it2A = itA->constBegin();
129  QMap< int, QMap< int, QVariant > >::const_iterator it2B = itB->constBegin();
130  for ( ; it2A != itA->constEnd(); ++it2A, ++it2B ) {
131  if ( it2A->count() != it2B->count() ) {
132  return false;
133  }
134  QMap< int, QVariant >::const_iterator it3A = it2A->constBegin();
135  QMap< int, QVariant >::const_iterator it3B = it2B->constBegin();
136  for ( ; it3A != it2A->constEnd(); ++it3A, ++it3B ) {
137  if ( it3A.key() != it3B.key() ) {
138  return false;
139  }
140  if ( !compareAttributes( it3A.key(), it3A.value(), it3B.value() ) ) {
141  return false;
142  }
143  }
144  }
145  }
146  }
147 
148  if ( !compareHeaderDataMaps( d->horizontalHeaderDataMap, other->d->horizontalHeaderDataMap ) ||
149  !compareHeaderDataMaps( d->verticalHeaderDataMap, other->d->verticalHeaderDataMap ) ) {
150  return false;
151  }
152 
153  {
154  if ( d->modelDataMap.count() != other->d->modelDataMap.count() ) {
155  return false;
156  }
157  QMap< int, QVariant >::const_iterator itA = d->modelDataMap.constBegin();
158  QMap< int, QVariant >::const_iterator itB = other->d->modelDataMap.constBegin();
159  for ( ; itA != d->modelDataMap.constEnd(); ++itA, ++itB ) {
160  if ( itA.key() != itB.key() ) {
161  return false;
162  }
163  if ( !compareAttributes( itA.key(), itA.value(), itB.value() ) ) {
164  return false;
165  }
166  }
167  }
168  return true;
169 }
170 
171 bool AttributesModel::compareAttributes(
172  int role, const QVariant& a, const QVariant& b ) const
173 {
174  if ( isKnownAttributesRole( role ) ) {
175  switch ( role ) {
176  case DataValueLabelAttributesRole:
177  return (a.value<DataValueAttributes>() ==
179  case DatasetBrushRole:
180  return (a.value<QBrush>() ==
181  b.value<QBrush>());
182  case DatasetPenRole:
183  return (a.value<QPen>() ==
184  b.value<QPen>());
185  case ThreeDAttributesRole:
186  // As of yet there is no ThreeDAttributes class,
187  // and the AbstractThreeDAttributes class is pure virtual,
188  // so we ignore this role for now.
189  // (khz, 04.04.2007)
190  /*
191  return (qVariantValue<ThreeDAttributes>( a ) ==
192  qVariantValue<ThreeDAttributes>( b ));
193  */
194  break;
195  case LineAttributesRole:
196  return (a.value<LineAttributes>() ==
197  b.value<LineAttributes>());
198  case ThreeDLineAttributesRole:
199  return (a.value<ThreeDLineAttributes>() ==
201  case BarAttributesRole:
202  return (a.value<BarAttributes>() ==
203  b.value<BarAttributes>());
204  case StockBarAttributesRole:
205  return (a.value<StockBarAttributes>() ==
207  case ThreeDBarAttributesRole:
208  return (a.value<ThreeDBarAttributes>() ==
210  case PieAttributesRole:
211  return (a.value<PieAttributes>() ==
212  b.value<PieAttributes>());
213  case ThreeDPieAttributesRole:
214  return (a.value<ThreeDPieAttributes>() ==
216  case ValueTrackerAttributesRole:
217  return (a.value<ValueTrackerAttributes>() ==
219  case DataHiddenRole:
220  return (a.value<bool>() ==
221  b.value<bool>());
222  default:
223  Q_ASSERT( false ); // all of our own roles need to be handled
224  break;
225  }
226  } else {
227  return (a == b);
228  }
229  return true;
230 }
231 
232 
234  int role/* = Qt::DisplayRole */ ) const
235 {
236  if ( sourceModel() ) {
237  const QVariant sourceData = sourceModel()->headerData( section, orientation, role );
238  if ( sourceData.isValid() ) {
239  return sourceData;
240  }
241  }
242 
243  // the source model didn't have data set, let's use our stored values
244  const QMap< int, QMap< int, QVariant> >& map = orientation == Qt::Horizontal ?
245  d->horizontalHeaderDataMap : d->verticalHeaderDataMap;
246  QMap< int, QMap< int, QVariant > >::const_iterator mapIt = map.find( section );
247  if ( mapIt != map.constEnd() ) {
248  const QMap< int, QVariant >& dataMap = mapIt.value();
249  QMap< int, QVariant >::const_iterator dataMapIt = dataMap.find( role );
250  if ( dataMapIt != dataMap.constEnd() ) {
251  return dataMapIt.value();
252  }
253  }
254 
255  return defaultHeaderData( section, orientation, role );
256 }
257 
258 
259 QVariant AttributesModel::defaultHeaderData( int section, Qt::Orientation orientation, int role ) const
260 {
261  // Default values if nothing else matches
262 
263  const int dataset = section / d->dataDimension;
264 
265  switch ( role ) {
266  case Qt::DisplayRole:
267  //TODO for KChart 3.0: return QString::number( dataset + 1 );
268  return QVariant( (orientation == Qt::Vertical ? QStringLiteral("Series ") : QStringLiteral("Item ")) + QString::number( dataset )) ;
269  case KChart::DatasetBrushRole:
270  return d->palette.getBrush( dataset );
271  case KChart::DatasetPenRole:
272  // if no per model override was set, use the (possibly default) color set for the brush
273  if ( !modelData( role ).isValid() ) {
274  QBrush brush = headerData( section, orientation, DatasetBrushRole ).value< QBrush >();
275  return QPen( brush.color() );
276  }
277  default:
278  break;
279  }
280 
281  return QVariant();
282 }
283 
284 
286 {
287  if ( isKnownAttributesRole( role ) ) {
288  // check if there is something set at global level
289  QVariant v = modelData( role );
290 
291  // else return the default setting, if any
292  if ( !v.isValid() )
293  v = defaultsForRole( role );
294  return v;
295  }
296  return QVariant();
297 }
298 
299 
300 QVariant AttributesModel::data( int column, int role ) const
301 {
302  if ( isKnownAttributesRole( role ) ) {
303  // check if there is something set for the column (dataset)
304  QVariant v;
305  v = headerData( column, Qt::Horizontal, role );
306 
307  // check if there is something set at global level
308  if ( !v.isValid() )
309  v = data( role ); // includes automatic fallback to default
310  return v;
311  }
312  return QVariant();
313 }
314 
315 
316 QVariant AttributesModel::data( const QModelIndex& index, int role ) const
317 {
318  if ( index.isValid() ) {
319  Q_ASSERT( index.model() == this );
320  }
321  if ( !sourceModel() ) {
322  return QVariant();
323  }
324 
325  if ( index.isValid() ) {
326  const QVariant sourceData = sourceModel()->data( mapToSource( index ), role );
327  if ( sourceData.isValid() ) {
328  return sourceData;
329  }
330  }
331 
332  // check if we are storing a value for this role at this cell index
333  if ( d->dataMap.contains( index.column() ) ) {
334  const QMap< int, QMap< int, QVariant > >& colDataMap = d->dataMap[ index.column() ];
335  if ( colDataMap.contains( index.row() ) ) {
336  const QMap< int, QVariant >& dataMap = colDataMap[ index.row() ];
337  if ( dataMap.contains( role ) ) {
338  const QVariant v = dataMap[ role ];
339  if ( v.isValid() ) {
340  return v;
341  }
342  }
343  }
344  }
345  // check if there is something set for the column (dataset), or at global level
346  if ( index.isValid() ) {
347  return data( index.column(), role ); // includes automatic fallback to default
348  }
349 
350  return QVariant();
351 }
352 
353 
355 {
356  switch ( role ) {
357  // fallthrough intended
358  case DataValueLabelAttributesRole:
359  case DatasetBrushRole:
360  case DatasetPenRole:
361  case ThreeDAttributesRole:
362  case LineAttributesRole:
363  case ThreeDLineAttributesRole:
364  case BarAttributesRole:
365  case StockBarAttributesRole:
366  case ThreeDBarAttributesRole:
367  case PieAttributesRole:
368  case ThreeDPieAttributesRole:
369  case ValueTrackerAttributesRole:
370  case DataHiddenRole:
371  return true;
372  default:
373  return false;
374  }
375 }
376 
377 QVariant AttributesModel::defaultsForRole( int role ) const
378 {
379  // returns default-constructed QVariant if not found
380  return d->defaultsMap.value( role );
381 }
382 
383 bool AttributesModel::setData ( const QModelIndex & index, const QVariant & value, int role )
384 {
385  if ( !isKnownAttributesRole( role ) ) {
386  return sourceModel()->setData( mapToSource(index), value, role );
387  } else {
388  QMap< int, QMap< int, QVariant> > &colDataMap = d->dataMap[ index.column() ];
389  QMap< int, QVariant > &dataMap = colDataMap[ index.row() ];
390  dataMap.insert( role, value );
391  Q_EMIT attributesChanged( index, index );
392  return true;
393  }
394 }
395 
396 bool AttributesModel::resetData ( const QModelIndex & index, int role )
397 {
398  return setData( index, QVariant(), role );
399 }
400 
401 bool AttributesModel::setHeaderData ( int section, Qt::Orientation orientation,
402  const QVariant & value, int role )
403 {
404  if ( sourceModel() && headerData( section, orientation, role ) == value ) {
405  return true;
406  }
407 
408  if ( !isKnownAttributesRole( role ) ) {
409  return sourceModel()->setHeaderData( section, orientation, value, role );
410  } else {
411  QMap< int, QMap<int, QVariant > > &sectionDataMap
412  = orientation == Qt::Horizontal ? d->horizontalHeaderDataMap : d->verticalHeaderDataMap;
413 
414  QMap< int, QVariant > &dataMap = sectionDataMap[ section ];
415  dataMap.insert( role, value );
416  if ( sourceModel() ) {
417  int numRows = rowCount( QModelIndex() );
418  int numCols = columnCount( QModelIndex() );
419  if ( orientation == Qt::Horizontal && numRows > 0 )
420  Q_EMIT attributesChanged( index( 0, section, QModelIndex() ),
421  index( numRows - 1, section, QModelIndex() ) );
422  else if ( orientation == Qt::Vertical && numCols > 0 )
423  Q_EMIT attributesChanged( index( section, 0, QModelIndex() ),
424  index( section, numCols - 1, QModelIndex() ) );
425  Q_EMIT headerDataChanged( orientation, section, section );
426 
427  // FIXME: This only makes sense for orientation == Qt::Horizontal,
428  // but what if orientation == Qt::Vertical?
429  if ( section != -1 && numRows > 0 )
430  Q_EMIT dataChanged( index( 0, section, QModelIndex() ),
431  index( numRows - 1, section, QModelIndex() ) );
432  }
433  return true;
434  }
435 }
436 
437 bool AttributesModel::resetHeaderData ( int section, Qt::Orientation orientation, int role )
438 {
439  return setHeaderData ( section, orientation, QVariant(), role );
440 }
441 
442 void AttributesModel::setPaletteType( AttributesModel::PaletteType type )
443 {
444  if ( d->paletteType == type ) {
445  return;
446  }
447  d->paletteType = type;
448  switch ( type ) {
449  case PaletteTypeDefault:
450  d->palette = Palette::defaultPalette();
451  break;
452  case PaletteTypeSubdued:
453  d->palette = Palette::subduedPalette();
454  break;
455  case PaletteTypeRainbow:
456  d->palette = Palette::rainbowPalette();
457  break;
458  default:
459  qWarning( "Unknown palette type!" );
460  }
461 }
462 
463 AttributesModel::PaletteType AttributesModel::paletteType() const
464 {
465  return d->paletteType;
466 }
467 
468 bool KChart::AttributesModel::setModelData( const QVariant value, int role )
469 {
470  d->modelDataMap.insert( role, value );
471  int numRows = rowCount( QModelIndex() );
472  int numCols = columnCount( QModelIndex() );
473  if ( sourceModel() && numRows > 0 && numCols > 0 ) {
474  Q_EMIT attributesChanged( index( 0, 0, QModelIndex() ),
475  index( numRows - 1, numCols - 1, QModelIndex() ) );
476  beginResetModel();
477  endResetModel();
478  }
479  return true;
480 }
481 
482 QVariant KChart::AttributesModel::modelData( int role ) const
483 {
484  return d->modelDataMap.value( role, QVariant() );
485 }
486 
487 int AttributesModel::rowCount( const QModelIndex& index ) const
488 {
489  if ( sourceModel() ) {
490  return sourceModel()->rowCount( mapToSource(index) );
491  } else {
492  return 0;
493  }
494 }
495 
496 int AttributesModel::columnCount( const QModelIndex& index ) const
497 {
498  if ( sourceModel() ) {
499  return sourceModel()->columnCount( mapToSource(index) );
500  } else {
501  return 0;
502  }
503 }
504 
506 {
507  if ( this->sourceModel() != nullptr )
508  {
509  disconnect( this->sourceModel(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
510  this, SLOT(slotDataChanged(QModelIndex,QModelIndex)));
511  disconnect( this->sourceModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
512  this, SLOT(slotRowsInserted(QModelIndex,int,int)) );
513  disconnect( this->sourceModel(), SIGNAL(rowsRemoved(QModelIndex,int,int)),
514  this, SLOT(slotRowsRemoved(QModelIndex,int,int)) );
515  disconnect( this->sourceModel(), SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
516  this, SLOT(slotRowsAboutToBeInserted(QModelIndex,int,int)) );
517  disconnect( this->sourceModel(), SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
518  this, SLOT(slotRowsAboutToBeRemoved(QModelIndex,int,int)) );
519  disconnect( this->sourceModel(), SIGNAL(columnsInserted(QModelIndex,int,int)),
520  this, SLOT(slotColumnsInserted(QModelIndex,int,int)) );
521  disconnect( this->sourceModel(), SIGNAL(columnsRemoved(QModelIndex,int,int)),
522  this, SLOT(slotColumnsRemoved(QModelIndex,int,int)) );
523  disconnect( this->sourceModel(), SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)),
524  this, SLOT(slotColumnsAboutToBeInserted(QModelIndex,int,int)) );
525  disconnect( this->sourceModel(), SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
526  this, SLOT(slotColumnsAboutToBeRemoved(QModelIndex,int,int)) );
527  disconnect( this->sourceModel(), SIGNAL(modelReset()),
528  this, SIGNAL(modelReset()) );
529  disconnect( this->sourceModel(), SIGNAL(layoutChanged()),
530  this, SIGNAL(layoutChanged()) );
531  }
533  if ( this->sourceModel() != nullptr )
534  {
535  connect( this->sourceModel(), SIGNAL(dataChanged(QModelIndex,QModelIndex)),
536  this, SLOT(slotDataChanged(QModelIndex,QModelIndex)));
537  connect( this->sourceModel(), SIGNAL(rowsInserted(QModelIndex,int,int)),
538  this, SLOT(slotRowsInserted(QModelIndex,int,int)) );
539  connect( this->sourceModel(), SIGNAL(rowsRemoved(QModelIndex,int,int)),
540  this, SLOT(slotRowsRemoved(QModelIndex,int,int)) );
541  connect( this->sourceModel(), SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)),
542  this, SLOT(slotRowsAboutToBeInserted(QModelIndex,int,int)) );
543  connect( this->sourceModel(), SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
544  this, SLOT(slotRowsAboutToBeRemoved(QModelIndex,int,int)) );
545  connect( this->sourceModel(), SIGNAL(columnsInserted(QModelIndex,int,int)),
546  this, SLOT(slotColumnsInserted(QModelIndex,int,int)) );
547  connect( this->sourceModel(), SIGNAL(columnsRemoved(QModelIndex,int,int)),
548  this, SLOT(slotColumnsRemoved(QModelIndex,int,int)) );
549  connect( this->sourceModel(), SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)),
550  this, SLOT(slotColumnsAboutToBeInserted(QModelIndex,int,int)) );
551  connect( this->sourceModel(), SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
552  this, SLOT(slotColumnsAboutToBeRemoved(QModelIndex,int,int)) );
553  connect( this->sourceModel(), SIGNAL(modelReset()),
554  this, SIGNAL(modelReset()) );
555  connect( this->sourceModel(), SIGNAL(layoutChanged()),
556  this, SIGNAL(layoutChanged()) );
557  }
558 }
559 
560 void AttributesModel::slotRowsAboutToBeInserted( const QModelIndex& parent, int start, int end )
561 {
562  beginInsertRows( mapFromSource( parent ), start, end );
563 }
564 
565 void AttributesModel::slotColumnsAboutToBeInserted( const QModelIndex& parent, int start, int end )
566 {
567  beginInsertColumns( mapFromSource( parent ), start, end );
568 }
569 
570 void AttributesModel::slotRowsInserted( const QModelIndex& parent, int start, int end )
571 {
572  Q_UNUSED( parent );
573  Q_UNUSED( start );
574  Q_UNUSED( end );
575  endInsertRows();
576 }
577 
578 void AttributesModel::slotColumnsInserted( const QModelIndex& parent, int start, int end )
579 {
580  Q_UNUSED( parent );
581  Q_UNUSED( start );
582  Q_UNUSED( end );
583  endInsertColumns();
584 }
585 
586 void AttributesModel::slotRowsAboutToBeRemoved( const QModelIndex& parent, int start, int end )
587 {
588  beginRemoveRows( mapFromSource( parent ), start, end );
589 }
590 
591 void AttributesModel::slotColumnsAboutToBeRemoved( const QModelIndex& parent, int start, int end )
592 {
593  beginRemoveColumns( mapFromSource( parent ), start, end );
594 }
595 
596 void AttributesModel::slotRowsRemoved( const QModelIndex& parent, int start, int end )
597 {
598  Q_UNUSED( parent );
599  Q_UNUSED( start );
600  Q_UNUSED( end );
601  endRemoveRows();
602 }
603 
604 void AttributesModel::removeEntriesFromDataMap( int start, int end )
605 {
606  QMap< int, QMap< int, QMap< int, QVariant > > >::iterator it = d->dataMap.find( end );
607  // check that the element was found
608  if ( it != d->dataMap.end() ) {
609  ++it;
610  QVector< int > indexesToDel;
611  for ( int i = start; i < end && it != d->dataMap.end(); ++i ) {
612  d->dataMap[ i ] = it.value();
613  indexesToDel << it.key();
614  ++it;
615  }
616  if ( indexesToDel.isEmpty() ) {
617  for ( int i = start; i < end; ++i ) {
618  indexesToDel << i;
619  }
620  }
621  for ( int i = 0; i < indexesToDel.count(); ++i ) {
622  d->dataMap.remove( indexesToDel[ i ] );
623  }
624  }
625 }
626 
627 void AttributesModel::removeEntriesFromDirectionDataMaps( Qt::Orientation dir, int start, int end )
628 {
629  QMap<int, QMap<int, QVariant> > &sectionDataMap
630  = dir == Qt::Horizontal ? d->horizontalHeaderDataMap : d->verticalHeaderDataMap;
631  QMap<int, QMap<int, QVariant> >::iterator it = sectionDataMap.upperBound( end );
632  // check that the element was found
633  if ( it != sectionDataMap.end() )
634  {
635  QVector< int > indexesToDel;
636  for ( int i = start; i < end && it != sectionDataMap.end(); ++i )
637  {
638  sectionDataMap[ i ] = it.value();
639  indexesToDel << it.key();
640  ++it;
641  }
642  if ( indexesToDel.isEmpty() )
643  {
644  for ( int i = start; i < end; ++i )
645  {
646  indexesToDel << i;
647  }
648  }
649  for ( int i = 0; i < indexesToDel.count(); ++i )
650  {
651  sectionDataMap.remove( indexesToDel[ i ] );
652  }
653  }
654 }
655 
656 void AttributesModel::slotColumnsRemoved( const QModelIndex& parent, int start, int end )
657 {
658  Q_UNUSED( parent );
659  Q_UNUSED( start );
660  Q_UNUSED( end );
661  Q_ASSERT_X( sourceModel(), "removeColumn", "This should only be triggered if a valid source Model exists!" );
662  for ( int i = start; i <= end; ++i ) {
663  d->verticalHeaderDataMap.remove( start );
664  }
665  removeEntriesFromDataMap( start, end );
666  removeEntriesFromDirectionDataMaps( Qt::Horizontal, start, end );
667  removeEntriesFromDirectionDataMaps( Qt::Vertical, start, end );
668 
669  endRemoveColumns();
670 }
671 
672 void AttributesModel::slotDataChanged( const QModelIndex& topLeft, const QModelIndex& bottomRight )
673 {
674  Q_EMIT dataChanged( mapFromSource( topLeft ), mapFromSource( bottomRight ) );
675 }
676 
677 void AttributesModel::setDefaultForRole( int role, const QVariant& value )
678 {
679  if ( value.isValid() ) {
680  d->defaultsMap.insert( role, value );
681  } else {
682  // erase the possibly existing value to not let the map grow:
683  QMap<int, QVariant>::iterator it = d->defaultsMap.find( role );
684  if ( it != d->defaultsMap.end() ) {
685  d->defaultsMap.erase( it );
686  }
687  }
688 
689  Q_ASSERT( defaultsForRole( role ).value<KChart::DataValueAttributes>() == value.value<KChart::DataValueAttributes>() );
690 }
691 
693 {
694  //### need to "reformat" or throw away internal data?
695  d->dataDimension = dimension;
696 }
697 
698 int AttributesModel::datasetDimension() const
699 {
700  return d->dataDimension;
701 }
A set of 3D line attributes.
bool contains(const Key &key) const const
int rowCount(const QModelIndex &) const override
void initFrom(const AttributesModel *other)
Copies the internal data (maps and palette) of another AttributesModel* into this one...
QMap::const_iterator constBegin() const const
A Palette is a set of brushes (or colors) to be used for painting data sets.
Definition: KChartPalette.h:35
virtual QVariant defaultHeaderData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const
Returns default values for the header data.
T value() const const
Diagram attributes dealing with data value labels.
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::DisplayRole) override
void setDefaultForRole(int role, const QVariant &value)
Define the default value for a certain role.
Declaring the class KChart::DataValueAttributes.
Set of attributes for changing the appearance of line charts.
void setDatasetDimension(int dimension)
Set the dimension of the dataset in the source model.
const QColor & color() const const
bool resetData(const QModelIndex &index, int role=Qt::DisplayRole)
Remove any explicit attributes settings that might have been specified before.
bool isValid() const const
QString number(int n, int base)
bool isKnownAttributesRole(int role) const
Returns whether the given role corresponds to one of the known internally used ones.
Set of attributes for changing the appearance of bar charts.
Base class for all proxy models used inside KChart.
Class only listed here to document inheritance of some KChart classes.
QVariant data(int role) const
Returns the data that were specified at global level, or the default data, or QVariant().
Contains KChart macros.
DisplayRole
QMap::const_iterator constEnd() const const
int row() const const
void setSourceModel(QAbstractItemModel *sourceModel) override
QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
virtual void setSourceModel(QAbstractItemModel *sourceModel)
bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role=Qt::DisplayRole) override
A proxy model used for decorating data with attributes.
int columnCount(const QModelIndex &) const override
QMap::iterator end()
bool resetHeaderData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole)
Remove any explicit attributes settings that might have been specified before.
Attributes to customize the appearance of a column in a stock chart.
static const Palette & defaultPalette()
Provide access to the three builtin palettes, one with standard bright colors, one with more subdued ...
Cell-specific attributes regarding value tracking.
A set of attributes controlling the appearance of pie charts.
A set of 3D pie attributes.
const QAbstractItemModel * model() const const
bool isEmpty() const const
QMap::iterator upperBound(const Key &key)
int count(const T &value) const const
int column() const const
bool compare(const AttributesModel *other) const
Returns true if both, all of the attributes set, and the palette set is equal in both of the Attribut...
bool isValid() const const
QMap::iterator insert(const Key &key, const T &value)
Orientation
void setPaletteType(PaletteType type)
Sets the palettetype used by this attributesmodel.
Global namespace.
QMap::iterator find(const Key &key)
A set of 3D bar attributes.
int remove(const Key &key)
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu Jan 27 2022 22:33:22 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.