|
QGIS API Documentation
master-59fd5e0
|
00001 /*************************************************************************** 00002 QgsAttributeTableFilterModel.cpp 00003 -------------------------------------- 00004 Date : Feb 2009 00005 Copyright : (C) 2009 Vita Cizek 00006 Email : weetya (at) gmail.com 00007 *************************************************************************** 00008 * * 00009 * This program is free software; you can redistribute it and/or modify * 00010 * it under the terms of the GNU General Public License as published by * 00011 * the Free Software Foundation; either version 2 of the License, or * 00012 * (at your option) any later version. * 00013 * * 00014 ***************************************************************************/ 00015 00016 #include <QItemSelectionModel> 00017 00018 #include "qgsattributetablefiltermodel.h" 00019 #include "qgsattributetablemodel.h" 00020 #include "qgsvectorlayer.h" 00021 #include "qgsfeature.h" 00022 #include "qgsmapcanvas.h" 00023 #include "qgslogger.h" 00024 #include "qgsrendererv2.h" 00025 #include "qgsvectorlayereditbuffer.h" 00027 // Filter Model // 00029 00030 QgsAttributeTableFilterModel::QgsAttributeTableFilterModel( QgsMapCanvas* canvas, QgsAttributeTableModel* sourceModel, QObject* parent ) 00031 : QSortFilterProxyModel( parent ) 00032 , mCanvas( canvas ) 00033 , mFilterMode( ShowAll ) 00034 , mSelectedOnTop( false ) 00035 { 00036 mMasterSelection = new QItemSelectionModel( this, this ); 00037 setSourceModel( sourceModel ); 00038 setDynamicSortFilter( true ); 00039 setSortRole( QgsAttributeTableModel::SortRole ); 00040 connect( layer(), SIGNAL( selectionChanged() ), SLOT( selectionChanged() ) ); 00041 } 00042 00043 bool QgsAttributeTableFilterModel::lessThan( const QModelIndex &left, const QModelIndex &right ) const 00044 { 00045 if ( mSelectedOnTop ) 00046 { 00047 bool leftSelected = layer()->selectedFeaturesIds().contains( masterModel()->rowToId( left.row() ) ); 00048 bool rightSelected = layer()->selectedFeaturesIds().contains( masterModel()->rowToId( right.row() ) ); 00049 00050 if ( leftSelected && !rightSelected ) 00051 { 00052 return true; 00053 } 00054 else if ( rightSelected && !leftSelected ) 00055 { 00056 return false; 00057 } 00058 } 00059 00060 00061 QVariant leftData = left.data( QgsAttributeTableModel::SortRole ); 00062 QVariant rightData = right.data( QgsAttributeTableModel::SortRole ); 00063 00064 if ( leftData.isNull() ) 00065 return true; 00066 00067 if ( rightData.isNull() ) 00068 return false; 00069 00070 switch ( leftData.type() ) 00071 { 00072 case QVariant::Int: 00073 case QVariant::UInt: 00074 case QVariant::LongLong: 00075 case QVariant::ULongLong: 00076 return leftData.toLongLong() < rightData.toLongLong(); 00077 00078 case QVariant::Double: 00079 return leftData.toDouble() < rightData.toDouble(); 00080 00081 default: 00082 return leftData.toString().localeAwareCompare( rightData.toString() ) < 0; 00083 } 00084 00085 // Avoid warning. Will never reach this 00086 return false; 00087 } 00088 00089 void QgsAttributeTableFilterModel::sort( int column, Qt::SortOrder order ) 00090 { 00091 masterModel()->prefetchColumnData( column ); 00092 QSortFilterProxyModel::sort( column, order ); 00093 } 00094 00095 void QgsAttributeTableFilterModel::setSelectedOnTop( bool selectedOnTop ) 00096 { 00097 if ( mSelectedOnTop != selectedOnTop ) 00098 { 00099 mSelectedOnTop = selectedOnTop; 00100 00101 if ( sortColumn() == -1 ) 00102 { 00103 sort( 0 ); 00104 } 00105 invalidate(); 00106 } 00107 } 00108 00109 void QgsAttributeTableFilterModel::setSourceModel( QgsAttributeTableModel* sourceModel ) 00110 { 00111 mTableModel = sourceModel; 00112 delete mMasterSelection; 00113 mMasterSelection = new QItemSelectionModel( sourceModel, this ); 00114 00115 QSortFilterProxyModel::setSourceModel( sourceModel ); 00116 } 00117 00118 bool QgsAttributeTableFilterModel::selectedOnTop() 00119 { 00120 return mSelectedOnTop; 00121 } 00122 00123 void QgsAttributeTableFilterModel::setFilteredFeatures( QgsFeatureIds ids ) 00124 { 00125 mFilteredFeatures = ids; 00126 setFilterMode( ShowFilteredList ); 00127 invalidateFilter(); 00128 } 00129 00130 void QgsAttributeTableFilterModel::setFilterMode( FilterMode filterMode ) 00131 { 00132 if ( filterMode != mFilterMode ) 00133 { 00134 if ( filterMode == ShowVisible ) 00135 { 00136 connect( mCanvas, SIGNAL( extentsChanged() ), this, SLOT( extentsChanged() ) ); 00137 generateListOfVisibleFeatures(); 00138 } 00139 else 00140 { 00141 disconnect( mCanvas, SIGNAL( extentsChanged() ), this, SLOT( extentsChanged() ) ); 00142 } 00143 00144 if ( filterMode == ShowSelected ) 00145 { 00146 generateListOfVisibleFeatures(); 00147 } 00148 00149 mFilterMode = filterMode; 00150 invalidateFilter(); 00151 } 00152 } 00153 00154 bool QgsAttributeTableFilterModel::filterAcceptsRow( int sourceRow, const QModelIndex &sourceParent ) const 00155 { 00156 Q_UNUSED( sourceParent ); 00157 switch ( mFilterMode ) 00158 { 00159 case ShowAll: 00160 return true; 00161 break; 00162 00163 case ShowFilteredList: 00164 return mFilteredFeatures.contains( masterModel()->rowToId( sourceRow ) ); 00165 break; 00166 00167 case ShowSelected: 00168 return layer()->selectedFeaturesIds().contains( masterModel()->rowToId( sourceRow ) ); 00169 break; 00170 00171 case ShowVisible: 00172 return mFilteredFeatures.contains( masterModel()->rowToId( sourceRow ) ); 00173 break; 00174 00175 case ShowEdited: 00176 { 00177 QgsVectorLayerEditBuffer* editBuffer = layer()->editBuffer(); 00178 if ( editBuffer ) 00179 { 00180 const QList<QgsFeatureId> addedFeatures = editBuffer->addedFeatures().keys(); 00181 const QList<QgsFeatureId> changedFeatures = editBuffer->changedAttributeValues().keys(); 00182 const QgsFeatureId fid = masterModel()->rowToId( sourceRow ); 00183 return addedFeatures.contains( fid ) || changedFeatures.contains( fid ); 00184 } 00185 return false; 00186 break; 00187 } 00188 00189 default: 00190 Q_ASSERT( false ); // In debug mode complain 00191 return true; // In release mode accept row 00192 break; 00193 } 00194 // returns are handled in their respective case statement above 00195 } 00196 00197 void QgsAttributeTableFilterModel::extentsChanged() 00198 { 00199 generateListOfVisibleFeatures(); 00200 invalidateFilter(); 00201 } 00202 00203 void QgsAttributeTableFilterModel::selectionChanged() 00204 { 00205 if ( ShowSelected == mFilterMode ) 00206 { 00207 generateListOfVisibleFeatures(); 00208 invalidateFilter(); 00209 } 00210 else if ( mSelectedOnTop ) 00211 { 00212 sort( sortColumn(), sortOrder() ); 00213 invalidate(); 00214 } 00215 } 00216 00217 void QgsAttributeTableFilterModel::generateListOfVisibleFeatures() 00218 { 00219 if ( !layer() ) 00220 return; 00221 00222 bool filter = false; 00223 QgsRectangle rect = mCanvas->mapRenderer()->mapToLayerCoordinates( layer(), mCanvas->extent() ); 00224 QgsRenderContext renderContext; 00225 QgsFeatureRendererV2* renderer = layer()->rendererV2(); 00226 00227 mFilteredFeatures.clear(); 00228 00229 if ( !renderer ) 00230 { 00231 QgsDebugMsg( "Cannot get renderer" ); 00232 return; 00233 } 00234 00235 if ( layer()->hasScaleBasedVisibility() && 00236 ( layer()->minimumScale() > mCanvas->mapRenderer()->scale() || 00237 layer()->maximumScale() <= mCanvas->mapRenderer()->scale() ) ) 00238 { 00239 QgsDebugMsg( "Out of scale limits" ); 00240 } 00241 else 00242 { 00243 if ( renderer && renderer->capabilities() & QgsFeatureRendererV2::ScaleDependent ) 00244 { 00245 // setup scale 00246 // mapRenderer()->renderContext()->scale is not automaticaly updated when 00247 // render extent changes (because it's scale is used to identify if changed 00248 // since last render) -> use local context 00249 renderContext.setExtent( mCanvas->mapRenderer()->rendererContext()->extent() ); 00250 renderContext.setMapToPixel( mCanvas->mapRenderer()->rendererContext()->mapToPixel() ); 00251 renderContext.setRendererScale( mCanvas->mapRenderer()->scale() ); 00252 } 00253 00254 filter = renderer && renderer->capabilities() & QgsFeatureRendererV2::Filter; 00255 } 00256 00257 renderer->startRender( renderContext, layer() ); 00258 00259 QgsFeatureIterator features = masterModel()->layerCache()->getFeatures( QgsFeatureRequest().setFlags( QgsFeatureRequest::NoGeometry ).setFilterRect( rect ) ); 00260 00261 QgsFeature f; 00262 00263 while ( features.nextFeature( f ) ) 00264 { 00265 if ( !filter || renderer->willRenderFeature( f ) ) 00266 { 00267 mFilteredFeatures << f.id(); 00268 } 00269 #if 0 00270 if ( t.elapsed() > 5000 ) 00271 { 00272 bool cancel = false; 00273 emit progress( i, cancel ); 00274 if ( cancel ) 00275 break; 00276 00277 t.restart(); 00278 } 00279 #endif 00280 } 00281 00282 features.close(); 00283 00284 if ( renderer && renderer->capabilities() & QgsFeatureRendererV2::ScaleDependent ) 00285 { 00286 renderer->stopRender( renderContext ); 00287 } 00288 } 00289 00290 QgsFeatureId QgsAttributeTableFilterModel::rowToId( const QModelIndex& row ) 00291 { 00292 return masterModel()->rowToId( mapToSource( row ).row() ); 00293 } 00294 00295 QModelIndex QgsAttributeTableFilterModel::fidToIndex( QgsFeatureId fid ) 00296 { 00297 return mapFromMaster( masterModel()->idToIndex( fid ) ); 00298 } 00299 00300 QModelIndexList QgsAttributeTableFilterModel::fidToIndexList( QgsFeatureId fid ) 00301 { 00302 QModelIndexList indexes; 00303 foreach ( QModelIndex idx, masterModel()->idToIndexList( fid ) ) 00304 { 00305 indexes.append( mapFromMaster( idx ) ); 00306 } 00307 00308 return indexes; 00309 } 00310 00311 QModelIndex QgsAttributeTableFilterModel::mapToMaster( const QModelIndex &proxyIndex ) const 00312 { 00313 // Master is source 00314 return mapToSource( proxyIndex ); 00315 } 00316 00317 QModelIndex QgsAttributeTableFilterModel::mapFromMaster( const QModelIndex &sourceIndex ) const 00318 { 00319 // Master is source 00320 return mapFromSource( sourceIndex ); 00321 }