KDChartAttributesModel.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 ** Copyright (C) 2001-2011 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>
00032 #include <KDChartFrameAttributes>
00033 #include <KDChartBackgroundAttributes>
00034 #include <KDChartDataValueAttributes>
00035 #include <KDChartMarkerAttributes>
00036 #include <KDChartBarAttributes>
00037 #include <KDChartStockBarAttributes>
00038 #include <KDChartLineAttributes>
00039 #include <KDChartPieAttributes>
00040 #include <KDChartAbstractThreeDAttributes>
00041 #include <KDChartThreeDBarAttributes>
00042 #include <KDChartThreeDLineAttributes>
00043 #include <KDChartThreeDPieAttributes>
00044 #include <KDChartGridAttributes>
00045 #include <KDChartValueTrackerAttributes>
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> > &sectionDataMap
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> > &sectionDataMap
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 }
 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/