KD Chart 2  [rev.2.5]
KDChartAttributesModel.cpp
Go to the documentation of this file.
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 > > &sectionDataMap
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> > &sectionDataMap
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Defines

Klarälvdalens Datakonsult AB (KDAB)
Qt-related services and products
http://www.kdab.com/
http://www.kdab.com/products/kd-chart/