File indexing completed on 2024-05-12 04:20:30
0001 /* 0002 * SPDX-FileCopyrightText: 2001-2015 Klaralvdalens Datakonsult AB. All rights reserved. 0003 * 0004 * This file is part of the KD Chart library. 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "KChartAttributesModel.h" 0010 0011 #include "KChartPalette.h" 0012 #include "KChartMath_p.h" 0013 0014 #include <QDebug> 0015 #include <QPen> 0016 #include <QPointer> 0017 0018 #include <KChartTextAttributes.h> 0019 #include <KChartFrameAttributes.h> 0020 #include <KChartBackgroundAttributes.h> 0021 #include <KChartDataValueAttributes.h> 0022 #include <KChartMarkerAttributes.h> 0023 #include <KChartBarAttributes.h> 0024 #include <KChartStockBarAttributes.h> 0025 #include <KChartLineAttributes.h> 0026 #include <KChartPieAttributes.h> 0027 #include <KChartAbstractThreeDAttributes.h> 0028 #include <KChartThreeDBarAttributes.h> 0029 #include <KChartThreeDLineAttributes.h> 0030 #include <KChartThreeDPieAttributes.h> 0031 #include <KChartGridAttributes.h> 0032 #include <KChartValueTrackerAttributes.h> 0033 0034 0035 using namespace KChart; 0036 0037 0038 class Q_DECL_HIDDEN AttributesModel::Private 0039 { 0040 public: 0041 Private(); 0042 0043 QMap< int, QMap< int, QMap< int, QVariant > > > dataMap; 0044 QMap< int, QMap< int, QVariant > > horizontalHeaderDataMap; 0045 QMap< int, QMap< int, QVariant > > verticalHeaderDataMap; 0046 QMap< int, QVariant > modelDataMap; 0047 QMap< int, QVariant > defaultsMap; 0048 int dataDimension; 0049 AttributesModel::PaletteType paletteType; 0050 Palette palette; 0051 }; 0052 0053 AttributesModel::Private::Private() 0054 : dataDimension( 1 ), 0055 paletteType( AttributesModel::PaletteTypeDefault ), 0056 palette( Palette::defaultPalette() ) 0057 { 0058 } 0059 0060 #define d d_func() 0061 0062 AttributesModel::AttributesModel( QAbstractItemModel* model, QObject * parent/* = 0 */ ) 0063 : AbstractProxyModel( parent ), 0064 _d( new Private ) 0065 { 0066 setSourceModel( model ); 0067 setDefaultForRole( KChart::DataValueLabelAttributesRole, 0068 DataValueAttributes::defaultAttributesAsVariant() ); 0069 } 0070 0071 AttributesModel::~AttributesModel() 0072 { 0073 delete _d; 0074 _d = nullptr; 0075 } 0076 0077 void AttributesModel::initFrom( const AttributesModel* other ) 0078 { 0079 *d = *other->d; 0080 } 0081 0082 bool AttributesModel::compareHeaderDataMaps( const QMap< int, QMap< int, QVariant > >& mapA, 0083 const QMap< int, QMap< int, QVariant > >& mapB ) const 0084 { 0085 if ( mapA.count() != mapB.count() ) { 0086 return false; 0087 } 0088 QMap< int, QMap< int, QVariant > >::const_iterator itA = mapA.constBegin(); 0089 QMap< int, QMap< int, QVariant > >::const_iterator itB = mapB.constBegin(); 0090 for ( ; itA != mapA.constEnd(); ++itA, ++itB ) { 0091 if ( itA->count() != itB->count() ) { 0092 return false; 0093 } 0094 QMap< int, QVariant >::const_iterator it2A = itA->constBegin(); 0095 QMap< int, QVariant >::const_iterator it2B = itB->constBegin(); 0096 for ( ; it2A != itA->constEnd(); ++it2A, ++it2B ) { 0097 if ( it2A.key() != it2B.key() ) { 0098 return false; 0099 } 0100 if ( !compareAttributes( it2A.key(), it2A.value(), it2B.value() ) ) { 0101 return false; 0102 } 0103 } 0104 } 0105 return true; 0106 } 0107 0108 bool AttributesModel::compare( const AttributesModel* other ) const 0109 { 0110 if ( other == this ) { 0111 return true; 0112 } 0113 if ( !other || d->paletteType != other->d->paletteType ) { 0114 return false; 0115 } 0116 0117 { 0118 if ( d->dataMap.count() != other->d->dataMap.count() ) { 0119 return false; 0120 } 0121 QMap< int, QMap< int, QMap<int, QVariant > > >::const_iterator itA = d->dataMap.constBegin(); 0122 QMap< int, QMap< int, QMap<int, QVariant > > >::const_iterator itB = other->d->dataMap.constBegin(); 0123 for ( ; itA != d->dataMap.constEnd(); ++itA, ++itB ) { 0124 if ( itA->count() != itB->count() ) { 0125 return false; 0126 } 0127 QMap< int, QMap< int, QVariant > >::const_iterator it2A = itA->constBegin(); 0128 QMap< int, QMap< int, QVariant > >::const_iterator it2B = itB->constBegin(); 0129 for ( ; it2A != itA->constEnd(); ++it2A, ++it2B ) { 0130 if ( it2A->count() != it2B->count() ) { 0131 return false; 0132 } 0133 QMap< int, QVariant >::const_iterator it3A = it2A->constBegin(); 0134 QMap< int, QVariant >::const_iterator it3B = it2B->constBegin(); 0135 for ( ; it3A != it2A->constEnd(); ++it3A, ++it3B ) { 0136 if ( it3A.key() != it3B.key() ) { 0137 return false; 0138 } 0139 if ( !compareAttributes( it3A.key(), it3A.value(), it3B.value() ) ) { 0140 return false; 0141 } 0142 } 0143 } 0144 } 0145 } 0146 0147 if ( !compareHeaderDataMaps( d->horizontalHeaderDataMap, other->d->horizontalHeaderDataMap ) || 0148 !compareHeaderDataMaps( d->verticalHeaderDataMap, other->d->verticalHeaderDataMap ) ) { 0149 return false; 0150 } 0151 0152 { 0153 if ( d->modelDataMap.count() != other->d->modelDataMap.count() ) { 0154 return false; 0155 } 0156 QMap< int, QVariant >::const_iterator itA = d->modelDataMap.constBegin(); 0157 QMap< int, QVariant >::const_iterator itB = other->d->modelDataMap.constBegin(); 0158 for ( ; itA != d->modelDataMap.constEnd(); ++itA, ++itB ) { 0159 if ( itA.key() != itB.key() ) { 0160 return false; 0161 } 0162 if ( !compareAttributes( itA.key(), itA.value(), itB.value() ) ) { 0163 return false; 0164 } 0165 } 0166 } 0167 return true; 0168 } 0169 0170 bool AttributesModel::compareAttributes( 0171 int role, const QVariant& a, const QVariant& b ) const 0172 { 0173 if ( isKnownAttributesRole( role ) ) { 0174 switch ( role ) { 0175 case DataValueLabelAttributesRole: 0176 return (a.value<DataValueAttributes>() == 0177 b.value<DataValueAttributes>()); 0178 case DatasetBrushRole: 0179 return (a.value<QBrush>() == 0180 b.value<QBrush>()); 0181 case DatasetPenRole: 0182 return (a.value<QPen>() == 0183 b.value<QPen>()); 0184 case ThreeDAttributesRole: 0185 // As of yet there is no ThreeDAttributes class, 0186 // and the AbstractThreeDAttributes class is pure virtual, 0187 // so we ignore this role for now. 0188 // (khz, 04.04.2007) 0189 /* 0190 return (qVariantValue<ThreeDAttributes>( a ) == 0191 qVariantValue<ThreeDAttributes>( b )); 0192 */ 0193 break; 0194 case LineAttributesRole: 0195 return (a.value<LineAttributes>() == 0196 b.value<LineAttributes>()); 0197 case ThreeDLineAttributesRole: 0198 return (a.value<ThreeDLineAttributes>() == 0199 b.value<ThreeDLineAttributes>()); 0200 case BarAttributesRole: 0201 return (a.value<BarAttributes>() == 0202 b.value<BarAttributes>()); 0203 case StockBarAttributesRole: 0204 return (a.value<StockBarAttributes>() == 0205 b.value<StockBarAttributes>()); 0206 case ThreeDBarAttributesRole: 0207 return (a.value<ThreeDBarAttributes>() == 0208 b.value<ThreeDBarAttributes>()); 0209 case PieAttributesRole: 0210 return (a.value<PieAttributes>() == 0211 b.value<PieAttributes>()); 0212 case ThreeDPieAttributesRole: 0213 return (a.value<ThreeDPieAttributes>() == 0214 b.value<ThreeDPieAttributes>()); 0215 case ValueTrackerAttributesRole: 0216 return (a.value<ValueTrackerAttributes>() == 0217 b.value<ValueTrackerAttributes>()); 0218 case DataHiddenRole: 0219 return (a.value<bool>() == 0220 b.value<bool>()); 0221 default: 0222 Q_ASSERT( false ); // all of our own roles need to be handled 0223 break; 0224 } 0225 } else { 0226 return (a == b); 0227 } 0228 return true; 0229 } 0230 0231 0232 QVariant AttributesModel::headerData( int section, Qt::Orientation orientation, 0233 int role/* = Qt::DisplayRole */ ) const 0234 { 0235 if ( sourceModel() ) { 0236 const QVariant sourceData = sourceModel()->headerData( section, orientation, role ); 0237 if ( sourceData.isValid() ) { 0238 return sourceData; 0239 } 0240 } 0241 0242 // the source model didn't have data set, let's use our stored values 0243 const QMap< int, QMap< int, QVariant> >& map = orientation == Qt::Horizontal ? 0244 d->horizontalHeaderDataMap : d->verticalHeaderDataMap; 0245 QMap< int, QMap< int, QVariant > >::const_iterator mapIt = map.find( section ); 0246 if ( mapIt != map.constEnd() ) { 0247 const QMap< int, QVariant >& dataMap = mapIt.value(); 0248 QMap< int, QVariant >::const_iterator dataMapIt = dataMap.find( role ); 0249 if ( dataMapIt != dataMap.constEnd() ) { 0250 return dataMapIt.value(); 0251 } 0252 } 0253 0254 return defaultHeaderData( section, orientation, role ); 0255 } 0256 0257 0258 QVariant AttributesModel::defaultHeaderData( int section, Qt::Orientation orientation, int role ) const 0259 { 0260 // Default values if nothing else matches 0261 0262 const int dataset = section / d->dataDimension; 0263 0264 switch ( role ) { 0265 case Qt::DisplayRole: 0266 //TODO for KChart 3.0: return QString::number( dataset + 1 ); 0267 return QVariant( (orientation == Qt::Vertical ? QStringLiteral("Series ") : QStringLiteral("Item ")) + QString::number( dataset )) ; 0268 case KChart::DatasetBrushRole: 0269 return d->palette.getBrush( dataset ); 0270 case KChart::DatasetPenRole: 0271 // if no per model override was set, use the (possibly default) color set for the brush 0272 if ( !modelData( role ).isValid() ) { 0273 QBrush brush = headerData( section, orientation, DatasetBrushRole ).value< QBrush >(); 0274 return QPen( brush.color() ); 0275 } 0276 default: 0277 break; 0278 } 0279 0280 return QVariant(); 0281 } 0282 0283 0284 QVariant AttributesModel::data( int role ) const 0285 { 0286 if ( isKnownAttributesRole( role ) ) { 0287 // check if there is something set at global level 0288 QVariant v = modelData( role ); 0289 0290 // else return the default setting, if any 0291 if ( !v.isValid() ) 0292 v = defaultsForRole( role ); 0293 return v; 0294 } 0295 return QVariant(); 0296 } 0297 0298 0299 QVariant AttributesModel::data( int column, int role ) const 0300 { 0301 if ( isKnownAttributesRole( role ) ) { 0302 // check if there is something set for the column (dataset) 0303 QVariant v; 0304 v = headerData( column, Qt::Horizontal, role ); 0305 0306 // check if there is something set at global level 0307 if ( !v.isValid() ) 0308 v = data( role ); // includes automatic fallback to default 0309 return v; 0310 } 0311 return QVariant(); 0312 } 0313 0314 0315 QVariant AttributesModel::data( const QModelIndex& index, int role ) const 0316 { 0317 if ( index.isValid() ) { 0318 Q_ASSERT( index.model() == this ); 0319 } 0320 if ( !sourceModel() ) { 0321 return QVariant(); 0322 } 0323 0324 if ( index.isValid() ) { 0325 const QVariant sourceData = sourceModel()->data( mapToSource( index ), role ); 0326 if ( sourceData.isValid() ) { 0327 return sourceData; 0328 } 0329 } 0330 0331 // check if we are storing a value for this role at this cell index 0332 if ( d->dataMap.contains( index.column() ) ) { 0333 const QMap< int, QMap< int, QVariant > >& colDataMap = d->dataMap[ index.column() ]; 0334 if ( colDataMap.contains( index.row() ) ) { 0335 const QMap< int, QVariant >& dataMap = colDataMap[ index.row() ]; 0336 if ( dataMap.contains( role ) ) { 0337 const QVariant v = dataMap[ role ]; 0338 if ( v.isValid() ) { 0339 return v; 0340 } 0341 } 0342 } 0343 } 0344 // check if there is something set for the column (dataset), or at global level 0345 if ( index.isValid() ) { 0346 return data( index.column(), role ); // includes automatic fallback to default 0347 } 0348 0349 return QVariant(); 0350 } 0351 0352 0353 bool AttributesModel::isKnownAttributesRole( int role ) const 0354 { 0355 switch ( role ) { 0356 // fallthrough intended 0357 case DataValueLabelAttributesRole: 0358 case DatasetBrushRole: 0359 case DatasetPenRole: 0360 case ThreeDAttributesRole: 0361 case LineAttributesRole: 0362 case ThreeDLineAttributesRole: 0363 case BarAttributesRole: 0364 case StockBarAttributesRole: 0365 case ThreeDBarAttributesRole: 0366 case PieAttributesRole: 0367 case ThreeDPieAttributesRole: 0368 case ValueTrackerAttributesRole: 0369 case DataHiddenRole: 0370 return true; 0371 default: 0372 return false; 0373 } 0374 } 0375 0376 QVariant AttributesModel::defaultsForRole( int role ) const 0377 { 0378 // returns default-constructed QVariant if not found 0379 return d->defaultsMap.value( role ); 0380 } 0381 0382 bool AttributesModel::setData ( const QModelIndex & index, const QVariant & value, int role ) 0383 { 0384 if ( !isKnownAttributesRole( role ) ) { 0385 return sourceModel()->setData( mapToSource(index), value, role ); 0386 } else { 0387 QMap< int, QMap< int, QVariant> > &colDataMap = d->dataMap[ index.column() ]; 0388 QMap< int, QVariant > &dataMap = colDataMap[ index.row() ]; 0389 dataMap.insert( role, value ); 0390 Q_EMIT attributesChanged( index, index ); 0391 return true; 0392 } 0393 } 0394 0395 bool AttributesModel::resetData ( const QModelIndex & index, int role ) 0396 { 0397 return setData( index, QVariant(), role ); 0398 } 0399 0400 bool AttributesModel::setHeaderData ( int section, Qt::Orientation orientation, 0401 const QVariant & value, int role ) 0402 { 0403 if ( sourceModel() && headerData( section, orientation, role ) == value ) { 0404 return true; 0405 } 0406 0407 if ( !isKnownAttributesRole( role ) ) { 0408 return sourceModel()->setHeaderData( section, orientation, value, role ); 0409 } else { 0410 QMap< int, QMap<int, QVariant > > §ionDataMap 0411 = orientation == Qt::Horizontal ? d->horizontalHeaderDataMap : d->verticalHeaderDataMap; 0412 0413 QMap< int, QVariant > &dataMap = sectionDataMap[ section ]; 0414 dataMap.insert( role, value ); 0415 if ( sourceModel() ) { 0416 int numRows = rowCount( QModelIndex() ); 0417 int numCols = columnCount( QModelIndex() ); 0418 if ( orientation == Qt::Horizontal && numRows > 0 ) 0419 Q_EMIT attributesChanged( index( 0, section, QModelIndex() ), 0420 index( numRows - 1, section, QModelIndex() ) ); 0421 else if ( orientation == Qt::Vertical && numCols > 0 ) 0422 Q_EMIT attributesChanged( index( section, 0, QModelIndex() ), 0423 index( section, numCols - 1, QModelIndex() ) ); 0424 Q_EMIT headerDataChanged( orientation, section, section ); 0425 0426 // FIXME: This only makes sense for orientation == Qt::Horizontal, 0427 // but what if orientation == Qt::Vertical? 0428 if ( section != -1 && numRows > 0 ) 0429 Q_EMIT dataChanged( index( 0, section, QModelIndex() ), 0430 index( numRows - 1, section, QModelIndex() ) ); 0431 } 0432 return true; 0433 } 0434 } 0435 0436 bool AttributesModel::resetHeaderData ( int section, Qt::Orientation orientation, int role ) 0437 { 0438 return setHeaderData ( section, orientation, QVariant(), role ); 0439 } 0440 0441 void AttributesModel::setPaletteType( AttributesModel::PaletteType type ) 0442 { 0443 if ( d->paletteType == type ) { 0444 return; 0445 } 0446 d->paletteType = type; 0447 switch ( type ) { 0448 case PaletteTypeDefault: 0449 d->palette = Palette::defaultPalette(); 0450 break; 0451 case PaletteTypeSubdued: 0452 d->palette = Palette::subduedPalette(); 0453 break; 0454 case PaletteTypeRainbow: 0455 d->palette = Palette::rainbowPalette(); 0456 break; 0457 default: 0458 qWarning( "Unknown palette type!" ); 0459 } 0460 } 0461 0462 AttributesModel::PaletteType AttributesModel::paletteType() const 0463 { 0464 return d->paletteType; 0465 } 0466 0467 bool KChart::AttributesModel::setModelData( const QVariant value, int role ) 0468 { 0469 d->modelDataMap.insert( role, value ); 0470 int numRows = rowCount( QModelIndex() ); 0471 int numCols = columnCount( QModelIndex() ); 0472 if ( sourceModel() && numRows > 0 && numCols > 0 ) { 0473 Q_EMIT attributesChanged( index( 0, 0, QModelIndex() ), 0474 index( numRows - 1, numCols - 1, QModelIndex() ) ); 0475 beginResetModel(); 0476 endResetModel(); 0477 } 0478 return true; 0479 } 0480 0481 QVariant KChart::AttributesModel::modelData( int role ) const 0482 { 0483 return d->modelDataMap.value( role, QVariant() ); 0484 } 0485 0486 int AttributesModel::rowCount( const QModelIndex& index ) const 0487 { 0488 if ( sourceModel() ) { 0489 return sourceModel()->rowCount( mapToSource(index) ); 0490 } else { 0491 return 0; 0492 } 0493 } 0494 0495 int AttributesModel::columnCount( const QModelIndex& index ) const 0496 { 0497 if ( sourceModel() ) { 0498 return sourceModel()->columnCount( mapToSource(index) ); 0499 } else { 0500 return 0; 0501 } 0502 } 0503 0504 void AttributesModel::setSourceModel( QAbstractItemModel* sourceModel ) 0505 { 0506 if ( this->sourceModel() != nullptr ) 0507 { 0508 disconnect( this->sourceModel(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), 0509 this, SLOT(slotDataChanged(QModelIndex,QModelIndex))); 0510 disconnect( this->sourceModel(), SIGNAL(rowsInserted(QModelIndex,int,int)), 0511 this, SLOT(slotRowsInserted(QModelIndex,int,int)) ); 0512 disconnect( this->sourceModel(), SIGNAL(rowsRemoved(QModelIndex,int,int)), 0513 this, SLOT(slotRowsRemoved(QModelIndex,int,int)) ); 0514 disconnect( this->sourceModel(), SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), 0515 this, SLOT(slotRowsAboutToBeInserted(QModelIndex,int,int)) ); 0516 disconnect( this->sourceModel(), SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), 0517 this, SLOT(slotRowsAboutToBeRemoved(QModelIndex,int,int)) ); 0518 disconnect( this->sourceModel(), SIGNAL(columnsInserted(QModelIndex,int,int)), 0519 this, SLOT(slotColumnsInserted(QModelIndex,int,int)) ); 0520 disconnect( this->sourceModel(), SIGNAL(columnsRemoved(QModelIndex,int,int)), 0521 this, SLOT(slotColumnsRemoved(QModelIndex,int,int)) ); 0522 disconnect( this->sourceModel(), SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)), 0523 this, SLOT(slotColumnsAboutToBeInserted(QModelIndex,int,int)) ); 0524 disconnect( this->sourceModel(), SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)), 0525 this, SLOT(slotColumnsAboutToBeRemoved(QModelIndex,int,int)) ); 0526 disconnect( this->sourceModel(), SIGNAL(modelReset()), 0527 this, SIGNAL(modelReset()) ); 0528 disconnect( this->sourceModel(), SIGNAL(layoutChanged()), 0529 this, SIGNAL(layoutChanged()) ); 0530 } 0531 QAbstractProxyModel::setSourceModel( sourceModel ); 0532 if ( this->sourceModel() != nullptr ) 0533 { 0534 connect( this->sourceModel(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), 0535 this, SLOT(slotDataChanged(QModelIndex,QModelIndex))); 0536 connect( this->sourceModel(), SIGNAL(rowsInserted(QModelIndex,int,int)), 0537 this, SLOT(slotRowsInserted(QModelIndex,int,int)) ); 0538 connect( this->sourceModel(), SIGNAL(rowsRemoved(QModelIndex,int,int)), 0539 this, SLOT(slotRowsRemoved(QModelIndex,int,int)) ); 0540 connect( this->sourceModel(), SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)), 0541 this, SLOT(slotRowsAboutToBeInserted(QModelIndex,int,int)) ); 0542 connect( this->sourceModel(), SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), 0543 this, SLOT(slotRowsAboutToBeRemoved(QModelIndex,int,int)) ); 0544 connect( this->sourceModel(), SIGNAL(columnsInserted(QModelIndex,int,int)), 0545 this, SLOT(slotColumnsInserted(QModelIndex,int,int)) ); 0546 connect( this->sourceModel(), SIGNAL(columnsRemoved(QModelIndex,int,int)), 0547 this, SLOT(slotColumnsRemoved(QModelIndex,int,int)) ); 0548 connect( this->sourceModel(), SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)), 0549 this, SLOT(slotColumnsAboutToBeInserted(QModelIndex,int,int)) ); 0550 connect( this->sourceModel(), SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)), 0551 this, SLOT(slotColumnsAboutToBeRemoved(QModelIndex,int,int)) ); 0552 connect( this->sourceModel(), SIGNAL(modelReset()), 0553 this, SIGNAL(modelReset()) ); 0554 connect( this->sourceModel(), SIGNAL(layoutChanged()), 0555 this, SIGNAL(layoutChanged()) ); 0556 } 0557 } 0558 0559 void AttributesModel::slotRowsAboutToBeInserted( const QModelIndex& parent, int start, int end ) 0560 { 0561 beginInsertRows( mapFromSource( parent ), start, end ); 0562 } 0563 0564 void AttributesModel::slotColumnsAboutToBeInserted( const QModelIndex& parent, int start, int end ) 0565 { 0566 beginInsertColumns( mapFromSource( parent ), start, end ); 0567 } 0568 0569 void AttributesModel::slotRowsInserted( const QModelIndex& parent, int start, int end ) 0570 { 0571 Q_UNUSED( parent ); 0572 Q_UNUSED( start ); 0573 Q_UNUSED( end ); 0574 endInsertRows(); 0575 } 0576 0577 void AttributesModel::slotColumnsInserted( const QModelIndex& parent, int start, int end ) 0578 { 0579 Q_UNUSED( parent ); 0580 Q_UNUSED( start ); 0581 Q_UNUSED( end ); 0582 endInsertColumns(); 0583 } 0584 0585 void AttributesModel::slotRowsAboutToBeRemoved( const QModelIndex& parent, int start, int end ) 0586 { 0587 beginRemoveRows( mapFromSource( parent ), start, end ); 0588 } 0589 0590 void AttributesModel::slotColumnsAboutToBeRemoved( const QModelIndex& parent, int start, int end ) 0591 { 0592 beginRemoveColumns( mapFromSource( parent ), start, end ); 0593 } 0594 0595 void AttributesModel::slotRowsRemoved( const QModelIndex& parent, int start, int end ) 0596 { 0597 Q_UNUSED( parent ); 0598 Q_UNUSED( start ); 0599 Q_UNUSED( end ); 0600 endRemoveRows(); 0601 } 0602 0603 void AttributesModel::removeEntriesFromDataMap( int start, int end ) 0604 { 0605 QMap< int, QMap< int, QMap< int, QVariant > > >::iterator it = d->dataMap.find( end ); 0606 // check that the element was found 0607 if ( it != d->dataMap.end() ) { 0608 ++it; 0609 QVector< int > indexesToDel; 0610 for ( int i = start; i < end && it != d->dataMap.end(); ++i ) { 0611 d->dataMap[ i ] = it.value(); 0612 indexesToDel << it.key(); 0613 ++it; 0614 } 0615 if ( indexesToDel.isEmpty() ) { 0616 for ( int i = start; i < end; ++i ) { 0617 indexesToDel << i; 0618 } 0619 } 0620 for ( int i = 0; i < indexesToDel.count(); ++i ) { 0621 d->dataMap.remove( indexesToDel[ i ] ); 0622 } 0623 } 0624 } 0625 0626 void AttributesModel::removeEntriesFromDirectionDataMaps( Qt::Orientation dir, int start, int end ) 0627 { 0628 QMap<int, QMap<int, QVariant> > §ionDataMap 0629 = dir == Qt::Horizontal ? d->horizontalHeaderDataMap : d->verticalHeaderDataMap; 0630 QMap<int, QMap<int, QVariant> >::iterator it = sectionDataMap.upperBound( end ); 0631 // check that the element was found 0632 if ( it != sectionDataMap.end() ) 0633 { 0634 QVector< int > indexesToDel; 0635 for ( int i = start; i < end && it != sectionDataMap.end(); ++i ) 0636 { 0637 sectionDataMap[ i ] = it.value(); 0638 indexesToDel << it.key(); 0639 ++it; 0640 } 0641 if ( indexesToDel.isEmpty() ) 0642 { 0643 for ( int i = start; i < end; ++i ) 0644 { 0645 indexesToDel << i; 0646 } 0647 } 0648 for ( int i = 0; i < indexesToDel.count(); ++i ) 0649 { 0650 sectionDataMap.remove( indexesToDel[ i ] ); 0651 } 0652 } 0653 } 0654 0655 void AttributesModel::slotColumnsRemoved( const QModelIndex& parent, int start, int end ) 0656 { 0657 Q_UNUSED( parent ); 0658 Q_UNUSED( start ); 0659 Q_UNUSED( end ); 0660 Q_ASSERT_X( sourceModel(), "removeColumn", "This should only be triggered if a valid source Model exists!" ); 0661 for ( int i = start; i <= end; ++i ) { 0662 d->verticalHeaderDataMap.remove( start ); 0663 } 0664 removeEntriesFromDataMap( start, end ); 0665 removeEntriesFromDirectionDataMaps( Qt::Horizontal, start, end ); 0666 removeEntriesFromDirectionDataMaps( Qt::Vertical, start, end ); 0667 0668 endRemoveColumns(); 0669 } 0670 0671 void AttributesModel::slotDataChanged( const QModelIndex& topLeft, const QModelIndex& bottomRight ) 0672 { 0673 Q_EMIT dataChanged( mapFromSource( topLeft ), mapFromSource( bottomRight ) ); 0674 } 0675 0676 void AttributesModel::setDefaultForRole( int role, const QVariant& value ) 0677 { 0678 if ( value.isValid() ) { 0679 d->defaultsMap.insert( role, value ); 0680 } else { 0681 // erase the possibly existing value to not let the map grow: 0682 QMap<int, QVariant>::iterator it = d->defaultsMap.find( role ); 0683 if ( it != d->defaultsMap.end() ) { 0684 d->defaultsMap.erase( it ); 0685 } 0686 } 0687 0688 Q_ASSERT( defaultsForRole( role ).value<KChart::DataValueAttributes>() == value.value<KChart::DataValueAttributes>() ); 0689 } 0690 0691 void AttributesModel::setDatasetDimension( int dimension ) 0692 { 0693 //### need to "reformat" or throw away internal data? 0694 d->dataDimension = dimension; 0695 } 0696 0697 int AttributesModel::datasetDimension() const 0698 { 0699 return d->dataDimension; 0700 }