Branch data Line data Source code
1 : : /*************************************************************************** 2 : : qgsmaplayerproxymodel.cpp 3 : : -------------------------------------- 4 : : Date : 01.04.2014 5 : : Copyright : (C) 2014 Denis Rouzaud 6 : : Email : denis.rouzaud@gmail.com 7 : : *************************************************************************** 8 : : * * 9 : : * This program is free software; you can redistribute it and/or modify * 10 : : * it under the terms of the GNU General Public License as published by * 11 : : * the Free Software Foundation; either version 2 of the License, or * 12 : : * (at your option) any later version. * 13 : : * * 14 : : ***************************************************************************/ 15 : : 16 : : #include "qgsmaplayerproxymodel.h" 17 : : #include "qgsmaplayermodel.h" 18 : : #include "qgsmaplayer.h" 19 : : #include "qgsproject.h" 20 : : #include "qgsvectorlayer.h" 21 : : #include "qgsrasterlayer.h" 22 : : #include "qgsmeshlayer.h" 23 : : #include "qgsvectordataprovider.h" 24 : : #include "qgsrasterdataprovider.h" 25 : : #include "qgsmeshdataprovider.h" 26 : : 27 : 0 : QgsMapLayerProxyModel::QgsMapLayerProxyModel( QObject *parent ) 28 : 0 : : QSortFilterProxyModel( parent ) 29 : 0 : , mFilters( All ) 30 : 0 : , mModel( new QgsMapLayerModel( parent ) ) 31 : 0 : { 32 : 0 : setSourceModel( mModel ); 33 : 0 : setDynamicSortFilter( true ); 34 : 0 : setSortLocaleAware( true ); 35 : 0 : setFilterCaseSensitivity( Qt::CaseInsensitive ); 36 : 0 : sort( 0 ); 37 : 0 : } 38 : : 39 : 0 : QgsMapLayerProxyModel *QgsMapLayerProxyModel::setFilters( Filters filters ) 40 : : { 41 : 0 : mFilters = filters; 42 : 0 : invalidateFilter(); 43 : 0 : return this; 44 : : } 45 : : 46 : 0 : bool QgsMapLayerProxyModel::layerMatchesFilters( const QgsMapLayer *layer, const Filters &filters ) 47 : : { 48 : 0 : if ( filters.testFlag( All ) ) 49 : 0 : return true; 50 : : 51 : : // layer type 52 : 0 : if ( ( filters.testFlag( RasterLayer ) && layer->type() == QgsMapLayerType::RasterLayer ) || 53 : 0 : ( filters.testFlag( VectorLayer ) && layer->type() == QgsMapLayerType::VectorLayer ) || 54 : 0 : ( filters.testFlag( MeshLayer ) && layer->type() == QgsMapLayerType::MeshLayer ) || 55 : 0 : ( filters.testFlag( VectorTileLayer ) && layer->type() == QgsMapLayerType::VectorTileLayer ) || 56 : 0 : ( filters.testFlag( PointCloudLayer ) && layer->type() == QgsMapLayerType::PointCloudLayer ) || 57 : 0 : ( filters.testFlag( PluginLayer ) && layer->type() == QgsMapLayerType::PluginLayer ) ) 58 : 0 : return true; 59 : : 60 : : // geometry type 61 : 0 : bool detectGeometry = filters.testFlag( NoGeometry ) || 62 : 0 : filters.testFlag( PointLayer ) || 63 : 0 : filters.testFlag( LineLayer ) || 64 : 0 : filters.testFlag( PolygonLayer ) || 65 : 0 : filters.testFlag( HasGeometry ); 66 : 0 : if ( detectGeometry && layer->type() == QgsMapLayerType::VectorLayer ) 67 : : { 68 : 0 : if ( const QgsVectorLayer *vl = qobject_cast<const QgsVectorLayer *>( layer ) ) 69 : : { 70 : 0 : if ( filters.testFlag( HasGeometry ) && vl->isSpatial() ) 71 : 0 : return true; 72 : 0 : if ( filters.testFlag( NoGeometry ) && vl->geometryType() == QgsWkbTypes::NullGeometry ) 73 : 0 : return true; 74 : 0 : if ( filters.testFlag( PointLayer ) && vl->geometryType() == QgsWkbTypes::PointGeometry ) 75 : 0 : return true; 76 : 0 : if ( filters.testFlag( LineLayer ) && vl->geometryType() == QgsWkbTypes::LineGeometry ) 77 : 0 : return true; 78 : 0 : if ( filters.testFlag( PolygonLayer ) && vl->geometryType() == QgsWkbTypes::PolygonGeometry ) 79 : 0 : return true; 80 : 0 : } 81 : 0 : } 82 : : 83 : 0 : return false; 84 : 0 : } 85 : : 86 : 0 : void QgsMapLayerProxyModel::setLayerWhitelist( const QList<QgsMapLayer *> &layers ) 87 : : { 88 : 0 : setLayerAllowlist( layers ); 89 : 0 : } 90 : : 91 : 0 : void QgsMapLayerProxyModel::setLayerAllowlist( const QList<QgsMapLayer *> &layers ) 92 : : { 93 : 0 : if ( mLayerAllowlist == layers ) 94 : 0 : return; 95 : : 96 : 0 : mLayerAllowlist = layers; 97 : 0 : invalidateFilter(); 98 : 0 : } 99 : : 100 : 0 : void QgsMapLayerProxyModel::setExceptedLayerList( const QList<QgsMapLayer *> &exceptList ) 101 : : { 102 : 0 : if ( mExceptList == exceptList ) 103 : 0 : return; 104 : : 105 : 0 : mExceptList = exceptList; 106 : 0 : invalidateFilter(); 107 : 0 : } 108 : : 109 : 0 : void QgsMapLayerProxyModel::setExceptedLayerIds( const QStringList &ids ) 110 : : { 111 : 0 : mExceptList.clear(); 112 : : 113 : 0 : const auto constIds = ids; 114 : 0 : for ( const QString &id : constIds ) 115 : : { 116 : 0 : QgsMapLayer *l = QgsProject::instance()->mapLayer( id ); 117 : 0 : if ( l ) 118 : 0 : mExceptList << l; 119 : : } 120 : 0 : invalidateFilter(); 121 : 0 : } 122 : : 123 : 0 : QStringList QgsMapLayerProxyModel::exceptedLayerIds() const 124 : : { 125 : 0 : QStringList lst; 126 : : 127 : 0 : const auto constMExceptList = mExceptList; 128 : 0 : for ( QgsMapLayer *l : constMExceptList ) 129 : 0 : lst << l->id(); 130 : : 131 : 0 : return lst; 132 : 0 : } 133 : : 134 : 0 : void QgsMapLayerProxyModel::setExcludedProviders( const QStringList &providers ) 135 : : { 136 : 0 : mExcludedProviders = providers; 137 : 0 : invalidateFilter(); 138 : 0 : } 139 : : 140 : 0 : bool QgsMapLayerProxyModel::acceptsLayer( QgsMapLayer *layer ) const 141 : : { 142 : 0 : if ( !layer ) 143 : 0 : return false; 144 : : 145 : 0 : if ( !mLayerAllowlist.isEmpty() && !mLayerAllowlist.contains( layer ) ) 146 : 0 : return false; 147 : : 148 : 0 : if ( mExceptList.contains( layer ) ) 149 : 0 : return false; 150 : : 151 : 0 : if ( layer->dataProvider() && mExcludedProviders.contains( layer->providerType() ) ) 152 : 0 : return false; 153 : : 154 : 0 : if ( mFilters.testFlag( WritableLayer ) && layer->readOnly() ) 155 : 0 : return false; 156 : : 157 : 0 : if ( !layer->name().contains( mFilterString, Qt::CaseInsensitive ) ) 158 : 0 : return false; 159 : : 160 : 0 : return layerMatchesFilters( layer, mFilters ); 161 : 0 : } 162 : : 163 : 0 : void QgsMapLayerProxyModel::setFilterString( const QString &filter ) 164 : : { 165 : 0 : mFilterString = filter; 166 : 0 : invalidateFilter(); 167 : 0 : } 168 : : 169 : 0 : bool QgsMapLayerProxyModel::filterAcceptsRow( int source_row, const QModelIndex &source_parent ) const 170 : : { 171 : 0 : if ( mFilters.testFlag( All ) && mExceptList.isEmpty() && mLayerAllowlist.isEmpty() && mExcludedProviders.isEmpty() && mFilterString.isEmpty() ) 172 : 0 : return true; 173 : : 174 : 0 : QModelIndex index = sourceModel()->index( source_row, 0, source_parent ); 175 : : 176 : 0 : if ( sourceModel()->data( index, QgsMapLayerModel::EmptyRole ).toBool() 177 : 0 : || sourceModel()->data( index, QgsMapLayerModel::AdditionalRole ).toBool() ) 178 : 0 : return true; 179 : : 180 : 0 : return acceptsLayer( static_cast<QgsMapLayer *>( index.internalPointer() ) ); 181 : 0 : } 182 : : 183 : 0 : bool QgsMapLayerProxyModel::lessThan( const QModelIndex &left, const QModelIndex &right ) const 184 : : { 185 : : // empty row is always first 186 : 0 : if ( sourceModel()->data( left, QgsMapLayerModel::EmptyRole ).toBool() ) 187 : 0 : return true; 188 : 0 : else if ( sourceModel()->data( right, QgsMapLayerModel::EmptyRole ).toBool() ) 189 : 0 : return false; 190 : : 191 : : // additional rows are always last 192 : 0 : bool leftAdditional = sourceModel()->data( left, QgsMapLayerModel::AdditionalRole ).toBool(); 193 : 0 : bool rightAdditional = sourceModel()->data( right, QgsMapLayerModel::AdditionalRole ).toBool(); 194 : : 195 : 0 : if ( leftAdditional && !rightAdditional ) 196 : 0 : return false; 197 : 0 : else if ( rightAdditional && !leftAdditional ) 198 : 0 : return true; 199 : : 200 : : // default mode is alphabetical order 201 : 0 : QString leftStr = sourceModel()->data( left ).toString(); 202 : 0 : QString rightStr = sourceModel()->data( right ).toString(); 203 : 0 : return QString::localeAwareCompare( leftStr, rightStr ) < 0; 204 : 0 : }