From 104e059a468ea49660b24ae9061d34d73cbffea3 Mon Sep 17 00:00:00 2001 From: Peter Petrik Date: Mon, 11 Jun 2018 17:41:48 +0200 Subject: [PATCH 01/13] [mesh] Style contours/scalars in GUI --- .../mesh/qgsmeshrenderersettings.sip.in | 47 +- .../raster/qgscolorrampshader.sip.in | 5 + ...singlebandpseudocolorrendererwidget.sip.in | 10 + src/app/CMakeLists.txt | 3 + src/app/qgslayerstylingwidget.cpp | 34 +- src/app/qgslayerstylingwidget.h | 2 + src/core/mesh/qgsmeshlayerrenderer.cpp | 38 +- src/core/mesh/qgsmeshrenderersettings.cpp | 33 +- src/core/mesh/qgsmeshrenderersettings.h | 53 +- src/core/mesh/qgsmeshvectorrenderer.cpp | 4 +- src/core/raster/qgscolorrampshader.cpp | 12 + src/core/raster/qgscolorrampshader.h | 3 + src/gui/CMakeLists.txt | 9 + .../qgsmeshrendererscalarsettingswidget.cpp | 174 ++++ .../qgsmeshrendererscalarsettingswidget.h | 71 ++ .../mesh/qgsrenderermeshpropertieswidget.cpp | 54 + .../mesh/qgsrenderermeshpropertieswidget.h | 56 ++ src/gui/raster/qgscolorrampshaderwidget.cpp | 921 ++++++++++++++++++ src/gui/raster/qgscolorrampshaderwidget.h | 134 +++ ...qgssinglebandpseudocolorrendererwidget.cpp | 15 +- .../qgssinglebandpseudocolorrendererwidget.h | 6 + src/ui/CMakeLists.txt | 2 + ...qgsmeshrendererscalarsettingswidgetbase.ui | 103 ++ src/ui/mesh/qgsrenderermeshpropswidgetbase.ui | 102 ++ src/ui/qgscolorrampshaderwidgetbase.ui | 322 ++++++ src/ui/raster/qgscolorrampshaderwidgetbase.ui | 294 ++++++ 26 files changed, 2380 insertions(+), 127 deletions(-) create mode 100644 src/gui/mesh/qgsmeshrendererscalarsettingswidget.cpp create mode 100644 src/gui/mesh/qgsmeshrendererscalarsettingswidget.h create mode 100644 src/gui/mesh/qgsrenderermeshpropertieswidget.cpp create mode 100644 src/gui/mesh/qgsrenderermeshpropertieswidget.h create mode 100644 src/gui/raster/qgscolorrampshaderwidget.cpp create mode 100644 src/gui/raster/qgscolorrampshaderwidget.h create mode 100644 src/ui/mesh/qgsmeshrendererscalarsettingswidgetbase.ui create mode 100644 src/ui/mesh/qgsrenderermeshpropswidgetbase.ui create mode 100644 src/ui/qgscolorrampshaderwidgetbase.ui create mode 100644 src/ui/raster/qgscolorrampshaderwidgetbase.ui diff --git a/python/core/auto_generated/mesh/qgsmeshrenderersettings.sip.in b/python/core/auto_generated/mesh/qgsmeshrenderersettings.sip.in index 5faeb0c51966..0d76438b81c0 100644 --- a/python/core/auto_generated/mesh/qgsmeshrenderersettings.sip.in +++ b/python/core/auto_generated/mesh/qgsmeshrenderersettings.sip.in @@ -10,6 +10,7 @@ + class QgsMeshRendererMeshSettings { %Docstring @@ -73,52 +74,22 @@ Represents a mesh renderer settings for scalar datasets #include "qgsmeshrenderersettings.h" %End public: - QColor maxColor() const; + QgsColorRampShader *colorRampShader() const; %Docstring -Returns color representing maximum scalar value in the dataset +Returns color ramp shader function. %End - void setMaxColor( const QColor &maxColor ); + void setColorRampShader( QgsColorRampShader *shader ); %Docstring -Sets color representing maximum scalar value in the dataset +Sets color ramp shader function. Takes ownership %End - QColor minColor() const; + QgsRasterMinMaxOrigin minMaxOrigin() const; %Docstring -Returns color representing minimum scalar value in the dataset +Returns raster min max origin %End - void setMinColor( const QColor &minColor ); + void setMinMaxOrigin( const QgsRasterMinMaxOrigin &minMaxOrigin ); %Docstring -Sets color representing maximum scalar value in the dataset -%End - - double minValue() const; -%Docstring -Returns min scalar value that represents minColor() - -if set to numerical_limits.quiet_NaN(), value for minColor() is -taken from minimum value of active scalar dataset -%End - - void setMinValue( double minValue ); -%Docstring -Sets min scalar value that represents minColor() - -.. seealso:: :py:func:`QgsMeshRendererScalarSettings.minValue` -%End - - double maxValue() const; -%Docstring -Returns max scalar value that represents maxColor() - -if set to numerical_limits.quiet_NaN(), value for maxColor() is -taken from maximum value of active scalar dataset -%End - - void setMaxValue( double maxValue ); -%Docstring -Sets min scalar value that represents minColor() - -.. seealso:: :py:func:`QgsMeshRendererScalarSettings.maxValue` +Sets raster min max origin %End }; diff --git a/python/core/auto_generated/raster/qgscolorrampshader.sip.in b/python/core/auto_generated/raster/qgscolorrampshader.sip.in index 45fd0bd703b0..45c49148b052 100644 --- a/python/core/auto_generated/raster/qgscolorrampshader.sip.in +++ b/python/core/auto_generated/raster/qgscolorrampshader.sip.in @@ -54,6 +54,11 @@ Copy constructor %End + QgsColorRampShader *clone() const /Factory/; +%Docstring +Clones this shader, return new instance +%End + struct ColorRampItem { ColorRampItem(); diff --git a/python/gui/auto_generated/raster/qgssinglebandpseudocolorrendererwidget.sip.in b/python/gui/auto_generated/raster/qgssinglebandpseudocolorrendererwidget.sip.in index f4fcc8729100..38c7e77a1574 100644 --- a/python/gui/auto_generated/raster/qgssinglebandpseudocolorrendererwidget.sip.in +++ b/python/gui/auto_generated/raster/qgssinglebandpseudocolorrendererwidget.sip.in @@ -23,12 +23,22 @@ class QgsSingleBandPseudoColorRendererWidget: QgsRasterRendererWidget static QgsRasterRendererWidget *create( QgsRasterLayer *layer, const QgsRectangle &extent ) /Factory/; virtual QgsRasterRenderer *renderer(); + + QgsColorRampShader *shaderFunction() const; +%Docstring +Returns shared function used in the renderer. Caller takes ownership and deletes it. +%End virtual void setMapCanvas( QgsMapCanvas *canvas ); virtual void doComputations(); virtual QgsRasterMinMaxWidget *minMaxWidget(); + int currentBand() const; +%Docstring +Returns the current raster band number +%End + void setFromRenderer( const QgsRasterRenderer *r ); public slots: diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index fb6b0a9f6aec..98ff8693188e 100755 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -607,6 +607,7 @@ INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/src/gui/ogr ${CMAKE_SOURCE_DIR}/src/gui/processing ${CMAKE_SOURCE_DIR}/src/gui/raster + ${CMAKE_SOURCE_DIR}/src/gui/mesh ${CMAKE_SOURCE_DIR}/src/gui/editorwidgets ${CMAKE_SOURCE_DIR}/src/gui/editorwidgets/core ${CMAKE_SOURCE_DIR}/src/gui/layertree @@ -658,6 +659,7 @@ INCLUDE_DIRECTORIES( ../core/processing ../core/providers/memory ../core/raster + ../core/mesh ../core/scalebar ../core/symbology ../gui @@ -666,6 +668,7 @@ INCLUDE_DIRECTORIES( ../gui/auth ../gui/ogr ../gui/raster + ../gui/mesh ../gui/editorwidgets ../gui/editorwidgets/core ../gui/layertree diff --git a/src/app/qgslayerstylingwidget.cpp b/src/app/qgslayerstylingwidget.cpp index 309b8bf1e707..6ad642870543 100644 --- a/src/app/qgslayerstylingwidget.cpp +++ b/src/app/qgslayerstylingwidget.cpp @@ -26,6 +26,7 @@ #include "qgsrastertransparencywidget.h" #include "qgsrendererpropertiesdialog.h" #include "qgsrendererrasterpropertieswidget.h" +#include "qgsrenderermeshpropertieswidget.h" #include "qgsrasterhistogramwidget.h" #include "qgsrasterrenderer.h" #include "qgsrasterrendererwidget.h" @@ -33,6 +34,7 @@ #include "qgsmaplayer.h" #include "qgsstyle.h" #include "qgsvectorlayer.h" +#include "qgsmeshlayer.h" #include "qgsproject.h" #include "qgsundowidget.h" #include "qgsreadwritecontext.h" @@ -189,6 +191,13 @@ void QgsLayerStylingWidget::setLayer( QgsMapLayer *layer ) histogramItem->setToolTip( tr( "Histogram" ) ); } } + else if ( layer->type() == QgsMapLayer::MeshLayer ) + { + QListWidgetItem *symbolItem = new QListWidgetItem( QgsApplication::getThemeIcon( QStringLiteral( "propertyicons/symbology.svg" ) ), QString() ); + symbolItem->setData( Qt::UserRole, Symbology ); + symbolItem->setToolTip( tr( "Symbology" ) ); + mOptionsListWidget->addItem( symbolItem ); + } Q_FOREACH ( QgsMapLayerConfigWidgetFactory *factory, mPageFactories ) { @@ -335,7 +344,10 @@ void QgsLayerStylingWidget::updateCurrentWidgetLayer() mVector3DWidget = widget; } #endif - + else if ( QgsRendererMeshPropertiesWidget *widget = qobject_cast( current ) ) + { + mMeshStyleWidget = widget; + } } mWidgetStack->clear(); @@ -481,6 +493,24 @@ void QgsLayerStylingWidget::updateCurrentWidgetLayer() break; } } + else if ( mCurrentLayer->type() == QgsMapLayer::MeshLayer ) + { + QgsMeshLayer *rlayer = qobject_cast( mCurrentLayer ); + switch ( row ) + { + case 0: // Style + { + mMeshStyleWidget = new QgsRendererMeshPropertiesWidget( rlayer, mMapCanvas, mWidgetStack ); + + mMeshStyleWidget->setDockMode( true ); + connect( mMeshStyleWidget, &QgsPanelWidget::widgetChanged, this, &QgsLayerStylingWidget::autoApply ); + mWidgetStack->setMainPanel( mMeshStyleWidget ); + break; + } + default: + break; + } + } else { mStackedWidget->setCurrentIndex( mNotSupportedPage ); @@ -591,5 +621,5 @@ QgsMapLayerConfigWidget *QgsLayerStyleManagerWidgetFactory::createWidget( QgsMap bool QgsLayerStyleManagerWidgetFactory::supportsLayer( QgsMapLayer *layer ) const { - return ( layer->type() == QgsMapLayer::VectorLayer || layer->type() == QgsMapLayer::RasterLayer ); + return ( layer->type() == QgsMapLayer::VectorLayer || layer->type() == QgsMapLayer::RasterLayer || layer->type() == QgsMapLayer::MeshLayer ); } diff --git a/src/app/qgslayerstylingwidget.h b/src/app/qgslayerstylingwidget.h index 3903349be4cb..dd07b6dfc157 100644 --- a/src/app/qgslayerstylingwidget.h +++ b/src/app/qgslayerstylingwidget.h @@ -36,6 +36,7 @@ class QgsMapLayer; class QgsMapCanvas; class QgsRendererPropertiesDialog; class QgsRendererRasterPropertiesWidget; +class QgsRendererMeshPropertiesWidget; class QgsUndoWidget; class QgsRasterHistogramWidget; class QgsMapLayerStyleManagerWidget; @@ -140,6 +141,7 @@ class APP_EXPORT QgsLayerStylingWidget : public QWidget, private Ui::QgsLayerSty QgsVectorLayer3DRendererWidget *mVector3DWidget = nullptr; #endif QgsRendererRasterPropertiesWidget *mRasterStyleWidget = nullptr; + QgsRendererMeshPropertiesWidget *mMeshStyleWidget = nullptr; QList mPageFactories; QMap mUserPages; QgsLayerStyleManagerWidgetFactory *mStyleManagerFactory = nullptr; diff --git a/src/core/mesh/qgsmeshlayerrenderer.cpp b/src/core/mesh/qgsmeshlayerrenderer.cpp index c9b7104181b4..fac71e1882d3 100644 --- a/src/core/mesh/qgsmeshlayerrenderer.cpp +++ b/src/core/mesh/qgsmeshlayerrenderer.cpp @@ -203,29 +203,33 @@ void QgsMeshLayerRenderer::renderMesh( const std::unique_ptr &symbol, void QgsMeshLayerRenderer::renderScalarDataset() { if ( mScalarDatasetValues.isEmpty() ) - return; - - // do not render if magnitude is outside of the filtered range (if filtering is enabled) - double vMin = mRendererScalarSettings.minValue(); - if ( std::isnan( vMin ) ) - vMin = *std::min_element( mScalarDatasetValues.constBegin(), mScalarDatasetValues.constEnd() ); + return; // activeScalarDataset == NO_ACTIVE_MESH_DATASET + QgsColorRampShader *fcn; + if ( mRendererScalarSettings.colorRampShader() ) + fcn = mRendererScalarSettings.colorRampShader()->clone(); + else + { + double vMin = *std::min_element( mScalarDatasetValues.constBegin(), mScalarDatasetValues.constEnd() ); + double vMax = *std::max_element( mScalarDatasetValues.constBegin(), mScalarDatasetValues.constEnd() ); - double vMax = mRendererScalarSettings.maxValue(); - if ( std::isnan( vMax ) ) - vMax = *std::max_element( mScalarDatasetValues.constBegin(), mScalarDatasetValues.constEnd() ); + QList lst; + lst << QgsColorRampShader::ColorRampItem( vMin, Qt::blue, QString::number( vMin ) ); + lst << QgsColorRampShader::ColorRampItem( vMax, Qt::red, QString::number( vMax ) ); - QList lst; - lst << QgsColorRampShader::ColorRampItem( vMin, mRendererScalarSettings.minColor(), QString::number( vMin ) ); - lst << QgsColorRampShader::ColorRampItem( vMax, mRendererScalarSettings.maxColor(), QString::number( vMax ) ); + fcn = new QgsColorRampShader( vMin, vMax ); + fcn->setColorRampItemList( lst ); + } - QgsColorRampShader *fcn = new QgsColorRampShader( vMin, vMax ); - fcn->setColorRampItemList( lst ); - QgsRasterShader *sh = new QgsRasterShader( vMin, vMax ); + QgsRasterShader *sh = new QgsRasterShader(); sh->setRasterShaderFunction( fcn ); // takes ownership of fcn QgsMeshLayerInterpolator interpolator( mTriangularMesh, mScalarDatasetValues, mScalarDataOnVertices, mContext, mOutputSize ); - QgsSingleBandPseudoColorRenderer r( &interpolator, 0, sh ); // takes ownership of sh - std::unique_ptr bl( r.block( 0, mContext.extent(), mOutputSize.width(), mOutputSize.height(), mFeedback.get() ) ); + QgsSingleBandPseudoColorRenderer renderer( &interpolator, 0, sh ); // takes ownership of sh + renderer.setClassificationMin( fcn->minimumValue() ); + renderer.setClassificationMax( fcn->maximumValue() ); + renderer.setMinMaxOrigin( mRendererScalarSettings.minMaxOrigin() ); + + std::unique_ptr bl( renderer.block( 0, mContext.extent(), mOutputSize.width(), mOutputSize.height(), mFeedback.get() ) ); QImage img = bl->image(); mContext.painter()->drawImage( 0, 0, img ); diff --git a/src/core/mesh/qgsmeshrenderersettings.cpp b/src/core/mesh/qgsmeshrenderersettings.cpp index b76e2da76dc1..d3ce87cc6243 100644 --- a/src/core/mesh/qgsmeshrenderersettings.cpp +++ b/src/core/mesh/qgsmeshrenderersettings.cpp @@ -47,44 +47,27 @@ void QgsMeshRendererMeshSettings::setColor( const QColor &color ) mColor = color; } -QColor QgsMeshRendererScalarSettings::maxColor() const -{ - return mMaxColor; -} -void QgsMeshRendererScalarSettings::setMaxColor( const QColor &maxColor ) +QgsColorRampShader *QgsMeshRendererScalarSettings::colorRampShader() const { - mMaxColor = maxColor; -} + return mColorRampShader.get(); -QColor QgsMeshRendererScalarSettings::minColor() const -{ - return mMinColor; } -void QgsMeshRendererScalarSettings::setMinColor( const QColor &minColor ) +void QgsMeshRendererScalarSettings::setColorRampShader( QgsColorRampShader *shader ) { - mMinColor = minColor; + mColorRampShader.reset( shader ); } -double QgsMeshRendererScalarSettings::minValue() const -{ - return mMinValue; -} - -void QgsMeshRendererScalarSettings::setMinValue( double minValue ) -{ - mMinValue = minValue; -} -double QgsMeshRendererScalarSettings::maxValue() const +QgsRasterMinMaxOrigin QgsMeshRendererScalarSettings::minMaxOrigin() const { - return mMaxValue; + return mRasterMinMaxOrigin; } -void QgsMeshRendererScalarSettings::setMaxValue( double maxValue ) +void QgsMeshRendererScalarSettings::setMinMaxOrigin( const QgsRasterMinMaxOrigin &minMaxOrigin ) { - mMaxValue = maxValue; + mRasterMinMaxOrigin = minMaxOrigin; } double QgsMeshRendererVectorSettings::lineWidth() const diff --git a/src/core/mesh/qgsmeshrenderersettings.h b/src/core/mesh/qgsmeshrenderersettings.h index e8a97ffbee40..e2cadbe2fb0f 100644 --- a/src/core/mesh/qgsmeshrenderersettings.h +++ b/src/core/mesh/qgsmeshrenderersettings.h @@ -23,6 +23,9 @@ #include "qgis_core.h" #include "qgis.h" +#include "qgscolorrampshader.h" +#include "qgsrasterminmaxorigin.h" + /** * \ingroup core @@ -69,49 +72,19 @@ class CORE_EXPORT QgsMeshRendererMeshSettings class CORE_EXPORT QgsMeshRendererScalarSettings { public: - //! Returns color representing maximum scalar value in the dataset - QColor maxColor() const; - //! Sets color representing maximum scalar value in the dataset - void setMaxColor( const QColor &maxColor ); - - //! Returns color representing minimum scalar value in the dataset - QColor minColor() const; - //! Sets color representing maximum scalar value in the dataset - void setMinColor( const QColor &minColor ); - - /** - * Returns min scalar value that represents minColor() - * - * if set to numerical_limits::quiet_NaN(), value for minColor() is - * taken from minimum value of active scalar dataset - */ - double minValue() const; + //! Returns color ramp shader function. + QgsColorRampShader *colorRampShader() const; + //! Sets color ramp shader function. Takes ownership + void setColorRampShader( QgsColorRampShader *shader ); - /** - * Sets min scalar value that represents minColor() - * \see QgsMeshRendererScalarSettings::minValue() - */ - void setMinValue( double minValue ); - - /** - * Returns max scalar value that represents maxColor() - * - * if set to numerical_limits::quiet_NaN(), value for maxColor() is - * taken from maximum value of active scalar dataset - */ - double maxValue() const; - - /** - * Sets min scalar value that represents minColor() - * \see QgsMeshRendererScalarSettings::maxValue() - */ - void setMaxValue( double maxValue ); + //! Returns raster min max origin + QgsRasterMinMaxOrigin minMaxOrigin() const; + //! Sets raster min max origin + void setMinMaxOrigin( const QgsRasterMinMaxOrigin &minMaxOrigin ); private: - QColor mMaxColor = QColor::fromRgb( 255, 0, 0 ); - QColor mMinColor = QColor::fromRgb( 0, 0, 255 ); - double mMaxValue = std::numeric_limits::quiet_NaN(); //disabled - double mMinValue = std::numeric_limits::quiet_NaN(); //disabled + std::shared_ptr mColorRampShader; + QgsRasterMinMaxOrigin mRasterMinMaxOrigin; }; /** diff --git a/src/core/mesh/qgsmeshvectorrenderer.cpp b/src/core/mesh/qgsmeshvectorrenderer.cpp index 4607a6d75bb7..84f8593b48a9 100644 --- a/src/core/mesh/qgsmeshvectorrenderer.cpp +++ b/src/core/mesh/qgsmeshvectorrenderer.cpp @@ -56,11 +56,11 @@ QgsMeshVectorRenderer::QgsMeshVectorRenderer( const QgsTriangularMesh &m, , mOutputSize( size ) { auto bounds = std::minmax_element( mDatasetValuesX.constBegin(), mDatasetValuesX.constEnd() ); - mMinX = *bounds.first; + mMinX = *bounds.first; //TODO del mMaxX = *bounds.second; bounds = std::minmax_element( mDatasetValuesY.constBegin(), mDatasetValuesY.constEnd() ); - mMinY = *bounds.first; + mMinY = *bounds.first; //TODO del mMaxY = *bounds.second; bounds = std::minmax_element( mDatasetValuesMag.constBegin(), mDatasetValuesMag.constEnd() ); diff --git a/src/core/raster/qgscolorrampshader.cpp b/src/core/raster/qgscolorrampshader.cpp index ac4d5a7cbc54..902db7cd7d31 100644 --- a/src/core/raster/qgscolorrampshader.cpp +++ b/src/core/raster/qgscolorrampshader.cpp @@ -66,6 +66,18 @@ QgsColorRampShader &QgsColorRampShader::operator=( const QgsColorRampShader &oth return *this; } +QgsColorRampShader *QgsColorRampShader::clone() const +{ + QgsColorRampShader *s = new QgsColorRampShader( + mMinimumValue, + mMaximumValue, + mSourceColorRamp->clone(), + mColorRampType, + mClassificationMode ); + s->setColorRampItemList( colorRampItemList() ); //TODO?? why it is not copied in operator=? + return s; +} + QString QgsColorRampShader::colorRampTypeAsQString() { switch ( mColorRampType ) diff --git a/src/core/raster/qgscolorrampshader.h b/src/core/raster/qgscolorrampshader.h index 3aa047eafd1b..03c83fe4dc8b 100644 --- a/src/core/raster/qgscolorrampshader.h +++ b/src/core/raster/qgscolorrampshader.h @@ -78,6 +78,9 @@ class CORE_EXPORT QgsColorRampShader : public QgsRasterShaderFunction */ QgsColorRampShader &operator=( const QgsColorRampShader &other ); + //! Clones this shader, return new instance + QgsColorRampShader *clone() const SIP_FACTORY; + //An entry for classification based upon value. //Such a classification is typically used for //single band layers where a pixel value represents diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 957c67f1b2c3..12ab6a05e6ee 100755 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -1,4 +1,8 @@ SET(QGIS_GUI_SRCS + mesh/qgsrenderermeshpropertieswidget.cpp + mesh/qgsmeshrendererscalarsettingswidget.cpp + + raster/qgscolorrampshaderwidget.cpp raster/qgsmultibandcolorrendererwidget.cpp raster/qgspalettedrendererwidget.cpp raster/qgsrasterbandcombobox.cpp @@ -541,6 +545,10 @@ SET(QGIS_GUI_MOC_HDRS ogr/qgsnewogrconnection.h ogr/qgsvectorlayersaveasdialog.h + mesh/qgsrenderermeshpropertieswidget.h + mesh/qgsmeshrendererscalarsettingswidget.h + + raster/qgscolorrampshaderwidget.h raster/qgsmultibandcolorrendererwidget.h raster/qgspalettedrendererwidget.h raster/qgsrasterbandcombobox.h @@ -878,6 +886,7 @@ INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/src/gui/effects ${CMAKE_SOURCE_DIR}/src/gui/layertree ${CMAKE_SOURCE_DIR}/src/gui/layout + ${CMAKE_SOURCE_DIR}/src/gui/mesh ${CMAKE_SOURCE_DIR}/src/gui/ogr ${CMAKE_SOURCE_DIR}/src/gui/processing ${CMAKE_SOURCE_DIR}/src/core diff --git a/src/gui/mesh/qgsmeshrendererscalarsettingswidget.cpp b/src/gui/mesh/qgsmeshrendererscalarsettingswidget.cpp new file mode 100644 index 000000000000..99492d193bbf --- /dev/null +++ b/src/gui/mesh/qgsmeshrendererscalarsettingswidget.cpp @@ -0,0 +1,174 @@ +/*************************************************************************** + qgsmeshrendererscalarsettingswidget.cpp + --------------------------------------- + begin : June 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 "qgsmeshrendererscalarsettingswidget.h" + +#include "qgis.h" +#include "qgsmapcanvas.h" +#include "qgsmeshlayer.h" +#include "qgsrasterlayer.h" +#include "raster/qgscolorrampshaderwidget.h" +#include "raster/qgsrasterminmaxwidget.h" +#include "qgsrasterminmaxorigin.h" +#include "qgsmessagelog.h" + + +QgsMeshRendererScalarSettingsWidget::QgsMeshRendererScalarSettingsWidget( QWidget *parent ) + : QWidget( parent ) + +{ + /* + mMeshLayer = qobject_cast( layer ); + if ( !mMeshLayer ) + return; + + if ( !mMapCanvas ) + return; + */ + + setupUi( this ); + + connect( mScalarRecalculateMinMaxButton, &QPushButton::clicked, this, &QgsMeshRendererScalarSettingsWidget::recalculateMinMaxButtonClicked ); + connect( mScalarMinLineEdit, &QLineEdit::textChanged, this, &QgsMeshRendererScalarSettingsWidget::minMaxChanged ); + connect( mScalarMaxLineEdit, &QLineEdit::textChanged, this, &QgsMeshRendererScalarSettingsWidget::minMaxChanged ); + connect( mScalarMinLineEdit, &QLineEdit::textEdited, this, &QgsMeshRendererScalarSettingsWidget::minMaxEdited ); + connect( mScalarMaxLineEdit, &QLineEdit::textEdited, this, &QgsMeshRendererScalarSettingsWidget::minMaxEdited ); + + connect( mScalarColorRampShaderWidget, &QgsColorRampShaderWidget::widgetChanged, this, &QgsMeshRendererScalarSettingsWidget::widgetChanged ); + +} + +void QgsMeshRendererScalarSettingsWidget::setLayer(QgsMeshLayer *layer) +{ + if (layer != mMeshLayer) + { + mMeshLayer = layer; + syncToLayer(); + connect( mMeshLayer, &QgsMapLayer::styleChanged, this, &QgsMeshRendererScalarSettingsWidget::refreshAfterStyleChanged ); + } +} + +QgsMeshRendererScalarSettings QgsMeshRendererScalarSettingsWidget::settings() const +{ + QgsMeshRendererScalarSettings settings; + settings.setColorRampShader( mScalarColorRampShaderWidget->shader() ); + return settings; +} + +int QgsMeshRendererScalarSettingsWidget::currentDataset() const +{ + if ( mScalarDatasetNoLineEdit->text().isEmpty() ) + { + return -1; + } + + return mScalarDatasetNoLineEdit->text().toInt(); +} + +QgsMeshRendererScalarSettingsWidget::~QgsMeshRendererScalarSettingsWidget() = default; + +void QgsMeshRendererScalarSettingsWidget::syncToLayer( ) +{ + if ( !mMeshLayer ) + return; + + whileBlocking( mScalarDatasetNoLineEdit )->setText( QString::number( mMeshLayer->activeScalarDataset() ) ); + if ( mMeshLayer->rendererScalarSettings().colorRampShader() ) + { + whileBlocking( mScalarMinLineEdit )->setText( QString::number( mMeshLayer->rendererScalarSettings().colorRampShader()->minimumValue() ) ); + whileBlocking( mScalarMaxLineEdit )->setText( QString::number( mMeshLayer->rendererScalarSettings().colorRampShader()->maximumValue() ) ); + whileBlocking( mScalarColorRampShaderWidget )->setFromShader( mMeshLayer->rendererScalarSettings().colorRampShader() ); + } +} + +double QgsMeshRendererScalarSettingsWidget::lineEditValue( const QLineEdit *lineEdit ) const +{ + if ( lineEdit->text().isEmpty() ) + { + return std::numeric_limits::quiet_NaN(); + } + + return lineEdit->text().toDouble(); +} + +void QgsMeshRendererScalarSettingsWidget::minMaxChanged() +{ + double min = lineEditValue( mScalarMinLineEdit ); + double max = lineEditValue( mScalarMaxLineEdit ); + mScalarColorRampShaderWidget->setMinMax( min, max ); +} + +void QgsMeshRendererScalarSettingsWidget::minMaxEdited() +{ + double min = lineEditValue( mScalarMinLineEdit ); + double max = lineEditValue( mScalarMaxLineEdit ); + mScalarColorRampShaderWidget->setMinMaxAndClassify( min, max ); +} + +void QgsMeshRendererScalarSettingsWidget::recalculateMinMaxButtonClicked() +{ + double min, max; + calcMinMax( currentDataset(), min, max ); + whileBlocking( mScalarMinLineEdit )->setText( QString::number( min ) ); + whileBlocking( mScalarMaxLineEdit )->setText( QString::number( max ) ); + mScalarColorRampShaderWidget->setMinMaxAndClassify( min, max ); +} + +void QgsMeshRendererScalarSettingsWidget::calcMinMax( int datasetIndex, double &min, double &max ) const +{ + if ( !mMeshLayer ) + return; + + if ( !mMeshLayer->dataProvider() ) + return; + + const QgsMeshDatasetMetadata metadata = mMeshLayer->dataProvider()->datasetMetadata( datasetIndex ); + bool scalarDataOnVertices = metadata.isOnVertices(); + int count; + if ( scalarDataOnVertices ) + count = mMeshLayer->dataProvider()->vertexCount(); + else + count = mMeshLayer->dataProvider()->faceCount(); + + bool myFirstIterationFlag = true; + for ( int i = 0; i < count; ++i ) + { + double myValue = mMeshLayer->dataProvider()->datasetValue( datasetIndex, i ).scalar(); + if ( std::isnan( myValue ) ) continue; // NULL + if ( myFirstIterationFlag ) + { + myFirstIterationFlag = false; + min = myValue; + max = myValue; + } + else + { + if ( myValue < min ) + { + min = myValue; + } + if ( myValue > max ) + { + max = myValue; + } + } + } +} + +void QgsMeshRendererScalarSettingsWidget::refreshAfterStyleChanged() +{ +} + + diff --git a/src/gui/mesh/qgsmeshrendererscalarsettingswidget.h b/src/gui/mesh/qgsmeshrendererscalarsettingswidget.h new file mode 100644 index 000000000000..245187ddad59 --- /dev/null +++ b/src/gui/mesh/qgsmeshrendererscalarsettingswidget.h @@ -0,0 +1,71 @@ +/*************************************************************************** + qgsmeshrendererscalarsettingswidget.h + ------------------------------------- + begin : June 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 QGSMESHRENDERERSCALARSETTINGSWIDGET_H +#define QGSMESHRENDERERSCALARSETTINGSWIDGET_H + +#include "ui_qgsmeshrendererscalarsettingswidgetbase.h" + +#include +#include +#include +#include "qgis_gui.h" +#include +#include "qgsmeshrenderersettings.h" + +class QgsMeshLayer; + +/** + * \ingroup gui + * \class QgsMeshRendererScalarSettingsWidget + */ +class GUI_EXPORT QgsMeshRendererScalarSettingsWidget : public QWidget, private Ui::QgsMeshRendererScalarSettingsWidgetBase +{ + Q_OBJECT + + public: + + /** + * A widget to hold the renderer scalar settings for a mesh layer. + * \param parent Parent object + */ + QgsMeshRendererScalarSettingsWidget( QWidget *parent = nullptr ); + ~QgsMeshRendererScalarSettingsWidget(); + + void setLayer( QgsMeshLayer *layer ); + + QgsMeshRendererScalarSettings settings() const; + + int currentDataset() const; + + signals: + void widgetChanged(); + + private slots: + void refreshAfterStyleChanged(); + void syncToLayer(); + + void minMaxChanged(); + void minMaxEdited(); + void recalculateMinMaxButtonClicked(); + + private: + double lineEditValue( const QLineEdit *lineEdit ) const; + void calcMinMax( int datasetIndex, double &min, double &max ) const; + + QgsMeshLayer *mMeshLayer = nullptr; +}; + +#endif // QGSMESHRENDERERSCALARSETTINGSWIDGET_H diff --git a/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp b/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp new file mode 100644 index 000000000000..065b98fe6bcf --- /dev/null +++ b/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp @@ -0,0 +1,54 @@ +/*************************************************************************** + qgsrenderermeshpropertieswidget.cpp + ----------------------------------- + begin : June 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 "qgsrenderermeshpropertieswidget.h" + +#include "qgis.h" +#include "qgsmapcanvas.h" +#include "qgsmeshlayer.h" +#include "qgsrasterlayer.h" +#include "raster/qgscolorrampshaderwidget.h" +#include "raster/qgsrasterminmaxwidget.h" +#include "qgsrasterminmaxorigin.h" +#include "qgsmessagelog.h" +#include "qgsmeshrendererscalarsettingswidget.h" + +QgsRendererMeshPropertiesWidget::QgsRendererMeshPropertiesWidget( QgsMapLayer *layer, QgsMapCanvas *canvas, QWidget *parent ) + : QgsMapLayerConfigWidget( layer, canvas, parent ) + +{ + mMeshLayer = qobject_cast( layer ); + if ( !mMeshLayer ) + return; + + if ( !mMapCanvas ) + return; + + setupUi( this ); + mMeshRendererScalarSettingsWidget->setLayer( mMeshLayer ); + connect( mMeshRendererScalarSettingsWidget, &QgsMeshRendererScalarSettingsWidget::widgetChanged, this, &QgsPanelWidget::widgetChanged ); +} + +QgsRendererMeshPropertiesWidget::~QgsRendererMeshPropertiesWidget() = default; + +void QgsRendererMeshPropertiesWidget::apply() +{ + if ( !mMeshLayer ) + return; + + QgsMeshRendererScalarSettings settings = mMeshRendererScalarSettingsWidget->settings(); + mMeshLayer->setActiveScalarDataset( mMeshRendererScalarSettingsWidget->currentDataset() ); // bands are numbered from 1, datasets from 0 + mMeshLayer->setRendererScalarSettings( settings ); +} diff --git a/src/gui/mesh/qgsrenderermeshpropertieswidget.h b/src/gui/mesh/qgsrenderermeshpropertieswidget.h new file mode 100644 index 000000000000..1649ce38d16a --- /dev/null +++ b/src/gui/mesh/qgsrenderermeshpropertieswidget.h @@ -0,0 +1,56 @@ +/*************************************************************************** + qgsrenderermeshpropertieswidget.h + --------------------- + begin : June 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 QGSRENDERERMESHPROPERTIESDIALOG_H +#define QGSRENDERERMESHPROPERTIESDIALOG_H + +#include +#include + +#include "ui_qgsrenderermeshpropswidgetbase.h" + +#include "qgsmaplayerconfigwidget.h" +#include "qgis_gui.h" +#include + +class QgsMeshLayer; +class QgsMapCanvas; + +/** + * \ingroup gui + * \class QgsRendererMeshPropertiesWidget + */ +class GUI_EXPORT QgsRendererMeshPropertiesWidget : public QgsMapLayerConfigWidget, private Ui::QgsRendererMeshPropsWidgetBase +{ + Q_OBJECT + + public: + + /** + * A widget to hold the renderer properties for a raster layer. + * \param layer The mesh layer to style + * \param canvas The canvas object used to calculate the max and min values from the extent. + * \param parent Parent object + */ + QgsRendererMeshPropertiesWidget( QgsMapLayer *layer, QgsMapCanvas *canvas, QWidget *parent = nullptr ); + ~QgsRendererMeshPropertiesWidget(); + + public slots: + void apply() override; + + private: + QgsMeshLayer *mMeshLayer = nullptr; +}; + +#endif // QGSRENDERERMESHPROPERTIESDIALOG_H diff --git a/src/gui/raster/qgscolorrampshaderwidget.cpp b/src/gui/raster/qgscolorrampshaderwidget.cpp new file mode 100644 index 000000000000..b87206d332f9 --- /dev/null +++ b/src/gui/raster/qgscolorrampshaderwidget.cpp @@ -0,0 +1,921 @@ +/*************************************************************************** + qgscolorrampshaderwidget.cpp + ---------------------------- + begin : Jun 2018 by Peter Petrik + copyright : (C) 2012 by Marco Hugentobler + email : marco at sourcepole dot ch + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 "qgsrasterdataprovider.h" + +#include "qgscolorrampshaderwidget.h" +#include "qgssinglebandpseudocolorrenderer.h" +#include "qgsrasterlayer.h" +#include "qgsrasterdataprovider.h" +#include "qgsrastershader.h" +#include "qgsrasterminmaxwidget.h" +#include "qgstreewidgetitem.h" +#include "qgssettings.h" + +// for color ramps - todo add rasterStyle and refactor raster vs. vector ramps +#include "qgsstyle.h" +#include "qgscolorramp.h" +#include "qgscolorrampbutton.h" +#include "qgscolordialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +QgsColorRampShaderWidget::QgsColorRampShaderWidget( QWidget *parent ) + : QWidget( parent ) +{ + QgsSettings settings; + + setupUi( this ); + mLoadFromBandButton->setVisible( false ); // only for raster version + + connect( mAddEntryButton, &QPushButton::clicked, this, &QgsColorRampShaderWidget::mAddEntryButton_clicked ); + connect( mDeleteEntryButton, &QPushButton::clicked, this, &QgsColorRampShaderWidget::mDeleteEntryButton_clicked ); + connect( mLoadFromBandButton, &QPushButton::clicked, this, &QgsColorRampShaderWidget::mLoadFromBandButton_clicked ); + connect( mLoadFromFileButton, &QPushButton::clicked, this, &QgsColorRampShaderWidget::mLoadFromFileButton_clicked ); + connect( mExportToFileButton, &QPushButton::clicked, this, &QgsColorRampShaderWidget::mExportToFileButton_clicked ); + connect( mUnitLineEdit, &QLineEdit::textEdited, this, &QgsColorRampShaderWidget::mUnitLineEdit_textEdited ); + connect( mColormapTreeWidget, &QTreeWidget::itemDoubleClicked, this, &QgsColorRampShaderWidget::mColormapTreeWidget_itemDoubleClicked ); + connect( mColorInterpolationComboBox, static_cast( &QComboBox::currentIndexChanged ), this, &QgsColorRampShaderWidget::mColorInterpolationComboBox_currentIndexChanged ); + // connect( mMinLineEdit, &QLineEdit::textChanged, this, &QgsColorRampShaderWidget::mMinLineEdit_textChanged ); + // connect( mMaxLineEdit, &QLineEdit::textChanged, this, &QgsColorRampShaderWidget::mMaxLineEdit_textChanged ); + // connect( mMinLineEdit, &QLineEdit::textEdited, this, &QgsColorRampShaderWidget::mMinLineEdit_textEdited ); + // connect( mMaxLineEdit, &QLineEdit::textEdited, this, &QgsColorRampShaderWidget::mMaxLineEdit_textEdited ); + connect( mClassificationModeComboBox, static_cast( &QComboBox::currentIndexChanged ), this, &QgsColorRampShaderWidget::mClassificationModeComboBox_currentIndexChanged ); + + contextMenu = new QMenu( tr( "Options" ), this ); + contextMenu->addAction( tr( "Change Color…" ), this, SLOT( changeColor() ) ); + contextMenu->addAction( tr( "Change Opacity…" ), this, SLOT( changeOpacity() ) ); + + mColormapTreeWidget->setColumnWidth( ColorColumn, 50 ); + mColormapTreeWidget->setContextMenuPolicy( Qt::CustomContextMenu ); + mColormapTreeWidget->setSelectionMode( QAbstractItemView::ExtendedSelection ); + connect( mColormapTreeWidget, &QTreeView::customContextMenuRequested, this, [ = ]( QPoint ) { contextMenu->exec( QCursor::pos() ); } + ); + + QString defaultPalette = settings.value( QStringLiteral( "Raster/defaultPalette" ), "" ).toString(); + btnColorRamp->setColorRampFromName( defaultPalette ); + + /* + if ( !mRasterLayer ) + { + return; + } + + QgsRasterDataProvider *provider = mRasterLayer->dataProvider(); + if ( !provider ) + { + return; + } + + // Must be before adding items to mBandComboBox (signal) + mMinLineEdit->setValidator( new QDoubleValidator( mMinLineEdit ) ); + mMaxLineEdit->setValidator( new QDoubleValidator( mMaxLineEdit ) ); + + mMinMaxWidget = new QgsRasterMinMaxWidget( layer, this ); + mMinMaxWidget->setExtent( extent ); + mMinMaxWidget->setMapCanvas( mCanvas ); + + QHBoxLayout *layout = new QHBoxLayout(); + layout->setContentsMargins( 0, 0, 0, 0 ); + mMinMaxContainerWidget->setLayout( layout ); + layout->addWidget( mMinMaxWidget ); + + mBandComboBox->setLayer( mRasterLayer ); + */ + mColorInterpolationComboBox->addItem( tr( "Discrete" ), QgsColorRampShader::Discrete ); + mColorInterpolationComboBox->addItem( tr( "Linear" ), QgsColorRampShader::Interpolated ); + mColorInterpolationComboBox->addItem( tr( "Exact" ), QgsColorRampShader::Exact ); + mColorInterpolationComboBox->setCurrentIndex( mColorInterpolationComboBox->findData( QgsColorRampShader::Interpolated ) ); + + mClassificationModeComboBox->addItem( tr( "Continuous" ), QgsColorRampShader::Continuous ); + mClassificationModeComboBox->addItem( tr( "Equal Interval" ), QgsColorRampShader::EqualInterval ); + // Quantile added only on demand + mClassificationModeComboBox->setCurrentIndex( mClassificationModeComboBox->findData( QgsColorRampShader::Continuous ) ); + + mNumberOfEntriesSpinBox->setValue( 5 ); // some default + + //setFromShader( shader ); + + /* + connect( mMinMaxWidget, &QgsRasterMinMaxWidget::widgetChanged, this, &QgsColorRampShaderWidget::widgetChanged ); + connect( mMinMaxWidget, &QgsRasterMinMaxWidget::load, this, &QgsColorRampShaderWidget::loadMinMax ); + + // If there is currently no min/max, load default with user current default options + if ( mMinLineEdit->text().isEmpty() || mMaxLineEdit->text().isEmpty() ) + { + QgsRasterMinMaxOrigin minMaxOrigin = mMinMaxWidget->minMaxOrigin(); + if ( minMaxOrigin.limits() == QgsRasterMinMaxOrigin::None ) + { + minMaxOrigin.setLimits( QgsRasterMinMaxOrigin::MinMax ); + mMinMaxWidget->setFromMinMaxOrigin( minMaxOrigin ); + } + mMinMaxWidget->doComputations(); + } + */ + + mClassificationModeComboBox_currentIndexChanged( 0 ); + + resetClassifyButton(); + + connect( mClassificationModeComboBox, static_cast( &QComboBox::currentIndexChanged ), this, &QgsColorRampShaderWidget::classify ); + connect( mClassifyButton, &QPushButton::clicked, this, &QgsColorRampShaderWidget::applyColorRamp ); + connect( btnColorRamp, &QgsColorRampButton::colorRampChanged, this, &QgsColorRampShaderWidget::applyColorRamp ); + connect( mNumberOfEntriesSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsColorRampShaderWidget::classify ); + /* + connect( mBandComboBox, &QgsRasterBandComboBox::bandChanged, this, &QgsColorRampShaderWidget::classify ); + connect( mBandComboBox, &QgsRasterBandComboBox::bandChanged, this, &QgsColorRampShaderWidget::bandChanged ); + connect( mClipCheckBox, &QAbstractButton::toggled, this, &QgsRasterRendererWidget::widgetChanged ); + */ +} + +void QgsColorRampShaderWidget::initForUseWithRasterLayer() +{ + Q_ASSERT( mClassificationModeComboBox->findData( QgsColorRampShader::Quantile < 0 ) ); + mClassificationModeComboBox->addItem( tr( "Quantile" ), QgsColorRampShader::Quantile ); + mLoadFromBandButton->setVisible( bool( mRasterDataProvider ) ); // only for raster version +} + +void QgsColorRampShaderWidget::setRasterBand( QgsRasterDataProvider *dp, + int band, + const QgsRectangle &extent ) +{ + mRasterDataProvider = dp; + mBand = band; + mExtent = extent; +} + +QgsColorRampShader *QgsColorRampShaderWidget::shader() const +{ + QgsColorRampShader *colorRampShader = new QgsColorRampShader( mMin, mMax ); + colorRampShader->setColorRampType( static_cast< QgsColorRampShader::Type >( mColorInterpolationComboBox->currentData().toInt() ) ); + colorRampShader->setClassificationMode( static_cast< QgsColorRampShader::ClassificationMode >( mClassificationModeComboBox->currentData().toInt() ) ); + colorRampShader->setClip( mClipCheckBox->isChecked() ); + + //iterate through mColormapTreeWidget and set colormap info of layer + QList colorRampItems; + int topLevelItemCount = mColormapTreeWidget->topLevelItemCount(); + QTreeWidgetItem *currentItem = nullptr; + for ( int i = 0; i < topLevelItemCount; ++i ) + { + currentItem = mColormapTreeWidget->topLevelItem( i ); + if ( !currentItem ) + { + continue; + } + QgsColorRampShader::ColorRampItem newColorRampItem; + newColorRampItem.value = currentItem->text( ValueColumn ).toDouble(); + newColorRampItem.color = currentItem->background( ColorColumn ).color(); + newColorRampItem.label = currentItem->text( LabelColumn ); + colorRampItems.append( newColorRampItem ); + } + // sort the shader items + std::sort( colorRampItems.begin(), colorRampItems.end() ); + colorRampShader->setColorRampItemList( colorRampItems ); + + if ( !btnColorRamp->isNull() ) + { + colorRampShader->setSourceColorRamp( btnColorRamp->colorRamp() ); + } + return colorRampShader; +} + +void QgsColorRampShaderWidget::autoLabel() +{ + QgsColorRampShader::Type interpolation = static_cast< QgsColorRampShader::Type >( mColorInterpolationComboBox->currentData().toInt() ); + bool discrete = interpolation == QgsColorRampShader::Discrete; + QString unit = mUnitLineEdit->text(); + QString label; + int topLevelItemCount = mColormapTreeWidget->topLevelItemCount(); + QTreeWidgetItem *currentItem = nullptr; + for ( int i = 0; i < topLevelItemCount; ++i ) + { + currentItem = mColormapTreeWidget->topLevelItem( i ); + //If the item is null or does not have a pixel values set, skip + if ( !currentItem || currentItem->text( ValueColumn ).isEmpty() ) + { + continue; + } + + if ( discrete ) + { + if ( i == 0 ) + { + label = "<= " + currentItem->text( ValueColumn ) + unit; + } + else if ( currentItem->text( ValueColumn ).toDouble() == std::numeric_limits::infinity() ) + { + label = "> " + mColormapTreeWidget->topLevelItem( i - 1 )->text( ValueColumn ) + unit; + } + else + { + label = mColormapTreeWidget->topLevelItem( i - 1 )->text( ValueColumn ) + " - " + currentItem->text( ValueColumn ) + unit; + } + } + else + { + label = currentItem->text( ValueColumn ) + unit; + } + + if ( currentItem->text( LabelColumn ).isEmpty() || currentItem->text( LabelColumn ) == label || currentItem->foreground( LabelColumn ).color() == QColor( Qt::gray ) ) + { + currentItem->setText( LabelColumn, label ); + currentItem->setForeground( LabelColumn, QBrush( QColor( Qt::gray ) ) ); + } + } +} + +void QgsColorRampShaderWidget::setUnitFromLabels() +{ + QgsColorRampShader::Type interpolation = static_cast< QgsColorRampShader::Type >( mColorInterpolationComboBox->currentData().toInt() ); + bool discrete = interpolation == QgsColorRampShader::Discrete; + QStringList allSuffixes; + QString label; + int topLevelItemCount = mColormapTreeWidget->topLevelItemCount(); + QTreeWidgetItem *currentItem = nullptr; + for ( int i = 0; i < topLevelItemCount; ++i ) + { + currentItem = mColormapTreeWidget->topLevelItem( i ); + //If the item is null or does not have a pixel values set, skip + if ( !currentItem || currentItem->text( ValueColumn ).isEmpty() ) + { + continue; + } + + if ( discrete ) + { + if ( i == 0 ) + { + label = "<= " + currentItem->text( ValueColumn ); + } + else if ( currentItem->text( ValueColumn ).toDouble() == std::numeric_limits::infinity() ) + { + label = "> " + mColormapTreeWidget->topLevelItem( i - 1 )->text( ValueColumn ); + } + else + { + label = mColormapTreeWidget->topLevelItem( i - 1 )->text( ValueColumn ) + " - " + currentItem->text( ValueColumn ); + } + } + else + { + label = currentItem->text( ValueColumn ); + } + + if ( currentItem->text( LabelColumn ).startsWith( label ) ) + { + allSuffixes.append( currentItem->text( LabelColumn ).mid( label.length() ) ); + } + } + // find most common suffix + QStringList suffixes = QStringList( allSuffixes ); + suffixes.removeDuplicates(); + int max = 0; + QString unit; + for ( int i = 0; i < suffixes.count(); ++i ) + { + int n = allSuffixes.count( suffixes[i] ); + if ( n > max ) + { + max = n; + unit = suffixes[i]; + } + } + // Set this suffix as unit if at least used twice + if ( max >= 2 ) + { + mUnitLineEdit->setText( unit ); + } + autoLabel(); +} + + +void QgsColorRampShaderWidget::mAddEntryButton_clicked() +{ + QgsTreeWidgetItemObject *newItem = new QgsTreeWidgetItemObject( mColormapTreeWidget ); + newItem->setText( ValueColumn, QStringLiteral( "0" ) ); + newItem->setBackground( ColorColumn, QBrush( QColor( Qt::magenta ) ) ); + newItem->setText( LabelColumn, QString() ); + newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable ); + connect( newItem, &QgsTreeWidgetItemObject::itemEdited, + this, &QgsColorRampShaderWidget::mColormapTreeWidget_itemEdited ); + mColormapTreeWidget->sortItems( ValueColumn, Qt::AscendingOrder ); + autoLabel(); + + loadMinMaxFromTree(); + emit widgetChanged(); +} + +void QgsColorRampShaderWidget::mDeleteEntryButton_clicked() +{ + QList itemList; + itemList = mColormapTreeWidget->selectedItems(); + if ( itemList.isEmpty() ) + { + return; + } + + Q_FOREACH ( QTreeWidgetItem *item, itemList ) + { + delete item; + } + + loadMinMaxFromTree(); + emit widgetChanged(); +} + +void QgsColorRampShaderWidget::classify() +{ + std::unique_ptr< QgsColorRamp > ramp( btnColorRamp->colorRamp() ); + if ( !ramp || std::isnan( mMin ) || std::isnan( mMax ) ) + { + return; + } + + QgsColorRampShader *colorRampShader = new QgsColorRampShader( + mMin, mMax, + ramp.get(), + static_cast< QgsColorRampShader::Type >( mColorInterpolationComboBox->currentData().toInt() ), + static_cast< QgsColorRampShader::ClassificationMode >( mClassificationModeComboBox->currentData().toInt() ) ); + + // only for Quantile we need band and provider and extent + colorRampShader->classifyColorRamp( mNumberOfEntriesSpinBox->value(), + mBand, + mExtent, + mRasterDataProvider ); + colorRampShader->setClip( mClipCheckBox->isChecked() ); + + + mColormapTreeWidget->clear(); + + const QList colorRampItemList = colorRampShader->colorRampItemList(); + QList::const_iterator it = colorRampItemList.constBegin(); + for ( ; it != colorRampItemList.end(); ++it ) + { + QgsTreeWidgetItemObject *newItem = new QgsTreeWidgetItemObject( mColormapTreeWidget ); + newItem->setText( ValueColumn, QString::number( it->value, 'g', 15 ) ); + newItem->setBackground( ColorColumn, QBrush( it->color ) ); + newItem->setText( LabelColumn, it->label ); + newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable ); + connect( newItem, &QgsTreeWidgetItemObject::itemEdited, + this, &QgsColorRampShaderWidget::mColormapTreeWidget_itemEdited ); + } + mClipCheckBox->setChecked( colorRampShader->clip() ); + + + autoLabel(); + emit widgetChanged(); +} + +void QgsColorRampShaderWidget::mClassificationModeComboBox_currentIndexChanged( int index ) +{ + QgsColorRampShader::ClassificationMode mode = static_cast< QgsColorRampShader::ClassificationMode >( mClassificationModeComboBox->itemData( index ).toInt() ); + mNumberOfEntriesSpinBox->setEnabled( mode != QgsColorRampShader::Continuous ); + //mMinLineEdit->setEnabled( mode != QgsColorRampShader::Quantile ); + //mMaxLineEdit->setEnabled( mode != QgsColorRampShader::Quantile ); + emit classificationModeChanged( mode ); + +} + +void QgsColorRampShaderWidget::applyColorRamp() +{ + std::unique_ptr< QgsColorRamp > ramp( btnColorRamp->colorRamp() ); + if ( !ramp ) + { + return; + } + + if ( !btnColorRamp->colorRampName().isEmpty() ) + { + // Remember last used color ramp + QgsSettings settings; + settings.setValue( QStringLiteral( "Raster/defaultPalette" ), btnColorRamp->colorRampName() ); + } + + bool enableContinuous = ( ramp->count() > 0 ); + mClassificationModeComboBox->setEnabled( enableContinuous ); + if ( !enableContinuous ) + { + mClassificationModeComboBox->setCurrentIndex( mClassificationModeComboBox->findData( QgsColorRampShader::EqualInterval ) ); + } + + classify(); +} + +void QgsColorRampShaderWidget::populateColormapTreeWidget( const QList &colorRampItems ) +{ + mColormapTreeWidget->clear(); + QList::const_iterator it = colorRampItems.constBegin(); + for ( ; it != colorRampItems.constEnd(); ++it ) + { + QgsTreeWidgetItemObject *newItem = new QgsTreeWidgetItemObject( mColormapTreeWidget ); + newItem->setText( ValueColumn, QString::number( it->value, 'g', 15 ) ); + newItem->setBackground( ColorColumn, QBrush( it->color ) ); + newItem->setText( LabelColumn, it->label ); + newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable ); + connect( newItem, &QgsTreeWidgetItemObject::itemEdited, + this, &QgsColorRampShaderWidget::mColormapTreeWidget_itemEdited ); + } + setUnitFromLabels(); + + autoLabel(); + emit widgetChanged(); +} + +void QgsColorRampShaderWidget::mLoadFromBandButton_clicked() +{ + if ( !mRasterDataProvider ) + return; + + QList colorRampList = mRasterDataProvider->colorTable( mBand ); + if ( !colorRampList.isEmpty() ) + { + populateColormapTreeWidget( colorRampList ); + mColorInterpolationComboBox->setCurrentIndex( mColorInterpolationComboBox->findData( QgsColorRampShader::Interpolated ) ); + } + else + { + QMessageBox::warning( this, tr( "Load Color Map" ), tr( "The color map for band %1 has no entries." ).arg( mBand ) ); + } + + loadMinMaxFromTree(); + emit widgetChanged(); +} + +void QgsColorRampShaderWidget::mLoadFromFileButton_clicked() +{ + int lineCounter = 0; + bool importError = false; + QString badLines; + QgsSettings settings; + QString lastDir = settings.value( QStringLiteral( "lastColorMapDir" ), QDir::homePath() ).toString(); + QString fileName = QFileDialog::getOpenFileName( this, tr( "Load Color Map from File" ), lastDir, tr( "Textfile (*.txt)" ) ); + QFile inputFile( fileName ); + if ( inputFile.open( QFile::ReadOnly ) ) + { + //clear the current tree + mColormapTreeWidget->clear(); + + QTextStream inputStream( &inputFile ); + QString inputLine; + QStringList inputStringComponents; + QList colorRampItems; + + //read through the input looking for valid data + while ( !inputStream.atEnd() ) + { + lineCounter++; + inputLine = inputStream.readLine(); + if ( !inputLine.isEmpty() ) + { + if ( !inputLine.simplified().startsWith( '#' ) ) + { + if ( inputLine.contains( QLatin1String( "INTERPOLATION" ), Qt::CaseInsensitive ) ) + { + inputStringComponents = inputLine.split( ':' ); + if ( inputStringComponents.size() == 2 ) + { + if ( inputStringComponents[1].trimmed().toUpper().compare( QLatin1String( "INTERPOLATED" ), Qt::CaseInsensitive ) == 0 ) + { + mColorInterpolationComboBox->setCurrentIndex( mColorInterpolationComboBox->findData( QgsColorRampShader::Interpolated ) ); + } + else if ( inputStringComponents[1].trimmed().toUpper().compare( QLatin1String( "DISCRETE" ), Qt::CaseInsensitive ) == 0 ) + { + mColorInterpolationComboBox->setCurrentIndex( mColorInterpolationComboBox->findData( QgsColorRampShader::Discrete ) ); + } + else + { + mColorInterpolationComboBox->setCurrentIndex( mColorInterpolationComboBox->findData( QgsColorRampShader::Exact ) ); + } + } + else + { + importError = true; + badLines = badLines + QString::number( lineCounter ) + ":\t[" + inputLine + "]\n"; + } + } + else + { + inputStringComponents = inputLine.split( ',' ); + if ( inputStringComponents.size() == 6 ) + { + QgsColorRampShader::ColorRampItem currentItem( inputStringComponents[0].toDouble(), + QColor::fromRgb( inputStringComponents[1].toInt(), inputStringComponents[2].toInt(), + inputStringComponents[3].toInt(), inputStringComponents[4].toInt() ), + inputStringComponents[5] ); + colorRampItems.push_back( currentItem ); + } + else + { + importError = true; + badLines = badLines + QString::number( lineCounter ) + ":\t[" + inputLine + "]\n"; + } + } + } + } + lineCounter++; + } + populateColormapTreeWidget( colorRampItems ); + + QFileInfo fileInfo( fileName ); + settings.setValue( QStringLiteral( "lastColorMapDir" ), fileInfo.absoluteDir().absolutePath() ); + + if ( importError ) + { + QMessageBox::warning( this, tr( "Load Color Map from File" ), tr( "The following lines contained errors\n\n" ) + badLines ); + } + } + else if ( !fileName.isEmpty() ) + { + QMessageBox::warning( this, tr( "Load Color Map from File" ), tr( "Read access denied. Adjust the file permissions and try again.\n\n" ) ); + } + + loadMinMaxFromTree(); + emit widgetChanged(); +} + +void QgsColorRampShaderWidget::mExportToFileButton_clicked() +{ + QgsSettings settings; + QString lastDir = settings.value( QStringLiteral( "lastColorMapDir" ), QDir::homePath() ).toString(); + QString fileName = QFileDialog::getSaveFileName( this, tr( "Save Color Map as File" ), lastDir, tr( "Textfile (*.txt)" ) ); + if ( !fileName.isEmpty() ) + { + if ( !fileName.endsWith( QLatin1String( ".txt" ), Qt::CaseInsensitive ) ) + { + fileName = fileName + ".txt"; + } + + QFile outputFile( fileName ); + if ( outputFile.open( QFile::WriteOnly | QIODevice::Truncate ) ) + { + QTextStream outputStream( &outputFile ); + outputStream << "# " << tr( "QGIS Generated Color Map Export File" ) << '\n'; + outputStream << "INTERPOLATION:"; + QgsColorRampShader::Type interpolation = static_cast< QgsColorRampShader::Type >( mColorInterpolationComboBox->currentData().toInt() ); + switch ( interpolation ) + { + case QgsColorRampShader::Interpolated: + outputStream << "INTERPOLATED\n"; + break; + case QgsColorRampShader::Discrete: + outputStream << "DISCRETE\n"; + break; + case QgsColorRampShader::Exact: + outputStream << "EXACT\n"; + break; + } + + int topLevelItemCount = mColormapTreeWidget->topLevelItemCount(); + QTreeWidgetItem *currentItem = nullptr; + QColor color; + for ( int i = 0; i < topLevelItemCount; ++i ) + { + currentItem = mColormapTreeWidget->topLevelItem( i ); + if ( !currentItem ) + { + continue; + } + color = currentItem->background( ColorColumn ).color(); + outputStream << currentItem->text( ValueColumn ).toDouble() << ','; + outputStream << color.red() << ',' << color.green() << ',' << color.blue() << ',' << color.alpha() << ','; + if ( currentItem->text( LabelColumn ).isEmpty() ) + { + outputStream << "Color entry " << i + 1 << '\n'; + } + else + { + outputStream << currentItem->text( LabelColumn ) << '\n'; + } + } + outputStream.flush(); + outputFile.close(); + + QFileInfo fileInfo( fileName ); + settings.setValue( QStringLiteral( "lastColorMapDir" ), fileInfo.absoluteDir().absolutePath() ); + } + else + { + QMessageBox::warning( this, tr( "Save Color Map as File" ), tr( "Write access denied. Adjust the file permissions and try again.\n\n" ) ); + } + } +} + +void QgsColorRampShaderWidget::mColormapTreeWidget_itemDoubleClicked( QTreeWidgetItem *item, int column ) +{ + if ( !item ) + { + return; + } + + if ( column == ColorColumn ) + { + item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable ); + QColor newColor = QgsColorDialog::getColor( item->background( column ).color(), this, QStringLiteral( "Change Color" ), true ); + if ( newColor.isValid() ) + { + item->setBackground( ColorColumn, QBrush( newColor ) ); + loadMinMaxFromTree(); + emit widgetChanged(); + } + } + else + { + if ( column == LabelColumn ) + { + // Set text color to default black, which signifies a manually edited label + item->setForeground( LabelColumn, QBrush() ); + } + item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable ); + } +} + +void QgsColorRampShaderWidget::mColormapTreeWidget_itemEdited( QTreeWidgetItem *item, int column ) +{ + Q_UNUSED( item ); + + if ( column == ValueColumn ) + { + mColormapTreeWidget->sortItems( ValueColumn, Qt::AscendingOrder ); + autoLabel(); + + loadMinMaxFromTree(); + + emit widgetChanged(); + } + else if ( column == LabelColumn ) + { + // call autoLabel to fill when empty or gray out when same as autoLabel + autoLabel(); + emit widgetChanged(); + } +} + +void QgsColorRampShaderWidget::setFromShader( const QgsColorRampShader *colorRampShader ) +{ + + + if ( colorRampShader ) + { + if ( colorRampShader->sourceColorRamp() ) + { + btnColorRamp->setColorRamp( colorRampShader->sourceColorRamp() ); + } + else + { + QgsSettings settings; + QString defaultPalette = settings.value( QStringLiteral( "/Raster/defaultPalette" ), "Spectral" ).toString(); + btnColorRamp->setColorRampFromName( defaultPalette ); + } + + mColorInterpolationComboBox->setCurrentIndex( mColorInterpolationComboBox->findData( colorRampShader->colorRampType() ) ); + + const QList colorRampItemList = colorRampShader->colorRampItemList(); + QList::const_iterator it = colorRampItemList.constBegin(); + for ( ; it != colorRampItemList.end(); ++it ) + { + QgsTreeWidgetItemObject *newItem = new QgsTreeWidgetItemObject( mColormapTreeWidget ); + newItem->setText( ValueColumn, QString::number( it->value, 'g', 15 ) ); + newItem->setBackground( ColorColumn, QBrush( it->color ) ); + newItem->setText( LabelColumn, it->label ); + newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable ); + connect( newItem, &QgsTreeWidgetItemObject::itemEdited, + this, &QgsColorRampShaderWidget::mColormapTreeWidget_itemEdited ); + } + setUnitFromLabels(); + mClipCheckBox->setChecked( colorRampShader->clip() ); + mClassificationModeComboBox->setCurrentIndex( mClassificationModeComboBox->findData( colorRampShader->classificationMode() ) ); + mNumberOfEntriesSpinBox->setValue( colorRampShader->colorRampItemList().count() ); // some default + } + +} + +void QgsColorRampShaderWidget::mColorInterpolationComboBox_currentIndexChanged( int index ) +{ + QgsColorRampShader::Type interpolation = static_cast< QgsColorRampShader::Type >( mColorInterpolationComboBox->itemData( index ).toInt() ); + + mClipCheckBox->setEnabled( interpolation == QgsColorRampShader::Interpolated ); + + QString valueLabel; + QString valueToolTip; + switch ( interpolation ) + { + case QgsColorRampShader::Interpolated: + valueLabel = tr( "Value" ); + valueToolTip = tr( "Value for color stop" ); + break; + case QgsColorRampShader::Discrete: + valueLabel = tr( "Value <=" ); + valueToolTip = tr( "Maximum value for class" ); + break; + case QgsColorRampShader::Exact: + valueLabel = tr( "Value =" ); + valueToolTip = tr( "Value for color" ); + break; + } + + QTreeWidgetItem *header = mColormapTreeWidget->headerItem(); + header->setText( ValueColumn, valueLabel ); + header->setToolTip( ValueColumn, valueToolTip ); + + autoLabel(); + emit widgetChanged(); +} + +void QgsColorRampShaderWidget::setMinMaxAndClassify( double min, double max ) +{ + if ( !qgsDoubleNear( mMin, min ) || !qgsDoubleNear( mMax, max ) ) + { + mMin = min; + mMax = max; + + classify(); + } +} + +void QgsColorRampShaderWidget::setMinMax( double min, double max ) +{ + mMin = min; + mMax = max; + resetClassifyButton(); +} + +void QgsColorRampShaderWidget::loadMinMaxFromTree() +{ + QTreeWidgetItem *item = mColormapTreeWidget->topLevelItem( 0 ); + if ( !item ) + { + return; + } + + double min = item->text( ValueColumn ).toDouble(); + item = mColormapTreeWidget->topLevelItem( mColormapTreeWidget->topLevelItemCount() - 1 ); + double max = item->text( ValueColumn ).toDouble(); + + //whileBlocking( mMinLineEdit )->setText( QString::number( min ) ); + //whileBlocking( mMaxLineEdit )->setText( QString::number( max ) ); + + if ( !qgsDoubleNear( mMin, min ) || !qgsDoubleNear( mMax, max ) ) + { + mMin = min; + mMax = max; + emit minMaxChangedFromTree( min, max ); + } +} + +/* +void QgsColorRampShaderWidget::setLineEditValue( QLineEdit *lineEdit, double value ) +{ + QString s; + if ( !std::isnan( value ) ) + { + s = QString::number( value ); + } + lineEdit->setText( s ); +} + +double QgsColorRampShaderWidget::lineEditValue( const QLineEdit *lineEdit ) const +{ + if ( lineEdit->text().isEmpty() ) + { + return std::numeric_limits::quiet_NaN(); + } + + return lineEdit->text().toDouble(); +}*/ + +void QgsColorRampShaderWidget::resetClassifyButton() +{ + mClassifyButton->setEnabled( true ); + // double min = lineEditValue( mMinLineEdit ); + // double max = lineEditValue( mMaxLineEdit ); + if ( std::isnan( mMin ) || std::isnan( mMax ) || mMin >= mMax ) + { + mClassifyButton->setEnabled( false ); + } +} + +void QgsColorRampShaderWidget::changeColor() +{ + QList itemList; + itemList = mColormapTreeWidget->selectedItems(); + if ( itemList.isEmpty() ) + { + return; + } + QTreeWidgetItem *firstItem = itemList.first(); + + QColor newColor = QgsColorDialog::getColor( firstItem->background( ColorColumn ).color(), this, QStringLiteral( "Change Color" ), true ); + if ( newColor.isValid() ) + { + Q_FOREACH ( QTreeWidgetItem *item, itemList ) + { + item->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable ); + item->setBackground( ColorColumn, QBrush( newColor ) ); + } + + loadMinMaxFromTree(); + emit widgetChanged(); + } +} + +void QgsColorRampShaderWidget::changeOpacity() +{ + QList itemList; + itemList = mColormapTreeWidget->selectedItems(); + if ( itemList.isEmpty() ) + { + return; + } + QTreeWidgetItem *firstItem = itemList.first(); + + bool ok; + double oldOpacity = firstItem->background( ColorColumn ).color().alpha() / 255 * 100; + double opacity = QInputDialog::getDouble( this, tr( "Opacity" ), tr( "Change color opacity [%]" ), oldOpacity, 0.0, 100.0, 0, &ok ); + if ( ok ) + { + int newOpacity = static_cast( opacity / 100 * 255 ); + Q_FOREACH ( QTreeWidgetItem *item, itemList ) + { + QColor newColor = item->background( ColorColumn ).color(); + newColor.setAlpha( newOpacity ); + item->setBackground( ColorColumn, QBrush( newColor ) ); + } + + loadMinMaxFromTree(); + emit widgetChanged(); + } +} + +/* +void QgsColorRampShaderWidget::mMinLineEdit_textEdited( const QString & ) +{ + minMaxModified(); + classify(); +} + +void QgsColorRampShaderWidget::mMaxLineEdit_textEdited( const QString & ) +{ + minMaxModified(); + classify(); +} + +void QgsColorRampShaderWidget::minMaxModified() +{ + mMinMaxWidget->userHasSetManualMinMaxValues(); +} +*/ + +// ************************************ // +/* QgsRasterColorRampShaderWidget + +QgsRasterColorRampShaderWidget::QgsRasterColorRampShaderWidget(QgsRasterLayer *layer, const QgsRectangle &extent) + : QgsColorRampShaderWidget() + , mRasterLayer( layer ) + , mExtent( extent ) +{ + + connect( mLoadFromBandButton, &QPushButton::clicked, this, &QgsRasterColorRampShaderWidget::mLoadFromBandButton_clicked ); + mLoadFromBandButton->setVisible(true); + mClassificationModeComboBox->addItem( tr( "Quantile" ), QgsColorRampShader::Quantile ); + + if ( !mRasterLayer ) + { + return; + } + + QgsRasterDataProvider *provider = mRasterLayer->dataProvider(); + if ( !provider ) + { + return; + } +} + +void QgsRasterColorRampShaderWidget::setBand(int band) +{ + mBand = band; +} +*/ + + + diff --git a/src/gui/raster/qgscolorrampshaderwidget.h b/src/gui/raster/qgscolorrampshaderwidget.h new file mode 100644 index 000000000000..5f867f460682 --- /dev/null +++ b/src/gui/raster/qgscolorrampshaderwidget.h @@ -0,0 +1,134 @@ +/*************************************************************************** + qgscolorrampshaderwidget.h + -------------------------- + begin : Jun 2018 by Peter Petrik + copyright : (C) 2012 by Marco Hugentobler + email : marco at sourcepole dot ch + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 QGSCOLORRAMPSHADERWIDGET_H +#define QGSCOLORRAMPSHADERWIDGET_H + +#include "qgis_sip.h" +#include "qgscolorrampshader.h" +#include "qgsrasterrenderer.h" +#include "ui_qgscolorrampshaderwidgetbase.h" +#include "qgis_gui.h" +#include "qgsrasterrendererwidget.h" + +class QgsRasterDataProvider; + +/** + * \ingroup gui + * \class QgsColorRampShaderWidget + * + * It has 2 ways how to use it. For raster layers, raster data provider and band is assigned and + * the Quantile classification mode can be used and the LoadFromBandButton is visible. + * + * The other mode is used to style mesh layer contours (scalar datasets) + */ +class GUI_EXPORT QgsColorRampShaderWidget: public QWidget, protected Ui::QgsColorRampShaderWidgetBase +{ + + Q_OBJECT + + public: + + QgsColorRampShaderWidget( QWidget *parent = nullptr ); + + void initForUseWithRasterLayer(); + + void setRasterBand( QgsRasterDataProvider *dp, int band, const QgsRectangle &extent ); + void setMinMaxAndClassify( double min, double max ); + void setMinMax( double min, double max ); + + //! Returns shared function used in the renderer. Caller takes ownership and deletes it. + QgsColorRampShader *shader() const; + void setFromShader( const QgsColorRampShader *colorRampShader ); + + signals: + void minMaxChangedFromTree( double min, double max ); + void widgetChanged(); + void classificationModeChanged( QgsColorRampShader::ClassificationMode mode ); + + public slots: + + /** + * Executes the single band pseudo raster classification + */ + void classify(); + + //! called when the color ramp tree has changed + void loadMinMaxFromTree(); + + protected: + void populateColormapTreeWidget( const QList &colorRampItems ); + + private: + + enum Column + { + ValueColumn = 0, + ColorColumn = 1, + LabelColumn = 2, + }; + + /** + * Generate labels from the values in the color map. + * Skip labels which were manually edited (black text). + * Text of generated labels is made gray + */ + void autoLabel(); + + //! Extract the unit out of the current labels and set the unit field. + void setUnitFromLabels(); + + QMenu *contextMenu = nullptr; + + private slots: + + void applyColorRamp(); + void mAddEntryButton_clicked(); + void mDeleteEntryButton_clicked(); + void mLoadFromBandButton_clicked(); + void mLoadFromFileButton_clicked(); + void mExportToFileButton_clicked(); + void mUnitLineEdit_textEdited( const QString &text ) { Q_UNUSED( text ); autoLabel(); } + void mColormapTreeWidget_itemDoubleClicked( QTreeWidgetItem *item, int column ); + void mColormapTreeWidget_itemEdited( QTreeWidgetItem *item, int column ); + //void bandChanged(); + void mColorInterpolationComboBox_currentIndexChanged( int index ); + //void mMinLineEdit_textChanged( const QString & ) { resetClassifyButton(); } + //void mMaxLineEdit_textChanged( const QString & ) { resetClassifyButton(); } + //void mMinLineEdit_textEdited( const QString &text ); + //void mMaxLineEdit_textEdited( const QString &text ); + void mClassificationModeComboBox_currentIndexChanged( int index ); + void changeColor(); + void changeOpacity(); + + private: + + void setLineEditValue( QLineEdit *lineEdit, double value ); + double lineEditValue( const QLineEdit *lineEdit ) const; + void resetClassifyButton(); + + double mMin = std::numeric_limits::quiet_NaN(); + double mMax = std::numeric_limits::quiet_NaN(); + + // For mode with raster layer + QgsRasterDataProvider *mRasterDataProvider = nullptr; + int mBand = -1; + QgsRectangle mExtent; + +}; + +#endif // QGSCOLORRAMPSHADERWIDGET_H diff --git a/src/gui/raster/qgssinglebandpseudocolorrendererwidget.cpp b/src/gui/raster/qgssinglebandpseudocolorrendererwidget.cpp index bf5fe54b2ef1..95d8f5bec4ec 100644 --- a/src/gui/raster/qgssinglebandpseudocolorrendererwidget.cpp +++ b/src/gui/raster/qgssinglebandpseudocolorrendererwidget.cpp @@ -142,9 +142,8 @@ QgsSingleBandPseudoColorRendererWidget::QgsSingleBandPseudoColorRendererWidget( connect( mClipCheckBox, &QAbstractButton::toggled, this, &QgsRasterRendererWidget::widgetChanged ); } -QgsRasterRenderer *QgsSingleBandPseudoColorRendererWidget::renderer() +QgsColorRampShader *QgsSingleBandPseudoColorRendererWidget::shaderFunction() const { - QgsRasterShader *rasterShader = new QgsRasterShader(); QgsColorRampShader *colorRampShader = new QgsColorRampShader( lineEditValue( mMinLineEdit ), lineEditValue( mMaxLineEdit ) ); colorRampShader->setColorRampType( static_cast< QgsColorRampShader::Type >( mColorInterpolationComboBox->currentData().toInt() ) ); colorRampShader->setClassificationMode( static_cast< QgsColorRampShader::ClassificationMode >( mClassificationModeComboBox->currentData().toInt() ) ); @@ -175,8 +174,13 @@ QgsRasterRenderer *QgsSingleBandPseudoColorRendererWidget::renderer() { colorRampShader->setSourceColorRamp( btnColorRamp->colorRamp() ); } + return colorRampShader; +} - rasterShader->setRasterShaderFunction( colorRampShader ); +QgsRasterRenderer *QgsSingleBandPseudoColorRendererWidget::renderer() +{ + QgsRasterShader *rasterShader = new QgsRasterShader(); + rasterShader->setRasterShaderFunction( shaderFunction() ); int bandNumber = mBandComboBox->currentBand(); QgsSingleBandPseudoColorRenderer *renderer = new QgsSingleBandPseudoColorRenderer( mRasterLayer->dataProvider(), bandNumber, rasterShader ); @@ -191,6 +195,11 @@ void QgsSingleBandPseudoColorRendererWidget::doComputations() mMinMaxWidget->doComputations(); } +int QgsSingleBandPseudoColorRendererWidget::currentBand() const +{ + return mBandComboBox->currentBand(); +} + void QgsSingleBandPseudoColorRendererWidget::setMapCanvas( QgsMapCanvas *canvas ) { QgsRasterRendererWidget::setMapCanvas( canvas ); diff --git a/src/gui/raster/qgssinglebandpseudocolorrendererwidget.h b/src/gui/raster/qgssinglebandpseudocolorrendererwidget.h index 7071fa05100d..ad13d29d99f9 100644 --- a/src/gui/raster/qgssinglebandpseudocolorrendererwidget.h +++ b/src/gui/raster/qgssinglebandpseudocolorrendererwidget.h @@ -42,10 +42,16 @@ class GUI_EXPORT QgsSingleBandPseudoColorRendererWidget: public QgsRasterRendere static QgsRasterRendererWidget *create( QgsRasterLayer *layer, const QgsRectangle &extent ) SIP_FACTORY { return new QgsSingleBandPseudoColorRendererWidget( layer, extent ); } QgsRasterRenderer *renderer() override; + + //! Returns shared function used in the renderer. Caller takes ownership and deletes it. + QgsColorRampShader *shaderFunction() const; void setMapCanvas( QgsMapCanvas *canvas ) override; void doComputations() override; QgsRasterMinMaxWidget *minMaxWidget() override { return mMinMaxWidget; } + //! Returns the current raster band number + int currentBand() const; + void setFromRenderer( const QgsRasterRenderer *r ); public slots: diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 377194f7b463..19ce33137568 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -8,6 +8,7 @@ FILE(GLOB PROCESSING_UIS "${CMAKE_CURRENT_SOURCE_DIR}/processing/*.ui") FILE(GLOB AUTH_UIS "${CMAKE_CURRENT_SOURCE_DIR}/auth/*.ui") FILE(GLOB RASTER_UIS "${CMAKE_CURRENT_SOURCE_DIR}/raster/*.ui") FILE(GLOB STYLEDOCK_UIS "${CMAKE_CURRENT_SOURCE_DIR}/styledock/*.ui") +FILE(GLOB MESH_UIS "${CMAKE_CURRENT_SOURCE_DIR}/mesh/*.ui") FILE(GLOB _3D_UIS "${CMAKE_CURRENT_SOURCE_DIR}/3d/*.ui") QT5_WRAP_UI(QGIS_UIS_H @@ -20,6 +21,7 @@ QT5_WRAP_UI(QGIS_UIS_H ${RASTER_UIS} ${STYLEDOCK_UIS} ${LAYOUT_UIS} + ${MESH_UIS} ${_3D_UIS} ) diff --git a/src/ui/mesh/qgsmeshrendererscalarsettingswidgetbase.ui b/src/ui/mesh/qgsmeshrendererscalarsettingswidgetbase.ui new file mode 100644 index 000000000000..50a9d4436eaf --- /dev/null +++ b/src/ui/mesh/qgsmeshrendererscalarsettingswidgetbase.ui @@ -0,0 +1,103 @@ + + + QgsMeshRendererScalarSettingsWidgetBase + + + + 0 + 0 + 344 + 267 + + + + Form + + + + + + + + Scalar Dataset # + + + + + + + 0 + + + + + + + + + + + + + + + + + + min + + + + + + + 1 + + + + + + + max + + + + + + + 0 + + + + + + + Recalculate + + + + + + + + + + 0 + 0 + + + + + + + + + QgsColorRampShaderWidget + QWidget +
raster/qgscolorrampshaderwidget.h
+ 1 +
+
+ + +
diff --git a/src/ui/mesh/qgsrenderermeshpropswidgetbase.ui b/src/ui/mesh/qgsrenderermeshpropswidgetbase.ui new file mode 100644 index 000000000000..a8963cdbd746 --- /dev/null +++ b/src/ui/mesh/qgsrenderermeshpropswidgetbase.ui @@ -0,0 +1,102 @@ + + + QgsRendererMeshPropsWidgetBase + + + + 0 + 0 + 386 + 593 + + + + Form + + + + + + Qt::Vertical + + + + 0 + 0 + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Scalar rendering + + + + + + + + + + + + Mesh rendering + + + false + + + + + + + Vector rendering + + + + + + + + + + + + QgsCollapsibleGroupBox + QGroupBox +
qgscollapsiblegroupbox.h
+ 1 +
+ + QgsMeshRendererScalarSettingsWidget + QWidget +
mesh/qgsmeshrendererscalarsettingswidget.h
+ 1 +
+
+ + +
diff --git a/src/ui/qgscolorrampshaderwidgetbase.ui b/src/ui/qgscolorrampshaderwidgetbase.ui new file mode 100644 index 000000000000..14ac1f67cf0e --- /dev/null +++ b/src/ui/qgscolorrampshaderwidgetbase.ui @@ -0,0 +1,322 @@ + + + QgsColorRampShaderWidgetBase + + + + 0 + 0 + 396 + 605 + + + + Form + + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + 0 + 0 + + + + + 0 + 250 + + + + 70 + + + 10 + + + true + + + + Value + + + + + Color + + + + + Label + + + + + + + + Color ramp + + + + + + + + 0 + 0 + + + + + 120 + 0 + + + + + 16777215 + 16777215 + + + + + + + + + + + Interpolation + + + + + + + + + Classify + + + + + + + Add values manually + + + + :/images/themes/default/symbologyAdd.svg:/images/themes/default/symbologyAdd.svg + + + + + + + Remove selected row(s) + + + + :/images/themes/default/symbologyRemove.svg:/images/themes/default/symbologyRemove.svg + + + + + + + Load color map from band + + + + :/images/themes/default/mActionDraw.svg:/images/themes/default/mActionDraw.svg + + + + + + + Load color map from file + + + + :/images/themes/default/mActionFileOpen.svg:/images/themes/default/mActionFileOpen.svg + + + + + + + Export color map to file + + + + :/images/themes/default/mActionFileSaveAs.svg:/images/themes/default/mActionFileSaveAs.svg + + + + + + + Qt::Horizontal + + + + 48 + 28 + + + + + + + + + + If checked, any pixels with a value out of range will not be rendered + + + Clip out of range values + + + + + + + + + Mode + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Classes + + + + + + + + 0 + 0 + + + + 2 + + + 255 + + + 5 + + + + + + + + + Unit suffix + + + + + + + Label unit +suffix + + + + + + + + QgsColorRampButton + QToolButton +
qgscolorrampbutton.h
+ 1 +
+
+ + mColorInterpolationComboBox + btnColorRamp + mUnitLineEdit + mColormapTreeWidget + mClassificationModeComboBox + mNumberOfEntriesSpinBox + mClassifyButton + mAddEntryButton + mDeleteEntryButton + mLoadFromBandButton + mLoadFromFileButton + mExportToFileButton + mClipCheckBox + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/ui/raster/qgscolorrampshaderwidgetbase.ui b/src/ui/raster/qgscolorrampshaderwidgetbase.ui new file mode 100644 index 000000000000..8176e6c15a54 --- /dev/null +++ b/src/ui/raster/qgscolorrampshaderwidgetbase.ui @@ -0,0 +1,294 @@ + + + QgsColorRampShaderWidgetBase + + + + 0 + 0 + 396 + 605 + + + + Form + + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + 0 + 0 + + + + + 0 + 250 + + + + 70 + + + 10 + + + true + + + + Value + + + + + Color + + + + + Label + + + + + + + + Color ramp + + + + + + + + 0 + 0 + + + + + 120 + 0 + + + + + 16777215 + 16777215 + + + + + + + + + + + Interpolation + + + + + + + + + Classify + + + + + + + Add values manually + + + + :/images/themes/default/symbologyAdd.svg:/images/themes/default/symbologyAdd.svg + + + + + + + Remove selected row(s) + + + + :/images/themes/default/symbologyRemove.svg:/images/themes/default/symbologyRemove.svg + + + + + + + Load color map from band + + + + :/images/themes/default/mActionDraw.svg:/images/themes/default/mActionDraw.svg + + + + + + + Load color map from file + + + + :/images/themes/default/mActionFileOpen.svg:/images/themes/default/mActionFileOpen.svg + + + + + + + Export color map to file + + + + :/images/themes/default/mActionFileSaveAs.svg:/images/themes/default/mActionFileSaveAs.svg + + + + + + + Qt::Horizontal + + + + 48 + 28 + + + + + + + + + + If checked, any pixels with a value out of range will not be rendered + + + Clip out of range values + + + + + + + + + Mode + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Classes + + + + + + + + 0 + 0 + + + + 2 + + + 255 + + + 5 + + + + + + + + + Unit suffix + + + + + + + Label unit +suffix + + + + + + + + QgsColorRampButton + QToolButton +
qgscolorrampbutton.h
+ 1 +
+
+ + mColorInterpolationComboBox + btnColorRamp + mUnitLineEdit + mColormapTreeWidget + mClassificationModeComboBox + mNumberOfEntriesSpinBox + mClassifyButton + mAddEntryButton + mDeleteEntryButton + mLoadFromBandButton + mLoadFromFileButton + mExportToFileButton + mClipCheckBox + + + + + +
From 0b17970ccfc031b64c2a39d16e757aead0d826be Mon Sep 17 00:00:00 2001 From: Peter Petrik Date: Thu, 14 Jun 2018 12:04:30 +0200 Subject: [PATCH 02/13] [mesh] Select active dataset in GUI --- src/gui/CMakeLists.txt | 4 + src/gui/mesh/qgsmeshdatasetgrouptree.cpp | 106 ++++++++++ src/gui/mesh/qgsmeshdatasetgrouptree.h | 63 ++++++ .../qgsmeshrendereractivedatasetwidget.cpp | 193 ++++++++++++++++++ .../mesh/qgsmeshrendereractivedatasetwidget.h | 78 +++++++ .../qgsmeshrendererscalarsettingswidget.cpp | 30 +-- .../qgsmeshrendererscalarsettingswidget.h | 7 +- .../mesh/qgsrenderermeshpropertieswidget.cpp | 43 +++- .../qgsmeshrendereractivedatasetwidgetbase.ui | 130 ++++++++++++ ...qgsmeshrendererscalarsettingswidgetbase.ui | 33 +-- src/ui/mesh/qgsrenderermeshpropswidgetbase.ui | 116 ++++++----- 11 files changed, 691 insertions(+), 112 deletions(-) create mode 100644 src/gui/mesh/qgsmeshdatasetgrouptree.cpp create mode 100644 src/gui/mesh/qgsmeshdatasetgrouptree.h create mode 100644 src/gui/mesh/qgsmeshrendereractivedatasetwidget.cpp create mode 100644 src/gui/mesh/qgsmeshrendereractivedatasetwidget.h create mode 100644 src/ui/mesh/qgsmeshrendereractivedatasetwidgetbase.ui diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 12ab6a05e6ee..0abe6d46e10b 100755 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -1,6 +1,8 @@ SET(QGIS_GUI_SRCS mesh/qgsrenderermeshpropertieswidget.cpp mesh/qgsmeshrendererscalarsettingswidget.cpp + mesh/qgsmeshrendereractivedatasetwidget.cpp + mesh/qgsmeshdatasetgrouptree.cpp raster/qgscolorrampshaderwidget.cpp raster/qgsmultibandcolorrendererwidget.cpp @@ -547,6 +549,8 @@ SET(QGIS_GUI_MOC_HDRS mesh/qgsrenderermeshpropertieswidget.h mesh/qgsmeshrendererscalarsettingswidget.h + mesh/qgsmeshrendereractivedatasetwidget.h + mesh/qgsmeshdatasetgrouptree.h raster/qgscolorrampshaderwidget.h raster/qgsmultibandcolorrendererwidget.h diff --git a/src/gui/mesh/qgsmeshdatasetgrouptree.cpp b/src/gui/mesh/qgsmeshdatasetgrouptree.cpp new file mode 100644 index 000000000000..288208b79282 --- /dev/null +++ b/src/gui/mesh/qgsmeshdatasetgrouptree.cpp @@ -0,0 +1,106 @@ +/*************************************************************************** + qgsmeshdatasetgrouptree.cpp + --------------------------- + begin : June 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 "qgsmeshdatasetgrouptree.h" + +#include "qgis.h" +#include "qgsmeshlayer.h" + +QgsMeshDatasetGroupTree::QgsMeshDatasetGroupTree( QWidget *parent ) + : QTreeWidget( parent ) + +{ + setColumnCount( 1 ); + connect( this, &QTreeWidget::currentItemChanged, this, &QgsMeshDatasetGroupTree::onSelectionChanged ); +} + +QgsMeshDatasetGroupTree::~QgsMeshDatasetGroupTree() = default; + +void QgsMeshDatasetGroupTree::setLayer( QgsMeshLayer *layer ) +{ + if ( layer != mMeshLayer ) + { + mMeshLayer = layer; + repopulateTree(); + } +} + +QVector QgsMeshDatasetGroupTree::datasetsInActiveGroup() const +{ + if ( mGroups.constFind( mActiveGroup ) == mGroups.constEnd() ) + return QVector(); + else + return mGroups[mActiveGroup]; +} + +void QgsMeshDatasetGroupTree::onSelectionChanged( QTreeWidgetItem *current, QTreeWidgetItem *previous ) +{ + Q_UNUSED( previous ); + + if ( current ) + { + mActiveGroup = current->text( 0 ); + } + else + { + mActiveGroup = QString(); + } + + emit activeGroupChanged(); +} + +void QgsMeshDatasetGroupTree::repopulateTree() +{ + mGroups.clear(); + mActiveGroup.clear(); + clear(); + + if ( !mMeshLayer || !mMeshLayer->dataProvider() ) + return; + + for ( int i = 0; i < mMeshLayer->dataProvider()->datasetCount(); ++i ) + { + // TODO name to metadata directly when groups are introduced in MDAL + const QgsMeshDatasetMetadata meta = mMeshLayer->dataProvider()->datasetMetadata( i ); + QString name = meta.extraOptions()["name"]; + if ( mGroups.constFind( name ) == mGroups.constEnd() ) + { + QVector datasets; + datasets.append( i ); + mGroups[name] = datasets; + } + else + { + mGroups[name].append( i ); + } + } + + QStringList groupsSorted = mGroups.keys(); + qSort( groupsSorted.begin(), groupsSorted.end() ); + + QList items; + for ( int i = 0; i < groupsSorted.size(); ++i ) + { + QString groupName = groupsSorted[i]; + QVector datasets = mGroups[groupName]; + qSort( datasets ); + mGroups[groupName] = datasets; + QTreeWidgetItem *item = new QTreeWidgetItem( ( QTreeWidget * )0, QStringList( QString( "%1" ).arg( groupName ) ) ); + // item->setData(0, Qt::UserRole, i); + items.append( item ); + } + insertTopLevelItems( 0, items ); +} + diff --git a/src/gui/mesh/qgsmeshdatasetgrouptree.h b/src/gui/mesh/qgsmeshdatasetgrouptree.h new file mode 100644 index 000000000000..e3498e33f291 --- /dev/null +++ b/src/gui/mesh/qgsmeshdatasetgrouptree.h @@ -0,0 +1,63 @@ +/*************************************************************************** + qgsmeshdatasetgrouptree.h + ------------------------- + begin : June 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 QGSMESHDATASETGROUPTREE_H +#define QGSMESHDATASETGROUPTREE_H + +#include +#include +#include "qgis_gui.h" +#include +#include + +class QgsMeshLayer; + +/** + * \ingroup gui + * \class QgsMeshDatasetGroupTree + */ +class GUI_EXPORT QgsMeshDatasetGroupTree : public QTreeWidget +{ + Q_OBJECT + + public: + + /** + * A widget to hold the renderer scalar settings for a mesh layer. + * \param parent Parent object + */ + QgsMeshDatasetGroupTree( QWidget *parent = nullptr ); + ~QgsMeshDatasetGroupTree(); + + void setLayer( QgsMeshLayer *layer ); + + QVector datasetsInActiveGroup() const; + + signals: + //! Datasets in active/selected group changed + void activeGroupChanged(); + + private slots: + void onSelectionChanged( QTreeWidgetItem *current, QTreeWidgetItem *previous ); + + private: + void repopulateTree(); + + QgsMeshLayer *mMeshLayer = nullptr; + QMap> mGroups; // value-> dataset numbers + QString mActiveGroup = QString(); +}; + +#endif // QGSMESHRENDERERSCALARSETTINGSWIDGET_H diff --git a/src/gui/mesh/qgsmeshrendereractivedatasetwidget.cpp b/src/gui/mesh/qgsmeshrendereractivedatasetwidget.cpp new file mode 100644 index 000000000000..f3cb71bdcf67 --- /dev/null +++ b/src/gui/mesh/qgsmeshrendereractivedatasetwidget.cpp @@ -0,0 +1,193 @@ +/*************************************************************************** + qgsmeshrendereractivedatasetwidget.cpp + --------------------------------------- + begin : June 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 "qgsmeshrendereractivedatasetwidget.h" + +#include "qgis.h" +#include "qgsmapcanvas.h" +#include "qgsmeshlayer.h" +#include "qgsrasterlayer.h" +#include "raster/qgscolorrampshaderwidget.h" +#include "raster/qgsrasterminmaxwidget.h" +#include "qgsrasterminmaxorigin.h" +#include "qgsmessagelog.h" + + +QgsMeshRendererActiveDatasetWidget::QgsMeshRendererActiveDatasetWidget( QWidget *parent ) + : QWidget( parent ) + +{ + setupUi( this ); + connect( mDatasetGroupTree, &QgsMeshDatasetGroupTree::activeGroupChanged, this, &QgsMeshRendererActiveDatasetWidget::onActiveGroupChanged ); + connect( mDatasetSlider, &QSlider::valueChanged, this, &QgsMeshRendererActiveDatasetWidget::onActiveDatasetChanged ); + connect( mDisplayScalarsCheckBox, &QCheckBox::stateChanged, this, &QgsMeshRendererActiveDatasetWidget::onScalarChecked ); + connect( mDisplayVectorsCheckBox, &QCheckBox::stateChanged, this, &QgsMeshRendererActiveDatasetWidget::onVectorChecked ); + connect( mDisplayNativeMeshCheckBox, &QCheckBox::stateChanged, this, &QgsMeshRendererActiveDatasetWidget::onMeshChecked ); + connect( mDisplayTriangularMeshCheckBox, &QCheckBox::stateChanged, this, &QgsMeshRendererActiveDatasetWidget::onTringularMeshChecked ); +} + +QgsMeshRendererActiveDatasetWidget::~QgsMeshRendererActiveDatasetWidget() = default; + +void QgsMeshRendererActiveDatasetWidget::setLayer( QgsMeshLayer *layer ) +{ + if ( layer != mMeshLayer ) + { + mMeshLayer = layer; + } + + setEnabled( mMeshLayer ); + syncToLayer(); + + mDatasetGroupTree->setLayer( layer ); +} + +int QgsMeshRendererActiveDatasetWidget::activeScalarDataset() const +{ + if ( !isEnabled() || + !mDisplayScalarsCheckBox->isEnabled() || + !mDisplayScalarsCheckBox->isChecked() ) + return -1; + return datasetIndex(); +} + +int QgsMeshRendererActiveDatasetWidget::activeVectorDataset() const +{ + if ( !isEnabled() || + !mDisplayVectorsCheckBox->isEnabled() || + !mDisplayVectorsCheckBox->isChecked() ) + return -1; + return datasetIndex(); +} + +bool QgsMeshRendererActiveDatasetWidget::meshRenderingOn() const +{ + return isEnabled() && mDisplayNativeMeshCheckBox->isChecked(); +} + +bool QgsMeshRendererActiveDatasetWidget::triangularMeshRenderingOn() const +{ + return isEnabled() && mDisplayTriangularMeshCheckBox->isChecked(); +} + +void QgsMeshRendererActiveDatasetWidget::onActiveGroupChanged() +{ + const QVector datasets = mDatasetGroupTree->datasetsInActiveGroup(); + + mDatasetSlider->setMinimum( 0 ); + mDatasetSlider->setMaximum( datasets.size() - 1 ); + mDatasetSlider->setValue( 0 ); + + qDebug() << "Size" << datasets.size() - 1; + +} + +void QgsMeshRendererActiveDatasetWidget::onActiveDatasetChanged( int value ) +{ + int datasetIndex = -1; + const QVector datasets = mDatasetGroupTree->datasetsInActiveGroup(); + if ( datasets.size() < value || !mMeshLayer || !mMeshLayer->dataProvider() ) + { + mDisplayScalarsCheckBox->setEnabled( false ); + mDisplayVectorsCheckBox->setEnabled( false ); + } + else + { + datasetIndex = datasets[value]; + const QgsMeshDatasetMetadata meta = mMeshLayer->dataProvider()->datasetMetadata( datasetIndex ); + mDisplayScalarsCheckBox->setEnabled( true ); + mDisplayVectorsCheckBox->setEnabled( meta.isVector() ); + } + + updateMetadata( datasetIndex ); + + emit activeScalarDatasetChanged( activeScalarDataset() ); + emit activeVectorDatasetChanged( activeVectorDataset() ); + + emit widgetChanged(); +} + +void QgsMeshRendererActiveDatasetWidget::onScalarChecked( int toggle ) +{ + Q_UNUSED( toggle ); + emit activeScalarDatasetChanged( activeScalarDataset() ); + emit widgetChanged(); +} + +void QgsMeshRendererActiveDatasetWidget::onVectorChecked( int toggle ) +{ + Q_UNUSED( toggle ); + emit activeVectorDatasetChanged( activeVectorDataset() ); + emit widgetChanged(); +} + +void QgsMeshRendererActiveDatasetWidget::onMeshChecked( int toggle ) +{ + Q_UNUSED( toggle ); + emit meshRenderingOnChanged( meshRenderingOn() ); + emit widgetChanged(); +} + +void QgsMeshRendererActiveDatasetWidget::onTringularMeshChecked( int toggle ) +{ + Q_UNUSED( toggle ); + emit triangularMeshRenderingOnChange( triangularMeshRenderingOn() ); + emit widgetChanged(); +} + +void QgsMeshRendererActiveDatasetWidget::updateMetadata( int datasetIndex ) +{ + if ( datasetIndex == -1 ) + { + mActiveDatasetMetadata->setText( QString( "N/A" ) ); + } + else + { + const QgsMeshDatasetMetadata meta = mMeshLayer->dataProvider()->datasetMetadata( datasetIndex ); + QString msg; + msg += QStringLiteral( "" ); + msg += QStringLiteral( "" ).arg( meta.isOnVertices() ); + msg += QStringLiteral( "" ).arg( meta.isVector() ); + for ( auto it = meta.extraOptions().constBegin(); it != meta.extraOptions().constEnd(); ++it ) + { + msg += QStringLiteral( "" ).arg( it.key() ).arg( it.value() ); + } + msg += QStringLiteral( "
is on vertices%1
is vector%1
%1%2
" ); + mActiveDatasetMetadata->setText( msg ); + } + +} + +int QgsMeshRendererActiveDatasetWidget::datasetIndex() const +{ + const QVector datasets = mDatasetGroupTree->datasetsInActiveGroup(); + int value = mDatasetSlider->value(); + int datasetIndex = -1; + if ( value < datasets.size() ) + { + datasetIndex = datasets[value]; + } + return datasetIndex; +} + +void QgsMeshRendererActiveDatasetWidget::syncToLayer() +{ + if ( mMeshLayer ) + { + whileBlocking( mDisplayNativeMeshCheckBox )->setChecked( mMeshLayer->rendererNativeMeshSettings().isEnabled() ); + whileBlocking( mDisplayTriangularMeshCheckBox )->setChecked( mMeshLayer->rendererTriangularMeshSettings().isEnabled() ); + whileBlocking( mDisplayScalarsCheckBox )->setChecked( mMeshLayer->activeScalarDataset() != -1 ); + whileBlocking( mDisplayVectorsCheckBox )->setChecked( mMeshLayer->activeVectorDataset() != -1 ); + } +} diff --git a/src/gui/mesh/qgsmeshrendereractivedatasetwidget.h b/src/gui/mesh/qgsmeshrendereractivedatasetwidget.h new file mode 100644 index 000000000000..8f9751ba9255 --- /dev/null +++ b/src/gui/mesh/qgsmeshrendereractivedatasetwidget.h @@ -0,0 +1,78 @@ +/*************************************************************************** + qgsmeshrendereractivedatasetwidget.h + ------------------------------------- + begin : June 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 QGSMESHRENDERERACTIVEDATASETWIDGET_H +#define QGSMESHRENDERERACTIVEDATASETWIDGET_H + +#include "ui_qgsmeshrendereractivedatasetwidgetbase.h" + +#include +#include +#include +#include "qgis_gui.h" +#include +#include "qgsmeshrenderersettings.h" + +class QgsMeshLayer; + +/** + * \ingroup gui + * \class QgsMeshRendererScalarSettingsWidget + */ +class GUI_EXPORT QgsMeshRendererActiveDatasetWidget : public QWidget, private Ui::QgsMeshRendererActiveDatasetWidgetBase +{ + Q_OBJECT + + public: + + /** + * A widget to hold the renderer scalar settings for a mesh layer. + * \param parent Parent object + */ + QgsMeshRendererActiveDatasetWidget( QWidget *parent = nullptr ); + ~QgsMeshRendererActiveDatasetWidget(); + + void setLayer( QgsMeshLayer *layer ); + int activeScalarDataset() const; + int activeVectorDataset() const; + bool meshRenderingOn() const; + bool triangularMeshRenderingOn() const; + + signals: + void activeScalarDatasetChanged( int index ); + void activeVectorDatasetChanged( int index ); + void meshRenderingOnChanged( bool on ); + void triangularMeshRenderingOnChange( bool on ); + + void widgetChanged(); + + private slots: + void onActiveGroupChanged(); + void onActiveDatasetChanged( int value ); + void onScalarChecked( int toggle ); + void onVectorChecked( int toggle ); + void onMeshChecked( int toggle ); + void onTringularMeshChecked( int toggle ); + + void updateMetadata( int datasetIndex ); + + private: + int datasetIndex() const; + void syncToLayer(); + + QgsMeshLayer *mMeshLayer = nullptr; +}; + +#endif // QGSMESHRENDERERSCALARSETTINGSWIDGET_H diff --git a/src/gui/mesh/qgsmeshrendererscalarsettingswidget.cpp b/src/gui/mesh/qgsmeshrendererscalarsettingswidget.cpp index 99492d193bbf..30054be47973 100644 --- a/src/gui/mesh/qgsmeshrendererscalarsettingswidget.cpp +++ b/src/gui/mesh/qgsmeshrendererscalarsettingswidget.cpp @@ -29,15 +29,6 @@ QgsMeshRendererScalarSettingsWidget::QgsMeshRendererScalarSettingsWidget( QWidge : QWidget( parent ) { - /* - mMeshLayer = qobject_cast( layer ); - if ( !mMeshLayer ) - return; - - if ( !mMapCanvas ) - return; - */ - setupUi( this ); connect( mScalarRecalculateMinMaxButton, &QPushButton::clicked, this, &QgsMeshRendererScalarSettingsWidget::recalculateMinMaxButtonClicked ); @@ -50,9 +41,9 @@ QgsMeshRendererScalarSettingsWidget::QgsMeshRendererScalarSettingsWidget( QWidge } -void QgsMeshRendererScalarSettingsWidget::setLayer(QgsMeshLayer *layer) +void QgsMeshRendererScalarSettingsWidget::setLayer( QgsMeshLayer *layer ) { - if (layer != mMeshLayer) + if ( layer != mMeshLayer ) { mMeshLayer = layer; syncToLayer(); @@ -67,15 +58,6 @@ QgsMeshRendererScalarSettings QgsMeshRendererScalarSettingsWidget::settings() co return settings; } -int QgsMeshRendererScalarSettingsWidget::currentDataset() const -{ - if ( mScalarDatasetNoLineEdit->text().isEmpty() ) - { - return -1; - } - - return mScalarDatasetNoLineEdit->text().toInt(); -} QgsMeshRendererScalarSettingsWidget::~QgsMeshRendererScalarSettingsWidget() = default; @@ -84,7 +66,6 @@ void QgsMeshRendererScalarSettingsWidget::syncToLayer( ) if ( !mMeshLayer ) return; - whileBlocking( mScalarDatasetNoLineEdit )->setText( QString::number( mMeshLayer->activeScalarDataset() ) ); if ( mMeshLayer->rendererScalarSettings().colorRampShader() ) { whileBlocking( mScalarMinLineEdit )->setText( QString::number( mMeshLayer->rendererScalarSettings().colorRampShader()->minimumValue() ) ); @@ -120,12 +101,17 @@ void QgsMeshRendererScalarSettingsWidget::minMaxEdited() void QgsMeshRendererScalarSettingsWidget::recalculateMinMaxButtonClicked() { double min, max; - calcMinMax( currentDataset(), min, max ); + calcMinMax( mActiveDataset, min, max ); whileBlocking( mScalarMinLineEdit )->setText( QString::number( min ) ); whileBlocking( mScalarMaxLineEdit )->setText( QString::number( max ) ); mScalarColorRampShaderWidget->setMinMaxAndClassify( min, max ); } +void QgsMeshRendererScalarSettingsWidget::setActiveDataset( int activeDataset ) +{ + mActiveDataset = activeDataset; +} + void QgsMeshRendererScalarSettingsWidget::calcMinMax( int datasetIndex, double &min, double &max ) const { if ( !mMeshLayer ) diff --git a/src/gui/mesh/qgsmeshrendererscalarsettingswidget.h b/src/gui/mesh/qgsmeshrendererscalarsettingswidget.h index 245187ddad59..11c757e00462 100644 --- a/src/gui/mesh/qgsmeshrendererscalarsettingswidget.h +++ b/src/gui/mesh/qgsmeshrendererscalarsettingswidget.h @@ -48,11 +48,12 @@ class GUI_EXPORT QgsMeshRendererScalarSettingsWidget : public QWidget, private U QgsMeshRendererScalarSettings settings() const; - int currentDataset() const; - signals: void widgetChanged(); + public slots: + void setActiveDataset( int activeDataset ); + private slots: void refreshAfterStyleChanged(); void syncToLayer(); @@ -66,6 +67,8 @@ class GUI_EXPORT QgsMeshRendererScalarSettingsWidget : public QWidget, private U void calcMinMax( int datasetIndex, double &min, double &max ) const; QgsMeshLayer *mMeshLayer = nullptr; + + int mActiveDataset = -1; }; #endif // QGSMESHRENDERERSCALARSETTINGSWIDGET_H diff --git a/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp b/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp index 065b98fe6bcf..27f743209a68 100644 --- a/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp +++ b/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp @@ -25,6 +25,9 @@ #include "qgsmessagelog.h" #include "qgsmeshrendererscalarsettingswidget.h" +#include "qgsmeshdatasetgrouptree.h" +#include "qgsmeshrendereractivedatasetwidget.h" + QgsRendererMeshPropertiesWidget::QgsRendererMeshPropertiesWidget( QgsMapLayer *layer, QgsMapCanvas *canvas, QWidget *parent ) : QgsMapLayerConfigWidget( layer, canvas, parent ) @@ -37,8 +40,15 @@ QgsRendererMeshPropertiesWidget::QgsRendererMeshPropertiesWidget( QgsMapLayer *l return; setupUi( this ); + + mMeshRendererActiveDatasetWidget->setLayer( mMeshLayer ); mMeshRendererScalarSettingsWidget->setLayer( mMeshLayer ); + + connect( mMeshRendererActiveDatasetWidget, &QgsMeshRendererActiveDatasetWidget::widgetChanged, this, &QgsPanelWidget::widgetChanged ); connect( mMeshRendererScalarSettingsWidget, &QgsMeshRendererScalarSettingsWidget::widgetChanged, this, &QgsPanelWidget::widgetChanged ); + + connect( mMeshRendererActiveDatasetWidget, &QgsMeshRendererActiveDatasetWidget::activeScalarDatasetChanged, + mMeshRendererScalarSettingsWidget, &QgsMeshRendererScalarSettingsWidget::setActiveDataset ); } QgsRendererMeshPropertiesWidget::~QgsRendererMeshPropertiesWidget() = default; @@ -48,7 +58,34 @@ void QgsRendererMeshPropertiesWidget::apply() if ( !mMeshLayer ) return; - QgsMeshRendererScalarSettings settings = mMeshRendererScalarSettingsWidget->settings(); - mMeshLayer->setActiveScalarDataset( mMeshRendererScalarSettingsWidget->currentDataset() ); // bands are numbered from 1, datasets from 0 - mMeshLayer->setRendererScalarSettings( settings ); + // MESH + bool meshRenderingIsEnabled = mMeshRendererActiveDatasetWidget->meshRenderingOn(); + QgsMeshRendererMeshSettings meshSettings = mMeshLayer->rendererNativeMeshSettings(); + meshSettings.setEnabled( meshRenderingIsEnabled ); + whileBlocking( mMeshLayer )->setRendererNativeMeshSettings( meshSettings ); + + // TRIANGULAR MESH + bool triangularMeshRenderingIsEnabled = mMeshRendererActiveDatasetWidget->triangularMeshRenderingOn(); + QgsMeshRendererMeshSettings triangularMeshSettings = mMeshLayer->rendererTriangularMeshSettings(); + triangularMeshSettings.setEnabled( triangularMeshRenderingIsEnabled ); + whileBlocking( mMeshLayer )->setRendererTriangularMeshSettings( triangularMeshSettings ); + + // SCALAR + int activeScalarDatasetIndex = mMeshRendererActiveDatasetWidget->activeScalarDataset(); + whileBlocking( mMeshLayer )->setActiveScalarDataset( activeScalarDatasetIndex ); + if ( activeScalarDatasetIndex != -1 ) + { + QgsMeshRendererScalarSettings settings = mMeshRendererScalarSettingsWidget->settings(); + whileBlocking( mMeshLayer )->setRendererScalarSettings( settings ); + } + + // VECTOR + int activeVectorDatasetIndex = mMeshRendererActiveDatasetWidget->activeVectorDataset(); + whileBlocking( mMeshLayer )->setActiveVectorDataset( activeVectorDatasetIndex ); + if ( activeVectorDatasetIndex != -1 ) + { + //TODO take settings from widget + } + + mMeshLayer->triggerRepaint(); } diff --git a/src/ui/mesh/qgsmeshrendereractivedatasetwidgetbase.ui b/src/ui/mesh/qgsmeshrendereractivedatasetwidgetbase.ui new file mode 100644 index 000000000000..9d6ed3a1cb12 --- /dev/null +++ b/src/ui/mesh/qgsmeshrendereractivedatasetwidgetbase.ui @@ -0,0 +1,130 @@ + + + QgsMeshRendererActiveDatasetWidgetBase + + + false + + + + 0 + 0 + 254 + 260 + + + + Form + + + + + + + 0 + 55 + + + + + 1 + + + + + + + + Dataset in Selected Group(s) + + + + + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 1 + + + + + + + Display + + + + + + + + + Contours + + + + + + + Vectors + + + + + + + Mesh + + + + + + + Triangular Mesh + + + + + + + + + Metadata + + + + + + + + + Qt::RichText + + + + + + + + + + + QgsMeshDatasetGroupTree + QTreeWidget +
mesh/qgsmeshdatasetgrouptree.h
+
+ + QgsCollapsibleGroupBox + QGroupBox +
qgscollapsiblegroupbox.h
+ 1 +
+
+ + +
diff --git a/src/ui/mesh/qgsmeshrendererscalarsettingswidgetbase.ui b/src/ui/mesh/qgsmeshrendererscalarsettingswidgetbase.ui index 50a9d4436eaf..6190459eeab1 100644 --- a/src/ui/mesh/qgsmeshrendererscalarsettingswidgetbase.ui +++ b/src/ui/mesh/qgsmeshrendererscalarsettingswidgetbase.ui @@ -14,31 +14,6 @@ Form - - - - - - Scalar Dataset # - - - - - - - 0 - - - - - - - - - - - - @@ -49,9 +24,9 @@ - + - 1 + 0 @@ -63,9 +38,9 @@ - + - 0 + 1 diff --git a/src/ui/mesh/qgsrenderermeshpropswidgetbase.ui b/src/ui/mesh/qgsrenderermeshpropswidgetbase.ui index a8963cdbd746..30b09659be25 100644 --- a/src/ui/mesh/qgsrenderermeshpropswidgetbase.ui +++ b/src/ui/mesh/qgsrenderermeshpropswidgetbase.ui @@ -13,74 +13,72 @@ Form - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - - - QFrame::NoFrame - - - QFrame::Raised + + + + + Active Dataset - - 0 - - - 0 - - - 0 - - - 0 - - - - Scalar rendering + + + true - - - - - - - - - - - Mesh rendering - - - false + + + 0 + 0 + + + + + + + + Scalar rendering + + - - - Vector rendering - - - + + + + + Vector rendering + + + + + + + + Mesh rendering + + + false + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + @@ -96,6 +94,12 @@
mesh/qgsmeshrendererscalarsettingswidget.h
1 + + QgsMeshRendererActiveDatasetWidget + QWidget +
mesh/qgsmeshrendereractivedatasetwidget.h
+ 1 +
From 24d9e7bbe3a9409ce91cdb9734678021c5aa1b64 Mon Sep 17 00:00:00 2001 From: Peter Petrik Date: Thu, 14 Jun 2018 19:12:53 +0200 Subject: [PATCH 03/13] [mesh] Style mesh frame in GUI --- src/gui/CMakeLists.txt | 4 + .../qgsmeshrenderermeshsettingswidget.cpp | 87 +++++++++++++++++++ .../mesh/qgsmeshrenderermeshsettingswidget.h | 65 ++++++++++++++ .../qgsmeshrendererscalarsettingswidget.h | 2 +- .../qgsmeshrenderervectorsettingswidget.cpp | 68 +++++++++++++++ .../qgsmeshrenderervectorsettingswidget.h | 67 ++++++++++++++ .../mesh/qgsrenderermeshpropertieswidget.cpp | 12 ++- .../qgsmeshrenderermeshsettingswidgetbase.ui | 53 +++++++++++ ...qgsmeshrenderervectorsettingswidgetbase.ui | 28 ++++++ src/ui/mesh/qgsrenderermeshpropswidgetbase.ui | 34 +++++++- ...singlebandpseudocolorrendererwidgetbase.ui | 28 ++++++ 11 files changed, 444 insertions(+), 4 deletions(-) create mode 100644 src/gui/mesh/qgsmeshrenderermeshsettingswidget.cpp create mode 100644 src/gui/mesh/qgsmeshrenderermeshsettingswidget.h create mode 100644 src/gui/mesh/qgsmeshrenderervectorsettingswidget.cpp create mode 100644 src/gui/mesh/qgsmeshrenderervectorsettingswidget.h create mode 100644 src/ui/mesh/qgsmeshrenderermeshsettingswidgetbase.ui create mode 100644 src/ui/mesh/qgsmeshrenderervectorsettingswidgetbase.ui diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 0abe6d46e10b..7ec9e9f622c2 100755 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -1,6 +1,8 @@ SET(QGIS_GUI_SRCS mesh/qgsrenderermeshpropertieswidget.cpp + mesh/qgsmeshrenderermeshsettingswidget.cpp mesh/qgsmeshrendererscalarsettingswidget.cpp + mesh/qgsmeshrenderervectorsettingswidget.cpp mesh/qgsmeshrendereractivedatasetwidget.cpp mesh/qgsmeshdatasetgrouptree.cpp @@ -548,7 +550,9 @@ SET(QGIS_GUI_MOC_HDRS ogr/qgsvectorlayersaveasdialog.h mesh/qgsrenderermeshpropertieswidget.h + mesh/qgsmeshrenderermeshsettingswidget.h mesh/qgsmeshrendererscalarsettingswidget.h + mesh/qgsmeshrenderervectorsettingswidget.h mesh/qgsmeshrendereractivedatasetwidget.h mesh/qgsmeshdatasetgrouptree.h diff --git a/src/gui/mesh/qgsmeshrenderermeshsettingswidget.cpp b/src/gui/mesh/qgsmeshrenderermeshsettingswidget.cpp new file mode 100644 index 000000000000..5cf0a065fdaa --- /dev/null +++ b/src/gui/mesh/qgsmeshrenderermeshsettingswidget.cpp @@ -0,0 +1,87 @@ +/*************************************************************************** + qgsmeshrenderermeshsettingswidget.cpp + --------------------------------------- + begin : June 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 "qgsmeshrenderermeshsettingswidget.h" +#include + +#include "qgis.h" +#include "qgsmapcanvas.h" +#include "qgsmeshlayer.h" +#include "qgsrasterlayer.h" +#include "raster/qgscolorrampshaderwidget.h" +#include "raster/qgsrasterminmaxwidget.h" +#include "qgsrasterminmaxorigin.h" +#include "qgsmessagelog.h" +#include "qgscolorbutton.h" +#include "qgsdoublespinbox.h" + +QgsMeshRendererMeshSettingsWidget::QgsMeshRendererMeshSettingsWidget( QWidget *parent ) + : QWidget( parent ) + +{ + setupUi( this ); + + connect( mColorWidget, &QgsColorButton::colorChanged, this, &QgsMeshRendererMeshSettingsWidget::widgetChanged ); + connect( mLineWidthSpinBox, QOverload::of( &QgsDoubleSpinBox::valueChanged ), + this, &QgsMeshRendererMeshSettingsWidget::onWidthChanged ); +} + +void QgsMeshRendererMeshSettingsWidget::setLayer( QgsMeshLayer *layer, bool isTriangularMesh ) +{ + mIsTriangularMesh = isTriangularMesh; + + if ( layer != mMeshLayer ) + { + mMeshLayer = layer; + syncToLayer(); + } +} + +QgsMeshRendererMeshSettings QgsMeshRendererMeshSettingsWidget::settings() const +{ + QgsMeshRendererMeshSettings settings; + settings.setColor( mColorWidget->color() ); + settings.setLineWidth( mLineWidthSpinBox->value() ); + return settings; +} + + +QgsMeshRendererMeshSettingsWidget::~QgsMeshRendererMeshSettingsWidget() = default; + +void QgsMeshRendererMeshSettingsWidget::syncToLayer( ) +{ + if ( !mMeshLayer ) + return; + + QgsMeshRendererMeshSettings settings; + if ( mIsTriangularMesh ) + settings = mMeshLayer->rendererTriangularMeshSettings(); + else + settings = mMeshLayer->rendererTriangularMeshSettings(); + + mColorWidget->setColor( settings.color() ); + mLineWidthSpinBox->setValue( settings.lineWidth() ); +} + +void QgsMeshRendererMeshSettingsWidget::onWidthChanged( double value ) +{ + emit widgetChanged(); +} + +void QgsMeshRendererMeshSettingsWidget::refreshAfterStyleChanged() +{ +} + + diff --git a/src/gui/mesh/qgsmeshrenderermeshsettingswidget.h b/src/gui/mesh/qgsmeshrenderermeshsettingswidget.h new file mode 100644 index 000000000000..bf2fcb9e79a5 --- /dev/null +++ b/src/gui/mesh/qgsmeshrenderermeshsettingswidget.h @@ -0,0 +1,65 @@ +/*************************************************************************** + qgsmeshrenderermeshsettingswidget.h + ------------------------------------- + begin : June 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 QGSMESHRENDERERMESHSETTINGSWIDGET_H +#define QGSMESHRENDERERMESHSETTINGSWIDGET_H + +#include "ui_qgsmeshrenderermeshsettingswidgetbase.h" + +#include +#include +#include +#include "qgis_gui.h" +#include +#include "qgsmeshrenderersettings.h" + +class QgsMeshLayer; + +/** + * \ingroup gui + * \class QgsMeshRendererMeshSettingsWidget + */ +class GUI_EXPORT QgsMeshRendererMeshSettingsWidget : public QWidget, private Ui::QgsMeshRendererMeshSettingsWidgetBase +{ + Q_OBJECT + + public: + + /** + * A widget to hold the renderer Mesh settings for a mesh layer. + * \param parent Parent object + */ + QgsMeshRendererMeshSettingsWidget( QWidget *parent = nullptr ); + ~QgsMeshRendererMeshSettingsWidget(); + + void setLayer( QgsMeshLayer *layer, bool isTriangularMesh ); + + QgsMeshRendererMeshSettings settings() const; + + signals: + void widgetChanged(); + + private slots: + void refreshAfterStyleChanged(); + void syncToLayer(); + + void onWidthChanged( double value ); + + private: + QgsMeshLayer *mMeshLayer = nullptr; + bool mIsTriangularMesh = true; +}; + +#endif // QGSMESHRENDERERMESHSETTINGSWIDGET_H diff --git a/src/gui/mesh/qgsmeshrendererscalarsettingswidget.h b/src/gui/mesh/qgsmeshrendererscalarsettingswidget.h index 11c757e00462..e09fe75f7460 100644 --- a/src/gui/mesh/qgsmeshrendererscalarsettingswidget.h +++ b/src/gui/mesh/qgsmeshrendererscalarsettingswidget.h @@ -52,7 +52,7 @@ class GUI_EXPORT QgsMeshRendererScalarSettingsWidget : public QWidget, private U void widgetChanged(); public slots: - void setActiveDataset( int activeDataset ); + void setActiveDataset( int activeDatase ); private slots: void refreshAfterStyleChanged(); diff --git a/src/gui/mesh/qgsmeshrenderervectorsettingswidget.cpp b/src/gui/mesh/qgsmeshrenderervectorsettingswidget.cpp new file mode 100644 index 000000000000..ac104139a13c --- /dev/null +++ b/src/gui/mesh/qgsmeshrenderervectorsettingswidget.cpp @@ -0,0 +1,68 @@ +/*************************************************************************** + qgsmeshrenderervectorsettingswidget.cpp + --------------------------------------- + begin : June 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 "qgsmeshrenderervectorsettingswidget.h" + +#include "qgis.h" +#include "qgsmapcanvas.h" +#include "qgsmeshlayer.h" +#include "qgsrasterlayer.h" +#include "raster/qgscolorrampshaderwidget.h" +#include "raster/qgsrasterminmaxwidget.h" +#include "qgsrasterminmaxorigin.h" +#include "qgsmessagelog.h" + + +QgsMeshRendererVectorSettingsWidget::QgsMeshRendererVectorSettingsWidget( QWidget *parent ) + : QWidget( parent ) + +{ + setupUi( this ); +} + +void QgsMeshRendererVectorSettingsWidget::setLayer( QgsMeshLayer *layer ) +{ + if ( layer != mMeshLayer ) + { + mMeshLayer = layer; + syncToLayer(); + } +} + +QgsMeshRendererVectorSettings QgsMeshRendererVectorSettingsWidget::settings() const +{ + QgsMeshRendererVectorSettings settings; + return settings; +} + +void QgsMeshRendererVectorSettingsWidget::setActiveDataset( int activeDataset ) +{ + +} + + +QgsMeshRendererVectorSettingsWidget::~QgsMeshRendererVectorSettingsWidget() = default; + +void QgsMeshRendererVectorSettingsWidget::syncToLayer( ) +{ + if ( !mMeshLayer ) + return; +} + +void QgsMeshRendererVectorSettingsWidget::refreshAfterStyleChanged() +{ +} + + diff --git a/src/gui/mesh/qgsmeshrenderervectorsettingswidget.h b/src/gui/mesh/qgsmeshrenderervectorsettingswidget.h new file mode 100644 index 000000000000..d9c32d93dfe7 --- /dev/null +++ b/src/gui/mesh/qgsmeshrenderervectorsettingswidget.h @@ -0,0 +1,67 @@ +/*************************************************************************** + qgsmeshrenderervectorsettingswidget.h + ------------------------------------- + begin : June 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 QGSMESHRENDERERVECTORSETTINGSWIDGET_H +#define QGSMESHRENDERERVECTORSETTINGSWIDGET_H + +#include "ui_qgsmeshrenderervectorsettingswidgetbase.h" + +#include +#include +#include +#include "qgis_gui.h" +#include +#include "qgsmeshrenderersettings.h" + +class QgsMeshLayer; + +/** + * \ingroup gui + * \class QgsMeshRendererVectorSettingsWidget + */ +class GUI_EXPORT QgsMeshRendererVectorSettingsWidget : public QWidget, private Ui::QgsMeshRendererVectorSettingsWidgetBase +{ + Q_OBJECT + + public: + + /** + * A widget to hold the renderer Vector settings for a mesh layer. + * \param parent Parent object + */ + QgsMeshRendererVectorSettingsWidget( QWidget *parent = nullptr ); + ~QgsMeshRendererVectorSettingsWidget(); + + void setLayer( QgsMeshLayer *layer ); + + QgsMeshRendererVectorSettings settings() const; + + signals: + void widgetChanged(); + + public slots: + void setActiveDataset( int activeDataset ); + + private slots: + void refreshAfterStyleChanged(); + void syncToLayer(); + + private: + QgsMeshLayer *mMeshLayer = nullptr; + + int mActiveDataset = -1; +}; + +#endif // QGSMESHRENDERERVECTORSETTINGSWIDGET_H diff --git a/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp b/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp index 27f743209a68..8e9be104a7bb 100644 --- a/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp +++ b/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp @@ -43,12 +43,20 @@ QgsRendererMeshPropertiesWidget::QgsRendererMeshPropertiesWidget( QgsMapLayer *l mMeshRendererActiveDatasetWidget->setLayer( mMeshLayer ); mMeshRendererScalarSettingsWidget->setLayer( mMeshLayer ); + mNativeMeshSettingsWidget->setLayer( mMeshLayer, false ); + mTriangularMeshSettingsWidget->setLayer( mMeshLayer, true ); connect( mMeshRendererActiveDatasetWidget, &QgsMeshRendererActiveDatasetWidget::widgetChanged, this, &QgsPanelWidget::widgetChanged ); connect( mMeshRendererScalarSettingsWidget, &QgsMeshRendererScalarSettingsWidget::widgetChanged, this, &QgsPanelWidget::widgetChanged ); connect( mMeshRendererActiveDatasetWidget, &QgsMeshRendererActiveDatasetWidget::activeScalarDatasetChanged, mMeshRendererScalarSettingsWidget, &QgsMeshRendererScalarSettingsWidget::setActiveDataset ); + + connect( mNativeMeshSettingsWidget, &QgsMeshRendererMeshSettingsWidget::widgetChanged, + this, &QgsPanelWidget::widgetChanged ); + + connect( mTriangularMeshSettingsWidget, &QgsMeshRendererMeshSettingsWidget::widgetChanged, + this, &QgsPanelWidget::widgetChanged ); } QgsRendererMeshPropertiesWidget::~QgsRendererMeshPropertiesWidget() = default; @@ -60,13 +68,13 @@ void QgsRendererMeshPropertiesWidget::apply() // MESH bool meshRenderingIsEnabled = mMeshRendererActiveDatasetWidget->meshRenderingOn(); - QgsMeshRendererMeshSettings meshSettings = mMeshLayer->rendererNativeMeshSettings(); + QgsMeshRendererMeshSettings meshSettings = mNativeMeshSettingsWidget->settings(); meshSettings.setEnabled( meshRenderingIsEnabled ); whileBlocking( mMeshLayer )->setRendererNativeMeshSettings( meshSettings ); // TRIANGULAR MESH bool triangularMeshRenderingIsEnabled = mMeshRendererActiveDatasetWidget->triangularMeshRenderingOn(); - QgsMeshRendererMeshSettings triangularMeshSettings = mMeshLayer->rendererTriangularMeshSettings(); + QgsMeshRendererMeshSettings triangularMeshSettings = mTriangularMeshSettingsWidget->settings(); triangularMeshSettings.setEnabled( triangularMeshRenderingIsEnabled ); whileBlocking( mMeshLayer )->setRendererTriangularMeshSettings( triangularMeshSettings ); diff --git a/src/ui/mesh/qgsmeshrenderermeshsettingswidgetbase.ui b/src/ui/mesh/qgsmeshrenderermeshsettingswidgetbase.ui new file mode 100644 index 000000000000..08c6c2ba5b41 --- /dev/null +++ b/src/ui/mesh/qgsmeshrenderermeshsettingswidgetbase.ui @@ -0,0 +1,53 @@ + + + QgsMeshRendererMeshSettingsWidgetBase + + + + 0 + 0 + 328 + 71 + + + + Form + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + QgsDoubleSpinBox + QDoubleSpinBox +
qgsdoublespinbox.h
+
+ + QgsColorButton + QFrame +
qgscolorbutton.h
+ 1 +
+
+ + +
diff --git a/src/ui/mesh/qgsmeshrenderervectorsettingswidgetbase.ui b/src/ui/mesh/qgsmeshrenderervectorsettingswidgetbase.ui new file mode 100644 index 000000000000..cf4eb9139fb4 --- /dev/null +++ b/src/ui/mesh/qgsmeshrenderervectorsettingswidgetbase.ui @@ -0,0 +1,28 @@ + + + QgsMeshRendererVectorSettingsWidgetBase + + + + 0 + 0 + 344 + 267 + + + + Form + + + + + + VECTOR + + + + + + + + diff --git a/src/ui/mesh/qgsrenderermeshpropswidgetbase.ui b/src/ui/mesh/qgsrenderermeshpropswidgetbase.ui index 30b09659be25..9bc0619879e4 100644 --- a/src/ui/mesh/qgsrenderermeshpropswidgetbase.ui +++ b/src/ui/mesh/qgsrenderermeshpropswidgetbase.ui @@ -53,7 +53,11 @@ Vector rendering - + + + + +
@@ -64,6 +68,28 @@ false + + + + + Native mesh + + + + + + + + + + Triangular mesh + + + + + + + @@ -100,6 +126,12 @@
mesh/qgsmeshrendereractivedatasetwidget.h
1 + + QgsMeshRendererMeshSettingsWidget + QWidget +
mesh/qgsmeshrenderermeshsettingswidget.h
+ 1 +
diff --git a/src/ui/qgssinglebandpseudocolorrendererwidgetbase.ui b/src/ui/qgssinglebandpseudocolorrendererwidgetbase.ui index 6a40eb0958c7..b46c6de0a52a 100644 --- a/src/ui/qgssinglebandpseudocolorrendererwidgetbase.ui +++ b/src/ui/qgssinglebandpseudocolorrendererwidgetbase.ui @@ -342,6 +342,34 @@ suffix + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 709cb5127d2db8950298b89cdde5c6d71638e4a1 Mon Sep 17 00:00:00 2001 From: Peter Petrik Date: Fri, 15 Jun 2018 09:18:41 +0200 Subject: [PATCH 04/13] [mesh] Style vector arrows in GUI --- src/gui/mesh/qgsmeshdatasetgrouptree.cpp | 1 + .../qgsmeshrendereractivedatasetwidget.cpp | 3 - .../qgsmeshrenderermeshsettingswidget.cpp | 1 + .../qgsmeshrenderervectorsettingswidget.cpp | 109 ++++++++- .../qgsmeshrenderervectorsettingswidget.h | 7 + .../mesh/qgsrenderermeshpropertieswidget.cpp | 15 +- ...qgsmeshrenderervectorsettingswidgetbase.ui | 210 +++++++++++++++++- src/ui/mesh/qgsrenderermeshpropswidgetbase.ui | 8 +- 8 files changed, 335 insertions(+), 19 deletions(-) diff --git a/src/gui/mesh/qgsmeshdatasetgrouptree.cpp b/src/gui/mesh/qgsmeshdatasetgrouptree.cpp index 288208b79282..e211de70c1d9 100644 --- a/src/gui/mesh/qgsmeshdatasetgrouptree.cpp +++ b/src/gui/mesh/qgsmeshdatasetgrouptree.cpp @@ -22,6 +22,7 @@ QgsMeshDatasetGroupTree::QgsMeshDatasetGroupTree( QWidget *parent ) : QTreeWidget( parent ) { + setHeaderLabel( tr( "Datasets" ) ); setColumnCount( 1 ); connect( this, &QTreeWidget::currentItemChanged, this, &QgsMeshDatasetGroupTree::onSelectionChanged ); } diff --git a/src/gui/mesh/qgsmeshrendereractivedatasetwidget.cpp b/src/gui/mesh/qgsmeshrendereractivedatasetwidget.cpp index f3cb71bdcf67..179812641247 100644 --- a/src/gui/mesh/qgsmeshrendereractivedatasetwidget.cpp +++ b/src/gui/mesh/qgsmeshrendereractivedatasetwidget.cpp @@ -88,9 +88,6 @@ void QgsMeshRendererActiveDatasetWidget::onActiveGroupChanged() mDatasetSlider->setMinimum( 0 ); mDatasetSlider->setMaximum( datasets.size() - 1 ); mDatasetSlider->setValue( 0 ); - - qDebug() << "Size" << datasets.size() - 1; - } void QgsMeshRendererActiveDatasetWidget::onActiveDatasetChanged( int value ) diff --git a/src/gui/mesh/qgsmeshrenderermeshsettingswidget.cpp b/src/gui/mesh/qgsmeshrenderermeshsettingswidget.cpp index 5cf0a065fdaa..b77823d4607f 100644 --- a/src/gui/mesh/qgsmeshrenderermeshsettingswidget.cpp +++ b/src/gui/mesh/qgsmeshrenderermeshsettingswidget.cpp @@ -77,6 +77,7 @@ void QgsMeshRendererMeshSettingsWidget::syncToLayer( ) void QgsMeshRendererMeshSettingsWidget::onWidthChanged( double value ) { + Q_UNUSED( value ); emit widgetChanged(); } diff --git a/src/gui/mesh/qgsmeshrenderervectorsettingswidget.cpp b/src/gui/mesh/qgsmeshrenderervectorsettingswidget.cpp index ac104139a13c..04ec68fb5032 100644 --- a/src/gui/mesh/qgsmeshrenderervectorsettingswidget.cpp +++ b/src/gui/mesh/qgsmeshrenderervectorsettingswidget.cpp @@ -30,8 +30,32 @@ QgsMeshRendererVectorSettingsWidget::QgsMeshRendererVectorSettingsWidget( QWidge { setupUi( this ); + + connect( mColorWidget, &QgsColorButton::colorChanged, this, &QgsMeshRendererVectorSettingsWidget::widgetChanged ); + connect( mLineWidthSpinBox, QOverload::of( &QgsDoubleSpinBox::valueChanged ), + this, &QgsMeshRendererVectorSettingsWidget::widgetChanged ); + + connect( mShaftLengthComboBox, QOverload::of( &QComboBox::currentIndexChanged ), + this, &QgsMeshRendererVectorSettingsWidget::widgetChanged ); + + connect( mShaftLengthComboBox, QOverload::of( &QComboBox::currentIndexChanged ), + mShaftOptionsStackedWidget, &QStackedWidget::setCurrentIndex ); + + QVector widgets; + widgets << mMinMagLineEdit << mMinMagLineEdit + << mHeadWidthLineEdit << mHeadLengthLineEdit + << mMinimumShaftLineEdit << mMaximumShaftLineEdit + << mScaleShaftByFactorOfLineEdit << mShaftLengthLineEdit; + + for ( auto widget : widgets ) + { + connect( widget, &QLineEdit::textChanged, this, &QgsMeshRendererVectorSettingsWidget::widgetChanged ); + connect( widget, &QLineEdit::textEdited, this, &QgsMeshRendererVectorSettingsWidget::widgetChanged ); + } } +QgsMeshRendererVectorSettingsWidget::~QgsMeshRendererVectorSettingsWidget() = default; + void QgsMeshRendererVectorSettingsWidget::setLayer( QgsMeshLayer *layer ) { if ( layer != mMeshLayer ) @@ -44,21 +68,98 @@ void QgsMeshRendererVectorSettingsWidget::setLayer( QgsMeshLayer *layer ) QgsMeshRendererVectorSettings QgsMeshRendererVectorSettingsWidget::settings() const { QgsMeshRendererVectorSettings settings; + + // basic + settings.setColor( mColorWidget->color() ); + settings.setLineWidth( mLineWidthSpinBox->value() ); + + // filter by magnitude + double val = filterValue( mMinMagLineEdit->text(), -1 ); + settings.setFilterMin( val ); + + val = filterValue( mMinMagLineEdit->text(), -1 ); + settings.setFilterMin( val ); + + // arrow head + val = filterValue( mHeadWidthLineEdit->text(), settings.arrowHeadWidthRatio() ); + settings.setArrowHeadWidthRatio( val ); + + val = filterValue( mHeadLengthLineEdit->text(), settings.arrowHeadLengthRatio() ); + settings.setArrowHeadLengthRatio( val ); + + // shaft length + auto method = static_cast( mShaftLengthComboBox->currentIndex() ); + settings.setShaftLengthMethod( method ); + + val = filterValue( mMinimumShaftLineEdit->text(), settings.minShaftLength() ); + settings.setMinShaftLength( val ); + + val = filterValue( mMaximumShaftLineEdit->text(), settings.maxShaftLength() ); + settings.setMaxShaftLength( val ); + + val = filterValue( mScaleShaftByFactorOfLineEdit->text(), settings.scaleFactor() ); + settings.setScaleFactor( val ); + + val = filterValue( mShaftLengthLineEdit->text(), settings.fixedShaftLength() ); + settings.setFixedShaftLength( val ); + return settings; } void QgsMeshRendererVectorSettingsWidget::setActiveDataset( int activeDataset ) { - + mActiveDataset = activeDataset; } - -QgsMeshRendererVectorSettingsWidget::~QgsMeshRendererVectorSettingsWidget() = default; - void QgsMeshRendererVectorSettingsWidget::syncToLayer( ) { if ( !mMeshLayer ) return; + + QgsMeshRendererVectorSettings settings = mMeshLayer->rendererVectorSettings(); + + // basic + mColorWidget->setColor( settings.color() ); + mLineWidthSpinBox->setValue( settings.lineWidth() ); + + // filter by magnitude + if ( settings.filterMin() > 0 ) + { + mMinMagLineEdit->setText( QString::number( settings.filterMin() ) ); + } + if ( settings.filterMax() > 0 ) + { + mMaxMagLineEdit->setText( QString::number( settings.filterMax() ) ); + } + + // arrow head + mHeadWidthLineEdit->setText( QString::number( settings.arrowHeadWidthRatio() ) ); + mHeadLengthLineEdit->setText( QString::number( settings.arrowHeadLengthRatio() ) ); + + // shaft length + mShaftLengthComboBox->setCurrentIndex( settings.shaftLengthMethod() ); + + mMinimumShaftLineEdit->setText( QString::number( settings.minShaftLength() ) ); + mMaximumShaftLineEdit->setText( QString::number( settings.maxShaftLength() ) ); + mScaleShaftByFactorOfLineEdit->setText( QString::number( settings.scaleFactor() ) ); + mShaftLengthLineEdit->setText( QString::number( settings.fixedShaftLength() ) ); + +} + +double QgsMeshRendererVectorSettingsWidget::filterValue( const QString &text, double err_val ) const +{ + if ( text.isEmpty() ) + return err_val; + + bool ok; + double val = text.toDouble( &ok ); + if ( !ok ) + return err_val; + + if ( val < 0 ) + return err_val; + + return val; } void QgsMeshRendererVectorSettingsWidget::refreshAfterStyleChanged() diff --git a/src/gui/mesh/qgsmeshrenderervectorsettingswidget.h b/src/gui/mesh/qgsmeshrenderervectorsettingswidget.h index d9c32d93dfe7..1b91dfc6c64c 100644 --- a/src/gui/mesh/qgsmeshrenderervectorsettingswidget.h +++ b/src/gui/mesh/qgsmeshrenderervectorsettingswidget.h @@ -59,6 +59,13 @@ class GUI_EXPORT QgsMeshRendererVectorSettingsWidget : public QWidget, private U void syncToLayer(); private: + + /** + * convert text to double, return err_val if there is a problem + * problem is also when the value is negative + */ + double filterValue( const QString &text, double err_val ) const; + QgsMeshLayer *mMeshLayer = nullptr; int mActiveDataset = -1; diff --git a/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp b/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp index 8e9be104a7bb..a8f10eca8d0c 100644 --- a/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp +++ b/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp @@ -45,16 +45,18 @@ QgsRendererMeshPropertiesWidget::QgsRendererMeshPropertiesWidget( QgsMapLayer *l mMeshRendererScalarSettingsWidget->setLayer( mMeshLayer ); mNativeMeshSettingsWidget->setLayer( mMeshLayer, false ); mTriangularMeshSettingsWidget->setLayer( mMeshLayer, true ); - - connect( mMeshRendererActiveDatasetWidget, &QgsMeshRendererActiveDatasetWidget::widgetChanged, this, &QgsPanelWidget::widgetChanged ); - connect( mMeshRendererScalarSettingsWidget, &QgsMeshRendererScalarSettingsWidget::widgetChanged, this, &QgsPanelWidget::widgetChanged ); + mMeshRendererVectorSettingsWidget->setLayer( mMeshLayer ); connect( mMeshRendererActiveDatasetWidget, &QgsMeshRendererActiveDatasetWidget::activeScalarDatasetChanged, mMeshRendererScalarSettingsWidget, &QgsMeshRendererScalarSettingsWidget::setActiveDataset ); + connect( mMeshRendererActiveDatasetWidget, &QgsMeshRendererActiveDatasetWidget::activeVectorDatasetChanged, + mMeshRendererVectorSettingsWidget, &QgsMeshRendererVectorSettingsWidget::setActiveDataset ); + connect( mMeshRendererActiveDatasetWidget, &QgsMeshRendererActiveDatasetWidget::widgetChanged, this, &QgsPanelWidget::widgetChanged ); + connect( mMeshRendererScalarSettingsWidget, &QgsMeshRendererScalarSettingsWidget::widgetChanged, this, &QgsPanelWidget::widgetChanged ); + connect( mMeshRendererVectorSettingsWidget, &QgsMeshRendererVectorSettingsWidget::widgetChanged, this, &QgsPanelWidget::widgetChanged ); connect( mNativeMeshSettingsWidget, &QgsMeshRendererMeshSettingsWidget::widgetChanged, this, &QgsPanelWidget::widgetChanged ); - connect( mTriangularMeshSettingsWidget, &QgsMeshRendererMeshSettingsWidget::widgetChanged, this, &QgsPanelWidget::widgetChanged ); } @@ -83,7 +85,7 @@ void QgsRendererMeshPropertiesWidget::apply() whileBlocking( mMeshLayer )->setActiveScalarDataset( activeScalarDatasetIndex ); if ( activeScalarDatasetIndex != -1 ) { - QgsMeshRendererScalarSettings settings = mMeshRendererScalarSettingsWidget->settings(); + const QgsMeshRendererScalarSettings settings = mMeshRendererScalarSettingsWidget->settings(); whileBlocking( mMeshLayer )->setRendererScalarSettings( settings ); } @@ -92,7 +94,8 @@ void QgsRendererMeshPropertiesWidget::apply() whileBlocking( mMeshLayer )->setActiveVectorDataset( activeVectorDatasetIndex ); if ( activeVectorDatasetIndex != -1 ) { - //TODO take settings from widget + const QgsMeshRendererVectorSettings settings = mMeshRendererVectorSettingsWidget->settings(); + whileBlocking( mMeshLayer )->setRendererVectorSettings( settings ); } mMeshLayer->triggerRepaint(); diff --git a/src/ui/mesh/qgsmeshrenderervectorsettingswidgetbase.ui b/src/ui/mesh/qgsmeshrenderervectorsettingswidgetbase.ui index cf4eb9139fb4..524464b67d3a 100644 --- a/src/ui/mesh/qgsmeshrenderervectorsettingswidgetbase.ui +++ b/src/ui/mesh/qgsmeshrenderervectorsettingswidgetbase.ui @@ -6,8 +6,8 @@ 0 0 - 344 - 267 + 310 + 419 @@ -15,14 +15,214 @@ - - - VECTOR + + + + + + + + + + + + + Filter by Magnitude + + + false + + + + + + Min + + + + + + + + + + Max + + + + + + + + + + + + + Head Options + + + + + Width + + + + + + + + + + % of Shaft Length + + + + + + + Length + + + + + + + + + + % of Shaft Length + + + + + + + + Arrow Length + + + + + + + 0 + 0 + + + + QComboBox::AdjustToContents + + + + Defined by Min and Max + + + + + Scaled to Magnitude + + + + + Fixed + + + + + + + + 2 + + + + + + + Minimum + + + + + + + + + + Maximum + + + + + + + + + + + + + + Scale by a Factor of: + + + + + + + + + + + + + + Length + + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + QgsDoubleSpinBox + QDoubleSpinBox +
qgsdoublespinbox.h
+
+ + QgsColorButton + QFrame +
qgscolorbutton.h
+ 1 +
+
diff --git a/src/ui/mesh/qgsrenderermeshpropswidgetbase.ui b/src/ui/mesh/qgsrenderermeshpropswidgetbase.ui index 9bc0619879e4..ac9f2f24f329 100644 --- a/src/ui/mesh/qgsrenderermeshpropswidgetbase.ui +++ b/src/ui/mesh/qgsrenderermeshpropswidgetbase.ui @@ -55,7 +55,7 @@ - + @@ -132,6 +132,12 @@
mesh/qgsmeshrenderermeshsettingswidget.h
1 + + QgsMeshRendererVectorSettingsWidget + QWidget +
mesh/qgsmeshrenderervectorsettingswidget.h
+ 1 +
From b960ba0c8ebec7fbff5182187afd29cbff7634f5 Mon Sep 17 00:00:00 2001 From: Peter Petrik Date: Fri, 15 Jun 2018 14:42:54 +0200 Subject: [PATCH 05/13] [mesh] basic mesh layer properties dialog --- src/app/CMakeLists.txt | 5 + src/app/mesh/qgsmeshlayerproperties.cpp | 228 +++++++++ src/app/mesh/qgsmeshlayerproperties.h | 84 ++++ src/app/qgisapp.cpp | 14 + .../mesh/qgsmeshrendereractivedatasetwidget.h | 3 +- .../mesh/qgsmeshrenderermeshsettingswidget.h | 3 +- .../qgsmeshrendererscalarsettingswidget.h | 4 +- .../qgsmeshrenderervectorsettingswidget.h | 4 +- .../mesh/qgsrenderermeshpropertieswidget.cpp | 9 + .../mesh/qgsrenderermeshpropertieswidget.h | 1 + src/ui/mesh/qgsmeshlayerpropertiesbase.ui | 467 ++++++++++++++++++ src/ui/qgsrasterlayerpropertiesbase.ui | 210 ++++++-- 12 files changed, 982 insertions(+), 50 deletions(-) create mode 100644 src/app/mesh/qgsmeshlayerproperties.cpp create mode 100644 src/app/mesh/qgsmeshlayerproperties.h create mode 100644 src/ui/mesh/qgsmeshlayerpropertiesbase.ui diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 98ff8693188e..13daaf19a196 100755 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -209,6 +209,8 @@ SET(QGIS_APP_SRCS qgssettingstree.cpp qgsvariantdelegate.cpp qgscrashhandler.cpp + + mesh/qgsmeshlayerproperties.cpp ) SET (QGIS_APP_MOC_HDRS @@ -408,6 +410,8 @@ SET (QGIS_APP_MOC_HDRS qgssettingstree.h qgsvariantdelegate.h + + mesh/qgsmeshlayerproperties.h ) @@ -582,6 +586,7 @@ INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/src/app/pluginmanager ${CMAKE_SOURCE_DIR}/src/app/gps ${CMAKE_SOURCE_DIR}/src/app/dwg + ${CMAKE_SOURCE_DIR}/src/app/mesh ${CMAKE_SOURCE_DIR}/src/app/locator ${CMAKE_SOURCE_DIR}/src/analysis/raster ${CMAKE_SOURCE_DIR}/src/core diff --git a/src/app/mesh/qgsmeshlayerproperties.cpp b/src/app/mesh/qgsmeshlayerproperties.cpp new file mode 100644 index 000000000000..24e9439d0c03 --- /dev/null +++ b/src/app/mesh/qgsmeshlayerproperties.cpp @@ -0,0 +1,228 @@ +/*************************************************************************** + qgsmeshlayerproperties.cpp + -------------------------- + begin : Jun 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 + +#include "qgisapp.h" +#include "qgsapplication.h" +#include "qgscontrastenhancement.h" +#include "qgscoordinatetransform.h" +#include "qgscubicrasterresampler.h" +#include "qgsprojectionselectiondialog.h" +#include "qgslogger.h" +#include "qgsmapcanvas.h" +#include "qgsmaplayerstyleguiutils.h" +#include "qgsmaptoolemitpoint.h" +#include "qgsmaptopixel.h" +#include "qgsmetadatawidget.h" +#include "qgsproject.h" +#include "qgsmeshlayer.h" +#include "qgsmeshlayerproperties.h" +#include "qgssettings.h" +#include "qgsrenderermeshpropertieswidget.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +QgsMeshLayerProperties::QgsMeshLayerProperties( QgsMapLayer *lyr, QgsMapCanvas *canvas, QWidget *parent, Qt::WindowFlags fl ) + : QgsOptionsDialogBase( QStringLiteral( "MeshLayerProperties" ), parent, fl ) + , mMeshLayer( qobject_cast( lyr ) ) +{ + setupUi( this ); + mRendererMeshPropertiesWidget = new QgsRendererMeshPropertiesWidget( lyr, canvas, this ); + mOptsPage_StyleContent->layout()->addWidget( mRendererMeshPropertiesWidget ); + + + connect( mLayerOrigNameLineEd, &QLineEdit::textEdited, this, &QgsMeshLayerProperties::mLayerOrigNameLineEd_textEdited ); + connect( mCrsSelector, &QgsProjectionSelectionWidget::crsChanged, this, &QgsMeshLayerProperties::mCrsSelector_crsChanged ); + connect( mAddDatasetButton, &QPushButton::clicked, this, &QgsMeshLayerProperties::mAddDatasetButton_clicked ); + + // QgsOptionsDialogBase handles saving/restoring of geometry, splitter and current tab states, + // switching vertical tabs between icon/text to icon-only modes (splitter collapsed to left), + // and connecting QDialogButtonBox's accepted/rejected signals to dialog's accept/reject slots + initOptionsBase( false ); + + connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsMeshLayerProperties::showHelp ); + connect( lyr->styleManager(), &QgsMapLayerStyleManager::currentStyleChanged, this, &QgsMeshLayerProperties::syncToLayer ); + + connect( this, &QDialog::accepted, this, &QgsMeshLayerProperties::apply ); + connect( this, &QDialog::rejected, this, &QgsMeshLayerProperties::onCancel ); + + connect( buttonBox->button( QDialogButtonBox::Apply ), &QAbstractButton::clicked, this, &QgsMeshLayerProperties::apply ); + + if ( !mMeshLayer ) + { + return; + } + + // update based on lyr's current state + sync(); + + QgsSettings settings; + // if dialog hasn't been opened/closed yet, default to Styles tab, which is used most often + // this will be read by restoreOptionsBaseUi() + if ( !settings.contains( QStringLiteral( "/Windows/MeshLayerProperties/tab" ) ) ) + { + settings.setValue( QStringLiteral( "Windows/MeshLayerProperties/tab" ), + mOptStackedWidget->indexOf( mOptsPage_Style ) ); + } + + QString title = QString( tr( "Layer Properties - %1" ) ).arg( lyr->name() ); + + if ( !mMeshLayer->styleManager()->isDefault( mMeshLayer->styleManager()->currentStyle() ) ) + title += QStringLiteral( " (%1)" ).arg( mMeshLayer->styleManager()->currentStyle() ); + restoreOptionsBaseUi( title ); +} + +/** + \note moved from ctor + + Previously this dialog was created anew with each right-click pop-up menu + invocation. Changed so that the dialog always exists after first + invocation, and is just re-synchronized with its layer's state when + re-shown. + +*/ +void QgsMeshLayerProperties::sync() +{ + Q_ASSERT( mRendererMeshPropertiesWidget ); + + QgsSettings myQSettings; + + QgsDebugMsg( "populate general information tab" ); + /* + * Information Tab + */ + QString info; + if ( mMeshLayer && mMeshLayer->dataProvider() ) + { + info += QStringLiteral( "" ); + info += QStringLiteral( "" ).arg( tr( "Uri" ) ).arg( mMeshLayer->dataProvider()->dataSourceUri() ); + info += QStringLiteral( "" ).arg( tr( "Vertex count" ) ).arg( mMeshLayer->dataProvider()->vertexCount() ); + info += QStringLiteral( "" ).arg( tr( "Face count" ) ).arg( mMeshLayer->dataProvider()->faceCount() ); + info += QStringLiteral( "" ).arg( tr( "Dataset count" ) ).arg( mMeshLayer->dataProvider()->datasetCount() ); + info += QStringLiteral( "
%1%2
%1%2
%1%2
%1%2
" ); + } + + mInformationTextBrowser->setText( info ); + + QgsDebugMsg( "populate source tab" ); + /* + * Source Tab + */ + mLayerOrigNameLineEd->setText( mMeshLayer->name() ); + leDisplayName->setText( mMeshLayer->name() ); + + if ( mMeshLayer && mMeshLayer->dataProvider() ) + { + mUriLabel->setText( mMeshLayer->dataProvider()->dataSourceUri() ); + } + else + { + mUriLabel->setText( tr( "Not assigned" ) ); + } + + QgsDebugMsg( "populate styling tab" ); + /* + * Styling Tab + */ + mRendererMeshPropertiesWidget->syncToLayer(); + +} // QgsMeshLayerProperties::sync() + +/* + * + * PUBLIC AND PRIVATE SLOTS + * + */ +void QgsMeshLayerProperties::mAddDatasetButton_clicked() +{ + if ( !mMeshLayer || !mMeshLayer->dataProvider() ) + return; + + QString fileName = QFileDialog::getOpenFileName( this ); + if ( !fileName.isEmpty() ) + { + bool ok = mMeshLayer->dataProvider()->addDataset( fileName ); + QgsDebugMsg( QStringLiteral( "Dataset added %1, %2" ).arg( fileName ).arg( ok ) ); + if ( ok ) + sync(); + } +} + +void QgsMeshLayerProperties::apply() +{ + Q_ASSERT( mRendererMeshPropertiesWidget ); + + QgsDebugMsg( "processing general tab" ); + /* + * General Tab + */ + mMeshLayer->setName( mLayerOrigNameLineEd->text() ); + + QgsDebugMsg( "processing style tab" ); + /* + * Style Tab + */ + mRendererMeshPropertiesWidget->apply(); + + //make sure the layer is redrawn + mMeshLayer->triggerRepaint(); + + // notify the project we've made a change + QgsProject::instance()->setDirty( true ); +} + +void QgsMeshLayerProperties::onCancel() +{ + +} + +void QgsMeshLayerProperties::mCrsSelector_crsChanged( const QgsCoordinateReferenceSystem &crs ) +{ + if ( mMeshLayer ) + mMeshLayer->setCrs( crs ); +} + +void QgsMeshLayerProperties::mLayerOrigNameLineEd_textEdited( const QString &text ) +{ + leDisplayName->setText( mMeshLayer->formatLayerName( text ) ); +} + +void QgsMeshLayerProperties::syncToLayer() +{ + sync(); + mMeshLayer->triggerRepaint(); +} + +void QgsMeshLayerProperties::showHelp() +{ + QgsHelp::openHelp( QStringLiteral( "working_with_mesh/mesh_properties.html" ) ); +} diff --git a/src/app/mesh/qgsmeshlayerproperties.h b/src/app/mesh/qgsmeshlayerproperties.h new file mode 100644 index 000000000000..59f379531fed --- /dev/null +++ b/src/app/mesh/qgsmeshlayerproperties.h @@ -0,0 +1,84 @@ +/*************************************************************************** + qgsmeshlayerproperties.h + ------------------------ + begin : Jun 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 QGSMESHLAYERPROPERTIES_H +#define QGSMESHLAYERPROPERTIES_H + +#include "qgsoptionsdialogbase.h" +#include "ui_qgsmeshlayerpropertiesbase.h" +#include "qgsguiutils.h" +#include "qgshelp.h" +#include "qgsmaplayerstylemanager.h" +#include "qgsmaptoolemitpoint.h" +#include "qgis_app.h" + +class QgsPointXY; +class QgsMapLayer; +class QgsMapCanvas; +class QgsMeshLayer; +class QgsMetadataWidget; +class QgsRasterRenderer; +class QgsRasterRendererWidget; +class QgsRasterHistogramWidget; +class QgsRendererMeshPropertiesWidget; + +/** + * Property sheet for a raster map layer + */ +class APP_EXPORT QgsMeshLayerProperties : public QgsOptionsDialogBase, private Ui::QgsMeshLayerPropertiesBase +{ + Q_OBJECT + + public: + + /** + * \brief Constructor + * \param ml Map layer for which properties will be displayed + */ + QgsMeshLayerProperties( QgsMapLayer *lyr, QgsMapCanvas *canvas, QWidget *parent = nullptr, Qt::WindowFlags = QgsGuiUtils::ModalDialogFlags ); + ~QgsMeshLayerProperties() = default; + + //! Synchronize state with associated mesh layer + void sync(); + + public slots: + //TODO: Verify that these all need to be public + //! \brief Applies the settings made in the dialog without closing the box + void apply(); + //! Called when cancel button is pressed + void onCancel(); + //! \brief Slot to update layer display name as original is edited. + void mLayerOrigNameLineEd_textEdited( const QString &text ); + + private slots: + //! Help button + void showHelp(); + + //! Make GUI reflect the layer's state + void syncToLayer(); + + void mCrsSelector_crsChanged( const QgsCoordinateReferenceSystem &crs ); + void mAddDatasetButton_clicked(); + + private: + QgsRendererMeshPropertiesWidget *mRendererMeshPropertiesWidget = nullptr; + + //! \brief Pointer to the raster layer that this property dilog changes the behavior of. + QgsMeshLayer *mMeshLayer = nullptr; +}; + + +#endif // QGSMESHLAYERPROPERTIES_H diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 5b04dfbed356..57ff8227b7f7 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -230,6 +230,7 @@ Q_GUI_EXPORT extern int qt_defaultDpiX(); #include "qgsmessagebar.h" #include "qgsmessagebaritem.h" #include "qgsmeshlayer.h" +#include "qgsmeshlayerproperties.h" #include "qgsmemoryproviderutils.h" #include "qgsmimedatautils.h" #include "qgsmessagelog.h" @@ -13037,6 +13038,19 @@ void QgisApp::showLayerProperties( QgsMapLayer *mapLayer ) rasterLayerPropertiesDialog->deleteLater(); } ); } + else if ( mapLayer->type() == QgsMapLayer::MeshLayer ) + { + QgsMeshLayerProperties *meshLayerPropertiesDialog = new QgsMeshLayerProperties( mapLayer, mMapCanvas, this ); + mMapStyleWidget->blockUpdates( true ); + if ( meshLayerPropertiesDialog->exec() ) + { + activateDeactivateLayerRelatedActions( mapLayer ); + mMapStyleWidget->updateCurrentWidgetLayer(); + } + mMapStyleWidget->blockUpdates( false ); + + delete meshLayerPropertiesDialog; // delete since dialog cannot be reused without updating code + } else if ( mapLayer->type() == QgsMapLayer::VectorLayer ) // VECTOR { QgsVectorLayer *vlayer = qobject_cast( mapLayer ); diff --git a/src/gui/mesh/qgsmeshrendereractivedatasetwidget.h b/src/gui/mesh/qgsmeshrendereractivedatasetwidget.h index 8f9751ba9255..87e1e0cabe1a 100644 --- a/src/gui/mesh/qgsmeshrendereractivedatasetwidget.h +++ b/src/gui/mesh/qgsmeshrendereractivedatasetwidget.h @@ -49,6 +49,7 @@ class GUI_EXPORT QgsMeshRendererActiveDatasetWidget : public QWidget, private Ui int activeVectorDataset() const; bool meshRenderingOn() const; bool triangularMeshRenderingOn() const; + void syncToLayer(); signals: void activeScalarDatasetChanged( int index ); @@ -70,7 +71,7 @@ class GUI_EXPORT QgsMeshRendererActiveDatasetWidget : public QWidget, private Ui private: int datasetIndex() const; - void syncToLayer(); + QgsMeshLayer *mMeshLayer = nullptr; }; diff --git a/src/gui/mesh/qgsmeshrenderermeshsettingswidget.h b/src/gui/mesh/qgsmeshrenderermeshsettingswidget.h index bf2fcb9e79a5..bb8e52141d91 100644 --- a/src/gui/mesh/qgsmeshrenderermeshsettingswidget.h +++ b/src/gui/mesh/qgsmeshrenderermeshsettingswidget.h @@ -47,13 +47,14 @@ class GUI_EXPORT QgsMeshRendererMeshSettingsWidget : public QWidget, private Ui: void setLayer( QgsMeshLayer *layer, bool isTriangularMesh ); QgsMeshRendererMeshSettings settings() const; + void syncToLayer(); signals: void widgetChanged(); private slots: void refreshAfterStyleChanged(); - void syncToLayer(); + void onWidthChanged( double value ); diff --git a/src/gui/mesh/qgsmeshrendererscalarsettingswidget.h b/src/gui/mesh/qgsmeshrendererscalarsettingswidget.h index e09fe75f7460..5d33cedb4186 100644 --- a/src/gui/mesh/qgsmeshrendererscalarsettingswidget.h +++ b/src/gui/mesh/qgsmeshrendererscalarsettingswidget.h @@ -48,6 +48,8 @@ class GUI_EXPORT QgsMeshRendererScalarSettingsWidget : public QWidget, private U QgsMeshRendererScalarSettings settings() const; + void syncToLayer(); + signals: void widgetChanged(); @@ -56,7 +58,7 @@ class GUI_EXPORT QgsMeshRendererScalarSettingsWidget : public QWidget, private U private slots: void refreshAfterStyleChanged(); - void syncToLayer(); + void minMaxChanged(); void minMaxEdited(); diff --git a/src/gui/mesh/qgsmeshrenderervectorsettingswidget.h b/src/gui/mesh/qgsmeshrenderervectorsettingswidget.h index 1b91dfc6c64c..9363ea6eda64 100644 --- a/src/gui/mesh/qgsmeshrenderervectorsettingswidget.h +++ b/src/gui/mesh/qgsmeshrenderervectorsettingswidget.h @@ -48,6 +48,8 @@ class GUI_EXPORT QgsMeshRendererVectorSettingsWidget : public QWidget, private U QgsMeshRendererVectorSettings settings() const; + void syncToLayer(); + signals: void widgetChanged(); @@ -56,7 +58,7 @@ class GUI_EXPORT QgsMeshRendererVectorSettingsWidget : public QWidget, private U private slots: void refreshAfterStyleChanged(); - void syncToLayer(); + private: diff --git a/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp b/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp index a8f10eca8d0c..628ad18138ef 100644 --- a/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp +++ b/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp @@ -100,3 +100,12 @@ void QgsRendererMeshPropertiesWidget::apply() mMeshLayer->triggerRepaint(); } + +void QgsRendererMeshPropertiesWidget::syncToLayer() +{ + mMeshRendererActiveDatasetWidget->syncToLayer(); + mMeshRendererScalarSettingsWidget->syncToLayer(); + mNativeMeshSettingsWidget->syncToLayer(); + mTriangularMeshSettingsWidget->syncToLayer(); + mMeshRendererVectorSettingsWidget->syncToLayer(); +} diff --git a/src/gui/mesh/qgsrenderermeshpropertieswidget.h b/src/gui/mesh/qgsrenderermeshpropertieswidget.h index 1649ce38d16a..5f1d67cef339 100644 --- a/src/gui/mesh/qgsrenderermeshpropertieswidget.h +++ b/src/gui/mesh/qgsrenderermeshpropertieswidget.h @@ -48,6 +48,7 @@ class GUI_EXPORT QgsRendererMeshPropertiesWidget : public QgsMapLayerConfigWidge public slots: void apply() override; + void syncToLayer(); private: QgsMeshLayer *mMeshLayer = nullptr; diff --git a/src/ui/mesh/qgsmeshlayerpropertiesbase.ui b/src/ui/mesh/qgsmeshlayerpropertiesbase.ui new file mode 100644 index 000000000000..512adf0944c5 --- /dev/null +++ b/src/ui/mesh/qgsmeshlayerpropertiesbase.ui @@ -0,0 +1,467 @@ + + + QgsMeshLayerPropertiesBase + + + + 0 + 0 + 815 + 777 + + + + + 700 + 0 + + + + Raster Layer Properties + + + + + + Qt::Horizontal + + + false + + + + + 0 + 0 + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 58 + 0 + + + + + 150 + 16777215 + + + + Qt::ScrollBarAlwaysOff + + + QAbstractItemView::NoEditTriggers + + + + 32 + 32 + + + + Qt::ElideNone + + + QListView::Adjust + + + true + + + + Information + + + + :/images/themes/default/propertyicons/metadata.svg:/images/themes/default/propertyicons/metadata.svg + + + + + Source + + + + :/images/themes/default/propertyicons/system.svg:/images/themes/default/propertyicons/system.svg + + + + + Style + + + Style + + + + :/images/themes/default/propertyicons/symbology.svg:/images/themes/default/propertyicons/symbology.svg + + + + + + + + + + 1 + 0 + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + 0 + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::NoFrame + + + true + + + + + 0 + 0 + 643 + 729 + + + + + + + + + Layer name + + + + + + + + + + displayed as + + + + + + + color: #505050; +background-color: #F0F0F0; +border: 1px solid #B0B0B0; +border-radius: 2px; + + + true + + + + + + + + + 5 + + + + + Set source coordinate reference system + + + + + + + + + Qt::StrongFocus + + + + + + + + + Uri + + + + + + + + + + + + + + + + Assign extra dataset to mesh + + + + + + + Qt::Vertical + + + + 20 + 415 + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::NoFrame + + + true + + + + + 0 + 0 + 643 + 729 + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok + + + + + + + + + + + QgsFilterLineEdit + QLineEdit +
qgsfilterlineedit.h
+
+ + QgsProjectionSelectionWidget + QWidget +
qgsprojectionselectionwidget.h
+ 1 +
+ + QgsScrollArea + QScrollArea +
qgsscrollarea.h
+ 1 +
+
+ + mSearchLineEdit + mOptionsListWidget + mInformationTextBrowser + scrollArea_3 + mLayerOrigNameLineEd + leDisplayName + mCrsSelector + scrollArea + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + mOptionsListWidget + currentRowChanged(int) + mOptionsStackedWidget + setCurrentIndex(int) + + + 86 + 325 + + + 794 + 14 + + + + +
diff --git a/src/ui/qgsrasterlayerpropertiesbase.ui b/src/ui/qgsrasterlayerpropertiesbase.ui index d461550b3cc4..f90822d5df46 100644 --- a/src/ui/qgsrasterlayerpropertiesbase.ui +++ b/src/ui/qgsrasterlayerpropertiesbase.ui @@ -42,7 +42,16 @@ QFrame::Raised - + + 0 + + + 0 + + + 0 + + 0 @@ -209,7 +218,16 @@ QFrame::Raised - + + 0 + + + 0 + + + 0 + + 0 @@ -232,7 +250,16 @@ - + + 0 + + + 0 + + + 0 + + 0 @@ -248,8 +275,8 @@ 0 0 - 744 - 705 + 643 + 729 @@ -302,7 +329,7 @@ border-radius: 2px; - + Qt::StrongFocus @@ -329,7 +356,16 @@ border-radius: 2px; - + + 0 + + + 0 + + + 0 + + 0 @@ -345,8 +381,8 @@ border-radius: 2px; 0 0 - 850 - 748 + 643 + 729 @@ -361,7 +397,7 @@ border-radius: 2px; Band rendering - + rasterstyle @@ -406,13 +442,13 @@ border-radius: 2px; Color rendering - + false - + rasterstyle - + true @@ -603,7 +639,7 @@ border-radius: 2px; 16777215 - + @@ -708,13 +744,13 @@ border-radius: 2px; false - + false - + rasterstyle - + true @@ -908,7 +944,16 @@ border-radius: 2px; - + + 0 + + + 0 + + + 0 + + 0 @@ -924,8 +969,8 @@ border-radius: 2px; 0 0 - 502 - 662 + 348 + 446 @@ -940,7 +985,7 @@ border-radius: 2px; Global opacity - + rastertransp @@ -959,7 +1004,7 @@ border-radius: 2px; No data value - + rastertransp @@ -1031,7 +1076,7 @@ border-radius: 2px; Custom transparency options - + rastertransp @@ -1246,7 +1291,16 @@ border-radius: 2px; - + + 0 + + + 0 + + + 0 + + 0 @@ -1262,8 +1316,8 @@ border-radius: 2px; 0 0 - 80 - 38 + 86 + 42 @@ -1307,18 +1361,27 @@ border-radius: 2px; false - + rastergeneral - + + 11 + + + 11 + + + 11 + + 11 6 - + @@ -1393,7 +1456,16 @@ border-radius: 2px; - + + 0 + + + 0 + + + 0 + + 0 @@ -1409,8 +1481,8 @@ border-radius: 2px; 0 0 - 1004 - 254 + 553 + 193 @@ -1473,7 +1545,7 @@ border-radius: 2px; <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Noto Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Cantarell'; font-size:11pt;"><br /></span></p></body></html> @@ -1584,7 +1656,16 @@ p, li { white-space: pre-wrap; } - + + 0 + + + 0 + + + 0 + + 0 @@ -1600,8 +1681,8 @@ p, li { white-space: pre-wrap; } 0 0 - 724 - 1060 + 643 + 729 @@ -1610,7 +1691,7 @@ p, li { white-space: pre-wrap; } Description - + rastermeta @@ -1746,7 +1827,7 @@ p, li { white-space: pre-wrap; } Attribution - + vectormeta @@ -1792,7 +1873,7 @@ p, li { white-space: pre-wrap; } MetadataUrl - + vectormeta @@ -2011,7 +2092,16 @@ p, li { white-space: pre-wrap; } QFrame::Raised - + + 0 + + + 0 + + + 0 + + 0 @@ -2031,15 +2121,15 @@ p, li { white-space: pre-wrap; } - QgsCollapsibleGroupBox - QGroupBox -
qgscollapsiblegroupbox.h
+ QgsColorButton + QFrame +
qgscolorbutton.h
1
- QgsColorButton - QPushButton -
qgscolorbutton.h
+ QgsCollapsibleGroupBox + QGroupBox +
qgscollapsiblegroupbox.h
1
@@ -2155,6 +2245,34 @@ p, li { white-space: pre-wrap; } + + + + + + + + + + + + + + + + + + + + + + + + + + + + From a4bf2767842b41bfdc2f7b05e3772ef70a0f9637 Mon Sep 17 00:00:00 2001 From: Peter Petrik Date: Tue, 19 Jun 2018 10:26:23 +0200 Subject: [PATCH 06/13] add docs and cleanup includes --- src/app/mesh/qgsmeshlayerproperties.cpp | 75 ++++++------------- src/app/mesh/qgsmeshlayerproperties.h | 52 +++++++------ src/gui/mesh/qgsmeshdatasetgrouptree.cpp | 8 +- src/gui/mesh/qgsmeshdatasetgrouptree.h | 29 ++++--- .../qgsmeshrendereractivedatasetwidget.cpp | 40 +++++----- .../mesh/qgsmeshrendereractivedatasetwidget.h | 46 ++++++++---- .../qgsmeshrenderermeshsettingswidget.cpp | 17 +---- .../mesh/qgsmeshrenderermeshsettingswidget.h | 41 ++++++---- .../qgsmeshrendererscalarsettingswidget.cpp | 16 ---- .../qgsmeshrendererscalarsettingswidget.h | 26 ++++--- .../qgsmeshrenderervectorsettingswidget.cpp | 13 ---- .../qgsmeshrenderervectorsettingswidget.h | 32 ++++---- .../mesh/qgsrenderermeshpropertieswidget.cpp | 14 +--- .../mesh/qgsrenderermeshpropertieswidget.h | 16 +++- 14 files changed, 192 insertions(+), 233 deletions(-) diff --git a/src/app/mesh/qgsmeshlayerproperties.cpp b/src/app/mesh/qgsmeshlayerproperties.cpp index 24e9439d0c03..1910eabd9895 100644 --- a/src/app/mesh/qgsmeshlayerproperties.cpp +++ b/src/app/mesh/qgsmeshlayerproperties.cpp @@ -20,36 +20,19 @@ #include "qgisapp.h" #include "qgsapplication.h" -#include "qgscontrastenhancement.h" #include "qgscoordinatetransform.h" -#include "qgscubicrasterresampler.h" -#include "qgsprojectionselectiondialog.h" +#include "qgshelp.h" #include "qgslogger.h" #include "qgsmapcanvas.h" -#include "qgsmaplayerstyleguiutils.h" -#include "qgsmaptoolemitpoint.h" -#include "qgsmaptopixel.h" -#include "qgsmetadatawidget.h" -#include "qgsproject.h" +#include "qgsmaplayerstylemanager.h" #include "qgsmeshlayer.h" #include "qgsmeshlayerproperties.h" -#include "qgssettings.h" +#include "qgsproject.h" +#include "qgsprojectionselectiondialog.h" #include "qgsrenderermeshpropertieswidget.h" +#include "qgssettings.h" -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include - QgsMeshLayerProperties::QgsMeshLayerProperties( QgsMapLayer *lyr, QgsMapCanvas *canvas, QWidget *parent, Qt::WindowFlags fl ) : QgsOptionsDialogBase( QStringLiteral( "MeshLayerProperties" ), parent, fl ) @@ -59,10 +42,9 @@ QgsMeshLayerProperties::QgsMeshLayerProperties( QgsMapLayer *lyr, QgsMapCanvas * mRendererMeshPropertiesWidget = new QgsRendererMeshPropertiesWidget( lyr, canvas, this ); mOptsPage_StyleContent->layout()->addWidget( mRendererMeshPropertiesWidget ); - - connect( mLayerOrigNameLineEd, &QLineEdit::textEdited, this, &QgsMeshLayerProperties::mLayerOrigNameLineEd_textEdited ); - connect( mCrsSelector, &QgsProjectionSelectionWidget::crsChanged, this, &QgsMeshLayerProperties::mCrsSelector_crsChanged ); - connect( mAddDatasetButton, &QPushButton::clicked, this, &QgsMeshLayerProperties::mAddDatasetButton_clicked ); + connect( mLayerOrigNameLineEd, &QLineEdit::textEdited, this, &QgsMeshLayerProperties::updateLayerName ); + connect( mCrsSelector, &QgsProjectionSelectionWidget::crsChanged, this, &QgsMeshLayerProperties::changeCrs ); + connect( mAddDatasetButton, &QPushButton::clicked, this, &QgsMeshLayerProperties::addDataset ); // QgsOptionsDialogBase handles saving/restoring of geometry, splitter and current tab states, // switching vertical tabs between icon/text to icon-only modes (splitter collapsed to left), @@ -70,7 +52,7 @@ QgsMeshLayerProperties::QgsMeshLayerProperties( QgsMapLayer *lyr, QgsMapCanvas * initOptionsBase( false ); connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsMeshLayerProperties::showHelp ); - connect( lyr->styleManager(), &QgsMapLayerStyleManager::currentStyleChanged, this, &QgsMeshLayerProperties::syncToLayer ); + connect( lyr->styleManager(), &QgsMapLayerStyleManager::currentStyleChanged, this, &QgsMeshLayerProperties::syncAndRepaint ); connect( this, &QDialog::accepted, this, &QgsMeshLayerProperties::apply ); connect( this, &QDialog::rejected, this, &QgsMeshLayerProperties::onCancel ); @@ -83,7 +65,7 @@ QgsMeshLayerProperties::QgsMeshLayerProperties( QgsMapLayer *lyr, QgsMapCanvas * } // update based on lyr's current state - sync(); + syncToLayer(); QgsSettings settings; // if dialog hasn't been opened/closed yet, default to Styles tab, which is used most often @@ -101,21 +83,10 @@ QgsMeshLayerProperties::QgsMeshLayerProperties( QgsMapLayer *lyr, QgsMapCanvas * restoreOptionsBaseUi( title ); } -/** - \note moved from ctor - - Previously this dialog was created anew with each right-click pop-up menu - invocation. Changed so that the dialog always exists after first - invocation, and is just re-synchronized with its layer's state when - re-shown. - -*/ -void QgsMeshLayerProperties::sync() +void QgsMeshLayerProperties::syncToLayer() { Q_ASSERT( mRendererMeshPropertiesWidget ); - QgsSettings myQSettings; - QgsDebugMsg( "populate general information tab" ); /* * Information Tab @@ -130,7 +101,10 @@ void QgsMeshLayerProperties::sync() info += QStringLiteral( "%1%2" ).arg( tr( "Dataset count" ) ).arg( mMeshLayer->dataProvider()->datasetCount() ); info += QStringLiteral( "" ); } - + else + { + info += tr( "Invalid data provider" ); + } mInformationTextBrowser->setText( info ); QgsDebugMsg( "populate source tab" ); @@ -155,14 +129,9 @@ void QgsMeshLayerProperties::sync() */ mRendererMeshPropertiesWidget->syncToLayer(); -} // QgsMeshLayerProperties::sync() +} -/* - * - * PUBLIC AND PRIVATE SLOTS - * - */ -void QgsMeshLayerProperties::mAddDatasetButton_clicked() +void QgsMeshLayerProperties::addDataset() { if ( !mMeshLayer || !mMeshLayer->dataProvider() ) return; @@ -173,7 +142,7 @@ void QgsMeshLayerProperties::mAddDatasetButton_clicked() bool ok = mMeshLayer->dataProvider()->addDataset( fileName ); QgsDebugMsg( QStringLiteral( "Dataset added %1, %2" ).arg( fileName ).arg( ok ) ); if ( ok ) - sync(); + syncToLayer(); } } @@ -205,20 +174,20 @@ void QgsMeshLayerProperties::onCancel() } -void QgsMeshLayerProperties::mCrsSelector_crsChanged( const QgsCoordinateReferenceSystem &crs ) +void QgsMeshLayerProperties::changeCrs( const QgsCoordinateReferenceSystem &crs ) { if ( mMeshLayer ) mMeshLayer->setCrs( crs ); } -void QgsMeshLayerProperties::mLayerOrigNameLineEd_textEdited( const QString &text ) +void QgsMeshLayerProperties::updateLayerName( const QString &text ) { leDisplayName->setText( mMeshLayer->formatLayerName( text ) ); } -void QgsMeshLayerProperties::syncToLayer() +void QgsMeshLayerProperties::syncAndRepaint() { - sync(); + syncToLayer(); mMeshLayer->triggerRepaint(); } diff --git a/src/app/mesh/qgsmeshlayerproperties.h b/src/app/mesh/qgsmeshlayerproperties.h index 59f379531fed..0ae6d197bd04 100644 --- a/src/app/mesh/qgsmeshlayerproperties.h +++ b/src/app/mesh/qgsmeshlayerproperties.h @@ -17,27 +17,27 @@ #ifndef QGSMESHLAYERPROPERTIES_H #define QGSMESHLAYERPROPERTIES_H -#include "qgsoptionsdialogbase.h" #include "ui_qgsmeshlayerpropertiesbase.h" + +#include "qgsoptionsdialogbase.h" + #include "qgsguiutils.h" -#include "qgshelp.h" -#include "qgsmaplayerstylemanager.h" -#include "qgsmaptoolemitpoint.h" +// #include "qgshelp.h" +// #include "qgsmaplayerstylemanager.h" +// #include "qgsmaptoolemitpoint.h" #include "qgis_app.h" -class QgsPointXY; class QgsMapLayer; class QgsMapCanvas; class QgsMeshLayer; -class QgsMetadataWidget; -class QgsRasterRenderer; -class QgsRasterRendererWidget; -class QgsRasterHistogramWidget; class QgsRendererMeshPropertiesWidget; /** - * Property sheet for a raster map layer - */ + * Property sheet for a mesh map layer. + * Contains information, source and style tabs + * + * \since QGIS 3.4 + */ class APP_EXPORT QgsMeshLayerProperties : public QgsOptionsDialogBase, private Ui::QgsMeshLayerPropertiesBase { Q_OBJECT @@ -46,37 +46,35 @@ class APP_EXPORT QgsMeshLayerProperties : public QgsOptionsDialogBase, private U /** * \brief Constructor - * \param ml Map layer for which properties will be displayed + * \param lyr Mesh map layer for which properties will be displayed */ QgsMeshLayerProperties( QgsMapLayer *lyr, QgsMapCanvas *canvas, QWidget *parent = nullptr, Qt::WindowFlags = QgsGuiUtils::ModalDialogFlags ); ~QgsMeshLayerProperties() = default; - //! Synchronize state with associated mesh layer - void sync(); + private slots: + //! Synchronize widgets state with associated mesh layer + void syncToLayer(); - public slots: - //TODO: Verify that these all need to be public - //! \brief Applies the settings made in the dialog without closing the box + //!Applies the settings made in the dialog without closing the box void apply(); //! Called when cancel button is pressed void onCancel(); //! \brief Slot to update layer display name as original is edited. - void mLayerOrigNameLineEd_textEdited( const QString &text ); - - private slots: + void updateLayerName( const QString &text ); //! Help button void showHelp(); - - //! Make GUI reflect the layer's state - void syncToLayer(); - - void mCrsSelector_crsChanged( const QgsCoordinateReferenceSystem &crs ); - void mAddDatasetButton_clicked(); + //! Synchronize GUI state with associated mesh layer and trigger repaint + void syncAndRepaint(); + //! Change layer coordinate reference system + void changeCrs( const QgsCoordinateReferenceSystem &crs ); + //! Associate dataset to the mesh layer + void addDataset(); private: + //! Pointer to the mesh styling widget QgsRendererMeshPropertiesWidget *mRendererMeshPropertiesWidget = nullptr; - //! \brief Pointer to the raster layer that this property dilog changes the behavior of. + //! \brief Pointer to the mesh layer that this property dilog changes the behavior of. QgsMeshLayer *mMeshLayer = nullptr; }; diff --git a/src/gui/mesh/qgsmeshdatasetgrouptree.cpp b/src/gui/mesh/qgsmeshdatasetgrouptree.cpp index e211de70c1d9..f11ecfdfd2d4 100644 --- a/src/gui/mesh/qgsmeshdatasetgrouptree.cpp +++ b/src/gui/mesh/qgsmeshdatasetgrouptree.cpp @@ -27,8 +27,6 @@ QgsMeshDatasetGroupTree::QgsMeshDatasetGroupTree( QWidget *parent ) connect( this, &QTreeWidget::currentItemChanged, this, &QgsMeshDatasetGroupTree::onSelectionChanged ); } -QgsMeshDatasetGroupTree::~QgsMeshDatasetGroupTree() = default; - void QgsMeshDatasetGroupTree::setLayer( QgsMeshLayer *layer ) { if ( layer != mMeshLayer ) @@ -98,10 +96,12 @@ void QgsMeshDatasetGroupTree::repopulateTree() QVector datasets = mGroups[groupName]; qSort( datasets ); mGroups[groupName] = datasets; - QTreeWidgetItem *item = new QTreeWidgetItem( ( QTreeWidget * )0, QStringList( QString( "%1" ).arg( groupName ) ) ); - // item->setData(0, Qt::UserRole, i); + QTreeWidgetItem *item = new QTreeWidgetItem( QStringList( QString( "%1" ).arg( groupName ) ) ) ; items.append( item ); } insertTopLevelItems( 0, items ); + + if ( topLevelItem( 0 ) ) + setCurrentItem( topLevelItem( 0 ), 0, QItemSelectionModel::Select ); } diff --git a/src/gui/mesh/qgsmeshdatasetgrouptree.h b/src/gui/mesh/qgsmeshdatasetgrouptree.h index e3498e33f291..b50de05da755 100644 --- a/src/gui/mesh/qgsmeshdatasetgrouptree.h +++ b/src/gui/mesh/qgsmeshdatasetgrouptree.h @@ -16,9 +16,10 @@ #ifndef QGSMESHDATASETGROUPTREE_H #define QGSMESHDATASETGROUPTREE_H +#include "qgis_gui.h" + #include #include -#include "qgis_gui.h" #include #include @@ -27,36 +28,42 @@ class QgsMeshLayer; /** * \ingroup gui * \class QgsMeshDatasetGroupTree + * + * Tree widget for display of the mesh dataset groups. + * Dataset group is set of datasets with the same name, + * but different control variable (e.g. time) + * + * One dataset group is selected (active) + * + * \since QGIS 3.4 */ class GUI_EXPORT QgsMeshDatasetGroupTree : public QTreeWidget { Q_OBJECT public: - - /** - * A widget to hold the renderer scalar settings for a mesh layer. - * \param parent Parent object - */ QgsMeshDatasetGroupTree( QWidget *parent = nullptr ); - ~QgsMeshDatasetGroupTree(); + ~QgsMeshDatasetGroupTree() = default; + //! Associates mesh layer with the widget void setLayer( QgsMeshLayer *layer ); + //! Returns all the dataset indexes in the active group QVector datasetsInActiveGroup() const; signals: - //! Datasets in active/selected group changed + //! Selected dataset group changed void activeGroupChanged(); private slots: - void onSelectionChanged( QTreeWidgetItem *current, QTreeWidgetItem *previous ); + void onSelectionChanged( QTreeWidgetItem *current, + QTreeWidgetItem *previous ); private: void repopulateTree(); - QgsMeshLayer *mMeshLayer = nullptr; - QMap> mGroups; // value-> dataset numbers + QgsMeshLayer *mMeshLayer = nullptr; // not owned + QMap> mGroups; // group name -> dataset indices QString mActiveGroup = QString(); }; diff --git a/src/gui/mesh/qgsmeshrendereractivedatasetwidget.cpp b/src/gui/mesh/qgsmeshrendereractivedatasetwidget.cpp index 179812641247..221ec439143f 100644 --- a/src/gui/mesh/qgsmeshrendereractivedatasetwidget.cpp +++ b/src/gui/mesh/qgsmeshrendereractivedatasetwidget.cpp @@ -16,30 +16,22 @@ #include "qgsmeshrendereractivedatasetwidget.h" #include "qgis.h" -#include "qgsmapcanvas.h" #include "qgsmeshlayer.h" -#include "qgsrasterlayer.h" -#include "raster/qgscolorrampshaderwidget.h" -#include "raster/qgsrasterminmaxwidget.h" -#include "qgsrasterminmaxorigin.h" #include "qgsmessagelog.h" - +#include "qgsmeshrenderersettings.h" QgsMeshRendererActiveDatasetWidget::QgsMeshRendererActiveDatasetWidget( QWidget *parent ) : QWidget( parent ) - { setupUi( this ); connect( mDatasetGroupTree, &QgsMeshDatasetGroupTree::activeGroupChanged, this, &QgsMeshRendererActiveDatasetWidget::onActiveGroupChanged ); connect( mDatasetSlider, &QSlider::valueChanged, this, &QgsMeshRendererActiveDatasetWidget::onActiveDatasetChanged ); connect( mDisplayScalarsCheckBox, &QCheckBox::stateChanged, this, &QgsMeshRendererActiveDatasetWidget::onScalarChecked ); connect( mDisplayVectorsCheckBox, &QCheckBox::stateChanged, this, &QgsMeshRendererActiveDatasetWidget::onVectorChecked ); - connect( mDisplayNativeMeshCheckBox, &QCheckBox::stateChanged, this, &QgsMeshRendererActiveDatasetWidget::onMeshChecked ); + connect( mDisplayNativeMeshCheckBox, &QCheckBox::stateChanged, this, &QgsMeshRendererActiveDatasetWidget::onNativeMeshChecked ); connect( mDisplayTriangularMeshCheckBox, &QCheckBox::stateChanged, this, &QgsMeshRendererActiveDatasetWidget::onTringularMeshChecked ); } -QgsMeshRendererActiveDatasetWidget::~QgsMeshRendererActiveDatasetWidget() = default; - void QgsMeshRendererActiveDatasetWidget::setLayer( QgsMeshLayer *layer ) { if ( layer != mMeshLayer ) @@ -55,28 +47,30 @@ void QgsMeshRendererActiveDatasetWidget::setLayer( QgsMeshLayer *layer ) int QgsMeshRendererActiveDatasetWidget::activeScalarDataset() const { - if ( !isEnabled() || - !mDisplayScalarsCheckBox->isEnabled() || - !mDisplayScalarsCheckBox->isChecked() ) + if ( isEnabled() && + mDisplayScalarsCheckBox->isEnabled() && + mDisplayScalarsCheckBox->isChecked() ) + return datasetIndex(); + else return -1; - return datasetIndex(); } int QgsMeshRendererActiveDatasetWidget::activeVectorDataset() const { - if ( !isEnabled() || - !mDisplayVectorsCheckBox->isEnabled() || - !mDisplayVectorsCheckBox->isChecked() ) + if ( isEnabled() && + mDisplayVectorsCheckBox->isEnabled() && + mDisplayVectorsCheckBox->isChecked() ) + return datasetIndex(); + else return -1; - return datasetIndex(); } -bool QgsMeshRendererActiveDatasetWidget::meshRenderingOn() const +bool QgsMeshRendererActiveDatasetWidget::isNativeMeshEnabled() const { return isEnabled() && mDisplayNativeMeshCheckBox->isChecked(); } -bool QgsMeshRendererActiveDatasetWidget::triangularMeshRenderingOn() const +bool QgsMeshRendererActiveDatasetWidget::isTriangularMeshEnabled() const { return isEnabled() && mDisplayTriangularMeshCheckBox->isChecked(); } @@ -129,17 +123,17 @@ void QgsMeshRendererActiveDatasetWidget::onVectorChecked( int toggle ) emit widgetChanged(); } -void QgsMeshRendererActiveDatasetWidget::onMeshChecked( int toggle ) +void QgsMeshRendererActiveDatasetWidget::onNativeMeshChecked( int toggle ) { Q_UNUSED( toggle ); - emit meshRenderingOnChanged( meshRenderingOn() ); + emit nativeMeshEnabledChanged( isNativeMeshEnabled() ); emit widgetChanged(); } void QgsMeshRendererActiveDatasetWidget::onTringularMeshChecked( int toggle ) { Q_UNUSED( toggle ); - emit triangularMeshRenderingOnChange( triangularMeshRenderingOn() ); + emit triangularMeshRenderingOnChange( isTriangularMeshEnabled() ); emit widgetChanged(); } diff --git a/src/gui/mesh/qgsmeshrendereractivedatasetwidget.h b/src/gui/mesh/qgsmeshrendereractivedatasetwidget.h index 87e1e0cabe1a..8f75c635e172 100644 --- a/src/gui/mesh/qgsmeshrendereractivedatasetwidget.h +++ b/src/gui/mesh/qgsmeshrendereractivedatasetwidget.h @@ -17,19 +17,19 @@ #define QGSMESHRENDERERACTIVEDATASETWIDGET_H #include "ui_qgsmeshrendereractivedatasetwidgetbase.h" - -#include -#include -#include #include "qgis_gui.h" -#include -#include "qgsmeshrenderersettings.h" + +#include class QgsMeshLayer; /** * \ingroup gui * \class QgsMeshRendererScalarSettingsWidget + * + * + * + * \since QGIS 3.4 */ class GUI_EXPORT QgsMeshRendererActiveDatasetWidget : public QWidget, private Ui::QgsMeshRendererActiveDatasetWidgetBase { @@ -42,21 +42,41 @@ class GUI_EXPORT QgsMeshRendererActiveDatasetWidget : public QWidget, private Ui * \param parent Parent object */ QgsMeshRendererActiveDatasetWidget( QWidget *parent = nullptr ); - ~QgsMeshRendererActiveDatasetWidget(); + ~QgsMeshRendererActiveDatasetWidget() = default; + //! Associates mesh layer with the widget void setLayer( QgsMeshLayer *layer ); + + //! Gets index of the selected/active scalar dataset int activeScalarDataset() const; + + //! Gets index of the selected/active vector dataset int activeVectorDataset() const; - bool meshRenderingOn() const; - bool triangularMeshRenderingOn() const; + + //! Returns whether rendering of the native mesh is enabled + bool isNativeMeshEnabled() const; + + //! Returns whether rendering of the triangular mesh is enabled + bool isTriangularMeshEnabled() const; + + //! Synchronizes widgets state with associated mesh layer void syncToLayer(); signals: + + //! Emitted when active scalar dataset changed void activeScalarDatasetChanged( int index ); + + //! Emitted when active vector dataset changed void activeVectorDatasetChanged( int index ); - void meshRenderingOnChanged( bool on ); + + //! Emitted when rendering of the native mesh changed + void nativeMeshEnabledChanged( bool on ); + + //! Emitted when rendering of the triangular mesh changed void triangularMeshRenderingOnChange( bool on ); + //! Emitted when any settings related to rendering changed void widgetChanged(); private slots: @@ -64,16 +84,14 @@ class GUI_EXPORT QgsMeshRendererActiveDatasetWidget : public QWidget, private Ui void onActiveDatasetChanged( int value ); void onScalarChecked( int toggle ); void onVectorChecked( int toggle ); - void onMeshChecked( int toggle ); + void onNativeMeshChecked( int toggle ); void onTringularMeshChecked( int toggle ); - void updateMetadata( int datasetIndex ); private: int datasetIndex() const; - - QgsMeshLayer *mMeshLayer = nullptr; + QgsMeshLayer *mMeshLayer = nullptr; // not owned }; #endif // QGSMESHRENDERERSCALARSETTINGSWIDGET_H diff --git a/src/gui/mesh/qgsmeshrenderermeshsettingswidget.cpp b/src/gui/mesh/qgsmeshrenderermeshsettingswidget.cpp index b77823d4607f..66147f396cb2 100644 --- a/src/gui/mesh/qgsmeshrenderermeshsettingswidget.cpp +++ b/src/gui/mesh/qgsmeshrenderermeshsettingswidget.cpp @@ -35,7 +35,7 @@ QgsMeshRendererMeshSettingsWidget::QgsMeshRendererMeshSettingsWidget( QWidget *p connect( mColorWidget, &QgsColorButton::colorChanged, this, &QgsMeshRendererMeshSettingsWidget::widgetChanged ); connect( mLineWidthSpinBox, QOverload::of( &QgsDoubleSpinBox::valueChanged ), - this, &QgsMeshRendererMeshSettingsWidget::onWidthChanged ); + this, &QgsMeshRendererMeshSettingsWidget::widgetChanged ); } void QgsMeshRendererMeshSettingsWidget::setLayer( QgsMeshLayer *layer, bool isTriangularMesh ) @@ -57,9 +57,6 @@ QgsMeshRendererMeshSettings QgsMeshRendererMeshSettingsWidget::settings() const return settings; } - -QgsMeshRendererMeshSettingsWidget::~QgsMeshRendererMeshSettingsWidget() = default; - void QgsMeshRendererMeshSettingsWidget::syncToLayer( ) { if ( !mMeshLayer ) @@ -74,15 +71,3 @@ void QgsMeshRendererMeshSettingsWidget::syncToLayer( ) mColorWidget->setColor( settings.color() ); mLineWidthSpinBox->setValue( settings.lineWidth() ); } - -void QgsMeshRendererMeshSettingsWidget::onWidthChanged( double value ) -{ - Q_UNUSED( value ); - emit widgetChanged(); -} - -void QgsMeshRendererMeshSettingsWidget::refreshAfterStyleChanged() -{ -} - - diff --git a/src/gui/mesh/qgsmeshrenderermeshsettingswidget.h b/src/gui/mesh/qgsmeshrenderermeshsettingswidget.h index bb8e52141d91..bf63895ac42e 100644 --- a/src/gui/mesh/qgsmeshrenderermeshsettingswidget.h +++ b/src/gui/mesh/qgsmeshrenderermeshsettingswidget.h @@ -17,19 +17,22 @@ #define QGSMESHRENDERERMESHSETTINGSWIDGET_H #include "ui_qgsmeshrenderermeshsettingswidgetbase.h" - -#include -#include -#include -#include "qgis_gui.h" -#include #include "qgsmeshrenderersettings.h" +#include "qgis_gui.h" + +#include class QgsMeshLayer; /** * \ingroup gui * \class QgsMeshRendererMeshSettingsWidget + * + * A widget for setup of the mesh frame settings of + * the mesh layer. Can be used for both native and + * triangular mesh renderer settings. + * + * \since QGIS 3.4 */ class GUI_EXPORT QgsMeshRendererMeshSettingsWidget : public QWidget, private Ui::QgsMeshRendererMeshSettingsWidgetBase { @@ -38,28 +41,36 @@ class GUI_EXPORT QgsMeshRendererMeshSettingsWidget : public QWidget, private Ui: public: /** - * A widget to hold the renderer Mesh settings for a mesh layer. + * A widget to hold the renderer mesh settings for a mesh layer. * \param parent Parent object */ QgsMeshRendererMeshSettingsWidget( QWidget *parent = nullptr ); - ~QgsMeshRendererMeshSettingsWidget(); + ~QgsMeshRendererMeshSettingsWidget() = default; + /** + * Associates mesh layer with the widget + * \param layer mesh layer that contains mesh frame + * \param isTriangularMesh whether use settings for triangular mesh or native mesh + */ void setLayer( QgsMeshLayer *layer, bool isTriangularMesh ); + //! Returns the mesh rendering settings (native or triangular) QgsMeshRendererMeshSettings settings() const; + + //! Synchronizes widgets state with associated mesh layer void syncToLayer(); signals: + //! Mesh rendering settings changed void widgetChanged(); - private slots: - void refreshAfterStyleChanged(); - - - void onWidthChanged( double value ); - private: - QgsMeshLayer *mMeshLayer = nullptr; + QgsMeshLayer *mMeshLayer = nullptr; // not owned + + /** + * If true, the widget works for triangular (derived) mesh + * If false, the widget works for native mesh + */ bool mIsTriangularMesh = true; }; diff --git a/src/gui/mesh/qgsmeshrendererscalarsettingswidget.cpp b/src/gui/mesh/qgsmeshrendererscalarsettingswidget.cpp index 30054be47973..1057d137648c 100644 --- a/src/gui/mesh/qgsmeshrendererscalarsettingswidget.cpp +++ b/src/gui/mesh/qgsmeshrendererscalarsettingswidget.cpp @@ -16,12 +16,7 @@ #include "qgsmeshrendererscalarsettingswidget.h" #include "qgis.h" -#include "qgsmapcanvas.h" #include "qgsmeshlayer.h" -#include "qgsrasterlayer.h" -#include "raster/qgscolorrampshaderwidget.h" -#include "raster/qgsrasterminmaxwidget.h" -#include "qgsrasterminmaxorigin.h" #include "qgsmessagelog.h" @@ -36,7 +31,6 @@ QgsMeshRendererScalarSettingsWidget::QgsMeshRendererScalarSettingsWidget( QWidge connect( mScalarMaxLineEdit, &QLineEdit::textChanged, this, &QgsMeshRendererScalarSettingsWidget::minMaxChanged ); connect( mScalarMinLineEdit, &QLineEdit::textEdited, this, &QgsMeshRendererScalarSettingsWidget::minMaxEdited ); connect( mScalarMaxLineEdit, &QLineEdit::textEdited, this, &QgsMeshRendererScalarSettingsWidget::minMaxEdited ); - connect( mScalarColorRampShaderWidget, &QgsColorRampShaderWidget::widgetChanged, this, &QgsMeshRendererScalarSettingsWidget::widgetChanged ); } @@ -47,7 +41,6 @@ void QgsMeshRendererScalarSettingsWidget::setLayer( QgsMeshLayer *layer ) { mMeshLayer = layer; syncToLayer(); - connect( mMeshLayer, &QgsMapLayer::styleChanged, this, &QgsMeshRendererScalarSettingsWidget::refreshAfterStyleChanged ); } } @@ -58,9 +51,6 @@ QgsMeshRendererScalarSettings QgsMeshRendererScalarSettingsWidget::settings() co return settings; } - -QgsMeshRendererScalarSettingsWidget::~QgsMeshRendererScalarSettingsWidget() = default; - void QgsMeshRendererScalarSettingsWidget::syncToLayer( ) { if ( !mMeshLayer ) @@ -152,9 +142,3 @@ void QgsMeshRendererScalarSettingsWidget::calcMinMax( int datasetIndex, double & } } } - -void QgsMeshRendererScalarSettingsWidget::refreshAfterStyleChanged() -{ -} - - diff --git a/src/gui/mesh/qgsmeshrendererscalarsettingswidget.h b/src/gui/mesh/qgsmeshrendererscalarsettingswidget.h index 5d33cedb4186..91e70caf87b0 100644 --- a/src/gui/mesh/qgsmeshrendererscalarsettingswidget.h +++ b/src/gui/mesh/qgsmeshrendererscalarsettingswidget.h @@ -17,19 +17,22 @@ #define QGSMESHRENDERERSCALARSETTINGSWIDGET_H #include "ui_qgsmeshrendererscalarsettingswidgetbase.h" - -#include -#include -#include #include "qgis_gui.h" -#include #include "qgsmeshrenderersettings.h" +#include + class QgsMeshLayer; /** * \ingroup gui * \class QgsMeshRendererScalarSettingsWidget + * + * A widget for setup of the scalar dataset renderer settings of + * a mesh layer. The layer must be connected and an active dataset + * must be selected. + * + * \since QGIS 3.4 */ class GUI_EXPORT QgsMeshRendererScalarSettingsWidget : public QWidget, private Ui::QgsMeshRendererScalarSettingsWidgetBase { @@ -42,24 +45,26 @@ class GUI_EXPORT QgsMeshRendererScalarSettingsWidget : public QWidget, private U * \param parent Parent object */ QgsMeshRendererScalarSettingsWidget( QWidget *parent = nullptr ); - ~QgsMeshRendererScalarSettingsWidget(); + ~QgsMeshRendererScalarSettingsWidget() = default; + //! Associates mesh layer with the widget void setLayer( QgsMeshLayer *layer ); + //! Returns scalar settings QgsMeshRendererScalarSettings settings() const; + //! Synchronizes widgets state with associated mesh layer void syncToLayer(); signals: + //! Mesh rendering settings changed void widgetChanged(); public slots: + //! Set active scalar dataset to be used void setActiveDataset( int activeDatase ); private slots: - void refreshAfterStyleChanged(); - - void minMaxChanged(); void minMaxEdited(); void recalculateMinMaxButtonClicked(); @@ -68,8 +73,7 @@ class GUI_EXPORT QgsMeshRendererScalarSettingsWidget : public QWidget, private U double lineEditValue( const QLineEdit *lineEdit ) const; void calcMinMax( int datasetIndex, double &min, double &max ) const; - QgsMeshLayer *mMeshLayer = nullptr; - + QgsMeshLayer *mMeshLayer = nullptr; // not owned int mActiveDataset = -1; }; diff --git a/src/gui/mesh/qgsmeshrenderervectorsettingswidget.cpp b/src/gui/mesh/qgsmeshrenderervectorsettingswidget.cpp index 04ec68fb5032..646dd8260792 100644 --- a/src/gui/mesh/qgsmeshrenderervectorsettingswidget.cpp +++ b/src/gui/mesh/qgsmeshrenderervectorsettingswidget.cpp @@ -16,12 +16,7 @@ #include "qgsmeshrenderervectorsettingswidget.h" #include "qgis.h" -#include "qgsmapcanvas.h" #include "qgsmeshlayer.h" -#include "qgsrasterlayer.h" -#include "raster/qgscolorrampshaderwidget.h" -#include "raster/qgsrasterminmaxwidget.h" -#include "qgsrasterminmaxorigin.h" #include "qgsmessagelog.h" @@ -54,8 +49,6 @@ QgsMeshRendererVectorSettingsWidget::QgsMeshRendererVectorSettingsWidget( QWidge } } -QgsMeshRendererVectorSettingsWidget::~QgsMeshRendererVectorSettingsWidget() = default; - void QgsMeshRendererVectorSettingsWidget::setLayer( QgsMeshLayer *layer ) { if ( layer != mMeshLayer ) @@ -161,9 +154,3 @@ double QgsMeshRendererVectorSettingsWidget::filterValue( const QString &text, do return val; } - -void QgsMeshRendererVectorSettingsWidget::refreshAfterStyleChanged() -{ -} - - diff --git a/src/gui/mesh/qgsmeshrenderervectorsettingswidget.h b/src/gui/mesh/qgsmeshrenderervectorsettingswidget.h index 9363ea6eda64..3b3f814c898b 100644 --- a/src/gui/mesh/qgsmeshrenderervectorsettingswidget.h +++ b/src/gui/mesh/qgsmeshrenderervectorsettingswidget.h @@ -17,19 +17,23 @@ #define QGSMESHRENDERERVECTORSETTINGSWIDGET_H #include "ui_qgsmeshrenderervectorsettingswidgetbase.h" - -#include -#include -#include #include "qgis_gui.h" -#include #include "qgsmeshrenderersettings.h" +#include +#include + class QgsMeshLayer; /** * \ingroup gui * \class QgsMeshRendererVectorSettingsWidget + * + * A widget for setup of the vector dataset renderer settings of + * a mesh layer. The layer must be connected and an active dataset + * must be selected. + * + * \since QGIS 3.4 */ class GUI_EXPORT QgsMeshRendererVectorSettingsWidget : public QWidget, private Ui::QgsMeshRendererVectorSettingsWidgetBase { @@ -42,34 +46,34 @@ class GUI_EXPORT QgsMeshRendererVectorSettingsWidget : public QWidget, private U * \param parent Parent object */ QgsMeshRendererVectorSettingsWidget( QWidget *parent = nullptr ); - ~QgsMeshRendererVectorSettingsWidget(); + ~QgsMeshRendererVectorSettingsWidget() = default; + //! Associates mesh layer with the widget void setLayer( QgsMeshLayer *layer ); + //! Returns vector settings QgsMeshRendererVectorSettings settings() const; + //! Synchronizes widgets state with associated mesh layer void syncToLayer(); signals: + //! Mesh rendering settings changed void widgetChanged(); public slots: + //! Set active vector dataset to be used void setActiveDataset( int activeDataset ); - private slots: - void refreshAfterStyleChanged(); - - private: /** - * convert text to double, return err_val if there is a problem - * problem is also when the value is negative + * convert text to double, return err_val if + * text is not possible to convert or the value is negative */ double filterValue( const QString &text, double err_val ) const; - QgsMeshLayer *mMeshLayer = nullptr; - + QgsMeshLayer *mMeshLayer = nullptr; //not owned int mActiveDataset = -1; }; diff --git a/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp b/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp index 628ad18138ef..c7aa24cf59cb 100644 --- a/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp +++ b/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp @@ -18,13 +18,8 @@ #include "qgis.h" #include "qgsmapcanvas.h" #include "qgsmeshlayer.h" -#include "qgsrasterlayer.h" -#include "raster/qgscolorrampshaderwidget.h" -#include "raster/qgsrasterminmaxwidget.h" -#include "qgsrasterminmaxorigin.h" #include "qgsmessagelog.h" #include "qgsmeshrendererscalarsettingswidget.h" - #include "qgsmeshdatasetgrouptree.h" #include "qgsmeshrendereractivedatasetwidget.h" @@ -36,9 +31,6 @@ QgsRendererMeshPropertiesWidget::QgsRendererMeshPropertiesWidget( QgsMapLayer *l if ( !mMeshLayer ) return; - if ( !mMapCanvas ) - return; - setupUi( this ); mMeshRendererActiveDatasetWidget->setLayer( mMeshLayer ); @@ -61,21 +53,19 @@ QgsRendererMeshPropertiesWidget::QgsRendererMeshPropertiesWidget( QgsMapLayer *l this, &QgsPanelWidget::widgetChanged ); } -QgsRendererMeshPropertiesWidget::~QgsRendererMeshPropertiesWidget() = default; - void QgsRendererMeshPropertiesWidget::apply() { if ( !mMeshLayer ) return; // MESH - bool meshRenderingIsEnabled = mMeshRendererActiveDatasetWidget->meshRenderingOn(); + bool meshRenderingIsEnabled = mMeshRendererActiveDatasetWidget->isNativeMeshEnabled(); QgsMeshRendererMeshSettings meshSettings = mNativeMeshSettingsWidget->settings(); meshSettings.setEnabled( meshRenderingIsEnabled ); whileBlocking( mMeshLayer )->setRendererNativeMeshSettings( meshSettings ); // TRIANGULAR MESH - bool triangularMeshRenderingIsEnabled = mMeshRendererActiveDatasetWidget->triangularMeshRenderingOn(); + bool triangularMeshRenderingIsEnabled = mMeshRendererActiveDatasetWidget->isTriangularMeshEnabled(); QgsMeshRendererMeshSettings triangularMeshSettings = mTriangularMeshSettingsWidget->settings(); triangularMeshSettings.setEnabled( triangularMeshRenderingIsEnabled ); whileBlocking( mMeshLayer )->setRendererTriangularMeshSettings( triangularMeshSettings ); diff --git a/src/gui/mesh/qgsrenderermeshpropertieswidget.h b/src/gui/mesh/qgsrenderermeshpropertieswidget.h index 5f1d67cef339..15d688c0ef7b 100644 --- a/src/gui/mesh/qgsrenderermeshpropertieswidget.h +++ b/src/gui/mesh/qgsrenderermeshpropertieswidget.h @@ -30,6 +30,11 @@ class QgsMapCanvas; /** * \ingroup gui * \class QgsRendererMeshPropertiesWidget + * + * Widget for renderer properties of the mesh, countours (scalars) + * and vectors data associated with the mesh layer + * + * \since QGIS 3.4 */ class GUI_EXPORT QgsRendererMeshPropertiesWidget : public QgsMapLayerConfigWidget, private Ui::QgsRendererMeshPropsWidgetBase { @@ -38,20 +43,23 @@ class GUI_EXPORT QgsRendererMeshPropertiesWidget : public QgsMapLayerConfigWidge public: /** - * A widget to hold the renderer properties for a raster layer. + * A widget to hold the renderer properties for a mesh layer. * \param layer The mesh layer to style - * \param canvas The canvas object used to calculate the max and min values from the extent. + * \param canvas The canvas object used * \param parent Parent object */ QgsRendererMeshPropertiesWidget( QgsMapLayer *layer, QgsMapCanvas *canvas, QWidget *parent = nullptr ); - ~QgsRendererMeshPropertiesWidget(); + ~QgsRendererMeshPropertiesWidget() = default; public slots: + //! Applies the settings made in the dialog void apply() override; + + //! Synchronize widgets state with associated mesh layer void syncToLayer(); private: - QgsMeshLayer *mMeshLayer = nullptr; + QgsMeshLayer *mMeshLayer = nullptr; //not owned }; #endif // QGSRENDERERMESHPROPERTIESDIALOG_H From 1a404764ecab7d4cfc49fc1a70f4e4d92d336264 Mon Sep 17 00:00:00 2001 From: Peter Petrik Date: Wed, 20 Jun 2018 07:24:54 +0200 Subject: [PATCH 07/13] move mesh files to app --- src/app/CMakeLists.txt | 14 ++++++++++++-- src/{gui => app}/mesh/qgsmeshdatasetgrouptree.cpp | 0 src/{gui => app}/mesh/qgsmeshdatasetgrouptree.h | 7 ++----- .../mesh/qgsmeshrendereractivedatasetwidget.cpp | 0 .../mesh/qgsmeshrendereractivedatasetwidget.h | 4 ++-- .../mesh/qgsmeshrenderermeshsettingswidget.cpp | 0 .../mesh/qgsmeshrenderermeshsettingswidget.h | 7 ++----- .../mesh/qgsmeshrendererscalarsettingswidget.cpp | 0 .../mesh/qgsmeshrendererscalarsettingswidget.h | 9 +++------ .../mesh/qgsmeshrenderervectorsettingswidget.cpp | 0 .../mesh/qgsmeshrenderervectorsettingswidget.h | 7 ++----- .../mesh/qgsrenderermeshpropertieswidget.cpp | 0 .../mesh/qgsrenderermeshpropertieswidget.h | 7 ++----- src/gui/CMakeLists.txt | 15 --------------- 14 files changed, 25 insertions(+), 45 deletions(-) rename src/{gui => app}/mesh/qgsmeshdatasetgrouptree.cpp (100%) rename src/{gui => app}/mesh/qgsmeshdatasetgrouptree.h (93%) rename src/{gui => app}/mesh/qgsmeshrendereractivedatasetwidget.cpp (100%) rename src/{gui => app}/mesh/qgsmeshrendereractivedatasetwidget.h (97%) rename src/{gui => app}/mesh/qgsmeshrenderermeshsettingswidget.cpp (100%) rename src/{gui => app}/mesh/qgsmeshrenderermeshsettingswidget.h (94%) rename src/{gui => app}/mesh/qgsmeshrendererscalarsettingswidget.cpp (100%) rename src/{gui => app}/mesh/qgsmeshrendererscalarsettingswidget.h (94%) rename src/{gui => app}/mesh/qgsmeshrenderervectorsettingswidget.cpp (100%) rename src/{gui => app}/mesh/qgsmeshrenderervectorsettingswidget.h (94%) rename src/{gui => app}/mesh/qgsrenderermeshpropertieswidget.cpp (100%) rename src/{gui => app}/mesh/qgsrenderermeshpropertieswidget.h (93%) diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 13daaf19a196..6acdb5f604c5 100755 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -211,6 +211,12 @@ SET(QGIS_APP_SRCS qgscrashhandler.cpp mesh/qgsmeshlayerproperties.cpp + mesh/qgsrenderermeshpropertieswidget.cpp + mesh/qgsmeshrenderermeshsettingswidget.cpp + mesh/qgsmeshrendererscalarsettingswidget.cpp + mesh/qgsmeshrenderervectorsettingswidget.cpp + mesh/qgsmeshrendereractivedatasetwidget.cpp + mesh/qgsmeshdatasetgrouptree.cpp ) SET (QGIS_APP_MOC_HDRS @@ -412,6 +418,12 @@ SET (QGIS_APP_MOC_HDRS qgsvariantdelegate.h mesh/qgsmeshlayerproperties.h + mesh/qgsrenderermeshpropertieswidget.h + mesh/qgsmeshrenderermeshsettingswidget.h + mesh/qgsmeshrendererscalarsettingswidget.h + mesh/qgsmeshrenderervectorsettingswidget.h + mesh/qgsmeshrendereractivedatasetwidget.h + mesh/qgsmeshdatasetgrouptree.h ) @@ -612,7 +624,6 @@ INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/src/gui/ogr ${CMAKE_SOURCE_DIR}/src/gui/processing ${CMAKE_SOURCE_DIR}/src/gui/raster - ${CMAKE_SOURCE_DIR}/src/gui/mesh ${CMAKE_SOURCE_DIR}/src/gui/editorwidgets ${CMAKE_SOURCE_DIR}/src/gui/editorwidgets/core ${CMAKE_SOURCE_DIR}/src/gui/layertree @@ -673,7 +684,6 @@ INCLUDE_DIRECTORIES( ../gui/auth ../gui/ogr ../gui/raster - ../gui/mesh ../gui/editorwidgets ../gui/editorwidgets/core ../gui/layertree diff --git a/src/gui/mesh/qgsmeshdatasetgrouptree.cpp b/src/app/mesh/qgsmeshdatasetgrouptree.cpp similarity index 100% rename from src/gui/mesh/qgsmeshdatasetgrouptree.cpp rename to src/app/mesh/qgsmeshdatasetgrouptree.cpp diff --git a/src/gui/mesh/qgsmeshdatasetgrouptree.h b/src/app/mesh/qgsmeshdatasetgrouptree.h similarity index 93% rename from src/gui/mesh/qgsmeshdatasetgrouptree.h rename to src/app/mesh/qgsmeshdatasetgrouptree.h index b50de05da755..318970d92230 100644 --- a/src/gui/mesh/qgsmeshdatasetgrouptree.h +++ b/src/app/mesh/qgsmeshdatasetgrouptree.h @@ -16,7 +16,7 @@ #ifndef QGSMESHDATASETGROUPTREE_H #define QGSMESHDATASETGROUPTREE_H -#include "qgis_gui.h" +#include "qgis_app.h" #include #include @@ -26,9 +26,6 @@ class QgsMeshLayer; /** - * \ingroup gui - * \class QgsMeshDatasetGroupTree - * * Tree widget for display of the mesh dataset groups. * Dataset group is set of datasets with the same name, * but different control variable (e.g. time) @@ -37,7 +34,7 @@ class QgsMeshLayer; * * \since QGIS 3.4 */ -class GUI_EXPORT QgsMeshDatasetGroupTree : public QTreeWidget +class APP_EXPORT QgsMeshDatasetGroupTree : public QTreeWidget { Q_OBJECT diff --git a/src/gui/mesh/qgsmeshrendereractivedatasetwidget.cpp b/src/app/mesh/qgsmeshrendereractivedatasetwidget.cpp similarity index 100% rename from src/gui/mesh/qgsmeshrendereractivedatasetwidget.cpp rename to src/app/mesh/qgsmeshrendereractivedatasetwidget.cpp diff --git a/src/gui/mesh/qgsmeshrendereractivedatasetwidget.h b/src/app/mesh/qgsmeshrendereractivedatasetwidget.h similarity index 97% rename from src/gui/mesh/qgsmeshrendereractivedatasetwidget.h rename to src/app/mesh/qgsmeshrendereractivedatasetwidget.h index 8f75c635e172..4de3676db9cd 100644 --- a/src/gui/mesh/qgsmeshrendereractivedatasetwidget.h +++ b/src/app/mesh/qgsmeshrendereractivedatasetwidget.h @@ -17,7 +17,7 @@ #define QGSMESHRENDERERACTIVEDATASETWIDGET_H #include "ui_qgsmeshrendereractivedatasetwidgetbase.h" -#include "qgis_gui.h" +#include "qgis_app.h" #include @@ -31,7 +31,7 @@ class QgsMeshLayer; * * \since QGIS 3.4 */ -class GUI_EXPORT QgsMeshRendererActiveDatasetWidget : public QWidget, private Ui::QgsMeshRendererActiveDatasetWidgetBase +class APP_EXPORT QgsMeshRendererActiveDatasetWidget : public QWidget, private Ui::QgsMeshRendererActiveDatasetWidgetBase { Q_OBJECT diff --git a/src/gui/mesh/qgsmeshrenderermeshsettingswidget.cpp b/src/app/mesh/qgsmeshrenderermeshsettingswidget.cpp similarity index 100% rename from src/gui/mesh/qgsmeshrenderermeshsettingswidget.cpp rename to src/app/mesh/qgsmeshrenderermeshsettingswidget.cpp diff --git a/src/gui/mesh/qgsmeshrenderermeshsettingswidget.h b/src/app/mesh/qgsmeshrenderermeshsettingswidget.h similarity index 94% rename from src/gui/mesh/qgsmeshrenderermeshsettingswidget.h rename to src/app/mesh/qgsmeshrenderermeshsettingswidget.h index bf63895ac42e..ca55b5e4331e 100644 --- a/src/gui/mesh/qgsmeshrenderermeshsettingswidget.h +++ b/src/app/mesh/qgsmeshrenderermeshsettingswidget.h @@ -18,23 +18,20 @@ #include "ui_qgsmeshrenderermeshsettingswidgetbase.h" #include "qgsmeshrenderersettings.h" -#include "qgis_gui.h" +#include "qgis_app.h" #include class QgsMeshLayer; /** - * \ingroup gui - * \class QgsMeshRendererMeshSettingsWidget - * * A widget for setup of the mesh frame settings of * the mesh layer. Can be used for both native and * triangular mesh renderer settings. * * \since QGIS 3.4 */ -class GUI_EXPORT QgsMeshRendererMeshSettingsWidget : public QWidget, private Ui::QgsMeshRendererMeshSettingsWidgetBase +class APP_EXPORT QgsMeshRendererMeshSettingsWidget : public QWidget, private Ui::QgsMeshRendererMeshSettingsWidgetBase { Q_OBJECT diff --git a/src/gui/mesh/qgsmeshrendererscalarsettingswidget.cpp b/src/app/mesh/qgsmeshrendererscalarsettingswidget.cpp similarity index 100% rename from src/gui/mesh/qgsmeshrendererscalarsettingswidget.cpp rename to src/app/mesh/qgsmeshrendererscalarsettingswidget.cpp diff --git a/src/gui/mesh/qgsmeshrendererscalarsettingswidget.h b/src/app/mesh/qgsmeshrendererscalarsettingswidget.h similarity index 94% rename from src/gui/mesh/qgsmeshrendererscalarsettingswidget.h rename to src/app/mesh/qgsmeshrendererscalarsettingswidget.h index 91e70caf87b0..e46280343216 100644 --- a/src/gui/mesh/qgsmeshrendererscalarsettingswidget.h +++ b/src/app/mesh/qgsmeshrendererscalarsettingswidget.h @@ -17,24 +17,21 @@ #define QGSMESHRENDERERSCALARSETTINGSWIDGET_H #include "ui_qgsmeshrendererscalarsettingswidgetbase.h" -#include "qgis_gui.h" +#include "qgis_app.h" #include "qgsmeshrenderersettings.h" #include class QgsMeshLayer; -/** - * \ingroup gui - * \class QgsMeshRendererScalarSettingsWidget - * +/*! * A widget for setup of the scalar dataset renderer settings of * a mesh layer. The layer must be connected and an active dataset * must be selected. * * \since QGIS 3.4 */ -class GUI_EXPORT QgsMeshRendererScalarSettingsWidget : public QWidget, private Ui::QgsMeshRendererScalarSettingsWidgetBase +class APP_EXPORT QgsMeshRendererScalarSettingsWidget : public QWidget, private Ui::QgsMeshRendererScalarSettingsWidgetBase { Q_OBJECT diff --git a/src/gui/mesh/qgsmeshrenderervectorsettingswidget.cpp b/src/app/mesh/qgsmeshrenderervectorsettingswidget.cpp similarity index 100% rename from src/gui/mesh/qgsmeshrenderervectorsettingswidget.cpp rename to src/app/mesh/qgsmeshrenderervectorsettingswidget.cpp diff --git a/src/gui/mesh/qgsmeshrenderervectorsettingswidget.h b/src/app/mesh/qgsmeshrenderervectorsettingswidget.h similarity index 94% rename from src/gui/mesh/qgsmeshrenderervectorsettingswidget.h rename to src/app/mesh/qgsmeshrenderervectorsettingswidget.h index 3b3f814c898b..400b33171d9f 100644 --- a/src/gui/mesh/qgsmeshrenderervectorsettingswidget.h +++ b/src/app/mesh/qgsmeshrenderervectorsettingswidget.h @@ -17,7 +17,7 @@ #define QGSMESHRENDERERVECTORSETTINGSWIDGET_H #include "ui_qgsmeshrenderervectorsettingswidgetbase.h" -#include "qgis_gui.h" +#include "qgis_app.h" #include "qgsmeshrenderersettings.h" #include @@ -26,16 +26,13 @@ class QgsMeshLayer; /** - * \ingroup gui - * \class QgsMeshRendererVectorSettingsWidget - * * A widget for setup of the vector dataset renderer settings of * a mesh layer. The layer must be connected and an active dataset * must be selected. * * \since QGIS 3.4 */ -class GUI_EXPORT QgsMeshRendererVectorSettingsWidget : public QWidget, private Ui::QgsMeshRendererVectorSettingsWidgetBase +class APP_EXPORT QgsMeshRendererVectorSettingsWidget : public QWidget, private Ui::QgsMeshRendererVectorSettingsWidgetBase { Q_OBJECT diff --git a/src/gui/mesh/qgsrenderermeshpropertieswidget.cpp b/src/app/mesh/qgsrenderermeshpropertieswidget.cpp similarity index 100% rename from src/gui/mesh/qgsrenderermeshpropertieswidget.cpp rename to src/app/mesh/qgsrenderermeshpropertieswidget.cpp diff --git a/src/gui/mesh/qgsrenderermeshpropertieswidget.h b/src/app/mesh/qgsrenderermeshpropertieswidget.h similarity index 93% rename from src/gui/mesh/qgsrenderermeshpropertieswidget.h rename to src/app/mesh/qgsrenderermeshpropertieswidget.h index 15d688c0ef7b..294fb35e9984 100644 --- a/src/gui/mesh/qgsrenderermeshpropertieswidget.h +++ b/src/app/mesh/qgsrenderermeshpropertieswidget.h @@ -21,22 +21,19 @@ #include "ui_qgsrenderermeshpropswidgetbase.h" #include "qgsmaplayerconfigwidget.h" -#include "qgis_gui.h" +#include "qgis_app.h" #include class QgsMeshLayer; class QgsMapCanvas; /** - * \ingroup gui - * \class QgsRendererMeshPropertiesWidget - * * Widget for renderer properties of the mesh, countours (scalars) * and vectors data associated with the mesh layer * * \since QGIS 3.4 */ -class GUI_EXPORT QgsRendererMeshPropertiesWidget : public QgsMapLayerConfigWidget, private Ui::QgsRendererMeshPropsWidgetBase +class APP_EXPORT QgsRendererMeshPropertiesWidget : public QgsMapLayerConfigWidget, private Ui::QgsRendererMeshPropsWidgetBase { Q_OBJECT diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 7ec9e9f622c2..db376c16c3e7 100755 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -1,11 +1,4 @@ SET(QGIS_GUI_SRCS - mesh/qgsrenderermeshpropertieswidget.cpp - mesh/qgsmeshrenderermeshsettingswidget.cpp - mesh/qgsmeshrendererscalarsettingswidget.cpp - mesh/qgsmeshrenderervectorsettingswidget.cpp - mesh/qgsmeshrendereractivedatasetwidget.cpp - mesh/qgsmeshdatasetgrouptree.cpp - raster/qgscolorrampshaderwidget.cpp raster/qgsmultibandcolorrendererwidget.cpp raster/qgspalettedrendererwidget.cpp @@ -549,13 +542,6 @@ SET(QGIS_GUI_MOC_HDRS ogr/qgsnewogrconnection.h ogr/qgsvectorlayersaveasdialog.h - mesh/qgsrenderermeshpropertieswidget.h - mesh/qgsmeshrenderermeshsettingswidget.h - mesh/qgsmeshrendererscalarsettingswidget.h - mesh/qgsmeshrenderervectorsettingswidget.h - mesh/qgsmeshrendereractivedatasetwidget.h - mesh/qgsmeshdatasetgrouptree.h - raster/qgscolorrampshaderwidget.h raster/qgsmultibandcolorrendererwidget.h raster/qgspalettedrendererwidget.h @@ -894,7 +880,6 @@ INCLUDE_DIRECTORIES( ${CMAKE_SOURCE_DIR}/src/gui/effects ${CMAKE_SOURCE_DIR}/src/gui/layertree ${CMAKE_SOURCE_DIR}/src/gui/layout - ${CMAKE_SOURCE_DIR}/src/gui/mesh ${CMAKE_SOURCE_DIR}/src/gui/ogr ${CMAKE_SOURCE_DIR}/src/gui/processing ${CMAKE_SOURCE_DIR}/src/core From ff670e00185cddd7e11a924058175bc270502d61 Mon Sep 17 00:00:00 2001 From: Peter Petrik Date: Wed, 20 Jun 2018 14:19:48 +0200 Subject: [PATCH 08/13] various code cleaning --- .../mesh/qgsmeshrenderersettings.sip.in | 17 +- .../raster/qgscolorrampshader.sip.in | 12 +- src/app/CMakeLists.txt | 4 +- ...ee.cpp => qgsmeshdatasetgrouptreeview.cpp} | 67 +++--- ...uptree.h => qgsmeshdatasetgrouptreeview.h} | 22 +- src/app/mesh/qgsmeshlayerproperties.cpp | 28 +-- src/app/mesh/qgsmeshlayerproperties.h | 10 - .../qgsmeshrendereractivedatasetwidget.cpp | 10 +- .../mesh/qgsmeshrendereractivedatasetwidget.h | 9 +- .../mesh/qgsmeshrenderermeshsettingswidget.h | 2 - .../qgsmeshrendererscalarsettingswidget.cpp | 9 +- .../qgsmeshrendererscalarsettingswidget.h | 2 - .../qgsmeshrenderervectorsettingswidget.h | 2 - .../mesh/qgsrenderermeshpropertieswidget.cpp | 2 +- .../mesh/qgsrenderermeshpropertieswidget.h | 2 - src/app/qgisapp.cpp | 8 +- src/app/qgslayerstylingwidget.cpp | 4 +- src/core/mesh/qgsmeshlayerrenderer.cpp | 39 ++-- src/core/mesh/qgsmeshlayerrenderer.h | 3 +- src/core/mesh/qgsmeshrenderersettings.cpp | 17 +- src/core/mesh/qgsmeshrenderersettings.h | 19 +- src/core/mesh/qgsmeshvectorrenderer.cpp | 10 +- src/core/mesh/qgsmeshvectorrenderer.h | 4 - src/core/raster/qgscolorrampshader.cpp | 25 +-- src/core/raster/qgscolorrampshader.h | 9 +- src/gui/raster/qgscolorrampshaderwidget.cpp | 210 +++--------------- src/gui/raster/qgscolorrampshaderwidget.h | 12 +- src/ui/mesh/qgsmeshlayerpropertiesbase.ui | 10 +- .../qgsmeshrendereractivedatasetwidgetbase.ui | 8 +- 29 files changed, 194 insertions(+), 382 deletions(-) rename src/app/mesh/{qgsmeshdatasetgrouptree.cpp => qgsmeshdatasetgrouptreeview.cpp} (57%) rename src/app/mesh/{qgsmeshdatasetgrouptree.h => qgsmeshdatasetgrouptreeview.h} (78%) diff --git a/python/core/auto_generated/mesh/qgsmeshrenderersettings.sip.in b/python/core/auto_generated/mesh/qgsmeshrenderersettings.sip.in index 0d76438b81c0..2f184a84eff4 100644 --- a/python/core/auto_generated/mesh/qgsmeshrenderersettings.sip.in +++ b/python/core/auto_generated/mesh/qgsmeshrenderersettings.sip.in @@ -74,24 +74,19 @@ Represents a mesh renderer settings for scalar datasets #include "qgsmeshrenderersettings.h" %End public: - QgsColorRampShader *colorRampShader() const; + QgsColorRampShader colorRampShader() const; %Docstring -Returns color ramp shader function. +Returns color ramp shader function %End - void setColorRampShader( QgsColorRampShader *shader ); + void setColorRampShader( QgsColorRampShader shader ); %Docstring -Sets color ramp shader function. Takes ownership +Sets color ramp shader function %End - QgsRasterMinMaxOrigin minMaxOrigin() const; -%Docstring -Returns raster min max origin -%End - void setMinMaxOrigin( const QgsRasterMinMaxOrigin &minMaxOrigin ); + bool isEnabled() const; %Docstring -Sets raster min max origin +Returns whether color ramp has any items assigned %End - }; class QgsMeshRendererVectorSettings diff --git a/python/core/auto_generated/raster/qgscolorrampshader.sip.in b/python/core/auto_generated/raster/qgscolorrampshader.sip.in index 45c49148b052..6fdb86640eed 100644 --- a/python/core/auto_generated/raster/qgscolorrampshader.sip.in +++ b/python/core/auto_generated/raster/qgscolorrampshader.sip.in @@ -54,11 +54,6 @@ Copy constructor %End - QgsColorRampShader *clone() const /Factory/; -%Docstring -Clones this shader, return new instance -%End - struct ColorRampItem { ColorRampItem(); @@ -97,6 +92,13 @@ Returns the color ramp type as a string. void setColorRampType( QgsColorRampShader::Type colorRampType ); %Docstring Sets the color ramp type +%End + + bool isEmpty() const; +%Docstring +Whether the color ramp contains any items + +.. versionadded:: 3.4 %End QgsColorRamp *sourceColorRamp() const /Factory/; diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 6acdb5f604c5..c75cd2fda8f9 100755 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -216,7 +216,7 @@ SET(QGIS_APP_SRCS mesh/qgsmeshrendererscalarsettingswidget.cpp mesh/qgsmeshrenderervectorsettingswidget.cpp mesh/qgsmeshrendereractivedatasetwidget.cpp - mesh/qgsmeshdatasetgrouptree.cpp + mesh/qgsmeshdatasetgrouptreeview.cpp ) SET (QGIS_APP_MOC_HDRS @@ -423,7 +423,7 @@ SET (QGIS_APP_MOC_HDRS mesh/qgsmeshrendererscalarsettingswidget.h mesh/qgsmeshrenderervectorsettingswidget.h mesh/qgsmeshrendereractivedatasetwidget.h - mesh/qgsmeshdatasetgrouptree.h + mesh/qgsmeshdatasetgrouptreeview.h ) diff --git a/src/app/mesh/qgsmeshdatasetgrouptree.cpp b/src/app/mesh/qgsmeshdatasetgrouptreeview.cpp similarity index 57% rename from src/app/mesh/qgsmeshdatasetgrouptree.cpp rename to src/app/mesh/qgsmeshdatasetgrouptreeview.cpp index f11ecfdfd2d4..e6a262b63b67 100644 --- a/src/app/mesh/qgsmeshdatasetgrouptree.cpp +++ b/src/app/mesh/qgsmeshdatasetgrouptreeview.cpp @@ -1,6 +1,6 @@ /*************************************************************************** - qgsmeshdatasetgrouptree.cpp - --------------------------- + qgsmeshdatasetgrouptreeview.cpp + ------------------------------- begin : June 2018 copyright : (C) 2018 by Peter Petrik email : zilolv at gmail dot com @@ -13,21 +13,33 @@ * * ***************************************************************************/ -#include "qgsmeshdatasetgrouptree.h" +#include "qgsmeshdatasetgrouptreeview.h" #include "qgis.h" #include "qgsmeshlayer.h" -QgsMeshDatasetGroupTree::QgsMeshDatasetGroupTree( QWidget *parent ) - : QTreeWidget( parent ) +#include +#include +static QList prepareRow(const QString &str) { - setHeaderLabel( tr( "Datasets" ) ); - setColumnCount( 1 ); - connect( this, &QTreeWidget::currentItemChanged, this, &QgsMeshDatasetGroupTree::onSelectionChanged ); + QList rowItems; + rowItems << new QStandardItem(str); + return rowItems; } -void QgsMeshDatasetGroupTree::setLayer( QgsMeshLayer *layer ) +QgsMeshDatasetGroupTreeView::QgsMeshDatasetGroupTreeView( QWidget *parent ) + : QTreeView( parent ) +{ + setSelectionMode(QAbstractItemView::SingleSelection) ; + connect( selectionModel(), + &QItemSelectionModel::selectionChanged, + this, + &QgsMeshDatasetGroupTreeView::onSelectionChanged + ); +} + +void QgsMeshDatasetGroupTreeView::setLayer( QgsMeshLayer *layer ) { if ( layer != mMeshLayer ) { @@ -36,7 +48,7 @@ void QgsMeshDatasetGroupTree::setLayer( QgsMeshLayer *layer ) } } -QVector QgsMeshDatasetGroupTree::datasetsInActiveGroup() const +QVector QgsMeshDatasetGroupTreeView::datasetsInActiveGroup() const { if ( mGroups.constFind( mActiveGroup ) == mGroups.constEnd() ) return QVector(); @@ -44,27 +56,33 @@ QVector QgsMeshDatasetGroupTree::datasetsInActiveGroup() const return mGroups[mActiveGroup]; } -void QgsMeshDatasetGroupTree::onSelectionChanged( QTreeWidgetItem *current, QTreeWidgetItem *previous ) +void QgsMeshDatasetGroupTreeView::onSelectionChanged( const QItemSelection &selected, const QItemSelection &deselected ) { - Q_UNUSED( previous ); + Q_UNUSED( deselected ); - if ( current ) - { - mActiveGroup = current->text( 0 ); + if ( selected.isEmpty() ) { + mActiveGroup = QString(); + return; } - else - { + + if ( selected.first().indexes().isEmpty() ) { mActiveGroup = QString(); + return; } + QModelIndex index = selected.first().indexes().first(); //single selection only + QStandardItem* item = mModel.itemFromIndex(index); + QString name = item->text(); + mActiveGroup = name; + emit activeGroupChanged(); } -void QgsMeshDatasetGroupTree::repopulateTree() +void QgsMeshDatasetGroupTreeView::repopulateTree() { mGroups.clear(); mActiveGroup.clear(); - clear(); + mModel.clear(); if ( !mMeshLayer || !mMeshLayer->dataProvider() ) return; @@ -89,19 +107,18 @@ void QgsMeshDatasetGroupTree::repopulateTree() QStringList groupsSorted = mGroups.keys(); qSort( groupsSorted.begin(), groupsSorted.end() ); - QList items; for ( int i = 0; i < groupsSorted.size(); ++i ) { QString groupName = groupsSorted[i]; QVector datasets = mGroups[groupName]; qSort( datasets ); mGroups[groupName] = datasets; - QTreeWidgetItem *item = new QTreeWidgetItem( QStringList( QString( "%1" ).arg( groupName ) ) ) ; - items.append( item ); + QString name = QString( "%1" ).arg( groupName ); + QStandardItem *root = mModel.invisibleRootItem(); + root->appendRow(prepareRow(name)); } - insertTopLevelItems( 0, items ); - if ( topLevelItem( 0 ) ) - setCurrentItem( topLevelItem( 0 ), 0, QItemSelectionModel::Select ); + if (groupsSorted.size() > 0) + setCurrentIndex(mModel.index(0, 0)); } diff --git a/src/app/mesh/qgsmeshdatasetgrouptree.h b/src/app/mesh/qgsmeshdatasetgrouptreeview.h similarity index 78% rename from src/app/mesh/qgsmeshdatasetgrouptree.h rename to src/app/mesh/qgsmeshdatasetgrouptreeview.h index 318970d92230..08af150ba4bf 100644 --- a/src/app/mesh/qgsmeshdatasetgrouptree.h +++ b/src/app/mesh/qgsmeshdatasetgrouptreeview.h @@ -1,6 +1,6 @@ /*************************************************************************** - qgsmeshdatasetgrouptree.h - ------------------------- + qgsmeshdatasetgrouptreeview.h + ----------------------------- begin : June 2018 copyright : (C) 2018 by Peter Petrik email : zilolv at gmail dot com @@ -19,9 +19,11 @@ #include "qgis_app.h" #include -#include +#include #include #include +#include +#include class QgsMeshLayer; @@ -31,16 +33,14 @@ class QgsMeshLayer; * but different control variable (e.g. time) * * One dataset group is selected (active) - * - * \since QGIS 3.4 */ -class APP_EXPORT QgsMeshDatasetGroupTree : public QTreeWidget +class APP_EXPORT QgsMeshDatasetGroupTreeView : public QTreeView { Q_OBJECT public: - QgsMeshDatasetGroupTree( QWidget *parent = nullptr ); - ~QgsMeshDatasetGroupTree() = default; + QgsMeshDatasetGroupTreeView( QWidget *parent = nullptr ); + ~QgsMeshDatasetGroupTreeView() = default; //! Associates mesh layer with the widget void setLayer( QgsMeshLayer *layer ); @@ -53,15 +53,15 @@ class APP_EXPORT QgsMeshDatasetGroupTree : public QTreeWidget void activeGroupChanged(); private slots: - void onSelectionChanged( QTreeWidgetItem *current, - QTreeWidgetItem *previous ); + void onSelectionChanged( const QItemSelection &selected, const QItemSelection &deselected ); private: void repopulateTree(); + QStandardItemModel mModel; QgsMeshLayer *mMeshLayer = nullptr; // not owned QMap> mGroups; // group name -> dataset indices - QString mActiveGroup = QString(); + QString mActiveGroup; }; #endif // QGSMESHRENDERERSCALARSETTINGSWIDGET_H diff --git a/src/app/mesh/qgsmeshlayerproperties.cpp b/src/app/mesh/qgsmeshlayerproperties.cpp index 1910eabd9895..a9b2008c6219 100644 --- a/src/app/mesh/qgsmeshlayerproperties.cpp +++ b/src/app/mesh/qgsmeshlayerproperties.cpp @@ -38,6 +38,8 @@ QgsMeshLayerProperties::QgsMeshLayerProperties( QgsMapLayer *lyr, QgsMapCanvas * : QgsOptionsDialogBase( QStringLiteral( "MeshLayerProperties" ), parent, fl ) , mMeshLayer( qobject_cast( lyr ) ) { + Q_ASSERT( mMeshLayer ); + setupUi( this ); mRendererMeshPropertiesWidget = new QgsRendererMeshPropertiesWidget( lyr, canvas, this ); mOptsPage_StyleContent->layout()->addWidget( mRendererMeshPropertiesWidget ); @@ -50,20 +52,11 @@ QgsMeshLayerProperties::QgsMeshLayerProperties( QgsMapLayer *lyr, QgsMapCanvas * // switching vertical tabs between icon/text to icon-only modes (splitter collapsed to left), // and connecting QDialogButtonBox's accepted/rejected signals to dialog's accept/reject slots initOptionsBase( false ); - - connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsMeshLayerProperties::showHelp ); connect( lyr->styleManager(), &QgsMapLayerStyleManager::currentStyleChanged, this, &QgsMeshLayerProperties::syncAndRepaint ); connect( this, &QDialog::accepted, this, &QgsMeshLayerProperties::apply ); - connect( this, &QDialog::rejected, this, &QgsMeshLayerProperties::onCancel ); - connect( buttonBox->button( QDialogButtonBox::Apply ), &QAbstractButton::clicked, this, &QgsMeshLayerProperties::apply ); - if ( !mMeshLayer ) - { - return; - } - // update based on lyr's current state syncToLayer(); @@ -92,7 +85,7 @@ void QgsMeshLayerProperties::syncToLayer() * Information Tab */ QString info; - if ( mMeshLayer && mMeshLayer->dataProvider() ) + if ( mMeshLayer->dataProvider() ) { info += QStringLiteral( "" ); info += QStringLiteral( "" ).arg( tr( "Uri" ) ).arg( mMeshLayer->dataProvider()->dataSourceUri() ); @@ -133,7 +126,7 @@ void QgsMeshLayerProperties::syncToLayer() void QgsMeshLayerProperties::addDataset() { - if ( !mMeshLayer || !mMeshLayer->dataProvider() ) + if ( !mMeshLayer->dataProvider() ) return; QString fileName = QFileDialog::getOpenFileName( this ); @@ -169,15 +162,9 @@ void QgsMeshLayerProperties::apply() QgsProject::instance()->setDirty( true ); } -void QgsMeshLayerProperties::onCancel() -{ - -} - void QgsMeshLayerProperties::changeCrs( const QgsCoordinateReferenceSystem &crs ) { - if ( mMeshLayer ) - mMeshLayer->setCrs( crs ); + mMeshLayer->setCrs( crs ); } void QgsMeshLayerProperties::updateLayerName( const QString &text ) @@ -190,8 +177,3 @@ void QgsMeshLayerProperties::syncAndRepaint() syncToLayer(); mMeshLayer->triggerRepaint(); } - -void QgsMeshLayerProperties::showHelp() -{ - QgsHelp::openHelp( QStringLiteral( "working_with_mesh/mesh_properties.html" ) ); -} diff --git a/src/app/mesh/qgsmeshlayerproperties.h b/src/app/mesh/qgsmeshlayerproperties.h index 0ae6d197bd04..a3d6d84d399d 100644 --- a/src/app/mesh/qgsmeshlayerproperties.h +++ b/src/app/mesh/qgsmeshlayerproperties.h @@ -20,11 +20,7 @@ #include "ui_qgsmeshlayerpropertiesbase.h" #include "qgsoptionsdialogbase.h" - #include "qgsguiutils.h" -// #include "qgshelp.h" -// #include "qgsmaplayerstylemanager.h" -// #include "qgsmaptoolemitpoint.h" #include "qgis_app.h" class QgsMapLayer; @@ -35,8 +31,6 @@ class QgsRendererMeshPropertiesWidget; /** * Property sheet for a mesh map layer. * Contains information, source and style tabs - * - * \since QGIS 3.4 */ class APP_EXPORT QgsMeshLayerProperties : public QgsOptionsDialogBase, private Ui::QgsMeshLayerPropertiesBase { @@ -57,12 +51,8 @@ class APP_EXPORT QgsMeshLayerProperties : public QgsOptionsDialogBase, private U //!Applies the settings made in the dialog without closing the box void apply(); - //! Called when cancel button is pressed - void onCancel(); //! \brief Slot to update layer display name as original is edited. void updateLayerName( const QString &text ); - //! Help button - void showHelp(); //! Synchronize GUI state with associated mesh layer and trigger repaint void syncAndRepaint(); //! Change layer coordinate reference system diff --git a/src/app/mesh/qgsmeshrendereractivedatasetwidget.cpp b/src/app/mesh/qgsmeshrendereractivedatasetwidget.cpp index 221ec439143f..5458eabc205a 100644 --- a/src/app/mesh/qgsmeshrendereractivedatasetwidget.cpp +++ b/src/app/mesh/qgsmeshrendereractivedatasetwidget.cpp @@ -24,7 +24,7 @@ QgsMeshRendererActiveDatasetWidget::QgsMeshRendererActiveDatasetWidget( QWidget : QWidget( parent ) { setupUi( this ); - connect( mDatasetGroupTree, &QgsMeshDatasetGroupTree::activeGroupChanged, this, &QgsMeshRendererActiveDatasetWidget::onActiveGroupChanged ); + connect( mDatasetGroupTreeView, &QgsMeshDatasetGroupTreeView::activeGroupChanged, this, &QgsMeshRendererActiveDatasetWidget::onActiveGroupChanged ); connect( mDatasetSlider, &QSlider::valueChanged, this, &QgsMeshRendererActiveDatasetWidget::onActiveDatasetChanged ); connect( mDisplayScalarsCheckBox, &QCheckBox::stateChanged, this, &QgsMeshRendererActiveDatasetWidget::onScalarChecked ); connect( mDisplayVectorsCheckBox, &QCheckBox::stateChanged, this, &QgsMeshRendererActiveDatasetWidget::onVectorChecked ); @@ -42,7 +42,7 @@ void QgsMeshRendererActiveDatasetWidget::setLayer( QgsMeshLayer *layer ) setEnabled( mMeshLayer ); syncToLayer(); - mDatasetGroupTree->setLayer( layer ); + mDatasetGroupTreeView->setLayer( layer ); } int QgsMeshRendererActiveDatasetWidget::activeScalarDataset() const @@ -77,7 +77,7 @@ bool QgsMeshRendererActiveDatasetWidget::isTriangularMeshEnabled() const void QgsMeshRendererActiveDatasetWidget::onActiveGroupChanged() { - const QVector datasets = mDatasetGroupTree->datasetsInActiveGroup(); + const QVector datasets = mDatasetGroupTreeView->datasetsInActiveGroup(); mDatasetSlider->setMinimum( 0 ); mDatasetSlider->setMaximum( datasets.size() - 1 ); @@ -87,7 +87,7 @@ void QgsMeshRendererActiveDatasetWidget::onActiveGroupChanged() void QgsMeshRendererActiveDatasetWidget::onActiveDatasetChanged( int value ) { int datasetIndex = -1; - const QVector datasets = mDatasetGroupTree->datasetsInActiveGroup(); + const QVector datasets = mDatasetGroupTreeView->datasetsInActiveGroup(); if ( datasets.size() < value || !mMeshLayer || !mMeshLayer->dataProvider() ) { mDisplayScalarsCheckBox->setEnabled( false ); @@ -162,7 +162,7 @@ void QgsMeshRendererActiveDatasetWidget::updateMetadata( int datasetIndex ) int QgsMeshRendererActiveDatasetWidget::datasetIndex() const { - const QVector datasets = mDatasetGroupTree->datasetsInActiveGroup(); + const QVector datasets = mDatasetGroupTreeView->datasetsInActiveGroup(); int value = mDatasetSlider->value(); int datasetIndex = -1; if ( value < datasets.size() ) diff --git a/src/app/mesh/qgsmeshrendereractivedatasetwidget.h b/src/app/mesh/qgsmeshrendereractivedatasetwidget.h index 4de3676db9cd..6bde9bdf7152 100644 --- a/src/app/mesh/qgsmeshrendereractivedatasetwidget.h +++ b/src/app/mesh/qgsmeshrendereractivedatasetwidget.h @@ -24,12 +24,9 @@ class QgsMeshLayer; /** - * \ingroup gui - * \class QgsMeshRendererScalarSettingsWidget - * - * - * - * \since QGIS 3.4 + * Widget for selection of active dataset group from tree view. + * Also selects the active scalar and vector dataset by slider + * and whether mesh rendering is enabled by checkboxes. */ class APP_EXPORT QgsMeshRendererActiveDatasetWidget : public QWidget, private Ui::QgsMeshRendererActiveDatasetWidgetBase { diff --git a/src/app/mesh/qgsmeshrenderermeshsettingswidget.h b/src/app/mesh/qgsmeshrenderermeshsettingswidget.h index ca55b5e4331e..3b4f59f96ed9 100644 --- a/src/app/mesh/qgsmeshrenderermeshsettingswidget.h +++ b/src/app/mesh/qgsmeshrenderermeshsettingswidget.h @@ -28,8 +28,6 @@ class QgsMeshLayer; * A widget for setup of the mesh frame settings of * the mesh layer. Can be used for both native and * triangular mesh renderer settings. - * - * \since QGIS 3.4 */ class APP_EXPORT QgsMeshRendererMeshSettingsWidget : public QWidget, private Ui::QgsMeshRendererMeshSettingsWidgetBase { diff --git a/src/app/mesh/qgsmeshrendererscalarsettingswidget.cpp b/src/app/mesh/qgsmeshrendererscalarsettingswidget.cpp index 1057d137648c..7ef2a0004fc7 100644 --- a/src/app/mesh/qgsmeshrendererscalarsettingswidget.cpp +++ b/src/app/mesh/qgsmeshrendererscalarsettingswidget.cpp @@ -56,11 +56,12 @@ void QgsMeshRendererScalarSettingsWidget::syncToLayer( ) if ( !mMeshLayer ) return; - if ( mMeshLayer->rendererScalarSettings().colorRampShader() ) + if ( mMeshLayer->rendererScalarSettings().isEnabled() ) { - whileBlocking( mScalarMinLineEdit )->setText( QString::number( mMeshLayer->rendererScalarSettings().colorRampShader()->minimumValue() ) ); - whileBlocking( mScalarMaxLineEdit )->setText( QString::number( mMeshLayer->rendererScalarSettings().colorRampShader()->maximumValue() ) ); - whileBlocking( mScalarColorRampShaderWidget )->setFromShader( mMeshLayer->rendererScalarSettings().colorRampShader() ); + const QgsColorRampShader shader = mMeshLayer->rendererScalarSettings().colorRampShader(); + whileBlocking( mScalarMinLineEdit )->setText( QString::number( shader.minimumValue() ) ); + whileBlocking( mScalarMaxLineEdit )->setText( QString::number( shader.maximumValue() ) ); + whileBlocking( mScalarColorRampShaderWidget )->setFromShader( shader ); } } diff --git a/src/app/mesh/qgsmeshrendererscalarsettingswidget.h b/src/app/mesh/qgsmeshrendererscalarsettingswidget.h index e46280343216..b62dff94d08d 100644 --- a/src/app/mesh/qgsmeshrendererscalarsettingswidget.h +++ b/src/app/mesh/qgsmeshrendererscalarsettingswidget.h @@ -28,8 +28,6 @@ class QgsMeshLayer; * A widget for setup of the scalar dataset renderer settings of * a mesh layer. The layer must be connected and an active dataset * must be selected. - * - * \since QGIS 3.4 */ class APP_EXPORT QgsMeshRendererScalarSettingsWidget : public QWidget, private Ui::QgsMeshRendererScalarSettingsWidgetBase { diff --git a/src/app/mesh/qgsmeshrenderervectorsettingswidget.h b/src/app/mesh/qgsmeshrenderervectorsettingswidget.h index 400b33171d9f..c971dbaea133 100644 --- a/src/app/mesh/qgsmeshrenderervectorsettingswidget.h +++ b/src/app/mesh/qgsmeshrenderervectorsettingswidget.h @@ -29,8 +29,6 @@ class QgsMeshLayer; * A widget for setup of the vector dataset renderer settings of * a mesh layer. The layer must be connected and an active dataset * must be selected. - * - * \since QGIS 3.4 */ class APP_EXPORT QgsMeshRendererVectorSettingsWidget : public QWidget, private Ui::QgsMeshRendererVectorSettingsWidgetBase { diff --git a/src/app/mesh/qgsrenderermeshpropertieswidget.cpp b/src/app/mesh/qgsrenderermeshpropertieswidget.cpp index c7aa24cf59cb..eadec609b5ee 100644 --- a/src/app/mesh/qgsrenderermeshpropertieswidget.cpp +++ b/src/app/mesh/qgsrenderermeshpropertieswidget.cpp @@ -20,7 +20,7 @@ #include "qgsmeshlayer.h" #include "qgsmessagelog.h" #include "qgsmeshrendererscalarsettingswidget.h" -#include "qgsmeshdatasetgrouptree.h" +#include "qgsmeshdatasetgrouptreeview.h" #include "qgsmeshrendereractivedatasetwidget.h" QgsRendererMeshPropertiesWidget::QgsRendererMeshPropertiesWidget( QgsMapLayer *layer, QgsMapCanvas *canvas, QWidget *parent ) diff --git a/src/app/mesh/qgsrenderermeshpropertieswidget.h b/src/app/mesh/qgsrenderermeshpropertieswidget.h index 294fb35e9984..6f1014d7c279 100644 --- a/src/app/mesh/qgsrenderermeshpropertieswidget.h +++ b/src/app/mesh/qgsrenderermeshpropertieswidget.h @@ -30,8 +30,6 @@ class QgsMapCanvas; /** * Widget for renderer properties of the mesh, countours (scalars) * and vectors data associated with the mesh layer - * - * \since QGIS 3.4 */ class APP_EXPORT QgsRendererMeshPropertiesWidget : public QgsMapLayerConfigWidget, private Ui::QgsRendererMeshPropsWidgetBase { diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 57ff8227b7f7..f0122a502437 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -13040,16 +13040,14 @@ void QgisApp::showLayerProperties( QgsMapLayer *mapLayer ) } else if ( mapLayer->type() == QgsMapLayer::MeshLayer ) { - QgsMeshLayerProperties *meshLayerPropertiesDialog = new QgsMeshLayerProperties( mapLayer, mMapCanvas, this ); + QgsMeshLayerProperties meshLayerPropertiesDialog( mapLayer, mMapCanvas, this ); mMapStyleWidget->blockUpdates( true ); - if ( meshLayerPropertiesDialog->exec() ) + if ( meshLayerPropertiesDialog.exec() ) { activateDeactivateLayerRelatedActions( mapLayer ); mMapStyleWidget->updateCurrentWidgetLayer(); } - mMapStyleWidget->blockUpdates( false ); - - delete meshLayerPropertiesDialog; // delete since dialog cannot be reused without updating code + mMapStyleWidget->blockUpdates( false ); // delete since dialog cannot be reused without updating code } else if ( mapLayer->type() == QgsMapLayer::VectorLayer ) // VECTOR { diff --git a/src/app/qgslayerstylingwidget.cpp b/src/app/qgslayerstylingwidget.cpp index 6ad642870543..bfd430cedf19 100644 --- a/src/app/qgslayerstylingwidget.cpp +++ b/src/app/qgslayerstylingwidget.cpp @@ -495,12 +495,12 @@ void QgsLayerStylingWidget::updateCurrentWidgetLayer() } else if ( mCurrentLayer->type() == QgsMapLayer::MeshLayer ) { - QgsMeshLayer *rlayer = qobject_cast( mCurrentLayer ); + QgsMeshLayer *meshLayer = qobject_cast( mCurrentLayer ); switch ( row ) { case 0: // Style { - mMeshStyleWidget = new QgsRendererMeshPropertiesWidget( rlayer, mMapCanvas, mWidgetStack ); + mMeshStyleWidget = new QgsRendererMeshPropertiesWidget( meshLayer, mMapCanvas, mWidgetStack ); mMeshStyleWidget->setDockMode( true ); connect( mMeshStyleWidget, &QgsPanelWidget::widgetChanged, this, &QgsLayerStylingWidget::autoApply ); diff --git a/src/core/mesh/qgsmeshlayerrenderer.cpp b/src/core/mesh/qgsmeshlayerrenderer.cpp index fac71e1882d3..4fe8c89f0054 100644 --- a/src/core/mesh/qgsmeshlayerrenderer.cpp +++ b/src/core/mesh/qgsmeshlayerrenderer.cpp @@ -55,9 +55,29 @@ QgsMeshLayerRenderer::QgsMeshLayerRenderer( QgsMeshLayer *layer, QgsRenderContex copyScalarDatasetValues( layer ); copyVectorDatasetValues( layer ); + assignDefaultScalarShader(); + calculateOutputSize(); } +void QgsMeshLayerRenderer::assignDefaultScalarShader( ) +{ + if ( mScalarDatasetValues.isEmpty() || mRendererScalarSettings.isEnabled() ) + return; // no need for default shader, either rendering is off or we already have some shader + + double vMin = *std::min_element( mScalarDatasetValues.constBegin(), mScalarDatasetValues.constEnd() ); + double vMax = *std::max_element( mScalarDatasetValues.constBegin(), mScalarDatasetValues.constEnd() ); + + QList lst; + lst << QgsColorRampShader::ColorRampItem( vMin, Qt::blue, QString::number( vMin ) ); + lst << QgsColorRampShader::ColorRampItem( vMax, Qt::red, QString::number( vMax ) ); + + QgsColorRampShader fcn( vMin, vMax ); + fcn.setColorRampItemList( lst ); + + mRendererScalarSettings.setColorRampShader( fcn ); +} + QgsFeedback *QgsMeshLayerRenderer::feedback() const { return mFeedback.get(); @@ -205,29 +225,16 @@ void QgsMeshLayerRenderer::renderScalarDataset() if ( mScalarDatasetValues.isEmpty() ) return; // activeScalarDataset == NO_ACTIVE_MESH_DATASET - QgsColorRampShader *fcn; - if ( mRendererScalarSettings.colorRampShader() ) - fcn = mRendererScalarSettings.colorRampShader()->clone(); - else - { - double vMin = *std::min_element( mScalarDatasetValues.constBegin(), mScalarDatasetValues.constEnd() ); - double vMax = *std::max_element( mScalarDatasetValues.constBegin(), mScalarDatasetValues.constEnd() ); - - QList lst; - lst << QgsColorRampShader::ColorRampItem( vMin, Qt::blue, QString::number( vMin ) ); - lst << QgsColorRampShader::ColorRampItem( vMax, Qt::red, QString::number( vMax ) ); - - fcn = new QgsColorRampShader( vMin, vMax ); - fcn->setColorRampItemList( lst ); - } + if ( !mRendererScalarSettings.isEnabled() ) + return; // no shader + QgsColorRampShader *fcn = new QgsColorRampShader( mRendererScalarSettings.colorRampShader() ); QgsRasterShader *sh = new QgsRasterShader(); sh->setRasterShaderFunction( fcn ); // takes ownership of fcn QgsMeshLayerInterpolator interpolator( mTriangularMesh, mScalarDatasetValues, mScalarDataOnVertices, mContext, mOutputSize ); QgsSingleBandPseudoColorRenderer renderer( &interpolator, 0, sh ); // takes ownership of sh renderer.setClassificationMin( fcn->minimumValue() ); renderer.setClassificationMax( fcn->maximumValue() ); - renderer.setMinMaxOrigin( mRendererScalarSettings.minMaxOrigin() ); std::unique_ptr bl( renderer.block( 0, mContext.extent(), mOutputSize.width(), mOutputSize.height(), mFeedback.get() ) ); QImage img = bl->image(); diff --git a/src/core/mesh/qgsmeshlayerrenderer.h b/src/core/mesh/qgsmeshlayerrenderer.h index f38f10ed39d2..a2ade8a076d7 100644 --- a/src/core/mesh/qgsmeshlayerrenderer.h +++ b/src/core/mesh/qgsmeshlayerrenderer.h @@ -46,7 +46,6 @@ class QgsMeshLayerRendererFeedback : public QgsRasterBlockFeedback ///@endcond - /** * \ingroup core * Implementation of threaded rendering for mesh layers. @@ -69,6 +68,8 @@ class QgsMeshLayerRenderer : public QgsMapLayerRenderer void renderVectorDataset(); void copyScalarDatasetValues( QgsMeshLayer *layer ); void copyVectorDatasetValues( QgsMeshLayer *layer ); + void assignDefaultScalarShader( ); + void createMeshSymbol( std::unique_ptr &symbol, const QgsMeshRendererMeshSettings &settings ); void calculateOutputSize(); diff --git a/src/core/mesh/qgsmeshrenderersettings.cpp b/src/core/mesh/qgsmeshrenderersettings.cpp index d3ce87cc6243..adb7fc58b276 100644 --- a/src/core/mesh/qgsmeshrenderersettings.cpp +++ b/src/core/mesh/qgsmeshrenderersettings.cpp @@ -48,27 +48,22 @@ void QgsMeshRendererMeshSettings::setColor( const QColor &color ) } -QgsColorRampShader *QgsMeshRendererScalarSettings::colorRampShader() const +QgsColorRampShader QgsMeshRendererScalarSettings::colorRampShader() const { - return mColorRampShader.get(); + return mColorRampShader; } -void QgsMeshRendererScalarSettings::setColorRampShader( QgsColorRampShader *shader ) +void QgsMeshRendererScalarSettings::setColorRampShader( QgsColorRampShader shader ) { - mColorRampShader.reset( shader ); + mColorRampShader = shader; } - -QgsRasterMinMaxOrigin QgsMeshRendererScalarSettings::minMaxOrigin() const +bool QgsMeshRendererScalarSettings::isEnabled() const { - return mRasterMinMaxOrigin; + return !mColorRampShader.isEmpty(); } -void QgsMeshRendererScalarSettings::setMinMaxOrigin( const QgsRasterMinMaxOrigin &minMaxOrigin ) -{ - mRasterMinMaxOrigin = minMaxOrigin; -} double QgsMeshRendererVectorSettings::lineWidth() const { diff --git a/src/core/mesh/qgsmeshrenderersettings.h b/src/core/mesh/qgsmeshrenderersettings.h index e2cadbe2fb0f..4f0fa47c6630 100644 --- a/src/core/mesh/qgsmeshrenderersettings.h +++ b/src/core/mesh/qgsmeshrenderersettings.h @@ -24,7 +24,6 @@ #include "qgis_core.h" #include "qgis.h" #include "qgscolorrampshader.h" -#include "qgsrasterminmaxorigin.h" /** @@ -72,19 +71,15 @@ class CORE_EXPORT QgsMeshRendererMeshSettings class CORE_EXPORT QgsMeshRendererScalarSettings { public: - //! Returns color ramp shader function. - QgsColorRampShader *colorRampShader() const; - //! Sets color ramp shader function. Takes ownership - void setColorRampShader( QgsColorRampShader *shader ); - - //! Returns raster min max origin - QgsRasterMinMaxOrigin minMaxOrigin() const; - //! Sets raster min max origin - void setMinMaxOrigin( const QgsRasterMinMaxOrigin &minMaxOrigin ); + //! Returns color ramp shader function + QgsColorRampShader colorRampShader() const; + //! Sets color ramp shader function + void setColorRampShader( QgsColorRampShader shader ); + //! Returns whether color ramp has any items assigned + bool isEnabled() const; private: - std::shared_ptr mColorRampShader; - QgsRasterMinMaxOrigin mRasterMinMaxOrigin; + QgsColorRampShader mColorRampShader; }; /** diff --git a/src/core/mesh/qgsmeshvectorrenderer.cpp b/src/core/mesh/qgsmeshvectorrenderer.cpp index 84f8593b48a9..d7df93d8efe4 100644 --- a/src/core/mesh/qgsmeshvectorrenderer.cpp +++ b/src/core/mesh/qgsmeshvectorrenderer.cpp @@ -55,15 +55,7 @@ QgsMeshVectorRenderer::QgsMeshVectorRenderer( const QgsTriangularMesh &m, , mDataOnVertices( dataIsOnVertices ) , mOutputSize( size ) { - auto bounds = std::minmax_element( mDatasetValuesX.constBegin(), mDatasetValuesX.constEnd() ); - mMinX = *bounds.first; //TODO del - mMaxX = *bounds.second; - - bounds = std::minmax_element( mDatasetValuesY.constBegin(), mDatasetValuesY.constEnd() ); - mMinY = *bounds.first; //TODO del - mMaxY = *bounds.second; - - bounds = std::minmax_element( mDatasetValuesMag.constBegin(), mDatasetValuesMag.constEnd() ); + auto bounds = std::minmax_element( mDatasetValuesMag.constBegin(), mDatasetValuesMag.constEnd() ); mMinMag = *bounds.first; mMaxMag = *bounds.second; } diff --git a/src/core/mesh/qgsmeshvectorrenderer.h b/src/core/mesh/qgsmeshvectorrenderer.h index f6306359ab7c..a5192d742c84 100644 --- a/src/core/mesh/qgsmeshvectorrenderer.h +++ b/src/core/mesh/qgsmeshvectorrenderer.h @@ -84,10 +84,6 @@ class QgsMeshVectorRenderer const QVector &mDatasetValuesX; const QVector &mDatasetValuesY; const QVector &mDatasetValuesMag; //magnitudes - double mMinX = 0.0; - double mMaxX = 0.0; - double mMinY = 0.0; - double mMaxY = 0.0; double mMinMag = 0.0; double mMaxMag = 0.0; QgsRenderContext &mContext; diff --git a/src/core/raster/qgscolorrampshader.cpp b/src/core/raster/qgscolorrampshader.cpp index 902db7cd7d31..70f398e672e9 100644 --- a/src/core/raster/qgscolorrampshader.cpp +++ b/src/core/raster/qgscolorrampshader.cpp @@ -50,12 +50,15 @@ QgsColorRampShader::QgsColorRampShader( const QgsColorRampShader &other ) , mLUTInitialized( other.mLUTInitialized ) , mClip( other.mClip ) { - mSourceColorRamp.reset( other.sourceColorRamp()->clone() ); + if ( other.sourceColorRamp() ) + mSourceColorRamp.reset( other.sourceColorRamp()->clone() ); + mColorRampItemList = other.mColorRampItemList; } QgsColorRampShader &QgsColorRampShader::operator=( const QgsColorRampShader &other ) { - mSourceColorRamp.reset( other.sourceColorRamp()->clone() ); + if ( other.sourceColorRamp() ) + mSourceColorRamp.reset( other.sourceColorRamp()->clone() ); mColorRampType = other.mColorRampType; mClassificationMode = other.mClassificationMode; mLUT = other.mLUT; @@ -63,21 +66,10 @@ QgsColorRampShader &QgsColorRampShader::operator=( const QgsColorRampShader &oth mLUTFactor = other.mLUTFactor; mLUTInitialized = other.mLUTInitialized; mClip = other.mClip; + mColorRampItemList = other.mColorRampItemList; return *this; } -QgsColorRampShader *QgsColorRampShader::clone() const -{ - QgsColorRampShader *s = new QgsColorRampShader( - mMinimumValue, - mMaximumValue, - mSourceColorRamp->clone(), - mColorRampType, - mClassificationMode ); - s->setColorRampItemList( colorRampItemList() ); //TODO?? why it is not copied in operator=? - return s; -} - QString QgsColorRampShader::colorRampTypeAsQString() { switch ( mColorRampType ) @@ -105,6 +97,11 @@ void QgsColorRampShader::setColorRampType( QgsColorRampShader::Type colorRampTyp mColorRampType = colorRampType; } +bool QgsColorRampShader::isEmpty() const +{ + return mColorRampItemList.isEmpty(); +} + void QgsColorRampShader::setColorRampType( const QString &type ) { if ( type == QLatin1String( "INTERPOLATED" ) ) diff --git a/src/core/raster/qgscolorrampshader.h b/src/core/raster/qgscolorrampshader.h index 03c83fe4dc8b..50e271b017c8 100644 --- a/src/core/raster/qgscolorrampshader.h +++ b/src/core/raster/qgscolorrampshader.h @@ -78,9 +78,6 @@ class CORE_EXPORT QgsColorRampShader : public QgsRasterShaderFunction */ QgsColorRampShader &operator=( const QgsColorRampShader &other ); - //! Clones this shader, return new instance - QgsColorRampShader *clone() const SIP_FACTORY; - //An entry for classification based upon value. //Such a classification is typically used for //single band layers where a pixel value represents @@ -119,6 +116,12 @@ class CORE_EXPORT QgsColorRampShader : public QgsRasterShaderFunction //! Sets the color ramp type void setColorRampType( QgsColorRampShader::Type colorRampType ); + /** + * Whether the color ramp contains any items + * \since QGIS 3.4 + */ + bool isEmpty() const; + /** * Gets the source color ramp * \see setSourceColorRamp() diff --git a/src/gui/raster/qgscolorrampshaderwidget.cpp b/src/gui/raster/qgscolorrampshaderwidget.cpp index b87206d332f9..d9f4fa256d86 100644 --- a/src/gui/raster/qgscolorrampshaderwidget.cpp +++ b/src/gui/raster/qgscolorrampshaderwidget.cpp @@ -25,8 +25,6 @@ #include "qgsrasterminmaxwidget.h" #include "qgstreewidgetitem.h" #include "qgssettings.h" - -// for color ramps - todo add rasterStyle and refactor raster vs. vector ramps #include "qgsstyle.h" #include "qgscolorramp.h" #include "qgscolorrampbutton.h" @@ -57,10 +55,6 @@ QgsColorRampShaderWidget::QgsColorRampShaderWidget( QWidget *parent ) connect( mUnitLineEdit, &QLineEdit::textEdited, this, &QgsColorRampShaderWidget::mUnitLineEdit_textEdited ); connect( mColormapTreeWidget, &QTreeWidget::itemDoubleClicked, this, &QgsColorRampShaderWidget::mColormapTreeWidget_itemDoubleClicked ); connect( mColorInterpolationComboBox, static_cast( &QComboBox::currentIndexChanged ), this, &QgsColorRampShaderWidget::mColorInterpolationComboBox_currentIndexChanged ); - // connect( mMinLineEdit, &QLineEdit::textChanged, this, &QgsColorRampShaderWidget::mMinLineEdit_textChanged ); - // connect( mMaxLineEdit, &QLineEdit::textChanged, this, &QgsColorRampShaderWidget::mMaxLineEdit_textChanged ); - // connect( mMinLineEdit, &QLineEdit::textEdited, this, &QgsColorRampShaderWidget::mMinLineEdit_textEdited ); - // connect( mMaxLineEdit, &QLineEdit::textEdited, this, &QgsColorRampShaderWidget::mMaxLineEdit_textEdited ); connect( mClassificationModeComboBox, static_cast( &QComboBox::currentIndexChanged ), this, &QgsColorRampShaderWidget::mClassificationModeComboBox_currentIndexChanged ); contextMenu = new QMenu( tr( "Options" ), this ); @@ -76,33 +70,6 @@ QgsColorRampShaderWidget::QgsColorRampShaderWidget( QWidget *parent ) QString defaultPalette = settings.value( QStringLiteral( "Raster/defaultPalette" ), "" ).toString(); btnColorRamp->setColorRampFromName( defaultPalette ); - /* - if ( !mRasterLayer ) - { - return; - } - - QgsRasterDataProvider *provider = mRasterLayer->dataProvider(); - if ( !provider ) - { - return; - } - - // Must be before adding items to mBandComboBox (signal) - mMinLineEdit->setValidator( new QDoubleValidator( mMinLineEdit ) ); - mMaxLineEdit->setValidator( new QDoubleValidator( mMaxLineEdit ) ); - - mMinMaxWidget = new QgsRasterMinMaxWidget( layer, this ); - mMinMaxWidget->setExtent( extent ); - mMinMaxWidget->setMapCanvas( mCanvas ); - - QHBoxLayout *layout = new QHBoxLayout(); - layout->setContentsMargins( 0, 0, 0, 0 ); - mMinMaxContainerWidget->setLayout( layout ); - layout->addWidget( mMinMaxWidget ); - - mBandComboBox->setLayer( mRasterLayer ); - */ mColorInterpolationComboBox->addItem( tr( "Discrete" ), QgsColorRampShader::Discrete ); mColorInterpolationComboBox->addItem( tr( "Linear" ), QgsColorRampShader::Interpolated ); mColorInterpolationComboBox->addItem( tr( "Exact" ), QgsColorRampShader::Exact ); @@ -115,25 +82,6 @@ QgsColorRampShaderWidget::QgsColorRampShaderWidget( QWidget *parent ) mNumberOfEntriesSpinBox->setValue( 5 ); // some default - //setFromShader( shader ); - - /* - connect( mMinMaxWidget, &QgsRasterMinMaxWidget::widgetChanged, this, &QgsColorRampShaderWidget::widgetChanged ); - connect( mMinMaxWidget, &QgsRasterMinMaxWidget::load, this, &QgsColorRampShaderWidget::loadMinMax ); - - // If there is currently no min/max, load default with user current default options - if ( mMinLineEdit->text().isEmpty() || mMaxLineEdit->text().isEmpty() ) - { - QgsRasterMinMaxOrigin minMaxOrigin = mMinMaxWidget->minMaxOrigin(); - if ( minMaxOrigin.limits() == QgsRasterMinMaxOrigin::None ) - { - minMaxOrigin.setLimits( QgsRasterMinMaxOrigin::MinMax ); - mMinMaxWidget->setFromMinMaxOrigin( minMaxOrigin ); - } - mMinMaxWidget->doComputations(); - } - */ - mClassificationModeComboBox_currentIndexChanged( 0 ); resetClassifyButton(); @@ -142,11 +90,6 @@ QgsColorRampShaderWidget::QgsColorRampShaderWidget( QWidget *parent ) connect( mClassifyButton, &QPushButton::clicked, this, &QgsColorRampShaderWidget::applyColorRamp ); connect( btnColorRamp, &QgsColorRampButton::colorRampChanged, this, &QgsColorRampShaderWidget::applyColorRamp ); connect( mNumberOfEntriesSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsColorRampShaderWidget::classify ); - /* - connect( mBandComboBox, &QgsRasterBandComboBox::bandChanged, this, &QgsColorRampShaderWidget::classify ); - connect( mBandComboBox, &QgsRasterBandComboBox::bandChanged, this, &QgsColorRampShaderWidget::bandChanged ); - connect( mClipCheckBox, &QAbstractButton::toggled, this, &QgsRasterRendererWidget::widgetChanged ); - */ } void QgsColorRampShaderWidget::initForUseWithRasterLayer() @@ -165,12 +108,12 @@ void QgsColorRampShaderWidget::setRasterBand( QgsRasterDataProvider *dp, mExtent = extent; } -QgsColorRampShader *QgsColorRampShaderWidget::shader() const +QgsColorRampShader QgsColorRampShaderWidget::shader() const { - QgsColorRampShader *colorRampShader = new QgsColorRampShader( mMin, mMax ); - colorRampShader->setColorRampType( static_cast< QgsColorRampShader::Type >( mColorInterpolationComboBox->currentData().toInt() ) ); - colorRampShader->setClassificationMode( static_cast< QgsColorRampShader::ClassificationMode >( mClassificationModeComboBox->currentData().toInt() ) ); - colorRampShader->setClip( mClipCheckBox->isChecked() ); + QgsColorRampShader colorRampShader( mMin, mMax ); + colorRampShader.setColorRampType( static_cast< QgsColorRampShader::Type >( mColorInterpolationComboBox->currentData().toInt() ) ); + colorRampShader.setClassificationMode( static_cast< QgsColorRampShader::ClassificationMode >( mClassificationModeComboBox->currentData().toInt() ) ); + colorRampShader.setClip( mClipCheckBox->isChecked() ); //iterate through mColormapTreeWidget and set colormap info of layer QList colorRampItems; @@ -191,11 +134,11 @@ QgsColorRampShader *QgsColorRampShaderWidget::shader() const } // sort the shader items std::sort( colorRampItems.begin(), colorRampItems.end() ); - colorRampShader->setColorRampItemList( colorRampItems ); + colorRampShader.setColorRampItemList( colorRampItems ); if ( !btnColorRamp->isNull() ) { - colorRampShader->setSourceColorRamp( btnColorRamp->colorRamp() ); + colorRampShader.setSourceColorRamp( btnColorRamp->colorRamp() ); } return colorRampShader; } @@ -391,8 +334,6 @@ void QgsColorRampShaderWidget::mClassificationModeComboBox_currentIndexChanged( { QgsColorRampShader::ClassificationMode mode = static_cast< QgsColorRampShader::ClassificationMode >( mClassificationModeComboBox->itemData( index ).toInt() ); mNumberOfEntriesSpinBox->setEnabled( mode != QgsColorRampShader::Continuous ); - //mMinLineEdit->setEnabled( mode != QgsColorRampShader::Quantile ); - //mMaxLineEdit->setEnabled( mode != QgsColorRampShader::Quantile ); emit classificationModeChanged( mode ); } @@ -671,43 +612,37 @@ void QgsColorRampShaderWidget::mColormapTreeWidget_itemEdited( QTreeWidgetItem * } } -void QgsColorRampShaderWidget::setFromShader( const QgsColorRampShader *colorRampShader ) +void QgsColorRampShaderWidget::setFromShader( const QgsColorRampShader &colorRampShader ) { - - - if ( colorRampShader ) + if ( colorRampShader.sourceColorRamp() ) { - if ( colorRampShader->sourceColorRamp() ) - { - btnColorRamp->setColorRamp( colorRampShader->sourceColorRamp() ); - } - else - { - QgsSettings settings; - QString defaultPalette = settings.value( QStringLiteral( "/Raster/defaultPalette" ), "Spectral" ).toString(); - btnColorRamp->setColorRampFromName( defaultPalette ); - } + btnColorRamp->setColorRamp( colorRampShader.sourceColorRamp() ); + } + else + { + QgsSettings settings; + QString defaultPalette = settings.value( QStringLiteral( "/Raster/defaultPalette" ), "Spectral" ).toString(); + btnColorRamp->setColorRampFromName( defaultPalette ); + } - mColorInterpolationComboBox->setCurrentIndex( mColorInterpolationComboBox->findData( colorRampShader->colorRampType() ) ); + mColorInterpolationComboBox->setCurrentIndex( mColorInterpolationComboBox->findData( colorRampShader.colorRampType() ) ); - const QList colorRampItemList = colorRampShader->colorRampItemList(); - QList::const_iterator it = colorRampItemList.constBegin(); - for ( ; it != colorRampItemList.end(); ++it ) - { - QgsTreeWidgetItemObject *newItem = new QgsTreeWidgetItemObject( mColormapTreeWidget ); - newItem->setText( ValueColumn, QString::number( it->value, 'g', 15 ) ); - newItem->setBackground( ColorColumn, QBrush( it->color ) ); - newItem->setText( LabelColumn, it->label ); - newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable ); - connect( newItem, &QgsTreeWidgetItemObject::itemEdited, - this, &QgsColorRampShaderWidget::mColormapTreeWidget_itemEdited ); - } - setUnitFromLabels(); - mClipCheckBox->setChecked( colorRampShader->clip() ); - mClassificationModeComboBox->setCurrentIndex( mClassificationModeComboBox->findData( colorRampShader->classificationMode() ) ); - mNumberOfEntriesSpinBox->setValue( colorRampShader->colorRampItemList().count() ); // some default + const QList colorRampItemList = colorRampShader.colorRampItemList(); + QList::const_iterator it = colorRampItemList.constBegin(); + for ( ; it != colorRampItemList.end(); ++it ) + { + QgsTreeWidgetItemObject *newItem = new QgsTreeWidgetItemObject( mColormapTreeWidget ); + newItem->setText( ValueColumn, QString::number( it->value, 'g', 15 ) ); + newItem->setBackground( ColorColumn, QBrush( it->color ) ); + newItem->setText( LabelColumn, it->label ); + newItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable ); + connect( newItem, &QgsTreeWidgetItemObject::itemEdited, + this, &QgsColorRampShaderWidget::mColormapTreeWidget_itemEdited ); } - + setUnitFromLabels(); + mClipCheckBox->setChecked( colorRampShader.clip() ); + mClassificationModeComboBox->setCurrentIndex( mClassificationModeComboBox->findData( colorRampShader.classificationMode() ) ); + mNumberOfEntriesSpinBox->setValue( colorRampShader.colorRampItemList().count() ); // some default } void QgsColorRampShaderWidget::mColorInterpolationComboBox_currentIndexChanged( int index ) @@ -772,9 +707,6 @@ void QgsColorRampShaderWidget::loadMinMaxFromTree() item = mColormapTreeWidget->topLevelItem( mColormapTreeWidget->topLevelItemCount() - 1 ); double max = item->text( ValueColumn ).toDouble(); - //whileBlocking( mMinLineEdit )->setText( QString::number( min ) ); - //whileBlocking( mMaxLineEdit )->setText( QString::number( max ) ); - if ( !qgsDoubleNear( mMin, min ) || !qgsDoubleNear( mMax, max ) ) { mMin = min; @@ -783,32 +715,9 @@ void QgsColorRampShaderWidget::loadMinMaxFromTree() } } -/* -void QgsColorRampShaderWidget::setLineEditValue( QLineEdit *lineEdit, double value ) -{ - QString s; - if ( !std::isnan( value ) ) - { - s = QString::number( value ); - } - lineEdit->setText( s ); -} - -double QgsColorRampShaderWidget::lineEditValue( const QLineEdit *lineEdit ) const -{ - if ( lineEdit->text().isEmpty() ) - { - return std::numeric_limits::quiet_NaN(); - } - - return lineEdit->text().toDouble(); -}*/ - void QgsColorRampShaderWidget::resetClassifyButton() { mClassifyButton->setEnabled( true ); - // double min = lineEditValue( mMinLineEdit ); - // double max = lineEditValue( mMaxLineEdit ); if ( std::isnan( mMin ) || std::isnan( mMax ) || mMin >= mMax ) { mClassifyButton->setEnabled( false ); @@ -866,56 +775,3 @@ void QgsColorRampShaderWidget::changeOpacity() emit widgetChanged(); } } - -/* -void QgsColorRampShaderWidget::mMinLineEdit_textEdited( const QString & ) -{ - minMaxModified(); - classify(); -} - -void QgsColorRampShaderWidget::mMaxLineEdit_textEdited( const QString & ) -{ - minMaxModified(); - classify(); -} - -void QgsColorRampShaderWidget::minMaxModified() -{ - mMinMaxWidget->userHasSetManualMinMaxValues(); -} -*/ - -// ************************************ // -/* QgsRasterColorRampShaderWidget - -QgsRasterColorRampShaderWidget::QgsRasterColorRampShaderWidget(QgsRasterLayer *layer, const QgsRectangle &extent) - : QgsColorRampShaderWidget() - , mRasterLayer( layer ) - , mExtent( extent ) -{ - - connect( mLoadFromBandButton, &QPushButton::clicked, this, &QgsRasterColorRampShaderWidget::mLoadFromBandButton_clicked ); - mLoadFromBandButton->setVisible(true); - mClassificationModeComboBox->addItem( tr( "Quantile" ), QgsColorRampShader::Quantile ); - - if ( !mRasterLayer ) - { - return; - } - - QgsRasterDataProvider *provider = mRasterLayer->dataProvider(); - if ( !provider ) - { - return; - } -} - -void QgsRasterColorRampShaderWidget::setBand(int band) -{ - mBand = band; -} -*/ - - - diff --git a/src/gui/raster/qgscolorrampshaderwidget.h b/src/gui/raster/qgscolorrampshaderwidget.h index 5f867f460682..6f2ab20bb043 100644 --- a/src/gui/raster/qgscolorrampshaderwidget.h +++ b/src/gui/raster/qgscolorrampshaderwidget.h @@ -35,6 +35,8 @@ class QgsRasterDataProvider; * the Quantile classification mode can be used and the LoadFromBandButton is visible. * * The other mode is used to style mesh layer contours (scalar datasets) + * + * \since QGIS 3.4 */ class GUI_EXPORT QgsColorRampShaderWidget: public QWidget, protected Ui::QgsColorRampShaderWidgetBase { @@ -52,8 +54,8 @@ class GUI_EXPORT QgsColorRampShaderWidget: public QWidget, protected Ui::QgsColo void setMinMax( double min, double max ); //! Returns shared function used in the renderer. Caller takes ownership and deletes it. - QgsColorRampShader *shader() const; - void setFromShader( const QgsColorRampShader *colorRampShader ); + QgsColorRampShader shader() const; + void setFromShader( const QgsColorRampShader &colorRampShader ); signals: void minMaxChangedFromTree( double min, double max ); @@ -105,18 +107,12 @@ class GUI_EXPORT QgsColorRampShaderWidget: public QWidget, protected Ui::QgsColo void mUnitLineEdit_textEdited( const QString &text ) { Q_UNUSED( text ); autoLabel(); } void mColormapTreeWidget_itemDoubleClicked( QTreeWidgetItem *item, int column ); void mColormapTreeWidget_itemEdited( QTreeWidgetItem *item, int column ); - //void bandChanged(); void mColorInterpolationComboBox_currentIndexChanged( int index ); - //void mMinLineEdit_textChanged( const QString & ) { resetClassifyButton(); } - //void mMaxLineEdit_textChanged( const QString & ) { resetClassifyButton(); } - //void mMinLineEdit_textEdited( const QString &text ); - //void mMaxLineEdit_textEdited( const QString &text ); void mClassificationModeComboBox_currentIndexChanged( int index ); void changeColor(); void changeOpacity(); private: - void setLineEditValue( QLineEdit *lineEdit, double value ); double lineEditValue( const QLineEdit *lineEdit ) const; void resetClassifyButton(); diff --git a/src/ui/mesh/qgsmeshlayerpropertiesbase.ui b/src/ui/mesh/qgsmeshlayerpropertiesbase.ui index 512adf0944c5..285620519b85 100644 --- a/src/ui/mesh/qgsmeshlayerpropertiesbase.ui +++ b/src/ui/mesh/qgsmeshlayerpropertiesbase.ui @@ -197,8 +197,8 @@ 0 0 - 643 - 729 + 261 + 144 @@ -328,8 +328,8 @@ border-radius: 2px; 0 0 - 643 - 729 + 100 + 30 @@ -377,7 +377,7 @@ border-radius: 2px; Qt::Horizontal - QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok + QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Ok diff --git a/src/ui/mesh/qgsmeshrendereractivedatasetwidgetbase.ui b/src/ui/mesh/qgsmeshrendereractivedatasetwidgetbase.ui index 9d6ed3a1cb12..8eb9eb67b818 100644 --- a/src/ui/mesh/qgsmeshrendereractivedatasetwidgetbase.ui +++ b/src/ui/mesh/qgsmeshrendereractivedatasetwidgetbase.ui @@ -18,7 +18,7 @@ - + 0 @@ -114,9 +114,9 @@ - QgsMeshDatasetGroupTree - QTreeWidget -
mesh/qgsmeshdatasetgrouptree.h
+ QgsMeshDatasetGroupTreeView + QTreeView +
mesh/qgsmeshdatasetgrouptreeview.h
QgsCollapsibleGroupBox From 17e2434498d3e9494e30a3ef021d32d01fd519c4 Mon Sep 17 00:00:00 2001 From: Peter Petrik Date: Thu, 21 Jun 2018 09:30:35 +0200 Subject: [PATCH 09/13] replace treewidget with treeview --- src/app/mesh/qgsmeshdatasetgrouptreeview.cpp | 222 ++++++++++++++++--- src/app/mesh/qgsmeshdatasetgrouptreeview.h | 72 +++++- 2 files changed, 261 insertions(+), 33 deletions(-) diff --git a/src/app/mesh/qgsmeshdatasetgrouptreeview.cpp b/src/app/mesh/qgsmeshdatasetgrouptreeview.cpp index e6a262b63b67..4cba7c0a7f07 100644 --- a/src/app/mesh/qgsmeshdatasetgrouptreeview.cpp +++ b/src/app/mesh/qgsmeshdatasetgrouptreeview.cpp @@ -21,22 +21,187 @@ #include #include -static QList prepareRow(const QString &str) + +QgsMeshDatasetGroupTreeItem::~QgsMeshDatasetGroupTreeItem() +{ + qDeleteAll( mChildren ); +} + +QgsMeshDatasetGroupTreeItem::QgsMeshDatasetGroupTreeItem( const QString &name, QgsMeshDatasetGroupTreeItem *parent ) + : mParent( parent ) + , mName( name ) +{ +} + +void QgsMeshDatasetGroupTreeItem::appendChild( QgsMeshDatasetGroupTreeItem *node ) +{ + mChildren.append( node ); +} + +QgsMeshDatasetGroupTreeItem *QgsMeshDatasetGroupTreeItem::child( int row ) const +{ + if ( row < mChildren.count() ) + return mChildren.at( row ); + else + return nullptr; +} + +int QgsMeshDatasetGroupTreeItem::columnCount() const +{ + return 1; +} + +int QgsMeshDatasetGroupTreeItem::childCount() const +{ + return mChildren.count(); +} + +QgsMeshDatasetGroupTreeItem *QgsMeshDatasetGroupTreeItem::parentItem() const +{ + return mParent; +} + +int QgsMeshDatasetGroupTreeItem::row() const +{ + if ( mParent ) + return mParent->mChildren.indexOf( const_cast( this ) ); + + return 0; +} + +QVariant QgsMeshDatasetGroupTreeItem::data( int column ) const { - QList rowItems; - rowItems << new QStandardItem(str); - return rowItems; + Q_UNUSED( column ); + return mName; +} + +///////////////////////////////////////////////////////////////////////////////////////// + +QgsMeshDatasetGroupTreeModel::QgsMeshDatasetGroupTreeModel( QObject *parent ) + : QAbstractItemModel( parent ) + , mRootItem( new QgsMeshDatasetGroupTreeItem( "Groups" ) ) +{ +} + +QgsMeshDatasetGroupTreeModel::~QgsMeshDatasetGroupTreeModel() = default; + +int QgsMeshDatasetGroupTreeModel::columnCount( const QModelIndex &parent ) const +{ + if ( parent.isValid() ) + return static_cast( parent.internalPointer() )->columnCount(); + else + return mRootItem->columnCount(); +} + +QVariant QgsMeshDatasetGroupTreeModel::data( const QModelIndex &index, int role ) const +{ + if ( !index.isValid() ) + return QVariant(); + + if ( role != Qt::DisplayRole ) + return QVariant(); + + QgsMeshDatasetGroupTreeItem *item = static_cast( index.internalPointer() ); + + return item->data( index.column() ); +} + +Qt::ItemFlags QgsMeshDatasetGroupTreeModel::flags( const QModelIndex &index ) const +{ + if ( !index.isValid() ) + return Qt::NoItemFlags; + + return QAbstractItemModel::flags( index ); +} + +QVariant QgsMeshDatasetGroupTreeModel::headerData( int section, Qt::Orientation orientation, + int role ) const +{ + if ( orientation == Qt::Horizontal && role == Qt::DisplayRole ) + return mRootItem->data( section ); + + return QVariant(); } +QModelIndex QgsMeshDatasetGroupTreeModel::index( int row, int column, const QModelIndex &parent ) +const +{ + if ( !hasIndex( row, column, parent ) ) + return QModelIndex(); + + QgsMeshDatasetGroupTreeItem *parentItem; + + if ( !parent.isValid() ) + parentItem = mRootItem.get(); + else + parentItem = static_cast( parent.internalPointer() ); + + QgsMeshDatasetGroupTreeItem *childItem = parentItem->child( row ); + if ( childItem ) + return createIndex( row, column, childItem ); + else + return QModelIndex(); +} + +QModelIndex QgsMeshDatasetGroupTreeModel::parent( const QModelIndex &index ) const +{ + if ( !index.isValid() ) + return QModelIndex(); + + QgsMeshDatasetGroupTreeItem *childItem = static_cast( index.internalPointer() ); + QgsMeshDatasetGroupTreeItem *parentItem = childItem->parentItem(); + + if ( parentItem == mRootItem.get() ) + return QModelIndex(); + + return createIndex( parentItem->row(), 0, parentItem ); +} + +int QgsMeshDatasetGroupTreeModel::rowCount( const QModelIndex &parent ) const +{ + QgsMeshDatasetGroupTreeItem *parentItem; + if ( parent.column() > 0 ) + return 0; + + if ( !parent.isValid() ) + parentItem = mRootItem.get(); + else + parentItem = static_cast( parent.internalPointer() ); + + return parentItem->childCount(); +} + +void QgsMeshDatasetGroupTreeModel::setupModelData( const QStringList &groups ) +{ + beginResetModel(); + + for ( const QString &groupName : groups ) + { + QgsMeshDatasetGroupTreeItem *item = new QgsMeshDatasetGroupTreeItem( groupName, mRootItem.get() ); + mRootItem->appendChild( item ); + } + + endResetModel(); +} + +void QgsMeshDatasetGroupTreeModel::clear() +{ + mRootItem.reset( new QgsMeshDatasetGroupTreeItem( "Groups" ) ); +} + +///////////////////////////////////////////////////////////////////////////////////////// + QgsMeshDatasetGroupTreeView::QgsMeshDatasetGroupTreeView( QWidget *parent ) : QTreeView( parent ) { - setSelectionMode(QAbstractItemView::SingleSelection) ; + setModel( &mModel ); + + setSelectionMode( QAbstractItemView::SingleSelection ) ; connect( selectionModel(), &QItemSelectionModel::selectionChanged, this, &QgsMeshDatasetGroupTreeView::onSelectionChanged - ); + ); } void QgsMeshDatasetGroupTreeView::setLayer( QgsMeshLayer *layer ) @@ -60,36 +225,35 @@ void QgsMeshDatasetGroupTreeView::onSelectionChanged( const QItemSelection &sele { Q_UNUSED( deselected ); - if ( selected.isEmpty() ) { + if ( selected.isEmpty() ) + { mActiveGroup = QString(); return; } - if ( selected.first().indexes().isEmpty() ) { + if ( selected.first().indexes().isEmpty() ) + { mActiveGroup = QString(); return; } QModelIndex index = selected.first().indexes().first(); //single selection only - QStandardItem* item = mModel.itemFromIndex(index); - QString name = item->text(); - mActiveGroup = name; - + QVariant name = mModel.data( index, 0 ); + mActiveGroup = name.toString(); emit activeGroupChanged(); } -void QgsMeshDatasetGroupTreeView::repopulateTree() + +void QgsMeshDatasetGroupTreeView::extractGroups() { + // TODO replace with MDAL groups when introduced mGroups.clear(); - mActiveGroup.clear(); - mModel.clear(); if ( !mMeshLayer || !mMeshLayer->dataProvider() ) return; for ( int i = 0; i < mMeshLayer->dataProvider()->datasetCount(); ++i ) { - // TODO name to metadata directly when groups are introduced in MDAL const QgsMeshDatasetMetadata meta = mMeshLayer->dataProvider()->datasetMetadata( i ); QString name = meta.extraOptions()["name"]; if ( mGroups.constFind( name ) == mGroups.constEnd() ) @@ -103,22 +267,18 @@ void QgsMeshDatasetGroupTreeView::repopulateTree() mGroups[name].append( i ); } } +} - QStringList groupsSorted = mGroups.keys(); - qSort( groupsSorted.begin(), groupsSorted.end() ); +void QgsMeshDatasetGroupTreeView::repopulateTree() +{ - for ( int i = 0; i < groupsSorted.size(); ++i ) - { - QString groupName = groupsSorted[i]; - QVector datasets = mGroups[groupName]; - qSort( datasets ); - mGroups[groupName] = datasets; - QString name = QString( "%1" ).arg( groupName ); - QStandardItem *root = mModel.invisibleRootItem(); - root->appendRow(prepareRow(name)); - } + mActiveGroup.clear(); + mModel.clear(); - if (groupsSorted.size() > 0) - setCurrentIndex(mModel.index(0, 0)); -} + extractGroups(); + + mModel.setupModelData( mGroups.keys() ); + if ( mGroups.size() > 0 ) + setCurrentIndex( mModel.index( 0, 0 ) ); +} diff --git a/src/app/mesh/qgsmeshdatasetgrouptreeview.h b/src/app/mesh/qgsmeshdatasetgrouptreeview.h index 08af150ba4bf..a1c93bb93dc0 100644 --- a/src/app/mesh/qgsmeshdatasetgrouptreeview.h +++ b/src/app/mesh/qgsmeshdatasetgrouptreeview.h @@ -24,14 +24,81 @@ #include #include #include +#include +#include class QgsMeshLayer; /** - * Tree widget for display of the mesh dataset groups. + * Tree item for display of the mesh dataset groups. * Dataset group is set of datasets with the same name, * but different control variable (e.g. time) * + * Support for multiple levels, because groups can have + * subgroups, for example + * + * Groups: + * Depth + * - Maximum/Depth + * Velocity + * Wind speed + * - Maximum/Wind Speed + */ +class APP_NO_EXPORT QgsMeshDatasetGroupTreeItem +{ + public: + QgsMeshDatasetGroupTreeItem( const QString &name, QgsMeshDatasetGroupTreeItem *parent = nullptr ); + ~QgsMeshDatasetGroupTreeItem(); + + void appendChild( QgsMeshDatasetGroupTreeItem *node ); + QgsMeshDatasetGroupTreeItem *child( int row ) const; + int columnCount() const; + int childCount() const; + QgsMeshDatasetGroupTreeItem *parentItem() const; + int row() const; + QVariant data( int column ) const; + + private: + QgsMeshDatasetGroupTreeItem *mParent = nullptr; + QList< QgsMeshDatasetGroupTreeItem * > mChildren; + + // Data + QString mName; +}; + +/** + * Item Model for QgsMeshDatasetGroupTreeItem + */ +class APP_NO_EXPORT QgsMeshDatasetGroupTreeModel : public QAbstractItemModel +{ + Q_OBJECT + + public: + explicit QgsMeshDatasetGroupTreeModel( QObject *parent = nullptr ); + ~QgsMeshDatasetGroupTreeModel(); + + QVariant data( const QModelIndex &index, int role ) const override; + Qt::ItemFlags flags( const QModelIndex &index ) const override; + QVariant headerData( int section, Qt::Orientation orientation, + int role = Qt::DisplayRole ) const override; + QModelIndex index( int row, int column, + const QModelIndex &parent = QModelIndex() ) const override; + QModelIndex parent( const QModelIndex &index ) const override; + int rowCount( const QModelIndex &parent = QModelIndex() ) const override; + int columnCount( const QModelIndex &parent = QModelIndex() ) const override; + + //! Add groups to the model + void setupModelData( const QStringList &groups ); + //! Remove all groups from the model + void clear(); + + private: + std::unique_ptr mRootItem; +}; + +/** + * Tree widget for display of the mesh dataset groups. + * * One dataset group is selected (active) */ class APP_EXPORT QgsMeshDatasetGroupTreeView : public QTreeView @@ -57,8 +124,9 @@ class APP_EXPORT QgsMeshDatasetGroupTreeView : public QTreeView private: void repopulateTree(); + void extractGroups(); - QStandardItemModel mModel; + QgsMeshDatasetGroupTreeModel mModel; QgsMeshLayer *mMeshLayer = nullptr; // not owned QMap> mGroups; // group name -> dataset indices QString mActiveGroup; From ec52aff203b0de2a3d5db454972cee2eecc806c0 Mon Sep 17 00:00:00 2001 From: Peter Petrik Date: Thu, 21 Jun 2018 12:32:22 +0200 Subject: [PATCH 10/13] remember last used folder for adding datasets --- src/app/mesh/qgsmeshlayerproperties.cpp | 28 +++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/app/mesh/qgsmeshlayerproperties.cpp b/src/app/mesh/qgsmeshlayerproperties.cpp index a9b2008c6219..56ece59a9a0d 100644 --- a/src/app/mesh/qgsmeshlayerproperties.cpp +++ b/src/app/mesh/qgsmeshlayerproperties.cpp @@ -33,6 +33,7 @@ #include "qgssettings.h" #include +#include QgsMeshLayerProperties::QgsMeshLayerProperties( QgsMapLayer *lyr, QgsMapCanvas *canvas, QWidget *parent, Qt::WindowFlags fl ) : QgsOptionsDialogBase( QStringLiteral( "MeshLayerProperties" ), parent, fl ) @@ -129,13 +130,28 @@ void QgsMeshLayerProperties::addDataset() if ( !mMeshLayer->dataProvider() ) return; - QString fileName = QFileDialog::getOpenFileName( this ); - if ( !fileName.isEmpty() ) + QgsSettings settings; + QString openFileDir = settings.value( QStringLiteral( "lastMeshDatasetDir" ), QDir::homePath(), QgsSettings::App ).toString(); + QString openFileString = QFileDialog::getOpenFileName( nullptr, tr( "Load mesh datasets" ), openFileDir, tr( "Layout mesh datasets" ) + " (*.*)" ); + + if ( openFileString.isEmpty() ) + { + return; //canceled by the user + } + + QFileInfo openFileInfo( openFileString ); + settings.setValue( QStringLiteral( "lastMeshDatasetDir" ), openFileInfo.absolutePath(), QgsSettings::App ); + QFile datasetFile( openFileString ); + + bool ok = mMeshLayer->dataProvider()->addDataset( openFileString ); + if ( ok ) + { + syncToLayer(); + QMessageBox::information( this, tr( "Load mesh datasets" ), tr( "Datasets added to the mesh layer." ) ); + } + else { - bool ok = mMeshLayer->dataProvider()->addDataset( fileName ); - QgsDebugMsg( QStringLiteral( "Dataset added %1, %2" ).arg( fileName ).arg( ok ) ); - if ( ok ) - syncToLayer(); + QMessageBox::warning( this, tr( "Load mesh datasets" ), tr( "Could not read mesh dataset." ) ); } } From eebf9a1c2b9284d1e756d4b7aee4a4c8e88d77ae Mon Sep 17 00:00:00 2001 From: Peter Petrik Date: Thu, 21 Jun 2018 13:24:01 +0200 Subject: [PATCH 11/13] update mesh renderer widgets when datasets are added --- .../auto_generated/mesh/qgsmeshdataprovider.sip.in | 2 ++ src/app/mesh/qgsmeshdatasetgrouptreeview.cpp | 5 ++--- src/app/mesh/qgsmeshdatasetgrouptreeview.h | 4 +++- src/app/mesh/qgsmeshlayerproperties.cpp | 12 +++++++----- src/app/mesh/qgsmeshrendereractivedatasetwidget.cpp | 2 ++ src/app/mesh/qgsrenderermeshpropertieswidget.cpp | 5 +++++ src/core/mesh/qgsmeshdataprovider.h | 2 ++ src/core/mesh/qgsmeshlayer.cpp | 2 ++ src/core/mesh/qgsmeshmemorydataprovider.cpp | 3 +++ src/providers/mdal/qgsmdalprovider.cpp | 13 ++++++++++++- 10 files changed, 40 insertions(+), 10 deletions(-) diff --git a/python/core/auto_generated/mesh/qgsmeshdataprovider.sip.in b/python/core/auto_generated/mesh/qgsmeshdataprovider.sip.in index 43ed5d671d9a..c786042c6a41 100644 --- a/python/core/auto_generated/mesh/qgsmeshdataprovider.sip.in +++ b/python/core/auto_generated/mesh/qgsmeshdataprovider.sip.in @@ -227,6 +227,8 @@ or read on demand virtual bool addDataset( const QString &uri ) = 0; %Docstring Associate dataset with the mesh + +emits dataChanged when successfull %End virtual int datasetCount() const = 0; diff --git a/src/app/mesh/qgsmeshdatasetgrouptreeview.cpp b/src/app/mesh/qgsmeshdatasetgrouptreeview.cpp index 4cba7c0a7f07..f352f9a75dd9 100644 --- a/src/app/mesh/qgsmeshdatasetgrouptreeview.cpp +++ b/src/app/mesh/qgsmeshdatasetgrouptreeview.cpp @@ -209,7 +209,7 @@ void QgsMeshDatasetGroupTreeView::setLayer( QgsMeshLayer *layer ) if ( layer != mMeshLayer ) { mMeshLayer = layer; - repopulateTree(); + syncToLayer(); } } @@ -269,9 +269,8 @@ void QgsMeshDatasetGroupTreeView::extractGroups() } } -void QgsMeshDatasetGroupTreeView::repopulateTree() +void QgsMeshDatasetGroupTreeView::syncToLayer() { - mActiveGroup.clear(); mModel.clear(); diff --git a/src/app/mesh/qgsmeshdatasetgrouptreeview.h b/src/app/mesh/qgsmeshdatasetgrouptreeview.h index a1c93bb93dc0..520f6c311bdd 100644 --- a/src/app/mesh/qgsmeshdatasetgrouptreeview.h +++ b/src/app/mesh/qgsmeshdatasetgrouptreeview.h @@ -115,6 +115,9 @@ class APP_EXPORT QgsMeshDatasetGroupTreeView : public QTreeView //! Returns all the dataset indexes in the active group QVector datasetsInActiveGroup() const; + //! Synchronize widgets state with associated mesh layer + void syncToLayer(); + signals: //! Selected dataset group changed void activeGroupChanged(); @@ -123,7 +126,6 @@ class APP_EXPORT QgsMeshDatasetGroupTreeView : public QTreeView void onSelectionChanged( const QItemSelection &selected, const QItemSelection &deselected ); private: - void repopulateTree(); void extractGroups(); QgsMeshDatasetGroupTreeModel mModel; diff --git a/src/app/mesh/qgsmeshlayerproperties.cpp b/src/app/mesh/qgsmeshlayerproperties.cpp index 56ece59a9a0d..9be4c3235751 100644 --- a/src/app/mesh/qgsmeshlayerproperties.cpp +++ b/src/app/mesh/qgsmeshlayerproperties.cpp @@ -53,11 +53,14 @@ QgsMeshLayerProperties::QgsMeshLayerProperties( QgsMapLayer *lyr, QgsMapCanvas * // switching vertical tabs between icon/text to icon-only modes (splitter collapsed to left), // and connecting QDialogButtonBox's accepted/rejected signals to dialog's accept/reject slots initOptionsBase( false ); + connect( lyr->styleManager(), &QgsMapLayerStyleManager::currentStyleChanged, this, &QgsMeshLayerProperties::syncAndRepaint ); connect( this, &QDialog::accepted, this, &QgsMeshLayerProperties::apply ); connect( buttonBox->button( QDialogButtonBox::Apply ), &QAbstractButton::clicked, this, &QgsMeshLayerProperties::apply ); + connect( mMeshLayer, &QgsMeshLayer::dataChanged, this, &QgsMeshLayerProperties::syncAndRepaint ); + // update based on lyr's current state syncToLayer(); @@ -89,10 +92,10 @@ void QgsMeshLayerProperties::syncToLayer() if ( mMeshLayer->dataProvider() ) { info += QStringLiteral( "
%1%2
" ); - info += QStringLiteral( "" ).arg( tr( "Uri" ) ).arg( mMeshLayer->dataProvider()->dataSourceUri() ); - info += QStringLiteral( "" ).arg( tr( "Vertex count" ) ).arg( mMeshLayer->dataProvider()->vertexCount() ); - info += QStringLiteral( "" ).arg( tr( "Face count" ) ).arg( mMeshLayer->dataProvider()->faceCount() ); - info += QStringLiteral( "" ).arg( tr( "Dataset count" ) ).arg( mMeshLayer->dataProvider()->datasetCount() ); + info += QStringLiteral( "" ).arg( tr( "Uri" ) ).arg( mMeshLayer->dataProvider()->dataSourceUri() ); + info += QStringLiteral( "" ).arg( tr( "Vertex count" ) ).arg( mMeshLayer->dataProvider()->vertexCount() ); + info += QStringLiteral( "" ).arg( tr( "Face count" ) ).arg( mMeshLayer->dataProvider()->faceCount() ); + info += QStringLiteral( "" ).arg( tr( "Dataset count" ) ).arg( mMeshLayer->dataProvider()->datasetCount() ); info += QStringLiteral( "
%1%2
%1%2
%1%2
%1%2
%1: %2
%1: %2
%1: %2
%1: %2
" ); } else @@ -122,7 +125,6 @@ void QgsMeshLayerProperties::syncToLayer() * Styling Tab */ mRendererMeshPropertiesWidget->syncToLayer(); - } void QgsMeshLayerProperties::addDataset() diff --git a/src/app/mesh/qgsmeshrendereractivedatasetwidget.cpp b/src/app/mesh/qgsmeshrendereractivedatasetwidget.cpp index 5458eabc205a..b32d56e5091b 100644 --- a/src/app/mesh/qgsmeshrendereractivedatasetwidget.cpp +++ b/src/app/mesh/qgsmeshrendereractivedatasetwidget.cpp @@ -174,6 +174,8 @@ int QgsMeshRendererActiveDatasetWidget::datasetIndex() const void QgsMeshRendererActiveDatasetWidget::syncToLayer() { + mDatasetGroupTreeView->syncToLayer(); + if ( mMeshLayer ) { whileBlocking( mDisplayNativeMeshCheckBox )->setChecked( mMeshLayer->rendererNativeMeshSettings().isEnabled() ); diff --git a/src/app/mesh/qgsrenderermeshpropertieswidget.cpp b/src/app/mesh/qgsrenderermeshpropertieswidget.cpp index eadec609b5ee..a4cb4b2db5b2 100644 --- a/src/app/mesh/qgsrenderermeshpropertieswidget.cpp +++ b/src/app/mesh/qgsrenderermeshpropertieswidget.cpp @@ -33,6 +33,11 @@ QgsRendererMeshPropertiesWidget::QgsRendererMeshPropertiesWidget( QgsMapLayer *l setupUi( this ); + connect( mMeshLayer, + &QgsMeshLayer::dataChanged, + this, + &QgsRendererMeshPropertiesWidget::syncToLayer ); + mMeshRendererActiveDatasetWidget->setLayer( mMeshLayer ); mMeshRendererScalarSettingsWidget->setLayer( mMeshLayer ); mNativeMeshSettingsWidget->setLayer( mMeshLayer, false ); diff --git a/src/core/mesh/qgsmeshdataprovider.h b/src/core/mesh/qgsmeshdataprovider.h index 8d629f2db035..9f9b0831e117 100644 --- a/src/core/mesh/qgsmeshdataprovider.h +++ b/src/core/mesh/qgsmeshdataprovider.h @@ -215,6 +215,8 @@ class CORE_EXPORT QgsMeshDatasetSourceInterface SIP_ABSTRACT /** * \brief Associate dataset with the mesh + * + * emits dataChanged when successfull */ virtual bool addDataset( const QString &uri ) = 0; diff --git a/src/core/mesh/qgsmeshlayer.cpp b/src/core/mesh/qgsmeshlayer.cpp index bf99b9347638..eda9c4276d10 100644 --- a/src/core/mesh/qgsmeshlayer.cpp +++ b/src/core/mesh/qgsmeshlayer.cpp @@ -338,5 +338,7 @@ bool QgsMeshLayer::setDataProvider( QString const &provider, const QgsDataProvid mDataSource = mDataSource + QStringLiteral( "&uid=%1" ).arg( QUuid::createUuid().toString() ); } + connect( mDataProvider, &QgsMeshDataProvider::dataChanged, this, &QgsMeshLayer::dataChanged ); + return true; } // QgsMeshLayer:: setDataProvider diff --git a/src/core/mesh/qgsmeshmemorydataprovider.cpp b/src/core/mesh/qgsmeshmemorydataprovider.cpp index 233e51ac5c25..2bf92d1c1bf9 100644 --- a/src/core/mesh/qgsmeshmemorydataprovider.cpp +++ b/src/core/mesh/qgsmeshmemorydataprovider.cpp @@ -307,6 +307,9 @@ bool QgsMeshMemoryDataProvider::addDataset( const QString &uri ) mDatasets.push_back( ds ); + if ( ds.valid ) + emit dataChanged(); + return ds.valid; } diff --git a/src/providers/mdal/qgsmdalprovider.cpp b/src/providers/mdal/qgsmdalprovider.cpp index 0d613a95bcc2..234ef8e94ae8 100644 --- a/src/providers/mdal/qgsmdalprovider.cpp +++ b/src/providers/mdal/qgsmdalprovider.cpp @@ -98,10 +98,21 @@ QgsMeshFace QgsMdalProvider::face( int index ) const bool QgsMdalProvider::addDataset( const QString &uri ) { + int datasetCount = mDatasets.count(); + std::string str = uri.toStdString(); MDAL_M_LoadDatasets( mMeshH, str.c_str() ); refreshDatasets(); - return true; + + if ( datasetCount == mDatasets.count() ) + { + return false; + } + else + { + emit dataChanged(); + return true; // Ok + } } int QgsMdalProvider::datasetCount() const From cd78fbdb8e088938553168bc529db1135a839844 Mon Sep 17 00:00:00 2001 From: Peter Petrik Date: Mon, 25 Jun 2018 17:34:17 +0200 Subject: [PATCH 12/13] fix issues from review --- .../mesh/qgsmeshdataprovider.sip.in | 2 +- .../mesh/qgsmeshrenderersettings.sip.in | 2 +- ...singlebandpseudocolorrendererwidget.sip.in | 4 ++-- src/app/mesh/qgsmeshdatasetgrouptreeview.cpp | 14 +++++++++---- src/app/mesh/qgsmeshdatasetgrouptreeview.h | 3 ++- src/app/mesh/qgsmeshlayerproperties.cpp | 4 ++-- .../qgsmeshrendereractivedatasetwidget.cpp | 8 ++++---- .../mesh/qgsmeshrendereractivedatasetwidget.h | 2 +- .../qgsmeshrenderermeshsettingswidget.cpp | 2 +- .../qgsmeshrenderervectorsettingswidget.cpp | 15 +++++++------- .../qgsmeshrenderervectorsettingswidget.h | 2 +- .../mesh/qgsrenderermeshpropertieswidget.cpp | 3 +-- .../mesh/qgsrenderermeshpropertieswidget.h | 8 ++++---- src/core/mesh/qgsmeshdataprovider.h | 2 +- src/core/mesh/qgsmeshlayerrenderer.cpp | 20 +++++++++---------- src/core/mesh/qgsmeshrenderersettings.cpp | 2 +- src/core/mesh/qgsmeshrenderersettings.h | 2 +- src/core/raster/qgscolorrampshader.cpp | 3 +++ src/gui/raster/qgscolorrampshaderwidget.cpp | 17 ++++++++-------- src/gui/raster/qgscolorrampshaderwidget.h | 20 +++++++++++++++---- .../qgssinglebandpseudocolorrendererwidget.h | 4 ++-- 21 files changed, 80 insertions(+), 59 deletions(-) diff --git a/python/core/auto_generated/mesh/qgsmeshdataprovider.sip.in b/python/core/auto_generated/mesh/qgsmeshdataprovider.sip.in index c786042c6a41..1fbf9c9725c5 100644 --- a/python/core/auto_generated/mesh/qgsmeshdataprovider.sip.in +++ b/python/core/auto_generated/mesh/qgsmeshdataprovider.sip.in @@ -228,7 +228,7 @@ or read on demand %Docstring Associate dataset with the mesh -emits dataChanged when successfull +emits dataChanged when successful %End virtual int datasetCount() const = 0; diff --git a/python/core/auto_generated/mesh/qgsmeshrenderersettings.sip.in b/python/core/auto_generated/mesh/qgsmeshrenderersettings.sip.in index 2f184a84eff4..db2a93c9b944 100644 --- a/python/core/auto_generated/mesh/qgsmeshrenderersettings.sip.in +++ b/python/core/auto_generated/mesh/qgsmeshrenderersettings.sip.in @@ -78,7 +78,7 @@ Represents a mesh renderer settings for scalar datasets %Docstring Returns color ramp shader function %End - void setColorRampShader( QgsColorRampShader shader ); + void setColorRampShader( const QgsColorRampShader &shader ); %Docstring Sets color ramp shader function %End diff --git a/python/gui/auto_generated/raster/qgssinglebandpseudocolorrendererwidget.sip.in b/python/gui/auto_generated/raster/qgssinglebandpseudocolorrendererwidget.sip.in index 38c7e77a1574..b35b858d12ce 100644 --- a/python/gui/auto_generated/raster/qgssinglebandpseudocolorrendererwidget.sip.in +++ b/python/gui/auto_generated/raster/qgssinglebandpseudocolorrendererwidget.sip.in @@ -24,9 +24,9 @@ class QgsSingleBandPseudoColorRendererWidget: QgsRasterRendererWidget virtual QgsRasterRenderer *renderer(); - QgsColorRampShader *shaderFunction() const; + QgsColorRampShader *shaderFunction() const /Factory/; %Docstring -Returns shared function used in the renderer. Caller takes ownership and deletes it. +Returns shader function used in the renderer. Caller takes ownership and deletes it. %End virtual void setMapCanvas( QgsMapCanvas *canvas ); diff --git a/src/app/mesh/qgsmeshdatasetgrouptreeview.cpp b/src/app/mesh/qgsmeshdatasetgrouptreeview.cpp index f352f9a75dd9..19ba25c16440 100644 --- a/src/app/mesh/qgsmeshdatasetgrouptreeview.cpp +++ b/src/app/mesh/qgsmeshdatasetgrouptreeview.cpp @@ -27,6 +27,11 @@ QgsMeshDatasetGroupTreeItem::~QgsMeshDatasetGroupTreeItem() qDeleteAll( mChildren ); } +QgsMeshDatasetGroupTreeItem::QgsMeshDatasetGroupTreeItem( QgsMeshDatasetGroupTreeItem *parent ) + : mParent( parent ) +{ +} + QgsMeshDatasetGroupTreeItem::QgsMeshDatasetGroupTreeItem( const QString &name, QgsMeshDatasetGroupTreeItem *parent ) : mParent( parent ) , mName( name ) @@ -79,7 +84,7 @@ QVariant QgsMeshDatasetGroupTreeItem::data( int column ) const QgsMeshDatasetGroupTreeModel::QgsMeshDatasetGroupTreeModel( QObject *parent ) : QAbstractItemModel( parent ) - , mRootItem( new QgsMeshDatasetGroupTreeItem( "Groups" ) ) + , mRootItem( new QgsMeshDatasetGroupTreeItem() ) { } @@ -118,7 +123,7 @@ QVariant QgsMeshDatasetGroupTreeModel::headerData( int section, Qt::Orientation int role ) const { if ( orientation == Qt::Horizontal && role == Qt::DisplayRole ) - return mRootItem->data( section ); + return tr( "Groups" ); return QVariant(); } @@ -175,6 +180,8 @@ void QgsMeshDatasetGroupTreeModel::setupModelData( const QStringList &groups ) { beginResetModel(); + mRootItem.reset(); + for ( const QString &groupName : groups ) { QgsMeshDatasetGroupTreeItem *item = new QgsMeshDatasetGroupTreeItem( groupName, mRootItem.get() ); @@ -186,7 +193,7 @@ void QgsMeshDatasetGroupTreeModel::setupModelData( const QStringList &groups ) void QgsMeshDatasetGroupTreeModel::clear() { - mRootItem.reset( new QgsMeshDatasetGroupTreeItem( "Groups" ) ); + mRootItem.reset( new QgsMeshDatasetGroupTreeItem() ); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -272,7 +279,6 @@ void QgsMeshDatasetGroupTreeView::extractGroups() void QgsMeshDatasetGroupTreeView::syncToLayer() { mActiveGroup.clear(); - mModel.clear(); extractGroups(); diff --git a/src/app/mesh/qgsmeshdatasetgrouptreeview.h b/src/app/mesh/qgsmeshdatasetgrouptreeview.h index 520f6c311bdd..5309d95b5bca 100644 --- a/src/app/mesh/qgsmeshdatasetgrouptreeview.h +++ b/src/app/mesh/qgsmeshdatasetgrouptreeview.h @@ -47,6 +47,7 @@ class QgsMeshLayer; class APP_NO_EXPORT QgsMeshDatasetGroupTreeItem { public: + QgsMeshDatasetGroupTreeItem( QgsMeshDatasetGroupTreeItem *parent = nullptr ); QgsMeshDatasetGroupTreeItem( const QString &name, QgsMeshDatasetGroupTreeItem *parent = nullptr ); ~QgsMeshDatasetGroupTreeItem(); @@ -134,4 +135,4 @@ class APP_EXPORT QgsMeshDatasetGroupTreeView : public QTreeView QString mActiveGroup; }; -#endif // QGSMESHRENDERERSCALARSETTINGSWIDGET_H +#endif // QGSMESHDATASETGROUPTREE_H diff --git a/src/app/mesh/qgsmeshlayerproperties.cpp b/src/app/mesh/qgsmeshlayerproperties.cpp index 9be4c3235751..30e4777904e2 100644 --- a/src/app/mesh/qgsmeshlayerproperties.cpp +++ b/src/app/mesh/qgsmeshlayerproperties.cpp @@ -42,7 +42,7 @@ QgsMeshLayerProperties::QgsMeshLayerProperties( QgsMapLayer *lyr, QgsMapCanvas * Q_ASSERT( mMeshLayer ); setupUi( this ); - mRendererMeshPropertiesWidget = new QgsRendererMeshPropertiesWidget( lyr, canvas, this ); + mRendererMeshPropertiesWidget = new QgsRendererMeshPropertiesWidget( mMeshLayer, canvas, this ); mOptsPage_StyleContent->layout()->addWidget( mRendererMeshPropertiesWidget ); connect( mLayerOrigNameLineEd, &QLineEdit::textEdited, this, &QgsMeshLayerProperties::updateLayerName ); @@ -149,7 +149,7 @@ void QgsMeshLayerProperties::addDataset() if ( ok ) { syncToLayer(); - QMessageBox::information( this, tr( "Load mesh datasets" ), tr( "Datasets added to the mesh layer." ) ); + QgsDebugMsg( "datasets added to the mesh layer" ); } else { diff --git a/src/app/mesh/qgsmeshrendereractivedatasetwidget.cpp b/src/app/mesh/qgsmeshrendereractivedatasetwidget.cpp index b32d56e5091b..7241e6559b26 100644 --- a/src/app/mesh/qgsmeshrendereractivedatasetwidget.cpp +++ b/src/app/mesh/qgsmeshrendereractivedatasetwidget.cpp @@ -133,7 +133,7 @@ void QgsMeshRendererActiveDatasetWidget::onNativeMeshChecked( int toggle ) void QgsMeshRendererActiveDatasetWidget::onTringularMeshChecked( int toggle ) { Q_UNUSED( toggle ); - emit triangularMeshRenderingOnChange( isTriangularMeshEnabled() ); + emit triangularMeshEnabledChanged( isTriangularMeshEnabled() ); emit widgetChanged(); } @@ -141,15 +141,15 @@ void QgsMeshRendererActiveDatasetWidget::updateMetadata( int datasetIndex ) { if ( datasetIndex == -1 ) { - mActiveDatasetMetadata->setText( QString( "N/A" ) ); + mActiveDatasetMetadata->setText( tr( "N/A" ) ); } else { const QgsMeshDatasetMetadata meta = mMeshLayer->dataProvider()->datasetMetadata( datasetIndex ); QString msg; msg += QStringLiteral( "" ); - msg += QStringLiteral( "" ).arg( meta.isOnVertices() ); - msg += QStringLiteral( "" ).arg( meta.isVector() ); + msg += QStringLiteral( "" ).arg( tr( "is on vertices" ) ).arg( meta.isOnVertices() ); + msg += QStringLiteral( "" ).arg( tr( "is vector" ) ).arg( meta.isVector() ); for ( auto it = meta.extraOptions().constBegin(); it != meta.extraOptions().constEnd(); ++it ) { msg += QStringLiteral( "" ).arg( it.key() ).arg( it.value() ); diff --git a/src/app/mesh/qgsmeshrendereractivedatasetwidget.h b/src/app/mesh/qgsmeshrendereractivedatasetwidget.h index 6bde9bdf7152..90859169036f 100644 --- a/src/app/mesh/qgsmeshrendereractivedatasetwidget.h +++ b/src/app/mesh/qgsmeshrendereractivedatasetwidget.h @@ -71,7 +71,7 @@ class APP_EXPORT QgsMeshRendererActiveDatasetWidget : public QWidget, private Ui void nativeMeshEnabledChanged( bool on ); //! Emitted when rendering of the triangular mesh changed - void triangularMeshRenderingOnChange( bool on ); + void triangularMeshEnabledChanged( bool on ); //! Emitted when any settings related to rendering changed void widgetChanged(); diff --git a/src/app/mesh/qgsmeshrenderermeshsettingswidget.cpp b/src/app/mesh/qgsmeshrenderermeshsettingswidget.cpp index 66147f396cb2..a9ff6faeb843 100644 --- a/src/app/mesh/qgsmeshrenderermeshsettingswidget.cpp +++ b/src/app/mesh/qgsmeshrenderermeshsettingswidget.cpp @@ -66,7 +66,7 @@ void QgsMeshRendererMeshSettingsWidget::syncToLayer( ) if ( mIsTriangularMesh ) settings = mMeshLayer->rendererTriangularMeshSettings(); else - settings = mMeshLayer->rendererTriangularMeshSettings(); + settings = mMeshLayer->rendererNativeMeshSettings(); mColorWidget->setColor( settings.color() ); mLineWidthSpinBox->setValue( settings.lineWidth() ); diff --git a/src/app/mesh/qgsmeshrenderervectorsettingswidget.cpp b/src/app/mesh/qgsmeshrenderervectorsettingswidget.cpp index 646dd8260792..79dc7d823fb3 100644 --- a/src/app/mesh/qgsmeshrenderervectorsettingswidget.cpp +++ b/src/app/mesh/qgsmeshrenderervectorsettingswidget.cpp @@ -37,7 +37,7 @@ QgsMeshRendererVectorSettingsWidget::QgsMeshRendererVectorSettingsWidget( QWidge mShaftOptionsStackedWidget, &QStackedWidget::setCurrentIndex ); QVector widgets; - widgets << mMinMagLineEdit << mMinMagLineEdit + widgets << mMinMagLineEdit << mMaxMagLineEdit << mHeadWidthLineEdit << mHeadLengthLineEdit << mMinimumShaftLineEdit << mMaximumShaftLineEdit << mScaleShaftByFactorOfLineEdit << mShaftLengthLineEdit; @@ -45,7 +45,6 @@ QgsMeshRendererVectorSettingsWidget::QgsMeshRendererVectorSettingsWidget( QWidge for ( auto widget : widgets ) { connect( widget, &QLineEdit::textChanged, this, &QgsMeshRendererVectorSettingsWidget::widgetChanged ); - connect( widget, &QLineEdit::textEdited, this, &QgsMeshRendererVectorSettingsWidget::widgetChanged ); } } @@ -70,8 +69,8 @@ QgsMeshRendererVectorSettings QgsMeshRendererVectorSettingsWidget::settings() co double val = filterValue( mMinMagLineEdit->text(), -1 ); settings.setFilterMin( val ); - val = filterValue( mMinMagLineEdit->text(), -1 ); - settings.setFilterMin( val ); + val = filterValue( mMaxMagLineEdit->text(), -1 ); + settings.setFilterMax( val ); // arrow head val = filterValue( mHeadWidthLineEdit->text(), settings.arrowHeadWidthRatio() ); @@ -139,18 +138,18 @@ void QgsMeshRendererVectorSettingsWidget::syncToLayer( ) } -double QgsMeshRendererVectorSettingsWidget::filterValue( const QString &text, double err_val ) const +double QgsMeshRendererVectorSettingsWidget::filterValue( const QString &text, double errVal ) const { if ( text.isEmpty() ) - return err_val; + return errVal; bool ok; double val = text.toDouble( &ok ); if ( !ok ) - return err_val; + return errVal; if ( val < 0 ) - return err_val; + return errVal; return val; } diff --git a/src/app/mesh/qgsmeshrenderervectorsettingswidget.h b/src/app/mesh/qgsmeshrenderervectorsettingswidget.h index c971dbaea133..d5f8a739b114 100644 --- a/src/app/mesh/qgsmeshrenderervectorsettingswidget.h +++ b/src/app/mesh/qgsmeshrenderervectorsettingswidget.h @@ -66,7 +66,7 @@ class APP_EXPORT QgsMeshRendererVectorSettingsWidget : public QWidget, private U * convert text to double, return err_val if * text is not possible to convert or the value is negative */ - double filterValue( const QString &text, double err_val ) const; + double filterValue( const QString &text, double errVal ) const; QgsMeshLayer *mMeshLayer = nullptr; //not owned int mActiveDataset = -1; diff --git a/src/app/mesh/qgsrenderermeshpropertieswidget.cpp b/src/app/mesh/qgsrenderermeshpropertieswidget.cpp index a4cb4b2db5b2..5c5200aa2b71 100644 --- a/src/app/mesh/qgsrenderermeshpropertieswidget.cpp +++ b/src/app/mesh/qgsrenderermeshpropertieswidget.cpp @@ -23,11 +23,10 @@ #include "qgsmeshdatasetgrouptreeview.h" #include "qgsmeshrendereractivedatasetwidget.h" -QgsRendererMeshPropertiesWidget::QgsRendererMeshPropertiesWidget( QgsMapLayer *layer, QgsMapCanvas *canvas, QWidget *parent ) +QgsRendererMeshPropertiesWidget::QgsRendererMeshPropertiesWidget( QgsMeshLayer *layer, QgsMapCanvas *canvas, QWidget *parent ) : QgsMapLayerConfigWidget( layer, canvas, parent ) { - mMeshLayer = qobject_cast( layer ); if ( !mMeshLayer ) return; diff --git a/src/app/mesh/qgsrenderermeshpropertieswidget.h b/src/app/mesh/qgsrenderermeshpropertieswidget.h index 6f1014d7c279..70dad3a29438 100644 --- a/src/app/mesh/qgsrenderermeshpropertieswidget.h +++ b/src/app/mesh/qgsrenderermeshpropertieswidget.h @@ -12,8 +12,8 @@ * (at your option) any later version. * * * ***************************************************************************/ -#ifndef QGSRENDERERMESHPROPERTIESDIALOG_H -#define QGSRENDERERMESHPROPERTIESDIALOG_H +#ifndef QGSRENDERERMESHPROPERTIESWIDGET_H +#define QGSRENDERERMESHPROPERTIESWIDGET_H #include #include @@ -43,7 +43,7 @@ class APP_EXPORT QgsRendererMeshPropertiesWidget : public QgsMapLayerConfigWidge * \param canvas The canvas object used * \param parent Parent object */ - QgsRendererMeshPropertiesWidget( QgsMapLayer *layer, QgsMapCanvas *canvas, QWidget *parent = nullptr ); + QgsRendererMeshPropertiesWidget( QgsMeshLayer *layer, QgsMapCanvas *canvas, QWidget *parent = nullptr ); ~QgsRendererMeshPropertiesWidget() = default; public slots: @@ -57,4 +57,4 @@ class APP_EXPORT QgsRendererMeshPropertiesWidget : public QgsMapLayerConfigWidge QgsMeshLayer *mMeshLayer = nullptr; //not owned }; -#endif // QGSRENDERERMESHPROPERTIESDIALOG_H +#endif // QGSRENDERERMESHPROPERTIESWIDGET_H diff --git a/src/core/mesh/qgsmeshdataprovider.h b/src/core/mesh/qgsmeshdataprovider.h index 9f9b0831e117..fbba5842bd1d 100644 --- a/src/core/mesh/qgsmeshdataprovider.h +++ b/src/core/mesh/qgsmeshdataprovider.h @@ -216,7 +216,7 @@ class CORE_EXPORT QgsMeshDatasetSourceInterface SIP_ABSTRACT /** * \brief Associate dataset with the mesh * - * emits dataChanged when successfull + * emits dataChanged when successful */ virtual bool addDataset( const QString &uri ) = 0; diff --git a/src/core/mesh/qgsmeshlayerrenderer.cpp b/src/core/mesh/qgsmeshlayerrenderer.cpp index 4fe8c89f0054..05386c608caa 100644 --- a/src/core/mesh/qgsmeshlayerrenderer.cpp +++ b/src/core/mesh/qgsmeshlayerrenderer.cpp @@ -31,8 +31,8 @@ #include "qgsmeshlayerinterpolator.h" #include "qgsmeshvectorrenderer.h" #include "qgsfillsymbollayer.h" - - +#include "qgssettings.h" +#include "qgsstyle.h" QgsMeshLayerRenderer::QgsMeshLayerRenderer( QgsMeshLayer *layer, QgsRenderContext &context ) : QgsMapLayerRenderer( layer->id() ) @@ -65,15 +65,15 @@ void QgsMeshLayerRenderer::assignDefaultScalarShader( ) if ( mScalarDatasetValues.isEmpty() || mRendererScalarSettings.isEnabled() ) return; // no need for default shader, either rendering is off or we already have some shader - double vMin = *std::min_element( mScalarDatasetValues.constBegin(), mScalarDatasetValues.constEnd() ); - double vMax = *std::max_element( mScalarDatasetValues.constBegin(), mScalarDatasetValues.constEnd() ); - - QList lst; - lst << QgsColorRampShader::ColorRampItem( vMin, Qt::blue, QString::number( vMin ) ); - lst << QgsColorRampShader::ColorRampItem( vMax, Qt::red, QString::number( vMax ) ); + auto bounds = std::minmax_element( mScalarDatasetValues.constBegin(), mScalarDatasetValues.constEnd() ); + double vMin = *bounds.first; + double vMax = *bounds.second; - QgsColorRampShader fcn( vMin, vMax ); - fcn.setColorRampItemList( lst ); + QgsSettings settings; + QString defaultPalette = settings.value( QStringLiteral( "/Raster/defaultPalette" ), "Spectral" ).toString(); + std::unique_ptr colorRamp( QgsStyle::defaultStyle()->colorRamp( defaultPalette ) ); + QgsColorRampShader fcn( vMin, vMax, colorRamp.release() ); + fcn.classifyColorRamp( -1, QgsRectangle(), nullptr ); mRendererScalarSettings.setColorRampShader( fcn ); } diff --git a/src/core/mesh/qgsmeshrenderersettings.cpp b/src/core/mesh/qgsmeshrenderersettings.cpp index adb7fc58b276..1f9988efd881 100644 --- a/src/core/mesh/qgsmeshrenderersettings.cpp +++ b/src/core/mesh/qgsmeshrenderersettings.cpp @@ -54,7 +54,7 @@ QgsColorRampShader QgsMeshRendererScalarSettings::colorRampShader() const } -void QgsMeshRendererScalarSettings::setColorRampShader( QgsColorRampShader shader ) +void QgsMeshRendererScalarSettings::setColorRampShader( const QgsColorRampShader &shader ) { mColorRampShader = shader; } diff --git a/src/core/mesh/qgsmeshrenderersettings.h b/src/core/mesh/qgsmeshrenderersettings.h index 4f0fa47c6630..b916fcde4c8e 100644 --- a/src/core/mesh/qgsmeshrenderersettings.h +++ b/src/core/mesh/qgsmeshrenderersettings.h @@ -74,7 +74,7 @@ class CORE_EXPORT QgsMeshRendererScalarSettings //! Returns color ramp shader function QgsColorRampShader colorRampShader() const; //! Sets color ramp shader function - void setColorRampShader( QgsColorRampShader shader ); + void setColorRampShader( const QgsColorRampShader &shader ); //! Returns whether color ramp has any items assigned bool isEnabled() const; diff --git a/src/core/raster/qgscolorrampshader.cpp b/src/core/raster/qgscolorrampshader.cpp index 70f398e672e9..eb17811cbf20 100644 --- a/src/core/raster/qgscolorrampshader.cpp +++ b/src/core/raster/qgscolorrampshader.cpp @@ -59,6 +59,9 @@ QgsColorRampShader &QgsColorRampShader::operator=( const QgsColorRampShader &oth { if ( other.sourceColorRamp() ) mSourceColorRamp.reset( other.sourceColorRamp()->clone() ); + else + mSourceColorRamp.reset(); + mColorRampType = other.mColorRampType; mClassificationMode = other.mClassificationMode; mLUT = other.mLUT; diff --git a/src/gui/raster/qgscolorrampshaderwidget.cpp b/src/gui/raster/qgscolorrampshaderwidget.cpp index d9f4fa256d86..f28b6446b6b4 100644 --- a/src/gui/raster/qgscolorrampshaderwidget.cpp +++ b/src/gui/raster/qgscolorrampshaderwidget.cpp @@ -1,9 +1,9 @@ /*************************************************************************** qgscolorrampshaderwidget.cpp ---------------------------- - begin : Jun 2018 by Peter Petrik - copyright : (C) 2012 by Marco Hugentobler - email : marco at sourcepole dot ch + begin : Jun 2018 + copyright : (C) 2018 by Peter Petrik + email : zilolv at gmail dot com ***************************************************************************/ /*************************************************************************** @@ -295,11 +295,12 @@ void QgsColorRampShaderWidget::classify() return; } - QgsColorRampShader *colorRampShader = new QgsColorRampShader( - mMin, mMax, - ramp.get(), - static_cast< QgsColorRampShader::Type >( mColorInterpolationComboBox->currentData().toInt() ), - static_cast< QgsColorRampShader::ClassificationMode >( mClassificationModeComboBox->currentData().toInt() ) ); + std::unique_ptr< QgsColorRampShader > colorRampShader( new QgsColorRampShader( + mMin, mMax, + ramp.release(), + static_cast< QgsColorRampShader::Type >( mColorInterpolationComboBox->currentData().toInt() ), + static_cast< QgsColorRampShader::ClassificationMode >( mClassificationModeComboBox->currentData().toInt() ) ) + ); // only for Quantile we need band and provider and extent colorRampShader->classifyColorRamp( mNumberOfEntriesSpinBox->value(), diff --git a/src/gui/raster/qgscolorrampshaderwidget.h b/src/gui/raster/qgscolorrampshaderwidget.h index 6f2ab20bb043..ac3e59153ffd 100644 --- a/src/gui/raster/qgscolorrampshaderwidget.h +++ b/src/gui/raster/qgscolorrampshaderwidget.h @@ -1,9 +1,9 @@ /*************************************************************************** qgscolorrampshaderwidget.h -------------------------- - begin : Jun 2018 by Peter Petrik - copyright : (C) 2012 by Marco Hugentobler - email : marco at sourcepole dot ch + begin : Jun 2018 + copyright : (C) 2018 by Peter Petrik + email : zilolv at gmail dot com ***************************************************************************/ /*************************************************************************** @@ -47,19 +47,31 @@ class GUI_EXPORT QgsColorRampShaderWidget: public QWidget, protected Ui::QgsColo QgsColorRampShaderWidget( QWidget *parent = nullptr ); + //! Allows quantile classification mode for raster layers void initForUseWithRasterLayer(); + //! Associates raster with the widget void setRasterBand( QgsRasterDataProvider *dp, int band, const QgsRectangle &extent ); + + //! Sets min max and classify color tree void setMinMaxAndClassify( double min, double max ); + + //! Sets min max void setMinMax( double min, double max ); - //! Returns shared function used in the renderer. Caller takes ownership and deletes it. + //! Returns shared function used in the renderer QgsColorRampShader shader() const; + //! Sets widget state from the color ramp shader void setFromShader( const QgsColorRampShader &colorRampShader ); signals: + //! color ramp tree has changed void minMaxChangedFromTree( double min, double max ); + + //! widget changed void widgetChanged(); + + //! classification mode changed void classificationModeChanged( QgsColorRampShader::ClassificationMode mode ); public slots: diff --git a/src/gui/raster/qgssinglebandpseudocolorrendererwidget.h b/src/gui/raster/qgssinglebandpseudocolorrendererwidget.h index ad13d29d99f9..8c0d90f4f4dc 100644 --- a/src/gui/raster/qgssinglebandpseudocolorrendererwidget.h +++ b/src/gui/raster/qgssinglebandpseudocolorrendererwidget.h @@ -43,8 +43,8 @@ class GUI_EXPORT QgsSingleBandPseudoColorRendererWidget: public QgsRasterRendere static QgsRasterRendererWidget *create( QgsRasterLayer *layer, const QgsRectangle &extent ) SIP_FACTORY { return new QgsSingleBandPseudoColorRendererWidget( layer, extent ); } QgsRasterRenderer *renderer() override; - //! Returns shared function used in the renderer. Caller takes ownership and deletes it. - QgsColorRampShader *shaderFunction() const; + //! Returns shader function used in the renderer. Caller takes ownership and deletes it. + QgsColorRampShader *shaderFunction() const SIP_FACTORY; void setMapCanvas( QgsMapCanvas *canvas ) override; void doComputations() override; QgsRasterMinMaxWidget *minMaxWidget() override { return mMinMaxWidget; } From c94865dcf1951bbad625439d446ac4c2c53dc545 Mon Sep 17 00:00:00 2001 From: Peter Petrik Date: Tue, 26 Jun 2018 08:42:29 +0200 Subject: [PATCH 13/13] fix coredump when opening properties panel --- src/app/mesh/qgsmeshdatasetgrouptreeview.cpp | 23 ++++++++----------- src/app/mesh/qgsmeshdatasetgrouptreeview.h | 2 -- .../mesh/qgsrenderermeshpropertieswidget.cpp | 2 +- src/core/mesh/qgsmeshlayerrenderer.cpp | 2 +- 4 files changed, 12 insertions(+), 17 deletions(-) diff --git a/src/app/mesh/qgsmeshdatasetgrouptreeview.cpp b/src/app/mesh/qgsmeshdatasetgrouptreeview.cpp index 19ba25c16440..290904acfac3 100644 --- a/src/app/mesh/qgsmeshdatasetgrouptreeview.cpp +++ b/src/app/mesh/qgsmeshdatasetgrouptreeview.cpp @@ -21,12 +21,6 @@ #include #include - -QgsMeshDatasetGroupTreeItem::~QgsMeshDatasetGroupTreeItem() -{ - qDeleteAll( mChildren ); -} - QgsMeshDatasetGroupTreeItem::QgsMeshDatasetGroupTreeItem( QgsMeshDatasetGroupTreeItem *parent ) : mParent( parent ) { @@ -38,6 +32,11 @@ QgsMeshDatasetGroupTreeItem::QgsMeshDatasetGroupTreeItem( const QString &name, Q { } +QgsMeshDatasetGroupTreeItem::~QgsMeshDatasetGroupTreeItem() +{ + qDeleteAll( mChildren ); +} + void QgsMeshDatasetGroupTreeItem::appendChild( QgsMeshDatasetGroupTreeItem *node ) { mChildren.append( node ); @@ -119,9 +118,12 @@ Qt::ItemFlags QgsMeshDatasetGroupTreeModel::flags( const QModelIndex &index ) co return QAbstractItemModel::flags( index ); } -QVariant QgsMeshDatasetGroupTreeModel::headerData( int section, Qt::Orientation orientation, +QVariant QgsMeshDatasetGroupTreeModel::headerData( int section, + Qt::Orientation orientation, int role ) const { + Q_UNUSED( section ); + if ( orientation == Qt::Horizontal && role == Qt::DisplayRole ) return tr( "Groups" ); @@ -180,7 +182,7 @@ void QgsMeshDatasetGroupTreeModel::setupModelData( const QStringList &groups ) { beginResetModel(); - mRootItem.reset(); + mRootItem.reset( new QgsMeshDatasetGroupTreeItem() ); for ( const QString &groupName : groups ) { @@ -191,11 +193,6 @@ void QgsMeshDatasetGroupTreeModel::setupModelData( const QStringList &groups ) endResetModel(); } -void QgsMeshDatasetGroupTreeModel::clear() -{ - mRootItem.reset( new QgsMeshDatasetGroupTreeItem() ); -} - ///////////////////////////////////////////////////////////////////////////////////////// QgsMeshDatasetGroupTreeView::QgsMeshDatasetGroupTreeView( QWidget *parent ) diff --git a/src/app/mesh/qgsmeshdatasetgrouptreeview.h b/src/app/mesh/qgsmeshdatasetgrouptreeview.h index 5309d95b5bca..c8da8ed719e1 100644 --- a/src/app/mesh/qgsmeshdatasetgrouptreeview.h +++ b/src/app/mesh/qgsmeshdatasetgrouptreeview.h @@ -90,8 +90,6 @@ class APP_NO_EXPORT QgsMeshDatasetGroupTreeModel : public QAbstractItemModel //! Add groups to the model void setupModelData( const QStringList &groups ); - //! Remove all groups from the model - void clear(); private: std::unique_ptr mRootItem; diff --git a/src/app/mesh/qgsrenderermeshpropertieswidget.cpp b/src/app/mesh/qgsrenderermeshpropertieswidget.cpp index 5c5200aa2b71..7a1eb7eddcde 100644 --- a/src/app/mesh/qgsrenderermeshpropertieswidget.cpp +++ b/src/app/mesh/qgsrenderermeshpropertieswidget.cpp @@ -25,7 +25,7 @@ QgsRendererMeshPropertiesWidget::QgsRendererMeshPropertiesWidget( QgsMeshLayer *layer, QgsMapCanvas *canvas, QWidget *parent ) : QgsMapLayerConfigWidget( layer, canvas, parent ) - + , mMeshLayer( layer ) { if ( !mMeshLayer ) return; diff --git a/src/core/mesh/qgsmeshlayerrenderer.cpp b/src/core/mesh/qgsmeshlayerrenderer.cpp index 05386c608caa..fa5846c1ca96 100644 --- a/src/core/mesh/qgsmeshlayerrenderer.cpp +++ b/src/core/mesh/qgsmeshlayerrenderer.cpp @@ -73,7 +73,7 @@ void QgsMeshLayerRenderer::assignDefaultScalarShader( ) QString defaultPalette = settings.value( QStringLiteral( "/Raster/defaultPalette" ), "Spectral" ).toString(); std::unique_ptr colorRamp( QgsStyle::defaultStyle()->colorRamp( defaultPalette ) ); QgsColorRampShader fcn( vMin, vMax, colorRamp.release() ); - fcn.classifyColorRamp( -1, QgsRectangle(), nullptr ); + fcn.classifyColorRamp( 5, -1, QgsRectangle(), nullptr ); mRendererScalarSettings.setColorRampShader( fcn ); }
is on vertices%1
is vector%1
%1%2
%1%2
%1%2