Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
[FEATURE] Implement a QtCreator style locator bar in the QGIS status bar
This adds a new "locator" bar to the QGIS status bar. If you're not familiar with QtCreator's locator, it's a quick search bar (activated by Ctrl+K) which displays matching search results from any number of registered search filters. Search filters are subclassed from QgsLocatorFilter, and added to the app's locator via iface.registerLocatorFilter(...) Searching is handled using threads, so that results always become available as quickly as possible, regardless of whether any slow search filters may be installed. They also appear as soon as each result is encountered by each filter, which means that e.g. a file search filter will show results one by one as the file tree is scanned. This ensures that the UI is always responsive even if a very slow search filter is present (e.g. one which uses an online service). This framework is designed to be extended by plugins, such as OSM nominatim searches, direct database searching (i.e. Discovery plugin), layer catalog searches, etc...
- Loading branch information
Showing
with
1,412 additions
and 1 deletion.
- +1 −0 doc/CMakeLists.txt
- +1 −0 python/CMakeLists.txt
- +3 −0 python/gui/gui.sip
- +130 −0 python/gui/locator/qgslocator.sip
- +107 −0 python/gui/locator/qgslocatorfilter.sip
- +22 −0 python/gui/qgisinterface.sip
- +1 −0 src/app/CMakeLists.txt
- +9 −1 src/app/qgisapp.cpp
- +3 −0 src/app/qgisapp.h
- +12 −0 src/app/qgisappinterface.cpp
- +3 −0 src/app/qgisappinterface.h
- +9 −0 src/gui/CMakeLists.txt
- +124 −0 src/gui/locator/qgslocator.cpp
- +155 −0 src/gui/locator/qgslocator.h
- +25 −0 src/gui/locator/qgslocatorfilter.cpp
- +120 −0 src/gui/locator/qgslocatorfilter.h
- +332 −0 src/gui/locator/qgslocatorwidget.cpp
- +180 −0 src/gui/locator/qgslocatorwidget.h
- +24 −0 src/gui/qgisinterface.h
- +1 −0 tests/src/python/CMakeLists.txt
- +150 −0 tests/src/python/test_qgslocator.py
@@ -0,0 +1,130 @@ | ||
/************************************************************************ | ||
* This file has been generated automatically from * | ||
* * | ||
* src/gui/locator/qgslocator.h * | ||
* * | ||
* Do not edit manually ! Edit header and run scripts/sipify.pl again * | ||
************************************************************************/ | ||
|
||
|
||
|
||
|
||
class QgsLocator : QObject | ||
{ | ||
%Docstring | ||
Handles the management of QgsLocatorFilter objects and async collection of search results from them. | ||
|
||
QgsLocator acts as both a registry for QgsLocatorFilter objects and a means of firing up | ||
asynchronous queries against these filter objects. | ||
|
||
Filters are first registered to the locator by calling registerFilter(). Registering filters | ||
transfers their ownership to the locator object. Plugins which register filters to the locator | ||
must take care to correctly call deregisterFilter() and deregister their filter upon plugin | ||
unload to avoid crashes. | ||
|
||
In order to trigger a search across registered filters, the fetchResults() method is called. | ||
This triggers threaded calls to QgsLocatorFilter.fetchResults() for all registered filters. | ||
As individual filters find matching results, the foundResult() signal will be triggered | ||
for each result. Callers should connect this signal to an appropriate slot designed | ||
to collect and handle these results. Since foundResult() is triggered whenever a filter | ||
encounters an individual result, it will usually be triggered many times for a single | ||
call to fetchResults(). | ||
|
||
.. versionadded:: 3.0 | ||
%End | ||
|
||
%TypeHeaderCode | ||
#include "qgslocator.h" | ||
%End | ||
public: | ||
|
||
QgsLocator( QObject *parent /TransferThis/ = 0 ); | ||
%Docstring | ||
Constructor for QgsLocator. | ||
%End | ||
|
||
~QgsLocator(); | ||
%Docstring | ||
Destructor for QgsLocator. Destruction will block while any currently running query is terminated. | ||
%End | ||
|
||
void registerFilter( QgsLocatorFilter *filter /Transfer/ ); | ||
%Docstring | ||
Registers a ``filter`` within the locator. Ownership of the filter is transferred to the | ||
locator. | ||
\warning Plugins which register filters to the locator must take care to correctly call | ||
deregisterFilter() and deregister their filters upon plugin unload to avoid crashes. | ||
.. seealso:: deregisterFilter() | ||
%End | ||
|
||
void deregisterFilter( QgsLocatorFilter *filter ); | ||
%Docstring | ||
Deregisters a ``filter`` from the locator and deletes it. Calling this will block whilst | ||
any currently running query is terminated. | ||
|
||
Plugins which register filters to the locator must take care to correctly call | ||
deregisterFilter() to deregister their filters upon plugin unload to avoid crashes. | ||
|
||
.. seealso:: registerFilter() | ||
%End | ||
|
||
QList< QgsLocatorFilter *> filters(); | ||
%Docstring | ||
Returns the list of filters registered in the locator. | ||
:rtype: list of QgsLocatorFilter | ||
%End | ||
|
||
void fetchResults( const QString &string, QgsFeedback *feedback = 0 ); | ||
%Docstring | ||
Triggers the background fetching of filter results for a specified search ``string``. | ||
If specified, the ``feedback`` object must exist for the lifetime of this query. | ||
|
||
The foundResult() signal will be emitted for each individual result encountered | ||
by the registered filters. | ||
%End | ||
|
||
void cancel(); | ||
%Docstring | ||
Cancels any current running query, and blocks until query is completely canceled by | ||
all filters. | ||
.. seealso:: cancelWithoutBlocking() | ||
%End | ||
|
||
void cancelWithoutBlocking(); | ||
%Docstring | ||
Triggers cancelation of any current running query without blocking. The query may | ||
take some time to cancel after calling this. | ||
.. seealso:: cancel() | ||
%End | ||
|
||
bool isRunning() const; | ||
%Docstring | ||
Returns true if a query is currently being executed by the locator. | ||
:rtype: bool | ||
%End | ||
|
||
signals: | ||
|
||
void foundResult( const QgsLocatorResult &result ); | ||
%Docstring | ||
Emitted whenever a filter encounters a matching ``result`` after the fetchResults() method | ||
is called. | ||
%End | ||
|
||
void finished(); | ||
%Docstring | ||
Emitted when locator has finished a query, either as a result | ||
of successful completion or early cancelation. | ||
%End | ||
|
||
}; | ||
|
||
|
||
|
||
/************************************************************************ | ||
* This file has been generated automatically from * | ||
* * | ||
* src/gui/locator/qgslocator.h * | ||
* * | ||
* Do not edit manually ! Edit header and run scripts/sipify.pl again * | ||
************************************************************************/ |
@@ -0,0 +1,107 @@ | ||
/************************************************************************ | ||
* This file has been generated automatically from * | ||
* * | ||
* src/gui/locator/qgslocatorfilter.h * | ||
* * | ||
* Do not edit manually ! Edit header and run scripts/sipify.pl again * | ||
************************************************************************/ | ||
|
||
|
||
|
||
|
||
|
||
class QgsLocatorResult | ||
{ | ||
%Docstring | ||
Encapsulates properties of an individual matching result found by a QgsLocatorFilter. | ||
.. versionadded:: 3.0 | ||
%End | ||
|
||
%TypeHeaderCode | ||
#include "qgslocatorfilter.h" | ||
%End | ||
public: | ||
|
||
QgsLocatorResult(); | ||
|
||
QgsLocatorResult( QgsLocatorFilter *filter, const QString &displayString, const QVariant &userData = QVariant() ); | ||
%Docstring | ||
Constructor for QgsLocatorResult. | ||
%End | ||
|
||
QgsLocatorFilter *filter; | ||
%Docstring | ||
Filter from which the result was obtained. | ||
%End | ||
|
||
QString displayString; | ||
%Docstring | ||
String displayed for result. | ||
%End | ||
|
||
QVariant userData; | ||
%Docstring | ||
Custom reference or other data set by the filter. | ||
%End | ||
|
||
}; | ||
|
||
class QgsLocatorFilter : QObject | ||
{ | ||
%Docstring | ||
Abstract base class for filters which collect locator results. | ||
.. versionadded:: 3.0 | ||
%End | ||
|
||
%TypeHeaderCode | ||
#include "qgslocatorfilter.h" | ||
%End | ||
public: | ||
|
||
QgsLocatorFilter( QObject *parent = 0 ); | ||
%Docstring | ||
Constructor for QgsLocatorFilter. | ||
%End | ||
|
||
virtual void fetchResults( const QString &string, QgsFeedback *feedback ) = 0; | ||
%Docstring | ||
Retrieves the filter results for a specified search ``string``. | ||
|
||
Implementations of fetchResults() should emit the resultFetched() | ||
signal whenever they encounter a matching result. | ||
|
||
Subclasses should periodically check the ``feedback`` object to determine | ||
whether the query has been canceled. If so, the subclass should return | ||
from this method as soon as possible. | ||
%End | ||
|
||
virtual void triggerResult( const QgsLocatorResult &result ) = 0; | ||
%Docstring | ||
Triggers a filter ``result`` from this filter. This is called when | ||
one of the results obtained by a call to fetchResults() is triggered | ||
by a user. The filter subclass must implement logic here | ||
to perform the desired operation for the search result. | ||
E.g. a file search filter would open file associated with the triggered | ||
result. | ||
%End | ||
|
||
signals: | ||
|
||
void resultFetched( const QgsLocatorResult &result ); | ||
%Docstring | ||
Should be emitted by filters whenever they encounter a matching result | ||
during within their fetchResults() implementation. | ||
%End | ||
|
||
}; | ||
|
||
|
||
|
||
|
||
/************************************************************************ | ||
* This file has been generated automatically from * | ||
* * | ||
* src/gui/locator/qgslocatorfilter.h * | ||
* * | ||
* Do not edit manually ! Edit header and run scripts/sipify.pl again * | ||
************************************************************************/ |
Oops, something went wrong.