KD Chart 2  [rev.2.5]
KDChartDatasetProxyModel.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 "KDChartDatasetProxyModel.h"
00024 
00025 #include <QtDebug>
00026 
00027 #include <KDABLibFakes>
00028 
00029 
00030 using namespace KDChart;
00031 
00032 DatasetProxyModel::DatasetProxyModel(QObject* parent)
00033     : QSortFilterProxyModel( parent )
00034 {
00035 }
00036 
00037 QModelIndex DatasetProxyModel::buddy( const QModelIndex& index ) const
00038 {
00039     return index;
00040 }
00041 
00042 Qt::ItemFlags DatasetProxyModel::flags( const QModelIndex& index ) const
00043 {
00044     return sourceModel()->flags( mapToSource( index ) );
00045 }
00046 
00047 void DatasetProxyModel::setDatasetRowDescriptionVector(
00048     const DatasetDescriptionVector& configuration )
00049 {
00050     Q_ASSERT_X( sourceModel(), "DatasetProxyModel::setDatasetRowDescriptionVector",
00051                 "A source model must be set before the selection can be configured." );
00052     initializeDatasetDecriptors( configuration, sourceModel()->rowCount(mRootIndex),
00053                                  mRowSrcToProxyMap,  mRowProxyToSrcMap );
00054     clear(); // clear emits layoutChanged()
00055 }
00056 
00057 void DatasetProxyModel::setDatasetColumnDescriptionVector(
00058     const DatasetDescriptionVector& configuration )
00059 {
00060     Q_ASSERT_X( sourceModel(), "DatasetProxyModel::setDatasetColumnDescriptionVector",
00061                 "A source model must be set before the selection can be configured." );
00062     initializeDatasetDecriptors( configuration, sourceModel()->columnCount(mRootIndex),
00063                                  mColSrcToProxyMap, mColProxyToSrcMap );
00064     clear(); // clear emits layoutChanged()
00065 }
00066 
00067 void DatasetProxyModel::setDatasetDescriptionVectors(
00068     const DatasetDescriptionVector& rowConfig,
00069     const DatasetDescriptionVector& columnConfig )
00070 {
00071     setDatasetRowDescriptionVector( rowConfig );
00072     setDatasetColumnDescriptionVector( columnConfig );
00073 }
00074 
00075 QModelIndex DatasetProxyModel::index( int row, int column,
00076                                       const QModelIndex &parent ) const
00077 {
00078     return mapFromSource( sourceModel()->index( mapProxyRowToSource(row),
00079                                                 mapProxyColumnToSource(column),
00080                                                 parent ) );
00081 }
00082 
00083 QModelIndex DatasetProxyModel::parent( const QModelIndex& child ) const
00084 {
00085 //    return mapFromSource( sourceModel()->parent( child ) );
00086     return mapFromSource( sourceModel()->parent( mapToSource( child ) ) );
00087 }
00088 
00089 QModelIndex DatasetProxyModel::mapFromSource( const QModelIndex & sourceIndex ) const
00090 {
00091     Q_ASSERT_X( sourceModel(), "DatasetProxyModel::mapFromSource", "A source "
00092                 "model must be set before the selection can be configured." );
00093 
00094     if ( !sourceIndex.isValid() ) return sourceIndex;
00095 
00096     if ( mRowSrcToProxyMap.isEmpty() && mColSrcToProxyMap.isEmpty() )
00097     {
00098         return createIndex( sourceIndex.row(), sourceIndex.column(),
00099                             sourceIndex.internalPointer() );
00100     } else {
00101         int row = mapSourceRowToProxy( sourceIndex.row() );
00102         int column = mapSourceColumnToProxy( sourceIndex.column() );
00103         return createIndex( row, column, sourceIndex.internalPointer() );
00104     }
00105 }
00106 
00107 QModelIndex DatasetProxyModel::mapToSource( const QModelIndex& proxyIndex ) const
00108 {
00109     Q_ASSERT_X( sourceModel(), "DatasetProxyModel::mapToSource", "A source "
00110                 "model must be set before the selection can be configured." );
00111 
00112     if ( !proxyIndex.isValid() ) return proxyIndex;
00113     if ( mRowSrcToProxyMap.isEmpty() && mColSrcToProxyMap.isEmpty() )
00114     {
00115         return sourceModel()->index( proxyIndex.row(),  proxyIndex.column(), mRootIndex );
00116     } else {
00117         int row = mapProxyRowToSource( proxyIndex.row() );
00118         int column = mapProxyColumnToSource( proxyIndex.column() );
00119         return sourceModel()->index( row, column, mRootIndex );
00120     }
00121 }
00122 
00123 bool DatasetProxyModel::filterAcceptsRow( int sourceRow,
00124                                           const QModelIndex & ) const
00125 {
00126     if ( mRowSrcToProxyMap.isEmpty() )
00127     {   // no row mapping set, all rows are passed down:
00128         return true;
00129     } else {
00130         Q_ASSERT( sourceModel() );
00131         Q_ASSERT( mRowSrcToProxyMap.size() == sourceModel()->rowCount(mRootIndex) );
00132         if ( mRowSrcToProxyMap[sourceRow] == -1 )
00133         {   // this row is explicitly not accepted:
00134             return false;
00135         } else {
00136             Q_ASSERT( mRowSrcToProxyMap[sourceRow] >= 0
00137                       && mRowSrcToProxyMap[sourceRow] < mRowSrcToProxyMap.size() );
00138             return true;
00139         }
00140     }
00141 }
00142 
00143 bool DatasetProxyModel::filterAcceptsColumn( int sourceColumn,
00144                                              const QModelIndex & ) const
00145 {
00146     if ( mColSrcToProxyMap.isEmpty() )
00147     {   // no column mapping set up yet, all columns are passed down:
00148         return true;
00149     } else {
00150         Q_ASSERT( sourceModel() );
00151         Q_ASSERT( mColSrcToProxyMap.size() == sourceModel()->columnCount(mRootIndex) );
00152         if ( mColSrcToProxyMap[sourceColumn] == -1 )
00153         {   // this column is explicitly not accepted:
00154             return false;
00155         } else {
00156             Q_ASSERT( mColSrcToProxyMap[sourceColumn] >= 0
00157                       && mColSrcToProxyMap[sourceColumn] < mColSrcToProxyMap.size() );
00158             return true;
00159         }
00160     }
00161 }
00162 
00163 int DatasetProxyModel::mapProxyRowToSource( const int& proxyRow ) const
00164 {
00165     if ( mRowProxyToSrcMap.isEmpty() )
00166     {   // if no row mapping is set, we pass down the row:
00167         return proxyRow;
00168     } else {
00169         Q_ASSERT( proxyRow >= 0 && proxyRow < mRowProxyToSrcMap.size() );
00170         return mRowProxyToSrcMap[ proxyRow ];
00171     }
00172 }
00173 
00174 int DatasetProxyModel::mapProxyColumnToSource( const int& proxyColumn ) const
00175 {
00176     if ( mColProxyToSrcMap.isEmpty() )
00177     {   // if no column mapping is set, we pass down the column:
00178         return proxyColumn;
00179     } else {
00180         Q_ASSERT( proxyColumn >= 0 && proxyColumn < mColProxyToSrcMap.size() );
00181         return mColProxyToSrcMap[ proxyColumn ];
00182     }
00183 }
00184 
00185 int DatasetProxyModel::mapSourceRowToProxy( const int& sourceRow ) const
00186 {
00187     if ( mRowSrcToProxyMap.isEmpty() )
00188     {
00189         return sourceRow;
00190     } else {
00191         Q_ASSERT( sourceRow >= 0 && sourceRow < mRowSrcToProxyMap.size() );
00192         return mRowSrcToProxyMap[sourceRow];
00193     }
00194 }
00195 
00196 int DatasetProxyModel::mapSourceColumnToProxy( const int& sourceColumn ) const
00197 {
00198     if ( mColSrcToProxyMap.isEmpty() )
00199     {
00200         return sourceColumn;
00201     } else {
00202         Q_ASSERT( sourceColumn >= 0 && sourceColumn < mColSrcToProxyMap.size() );
00203         return mColSrcToProxyMap.at( sourceColumn ) ;
00204     }
00205 }
00206 
00207 void DatasetProxyModel::resetDatasetDescriptions()
00208 {
00209     mRowSrcToProxyMap.clear();
00210     mRowProxyToSrcMap.clear();
00211     mColSrcToProxyMap.clear();
00212     mColProxyToSrcMap.clear();
00213     clear();
00214 }
00215 
00216 QVariant DatasetProxyModel::data(const QModelIndex &index, int role) const
00217 {
00218    return sourceModel()->data( mapToSource( index ), role );
00219 }
00220 
00221 bool DatasetProxyModel::setData( const QModelIndex& index, const QVariant& value, int role )
00222 {
00223     return sourceModel()->setData( mapToSource( index ), value, role );
00224 }
00225 
00226 QVariant DatasetProxyModel::headerData( int section, Qt::Orientation orientation, int role ) const
00227 {
00228     if ( orientation == Qt::Horizontal )
00229     {
00230         if ( mapProxyColumnToSource ( section ) == -1 )
00231         {
00232             return QVariant();
00233         } else {
00234             return sourceModel()->headerData( mapProxyColumnToSource( section ), orientation,  role );
00235         }
00236     } else {
00237         if ( mapProxyRowToSource ( section ) == -1 )
00238         {
00239             return QVariant();
00240         } else {
00241             return sourceModel()->headerData( mapProxyRowToSource ( section ), orientation, role );
00242         }
00243     }
00244 }
00245 
00246 void DatasetProxyModel::initializeDatasetDecriptors(
00247     const DatasetDescriptionVector& inConfiguration,
00248     const int sourceCount,
00249     DatasetDescriptionVector& outSourceToProxyMap,
00250     DatasetDescriptionVector& outProxyToSourceMap )
00251 {
00252     // in the current mapping implementation, the proxy-to-source map is
00253     // identical to the configuration vector:
00254     outProxyToSourceMap = inConfiguration;
00255     outSourceToProxyMap.fill( -1,  sourceCount );
00256 
00257     for ( int index = 0; index < inConfiguration.size(); ++index ) {
00258         // make sure the values in inConfiguration point to columns in the
00259         // source model:
00260 
00261         if ( inConfiguration[index] == -1 ) {
00262             continue;
00263         }
00264 
00265         Q_ASSERT_X( inConfiguration[ index ] >= 0 && inConfiguration[ index ] < sourceCount,
00266                     "DatasetProxyModel::initializeDatasetDecriptors",
00267                     "column index outside of source model" );
00268         Q_ASSERT_X( outSourceToProxyMap[ inConfiguration[ index ] ] == -1 ,
00269                     "DatasetProxyModel::initializeDatasetDecriptors",
00270                     "no duplicates allowed in mapping configuration, mapping has to be reversible" );
00271 
00272         outSourceToProxyMap[ inConfiguration[ index ] ] = index;
00273     }
00274 }
00275 
00276 void DatasetProxyModel::setSourceModel(QAbstractItemModel *m)
00277 {
00278     if ( sourceModel() ) {
00279         disconnect( sourceModel(),  SIGNAL( layoutChanged() ),
00280                     this, SLOT( resetDatasetDescriptions() ) );
00281     }
00282     QSortFilterProxyModel::setSourceModel( m );
00283     mRootIndex = QModelIndex();
00284     if ( m ) {
00285         connect( m,  SIGNAL( layoutChanged() ),
00286                  this, SLOT( resetDatasetDescriptions() ) );
00287         connect( m, SIGNAL( layoutChanged() ), this, SIGNAL( layoutChanged() ) );
00288     }
00289     resetDatasetDescriptions();
00290 }
00291 
00292 void DatasetProxyModel::setSourceRootIndex(const QModelIndex& rootIdx)
00293 {
00294     mRootIndex = rootIdx;
00295     resetDatasetDescriptions();
00296 }
00297 
 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/