Skip to content

Commit

Permalink
[FEATURE][MESH] save style for mesh layer (#34996)
Browse files Browse the repository at this point in the history
save style for mesh layer and refactoring for raster and vector widget properties
  • Loading branch information
vcloarec committed Mar 13, 2020
1 parent 9e5966c commit 970052d
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 52 deletions.
127 changes: 126 additions & 1 deletion src/app/mesh/qgsmeshlayerproperties.cpp
Expand Up @@ -21,10 +21,12 @@
#include "qgisapp.h"
#include "qgsapplication.h"
#include "qgscoordinatetransform.h"
#include "qgsfileutils.h"
#include "qgshelp.h"
#include "qgslogger.h"
#include "qgsmapcanvas.h"
#include "qgsmaplayerstylemanager.h"
#include "qgsmaplayerstyleguiutils.h"
#include "qgsmeshlayer.h"
#include "qgsmeshlayerproperties.h"
#include "qgsproject.h"
Expand Down Expand Up @@ -100,6 +102,18 @@ QgsMeshLayerProperties::QgsMeshLayerProperties( QgsMapLayer *lyr, QgsMapCanvas *
mOptsPage_Style->setProperty( "helpPage", QStringLiteral( "working_with_mesh/mesh_properties.html#symbology-properties" ) );
mOptsPage_Rendering->setProperty( "helpPage", QStringLiteral( "working_with_mesh/mesh_properties.html#rendering-properties" ) );


QPushButton *btnStyle = new QPushButton( tr( "Style" ) );
QMenu *menuStyle = new QMenu( this );
menuStyle->addAction( tr( "Load Style…" ), this, &QgsMeshLayerProperties::loadStyle );
menuStyle->addAction( tr( "Save Style…" ), this, &QgsMeshLayerProperties::saveStyleAs );
menuStyle->addSeparator();
menuStyle->addAction( tr( "Save as Default" ), this, &QgsMeshLayerProperties::saveDefaultStyle );
menuStyle->addAction( tr( "Restore Default" ), this, &QgsMeshLayerProperties::loadDefaultStyle );
btnStyle->setMenu( menuStyle );
connect( menuStyle, &QMenu::aboutToShow, this, &QgsMeshLayerProperties::aboutToShowStyleMenu );

buttonBox->addButton( btnStyle, QDialogButtonBox::ResetRole );
}

void QgsMeshLayerProperties::syncToLayer()
Expand Down Expand Up @@ -179,7 +193,7 @@ void QgsMeshLayerProperties::addDataset()

if ( openFileString.isEmpty() )
{
return; //canceled by the user
return; // canceled by the user
}

QFileInfo openFileInfo( openFileString );
Expand All @@ -198,6 +212,107 @@ void QgsMeshLayerProperties::addDataset()
}
}

void QgsMeshLayerProperties::loadDefaultStyle()
{
bool defaultLoadedFlag = false;
QString myMessage = mMeshLayer->loadDefaultStyle( defaultLoadedFlag );
// reset if the default style was loaded OK only
if ( defaultLoadedFlag )
{
syncToLayer();
}
else
{
// otherwise let the user know what went wrong
QMessageBox::information( this,
tr( "Default Style" ),
myMessage
);
}
}

void QgsMeshLayerProperties::saveDefaultStyle()
{
apply(); // make sure the style to save is up-to-date

// a flag passed by reference
bool defaultSavedFlag = false;
// after calling this the above flag will be set true for success
// or false if the save operation failed
QString myMessage = mMeshLayer->saveDefaultStyle( defaultSavedFlag );
if ( !defaultSavedFlag )
{
// let the user know what went wrong
QMessageBox::information( this,
tr( "Default Style" ),
myMessage
);
}
}

void QgsMeshLayerProperties::loadStyle()
{
QgsSettings settings;
QString lastUsedDir = settings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();

QString fileName = QFileDialog::getOpenFileName(
this,
tr( "Load rendering setting from style file" ),
lastUsedDir,
tr( "QGIS Layer Style File" ) + " (*.qml)" );
if ( fileName.isEmpty() )
return;

// ensure the user never omits the extension from the file name
if ( !fileName.endsWith( QLatin1String( ".qml" ), Qt::CaseInsensitive ) )
fileName += QLatin1String( ".qml" );

mOldStyle = mMeshLayer->styleManager()->style( mMeshLayer->styleManager()->currentStyle() );

bool defaultLoadedFlag = false;
QString message = mMeshLayer->loadNamedStyle( fileName, defaultLoadedFlag );
if ( defaultLoadedFlag )
{
settings.setValue( QStringLiteral( "style/lastStyleDir" ), QFileInfo( fileName ).absolutePath() );
syncToLayer();
}
else
{
QMessageBox::information( this, tr( "Load Style" ), message );
}
}

