# KDChartDatasetProxyModel.cpp

Go to the documentation of this file.

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