|
25 | 25 | #include "qgsmaplayermodel.h" |
26 | 26 | #include "qgscomposition.h" |
27 | 27 | #include "qgslayoutmanager.h" |
| 28 | +#include "qgsmapcanvas.h" |
28 | 29 | #include <QToolButton> |
29 | 30 |
|
30 | 31 | QgsLayerTreeLocatorFilter::QgsLayerTreeLocatorFilter( QObject *parent ) |
@@ -163,3 +164,98 @@ void QgsActionLocatorFilter::searchActions( const QString &string, QWidget *pare |
163 | 164 | } |
164 | 165 | } |
165 | 166 | } |
| 167 | + |
| 168 | +QgsActiveLayerFeaturesLocatorFilter::QgsActiveLayerFeaturesLocatorFilter( QObject *parent ) |
| 169 | + : QgsLocatorFilter( parent ) |
| 170 | +{ |
| 171 | + setUseWithoutPrefix( false ); |
| 172 | +} |
| 173 | + |
| 174 | +void QgsActiveLayerFeaturesLocatorFilter::fetchResults( const QString &string, const QgsLocatorContext &, QgsFeedback *feedback ) |
| 175 | +{ |
| 176 | + if ( string.length() < 3 ) |
| 177 | + return; |
| 178 | + |
| 179 | + bool allowNumeric = false; |
| 180 | + double numericValue = string.toDouble( &allowNumeric ); |
| 181 | + |
| 182 | + QgsVectorLayer *layer = qobject_cast< QgsVectorLayer *>( QgisApp::instance()->activeLayer() ); |
| 183 | + if ( !layer ) |
| 184 | + return; |
| 185 | + |
| 186 | + int found = 0; |
| 187 | + QgsExpression dispExpression( layer->displayExpression() ); |
| 188 | + QgsExpressionContext context; |
| 189 | + context.appendScopes( QgsExpressionContextUtils::globalProjectLayerScopes( layer ) ); |
| 190 | + dispExpression.prepare( &context ); |
| 191 | + |
| 192 | + // build up request expression |
| 193 | + QStringList expressionParts; |
| 194 | + Q_FOREACH ( const QgsField &field, layer->fields() ) |
| 195 | + { |
| 196 | + if ( field.type() == QVariant::String ) |
| 197 | + { |
| 198 | + expressionParts << QStringLiteral( "%1 ILIKE '%%2%'" ).arg( QgsExpression::quotedColumnRef( field.name() ), |
| 199 | + string ); |
| 200 | + } |
| 201 | + else if ( allowNumeric && field.isNumeric() ) |
| 202 | + { |
| 203 | + expressionParts << QStringLiteral( "%1 = %2" ).arg( QgsExpression::quotedColumnRef( field.name() ) ).arg( numericValue ); |
| 204 | + } |
| 205 | + } |
| 206 | + |
| 207 | + QString expression = QStringLiteral( "(%1)" ).arg( expressionParts.join( QStringLiteral( " ) OR ( " ) ) ); |
| 208 | + |
| 209 | + QgsFeatureRequest req; |
| 210 | + req.setFlags( QgsFeatureRequest::NoGeometry ); |
| 211 | + req.setFilterExpression( expression ); |
| 212 | + req.setLimit( 30 ); |
| 213 | + QgsFeature f; |
| 214 | + QgsFeatureIterator it = layer->getFeatures( req ); |
| 215 | + while ( it.nextFeature( f ) ) |
| 216 | + { |
| 217 | + if ( feedback->isCanceled() ) |
| 218 | + return; |
| 219 | + |
| 220 | + QgsLocatorResult result; |
| 221 | + result.filter = this; |
| 222 | + |
| 223 | + context.setFeature( f ); |
| 224 | + |
| 225 | + // find matching field content |
| 226 | + Q_FOREACH ( const QVariant &var, f.attributes() ) |
| 227 | + { |
| 228 | + QString attrString = var.toString(); |
| 229 | + if ( attrString.contains( string, Qt::CaseInsensitive ) ) |
| 230 | + { |
| 231 | + result.displayString = attrString; |
| 232 | + break; |
| 233 | + } |
| 234 | + } |
| 235 | + if ( result.displayString.isEmpty() ) |
| 236 | + continue; //not sure how this result slipped through... |
| 237 | + |
| 238 | + result.description = dispExpression.evaluate( &context ).toString(); |
| 239 | + |
| 240 | + result.userData = QVariantList() << f.id() << layer->id(); |
| 241 | + result.icon = QgsMapLayerModel::iconForLayer( layer ); |
| 242 | + result.score = static_cast< double >( string.length() ) / result.displayString.size(); |
| 243 | + emit resultFetched( result ); |
| 244 | + |
| 245 | + found++; |
| 246 | + if ( found >= 30 ) |
| 247 | + break; |
| 248 | + } |
| 249 | +} |
| 250 | + |
| 251 | +void QgsActiveLayerFeaturesLocatorFilter::triggerResult( const QgsLocatorResult &result ) |
| 252 | +{ |
| 253 | + QVariantList dataList = result.userData.toList(); |
| 254 | + QgsFeatureId id = dataList.at( 0 ).toLongLong(); |
| 255 | + QString layerId = dataList.at( 1 ).toString(); |
| 256 | + QgsVectorLayer *layer = qobject_cast< QgsVectorLayer *>( QgsProject::instance()->mapLayer( layerId ) ); |
| 257 | + if ( !layer ) |
| 258 | + return; |
| 259 | + |
| 260 | + QgisApp::instance()->mapCanvas()->zoomToFeatureIds( layer, QgsFeatureIds() << id ); |
| 261 | +} |
0 commit comments