QGIS API Documentation 4.3.0-Master (bf28115e945)
Loading...
Searching...
No Matches
qgsdatasourcemanagerdialog.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsdatasourcemanagerdialog.cpp - datasource manager dialog
3
4 ---------------------
5 begin : May 19, 2017
6 copyright : (C) 2017 by Alessandro Pasotti
7 email : apasotti 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 ***************************************************************************/
16
17#include "ui_qgsdatasourcemanagerdialog.h"
19
22#include "qgsbrowserguimodel.h"
23#include "qgsbrowserwidget.h"
24#include "qgsgui.h"
25#include "qgsmapcanvas.h"
26#include "qgsmessagebar.h"
27#include "qgsmessagelog.h"
28#include "qgsproviderregistry.h"
29#include "qgssettings.h"
32
33#include <QListWidgetItem>
34#include <QString>
35
36#include "moc_qgsdatasourcemanagerdialog.cpp"
37
38using namespace Qt::StringLiterals;
39
40QgsDataSourceManagerDialog::QgsDataSourceManagerDialog( QgsBrowserGuiModel *browserModel, QWidget *parent, QgsMapCanvas *canvas, Qt::WindowFlags fl )
41 : QgsOptionsDialogBase( tr( "Data Source Manager" ), parent, fl )
42 , ui( std::make_unique<Ui::QgsDataSourceManagerDialog>() )
43 , mMapCanvas( canvas )
44 , mBrowserModel( browserModel )
45{
46 ui->setupUi( this );
47 ui->verticalLayout_2->setSpacing( 6 );
48 ui->verticalLayout_2->setContentsMargins( 0, 0, 0, 0 );
49
50 mMessageBar = new QgsMessageBar( this );
51 mMessageBar->setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Fixed );
52 static_cast<QVBoxLayout *>( layout() )->insertWidget( 0, mMessageBar );
53
54 // QgsOptionsDialogBase handles saving/restoring of geometry, splitter and current tab states,
55 // switching vertical tabs between icon/text to icon-only modes (splitter collapsed to left),
56 // and connecting QDialogButtonBox's accepted/rejected signals to dialog's accept/reject slots
57 initOptionsBase( false );
58
59 // Bind list index to the stacked dialogs
60 connect( ui->mOptionsListWidget, &QListWidget::currentRowChanged, this, &QgsDataSourceManagerDialog::setCurrentPage );
61
62 // BROWSER Add the browser widget to the first stacked widget page
63 mBrowserWidget = new QgsBrowserDockWidget( u"Browser"_s, mBrowserModel, this );
64 mBrowserWidget->setFeatures( QDockWidget::NoDockWidgetFeatures );
65 mBrowserWidget->setTitleBarWidget( new QWidget( mBrowserWidget ) );
66 mBrowserWidget->setMessageBar( mMessageBar );
67
68 QWidget *browserWidgetWrapper = new QWidget( this );
69 browserWidgetWrapper->setLayout( new QVBoxLayout( browserWidgetWrapper ) );
70 browserWidgetWrapper->layout()->addWidget( mBrowserWidget );
71 QDialogButtonBox *browserButtonBox = new QDialogButtonBox( QDialogButtonBox::StandardButton::Close | QDialogButtonBox::StandardButton::Help, browserWidgetWrapper );
72 browserWidgetWrapper->layout()->addWidget( browserButtonBox );
73
74 connect( browserButtonBox, &QDialogButtonBox::helpRequested, this, [] { QgsHelp::openHelp( u"managing_data_source/opening_data.html#the-browser-panel"_s ); } );
75 connect( browserButtonBox, &QDialogButtonBox::rejected, this, &QgsDataSourceManagerDialog::reject );
76
77 ui->mOptionsStackedWidget->addWidget( browserWidgetWrapper );
78 mPageProviderKeys.append( u"browser"_s );
79 mPageProviderNames.append( u"browser"_s );
80
81 // Forward all browser signals
85 connect( this, &QgsDataSourceManagerDialog::updateProjectHome, mBrowserWidget->browserWidget(), &QgsBrowserWidget::updateProjectHome );
86
87 // Add registered source select dialogs
88 const QList<QgsSourceSelectProvider *> sourceSelectProviders = QgsGui::sourceSelectProviderRegistry()->providers();
89 for ( QgsSourceSelectProvider *provider : sourceSelectProviders )
90 {
91 QgsAbstractDataSourceWidget *dlg = provider->createDataSourceWidget( this );
92 if ( !dlg )
93 {
94 QgsMessageLog::logMessage( tr( "Cannot get %1 select dialog from source select provider %2." ).arg( provider->name(), provider->providerKey() ), u"DataSourceManager"_s, Qgis::MessageLevel::Critical );
95 continue;
96 }
97 addProviderDialog( dlg, provider->providerKey(), provider->name(), provider->text(), provider->icon(), provider->toolTip() );
98 }
99
100 connect( QgsGui::sourceSelectProviderRegistry(), &QgsSourceSelectProviderRegistry::providerAdded, this, [this]( const QString &name ) {
101 if ( QgsSourceSelectProvider *provider = QgsGui::sourceSelectProviderRegistry()->providerByName( name ) )
102 {
103 QgsAbstractDataSourceWidget *dlg = provider->createDataSourceWidget( this );
104 if ( !dlg )
105 {
106 QgsMessageLog::logMessage( tr( "Cannot get %1 select dialog from source select provider %2." ).arg( provider->name(), provider->providerKey() ), u"DataSourceManager"_s, Qgis::MessageLevel::Critical );
107 return;
108 }
109 addProviderDialog( dlg, provider->providerKey(), provider->name(), provider->text(), provider->icon(), provider->toolTip() );
110 }
111 } );
112
113 connect( QgsGui::sourceSelectProviderRegistry(), &QgsSourceSelectProviderRegistry::providerRemoved, this, [this]( const QString &name ) { removeProviderDialog( name ); } );
114
115 restoreOptionsBaseUi( tr( "Data Source Manager" ) );
116}
117
120
121void QgsDataSourceManagerDialog::openPage( const QString &pageName )
122{
123 // TODO -- this is actually using provider keys, not provider names!
124 const int pageIdx = mPageProviderKeys.indexOf( pageName );
125 if ( pageIdx != -1 )
126 {
127 QTimer::singleShot( 0, this, [this, pageIdx] { setCurrentPage( pageIdx ); } );
128 }
129}
130
132{
133 return mMessageBar;
134}
135
137{
138 raise();
139 setWindowState( windowState() & ~Qt::WindowMinimized );
140 activateWindow();
141}
142
144{
145 mPreviousRow = ui->mOptionsStackedWidget->currentIndex();
146 ui->mOptionsStackedWidget->setCurrentIndex( index );
147 setWindowTitle( tr( "Data Source Manager | %1" ).arg( ui->mOptionsListWidget->currentItem()->text() ) );
148 resizeAlltabs( index );
149}
150
152{
153 const int prevPage = mPreviousRow != -1 ? mPreviousRow : 0;
154 setCurrentPage( prevPage );
155}
156
158{
159 mBrowserWidget->browserWidget()->refresh();
161}
162
164{
165 const int pageCount = ui->mOptionsStackedWidget->count();
166 for ( int i = 0; i < pageCount; ++i )
167 {
168 QWidget *widget = ui->mOptionsStackedWidget->widget( i );
169 QgsAbstractDataSourceWidget *dataSourceWidget = qobject_cast<QgsAbstractDataSourceWidget *>( widget );
170 if ( dataSourceWidget )
171 dataSourceWidget->reset();
172 }
173}
174
175void QgsDataSourceManagerDialog::configureFromUri( const QString &pageName, const QString &uri )
176{
177 const int pageIdx = mPageProviderNames.indexOf( pageName );
178 if ( pageIdx != -1 )
179 {
180 QTimer::singleShot( 0, this, [this, pageIdx, uri] {
181 setCurrentPage( pageIdx );
182 if ( QgsAbstractDataSourceWidget *dataSourceWidget = qobject_cast<QgsAbstractDataSourceWidget *>( ui->mOptionsStackedWidget->currentWidget() ) )
183 {
184 dataSourceWidget->configureFromUri( uri );
185 }
186 } );
187 }
188}
189
190void QgsDataSourceManagerDialog::rasterLayersAdded( const QStringList &layersList )
191{
192 emit addRasterLayers( layersList );
193}
194
195void QgsDataSourceManagerDialog::vectorLayersAdded( const QStringList &layerQStringList, const QString &enc, const QString &dataSourceType )
196{
197 emit addVectorLayers( layerQStringList, enc, dataSourceType );
198}
199
200void QgsDataSourceManagerDialog::addProviderDialog( QgsAbstractDataSourceWidget *dlg, const QString &providerKey, const QString &providerName, const QString &text, const QIcon &icon, const QString &toolTip )
201{
202 mPageProviderKeys.append( providerKey );
203 mPageProviderNames.append( providerName );
204 ui->mOptionsStackedWidget->addWidget( dlg );
205 QListWidgetItem *layerItem = new QListWidgetItem( text, ui->mOptionsListWidget );
206 layerItem->setData( Qt::UserRole, providerName );
207 layerItem->setToolTip( toolTip.isEmpty() ? tr( "Add %1 layer" ).arg( text ) : toolTip );
208 layerItem->setIcon( icon );
209 // Set crs and extent from canvas
210 if ( mMapCanvas )
211 {
212 dlg->setMapCanvas( mMapCanvas );
213 }
214 dlg->setBrowserModel( mBrowserModel );
215
216 connect( dlg, &QgsAbstractDataSourceWidget::rejected, this, &QgsDataSourceManagerDialog::reject );
217 connect( dlg, &QgsAbstractDataSourceWidget::accepted, this, &QgsDataSourceManagerDialog::accept );
218 makeConnections( dlg, providerKey );
219}
220
221void QgsDataSourceManagerDialog::removeProviderDialog( const QString &providerName )
222{
223 const int pageIdx = mPageProviderNames.indexOf( providerName );
224 if ( pageIdx != -1 )
225 {
226 ui->mOptionsStackedWidget->removeWidget( ui->mOptionsStackedWidget->widget( pageIdx ) );
227 mPageProviderKeys.removeAt( pageIdx );
228 mPageProviderNames.removeAt( pageIdx );
229 ui->mOptionsListWidget->removeItemWidget( ui->mOptionsListWidget->item( pageIdx ) );
230 }
231}
232
233void QgsDataSourceManagerDialog::makeConnections( QgsAbstractDataSourceWidget *dlg, const QString &providerKey )
234{
235 // DB
238
239 connect( dlg, &QgsAbstractDataSourceWidget::addLayer, this, [this]( Qgis::LayerType type, const QString &url, const QString &baseName, const QString &providerKey ) {
240 Q_UNUSED( url )
241 Q_UNUSED( baseName )
242 Q_UNUSED( providerKey )
243
244 switch ( type )
245 {
254 // for compatibility with older API, we ignore these signals and rely on the older granular signals (eg "addVectorLayer").
255 // otherwise we will be emitting double signals for the old/new signal for these layer types
256 break;
257
259 emit addLayer( type, url, baseName, providerKey );
260 break;
261 }
262 } );
263
264 // Vector
266 connect( dlg, &QgsAbstractDataSourceWidget::addVectorLayer, this, [this, providerKey]( const QString &vectorLayerPath, const QString &baseName, const QString &specifiedProvider ) {
267 const QString key = specifiedProvider.isEmpty() ? providerKey : specifiedProvider;
268 emit addLayer( Qgis::LayerType::Vector, vectorLayerPath, baseName, key );
269 } );
273
274 // Raster
276 connect( dlg, &QgsAbstractDataSourceWidget::addRasterLayer, this, [this]( const QString &rasterLayerPath, const QString &baseName, const QString &providerKey ) {
277 emit addLayer( Qgis::LayerType::Raster, rasterLayerPath, baseName, providerKey );
278 } );
281
282 // Mesh
284 connect( dlg, &QgsAbstractDataSourceWidget::addMeshLayer, this, [this]( const QString &url, const QString &baseName, const QString &providerKey ) {
285 emit addLayer( Qgis::LayerType::Mesh, url, baseName, providerKey );
286 } );
288 // Vector tile
290 connect( dlg, &QgsAbstractDataSourceWidget::addVectorTileLayer, this, [this]( const QString &url, const QString &baseName ) {
291 emit addLayer( Qgis::LayerType::VectorTile, url, baseName, QString() );
292 } );
294 // Point Cloud
296 connect( dlg, &QgsAbstractDataSourceWidget::addPointCloudLayer, this, [this]( const QString &url, const QString &baseName, const QString &providerKey ) {
297 emit addLayer( Qgis::LayerType::PointCloud, url, baseName, providerKey );
298 } );
300 // Virtual
302 // Common
304 connect( this, &QgsDataSourceManagerDialog::providerDialogsRefreshRequested, dlg, &QgsAbstractDataSourceWidget::refresh, Qt::ConnectionType::QueuedConnection );
305
306 // Message
307 connect( dlg, &QgsAbstractDataSourceWidget::pushMessage, this, [this]( const QString &title, const QString &message, const Qgis::MessageLevel level ) {
308 mMessageBar->pushMessage( title, message, level );
309 } );
310}
311
313{
314 ui->mOptionsStackedWidget->currentWidget()->show();
316 resizeAlltabs( ui->mOptionsStackedWidget->currentIndex() );
317}
MessageLevel
Level for messages This will be used both for message log and message bar in application.
Definition qgis.h:160
@ Critical
Critical/error message.
Definition qgis.h:163
LayerType
Types of layers that can be added to a map.
Definition qgis.h:206
@ Group
Composite group layer. Added in QGIS 3.24.
Definition qgis.h:214
@ Plugin
Plugin based layer.
Definition qgis.h:209
@ TiledScene
Tiled scene layer. Added in QGIS 3.34.
Definition qgis.h:215
@ Annotation
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
Definition qgis.h:212
@ Vector
Vector layer.
Definition qgis.h:207
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
Definition qgis.h:211
@ Mesh
Mesh layer. Added in QGIS 3.2.
Definition qgis.h:210
@ Raster
Raster layer.
Definition qgis.h:208
@ PointCloud
Point cloud layer. Added in QGIS 3.18.
Definition qgis.h:213
Abstract base class for Data Source widgets to create connections and add layers.
void pushMessage(const QString &title, const QString &message, const Qgis::MessageLevel level=Qgis::MessageLevel::Info)
Emitted when a message with title and level must be shown to the user using the parent visible messag...
Q_DECL_DEPRECATED void addPointCloudLayer(const QString &url, const QString &baseName, const QString &providerKey)
Emitted when a point cloud layer has been selected for addition.
Q_DECL_DEPRECATED void addVectorTileLayer(const QString &url, const QString &baseName)
Emitted when a vector tile layer has been selected for addition.
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.
void replaceVectorLayer(const QString &oldId, const QString &source, const QString &name, const QString &provider)
Emitted when a layer needs to be replaced.
void connectionsChanged()
Emitted when the provider's connections have changed This signal is normally forwarded the app and us...
void addRasterLayers(const QStringList &layersList)
Emitted when one or more GDAL supported layers are selected for addition.
virtual void refresh()
Triggered when the provider's connections need to be refreshed The default implementation does nothin...
virtual void setBrowserModel(QgsBrowserModel *model)
Sets a browser model to use with the widget.
Q_DECL_DEPRECATED void addMeshLayer(const QString &url, const QString &baseName, const QString &providerKey)
Emitted when a mesh layer has been selected for addition.
void progressMessage(QString message)
Emitted when a progress dialog is shown by the provider dialog.
void addVectorLayers(const QStringList &layerList, const QString &encoding, const QString &dataSourceType)
Emitted when one or more OGR supported layers are selected for addition.
void addDatabaseLayers(const QStringList &paths, const QString &providerKey)
Emitted when a DB layer has been selected for addition.
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.
virtual void reset()
Called when this source select widget is being shown in a "new and clean" dialog.
void addLayer(Qgis::LayerType type, const QString &url, const QString &baseName, const QString &providerKey)
Emitted when a layer has been selected for addition.
A dock widget containing a QgsBrowserWidget for navigating and managing data sources.
void connectionsChanged()
Connections changed in the browser.
void handleDropUriList(const QgsMimeDataUtils::UriList &uris)
Emitted when drop uri list needs to be handled.
void openFile(const QString &fileName, const QString &fileTypeHint=QString())
Emitted when a file needs to be opened.
A model for showing available data sources and other items in a structured tree.
void updateProjectHome()
Update project home directory.
void reset()
Resets the interface of the datasource manager after reopening the dialog.
void refresh()
Refresh the browser view.
void addVectorLayers(const QStringList &layerQStringList, const QString &enc, const QString &dataSourceType)
Emitted when a one or more layer were selected for addition: for signal forwarding to QgisApp.
void openFile(const QString &fileName, const QString &fileTypeHint=QString())
Emitted when a file needs to be opened.
QgsMessageBar * messageBar() const
Returns the dialog's message bar.
void rasterLayersAdded(const QStringList &layersList)
One or more raster layer were added: for signal forwarding to QgisApp.
void setPreviousPage()
Reset current page to previously selected page.
QgsDataSourceManagerDialog(QgsBrowserGuiModel *browserModel, QWidget *parent=nullptr, QgsMapCanvas *canvas=nullptr, Qt::WindowFlags fl=Qt::Window)
QgsDataSourceManagerDialog constructor.
void showStatusMessage(const QString &message)
Emitted when a status message needs to be shown: for signal forwarding to QgisApp.
void showEvent(QShowEvent *event) override
void replaceSelectedVectorLayer(const QString &oldId, const QString &uri, const QString &layerName, const QString &provider)
Replace the selected layer by a vector layer defined by uri, layer name, data source uri.
void configureFromUri(const QString &pageName, const QString &uri)
Shows the page pageName and configure the source select widget from the layer uri.
void openPage(const QString &pageName)
Open a given page in the dialog.
void activate()
Raise, unminimize and activate this window.
void connectionsChanged()
Emitted when a connection has changed inside the provider dialogs This signal is normally forwarded t...
void vectorLayersAdded(const QStringList &layerQStringList, const QString &enc, const QString &dataSourceType)
One or more vector layer were added: for signal forwarding to QgisApp.
void addDatabaseLayers(const QStringList &layerPathList, const QString &providerKey)
Emitted when a DB layer was selected for addition: for signal forwarding to QgisApp.
void handleDropUriList(const QgsMimeDataUtils::UriList &)
Emitted when drop uri list needs to be handled from the browser.
void providerDialogsRefreshRequested()
One or more provider connections have changed and the dialogs should be refreshed.
void addLayer(Qgis::LayerType type, const QString &url, const QString &baseName, const QString &providerKey)
Emitted when a layer has been selected for addition.
void updateProjectHome()
Update project home directory.
void setCurrentPage(int index)
Sync current page with the leftbar list.
void addRasterLayers(const QStringList &layersList)
Emitted when a one or more layer were selected for addition: for signal forwarding to QgisApp.
static QgsSourceSelectProviderRegistry * sourceSelectProviderRegistry()
Returns the global source select provider registry, used for managing all known source select widget ...
Definition qgsgui.cpp:124
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition qgshelp.cpp:41
Map canvas is a class for displaying all GIS data types on a canvas.
A bar for displaying non-blocking messages to the user.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE(), Qgis::StringFormat format=Qgis::StringFormat::PlainText)
Adds a message to the log instance (and creates it if necessary).
void resizeAlltabs(int index)
Resizes all tabs when the dialog is resized.
QgsOptionsDialogBase(const QString &settingsKey, QWidget *parent=nullptr, Qt::WindowFlags fl=Qt::WindowFlags(), QgsSettings *settings=nullptr)
Constructor.
void restoreOptionsBaseUi(const QString &title=QString())
Restore the base ui.
void initOptionsBase(bool restoreUi=true, const QString &title=QString())
Set up the base ui connections for vertical tabs.
void showEvent(QShowEvent *e) override
void providerRemoved(const QString &name)
Emitted whenever a provider is removed from the registry.
void providerAdded(const QString &name)
Emitted whenever a provider is added to the registry.
QList< QgsSourceSelectProvider * > providers()
Gets list of available providers.
An interface for pages shown in a QgsDataSourceManagerDialog.
#define Q_NOWARN_DEPRECATED_POP
Definition qgis.h:7979
#define Q_NOWARN_DEPRECATED_PUSH
Definition qgis.h:7978