Merge pull request #8404 from 3nids/locator_core

Move parts of QgsLocatorFilter to core
This commit is contained in:
Denis Rouzaud 2018-11-09 12:18:27 +00:00 committed by GitHub
commit 30cf2d37bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 530 additions and 107 deletions

View File

@ -67,6 +67,8 @@ which may occur if the model is being updated quickly multiple times as a result
virtual Qt::ItemFlags flags( const QModelIndex &index ) const;
virtual QHash<int, QByteArray> roleNames() const;
public slots:

View File

@ -0,0 +1,104 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/locator/qgslocatormodelbridge.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
class QgsLocatorModelBridge : QObject
{
%Docstring
The QgsLocatorModelBridge class provides the core functionality
to be used in a locator widget.
.. versionadded:: 3.6
%End
%TypeHeaderCode
#include "qgslocatormodelbridge.h"
%End
public:
explicit QgsLocatorModelBridge( QObject *parent = 0 );
%Docstring
Constructor of QgsLocatorModelBridge
%End
virtual ~QgsLocatorModelBridge();
void performSearch( const QString &text );
%Docstring
Perform a search
%End
QgsLocator *locator() const;
%Docstring
Returns the locator
%End
QgsLocatorProxyModel *proxyModel() const;
%Docstring
Returns the proxy model
%End
bool hasQueueRequested() const;
%Docstring
Returns true if some text to be search is pending in the queue
%End
bool isRunning() const;
%Docstring
Returns true if the a search is currently running
%End
void triggerResult( const QModelIndex &index );
%Docstring
Triggers the result at given index
%End
signals:
void resultAdded();
%Docstring
Emitted when a result is added
%End
void isRunningChanged();
%Docstring
Emitted when the running status changes
%End
void resultsCleared();
%Docstring
Emitted when the results are cleared
%End
public slots:
void invalidateResults();
%Docstring
This will invalidate current search results
%End
void updateCanvasExtent( const QgsRectangle &extent );
%Docstring
Update the canvas extent used to create search context
%End
void updateCanvasCrs( const QgsCoordinateReferenceSystem &crs );
%Docstring
Update the canvas CRS used to create search context
%End
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/locator/qgslocatormodelbridge.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -0,0 +1,98 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/locator/qgslocatormodelbridge.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
class QgsLocatorModelBridge : QObject
{
%Docstring
The QgsLocatorModelBridge class provides the core functionality
to be used in a locator widget.
.. versionadded:: 3.6
%End
%TypeHeaderCode
#include "qgslocatormodelbridge.h"
%End
public:
explicit QgsLocatorModelBridge( QObject *parent = 0 );
%Docstring
Constructor of QgsLocatorModelBridge
%End
void performSearch( const QString &text );
%Docstring
Perform a search
%End
QgsLocator *locator() const;
%Docstring
Returns the locator
%End
QgsLocatorProxyModel *proxyModel() const;
%Docstring
Returns the proxy model
%End
bool hasQueueRequested() const;
%Docstring
Returns true if some text to be search is pending in the queue
%End
bool isRunning() const;
%Docstring
Returns true if the a search is currently running
%End
signals:
void resultAdded();
%Docstring
Emitted when a result is added
%End
void isRunningChanged();
%Docstring
Emitted when the running status changes
%End
void resultsCleared();
%Docstring
Emitted when the results are cleared
%End
public slots:
void invalidateResults();
%Docstring
This will invalidate current search results
%End
void updateCanvasExtent( const QgsRectangle &extent );
%Docstring
Update the canvas extent used to create search context
%End
void updateCanvasCrs( const QgsCoordinateReferenceSystem &crs );
%Docstring
Update the canvas CRS used to create search context
%End
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/locator/qgslocatormodelbridge.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -382,6 +382,7 @@
%Include auto_generated/locator/qgslocator.sip
%Include auto_generated/locator/qgslocatorfilter.sip
%Include auto_generated/locator/qgslocatormodel.sip
%Include auto_generated/locator/qgslocatormodelbridge.sip
%Include auto_generated/processing/qgsprocessingalgrunnertask.sip
%Include auto_generated/processing/qgsprocessingfeedback.sip
%Include auto_generated/processing/qgsprocessingprovider.sip

View File

@ -64,7 +64,6 @@ Emitted when the configure option is triggered in the widget.
%End
protected:
virtual bool eventFilter( QObject *obj, QEvent *event );

View File

@ -109,6 +109,7 @@ SET(QGIS_CORE_SRCS
locator/qgslocator.cpp
locator/qgslocatorfilter.cpp
locator/qgslocatormodel.cpp
locator/qgslocatormodelbridge.cpp
processing/qgsprocessingalgorithm.cpp
processing/qgsprocessingalgrunnertask.cpp
@ -681,6 +682,7 @@ SET(QGIS_CORE_MOC_HDRS
locator/qgslocator.h
locator/qgslocatorfilter.h
locator/qgslocatormodel.h
locator/qgslocatormodelbridge.h
processing/qgsprocessingalgrunnertask.h
processing/qgsprocessingfeedback.h

View File

@ -179,6 +179,19 @@ Qt::ItemFlags QgsLocatorModel::flags( const QModelIndex &index ) const
return flags;
}
QHash<int, QByteArray> QgsLocatorModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[ResultDataRole] = "ResultData";
roles[ResultTypeRole] = "ResultType";
roles[ResultFilterPriorityRole] = "ResultFilterPriority";
roles[ResultScoreRole] = "ResultScore";
roles[ResultFilterNameRole] = "ResultFilterName";
roles[ResultFilterGroupSortingRole] = "ResultFilterGroupSorting";
roles[Qt::DisplayRole] = "Text";
return roles;
}
void QgsLocatorModel::addResult( const QgsLocatorResult &result )
{
mDeferredClearTimer.stop();

View File

@ -81,6 +81,7 @@ class CORE_EXPORT QgsLocatorModel : public QAbstractTableModel
int columnCount( const QModelIndex &parent = QModelIndex() ) const override;
QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const override;
Qt::ItemFlags flags( const QModelIndex &index ) const override;
QHash<int, QByteArray> roleNames() const override;
public slots:

View File

@ -0,0 +1,139 @@
/***************************************************************************
qgslocatormodelbridge.cpp
------------------
begin : November 2018
copyright : (C) 2018 by Denis Rouzaud
email : denis@opengis.ch
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgslocatormodelbridge.h"
#include "qgslocator.h"
#include "qgslocatormodel.h"
QgsLocatorModelBridge::QgsLocatorModelBridge( QObject *parent )
: QObject( parent )
, mLocator( new QgsLocator( this ) )
, mLocatorModel( new QgsLocatorModel( this ) )
{
mProxyModel = new QgsLocatorProxyModel( mLocatorModel );
mProxyModel->setSourceModel( mLocatorModel );
connect( mLocator, &QgsLocator::foundResult, this, &QgsLocatorModelBridge::addResult );
connect( mLocator, &QgsLocator::finished, this, &QgsLocatorModelBridge::searchFinished );
}
bool QgsLocatorModelBridge::isRunning() const
{
return mIsRunning;
}
void QgsLocatorModelBridge::triggerResult( const QModelIndex &index )
{
mLocator->clearPreviousResults();
QgsLocatorResult result = mProxyModel->data( index, QgsLocatorModel::ResultDataRole ).value< QgsLocatorResult >();
if ( result.filter )
result.filter->triggerResult( result );
}
void QgsLocatorModelBridge::setIsRunning( bool isRunning )
{
if ( mIsRunning == isRunning )
return;
mIsRunning = isRunning;
emit isRunningChanged();
}
void QgsLocatorModelBridge::invalidateResults()
{
mLocator->cancelWithoutBlocking();
mLocatorModel->clear();
}
void QgsLocatorModelBridge::updateCanvasExtent( const QgsRectangle &extent )
{
mCanvasExtent = extent;
}
void QgsLocatorModelBridge::updateCanvasCrs( const QgsCoordinateReferenceSystem &crs )
{
mCanvasCrs = crs;
}
void QgsLocatorModelBridge::addResult( const QgsLocatorResult &result )
{
mLocatorModel->addResult( result );
emit resultAdded();
}
void QgsLocatorModelBridge::searchFinished()
{
if ( mHasQueuedRequest )
{
// a queued request was waiting for this - run the queued search now
QString nextSearch = mNextRequestedString;
mNextRequestedString.clear();
mHasQueuedRequest = false;
performSearch( nextSearch );
}
else
{
if ( !mLocator->isRunning() )
setIsRunning( false );
}
}
void QgsLocatorModelBridge::performSearch( const QString &text )
{
setIsRunning( true );
if ( mLocator->isRunning() )
{
// can't do anything while a query is running, and can't block
// here waiting for the current query to cancel
// so we queue up this string until cancel has happened
mLocator->cancelWithoutBlocking();
mNextRequestedString = text;
mHasQueuedRequest = true;
return;
}
else
{
emit resultsCleared();
mLocatorModel->deferredClear();
mLocator->fetchResults( text, createContext() );
}
}
QgsLocator *QgsLocatorModelBridge::locator() const
{
return mLocator;
}
QgsLocatorProxyModel *QgsLocatorModelBridge::proxyModel() const
{
return mProxyModel;
}
bool QgsLocatorModelBridge::hasQueueRequested() const
{
return mHasQueuedRequest;
}
QgsLocatorContext QgsLocatorModelBridge::createContext()
{
QgsLocatorContext context;
context.targetExtent = mCanvasExtent;
context.targetExtentCrs = mCanvasCrs;
return context;
}

View File

@ -0,0 +1,111 @@
/***************************************************************************
qgslocatormodelbridge.h
------------------
begin : November 2018
copyright : (C) 2018 by Denis Rouzaud
email : denis@opengis.ch
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSLOCATORMODELBRIDGE_H
#define QGSLOCATORMODELBRIDGE_H
#include <QObject>
#include "qgis_core.h"
#include "qgscoordinatereferencesystem.h"
#include "qgsrectangle.h"
class QgsLocatorResult;
class QgsLocator;
class QgsLocatorContext;
class QgsLocatorModel;
class QgsLocatorProxyModel;
/**
* \ingroup core
* The QgsLocatorModelBridge class provides the core functionality
* to be used in a locator widget.
* \since QGIS 3.6
*/
class CORE_EXPORT QgsLocatorModelBridge : public QObject
{
Q_OBJECT
Q_PROPERTY( bool isRunning READ isRunning NOTIFY isRunningChanged )
public:
//! Constructor of QgsLocatorModelBridge
explicit QgsLocatorModelBridge( QObject *parent = nullptr );
virtual ~QgsLocatorModelBridge() = default;
//! Perform a search
Q_INVOKABLE void performSearch( const QString &text );
//! Returns the locator
QgsLocator *locator() const;
//! Returns the proxy model
Q_INVOKABLE QgsLocatorProxyModel *proxyModel() const;
//! Returns true if some text to be search is pending in the queue
bool hasQueueRequested() const;
//! Returns true if the a search is currently running
bool isRunning() const;
//! Triggers the result at given index
void triggerResult( const QModelIndex &index );
signals:
//! Emitted when a result is added
void resultAdded();
//! Emitted when the running status changes
void isRunningChanged();
//! Emitted when the results are cleared
void resultsCleared();
public slots:
//! This will invalidate current search results
void invalidateResults();
//! Update the canvas extent used to create search context
void updateCanvasExtent( const QgsRectangle &extent );
//! Update the canvas CRS used to create search context
void updateCanvasCrs( const QgsCoordinateReferenceSystem &crs );
private slots:
void searchFinished();
void addResult( const QgsLocatorResult &result );
private:
QgsLocatorContext createContext();
void setIsRunning( bool isRunning );
QgsLocator *mLocator = nullptr;
QgsLocatorModel *mLocatorModel = nullptr;
QgsLocatorProxyModel *mProxyModel = nullptr;
QString mNextRequestedString;
bool mHasQueuedRequest = false;
bool mIsRunning = false;
// keep track of map canvas extent and CRS
// if much if needed, it would be possible to add
// a QgsMapCanvasController in core to achieve this
// see discussion in https://github.com/qgis/QGIS/pull/8404
QgsRectangle mCanvasExtent;
QgsCoordinateReferenceSystem mCanvasCrs;
};
#endif // QGSLOCATORMODELBRIDGE_H

View File

@ -15,10 +15,10 @@
* *
***************************************************************************/
#include "qgslocatorwidget.h"
#include "qgslocator.h"
#include "qgslocatormodel.h"
#include "qgslocatorwidget.h"
#include "qgslocatormodelbridge.h"
#include "qgsfilterlineedit.h"
#include "qgsmapcanvas.h"
#include "qgsapplication.h"
@ -29,9 +29,8 @@
QgsLocatorWidget::QgsLocatorWidget( QWidget *parent )
: QWidget( parent )
, mLocator( new QgsLocator( this ) )
, mModelBridge( new QgsLocatorModelBridge( this ) )
, mLineEdit( new QgsFilterLineEdit() )
, mLocatorModel( new QgsLocatorModel( this ) )
, mResultsView( new QgsLocatorResultsView() )
{
mLineEdit->setShowClearButton( true );
@ -71,17 +70,16 @@ QgsLocatorWidget::QgsLocatorWidget( QWidget *parent )
mResultsContainer->setLayout( containerLayout );
mResultsContainer->hide();
mProxyModel = new QgsLocatorProxyModel( mLocatorModel );
mProxyModel->setSourceModel( mLocatorModel );
mResultsView->setModel( mProxyModel );
mResultsView->setModel( mModelBridge->proxyModel() );
mResultsView->setUniformRowHeights( true );
mResultsView->setIconSize( QSize( 16, 16 ) );
mResultsView->recalculateSize();
connect( mLocator, &QgsLocator::foundResult, this, &QgsLocatorWidget::addResult );
connect( mLocator, &QgsLocator::finished, this, &QgsLocatorWidget::searchFinished );
connect( mLineEdit, &QLineEdit::textChanged, this, &QgsLocatorWidget::scheduleDelayedPopup );
connect( mResultsView, &QAbstractItemView::activated, this, &QgsLocatorWidget::acceptCurrentEntry );
connect( mModelBridge, &QgsLocatorModelBridge::resultAdded, this, &QgsLocatorWidget::resultAdded );
connect( mModelBridge, &QgsLocatorModelBridge::isRunningChanged, this, [ = ]() {mLineEdit->setShowSpinner( mModelBridge->isRunning() );} );
connect( mModelBridge, & QgsLocatorModelBridge::resultsCleared, this, [ = ]() {mHasSelectedResult = false;} );
// have a tiny delay between typing text in line edit and showing the window
mPopupTimer.setInterval( 100 );
@ -97,7 +95,7 @@ QgsLocatorWidget::QgsLocatorWidget( QWidget *parent )
installEventFilter( this );
window()->installEventFilter( this );
mLocator->registerFilter( new QgsLocatorFilterFilter( this, this ) );
mModelBridge->locator()->registerFilter( new QgsLocatorFilterFilter( this, this ) );
mMenu = new QMenu( this );
QAction *menuAction = mLineEdit->addAction( QgsApplication::getThemeIcon( QStringLiteral( "/search.svg" ) ), QLineEdit::LeadingPosition );
@ -113,12 +111,29 @@ QgsLocatorWidget::QgsLocatorWidget( QWidget *parent )
QgsLocator *QgsLocatorWidget::locator()
{
return mLocator;
return mModelBridge->locator();
}
void QgsLocatorWidget::setMapCanvas( QgsMapCanvas *canvas )
{
if ( mMapCanvas == canvas )
return;
for ( const QMetaObject::Connection &conn : qgis::as_const( mCanvasConnections ) )
{
disconnect( conn );
}
mCanvasConnections.clear();
mMapCanvas = canvas;
if ( mMapCanvas )
{
mModelBridge->updateCanvasExtent( mMapCanvas->mapSettings().visibleExtent() );
mModelBridge->updateCanvasCrs( mMapCanvas->mapSettings().destinationCrs() );
mCanvasConnections
<< connect( mMapCanvas, &QgsMapCanvas::extentsChanged, this, [ = ]() {mModelBridge->updateCanvasExtent( mMapCanvas->mapSettings().visibleExtent() );} )
<< connect( mMapCanvas, &QgsMapCanvas::destinationCrsChanged, this, [ = ]() {mModelBridge->updateCanvasCrs( mMapCanvas->mapSettings().destinationCrs() );} ) ;
}
}
void QgsLocatorWidget::search( const QString &string )
@ -131,8 +146,7 @@ void QgsLocatorWidget::search( const QString &string )
void QgsLocatorWidget::invalidateResults()
{
mLocator->cancelWithoutBlocking();
mLocatorModel->clear();
mModelBridge->invalidateResults();
mResultsContainer->hide();
}
@ -141,10 +155,27 @@ void QgsLocatorWidget::scheduleDelayedPopup()
mPopupTimer.start();
}
void QgsLocatorWidget::resultAdded()
{
bool selectFirst = !mHasSelectedResult || mModelBridge->proxyModel()->rowCount() == 0;
if ( selectFirst )
{
int row = -1;
bool selectable = false;
while ( !selectable && row < mModelBridge->proxyModel()->rowCount() )
{
row++;
selectable = mModelBridge->proxyModel()->flags( mModelBridge->proxyModel()->index( row, 0 ) ).testFlag( Qt::ItemIsSelectable );
}
if ( selectable )
mResultsView->setCurrentIndex( mModelBridge->proxyModel()->index( row, 0 ) );
}
}
void QgsLocatorWidget::performSearch()
{
mPopupTimer.stop();
updateResults( mLineEdit->text() );
mModelBridge->performSearch( mLineEdit->text() );
showList();
}
@ -156,29 +187,12 @@ void QgsLocatorWidget::showList()
void QgsLocatorWidget::triggerSearchAndShowList()
{
if ( mProxyModel->rowCount() == 0 )
if ( mModelBridge->proxyModel()->rowCount() == 0 )
performSearch();
else
showList();
}
void QgsLocatorWidget::searchFinished()
{
if ( mHasQueuedRequest )
{
// a queued request was waiting for this - run the queued search now
QString nextSearch = mNextRequestedString;
mNextRequestedString.clear();
mHasQueuedRequest = false;
updateResults( nextSearch );
}
else
{
if ( !mLocator->isRunning() )
mLineEdit->setShowSpinner( false );
}
}
bool QgsLocatorWidget::eventFilter( QObject *obj, QEvent *event )
{
if ( obj == mLineEdit && event->type() == QEvent::KeyPress )
@ -246,28 +260,10 @@ bool QgsLocatorWidget::eventFilter( QObject *obj, QEvent *event )
return QWidget::eventFilter( obj, event );
}
void QgsLocatorWidget::addResult( const QgsLocatorResult &result )
{
bool selectFirst = !mHasSelectedResult || mProxyModel->rowCount() == 0;
mLocatorModel->addResult( result );
if ( selectFirst )
{
int row = -1;
bool selectable = false;
while ( !selectable && row < mProxyModel->rowCount() )
{
row++;
selectable = mProxyModel->flags( mProxyModel->index( row, 0 ) ).testFlag( Qt::ItemIsSelectable );
}
if ( selectable )
mResultsView->setCurrentIndex( mProxyModel->index( row, 0 ) );
}
}
void QgsLocatorWidget::configMenuAboutToShow()
{
mMenu->clear();
for ( QgsLocatorFilter *filter : mLocator->filters() )
for ( QgsLocatorFilter *filter : mModelBridge->locator()->filters() )
{
if ( !filter->enabled() )
continue;
@ -281,7 +277,7 @@ void QgsLocatorWidget::configMenuAboutToShow()
else
{
QStringList parts = currentText.split( ' ' );
if ( parts.count() > 1 && mLocator->filters( parts.at( 0 ) ).count() > 0 )
if ( parts.count() > 1 && mModelBridge->locator()->filters( parts.at( 0 ) ).count() > 0 )
{
parts.pop_front();
currentText = parts.join( ' ' );
@ -297,33 +293,13 @@ void QgsLocatorWidget::configMenuAboutToShow()
QAction *configAction = new QAction( tr( "Configure…" ), mMenu );
connect( configAction, &QAction::triggered, this, &QgsLocatorWidget::configTriggered );
mMenu->addAction( configAction );
}
void QgsLocatorWidget::updateResults( const QString &text )
{
mLineEdit->setShowSpinner( true );
if ( mLocator->isRunning() )
{
// can't do anything while a query is running, and can't block
// here waiting for the current query to cancel
// so we queue up this string until cancel has happened
mLocator->cancelWithoutBlocking();
mNextRequestedString = text;
mHasQueuedRequest = true;
return;
}
else
{
mHasSelectedResult = false;
mLocatorModel->deferredClear();
mLocator->fetchResults( text, createContext() );
}
}
void QgsLocatorWidget::acceptCurrentEntry()
{
if ( mHasQueuedRequest )
if ( mModelBridge->hasQueueRequested() )
{
return;
}
@ -336,24 +312,13 @@ void QgsLocatorWidget::acceptCurrentEntry()
if ( !index.isValid() )
return;
QgsLocatorResult result = mProxyModel->data( index, QgsLocatorModel::ResultDataRole ).value< QgsLocatorResult >();
mResultsContainer->hide();
mLineEdit->clearFocus();
mLocator->clearPreviousResults();
result.filter->triggerResult( result );
mModelBridge->triggerResult( index );
}
}
QgsLocatorContext QgsLocatorWidget::createContext()
{
QgsLocatorContext context;
if ( mMapCanvas )
{
context.targetExtent = mMapCanvas->mapSettings().visibleExtent();
context.targetExtentCrs = mMapCanvas->mapSettings().destinationCrs();
}
return context;
}
///@cond PRIVATE

View File

@ -29,10 +29,9 @@
class QgsLocator;
class QgsFilterLineEdit;
class QgsLocatorModel;
class QgsLocatorResultsView;
class QgsMapCanvas;
class QgsLocatorProxyModel;
class QgsLocatorModelBridge;
/**
* \class QgsLocatorWidget
@ -86,40 +85,30 @@ class GUI_EXPORT QgsLocatorWidget : public QWidget
void configTriggered();
protected:
bool eventFilter( QObject *obj, QEvent *event ) override;
private slots:
void scheduleDelayedPopup();
void performSearch();
void showList();
void triggerSearchAndShowList();
void searchFinished();
void addResult( const QgsLocatorResult &result );
void configMenuAboutToShow();
void scheduleDelayedPopup();
void resultAdded();
private:
QgsLocator *mLocator = nullptr;
QgsLocatorModelBridge *mModelBridge = nullptr;
QgsFilterLineEdit *mLineEdit = nullptr;
QgsLocatorModel *mLocatorModel = nullptr;
QgsLocatorProxyModel *mProxyModel = nullptr;
QgsFloatingWidget *mResultsContainer = nullptr;
QgsLocatorResultsView *mResultsView = nullptr;
QgsMapCanvas *mMapCanvas = nullptr;
QList<QMetaObject::Connection> mCanvasConnections;
QMenu *mMenu = nullptr;
QString mNextRequestedString;
bool mHasQueuedRequest = false;
bool mHasSelectedResult = false;
QTimer mPopupTimer;
QTimer mFocusTimer;
QTimer mPopupTimer;
bool mHasSelectedResult = false;
void updateResults( const QString &text );
void acceptCurrentEntry();
QgsLocatorContext createContext();
};
#ifndef SIP_RUN
@ -144,7 +133,6 @@ class QgsLocatorFilterFilter : public QgsLocatorFilter
void triggerResult( const QgsLocatorResult &result ) override;
private:
QgsLocatorWidget *mLocator = nullptr;
};