KDChartDatasetProxyModel.cpp

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

Generated on Thu Mar 4 23:19:10 2010 for KD Chart 2 by  doxygen 1.5.4