void QgsMeshLayerProperties::saveStyleAs()
{
QgsSettings settings;
QString lastUsedDir = settings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();

QString outputFileName = QFileDialog::getSaveFileName(
this,
tr( "Save layer properties as style file" ),
lastUsedDir,
tr( "QGIS Layer Style File" ) + " (*.qml)" );
if ( outputFileName.isEmpty() )
return;

// ensure the user never omits the extension from the file name
outputFileName = QgsFileUtils::ensureFileNameHasExtension( outputFileName, QStringList() << QStringLiteral( "qml" ) );

apply(); // make sure the style to save is up-to-date

// then export style
bool defaultLoadedFlag = false;
QString message;
message = mMeshLayer->saveNamedStyle( outputFileName, defaultLoadedFlag );

if ( defaultLoadedFlag )
{
settings.setValue( QStringLiteral( "style/lastStyleDir" ), QFileInfo( outputFileName ).absolutePath() );
}
else
QMessageBox::information( this, tr( "Save Style" ), message );
}

void QgsMeshLayerProperties::apply()
{
Q_ASSERT( mRendererMeshPropertiesWidget );
Expand Down Expand Up @@ -274,3 +389,13 @@ void QgsMeshLayerProperties::showHelp()
QgsHelp::openHelp( QStringLiteral( "working_with_mesh/mesh_properties.html" ) );
}
}

void QgsMeshLayerProperties::aboutToShowStyleMenu()
{
QMenu *m = qobject_cast<QMenu *>( sender() );

QgsMapLayerStyleGuiUtils::instance()->removesExtraMenuSeparators( m );
// re-add style manager actions!
m->addSeparator();
QgsMapLayerStyleGuiUtils::instance()->addStyleManagerActions( m, mMeshLayer );
}
25 changes: 20 additions & 5 deletions src/app/mesh/qgsmeshlayerproperties.h
Expand Up @@ -19,6 +19,7 @@

#include "ui_qgsmeshlayerpropertiesbase.h"

#include "qgsmaplayerstylemanager.h"
#include "qgsoptionsdialogbase.h"
#include "qgsguiutils.h"
#include "qgis_app.h"
Expand Down Expand Up @@ -46,20 +47,29 @@ class APP_EXPORT QgsMeshLayerProperties : public QgsOptionsDialogBase, private U
QgsMeshLayerProperties( QgsMapLayer *lyr, QgsMapCanvas *canvas, QWidget *parent = nullptr, Qt::WindowFlags = QgsGuiUtils::ModalDialogFlags );

private slots:
//! Synchronize widgets state with associated mesh layer
//! Synchronizes widgets state with associated mesh layer
void syncToLayer();

//!Applies the settings made in the dialog without closing the box
void apply();
//! \brief Slot to update layer display name as original is edited.
void updateLayerName( const QString &text );
//! Synchronize GUI state with associated mesh layer and trigger repaint
//! Synchronizes GUI state with associated mesh layer and trigger repaint
void syncAndRepaint();
//! Change layer coordinate reference system
//! Changes layer coordinate reference system
void changeCrs( const QgsCoordinateReferenceSystem &crs );
//! Associate dataset to the mesh layer
//! Associates dataset to the mesh layer
void addDataset();

//! Loads the default style when appropriate button is pressed
void loadDefaultStyle();
//! Saves the default style when appropriate button is pressed
void saveDefaultStyle();
//! Loads a saved style when appropriate button is pressed
void loadStyle();
//! Saves a style when appriate button is pressed
void saveStyleAs();

void aboutToShowStyleMenu();
private:
//! Pointer to the mesh styling widget
QgsRendererMeshPropertiesWidget *mRendererMeshPropertiesWidget = nullptr;
Expand All @@ -70,6 +80,11 @@ class APP_EXPORT QgsMeshLayerProperties : public QgsOptionsDialogBase, private U
//! Pointer to mesh 3d styling widget
QgsMeshLayer3DRendererWidget *mMesh3DWidget = nullptr;

/**
* Previous layer style. Used to reset style to previous state if new style
* was loaded but dialog is canceled */
QgsMapLayerStyle mOldStyle;

friend class TestQgsMeshLayerPropertiesDialog;

void showHelp();
Expand Down
26 changes: 26 additions & 0 deletions src/gui/qgsmaplayerstyleguiutils.cpp
Expand Up @@ -94,6 +94,32 @@ void QgsMapLayerStyleGuiUtils::addStyleManagerActions( QMenu *m, QgsMapLayer *la
m->addAction( a );
}

