QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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 ***************************************************************************/
19#include "qgsapplication.h"
20#include "qgsmapcanvas.h"
22#include "qgsiconutils.h"
23
24
26 : QgsAbstractDataSourceWidget( parent, fl, widgetMode )
27{
28
29 setupUi( this );
30 setupButtons( mButtonBox );
31
32 QgsMetadataSearchContext searchContext;
34
35 mSourceModel = new QgsLayerMetadataResultsModel( searchContext, this );
36 mProxyModel = new QgsLayerMetadataResultsProxyModel( this );
37 mProxyModel->setSourceModel( mSourceModel );
38 mMetadataTableView->setModel( mProxyModel );
39 mMetadataTableView->setSortingEnabled( true );
40 mMetadataTableView->sortByColumn( 0, Qt::SortOrder::AscendingOrder );
41 mMetadataTableView->horizontalHeader()->setSectionResizeMode( QgsLayerMetadataResultsModel::Sections::Identifier, QHeaderView::ResizeMode::Stretch );
42 mMetadataTableView->horizontalHeader()->setSectionResizeMode( QgsLayerMetadataResultsModel::Sections::Title, QHeaderView::ResizeMode::Stretch );
43 mMetadataTableView->horizontalHeader()->setSectionResizeMode( QgsLayerMetadataResultsModel::Sections::Abstract, QHeaderView::ResizeMode::Stretch );
44 mMetadataTableView->horizontalHeader()->setSectionResizeMode( QgsLayerMetadataResultsModel::Sections::DataProviderName, QHeaderView::ResizeMode::ResizeToContents );
45 mMetadataTableView->horizontalHeader()->setSectionResizeMode( QgsLayerMetadataResultsModel::Sections::GeometryType, QHeaderView::ResizeMode::ResizeToContents );
46 mMetadataTableView->setSelectionBehavior( QAbstractItemView::SelectRows );
47
48 mExtentFilterComboBox->addItem( QString( ) );
49 mExtentFilterComboBox->addItem( QStringLiteral( "Map Canvas Extent" ) );
50 mExtentFilterComboBox->addItem( QStringLiteral( "Current Project Extent" ) );
51 mExtentFilterComboBox->setCurrentIndex( 0 );
52 mExtentFilterComboBox->setSizeAdjustPolicy( QComboBox::SizeAdjustPolicy::AdjustToContents );
53 mExtentFilterComboBox->adjustSize();
54
55 mGeometryTypeComboBox->addItem( QString( ), QVariant() );
56 mGeometryTypeComboBox->addItem( QgsIconUtils::iconForGeometryType( QgsWkbTypes::GeometryType::PointGeometry ), QgsWkbTypes::geometryDisplayString( QgsWkbTypes::GeometryType::PointGeometry ), QgsWkbTypes::GeometryType::PointGeometry );
57 mGeometryTypeComboBox->addItem( QgsIconUtils::iconForGeometryType( QgsWkbTypes::GeometryType::LineGeometry ), QgsWkbTypes::geometryDisplayString( QgsWkbTypes::GeometryType::LineGeometry ), QgsWkbTypes::GeometryType::LineGeometry );
58 mGeometryTypeComboBox->addItem( QgsIconUtils::iconForGeometryType( QgsWkbTypes::GeometryType::PolygonGeometry ), QgsWkbTypes::geometryDisplayString( QgsWkbTypes::GeometryType::PolygonGeometry ), QgsWkbTypes::GeometryType::PolygonGeometry );
59 // Note: unknown geometry is mapped to null and missing from the combo
60 mGeometryTypeComboBox->addItem( QgsIconUtils::iconForGeometryType( QgsWkbTypes::GeometryType::NullGeometry ), QgsWkbTypes::geometryDisplayString( QgsWkbTypes::GeometryType::NullGeometry ), QgsWkbTypes::GeometryType::NullGeometry );
61 mGeometryTypeComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconRaster.svg" ) ), tr( "Raster" ), QVariant() );
62 mGeometryTypeComboBox->setCurrentIndex( 0 );
63 mGeometryTypeComboBox->setSizeAdjustPolicy( QComboBox::SizeAdjustPolicy::AdjustToContents );
64 mGeometryTypeComboBox->adjustSize();
65
66 auto updateLoadBtn = [ = ]
67 {
68 if ( mIsLoading )
69 {
70 mAbortPushButton->setText( tr( "Abort" ) );
71 mAbortPushButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mTaskCancel.svg" ) ) );
72 }
73 else
74 {
75 mAbortPushButton->setText( tr( "Refresh" ) );
76 mAbortPushButton->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "mActionRefresh.svg" ) ) );
77 }
78 };
79
80 connect( mSourceModel, &QgsLayerMetadataResultsModel::progressChanged, mProgressBar, &QProgressBar::setValue );
81 connect( mSourceModel, &QgsLayerMetadataResultsModel::progressChanged, this, [ = ]( int progress )
82 {
83 if ( progress == 100 )
84 {
85 mIsLoading = false;
86 mProgressBar->hide();
87 updateLoadBtn();
88 }
89 } );
90
91 connect( mAbortPushButton, &QPushButton::clicked, mSourceModel, [ = ]( bool )
92 {
93 if ( ! mIsLoading )
94 {
95 mIsLoading = true;
96 mProgressBar->show();
97 mSourceModel->reloadAsync( );
98 }
99 else
100 {
101 mProgressBar->hide();
102 mSourceModel->cancel();
103 mIsLoading = false;
104 }
105 updateLoadBtn();
106 } );
107
108 connect( mMetadataTableView->selectionModel(), &QItemSelectionModel::selectionChanged, this, [ = ]( const QItemSelection &, const QItemSelection & )
109 {
110 emit enableButtons( mMetadataTableView->selectionModel()->hasSelection() );
111 } );
112
113 connect( mSearchFilterLineEdit, &QLineEdit::textEdited, mProxyModel, &QgsLayerMetadataResultsProxyModel::setFilterString );
114 connect( mSearchFilterLineEdit, &QgsFilterLineEdit::cleared, mProxyModel, [ = ] { mProxyModel->setFilterString( QString() ); } );
115 connect( mExtentFilterComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, &QgsLayerMetadataSearchWidget::updateExtentFilter );
116
117 connect( mGeometryTypeComboBox, qOverload<int>( &QComboBox::currentIndexChanged ), this, [ = ]( int index )
118 {
119 if ( index == 0 ) // reset all filters
120 {
121 mProxyModel->setFilterGeometryTypeEnabled( false );
122 mProxyModel->setFilterMapLayerTypeEnabled( false );
123 }
124 else
125 {
126 const QVariant geomTypeFilterValue( mGeometryTypeComboBox->currentData() );
127 if ( geomTypeFilterValue.isValid() ) // Vector layers
128 {
129 mProxyModel->setFilterGeometryTypeEnabled( true );
130 mProxyModel->setFilterGeometryType( geomTypeFilterValue.value<QgsWkbTypes::GeometryType>( ) );
131 mProxyModel->setFilterMapLayerTypeEnabled( true );
133 }
134 else // Raster layers
135 {
136 mProxyModel->setFilterGeometryTypeEnabled( false );
137 mProxyModel->setFilterMapLayerTypeEnabled( true );
139 }
140 }
141
142 } );
143
144 connect( QgsProject::instance(), &QgsProject::layersAdded, this, [ = ]( const QList<QgsMapLayer *> & )
145 {
146 updateExtentFilter( mExtentFilterComboBox->currentIndex() );
147 } );
148
149 connect( QgsProject::instance(), &QgsProject::layersRemoved, this, [ = ]( const QStringList & )
150 {
151 updateExtentFilter( mExtentFilterComboBox->currentIndex() );
152 } );
153
154 // Start loading metadata in the model
155 mSourceModel->reloadAsync();
156 mIsLoading = true;
157
158}
159
161{
162 if ( newMapCanvas && mapCanvas() != newMapCanvas )
163 {
164 connect( newMapCanvas, &QgsMapCanvas::extentsChanged, this, [ = ]
165 {
166 updateExtentFilter( mExtentFilterComboBox->currentIndex() );
167 } );
168 }
170}
171
173{
174 if ( index == 1 && mapCanvas() )
175 {
176 QgsCoordinateTransform ct( mapCanvas()->mapSettings().destinationCrs(), QgsCoordinateReferenceSystem::fromEpsgId( 4326 ), QgsProject::instance()->transformContext() );
178 mProxyModel->setFilterExtent( ct.transformBoundingBox( mapCanvas()->extent() ) );
179 }
180 else if ( index == 2 )
181 {
185 mProxyModel->setFilterExtent( ct.transformBoundingBox( extent ) );
186 }
187 else
188 {
189 mProxyModel->setFilterExtent( QgsRectangle( ) );
190 }
191}
192
194{
195 mSourceModel->reloadAsync();
196}
197
199{
200 const QModelIndexList &selectedIndexes { mMetadataTableView->selectionModel()->selectedRows() };
201 if ( ! selectedIndexes.isEmpty() )
202 {
203 for ( const auto &selectedIndex : std::as_const( selectedIndexes ) )
204 {
205 const QgsLayerMetadataProviderResult metadataResult { mSourceModel->data( mProxyModel->mapToSource( selectedIndex ), QgsLayerMetadataResultsModel::Roles::Metadata ).value<QgsLayerMetadataProviderResult>() };
206 switch ( metadataResult.layerType() )
207 {
209 {
210 emit addRasterLayer( metadataResult.uri(), metadataResult.identifier(), metadataResult.dataProviderName() );
211 break;
212 }
214 {
215 emit addVectorLayer( metadataResult.uri(), metadataResult.identifier(), metadataResult.dataProviderName() );
216 break;
217 }
219 {
220 emit addMeshLayer( metadataResult.uri(), metadataResult.identifier(), metadataResult.dataProviderName() );
221 break;
222 }
223 default: // unsupported
224 {
225 // Ignore
226 break;
227 }
228 }
229 }
230 }
231}
232
234{
235 mSearchFilterLineEdit->clear();
236 mExtentFilterComboBox->setCurrentIndex( 0 );
237}
238
240{
241 QgsAbstractDataSourceWidget::showEvent( event );
242 mSearchFilterLineEdit->setText( mProxyModel->filterString( ) );
243}
Abstract base Data Source Widget to create connections and add layers This class provides common func...
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.
virtual void setMapCanvas(QgsMapCanvas *mapCanvas)
Sets the dialog map canvas.
void addMeshLayer(const QString &url, const QString &baseName, const QString &providerKey)
Emitted when a mesh layer has been selected for addition.
void addRasterLayer(const QString &rasterLayerPath, const QString &baseName, const QString &providerKey)
Emitted when a raster layer has been selected for addition.
void addVectorLayer(const QString &uri, const QString &layerName, const QString &providerKey=QString())
Emitted when a vector layer has been selected for addition.
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.
Class for doing transforms between two map 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 SIP_THROW(QgsCsException)
Transforms a rectangle from the source CRS to the destination CRS.
void cleared()
Emitted when the widget is cleared.
static QIcon iconForGeometryType(QgsWkbTypes::GeometryType typeGroup)
Returns the icon for a vector layer whose geometry typeGroup is provided.
Result record of layer metadata provider search.
The QgsLayerMetadataResultsModel class handles the metadata fetching from the registered layer metada...
void cancel()
Cancels the results fetching.
void reloadAsync()
Load/Reload model data asynchronously using threads.
QVariant data(const QModelIndex &index, int role) const override
void progressChanged(int progress)
Emitted when the progress changed to progress.
The QgsLayerMetadataResultsProxyModel class is a proxy model for QgsLayerMetadataResultsModel,...
void setFilterGeometryType(const QgsWkbTypes::GeometryType geometryType)
Sets the geometry type filter to geometryType.
void setFilterString(const QString &filterString)
Sets the text filter to filterString.
void setFilterExtent(const QgsRectangle &extent)
Sets the extent filter to extent.
void setFilterMapLayerType(const QgsMapLayerType mapLayerType)
Sets the map layer type filter to mapLayerType.
void setFilterMapLayerTypeEnabled(bool enabled)
Sets the map layer type filter status to enabled.
void setFilterGeometryTypeEnabled(bool enabled)
Sets the geometry type filter status to enabled.
const QString filterString() const
Returns the filter string.
QgsLayerMetadataSearchWidget(QWidget *parent=nullptr, Qt::WindowFlags fl=Qt::WindowFlags(), QgsProviderRegistry::WidgetMode widgetMode=QgsProviderRegistry::WidgetMode::None)
Creates a new QgsLayerMetadataSearchWidget.
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.
void showEvent(QShowEvent *event) override
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:90
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.
Definition: qgsproject.cpp:477
QgsCoordinateTransformContext transformContext
Definition: qgsproject.h:110
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.
WidgetMode
Different ways a source select dialog can be used.
A rectangle specified with double values.
Definition: qgsrectangle.h:42
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 QString geometryDisplayString(GeometryType type) SIP_HOLDGIL
Returns a display string for a geometry type.
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:141
@ MeshLayer
Mesh layer. Added in QGIS 3.2.
@ VectorLayer
Vector layer.
@ RasterLayer
Raster layer.
QgsCoordinateTransformContext transformContext
Coordinate transform context.