From 4f7017322f02390489c757a423e5f954be00cc72 Mon Sep 17 00:00:00 2001 From: Peter Petrik Date: Thu, 12 Jul 2018 15:04:11 +0200 Subject: [PATCH] [mesh] option to add mesh layer from data source manager dialog --- images/images.qrc | 1 + images/themes/default/mActionAddMeshLayer.svg | 106 +++++++++++++++++ .../qgsabstractdatasourcewidget.sip.in | 7 ++ src/app/qgisapp.cpp | 49 ++++++++ src/app/qgisapp.h | 6 + src/gui/qgsabstractdatasourcewidget.h | 6 + src/gui/qgsdatasourcemanagerdialog.cpp | 2 + src/gui/qgsdatasourcemanagerdialog.h | 5 + src/providers/mdal/CMakeLists.txt | 19 +++ src/providers/mdal/qgsmdalprovider.cpp | 34 ++++++ src/providers/mdal/qgsmdalsourceselect.cpp | 59 ++++++++++ src/providers/mdal/qgsmdalsourceselect.h | 46 ++++++++ src/ui/mesh/qgsmdalsourceselectbase.ui | 108 ++++++++++++++++++ 13 files changed, 448 insertions(+) create mode 100644 images/themes/default/mActionAddMeshLayer.svg create mode 100644 src/providers/mdal/qgsmdalsourceselect.cpp create mode 100644 src/providers/mdal/qgsmdalsourceselect.h create mode 100644 src/ui/mesh/qgsmdalsourceselectbase.ui diff --git a/images/images.qrc b/images/images.qrc index 15b0714b3ef..ec1c3a90dc4 100755 --- a/images/images.qrc +++ b/images/images.qrc @@ -170,6 +170,7 @@ themes/default/mActionDistributeTop.svg themes/default/mActionDistributeVCenter.svg themes/default/mActionAddLayer.svg + themes/default/mActionAddMeshLayer.svg themes/default/mActionAddAllToOverview.svg themes/default/mActionAddArrow.svg themes/default/mActionAddBasicShape.svg diff --git a/images/themes/default/mActionAddMeshLayer.svg b/images/themes/default/mActionAddMeshLayer.svg new file mode 100644 index 00000000000..ad8020e5460 --- /dev/null +++ b/images/themes/default/mActionAddMeshLayer.svg @@ -0,0 +1,106 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/python/gui/auto_generated/qgsabstractdatasourcewidget.sip.in b/python/gui/auto_generated/qgsabstractdatasourcewidget.sip.in index 526c7766025..af705c958e3 100644 --- a/python/gui/auto_generated/qgsabstractdatasourcewidget.sip.in +++ b/python/gui/auto_generated/qgsabstractdatasourcewidget.sip.in @@ -74,6 +74,13 @@ Emitted when a vector layer has been selected for addition. If ``providerKey`` is not specified, the default provider key associated with the source will be used. +%End + + void addMeshLayer( const QString &uri, const QString &providerKey ); +%Docstring +Emitted when a mesh layer has been selected for addition. + +.. versionadded:: 3.4 %End void addVectorLayers( const QStringList &layerList, const QString &encoding, const QString &dataSourceType ); diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 88a677150fe..5d6699b0ddc 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -1765,6 +1765,7 @@ void QgisApp::dataSourceManager( const QString &pageName ) this, SLOT( addVectorLayer( QString const &, QString const &, QString const & ) ) ); connect( mDataSourceManagerDialog, SIGNAL( addVectorLayers( QStringList const &, QString const &, QString const & ) ), this, SLOT( addVectorLayers( QStringList const &, QString const &, QString const & ) ) ); + connect( mDataSourceManagerDialog, &QgsDataSourceManagerDialog::addMeshLayer, this, &QgisApp::addMeshLayer ); connect( mDataSourceManagerDialog, &QgsDataSourceManagerDialog::showProgress, this, &QgisApp::showProgress ); connect( mDataSourceManagerDialog, &QgsDataSourceManagerDialog::showStatusMessage, this, &QgisApp::showStatusMessage ); connect( mDataSourceManagerDialog, &QgsDataSourceManagerDialog::addDatabaseLayers, this, &QgisApp::addDatabaseLayers ); @@ -4484,6 +4485,54 @@ bool QgisApp::addVectorLayers( const QStringList &layerQStringList, const QStrin return true; } // QgisApp::addVectorLayer() + +bool QgisApp::addMeshLayer( const QString &uri, const QString &providerKey ) +{ + bool wasfrozen = mMapCanvas->isFrozen(); + QgsSettings settings; + + QFileInfo fi( uri ); + QString base = fi.completeBaseName(); + + if ( settings.value( QStringLiteral( "qgis/formatLayerName" ), false ).toBool() ) + { + base = QgsMapLayer::formatLayerName( base ); + } + + QgsDebugMsg( "completeBaseName: " + base ); + + // create the layer + QgsMeshLayer::LayerOptions options; + std::unique_ptr layer( new QgsMeshLayer( uri, base, providerKey, options ) ); + + if ( ! layer || !layer->isValid() ) + { + QString msg = tr( "%1 is not a valid or recognized data source." ).arg( uri ); + messageBar()->pushMessage( tr( "Invalid Data Source" ), msg, Qgis::Critical, messageTimeout() ); + + // since the layer is bad, stomp on it + return false; + } + + // Register this layer with the layers registry + freezeCanvases(); + bool ok; + layer->loadDefaultStyle( ok ); + layer->loadDefaultMetadata( ok ); + QgsProject::instance()->addMapLayer( layer.release() ); + + activateDeactivateLayerRelatedActions( activeLayer() ); + + // Only update the map if we frozen in this method + // Let the caller do it otherwise + if ( !wasfrozen ) + { + freezeCanvases( false ); + refreshMapCanvas(); + } + return true; +} // QgisApp::addMeshLayer() + // present a dialog to choose zipitem layers bool QgisApp::askUserForZipItemLayers( const QString &path ) { diff --git a/src/app/qgisapp.h b/src/app/qgisapp.h index faa1631fa9f..82949d64eec 100644 --- a/src/app/qgisapp.h +++ b/src/app/qgisapp.h @@ -922,6 +922,12 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow */ bool addRasterLayers( const QStringList &layerQStringList, bool guiWarning = true ); + /** + * Adds a mesh layer directly without prompting user for location + * \returns true if successfully added layer + */ + bool addMeshLayer( const QString &uri, const QString &providerKey ); + //! Open a plugin layer using its provider QgsPluginLayer *addPluginLayer( const QString &uri, const QString &baseName, const QString &providerKey ); diff --git a/src/gui/qgsabstractdatasourcewidget.h b/src/gui/qgsabstractdatasourcewidget.h index c25bb3e4557..c9a136e8d83 100644 --- a/src/gui/qgsabstractdatasourcewidget.h +++ b/src/gui/qgsabstractdatasourcewidget.h @@ -89,6 +89,12 @@ class GUI_EXPORT QgsAbstractDataSourceWidget : public QDialog */ void addVectorLayer( const QString &uri, const QString &layerName, const QString &providerKey = QString() ); + /** + * Emitted when a mesh layer has been selected for addition. + * \since QGIS 3.4 + */ + void addMeshLayer( const QString &uri, const QString &providerKey ); + /** * Emitted when one or more OGR supported layers are selected for addition * \param layerList list of layers protocol URIs diff --git a/src/gui/qgsdatasourcemanagerdialog.cpp b/src/gui/qgsdatasourcemanagerdialog.cpp index efd3cd53104..b4b471433b0 100644 --- a/src/gui/qgsdatasourcemanagerdialog.cpp +++ b/src/gui/qgsdatasourcemanagerdialog.cpp @@ -161,6 +161,8 @@ void QgsDataSourceManagerDialog::makeConnections( QgsAbstractDataSourceWidget *d // Raster connect( dlg, SIGNAL( addRasterLayer( QString const &, QString const &, QString const & ) ), this, SIGNAL( addRasterLayer( QString const &, QString const &, QString const & ) ) ); + // Mesh + connect( dlg, &QgsAbstractDataSourceWidget::addMeshLayer, this, &QgsDataSourceManagerDialog::addMeshLayer ); // Virtual connect( dlg, SIGNAL( replaceVectorLayer( QString, QString, QString, QString ) ), diff --git a/src/gui/qgsdatasourcemanagerdialog.h b/src/gui/qgsdatasourcemanagerdialog.h index 81a2bbf2c07..51c2444f12f 100644 --- a/src/gui/qgsdatasourcemanagerdialog.h +++ b/src/gui/qgsdatasourcemanagerdialog.h @@ -95,6 +95,11 @@ class GUI_EXPORT QgsDataSourceManagerDialog : public QgsOptionsDialogBase, priva void addRasterLayer(); //! Emitted when a vector layer was selected for addition: for signal forwarding to QgisApp void addVectorLayer( const QString &vectorLayerPath, const QString &baseName, const QString &providerKey ); + /* + * Emitted when a mesh layer was selected for addition: for signal forwarding to QgisApp\ + * \since QGIS 3.4 + */ + void addMeshLayer( const QString &uri, const QString &providerKey ); //! Replace the selected layer by a vector layer defined by uri, layer name, data source uri void replaceSelectedVectorLayer( const QString &oldId, const QString &uri, const QString &layerName, const QString &provider ); //! Emitted when a one or more layer were selected for addition: for signal forwarding to QgisApp diff --git a/src/providers/mdal/CMakeLists.txt b/src/providers/mdal/CMakeLists.txt index 7d0f66cf15e..8fb22ea4e96 100644 --- a/src/providers/mdal/CMakeLists.txt +++ b/src/providers/mdal/CMakeLists.txt @@ -9,6 +9,14 @@ SET(MDAL_MOC_HDRS SET(MDAL_HDRS ) +IF (WITH_GUI) + SET(MDAL_SRCS ${MDAL_SRCS} + qgsmdalsourceselect.cpp + ) + SET(MDAL_MOC_HDRS ${MDAL_MOC_HDRS} + qgsmdalsourceselect.h + ) +ENDIF () ######################################################## # Compile internal MDAL @@ -58,8 +66,13 @@ INCLUDE_DIRECTORIES ( ${CMAKE_SOURCE_DIR}/src/core/expression ${CMAKE_SOURCE_DIR}/src/core/geometry ${CMAKE_SOURCE_DIR}/src/core/metadata + ${CMAKE_SOURCE_DIR}/src/gui + ${CMAKE_SOURCE_DIR}/src/gui/auth ${CMAKE_BINARY_DIR}/src/core + ${CMAKE_BINARY_DIR}/src/gui + ${CMAKE_BINARY_DIR}/src/ui + ) QT5_WRAP_CPP(MDAL_MOC_SRCS ${MDAL_MOC_HDRS}) @@ -70,6 +83,12 @@ TARGET_LINK_LIBRARIES (mdalprovider ${MDAL_LIBRARY} ) +IF (WITH_GUI) + TARGET_LINK_LIBRARIES (mdalprovider + qgis_gui + ) +ENDIF () + # clang-tidy IF(CLANG_TIDY_EXE) SET_TARGET_PROPERTIES( diff --git a/src/providers/mdal/qgsmdalprovider.cpp b/src/providers/mdal/qgsmdalprovider.cpp index 234ef8e94ae..91efb19cad1 100644 --- a/src/providers/mdal/qgsmdalprovider.cpp +++ b/src/providers/mdal/qgsmdalprovider.cpp @@ -19,6 +19,11 @@ #include "qgsmdalprovider.h" +#ifdef HAVE_GUI +#include "qgssourceselectprovider.h" +#include "qgsmdalsourceselect.h" +#endif + static const QString TEXT_PROVIDER_KEY = QStringLiteral( "mdal" ); static const QString TEXT_PROVIDER_DESCRIPTION = QStringLiteral( "MDAL provider" ); @@ -229,3 +234,32 @@ QGISEXTERN void cleanupProvider() { } +#ifdef HAVE_GUI + +//! Provider for mdal mesh source select +class QgsMdalMeshSourceSelectProvider : public QgsSourceSelectProvider +{ + public: + + QString providerKey() const override { return QStringLiteral( "mdal" ); } + QString text() const override { return QObject::tr( "Mesh" ); } + int ordering() const override { return QgsSourceSelectProvider::OrderLocalProvider + 22; } + QIcon icon() const override { return QgsApplication::getThemeIcon( QStringLiteral( "/mActionAddMeshLayer.svg" ) ); } + QgsAbstractDataSourceWidget *createDataSourceWidget( QWidget *parent = nullptr, Qt::WindowFlags fl = Qt::Widget, QgsProviderRegistry::WidgetMode widgetMode = QgsProviderRegistry::WidgetMode::Embedded ) const override + { + return new QgsMdalSourceSelect( parent, fl, widgetMode ); + } +}; + + +QGISEXTERN QList *sourceSelectProviders() +{ + QList *providers = new QList(); + + *providers + << new QgsMdalMeshSourceSelectProvider; + + return providers; +} + +#endif diff --git a/src/providers/mdal/qgsmdalsourceselect.cpp b/src/providers/mdal/qgsmdalsourceselect.cpp new file mode 100644 index 00000000000..debbe3d31a5 --- /dev/null +++ b/src/providers/mdal/qgsmdalsourceselect.cpp @@ -0,0 +1,59 @@ +/*************************************************************************** + qgsmdalsourceselect.cpp + ----------------------- + begin : July 2018 + copyright : (C) 2018 by Peter Petrik + email : zilolv at gmail dot com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 + +#include "qgsmdalsourceselect.h" +#include "qgsproviderregistry.h" +#include "ogr/qgsogrhelperfunctions.h" + +QgsMdalSourceSelect::QgsMdalSourceSelect( QWidget *parent, Qt::WindowFlags fl, QgsProviderRegistry::WidgetMode widgetMode ): + QgsAbstractDataSourceWidget( parent, fl, widgetMode ) +{ + setupUi( this ); + setupButtons( buttonBox ); + + mFileWidget->setDialogTitle( tr( "Open MDAL Supported Mesh Dataset(s)" ) ); + mFileWidget->setFilter( QStringLiteral( "Mesh File (*.2dm);;All files (*.*)" ) ); + mFileWidget->setStorageMode( QgsFileWidget::GetMultipleFiles ); + connect( mFileWidget, &QgsFileWidget::fileChanged, this, [ = ]( const QString & path ) + { + mMeshPath = path; + emit enableButtons( ! mMeshPath.isEmpty() ); + } ); +} + +void QgsMdalSourceSelect::addButtonClicked() +{ + if ( mMeshPath.isEmpty() ) + { + QMessageBox::information( this, + tr( "Add mesh layer" ), + tr( "No layers selected." ) ); + return; + } + + for ( const QString &path : QgsFileWidget::splitFilePaths( mMeshPath ) ) + { + emit addMeshLayer( path, QStringLiteral( "mdal" ) ); + } +} + +QGISEXTERN QgsMdalSourceSelect *selectWidget( QWidget *parent, Qt::WindowFlags fl, QgsProviderRegistry::WidgetMode widgetMode ) +{ + return new QgsMdalSourceSelect( parent, fl, widgetMode ); +} diff --git a/src/providers/mdal/qgsmdalsourceselect.h b/src/providers/mdal/qgsmdalsourceselect.h new file mode 100644 index 00000000000..c4eea3deb7f --- /dev/null +++ b/src/providers/mdal/qgsmdalsourceselect.h @@ -0,0 +1,46 @@ +/*************************************************************************** + qgsmdalsourceselect.h + ------------------- + begin : July 2018 + copyright : (C) 2018 by Peter Petrik + email : zilolv at gmail dot com + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 QGMDALSOURCESELECT_H +#define QGMDALSOURCESELECT_H + +#include "ui_qgsmdalsourceselectbase.h" +#include "qgsabstractdatasourcewidget.h" +#include "qgis_gui.h" + + +/** + * \class QgsMdalSourceSelect + * \brief Dialog to select MDAL supported mesh sources + */ +class QgsMdalSourceSelect : public QgsAbstractDataSourceWidget, private Ui::QgsMdalSourceSelectBase +{ + Q_OBJECT + + public: + //! Constructor + QgsMdalSourceSelect( QWidget *parent = nullptr, Qt::WindowFlags fl = QgsGuiUtils::ModalDialogFlags, QgsProviderRegistry::WidgetMode widgetMode = QgsProviderRegistry::WidgetMode::None ); + + public slots: + //! Determines the tables the user selected and closes the dialog + void addButtonClicked() override; + + private: + QString mMeshPath; + +}; + +#endif // QGMDALSOURCESELECT_H diff --git a/src/ui/mesh/qgsmdalsourceselectbase.ui b/src/ui/mesh/qgsmdalsourceselectbase.ui new file mode 100644 index 00000000000..baca36d6b7a --- /dev/null +++ b/src/ui/mesh/qgsmdalsourceselectbase.ui @@ -0,0 +1,108 @@ + + + QgsMdalSourceSelectBase + + + + 0 + 0 + 351 + 115 + + + + Add Mesh Layer(s) + + + + .. + + + true + + + true + + + + + + + + + 0 + 0 + + + + Source + + + + + + Mesh dataset + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + QDialogButtonBox::NoButton + + + + + + + + + QgsFileWidget + QWidget +
qgsfilewidget.h
+
+
+ + buttonBox + + + + + buttonBox + rejected() + QgsMdalSourceSelectBase + reject() + + + 518 + 510 + + + 551 + 370 + + + + +