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

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/