mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
Merge pull request #8404 from 3nids/locator_core
Move parts of QgsLocatorFilter to core
This commit is contained in:
commit
30cf2d37bc
@ -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:
|
||||
|
||||
|
104
python/core/auto_generated/locator/qgslocatormodelbridge.sip.in
Normal file
104
python/core/auto_generated/locator/qgslocatormodelbridge.sip.in
Normal 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 *
|
||||
************************************************************************/
|
@ -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 *
|
||||
************************************************************************/
|
@ -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
|
||||
|
@ -64,7 +64,6 @@ Emitted when the configure option is triggered in the widget.
|
||||
%End
|
||||
|
||||
protected:
|
||||
|
||||
virtual bool eventFilter( QObject *obj, QEvent *event );
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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:
|
||||
|
||||
|
139
src/core/locator/qgslocatormodelbridge.cpp
Normal file
139
src/core/locator/qgslocatormodelbridge.cpp
Normal 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;
|
||||
}
|
111
src/core/locator/qgslocatormodelbridge.h
Normal file
111
src/core/locator/qgslocatormodelbridge.h
Normal 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
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user