QGIS API Documentation 3.99.0-Master (e9821da5c6b)
Loading...
Searching...
No Matches
qgslayermetadatasearchwidget.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgslayermetadatasearchwidget.cpp - QgsLayerMetadataSearchWidget
3
4 ---------------------
5 begin : 1.9.2022
6 copyright : (C) 2022 by Alessandro Pasotti
7 email : elpaso at itopen dot it
8 ***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
17
18#include "qgsapplication.h"
19#include "qgshelp.h"
20#include "qgsiconutils.h"
23#include "qgsmapcanvas.h"
25
26#include <QString>
27
28#include "moc_qgslayermetadatasearchwidget.cpp"
29
30using namespace Qt::StringLiterals;
31
34{
35 setupUi( this );
36 setupButtons( mButtonBox );
37
38 QgsMetadataSearchContext searchContext;
40
41 mSourceModel = new QgsLayerMetadataResultsModel( searchContext, this );
42 mProxyModel = new QgsLayerMetadataResultsProxyModel( this );
43 mProxyModel->setSourceModel( mSourceModel );
44 mMetadataTableView->setModel( mProxyModel );
45 mMetadataTableView->setSortingEnabled( true );
46 mMetadataTableView->sortByColumn( 0, Qt::SortOrder::AscendingOrder );
47 mMetadataTableView->horizontalHeader()->setSectionResizeMode( QgsLayerMetadataResultsModel::Sections::Identifier, QHeaderView::ResizeMode::Stretch );
48 mMetadataTableView->horizontalHeader()->setSectionResizeMode( QgsLayerMetadataResultsModel::Sections::Title, QHeaderView::ResizeMode::Stretch );
49 mMetadataTableView->horizontalHeader()->setSectionResizeMode( QgsLayerMetadataResultsModel::Sections::Abstract, QHeaderView::ResizeMode::Stretch );
50 mMetadataTableView->horizontalHeader()->setSectionResizeMode( QgsLayerMetadataResultsModel::Sections::DataProviderName, QHeaderView::ResizeMode::ResizeToContents );
51 mMetadataTableView->horizontalHeader()->setSectionResizeMode( QgsLayerMetadataResultsModel::Sections::GeometryType, QHeaderView::ResizeMode::ResizeToContents );
52 mMetadataTableView->setSelectionBehavior( QAbstractItemView::SelectRows );
53
54 mExtentFilterComboBox->addItem( QString() );
55 mExtentFilterComboBox->addItem( u"Map Canvas Extent"_s );
56 mExtentFilterComboBox->addItem( u"Current Project Extent"_s );
57 mExtentFilterComboBox->setCurrentIndex( 0 );
58 mExtentFilterComboBox->setSizeAdjustPolicy( QComboBox::SizeAdjustPolicy::AdjustToContents );
59 mExtentFilterComboBox->adjustSize();
60
61 mGeometryTypeComboBox->addItem( QString(), QVariant() );
65 // Note: unknown geometry is mapped to null and missing from the combo
67 mGeometryTypeComboBox->addItem( QgsApplication::getThemeIcon( u"mIconRaster.svg"_s ), tr( "Raster" ), QVariant() );
68 mGeometryTypeComboBox->setCurrentIndex( 0 );
69 mGeometryTypeComboBox->setSizeAdjustPolicy( QComboBox::SizeAdjustPolicy::AdjustToContents );
70 mGeometryTypeComboBox->adjustSize();
71
72 auto updateLoadBtn = [this] {
73 if ( mIsLoading )
74 {
75 mAbortPushButton->setText( tr( "Abort" ) );
76 mAbortPushButton->setIcon( QgsApplication::getThemeIcon( u"mTaskCancel.svg"_s ) );
77 }
78 else
79 {
80 mAbortPushButton->setText( tr( "Refresh" ) );
81 mAbortPushButton->setIcon( QgsApplication::getThemeIcon( u"mActionRefresh.svg"_s ) );
82 }
83 };
84
85 connect( mSourceModel, &QgsLayerMetadataResultsModel::progressChanged, mProgressBar, &QProgressBar::setValue );
86 connect( mSourceModel, &QgsLayerMetadataResultsModel::progressChanged, this, [this, updateLoadBtn]( int progress ) {
87 if ( progress == 100 )
88 {
89 mIsLoading = false;
90 mReloadRequired = false;
91 mProgressBar->hide();
92 updateLoadBtn();
93 }
94 } );
95
96 connect( mAbortPushButton, &QPushButton::clicked, mSourceModel, [this, updateLoadBtn]( bool ) {
97 if ( !mIsLoading )
98 {
99 mProgressBar->show();
100 mReloadRequired = true;
101 refresh();
102 }
103 else
104 {
105 mProgressBar->hide();
106 mSourceModel->cancel();
107 mIsLoading = false;
108 mReloadRequired = false;
109 }
110 updateLoadBtn();
111 } );
112
113 connect( mMetadataTableView->selectionModel(), &QItemSelectionModel::selectionChanged, this, [this]( const QItemSelection &, const QItemSelection & ) {
114 emit enableButtons( mMetadataTableView->selectionModel()->hasSelection() );
115 } );
116
117 connect( mSearchFilterLineEdit, &QLineEdit::textEdited, mProxyModel, &QgsLayerMetadataResultsProxyModel::setFilterString );
118 connect( mSearchFilterLineEdit, &QgsFilterLineEdit::cleared, mProxyModel, [this] { mProxyModel->setFilterString( QString() ); } );
119 connect( mExtentFilterComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, &QgsLayerMetadataSearchWidget::updateExtentFilter );
120
121 connect( mGeometryTypeComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, [this]( int index ) {
122 if ( index == 0 ) // reset all filters
123 {
124 mProxyModel->setFilterGeometryTypeEnabled( false );
125 mProxyModel->setFilterMapLayerTypeEnabled( false );
126 }
127 else
128 {
129 const QVariant geomTypeFilterValue( mGeometryTypeComboBox->currentData() );
130 if ( geomTypeFilterValue.isValid() ) // Vector layers
131 {
132 mProxyModel->setFilterGeometryTypeEnabled( true );
133 mProxyModel->setFilterGeometryType( geomTypeFilterValue.value<Qgis::GeometryType>() );
134 mProxyModel->setFilterMapLayerTypeEnabled( true );
135 mProxyModel->setFilterMapLayerType( Qgis::LayerType::Vector );
136 }
137 else // Raster layers
138 {
139 mProxyModel->setFilterGeometryTypeEnabled( false );
140 mProxyModel->setFilterMapLayerTypeEnabled( true );
141 mProxyModel->setFilterMapLayerType( Qgis::LayerType::Raster );
142 }
143 }
144 } );
145
146 connect( QgsProject::instance(), &QgsProject::layersAdded, this, [this]( const QList<QgsMapLayer *> & ) {
147 updateExtentFilter( mExtentFilterComboBox->currentIndex() );
148 } );
149
150 connect( QgsProject::instance(), &QgsProject::layersRemoved, this, [this]( const QStringList & ) {
151 updateExtentFilter( mExtentFilterComboBox->currentIndex() );
152 } );
153
154 connect( mButtonBox, &QDialogButtonBox::helpRequested, this, &QgsLayerMetadataSearchWidget::showHelp );
155}
156
158{
159 if ( newMapCanvas && mapCanvas() != newMapCanvas )
160 {
161 connect( newMapCanvas, &QgsMapCanvas::extentsChanged, this, [this] {
162 updateExtentFilter( mExtentFilterComboBox->currentIndex() );
163 } );
164 }
166}
167
169{
170 if ( index == 1 && mapCanvas() )
171 {
172 QgsCoordinateTransform ct( mapCanvas()->mapSettings().destinationCrs(), QgsCoordinateReferenceSystem::fromEpsgId( 4326 ), QgsProject::instance()->transformContext() );
174 mProxyModel->setFilterExtent( ct.transformBoundingBox( mapCanvas()->extent() ) );
175 }
176 else if ( index == 2 )
177 {
181 mProxyModel->setFilterExtent( ct.transformBoundingBox( extent ) );
182 }
183 else
184 {
185 mProxyModel->setFilterExtent( QgsRectangle() );
186 }
187}
188
190{
191 // Lazy reload
192 mReloadRequired = true;
193 refreshInternal();
194}
195
197{
198 const QModelIndexList &selectedIndexes { mMetadataTableView->selectionModel()->selectedRows() };
199 if ( !selectedIndexes.isEmpty() )
200 {
201 for ( const auto &selectedIndex : std::as_const( selectedIndexes ) )
202 {
203 const QgsLayerMetadataProviderResult metadataResult { mSourceModel->data( mProxyModel->mapToSource( selectedIndex ), static_cast<int>( QgsLayerMetadataResultsModel::CustomRole::Metadata ) ).value<QgsLayerMetadataProviderResult>() };
204
205 QString layerName = metadataResult.title();
206 if ( layerName.isEmpty() )
207 {
208 QVariantMap components = QgsProviderRegistry::instance()->decodeUri( metadataResult.dataProviderName(), metadataResult.uri() );
209 if ( components.contains( u"layerName"_s ) )
210 {
211 layerName = components.value( u"layerName"_s ).toString();
212 }
213 else if ( components.contains( u"table"_s ) )
214 {
215 layerName = components.value( u"table"_s ).toString();
216 }
217 else
218 {
219 layerName = metadataResult.identifier();
220 }
221 }
222
223 switch ( metadataResult.layerType() )
224 {
226 {
228 emit addRasterLayer( metadataResult.uri(), layerName, metadataResult.dataProviderName() );
230 emit addLayer( metadataResult.layerType(), metadataResult.uri(), layerName, metadataResult.dataProviderName() );
231 break;
232 }
234 {
236 emit addVectorLayer( metadataResult.uri(), layerName, metadataResult.dataProviderName() );
238 emit addLayer( metadataResult.layerType(), metadataResult.uri(), layerName, metadataResult.dataProviderName() );
239 break;
240 }
242 {
244 emit addMeshLayer( metadataResult.uri(), layerName, metadataResult.dataProviderName() );
246 emit addLayer( metadataResult.layerType(), metadataResult.uri(), layerName, metadataResult.dataProviderName() );
247 break;
248 }
249 default: // unsupported
250 {
251 // Ignore
252 break;
253 }
254 }
255 }
256 }
257}
258
260{
261 mSearchFilterLineEdit->clear();
262 mExtentFilterComboBox->setCurrentIndex( 0 );
263}
264
266{
267 QgsAbstractDataSourceWidget::showEvent( event );
268 mSearchFilterLineEdit->setText( mProxyModel->filterString() );
269 refreshInternal();
270}
271
272void QgsLayerMetadataSearchWidget::showHelp()
273{
274 QgsHelp::openHelp( u"managing_data_source/opening_data.html#the-layer-metadata-search-panel"_s );
275}
276
277void QgsLayerMetadataSearchWidget::refreshInternal()
278{
279 if ( mReloadRequired && isVisible() )
280 {
281 mIsLoading = true;
282 mSourceModel->reloadAsync();
283 }
284}
GeometryType
The geometry types are used to group Qgis::WkbType in a coarse way.
Definition qgis.h:365
@ Point
Points.
Definition qgis.h:366
@ Line
Lines.
Definition qgis.h:367
@ Polygon
Polygons.
Definition qgis.h:368
@ Null
No geometry.
Definition qgis.h:370
@ Vector
Vector layer.
Definition qgis.h:194
@ Mesh
Mesh layer. Added in QGIS 3.2.
Definition qgis.h:197
@ Raster
Raster layer.
Definition qgis.h:195
Q_DECL_DEPRECATED void progress(int, int)
Emitted when a progress dialog is shown by the provider dialog.
virtual QgsMapCanvas * mapCanvas()
Returns the dialog map canvas.
void setupButtons(QDialogButtonBox *buttonBox)
Connect the ok and apply/add buttons to the slots.
Q_DECL_DEPRECATED void addRasterLayer(const QString &rasterLayerPath, const QString &baseName, const QString &providerKey)
Emitted when a raster layer has been selected for addition.
virtual void setMapCanvas(QgsMapCanvas *mapCanvas)
Sets the dialog map canvas.
QgsAbstractDataSourceWidget(QWidget *parent=nullptr, Qt::WindowFlags fl=QgsGuiUtils::ModalDialogFlags, QgsProviderRegistry::WidgetMode widgetMode=QgsProviderRegistry::WidgetMode::Standalone)
Constructor.
Q_DECL_DEPRECATED void addMeshLayer(const QString &url, const QString &baseName, const QString &providerKey)
Emitted when a mesh layer has been selected for addition.
QgsProviderRegistry::WidgetMode widgetMode() const
Returns the widget mode.
Q_DECL_DEPRECATED void addVectorLayer(const QString &uri, const QString &layerName, const QString &providerKey=QString())
Emitted when a vector layer has been selected for addition.
void addLayer(Qgis::LayerType type, const QString &url, const QString &baseName, const QString &providerKey)
Emitted when a layer has been selected for addition.
QString title() const
Returns the human readable name of the resource, typically displayed in search results.
QString identifier() const
A reference, URI, URL or some other mechanism to identify the resource.
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
static Q_INVOKABLE QgsCoordinateReferenceSystem fromEpsgId(long epsg)
Creates a CRS from a given EPSG ID.
Handles coordinate transforms between two coordinate systems.
void setBallparkTransformsAreAppropriate(bool appropriate)
Sets whether approximate "ballpark" results are appropriate for this coordinate transform.
QgsRectangle transformBoundingBox(const QgsRectangle &rectangle, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool handle180Crossover=false) const
Transforms a rectangle from the source CRS to the destination CRS.
void cleared()
Emitted when the widget is cleared.
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition qgshelp.cpp:41
static QIcon iconForGeometryType(Qgis::GeometryType typeGroup)
Returns the icon for a vector layer whose geometry typeGroup is provided.
Result record of layer metadata provider search.
const QString & dataProviderName() const
Returns the data provider name.
const QString & uri() const
Returns the layer data source URI.
Qgis::LayerType layerType() const
Returns the layer type.
A proxy model for QgsLayerMetadataResultsModel, handling text and extent filtering.
void setFilterString(const QString &filterString)
Sets the text filter to filterString.
void setMapCanvas(QgsMapCanvas *mapCanvas) override
Sets the dialog map canvas.
void updateExtentFilter(int index)
Updates the extent filter based on the combo box current item index.
QgsLayerMetadataSearchWidget(QWidget *parent=nullptr, Qt::WindowFlags fl=Qt::WindowFlags(), QgsProviderRegistry::WidgetMode widgetMode=QgsProviderRegistry::WidgetMode::Standalone)
Creates a new QgsLayerMetadataSearchWidget.
void showEvent(QShowEvent *event) override
Map canvas is a class for displaying all GIS data types on a canvas.
void extentsChanged()
Emitted when the extents of the map change.
QgsReferencedRectangle fullExtent() const
Returns the full extent of the project, which represents the maximal limits of the project.
void layersRemoved(const QStringList &layerIds)
Emitted after one or more layers were removed from the registry.
static QgsProject * instance()
Returns the QgsProject singleton instance.
QgsCoordinateTransformContext transformContext
Definition qgsproject.h:120
const QgsProjectViewSettings * viewSettings() const
Returns the project's view settings, which contains settings and properties relating to how a QgsProj...
void layersAdded(const QList< QgsMapLayer * > &layers)
Emitted when one or more layers were added to the registry.
QVariantMap decodeUri(const QString &providerKey, const QString &uri)
Breaks a provider data source URI into its component paths (e.g.
static QgsProviderRegistry * instance(const QString &pluginPath=QString())
Means of accessing canonical single instance.
WidgetMode
Different ways a source select dialog can be used.
A rectangle specified with double values.
QgsCoordinateReferenceSystem crs() const
Returns the associated coordinate reference system, or an invalid CRS if no reference system is set.
A QgsRectangle with associated coordinate reference system.
static Q_INVOKABLE QString geometryDisplayString(Qgis::GeometryType type)
Returns a display string for a geometry type.
#define Q_NOWARN_DEPRECATED_POP
Definition qgis.h:7475
#define Q_NOWARN_DEPRECATED_PUSH
Definition qgis.h:7474
QgsCoordinateTransformContext transformContext
Coordinate transform context.