KD Chart 2 [rev.2.4]
|
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 AttributesModel::AttributesModel( QAbstractItemModel* model, QObject * parent/* = 0 */ ) 00053 : AbstractProxyModel( parent ), 00054 mPaletteType( PaletteTypeDefault ) 00055 { 00056 setSourceModel(model); 00057 setDefaultForRole( KDChart::DataValueLabelAttributesRole, 00058 DataValueAttributes::defaultAttributesAsVariant() ); 00059 } 00060 00061 AttributesModel::~AttributesModel() 00062 { 00063 } 00064 00065 void AttributesModel::initFrom( const AttributesModel* other ) 00066 { 00067 if( other == this || ! other ) return; 00068 00069 mDataMap = other->mDataMap; 00070 mHorizontalHeaderDataMap = other->mHorizontalHeaderDataMap; 00071 mVerticalHeaderDataMap = other->mVerticalHeaderDataMap; 00072 mModelDataMap = other->mModelDataMap; 00073 mDefaultsMap = other->mDefaultsMap; 00074 00075 setPaletteType( other->paletteType() ); 00076 } 00077 00078 bool AttributesModel::compare( const AttributesModel* other )const 00079 { 00080 if( other == this ) return true; 00081 if( ! other ){ 00082 //qDebug() << "AttributesModel::compare() cannot compare to Null pointer"; 00083 return false; 00084 } 00085 00086 { 00087 if (mDataMap.count() != other->mDataMap.count()){ 00088 //qDebug() << "AttributesModel::compare() dataMap have different sizes"; 00089 return false; 00090 } 00091 QMap<int, QMap<int, QMap<int, QVariant> > >::const_iterator itA = mDataMap.constBegin(); 00092 QMap<int, QMap<int, QMap<int, QVariant> > >::const_iterator itB = other->mDataMap.constBegin(); 00093 while (itA != mDataMap.constEnd()) { 00094 if ((*itA).count() != (*itB).count()){ 00095 //qDebug() << "AttributesModel::compare() dataMap/map have different sizes"; 00096 return false; 00097 } 00098 QMap<int, QMap<int, QVariant> >::const_iterator it2A = (*itA).constBegin(); 00099 QMap<int, QMap<int, QVariant> >::const_iterator it2B = (*itB).constBegin(); 00100 while (it2A != itA->constEnd()) { 00101 if ((*it2A).count() != (*it2B).count()){ 00102 //qDebug() << "AttributesModel::compare() dataMap/map/map have different sizes:" 00103 // << (*it2A).count() << (*it2B).count(); 00104 return false; 00105 } 00106 QMap<int, QVariant>::const_iterator it3A = (*it2A).constBegin(); 00107 QMap<int, QVariant>::const_iterator it3B = (*it2B).constBegin(); 00108 while (it3A != it2A->constEnd()) { 00109 if ( it3A.key() != it3B.key() ){ 00110 //qDebug( "AttributesModel::compare()\n" 00111 // " dataMap[%i, %i] values have different types. A: %x B: %x", 00112 // itA.key(), it2A.key(), it3A.key(), it3B.key()); 00113 return false; 00114 } 00115 if ( ! compareAttributes( it3A.key(), it3A.value(), it3B.value() ) ){ 00116 //qDebug( "AttributesModel::compare()\n" 00117 // " dataMap[%i, %i] values are different. Role: %x", itA.key(), it2A.key(), it3A.key()); 00118 return false; 00119 } 00120 ++it3A; 00121 ++it3B; 00122 } 00123 ++it2A; 00124 ++it2B; 00125 } 00126 ++itA; 00127 ++itB; 00128 } 00129 } 00130 { 00131 if (mHorizontalHeaderDataMap.count() != other->mHorizontalHeaderDataMap.count()){ 00132 //qDebug() << "AttributesModel::compare() horizontalHeaderDataMap have different sizes"; 00133 return false; 00134 } 00135 QMap<int, QMap<int, QVariant> >::const_iterator itA = mHorizontalHeaderDataMap.constBegin(); 00136 QMap<int, QMap<int, QVariant> >::const_iterator itB = other->mHorizontalHeaderDataMap.constBegin(); 00137 while (itA != mHorizontalHeaderDataMap.constEnd()) { 00138 if ((*itA).count() != (*itB).count()){ 00139 //qDebug() << "AttributesModel::compare() horizontalHeaderDataMap/map have different sizes"; 00140 return false; 00141 } 00142 QMap<int, QVariant>::const_iterator it2A = (*itA).constBegin(); 00143 QMap<int, QVariant>::const_iterator it2B = (*itB).constBegin(); 00144 while (it2A != itA->constEnd()) { 00145 if ( it2A.key() != it2B.key() ){ 00146 //qDebug( "AttributesModel::compare()\n" 00147 // " horizontalHeaderDataMap[ %i ] values have different types. A: %x B: %x", 00148 // itA.key(), it2A.key(), it2B.key()); 00149 return false; 00150 } 00151 if ( ! compareAttributes( it2A.key(), it2A.value(), it2B.value() ) ){ 00152 //qDebug( "AttributesModel::compare()\n" 00153 // " horizontalHeaderDataMap[ %i ] values are different. Role: %x", itA.key(), it2A.key() ); 00154 return false; 00155 } 00156 ++it2A; 00157 ++it2B; 00158 } 00159 ++itA; 00160 ++itB; 00161 } 00162 } 00163 { 00164 if (mVerticalHeaderDataMap.count() != other->mVerticalHeaderDataMap.count()){ 00165 //qDebug() << "AttributesModel::compare() verticalHeaderDataMap have different sizes"; 00166 return false; 00167 } 00168 QMap<int, QMap<int, QVariant> >::const_iterator itA = mVerticalHeaderDataMap.constBegin(); 00169 QMap<int, QMap<int, QVariant> >::const_iterator itB = other->mVerticalHeaderDataMap.constBegin(); 00170 while (itA != mVerticalHeaderDataMap.constEnd()) { 00171 if ((*itA).count() != (*itB).count()){ 00172 //qDebug() << "AttributesModel::compare() verticalHeaderDataMap/map have different sizes"; 00173 return false; 00174 } 00175 QMap<int, QVariant>::const_iterator it2A = (*itA).constBegin(); 00176 QMap<int, QVariant>::const_iterator it2B = (*itB).constBegin(); 00177 while (it2A != itA->constEnd()) { 00178 if ( it2A.key() != it2B.key() ){ 00179 //qDebug( "AttributesModel::compare()\n" 00180 // " verticalHeaderDataMap[ %i ] values have different types. A: %x B: %x", 00181 // itA.key(), it2A.key(), it2B.key()); 00182 return false; 00183 } 00184 if ( ! compareAttributes( it2A.key(), it2A.value(), it2B.value() ) ){ 00185 //qDebug( "AttributesModel::compare()\n" 00186 // " verticalHeaderDataMap[ %i ] values are different. Role: %x", itA.key(), it2A.key() ); 00187 return false; 00188 } 00189 ++it2A; 00190 ++it2B; 00191 } 00192 ++itA; 00193 ++itB; 00194 } 00195 } 00196 { 00197 if (mModelDataMap.count() != other->mModelDataMap.count()){ 00198 //qDebug() << "AttributesModel::compare() modelDataMap have different sizes:" << mModelDataMap.count() << other->mModelDataMap.count(); 00199 return false; 00200 } 00201 QMap<int, QVariant>::const_iterator itA = mModelDataMap.constBegin(); 00202 QMap<int, QVariant>::const_iterator itB = other->mModelDataMap.constBegin(); 00203 while (itA != mModelDataMap.constEnd()) { 00204 if ( itA.key() != itB.key() ){ 00205 //qDebug( "AttributesModel::compare()\n" 00206 // " modelDataMap values have different types. A: %x B: %x", 00207 // itA.key(), itB.key()); 00208 return false; 00209 } 00210 if ( ! compareAttributes( itA.key(), itA.value(), itB.value() ) ){ 00211 //qDebug( "AttributesModel::compare()\n" 00212 // " modelDataMap values are different. Role: %x", itA.key() ); 00213 return false; 00214 } 00215 ++itA; 00216 ++itB; 00217 } 00218 } 00219 if (paletteType() != other->paletteType()){ 00220 //qDebug() << "AttributesModel::compare() palette types are different"; 00221 return false; 00222 } 00223 return true; 00224 } 00225 00226 bool AttributesModel::compareAttributes( 00227 int role, const QVariant& a, const QVariant& b )const 00228 { 00229 if( isKnownAttributesRole( role ) ){ 00230 switch( role ) { 00231 case DataValueLabelAttributesRole: 00232 return (qVariantValue<DataValueAttributes>( a ) == 00233 qVariantValue<DataValueAttributes>( b )); 00234 case DatasetBrushRole: 00235 return (qVariantValue<QBrush>( a ) == 00236 qVariantValue<QBrush>( b )); 00237 case DatasetPenRole: 00238 return (qVariantValue<QPen>( a ) == 00239 qVariantValue<QPen>( b )); 00240 case ThreeDAttributesRole: 00241 // As of yet there is no ThreeDAttributes class, 00242 // and the AbstractThreeDAttributes class is pure virtual, 00243 // so we ignore this role for now. 00244 // (khz, 04.04.2007) 00245 /* 00246 return (qVariantValue<ThreeDAttributes>( a ) == 00247 qVariantValue<ThreeDAttributes>( b )); 00248 */ 00249 break; 00250 case LineAttributesRole: 00251 return (qVariantValue<LineAttributes>( a ) == 00252 qVariantValue<LineAttributes>( b )); 00253 case ThreeDLineAttributesRole: 00254 return (qVariantValue<ThreeDLineAttributes>( a ) == 00255 qVariantValue<ThreeDLineAttributes>( b )); 00256 case BarAttributesRole: 00257 return (qVariantValue<BarAttributes>( a ) == 00258 qVariantValue<BarAttributes>( b )); 00259 case StockBarAttributesRole: 00260 return (qVariantValue<StockBarAttributes>( a ) == 00261 qVariantValue<StockBarAttributes>( b )); 00262 case ThreeDBarAttributesRole: 00263 return (qVariantValue<ThreeDBarAttributes>( a ) == 00264 qVariantValue<ThreeDBarAttributes>( b )); 00265 case PieAttributesRole: 00266 return (qVariantValue<PieAttributes>( a ) == 00267 qVariantValue<PieAttributes>( b )); 00268 case ThreeDPieAttributesRole: 00269 return (qVariantValue<ThreeDPieAttributes>( a ) == 00270 qVariantValue<ThreeDPieAttributes>( b )); 00271 case ValueTrackerAttributesRole: 00272 return (qVariantValue<ValueTrackerAttributes>( a ) == 00273 qVariantValue<ValueTrackerAttributes>( b )); 00274 case DataHiddenRole: 00275 return (qVariantValue<bool>( a ) == 00276 qVariantValue<bool>( b )); 00277 default: 00278 Q_ASSERT( false ); // all of our own roles need to be handled 00279 break; 00280 } 00281 }else{ 00282 return (a == b); 00283 } 00284 return true; 00285 } 00286 00287 00288 QVariant AttributesModel::headerData ( int section, 00289 Qt::Orientation orientation, 00290 int role/* = Qt::DisplayRole */ ) const 00291 { 00292 if( sourceModel() ) { 00293 const QVariant sourceData = sourceModel()->headerData( section, orientation, role ); 00294 if ( sourceData.isValid() ) return sourceData; 00295 } 00296 00297 if( orientation == Qt::Horizontal && role == ColumnDataRole ) 00298 { 00299 // it seems the source model doesn't like the idea of handing out all the column data at once... 00300 // so we have to do it manually. 00301 QVariantList result; 00302 const int rows = sourceModel()->rowCount(); 00303 for( int row = 0; row < rows; ++row ) 00304 result.push_back( sourceModel()->index( row, section ).data() ); 00305 00306 return result; 00307 } 00308 00309 00310 // the source model didn't have data set, let's use our stored values 00311 const QMap<int, QMap<int, QVariant> >& map = orientation == Qt::Horizontal ? mHorizontalHeaderDataMap : mVerticalHeaderDataMap; 00312 if ( map.contains( section ) ) { 00313 const QMap<int, QVariant> &dataMap = map[ section ]; 00314 if ( dataMap.contains( role ) ) { 00315 return dataMap[ role ]; 00316 } 00317 } 00318 00319 return defaultHeaderData( section, orientation, role ); 00320 } 00321 00322 00323 QVariant AttributesModel::defaultHeaderData ( int section, Qt::Orientation orientation, int role ) const 00324 { 00325 // Default values if nothing else matches 00326 switch ( role ) { 00327 case Qt::DisplayRole: 00328 //TODO for KDChart 3.0: Change to "return QString::number( section+1 );" 00329 return QLatin1String( orientation == Qt::Vertical ? "Series " : "Item " ) + QString::number( section ) ; 00330 00331 case KDChart::DatasetBrushRole: { 00332 if ( paletteType() == PaletteTypeSubdued ) 00333 return Palette::subduedPalette().getBrush( section ); 00334 else if ( paletteType() == PaletteTypeRainbow ) 00335 return Palette::rainbowPalette().getBrush( section ); 00336 else if ( paletteType() == PaletteTypeDefault ) 00337 return Palette::defaultPalette().getBrush( section ); 00338 else 00339 qWarning("Unknown type of fallback palette!"); 00340 } break; 00341 case KDChart::DatasetPenRole: { 00342 // default to the color set for the brush (or it's defaults) 00343 // but only if no per model override was set 00344 if ( !modelData( role ).isValid() ) { 00345 QBrush brush = qVariantValue<QBrush>( headerData( section, orientation, DatasetBrushRole ) ); 00346 return QPen( brush.color() ); 00347 } 00348 } break; 00349 default: 00350 break; 00351 } 00352 00353 return QVariant(); 00354 } 00355 00356 // Note: Our users NEED this method - even if 00357 // we do not need it at drawing time! 00358 // (khz, 2006-07-28) 00359 QVariant AttributesModel::data( int role ) const 00360 { 00361 if ( isKnownAttributesRole( role ) ) { 00362 // check if there is something set at global level 00363 QVariant v = modelData( role ); 00364 00365 // else return the default setting, if any 00366 if ( !v.isValid() ) 00367 v = defaultsForRole( role ); 00368 return v; 00369 } 00370 return QVariant(); 00371 } 00372 00373 00374 // Note: Our users NEED this method - even if 00375 // we do not need it at drawing time! 00376 // (khz, 2006-07-28) 00377 QVariant AttributesModel::data( int column, int role ) const 00378 { 00379 if ( isKnownAttributesRole( role ) ) { 00380 // check if there is something set for the column (dataset) 00381 QVariant v; 00382 v = headerData( column, Qt::Horizontal, role ); 00383 00384 // check if there is something set at global level 00385 if ( !v.isValid() ) 00386 v = data( role ); // includes automatic fallback to default 00387 return v; 00388 } 00389 return QVariant(); 00390 } 00391 00392 00393 QVariant AttributesModel::data( const QModelIndex& index, int role ) const 00394 { 00395 //qDebug() << "AttributesModel::data(" << index << role << ")"; 00396 if( index.isValid() ) { 00397 Q_ASSERT( index.model() == this ); 00398 } 00399 00400 if( sourceModel() == 0 ) 00401 return QVariant(); 00402 00403 if( index.isValid() ) 00404 { 00405 const QVariant sourceData = sourceModel()->data( mapToSource(index), role ); 00406 if( sourceData.isValid() ) 00407 return sourceData; 00408 } 00409 00410 // check if we are storing a value for this role at this cell index 00411 if( mDataMap.contains( index.column() ) ) 00412 { 00413 const QMap< int, QMap< int, QVariant > >& colDataMap = mDataMap[ index.column() ]; 00414 if( colDataMap.contains( index.row() ) ) 00415 { 00416 const QMap< int, QVariant >& dataMap = colDataMap[ index.row() ]; 00417 if( dataMap.contains( role ) ) 00418 { 00419 const QVariant v = dataMap[ role ]; 00420 if( v.isValid() ) 00421 return v; 00422 } 00423 } 00424 } 00425 // check if there is something set for the column (dataset), or at global level 00426 if( index.isValid() ) 00427 return data( index.column(), role ); // includes automatic fallback to default 00428 00429 return QVariant(); 00430 } 00431 00432 00433 bool AttributesModel::isKnownAttributesRole( int role ) const 00434 { 00435 bool oneOfOurs = false; 00436 switch( role ) { 00437 // fallthrough intended 00438 case DataValueLabelAttributesRole: 00439 case DatasetBrushRole: 00440 case DatasetPenRole: 00441 case ThreeDAttributesRole: 00442 case LineAttributesRole: 00443 case ThreeDLineAttributesRole: 00444 case BarAttributesRole: 00445 case StockBarAttributesRole: 00446 case ThreeDBarAttributesRole: 00447 case PieAttributesRole: 00448 case ThreeDPieAttributesRole: 00449 case ValueTrackerAttributesRole: 00450 case DataHiddenRole: 00451 oneOfOurs = true; 00452 default: 00453 break; 00454 } 00455 return oneOfOurs; 00456 } 00457 00458 QVariant AttributesModel::defaultsForRole( int role ) const 00459 { 00460 // returns default-constructed QVariant if not found 00461 return mDefaultsMap.value( role ); 00462 } 00463 00464 bool AttributesModel::setData ( const QModelIndex & index, const QVariant & value, int role ) 00465 { 00466 if ( !isKnownAttributesRole( role ) ) { 00467 return sourceModel()->setData( mapToSource(index), value, role ); 00468 } else { 00469 QMap< int, QMap< int, QVariant> > &colDataMap = mDataMap[ index.column() ]; 00470 QMap<int, QVariant> &dataMap = colDataMap[ index.row() ]; 00471 //qDebug() << "AttributesModel::setData" <<"role" << role << "value" << value; 00472 dataMap.insert( role, value ); 00473 emit attributesChanged( index, index ); 00474 return true; 00475 } 00476 } 00477 00478 bool AttributesModel::resetData ( const QModelIndex & index, int role ) 00479 { 00480 return setData ( index, QVariant(), role ); 00481 } 00482 00483 bool AttributesModel::setHeaderData ( int section, Qt::Orientation orientation, 00484 const QVariant & value, int role ) 00485 { 00486 if( sourceModel() != 0 && headerData( section, orientation, role ) == value ) 00487 return true; 00488 if ( !isKnownAttributesRole( role ) ) { 00489 return sourceModel()->setHeaderData( section, orientation, value, role ); 00490 } else { 00491 QMap<int, QMap<int, QVariant> > §ionDataMap 00492 = orientation == Qt::Horizontal ? mHorizontalHeaderDataMap : mVerticalHeaderDataMap; 00493 QMap<int, QVariant> &dataMap = sectionDataMap[ section ]; 00494 dataMap.insert( role, value ); 00495 if( sourceModel() ){ 00496 emit attributesChanged( index( 0, section, QModelIndex() ), 00497 index( rowCount( QModelIndex() ), section, QModelIndex() ) ); 00498 emit headerDataChanged( orientation, section, section ); 00499 if ( section != -1 ) 00500 emit dataChanged( index( 0, section, QModelIndex() ), 00501 index( rowCount( QModelIndex() ) - 1, section, QModelIndex() ) ); 00502 } 00503 return true; 00504 } 00505 } 00506 00507 bool AttributesModel::resetHeaderData ( int section, Qt::Orientation orientation, int role ) 00508 { 00509 return setHeaderData ( section, orientation, QVariant(), role ); 00510 } 00511 00512 void AttributesModel::setPaletteType( AttributesModel::PaletteType type ) 00513 { 00514 mPaletteType = type; 00515 } 00516 00517 AttributesModel::PaletteType AttributesModel::paletteType() const 00518 { 00519 return mPaletteType; 00520 } 00521 00522 bool KDChart::AttributesModel::setModelData( const QVariant value, int role ) 00523 { 00524 mModelDataMap.insert( role, value ); 00525 if( sourceModel() ){ 00526 emit attributesChanged( index( 0, 0, QModelIndex() ), 00527 index( rowCount( QModelIndex() ), 00528 columnCount( QModelIndex() ), QModelIndex() ) ); 00529 } 00530 return true; 00531 } 00532 00533 QVariant KDChart::AttributesModel::modelData( int role ) const 00534 { 00535 return mModelDataMap.value( role, QVariant() ); 00536 } 00537 00538 int AttributesModel::rowCount( const QModelIndex& index ) const 00539 { 00540 if ( sourceModel() ) { 00541 return sourceModel()->rowCount( mapToSource(index) ); 00542 } else { 00543 return 0; 00544 } 00545 } 00546 00547 int AttributesModel::columnCount( const QModelIndex& index ) const 00548 { 00549 if ( sourceModel() ) { 00550 return sourceModel()->columnCount( mapToSource(index) ); 00551 } else { 00552 return 0; 00553 } 00554 } 00555 00556 void AttributesModel::setSourceModel( QAbstractItemModel* sourceModel ) 00557 { 00558 if( this->sourceModel() != 0 ) 00559 { 00560 disconnect( this->sourceModel(), SIGNAL( dataChanged( const QModelIndex&, const QModelIndex&)), 00561 this, SLOT( slotDataChanged( const QModelIndex&, const QModelIndex&))); 00562 disconnect( this->sourceModel(), SIGNAL( rowsInserted( const QModelIndex&, int, int ) ), 00563 this, SLOT( slotRowsInserted( const QModelIndex&, int, int ) ) ); 00564 disconnect( this->sourceModel(), SIGNAL( rowsRemoved( const QModelIndex&, int, int ) ), 00565 this, SLOT( slotRowsRemoved( const QModelIndex&, int, int ) ) ); 00566 disconnect( this->sourceModel(), SIGNAL( rowsAboutToBeInserted( const QModelIndex&, int, int ) ), 00567 this, SLOT( slotRowsAboutToBeInserted( const QModelIndex&, int, int ) ) ); 00568 disconnect( this->sourceModel(), SIGNAL( rowsAboutToBeRemoved( const QModelIndex&, int, int ) ), 00569 this, SLOT( slotRowsAboutToBeRemoved( const QModelIndex&, int, int ) ) ); 00570 disconnect( this->sourceModel(), SIGNAL( columnsInserted( const QModelIndex&, int, int ) ), 00571 this, SLOT( slotColumnsInserted( const QModelIndex&, int, int ) ) ); 00572 disconnect( this->sourceModel(), SIGNAL( columnsRemoved( const QModelIndex&, int, int ) ), 00573 this, SLOT( slotColumnsRemoved( const QModelIndex&, int, int ) ) ); 00574 disconnect( this->sourceModel(), SIGNAL( columnsAboutToBeInserted( const QModelIndex&, int, int ) ), 00575 this, SLOT( slotColumnsAboutToBeInserted( const QModelIndex&, int, int ) ) ); 00576 disconnect( this->sourceModel(), SIGNAL( columnsAboutToBeRemoved( const QModelIndex&, int, int ) ), 00577 this, SLOT( slotColumnsAboutToBeRemoved( const QModelIndex&, int, int ) ) ); 00578 disconnect( this->sourceModel(), SIGNAL( modelReset() ), 00579 this, SIGNAL( modelReset() ) ); 00580 disconnect( this->sourceModel(), SIGNAL( layoutChanged() ), 00581 this, SIGNAL( layoutChanged() ) ); 00582 } 00583 QAbstractProxyModel::setSourceModel( sourceModel ); 00584 if( this->sourceModel() != NULL ) 00585 { 00586 connect( this->sourceModel(), SIGNAL( dataChanged( const QModelIndex&, const QModelIndex&)), 00587 this, SLOT( slotDataChanged( const QModelIndex&, const QModelIndex&))); 00588 connect( this->sourceModel(), SIGNAL( rowsInserted( const QModelIndex&, int, int ) ), 00589 this, SLOT( slotRowsInserted( const QModelIndex&, int, int ) ) ); 00590 connect( this->sourceModel(), SIGNAL( rowsRemoved( const QModelIndex&, int, int ) ), 00591 this, SLOT( slotRowsRemoved( const QModelIndex&, int, int ) ) ); 00592 connect( this->sourceModel(), SIGNAL( rowsAboutToBeInserted( const QModelIndex&, int, int ) ), 00593 this, SLOT( slotRowsAboutToBeInserted( const QModelIndex&, int, int ) ) ); 00594 connect( this->sourceModel(), SIGNAL( rowsAboutToBeRemoved( const QModelIndex&, int, int ) ), 00595 this, SLOT( slotRowsAboutToBeRemoved( const QModelIndex&, int, int ) ) ); 00596 connect( this->sourceModel(), SIGNAL( columnsInserted( const QModelIndex&, int, int ) ), 00597 this, SLOT( slotColumnsInserted( const QModelIndex&, int, int ) ) ); 00598 connect( this->sourceModel(), SIGNAL( columnsRemoved( const QModelIndex&, int, int ) ), 00599 this, SLOT( slotColumnsRemoved( const QModelIndex&, int, int ) ) ); 00600 connect( this->sourceModel(), SIGNAL( columnsAboutToBeInserted( const QModelIndex&, int, int ) ), 00601 this, SLOT( slotColumnsAboutToBeInserted( const QModelIndex&, int, int ) ) ); 00602 connect( this->sourceModel(), SIGNAL( columnsAboutToBeRemoved( const QModelIndex&, int, int ) ), 00603 this, SLOT( slotColumnsAboutToBeRemoved( const QModelIndex&, int, int ) ) ); 00604 connect( this->sourceModel(), SIGNAL( modelReset() ), 00605 this, SIGNAL( modelReset() ) ); 00606 connect( this->sourceModel(), SIGNAL( layoutChanged() ), 00607 this, SIGNAL( layoutChanged() ) ); 00608 } 00609 } 00610 00611 void AttributesModel::slotRowsAboutToBeInserted( const QModelIndex& parent, int start, int end ) 00612 { 00613 beginInsertRows( mapFromSource( parent ), start, end ); 00614 } 00615 00616 void AttributesModel::slotColumnsAboutToBeInserted( const QModelIndex& parent, int start, int end ) 00617 { 00618 beginInsertColumns( mapFromSource( parent ), start, end ); 00619 } 00620 00621 void AttributesModel::slotRowsInserted( const QModelIndex& parent, int start, int end ) 00622 { 00623 Q_UNUSED( parent ); 00624 Q_UNUSED( start ); 00625 Q_UNUSED( end ); 00626 endInsertRows(); 00627 } 00628 00629 void AttributesModel::slotColumnsInserted( const QModelIndex& parent, int start, int end ) 00630 { 00631 Q_UNUSED( parent ); 00632 Q_UNUSED( start ); 00633 Q_UNUSED( end ); 00634 endInsertColumns(); 00635 } 00636 00637 void AttributesModel::slotRowsAboutToBeRemoved( const QModelIndex& parent, int start, int end ) 00638 { 00639 beginRemoveRows( mapFromSource( parent ), start, end ); 00640 } 00641 00642 void AttributesModel::slotColumnsAboutToBeRemoved( const QModelIndex& parent, int start, int end ) 00643 { 00644 beginRemoveColumns( mapFromSource( parent ), start, end ); 00645 } 00646 00647 void AttributesModel::slotRowsRemoved( const QModelIndex& parent, int start, int end ) 00648 { 00649 Q_UNUSED( parent ); 00650 Q_UNUSED( start ); 00651 Q_UNUSED( end ); 00652 endRemoveRows(); 00653 } 00654 00655 void AttributesModel::removeEntriesFromDataMap( int start, int end ) 00656 { 00657 QMap<int, QMap<int, QMap<int, QVariant> > >::iterator it = mDataMap.find( end ); 00658 // check that the element was found 00659 if ( it != mDataMap.end() ) 00660 { 00661 ++it; 00662 QVector< int > indexesToDel; 00663 for ( int i = start; i < end && it != mDataMap.end(); ++i ) 00664 { 00665 mDataMap[ i ] = it.value(); 00666 indexesToDel << it.key(); 00667 ++it; 00668 } 00669 if ( indexesToDel.isEmpty() ) 00670 { 00671 for ( int i = start; i < end; ++i ) 00672 { 00673 indexesToDel << i; 00674 } 00675 } 00676 for ( int i = 0; i < indexesToDel.count(); ++i ) 00677 { 00678 mDataMap.remove( indexesToDel[ i ] ); 00679 } 00680 } 00681 } 00682 00683 void AttributesModel::removeEntriesFromDirectionDataMaps( Qt::Orientation dir, int start, int end ) 00684 { 00685 QMap<int, QMap<int, QVariant> > §ionDataMap 00686 = dir == Qt::Horizontal ? mHorizontalHeaderDataMap : mVerticalHeaderDataMap; 00687 QMap<int, QMap<int, QVariant> >::iterator it = sectionDataMap.upperBound( end ); 00688 // check that the element was found 00689 if ( it != sectionDataMap.end() ) 00690 { 00691 QVector< int > indexesToDel; 00692 for ( int i = start; i < end && it != sectionDataMap.end(); ++i ) 00693 { 00694 sectionDataMap[ i ] = it.value(); 00695 indexesToDel << it.key(); 00696 ++it; 00697 } 00698 if ( indexesToDel.isEmpty() ) 00699 { 00700 for ( int i = start; i < end; ++i ) 00701 { 00702 indexesToDel << i; 00703 } 00704 } 00705 for ( int i = 0; i < indexesToDel.count(); ++i ) 00706 { 00707 sectionDataMap.remove( indexesToDel[ i ] ); 00708 } 00709 } 00710 } 00711 00712 void AttributesModel::slotColumnsRemoved( const QModelIndex& parent, int start, int end ) 00713 { 00714 Q_UNUSED( parent ); 00715 Q_UNUSED( start ); 00716 Q_UNUSED( end ); 00717 Q_ASSERT_X( sourceModel(), "removeColumn", "This should only be triggered if a valid source Model exists! " ); 00718 for ( int i = start; i <= end; ++i ) 00719 { 00720 mVerticalHeaderDataMap.remove( start ); 00721 } 00722 removeEntriesFromDataMap( start, end ); 00723 removeEntriesFromDirectionDataMaps( Qt::Horizontal, start, end ); 00724 removeEntriesFromDirectionDataMaps( Qt::Vertical, start, end ); 00725 00726 endRemoveColumns(); 00727 } 00728 00729 void AttributesModel::slotDataChanged( const QModelIndex& topLeft, const QModelIndex& bottomRight ) 00730 { 00731 emit dataChanged( mapFromSource( topLeft ), mapFromSource( bottomRight ) ); 00732 } 00733 00735 const QMap<int, QMap<int, QMap<int, QVariant> > > AttributesModel::dataMap()const 00736 { 00737 return mDataMap; 00738 } 00740 const QMap<int, QMap<int, QVariant> > AttributesModel::horizontalHeaderDataMap()const 00741 { 00742 return mHorizontalHeaderDataMap; 00743 } 00745 const QMap<int, QMap<int, QVariant> > AttributesModel::verticalHeaderDataMap()const 00746 { 00747 return mVerticalHeaderDataMap; 00748 } 00750 const QMap<int, QVariant> AttributesModel::modelDataMap()const 00751 { 00752 return mModelDataMap; 00753 } 00754 00756 void AttributesModel::setDataMap( const QMap<int, QMap<int, QMap<int, QVariant> > > map ) 00757 { 00758 mDataMap = map; 00759 } 00761 void AttributesModel::setHorizontalHeaderDataMap( const QMap<int, QMap<int, QVariant> > map ) 00762 { 00763 mHorizontalHeaderDataMap = map; 00764 } 00766 void AttributesModel::setVerticalHeaderDataMap( const QMap<int, QMap<int, QVariant> > map ) 00767 { 00768 mVerticalHeaderDataMap = map; 00769 } 00771 void AttributesModel::setModelDataMap( const QMap<int, QVariant> map ) 00772 { 00773 mModelDataMap = map; 00774 } 00775 00776 void AttributesModel::setDefaultForRole( int role, const QVariant& value ) 00777 { 00778 if ( value.isValid() ) { 00779 mDefaultsMap.insert( role, value ); 00780 } else { 00781 // erase the possibily existing value to not let the map grow: 00782 QMap<int, QVariant>::iterator it = mDefaultsMap.find( role ); 00783 if ( it != mDefaultsMap.end() ) { 00784 mDefaultsMap.erase( it ); 00785 } 00786 } 00787 00788 Q_ASSERT( defaultsForRole( role ) == value ); 00789 }