KD Chart 2
[rev.2.5]
|
00001 /**************************************************************************** 00002 ** Copyright (C) 2001-2012 Klaralvdalens Datakonsult AB. All rights reserved. 00003 ** 00004 ** This file is part of the KD Chart library. 00005 ** 00006 ** Licensees holding valid commercial KD Chart licenses may use this file in 00007 ** accordance with the KD Chart Commercial License Agreement provided with 00008 ** the Software. 00009 ** 00010 ** 00011 ** This file may be distributed and/or modified under the terms of the 00012 ** GNU General Public License version 2 and version 3 as published by the 00013 ** Free Software Foundation and appearing in the file LICENSE.GPL.txt included. 00014 ** 00015 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00016 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00017 ** 00018 ** Contact info@kdab.com if any conditions of this licensing are not 00019 ** clear to you. 00020 ** 00021 **********************************************************************/ 00022 00023 #include "KDChartAttributesModel.h" 00024 #include "KDChartPalette.h" 00025 #include "KDChartGlobal.h" 00026 00027 #include <QDebug> 00028 #include <QPen> 00029 #include <QPointer> 00030 00031 #include <KDChartTextAttributes.h> 00032 #include <KDChartFrameAttributes.h> 00033 #include <KDChartBackgroundAttributes.h> 00034 #include <KDChartDataValueAttributes.h> 00035 #include <KDChartMarkerAttributes.h> 00036 #include <KDChartBarAttributes.h> 00037 #include <KDChartStockBarAttributes.h> 00038 #include <KDChartLineAttributes.h> 00039 #include <KDChartPieAttributes.h> 00040 #include <KDChartAbstractThreeDAttributes.h> 00041 #include <KDChartThreeDBarAttributes.h> 00042 #include <KDChartThreeDLineAttributes.h> 00043 #include <KDChartThreeDPieAttributes.h> 00044 #include <KDChartGridAttributes.h> 00045 #include <KDChartValueTrackerAttributes.h> 00046 00047 #include <KDABLibFakes> 00048 00049 00050 using namespace KDChart; 00051 00052 00053 class AttributesModel::Private 00054 { 00055 public: 00056 Private(); 00057 00058 QMap< int, QMap< int, QMap< int, QVariant > > > dataMap; 00059 QMap< int, QMap< int, QVariant > > horizontalHeaderDataMap; 00060 QMap< int, QMap< int, QVariant > > verticalHeaderDataMap; 00061 QMap< int, QVariant > modelDataMap; 00062 QMap< int, QVariant > defaultsMap; 00063 int dataDimension; 00064 AttributesModel::PaletteType paletteType; 00065 Palette palette; 00066 }; 00067 00068 AttributesModel::Private::Private() 00069 : dataDimension( 1 ), 00070 paletteType( AttributesModel::PaletteTypeDefault ), 00071 palette( Palette::defaultPalette() ) 00072 { 00073 } 00074 00075 #define d d_func() 00076 00077 AttributesModel::AttributesModel( QAbstractItemModel* model, QObject * parent/* = 0 */ ) 00078 : AbstractProxyModel( parent ), 00079 _d( new Private ) 00080 { 00081 setSourceModel( model ); 00082 setDefaultForRole( KDChart::DataValueLabelAttributesRole, 00083 DataValueAttributes::defaultAttributesAsVariant() ); 00084 } 00085 00086 AttributesModel::~AttributesModel() 00087 { 00088 delete _d; 00089 _d = 0; 00090 } 00091 00092 void AttributesModel::initFrom( const AttributesModel* other ) 00093 { 00094 *d = *other->d; 00095 } 00096 00097 bool AttributesModel::compareHeaderDataMaps( const QMap< int, QMap< int, QVariant > >& mapA, 00098 const QMap< int, QMap< int, QVariant > >& mapB ) const 00099 { 00100 if ( mapA.count() != mapB.count() ) { 00101 return false; 00102 } 00103 QMap< int, QMap< int, QVariant > >::const_iterator itA = mapA.constBegin(); 00104 QMap< int, QMap< int, QVariant > >::const_iterator itB = mapB.constBegin(); 00105 for ( ; itA != mapA.constEnd(); ++itA, ++itB ) { 00106 if ( itA->count() != itB->count() ) { 00107 return false; 00108 } 00109 QMap< int, QVariant >::const_iterator it2A = itA->constBegin(); 00110 QMap< int, QVariant >::const_iterator it2B = itB->constBegin(); 00111 for ( ; it2A != itA->constEnd(); ++it2A, ++it2B ) { 00112 if ( it2A.key() != it2B.key() ) { 00113 return false; 00114 } 00115 if ( !compareAttributes( it2A.key(), it2A.value(), it2B.value() ) ) { 00116 return false; 00117 } 00118 } 00119 } 00120 return true; 00121 } 00122 00123 bool AttributesModel::compare( const AttributesModel* other ) const 00124 { 00125 if ( other == this ) { 00126 return true; 00127 } 00128 if ( !other || d->paletteType != other->d->paletteType ) { 00129 return false; 00130 } 00131 00132 { 00133 if ( d->dataMap.count() != other->d->dataMap.count() ) { 00134 return false; 00135 } 00136 QMap< int, QMap< int, QMap<int, QVariant > > >::const_iterator itA = d->dataMap.constBegin(); 00137 QMap< int, QMap< int, QMap<int, QVariant > > >::const_iterator itB = other->d->dataMap.constBegin(); 00138 for ( ; itA != d->dataMap.constEnd(); ++itA, ++itB ) { 00139 if ( itA->count() != itB->count() ) { 00140 return false; 00141 } 00142 QMap< int, QMap< int, QVariant > >::const_iterator it2A = itA->constBegin(); 00143 QMap< int, QMap< int, QVariant > >::const_iterator it2B = itB->constBegin(); 00144 for ( ; it2A != itA->constEnd(); ++it2A, ++it2B ) { 00145 if ( it2A->count() != it2B->count() ) { 00146 return false; 00147 } 00148 QMap< int, QVariant >::const_iterator it3A = it2A->constBegin(); 00149 QMap< int, QVariant >::const_iterator it3B = it2B->constBegin(); 00150 for ( ; it3A != it2A->constEnd(); ++it3A, ++it3B ) { 00151 if ( it3A.key() != it3B.key() ) { 00152 return false; 00153 } 00154 if ( !compareAttributes( it3A.key(), it3A.value(), it3B.value() ) ) { 00155 return false; 00156 } 00157 } 00158 } 00159 } 00160 } 00161 00162 if ( !compareHeaderDataMaps( d->horizontalHeaderDataMap, other->d->horizontalHeaderDataMap ) || 00163 !compareHeaderDataMaps( d->verticalHeaderDataMap, other->d->verticalHeaderDataMap ) ) { 00164 return false; 00165 } 00166 00167 { 00168 if ( d->modelDataMap.count() != other->d->modelDataMap.count() ) { 00169 return false; 00170 } 00171 QMap< int, QVariant >::const_iterator itA = d->modelDataMap.constBegin(); 00172 QMap< int, QVariant >::const_iterator itB = other->d->modelDataMap.constBegin(); 00173 for ( ; itA != d->modelDataMap.constEnd(); ++itA, ++itB ) { 00174 if ( itA.key() != itB.key() ) { 00175 return false; 00176 } 00177 if ( !compareAttributes( itA.key(), itA.value(), itB.value() ) ) { 00178 return false; 00179 } 00180 } 00181 } 00182 return true; 00183 } 00184 00185 bool AttributesModel::compareAttributes( 00186 int role, const QVariant& a, const QVariant& b ) const 00187 { 00188 if( isKnownAttributesRole( role ) ){ 00189 switch( role ) { 00190 case DataValueLabelAttributesRole: 00191 return (qVariantValue<DataValueAttributes>( a ) == 00192 qVariantValue<DataValueAttributes>( b )); 00193 case DatasetBrushRole: 00194 return (qVariantValue<QBrush>( a ) == 00195 qVariantValue<QBrush>( b )); 00196 case DatasetPenRole: 00197 return (qVariantValue<QPen>( a ) == 00198 qVariantValue<QPen>( b )); 00199 case ThreeDAttributesRole: 00200 // As of yet there is no ThreeDAttributes class, 00201 // and the AbstractThreeDAttributes class is pure virtual, 00202 // so we ignore this role for now. 00203 // (khz, 04.04.2007) 00204 /* 00205 return (qVariantValue<ThreeDAttributes>( a ) == 00206 qVariantValue<ThreeDAttributes>( b )); 00207 */ 00208 break; 00209 case LineAttributesRole: 00210 return (qVariantValue<LineAttributes>( a ) == 00211 qVariantValue<LineAttributes>( b )); 00212 case ThreeDLineAttributesRole: 00213 return (qVariantValue<ThreeDLineAttributes>( a ) == 00214 qVariantValue<ThreeDLineAttributes>( b )); 00215 case BarAttributesRole: 00216 return (qVariantValue<BarAttributes>( a ) == 00217 qVariantValue<BarAttributes>( b )); 00218 case StockBarAttributesRole: 00219 return (qVariantValue<StockBarAttributes>( a ) == 00220 qVariantValue<StockBarAttributes>( b )); 00221 case ThreeDBarAttributesRole: 00222 return (qVariantValue<ThreeDBarAttributes>( a ) == 00223 qVariantValue<ThreeDBarAttributes>( b )); 00224 case PieAttributesRole: 00225 return (qVariantValue<PieAttributes>( a ) == 00226 qVariantValue<PieAttributes>( b )); 00227 case ThreeDPieAttributesRole: 00228 return (qVariantValue<ThreeDPieAttributes>( a ) == 00229 qVariantValue<ThreeDPieAttributes>( b )); 00230 case ValueTrackerAttributesRole: 00231 return (qVariantValue<ValueTrackerAttributes>( a ) == 00232 qVariantValue<ValueTrackerAttributes>( b )); 00233 case DataHiddenRole: 00234 return (qVariantValue<bool>( a ) == 00235 qVariantValue<bool>( b )); 00236 default: 00237 Q_ASSERT( false ); // all of our own roles need to be handled 00238 break; 00239 } 00240 }else{ 00241 return (a == b); 00242 } 00243 return true; 00244 } 00245 00246 00247 QVariant AttributesModel::headerData( int section, Qt::Orientation orientation, 00248 int role/* = Qt::DisplayRole */ ) const 00249 { 00250 if ( sourceModel() ) { 00251 const QVariant sourceData = sourceModel()->headerData( section, orientation, role ); 00252 if ( sourceData.isValid() ) { 00253 return sourceData; 00254 } 00255 } 00256 00257 // the source model didn't have data set, let's use our stored values 00258 const QMap< int, QMap< int, QVariant> >& map = orientation == Qt::Horizontal ? 00259 d->horizontalHeaderDataMap : d->verticalHeaderDataMap; 00260 QMap< int, QMap< int, QVariant > >::const_iterator mapIt = map.find( section ); 00261 if ( mapIt != map.constEnd() ) { 00262 const QMap< int, QVariant >& dataMap = mapIt.value(); 00263 QMap< int, QVariant >::const_iterator dataMapIt = dataMap.find( role ); 00264 if ( dataMapIt != dataMap.constEnd() ) { 00265 return dataMapIt.value(); 00266 } 00267 } 00268 00269 return defaultHeaderData( section, orientation, role ); 00270 } 00271 00272 00273 QVariant AttributesModel::defaultHeaderData( int section, Qt::Orientation orientation, int role ) const 00274 { 00275 // Default values if nothing else matches 00276 00277 const int dataset = section / d->dataDimension; 00278 00279 switch ( role ) { 00280 case Qt::DisplayRole: 00281 //TODO for KDChart 3.0: return QString::number( dataset + 1 ); 00282 return QLatin1String( orientation == Qt::Vertical ? "Series " : "Item " ) + QString::number( dataset ) ; 00283 case KDChart::DatasetBrushRole: 00284 return d->palette.getBrush( dataset ); 00285 case KDChart::DatasetPenRole: 00286 // if no per model override was set, use the (possibly default) color set for the brush 00287 if ( !modelData( role ).isValid() ) { 00288 QBrush brush = qVariantValue< QBrush >( headerData( section, orientation, DatasetBrushRole ) ); 00289 return QPen( brush.color() ); 00290 } 00291 default: 00292 break; 00293 } 00294 00295 return QVariant(); 00296 } 00297 00298 // Note: Our users NEED this method - even if 00299 // we do not need it at drawing time! 00300 // (khz, 2006-07-28) 00301 QVariant AttributesModel::data( int role ) const 00302 { 00303 if ( isKnownAttributesRole( role ) ) { 00304 // check if there is something set at global level 00305 QVariant v = modelData( role ); 00306 00307 // else return the default setting, if any 00308 if ( !v.isValid() ) 00309 v = defaultsForRole( role ); 00310 return v; 00311 } 00312 return QVariant(); 00313 } 00314 00315 00316 // Note: Our users NEED this method - even if 00317 // we do not need it at drawing time! 00318 // (khz, 2006-07-28) 00319 QVariant AttributesModel::data( int column, int role ) const 00320 { 00321 if ( isKnownAttributesRole( role ) ) { 00322 // check if there is something set for the column (dataset) 00323 QVariant v; 00324 v = headerData( column, Qt::Horizontal, role ); 00325 00326 // check if there is something set at global level 00327 if ( !v.isValid() ) 00328 v = data( role ); // includes automatic fallback to default 00329 return v; 00330 } 00331 return QVariant(); 00332 } 00333 00334 00335 QVariant AttributesModel::data( const QModelIndex& index, int role ) const 00336 { 00337 if( index.isValid() ) { 00338 Q_ASSERT( index.model() == this ); 00339 } 00340 if ( !sourceModel() ) { 00341 return QVariant(); 00342 } 00343 00344 if ( index.isValid() ) { 00345 const QVariant sourceData = sourceModel()->data( mapToSource( index ), role ); 00346 if ( sourceData.isValid() ) { 00347 return sourceData; 00348 } 00349 } 00350 00351 // check if we are storing a value for this role at this cell index 00352 if ( d->dataMap.contains( index.column() ) ) { 00353 const QMap< int, QMap< int, QVariant > >& colDataMap = d->dataMap[ index.column() ]; 00354 if ( colDataMap.contains( index.row() ) ) { 00355 const QMap< int, QVariant >& dataMap = colDataMap[ index.row() ]; 00356 if ( dataMap.contains( role ) ) { 00357 const QVariant v = dataMap[ role ]; 00358 if ( v.isValid() ) { 00359 return v; 00360 } 00361 } 00362 } 00363 } 00364 // check if there is something set for the column (dataset), or at global level 00365 if ( index.isValid() ) { 00366 return data( index.column(), role ); // includes automatic fallback to default 00367 } 00368 00369 return QVariant(); 00370 } 00371 00372 00373 bool AttributesModel::isKnownAttributesRole( int role ) const 00374 { 00375 switch ( role ) { 00376 // fallthrough intended 00377 case DataValueLabelAttributesRole: 00378 case DatasetBrushRole: 00379 case DatasetPenRole: 00380 case ThreeDAttributesRole: 00381 case LineAttributesRole: 00382 case ThreeDLineAttributesRole: 00383 case BarAttributesRole: 00384 case StockBarAttributesRole: 00385 case ThreeDBarAttributesRole: 00386 case PieAttributesRole: 00387 case ThreeDPieAttributesRole: 00388 case ValueTrackerAttributesRole: 00389 case DataHiddenRole: 00390 return true; 00391 default: 00392 return false; 00393 } 00394 } 00395 00396 QVariant AttributesModel::defaultsForRole( int role ) const 00397 { 00398 // returns default-constructed QVariant if not found 00399 return d->defaultsMap.value( role ); 00400 } 00401 00402 bool AttributesModel::setData ( const QModelIndex & index, const QVariant & value, int role ) 00403 { 00404 if ( !isKnownAttributesRole( role ) ) { 00405 return sourceModel()->setData( mapToSource(index), value, role ); 00406 } else { 00407 QMap< int, QMap< int, QVariant> > &colDataMap = d->dataMap[ index.column() ]; 00408 QMap< int, QVariant > &dataMap = colDataMap[ index.row() ]; 00409 dataMap.insert( role, value ); 00410 emit attributesChanged( index, index ); 00411 return true; 00412 } 00413 } 00414 00415 bool AttributesModel::resetData ( const QModelIndex & index, int role ) 00416 { 00417 return setData( index, QVariant(), role ); 00418 } 00419 00420 bool AttributesModel::setHeaderData ( int section, Qt::Orientation orientation, 00421 const QVariant & value, int role ) 00422 { 00423 if( sourceModel() && headerData( section, orientation, role ) == value ) { 00424 return true; 00425 } 00426 00427 if ( !isKnownAttributesRole( role ) ) { 00428 return sourceModel()->setHeaderData( section, orientation, value, role ); 00429 } else { 00430 QMap< int, QMap<int, QVariant > > §ionDataMap 00431 = orientation == Qt::Horizontal ? d->horizontalHeaderDataMap : d->verticalHeaderDataMap; 00432 00433 QMap< int, QVariant > &dataMap = sectionDataMap[ section ]; 00434 dataMap.insert( role, value ); 00435 if ( sourceModel() ) { 00436 int numRows = rowCount( QModelIndex() ); 00437 int numCols = columnCount( QModelIndex() ); 00438 if ( orientation == Qt::Horizontal && numRows > 0 ) 00439 emit attributesChanged( index( 0, section, QModelIndex() ), 00440 index( numRows - 1, section, QModelIndex() ) ); 00441 else if ( orientation == Qt::Vertical && numCols > 0 ) 00442 emit attributesChanged( index( section, 0, QModelIndex() ), 00443 index( section, numCols - 1, QModelIndex() ) ); 00444 emit headerDataChanged( orientation, section, section ); 00445 00446 // FIXME: This only makes sense for orientation == Qt::Horizontal, 00447 // but what if orientation == Qt::Vertical? 00448 if ( section != -1 && numRows > 0 ) 00449 emit dataChanged( index( 0, section, QModelIndex() ), 00450 index( numRows - 1, section, QModelIndex() ) ); 00451 } 00452 return true; 00453 } 00454 } 00455 00456 bool AttributesModel::resetHeaderData ( int section, Qt::Orientation orientation, int role ) 00457 { 00458 return setHeaderData ( section, orientation, QVariant(), role ); 00459 } 00460 00461 void AttributesModel::setPaletteType( AttributesModel::PaletteType type ) 00462 { 00463 if ( d->paletteType == type ) { 00464 return; 00465 } 00466 d->paletteType = type; 00467 switch ( type ) { 00468 case PaletteTypeDefault: 00469 d->palette = Palette::defaultPalette(); 00470 break; 00471 case PaletteTypeSubdued: 00472 d->palette = Palette::subduedPalette(); 00473 break; 00474 case PaletteTypeRainbow: 00475 d->palette = Palette::rainbowPalette(); 00476 break; 00477 default: 00478 qWarning( "Unknown palette type!" ); 00479 } 00480 } 00481 00482 AttributesModel::PaletteType AttributesModel::paletteType() const 00483 { 00484 return d->paletteType; 00485 } 00486 00487 bool KDChart::AttributesModel::setModelData( const QVariant value, int role ) 00488 { 00489 d->modelDataMap.insert( role, value ); 00490 int numRows = rowCount( QModelIndex() ); 00491 int numCols = columnCount( QModelIndex() ); 00492 if ( sourceModel() && numRows > 0 && numCols > 0 ) { 00493 emit attributesChanged( index( 0, 0, QModelIndex() ), 00494 index( numRows - 1, numCols - 1, QModelIndex() ) ); 00495 reset(); 00496 } 00497 return true; 00498 } 00499 00500 QVariant KDChart::AttributesModel::modelData( int role ) const 00501 { 00502 return d->modelDataMap.value( role, QVariant() ); 00503 } 00504 00505 int AttributesModel::rowCount( const QModelIndex& index ) const 00506 { 00507 if ( sourceModel() ) { 00508 return sourceModel()->rowCount( mapToSource(index) ); 00509 } else { 00510 return 0; 00511 } 00512 } 00513 00514 int AttributesModel::columnCount( const QModelIndex& index ) const 00515 { 00516 if ( sourceModel() ) { 00517 return sourceModel()->columnCount( mapToSource(index) ); 00518 } else { 00519 return 0; 00520 } 00521 } 00522 00523 void AttributesModel::setSourceModel( QAbstractItemModel* sourceModel ) 00524 { 00525 if( this->sourceModel() != 0 ) 00526 { 00527 disconnect( this->sourceModel(), SIGNAL( dataChanged( const QModelIndex&, const QModelIndex&)), 00528 this, SLOT( slotDataChanged( const QModelIndex&, const QModelIndex&))); 00529 disconnect( this->sourceModel(), SIGNAL( rowsInserted( const QModelIndex&, int, int ) ), 00530 this, SLOT( slotRowsInserted( const QModelIndex&, int, int ) ) ); 00531 disconnect( this->sourceModel(), SIGNAL( rowsRemoved( const QModelIndex&, int, int ) ), 00532 this, SLOT( slotRowsRemoved( const QModelIndex&, int, int ) ) ); 00533 disconnect( this->sourceModel(), SIGNAL( rowsAboutToBeInserted( const QModelIndex&, int, int ) ), 00534 this, SLOT( slotRowsAboutToBeInserted( const QModelIndex&, int, int ) ) ); 00535 disconnect( this->sourceModel(), SIGNAL( rowsAboutToBeRemoved( const QModelIndex&, int, int ) ), 00536 this, SLOT( slotRowsAboutToBeRemoved( const QModelIndex&, int, int ) ) ); 00537 disconnect( this->sourceModel(), SIGNAL( columnsInserted( const QModelIndex&, int, int ) ), 00538 this, SLOT( slotColumnsInserted( const QModelIndex&, int, int ) ) ); 00539 disconnect( this->sourceModel(), SIGNAL( columnsRemoved( const QModelIndex&, int, int ) ), 00540 this, SLOT( slotColumnsRemoved( const QModelIndex&, int, int ) ) ); 00541 disconnect( this->sourceModel(), SIGNAL( columnsAboutToBeInserted( const QModelIndex&, int, int ) ), 00542 this, SLOT( slotColumnsAboutToBeInserted( const QModelIndex&, int, int ) ) ); 00543 disconnect( this->sourceModel(), SIGNAL( columnsAboutToBeRemoved( const QModelIndex&, int, int ) ), 00544 this, SLOT( slotColumnsAboutToBeRemoved( const QModelIndex&, int, int ) ) ); 00545 disconnect( this->sourceModel(), SIGNAL( modelReset() ), 00546 this, SIGNAL( modelReset() ) ); 00547 disconnect( this->sourceModel(), SIGNAL( layoutChanged() ), 00548 this, SIGNAL( layoutChanged() ) ); 00549 } 00550 QAbstractProxyModel::setSourceModel( sourceModel ); 00551 if( this->sourceModel() != NULL ) 00552 { 00553 connect( this->sourceModel(), SIGNAL( dataChanged( const QModelIndex&, const QModelIndex&)), 00554 this, SLOT( slotDataChanged( const QModelIndex&, const QModelIndex&))); 00555 connect( this->sourceModel(), SIGNAL( rowsInserted( const QModelIndex&, int, int ) ), 00556 this, SLOT( slotRowsInserted( const QModelIndex&, int, int ) ) ); 00557 connect( this->sourceModel(), SIGNAL( rowsRemoved( const QModelIndex&, int, int ) ), 00558 this, SLOT( slotRowsRemoved( const QModelIndex&, int, int ) ) ); 00559 connect( this->sourceModel(), SIGNAL( rowsAboutToBeInserted( const QModelIndex&, int, int ) ), 00560 this, SLOT( slotRowsAboutToBeInserted( const QModelIndex&, int, int ) ) ); 00561 connect( this->sourceModel(), SIGNAL( rowsAboutToBeRemoved( const QModelIndex&, int, int ) ), 00562 this, SLOT( slotRowsAboutToBeRemoved( const QModelIndex&, int, int ) ) ); 00563 connect( this->sourceModel(), SIGNAL( columnsInserted( const QModelIndex&, int, int ) ), 00564 this, SLOT( slotColumnsInserted( const QModelIndex&, int, int ) ) ); 00565 connect( this->sourceModel(), SIGNAL( columnsRemoved( const QModelIndex&, int, int ) ), 00566 this, SLOT( slotColumnsRemoved( const QModelIndex&, int, int ) ) ); 00567 connect( this->sourceModel(), SIGNAL( columnsAboutToBeInserted( const QModelIndex&, int, int ) ), 00568 this, SLOT( slotColumnsAboutToBeInserted( const QModelIndex&, int, int ) ) ); 00569 connect( this->sourceModel(), SIGNAL( columnsAboutToBeRemoved( const QModelIndex&, int, int ) ), 00570 this, SLOT( slotColumnsAboutToBeRemoved( const QModelIndex&, int, int ) ) ); 00571 connect( this->sourceModel(), SIGNAL( modelReset() ), 00572 this, SIGNAL( modelReset() ) ); 00573 connect( this->sourceModel(), SIGNAL( layoutChanged() ), 00574 this, SIGNAL( layoutChanged() ) ); 00575 } 00576 } 00577 00578 void AttributesModel::slotRowsAboutToBeInserted( const QModelIndex& parent, int start, int end ) 00579 { 00580 beginInsertRows( mapFromSource( parent ), start, end ); 00581 } 00582 00583 void AttributesModel::slotColumnsAboutToBeInserted( const QModelIndex& parent, int start, int end ) 00584 { 00585 beginInsertColumns( mapFromSource( parent ), start, end ); 00586 } 00587 00588 void AttributesModel::slotRowsInserted( const QModelIndex& parent, int start, int end ) 00589 { 00590 Q_UNUSED( parent ); 00591 Q_UNUSED( start ); 00592 Q_UNUSED( end ); 00593 endInsertRows(); 00594 } 00595 00596 void AttributesModel::slotColumnsInserted( const QModelIndex& parent, int start, int end ) 00597 { 00598 Q_UNUSED( parent ); 00599 Q_UNUSED( start ); 00600 Q_UNUSED( end ); 00601 endInsertColumns(); 00602 } 00603 00604 void AttributesModel::slotRowsAboutToBeRemoved( const QModelIndex& parent, int start, int end ) 00605 { 00606 beginRemoveRows( mapFromSource( parent ), start, end ); 00607 } 00608 00609 void AttributesModel::slotColumnsAboutToBeRemoved( const QModelIndex& parent, int start, int end ) 00610 { 00611 beginRemoveColumns( mapFromSource( parent ), start, end ); 00612 } 00613 00614 void AttributesModel::slotRowsRemoved( const QModelIndex& parent, int start, int end ) 00615 { 00616 Q_UNUSED( parent ); 00617 Q_UNUSED( start ); 00618 Q_UNUSED( end ); 00619 endRemoveRows(); 00620 } 00621 00622 void AttributesModel::removeEntriesFromDataMap( int start, int end ) 00623 { 00624 QMap< int, QMap< int, QMap< int, QVariant > > >::iterator it = d->dataMap.find( end ); 00625 // check that the element was found 00626 if ( it != d->dataMap.end() ) { 00627 ++it; 00628 QVector< int > indexesToDel; 00629 for ( int i = start; i < end && it != d->dataMap.end(); ++i ) { 00630 d->dataMap[ i ] = it.value(); 00631 indexesToDel << it.key(); 00632 ++it; 00633 } 00634 if ( indexesToDel.isEmpty() ) { 00635 for ( int i = start; i < end; ++i ) { 00636 indexesToDel << i; 00637 } 00638 } 00639 for ( int i = 0; i < indexesToDel.count(); ++i ) { 00640 d->dataMap.remove( indexesToDel[ i ] ); 00641 } 00642 } 00643 } 00644 00645 void AttributesModel::removeEntriesFromDirectionDataMaps( Qt::Orientation dir, int start, int end ) 00646 { 00647 QMap<int, QMap<int, QVariant> > §ionDataMap 00648 = dir == Qt::Horizontal ? d->horizontalHeaderDataMap : d->verticalHeaderDataMap; 00649 QMap<int, QMap<int, QVariant> >::iterator it = sectionDataMap.upperBound( end ); 00650 // check that the element was found 00651 if ( it != sectionDataMap.end() ) 00652 { 00653 QVector< int > indexesToDel; 00654 for ( int i = start; i < end && it != sectionDataMap.end(); ++i ) 00655 { 00656 sectionDataMap[ i ] = it.value(); 00657 indexesToDel << it.key(); 00658 ++it; 00659 } 00660 if ( indexesToDel.isEmpty() ) 00661 { 00662 for ( int i = start; i < end; ++i ) 00663 { 00664 indexesToDel << i; 00665 } 00666 } 00667 for ( int i = 0; i < indexesToDel.count(); ++i ) 00668 { 00669 sectionDataMap.remove( indexesToDel[ i ] ); 00670 } 00671 } 00672 } 00673 00674 void AttributesModel::slotColumnsRemoved( const QModelIndex& parent, int start, int end ) 00675 { 00676 Q_UNUSED( parent ); 00677 Q_UNUSED( start ); 00678 Q_UNUSED( end ); 00679 Q_ASSERT_X( sourceModel(), "removeColumn", "This should only be triggered if a valid source Model exists!" ); 00680 for ( int i = start; i <= end; ++i ) { 00681 d->verticalHeaderDataMap.remove( start ); 00682 } 00683 removeEntriesFromDataMap( start, end ); 00684 removeEntriesFromDirectionDataMaps( Qt::Horizontal, start, end ); 00685 removeEntriesFromDirectionDataMaps( Qt::Vertical, start, end ); 00686 00687 endRemoveColumns(); 00688 } 00689 00690 void AttributesModel::slotDataChanged( const QModelIndex& topLeft, const QModelIndex& bottomRight ) 00691 { 00692 emit dataChanged( mapFromSource( topLeft ), mapFromSource( bottomRight ) ); 00693 } 00694 00695 void AttributesModel::setDefaultForRole( int role, const QVariant& value ) 00696 { 00697 if ( value.isValid() ) { 00698 d->defaultsMap.insert( role, value ); 00699 } else { 00700 // erase the possibily existing value to not let the map grow: 00701 QMap<int, QVariant>::iterator it = d->defaultsMap.find( role ); 00702 if ( it != d->defaultsMap.end() ) { 00703 d->defaultsMap.erase( it ); 00704 } 00705 } 00706 00707 Q_ASSERT( defaultsForRole( role ) == value ); 00708 } 00709 00710 void AttributesModel::setDatasetDimension( int dimension ) 00711 { 00712 //### need to "reformat" or throw away internal data? 00713 d->dataDimension = dimension; 00714 } 00715 00716 int AttributesModel::datasetDimension() const 00717 { 00718 return d->dataDimension; 00719 }