Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mesh gui #13

Closed
wants to merge 13 commits into from
47 changes: 9 additions & 38 deletions python/core/auto_generated/mesh/qgsmeshrenderersettings.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@




class QgsMeshRendererMeshSettings
{
%Docstring
Expand Down Expand Up @@ -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<double>.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<double>.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

};
Expand Down
5 changes: 5 additions & 0 deletions python/core/auto_generated/raster/qgscolorrampshader.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ Copy constructor
%End


QgsColorRampShader *clone() const /Factory/;
%Docstring
Clones this shader, return new instance
%End

struct ColorRampItem
{
ColorRampItem();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
8 changes: 8 additions & 0 deletions src/app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,8 @@ SET(QGIS_APP_SRCS
qgssettingstree.cpp
qgsvariantdelegate.cpp
qgscrashhandler.cpp

mesh/qgsmeshlayerproperties.cpp
)

SET (QGIS_APP_MOC_HDRS
Expand Down Expand Up @@ -408,6 +410,8 @@ SET (QGIS_APP_MOC_HDRS

qgssettingstree.h
qgsvariantdelegate.h

mesh/qgsmeshlayerproperties.h
)


Expand Down Expand Up @@ -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
Expand All @@ -607,6 +612,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
Expand Down Expand Up @@ -658,6 +664,7 @@ INCLUDE_DIRECTORIES(
../core/processing
../core/providers/memory
../core/raster
../core/mesh
../core/scalebar
../core/symbology
../gui
Expand All @@ -666,6 +673,7 @@ INCLUDE_DIRECTORIES(
../gui/auth
../gui/ogr
../gui/raster
../gui/mesh
../gui/editorwidgets
../gui/editorwidgets/core
../gui/layertree
Expand Down
197 changes: 197 additions & 0 deletions src/app/mesh/qgsmeshlayerproperties.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
/***************************************************************************
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 <limits>
#include <typeinfo>

#include "qgisapp.h"
#include "qgsapplication.h"
#include "qgscoordinatetransform.h"
#include "qgshelp.h"
#include "qgslogger.h"
#include "qgsmapcanvas.h"
#include "qgsmaplayerstylemanager.h"
#include "qgsmeshlayer.h"
#include "qgsmeshlayerproperties.h"
#include "qgsproject.h"
#include "qgsprojectionselectiondialog.h"
#include "qgsrenderermeshpropertieswidget.h"
#include "qgssettings.h"

#include <QFileDialog>

QgsMeshLayerProperties::QgsMeshLayerProperties( QgsMapLayer *lyr, QgsMapCanvas *canvas, QWidget *parent, Qt::WindowFlags fl )
: QgsOptionsDialogBase( QStringLiteral( "MeshLayerProperties" ), parent, fl )
, mMeshLayer( qobject_cast<QgsMeshLayer *>( lyr ) )
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about we only expect QgsMeshLayer in constructor? should be safer and we would not need to test "if ( mMeshLayer )" in various places

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if ( mMeshLayer ) is in the code because of pointer in the constuctor, not because of type cast to mesh layer. Do we want to replace it with reference?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Until now probably everywhere in qgis code we use pointers to map layers, so i would keep that for consistency. Maybe just add Q_ASSERT( mMeshLayer ) to the constructor?

{
setupUi( this );
mRendererMeshPropertiesWidget = new QgsRendererMeshPropertiesWidget( lyr, canvas, this );
mOptsPage_StyleContent->layout()->addWidget( mRendererMeshPropertiesWidget );

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),
// 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();

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 );
}

void QgsMeshLayerProperties::syncToLayer()
{
Q_ASSERT( mRendererMeshPropertiesWidget );

QgsDebugMsg( "populate general information tab" );
/*
* Information Tab
*/
QString info;
if ( mMeshLayer && mMeshLayer->dataProvider() )
{
info += QStringLiteral( "<table>" );
info += QStringLiteral( "<tr><td>%1</td><td>%2</td><tr>" ).arg( tr( "Uri" ) ).arg( mMeshLayer->dataProvider()->dataSourceUri() );
info += QStringLiteral( "<tr><td>%1</td><td>%2</td><tr>" ).arg( tr( "Vertex count" ) ).arg( mMeshLayer->dataProvider()->vertexCount() );
info += QStringLiteral( "<tr><td>%1</td><td>%2</td><tr>" ).arg( tr( "Face count" ) ).arg( mMeshLayer->dataProvider()->faceCount() );
info += QStringLiteral( "<tr><td>%1</td><td>%2</td><tr>" ).arg( tr( "Dataset count" ) ).arg( mMeshLayer->dataProvider()->datasetCount() );
info += QStringLiteral( "</table>" );
}
else
{
info += tr( "Invalid data provider" );
}
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();

}

void QgsMeshLayerProperties::addDataset()
{
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 )
syncToLayer();
}
}

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()
{

}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove?


void QgsMeshLayerProperties::changeCrs( const QgsCoordinateReferenceSystem &crs )
{
if ( mMeshLayer )
mMeshLayer->setCrs( crs );
}

void QgsMeshLayerProperties::updateLayerName( const QString &text )
{
leDisplayName->setText( mMeshLayer->formatLayerName( text ) );
}

void QgsMeshLayerProperties::syncAndRepaint()
{
syncToLayer();
mMeshLayer->triggerRepaint();
}

void QgsMeshLayerProperties::showHelp()
{
QgsHelp::openHelp( QStringLiteral( "working_with_mesh/mesh_properties.html" ) );
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better not to implement this (yet) if the page does not exist

Loading