KD Chart 2
[rev.2.5]
|
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