void QgsMapLayerStyleGuiUtils::removesExtraMenuSeparators( QMenu *m )
{
if ( !m )
return;

// Get rid of previously added style manager actions (they are dynamic)
bool gotFirstSeparator = false;
QList<QAction *> actions = m->actions();
for ( int i = 0; i < actions.count(); ++i )
{
if ( actions[i]->isSeparator() )
{
if ( gotFirstSeparator )
{
// remove all actions after second separator (including it)
while ( actions.count() != i )
delete actions.takeAt( i );
break;
}
else
gotFirstSeparator = true;
}
}

}

void QgsMapLayerStyleGuiUtils::addStyle()
{
QAction *a = qobject_cast<QAction *>( sender() );
Expand Down
9 changes: 9 additions & 0 deletions src/gui/qgsmaplayerstyleguiutils.h
Expand Up @@ -51,6 +51,15 @@ class GUI_EXPORT QgsMapLayerStyleGuiUtils : public QObject
*/
void addStyleManagerActions( QMenu *m, QgsMapLayer *layer );

/**
* \brief removes extra separators from the menu
*
* \since QGIS 3.14
*/
void removesExtraMenuSeparators( QMenu *m );

public slots:

private :
QAction *actionAddStyle( QgsMapLayer *layer, QObject *parent = nullptr );
QAction *actionRemoveStyle( QgsMapLayer *layer, QObject *parent = nullptr );
Expand Down
22 changes: 1 addition & 21 deletions src/gui/raster/qgsrasterlayerproperties.cpp
Expand Up @@ -1536,28 +1536,8 @@ void QgsRasterLayerProperties::aboutToShowStyleMenu()
// this should be unified with QgsVectorLayerProperties::aboutToShowStyleMenu()

QMenu *m = qobject_cast<QMenu *>( sender() );
if ( !m )
return;

// first get rid of previously added style manager actions (they are dynamic)
bool gotFirstSeparator = false;
QList<QAction *> actions = m->actions();
for ( int i = 0; i < actions.count(); ++i )
{
if ( actions[i]->isSeparator() )
{
if ( gotFirstSeparator )
{
// remove all actions after second separator (including it)
while ( actions.count() != i )
delete actions.takeAt( i );
break;
}
else
gotFirstSeparator = true;
}
}

QgsMapLayerStyleGuiUtils::instance()->removesExtraMenuSeparators( m );
// re-add style manager actions!
m->addSeparator();
QgsMapLayerStyleGuiUtils::instance()->addStyleManagerActions( m, mRasterLayer );
Expand Down
29 changes: 4 additions & 25 deletions src/gui/vector/qgsvectorlayerproperties.cpp
Expand Up @@ -89,7 +89,7 @@

QgsVectorLayerProperties::QgsVectorLayerProperties(
QgsMapCanvas *canvas,
QgsMessageBar* messageBar,
QgsMessageBar *messageBar,
QgsVectorLayer *lyr,
QWidget *parent,
Qt::WindowFlags fl
Expand Down Expand Up @@ -415,7 +415,7 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(

mAuxiliaryLayerActionExport = new QAction( tr( "Export" ), this );
menu->addAction( mAuxiliaryLayerActionExport );
connect( mAuxiliaryLayerActionExport, &QAction::triggered, this, [=]{ emit exportAuxiliaryLayer( mLayer->auxiliaryLayer() ); } );
connect( mAuxiliaryLayerActionExport, &QAction::triggered, this, [ = ] { emit exportAuxiliaryLayer( mLayer->auxiliaryLayer() ); } );

mAuxiliaryStorageActions->setMenu( menu );

Expand Down Expand Up @@ -1255,7 +1255,7 @@ void QgsVectorLayerProperties::saveMultipleStylesAs()
else
{
mMessageBar->pushMessage( infoWindowTitle, tr( "Style '%1' saved" ).arg( styleName ),
Qgis::Info, timeout );
Qgis::Info, timeout );
}
break;
}
Expand All @@ -1271,30 +1271,9 @@ void QgsVectorLayerProperties::saveMultipleStylesAs()
void QgsVectorLayerProperties::aboutToShowStyleMenu()
{
// this should be unified with QgsRasterLayerProperties::aboutToShowStyleMenu()

QMenu *m = qobject_cast<QMenu *>( sender() );
if ( !m )
return;

// first get rid of previously added style manager actions (they are dynamic)
bool gotFirstSeparator = false;
QList<QAction *> actions = m->actions();
for ( int i = 0; i < actions.count(); ++i )
{
if ( actions[i]->isSeparator() )
{
if ( gotFirstSeparator )
{
// remove all actions after second separator (including it)
while ( actions.count() != i )
delete actions.takeAt( i );
break;
}
else
gotFirstSeparator = true;
}
}

QgsMapLayerStyleGuiUtils::instance()->removesExtraMenuSeparators( m );
// re-add style manager actions!
m->addSeparator();
QgsMapLayerStyleGuiUtils::instance()->addStyleManagerActions( m, mLayer );
Expand Down

0 comments on commit 970052d

Please sign in to comment.