1 /***************************************************************************
2                          qgslocatormodelbridge.h
3                          ------------------
4     begin                : November 2018
5     copyright            : (C) 2018 by Denis Rouzaud
6     email                : denis@opengis.ch
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #ifndef QGSLOCATORMODELBRIDGE_H
19 #define QGSLOCATORMODELBRIDGE_H
20 
21 #include <QObject>
22 
23 #include "qgis_core.h"
24 #include "qgscoordinatereferencesystem.h"
25 #include "qgscoordinatetransformcontext.h"
26 #include "qgsrectangle.h"
27 
28 class QgsLocatorResult;
29 class QgsLocator;
30 class QgsLocatorContext;
31 class QgsLocatorModel;
32 class QgsLocatorProxyModel;
33 
34 
35 /**
36  * \ingroup core
37  * \brief The QgsLocatorModelBridge class provides the core functionality
38  * to be used in a locator widget.
39  * \since QGIS 3.6
40  */
41 class CORE_EXPORT QgsLocatorModelBridge : public QObject
42 {
43     Q_OBJECT
44     Q_PROPERTY( bool isRunning READ isRunning NOTIFY isRunningChanged )
45   public:
46     //! Constructor of QgsLocatorModelBridge
47     explicit QgsLocatorModelBridge( QObject *parent = nullptr );
48     virtual ~QgsLocatorModelBridge() = default;
49 
50     //! Perform a search
51     Q_INVOKABLE void performSearch( const QString &text );
52 
53     //! Returns the locator
54     QgsLocator *locator() const;
55 
56     //! Returns the proxy model
57     Q_INVOKABLE QgsLocatorProxyModel *proxyModel() const;
58 
59     //! Returns TRUE if some text to be search is pending in the queue
60     bool hasQueueRequested() const;
61 
62     //! Returns TRUE if the a search is currently running
63     bool isRunning() const;
64 
65     //! Triggers the result at given \a index and with optional \a actionId if an additional action was triggered
66     void triggerResult( const QModelIndex &index,  const int actionId = -1 );
67 
68     /**
69      * Returns the coordinate transform context, which should be used whenever the
70      * locator constructs a coordinate transform.
71      *
72      * \see setTransformContext()
73      * \since QGIS 3.18
74      */
transformContext()75     QgsCoordinateTransformContext transformContext() const { return mTransformContext; }
76 
77     /**
78      * Sets the coordinate transform \a context, which should be used whenever the
79      * locator constructs a coordinate transform.
80      *
81      * \see transformContext()
82      * \since QGIS 3.18
83      */
setTransformContext(const QgsCoordinateTransformContext & context)84     void setTransformContext( const QgsCoordinateTransformContext &context ) { mTransformContext = context; }
85 
86   signals:
87     //! Emitted when a result is added
88     void resultAdded();
89 
90     //! Emitted when the running status changes
91     void isRunningChanged();
92 
93     //! Emitted when the results are cleared
94     void resultsCleared();
95 
96   public slots:
97     //! This will invalidate current search results
98     void invalidateResults();
99 
100     //! Update the canvas extent used to create search context
101     void updateCanvasExtent( const QgsRectangle &extent );
102 
103     //! Update the canvas CRS used to create search context
104     void updateCanvasCrs( const QgsCoordinateReferenceSystem &crs );
105 
106   private slots:
107     void searchFinished();
108     void addResult( const QgsLocatorResult &result );
109 
110   private:
111     QgsLocatorContext createContext();
112     void setIsRunning( bool isRunning );
113 
114     QgsLocator *mLocator = nullptr;
115     QgsLocatorModel *mLocatorModel = nullptr;
116     QgsLocatorProxyModel *mProxyModel = nullptr;
117 
118     QString mNextRequestedString;
119     bool mHasQueuedRequest = false;
120     bool mIsRunning = false;
121 
122     // keep track of map canvas extent and CRS
123     // if much if needed, it would be possible to add
124     // a QgsMapCanvasController in core to achieve this
125     // see discussion in https://github.com/qgis/QGIS/pull/8404
126     QgsRectangle mCanvasExtent;
127     QgsCoordinateReferenceSystem mCanvasCrs;
128     QgsCoordinateTransformContext mTransformContext;
129 };
130 
131 #endif // QGSLOCATORMODELBRIDGE_H
132