create dialog for saving different styles

This commit is contained in:
Denis Rouzaud 2018-09-13 14:11:31 -04:00 committed by Nyall Dawson
parent 20a70eea25
commit cb9774022f
18 changed files with 451 additions and 182 deletions

View File

@ -110,9 +110,9 @@ QgsMeshLayer cannot be copied.
virtual QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) /Factory/;
virtual bool readSymbology( const QDomNode &node, QString &errorMessage,
QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories );
QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories );
virtual bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories ) const;
const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) const;
virtual QString encodedSource( const QString &source, const QgsReadWriteContext &context ) const;
virtual QString decodedSource( const QString &source, const QString &provider, const QgsReadWriteContext &context ) const;

View File

@ -89,7 +89,7 @@ This is the base class for all map layer types (vector, raster).
AttributeTable,
Rendering,
CustomProperties,
AllCategories
AllStyleCategories
};
typedef QFlags<QgsMapLayer::StyleCategory> StyleCategories;
@ -824,7 +824,7 @@ Retrieve a named style for this layer from a sqlite database.
%End
virtual bool importNamedStyle( QDomDocument &doc, QString &errorMsg /Out/,
QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories );
QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories );
%Docstring
Import the properties of this layer from a QDomDocument
@ -838,13 +838,14 @@ Import the properties of this layer from a QDomDocument
.. versionadded:: 2.8
%End
virtual void exportNamedStyle( QDomDocument &doc, QString &errorMsg /Out/, QgsReadWriteContext &context,
QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories ) const;
virtual void exportNamedStyle( QDomDocument &doc, QString &errorMsg /Out/, const QgsReadWriteContext &context = QgsReadWriteContext(),
QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) const;
%Docstring
Export the properties of this layer as named style in a QDomDocument
:param doc: the target QDomDocument
:param errorMsg: this QString will be initialized on error
:param context: read write context
:param categories: the style categories to export
during the execution of writeSymbology
%End
@ -923,25 +924,27 @@ Attempts to style the layer using the formatting from an SLD type file.
virtual bool readSymbology( const QDomNode &node, QString &errorMessage,
QgsReadWriteContext &context, StyleCategories categories = AllCategories ) = 0;
QgsReadWriteContext &context, StyleCategories categories = AllStyleCategories ) = 0;
%Docstring
Read the symbology for the current layer from the DOM node supplied.
:param node: node that will contain the symbology definition for this layer.
:param errorMessage: reference to string that will be updated with any error messages
:param context: reading context (used for transform from relative to absolute paths)
:param categories: the style categories to be read
:return: true in case of success.
%End
virtual bool readStyle( const QDomNode &node, QString &errorMessage,
QgsReadWriteContext &context, StyleCategories categories = AllCategories );
QgsReadWriteContext &context, StyleCategories categories = AllStyleCategories );
%Docstring
Read the style for the current layer from the DOM node supplied.
:param node: node that will contain the style definition for this layer.
:param errorMessage: reference to string that will be updated with any error messages
:param context: reading context (used for transform from relative to absolute paths)
:param categories: the style categories to be read
:return: true in case of success.
@ -953,7 +956,7 @@ Read the style for the current layer from the DOM node supplied.
%End
virtual bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context,
StyleCategories categories = AllCategories ) const = 0;
StyleCategories categories = AllStyleCategories ) const = 0;
%Docstring
Write the style for the layer into the docment provided.
@ -961,6 +964,7 @@ Write the style for the layer into the docment provided.
:param doc: the document that will have the QDomNode added.
:param errorMessage: reference to string that will be updated with any error messages
:param context: writing context (used for transform from absolute to relative paths)
:param categories: the style categories to be written
.. note::
@ -970,7 +974,7 @@ Write the style for the layer into the docment provided.
%End
virtual bool writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context,
StyleCategories categories = AllCategories ) const;
StyleCategories categories = AllStyleCategories ) const;
%Docstring
Write just the symbology information for the layer into the document
@ -978,6 +982,7 @@ Write just the symbology information for the layer into the document
:param doc: the document that will have the QDomNode added.
:param errorMessage: reference to string that will be updated with any error messages
:param context: writing context (used for transform from absolute to relative paths)
:param categories: the style categories to be written
:return: true in case of success.
@ -1546,7 +1551,7 @@ Write style manager's configuration (if exists). To be called by subclasses.
void writeCommonStyle( QDomElement &layerElement, QDomDocument &document,
const QgsReadWriteContext &context,
StyleCategories categories = AllCategories ) const;
StyleCategories categories = AllStyleCategories ) const;
%Docstring
Write style data common to all layer types
@ -1554,7 +1559,7 @@ Write style data common to all layer types
%End
void readCommonStyle( const QDomElement &layerElement, const QgsReadWriteContext &context,
StyleCategories categories = AllCategories );
StyleCategories categories = AllStyleCategories );
%Docstring
Read style data common to all layer types

View File

@ -871,7 +871,7 @@ Returns the current auxiliary layer.
virtual bool readSymbology( const QDomNode &layerNode, QString &errorMessage,
QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories );
QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories );
%Docstring
Read the symbology for the current layer from the Dom node supplied.
@ -883,7 +883,7 @@ Read the symbology for the current layer from the Dom node supplied.
%End
virtual bool readStyle( const QDomNode &node, QString &errorMessage,
QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories );
QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories );
%Docstring
Read the style for the current layer from the Dom node supplied.
@ -895,7 +895,7 @@ Read the style for the current layer from the Dom node supplied.
%End
virtual bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories ) const;
const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) const;
%Docstring
Write the symbology for the layer into the docment provided.
@ -908,7 +908,7 @@ Write the symbology for the layer into the docment provided.
%End
virtual bool writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories ) const;
const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) const;
%Docstring
Write just the style information for the layer into the document

View File

@ -348,16 +348,16 @@ Draws a preview of the rasterlayer into a QImage
void showStatusMessage( const QString &message );
protected:
virtual bool readSymbology( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories );
virtual bool readSymbology( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories );
virtual bool readStyle( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories );
virtual bool readStyle( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories );
virtual bool readXml( const QDomNode &layer_node, QgsReadWriteContext &context );
virtual bool writeSymbology( QDomNode &, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories ) const;
const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) const;
virtual bool writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories ) const;
const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) const;
virtual bool writeXml( QDomNode &layer_node, QDomDocument &doc, const QgsReadWriteContext &context ) const;
virtual QString encodedSource( const QString &source, const QgsReadWriteContext &context ) const;

View File

@ -138,6 +138,7 @@ SET(QGIS_APP_SRCS
qgssvgannotationdialog.cpp
qgsundowidget.cpp
qgsvectorlayerlegendwidget.cpp
qgsvectorlayerloadsavestyledialog.cpp
qgsvectorlayerproperties.cpp
qgsmapthemes.cpp
qgshandlebadlayers.cpp
@ -377,6 +378,7 @@ SET (QGIS_APP_MOC_HDRS
qgstextannotationdialog.h
qgsundowidget.h
qgsvectorlayerlegendwidget.h
qgsvectorlayerloadsavestyledialog.h
qgsvectorlayerproperties.h
qgsmapthemes.h
qgshandlebadlayers.h

View File

@ -834,7 +834,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
* \param sourceLayer The layer where the style will be taken from (defaults to the active layer on the legend)
* \param categories The style categories to copy
*/
void copyStyle( QgsMapLayer *sourceLayer = nullptr, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories );
void copyStyle( QgsMapLayer *sourceLayer = nullptr, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories );
//! pastes style on the clipboard to the active layer
/**
@ -842,7 +842,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
* \param categories The style categories to copy
*/
void pasteStyle( QgsMapLayer *destinationLayer = nullptr,
QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories );
QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories );
//! copies group or layer on the clipboard
void copyLayer();
//! pastes group or layer from the clipboard to layer tree

View File

@ -321,7 +321,7 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu()
QMenu *copyStyleMenu = menuStyleManager->addMenu( tr( "Copy Style" ) );
copyStyleMenu->setToolTipsVisible( true );
QList<QgsMapLayer::StyleCategory> categories = qgsEnumMap<QgsMapLayer::StyleCategory>().keys();
categories.move( categories.indexOf( QgsMapLayer::AllCategories ), 0 ); // move All categories to top
categories.move( categories.indexOf( QgsMapLayer::AllStyleCategories ), 0 ); // move All categories to top
for ( QgsMapLayer::StyleCategory category : categories )
{
QgsMapLayer::ReadableStyleCategory readableCategory = QgsMapLayer::readableStyleCategory( category );
@ -329,7 +329,7 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu()
copyAction->setToolTip( readableCategory.toolTip() );
connect( copyAction, &QAction::triggered, this, [ = ]() {app->copyStyle( layer, category );} );
copyStyleMenu->addAction( copyAction );
if ( category == QgsMapLayer::AllCategories )
if ( category == QgsMapLayer::AllStyleCategories )
copyStyleMenu->addSeparator();
}
}
@ -345,7 +345,7 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu()
QMenu *copyStyleMenu = menuStyleManager->addMenu( tr( "Paste Style" ) );
copyStyleMenu->setToolTipsVisible( true );
QList<QgsMapLayer::StyleCategory> categories = qgsEnumMap<QgsMapLayer::StyleCategory>().keys();
categories.move( categories.indexOf( QgsMapLayer::AllCategories ), 0 ); // move All categories to top
categories.move( categories.indexOf( QgsMapLayer::AllStyleCategories ), 0 ); // move All categories to top
for ( QgsMapLayer::StyleCategory category : categories )
{
QgsMapLayer::ReadableStyleCategory readableCategory = QgsMapLayer::readableStyleCategory( category );
@ -353,7 +353,7 @@ QMenu *QgsAppLayerTreeViewMenuProvider::createContextMenu()
copyAction->setToolTip( readableCategory.toolTip() );
connect( copyAction, &QAction::triggered, this, [ = ]() {app->pasteStyle( layer, category );} );
copyStyleMenu->addAction( copyAction );
if ( category == QgsMapLayer::AllCategories )
if ( category == QgsMapLayer::AllStyleCategories )
copyStyleMenu->addSeparator();
}
}

View File

@ -0,0 +1,96 @@
/***************************************************************************
qgsvectorlayerloadsavestyledialog.h
--------------------------------------
Date : September 2018
Copyright : (C) 2018 by Denis Rouzaud
Email : denis@opengis.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 <QListWidgetItem>
#include <QMessageBox>
#include "qgsvectorlayerloadsavestyledialog.h"
#include "qgsvectorlayer.h"
#include "qgssettings.h"
#include "qgisapp.h"
#include "qgshelp.h"
QgsVectorLayerLoadSaveStyleDialog::QgsVectorLayerLoadSaveStyleDialog( QgsVectorLayer *layer, Mode mode, QWidget *parent )
: QDialog( parent )
, mLayer( layer )
, mMode( mode )
{
setupUi( this );
QString providerName = mLayer->providerType();
if ( providerName == QLatin1String( "ogr" ) )
{
providerName = mLayer->dataProvider()->storageType();
if ( providerName == QLatin1String( "GPKG" ) )
providerName = QStringLiteral( "GeoPackage" );
}
//QStringLiteral( "style/lastStyleDir" )
QgsSettings settings;
QgsMapLayer::StyleCategories lastStyleCategories = settings.flagValue( QStringLiteral( "style/lastStyleCategories" ), QgsMapLayer::AllStyleCategories );
switch ( mMode )
{
case Save:
mModeLabel->setText( tr( "Save" ) );
mStyleTypeComboBox->addItem( tr( "from file" ), GenericFile );
if ( mLayer->dataProvider()->isSaveAndLoadStyleToDatabaseSupported() )
mStyleTypeComboBox->addItem( tr( "from database (%1)" ).arg( providerName ), DB );
break;
case Load:
mModeLabel->setText( tr( "Load" ) );
mStyleTypeComboBox->addItem( tr( "as QGIS QML style file" ), QML );
mStyleTypeComboBox->addItem( tr( "as SLD style file" ), SLD );
if ( mLayer->dataProvider()->isSaveAndLoadStyleToDatabaseSupported() )
mStyleTypeComboBox->addItem( tr( "in database (%1)" ).arg( providerName ), DB );
break;
}
connect( mStyleTypeComboBox, qgis::overload<int>::of( &QComboBox::currentIndexChanged ), this, [ = ]( int idx ) {mFileWidget->setVisible( mStyleTypeComboBox->itemData( idx ) != DB );} );
for ( QgsMapLayer::StyleCategory category : qgsEnumMap<QgsMapLayer::StyleCategory>().keys() )
{
if ( category == QgsMapLayer::AllStyleCategories )
continue;
QgsMapLayer::ReadableStyleCategory readableCategory = QgsMapLayer::readableStyleCategory( category );
QListWidgetItem *item = new QListWidgetItem( readableCategory.icon(), readableCategory.name(), mStyleCategoriesListWidget );
item->setFlags( item->flags() | Qt::ItemIsUserCheckable );
item->setCheckState( lastStyleCategories.testFlag( category ) ? Qt::Checked : Qt::Unchecked );
item->setData( Qt::UserRole, category );
}
}
void QgsVectorLayerLoadSaveStyleDialog::accept()
{
bool ok = true;
QgsMapLayer::StyleCategories lastStyleCategories;
for ( int row = 0; row < mStyleCategoriesListWidget->count(); ++row )
{
QListWidgetItem *item = mStyleCategoriesListWidget->item( row );
if ( item->checkState() == Qt::Checked )
lastStyleCategories |= static_cast<QgsMapLayer::StyleCategory>( item->data( Qt::UserRole ).toInt() );
}
if ( ok )
{
QgsSettings settings;
settings.setFlagValue( QStringLiteral( "style/lastStyleCategories" ), lastStyleCategories );
close();
}
}

View File

@ -0,0 +1,55 @@
/***************************************************************************
qgsvectorlayerloadsavestyledialog.h
--------------------------------------
Date : September 2018
Copyright : (C) 2018 by Denis Rouzaud
Email : denis@opengis.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 QGSVECTORLAYERLOADSAVESTYLEDIALOG_H
#define QGSVECTORLAYERLOADSAVESTYLEDIALOG_H
#include <QDialog>
#include "ui_qgsvectorlayerloadsavestyledialog.h"
class QgsVectorLayer;
class QgsVectorLayerLoadSaveStyleDialog : public QDialog, private Ui::QgsVectorLayerLoadSaveStyleDialog
{
Q_OBJECT
public:
enum Mode
{
Save,
Load
};
enum StyleType
{
GenericFile,
QML,
SLD,
DB,
};
explicit QgsVectorLayerLoadSaveStyleDialog( QgsVectorLayer *layer, Mode mode, QWidget *parent = nullptr );
~QgsVectorLayerLoadSaveStyleDialog() = default;
public slots:
void accept();
private:
QgsVectorLayer *mLayer;
Mode mMode;
};
#endif // QGSVECTORLAYERLOADSAVESTYLE_H

View File

@ -63,6 +63,7 @@
#include "qgslabelinggui.h"
#include "qgssymbollayer.h"
#include "qgsgeometryfixes.h"
#include "qgsvectorlayerloadsavestyledialog.h"
#include "layertree/qgslayertreelayer.h"
#include "qgslayertree.h"
@ -117,8 +118,8 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
mBtnStyle = new QPushButton( tr( "Style" ), this );
QMenu *menuStyle = new QMenu( this );
mActionLoadStyle = menuStyle->addAction( tr( "Load Style" ), this, SLOT( loadStyle_clicked() ) );
mActionSaveStyleAs = menuStyle->addAction( tr( "Save Style" ), this, SLOT( saveStyleAs_clicked() ) );
mActionLoadStyle = menuStyle->addAction( tr( "Load Style" ), this, &QgsVectorLayerProperties::loadStyle_clicked );
menuStyle->addAction( tr( "Save Style" ), this, &QgsVectorLayerProperties::saveStyleAs );
menuStyle->addSeparator();
menuStyle->addAction( tr( "Save as Default" ), this, SLOT( saveDefaultStyle_clicked() ) );
menuStyle->addAction( tr( "Restore Default" ), this, SLOT( loadDefaultStyle_clicked() ) );
@ -186,11 +187,6 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
mActionDialog->layout()->setMargin( 0 );
actionLayout->addWidget( mActionDialog );
// Create the menu for the save style button to choose the output format
mSaveAsMenu = new QMenu( this );
mSaveAsMenu->addAction( tr( "QGIS Layer Style File…" ) );
mSaveAsMenu->addAction( tr( "SLD File…" ) );
//Only if the provider support loading & saving styles to db add new choices
if ( mLayer->dataProvider()->isSaveAndLoadStyleToDatabaseSupported() )
{
@ -203,21 +199,8 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
connect( mLoadStyleMenu, &QMenu::triggered,
this, &QgsVectorLayerProperties::loadStyleMenuTriggered );
//for saving
QString providerName = mLayer->providerType();
if ( providerName == QLatin1String( "ogr" ) )
{
providerName = mLayer->dataProvider()->storageType();
if ( providerName == QLatin1String( "GPKG" ) )
providerName = QStringLiteral( "GeoPackage" );
}
mSaveAsMenu->addAction( tr( "Save in Database (%1)" ).arg( providerName ) );
}
connect( mSaveAsMenu, &QMenu::triggered,
this, &QgsVectorLayerProperties::saveStyleAsMenuTriggered );
mSourceFieldsPropertiesDialog = new QgsSourceFieldsProperties( mLayer, mSourceFieldsFrame );
mSourceFieldsPropertiesDialog->layout()->setMargin( 0 );
mSourceFieldsFrame->setLayout( new QVBoxLayout( mSourceFieldsFrame ) );
@ -992,8 +975,8 @@ void QgsVectorLayerProperties::saveDefaultStyle_clicked()
void QgsVectorLayerProperties::loadStyle_clicked()
{
QgsSettings myQSettings; // where we keep last used filter in persistent state
QString myLastUsedDir = myQSettings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();
QgsSettings settings; // where we keep last used filter in persistent state
QString myLastUsedDir = settings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();
QString myFileName = QFileDialog::getOpenFileName( this, tr( "Load Layer Properties from Style File" ), myLastUsedDir,
tr( "QGIS Layer Style File" ) + " (*.qml);;" + tr( "SLD File" ) + " (*.sld)" );
@ -1029,17 +1012,12 @@ void QgsVectorLayerProperties::loadStyle_clicked()
QFileInfo myFI( myFileName );
QString myPath = myFI.path();
myQSettings.setValue( QStringLiteral( "style/lastStyleDir" ), myPath );
settings.setValue( QStringLiteral( "style/lastStyleDir" ), myPath );
activateWindow(); // set focus back to properties dialog
}
void QgsVectorLayerProperties::saveStyleAs_clicked()
{
saveStyleAs( QML );
}
void QgsVectorLayerProperties::loadMetadata()
{
QgsSettings myQSettings; // where we keep last used filter in persistent state
@ -1142,116 +1120,109 @@ void QgsVectorLayerProperties::loadDefaultMetadata()
}
}
void QgsVectorLayerProperties::saveStyleAsMenuTriggered( QAction *action )
void QgsVectorLayerProperties::saveStyleAs()
{
QMenu *menu = qobject_cast<QMenu *>( sender() );
if ( !menu )
return;
QgsVectorLayerLoadSaveStyleDialog dlg( mLayer, QgsVectorLayerLoadSaveStyleDialog::Save );
dlg.exec();
int index = mSaveAsMenu->actions().indexOf( action );
if ( index < 0 )
return;
/*
QgsSettings myQSettings; // where we keep last used filter in persistent state
QString myLastUsedDir = myQSettings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();
saveStyleAs( static_cast< StyleType >( index ) );
}
void QgsVectorLayerProperties::saveStyleAs( StyleType styleType )
{
QgsSettings myQSettings; // where we keep last used filter in persistent state
QString myLastUsedDir = myQSettings.value( QStringLiteral( "style/lastStyleDir" ), QDir::homePath() ).toString();
if ( styleType == DB )
{
QString infoWindowTitle = QObject::tr( "Save style to DB (%1)" ).arg( mLayer->providerType() );
QString msgError;
QgsSaveStyleToDbDialog askToUser;
//Ask the user for a name and a description about the style
if ( askToUser.exec() == QDialog::Accepted )
if ( styleType == DB )
{
QString styleName = askToUser.getName();
QString styleDesc = askToUser.getDescription();
QString uiFileContent = askToUser.getUIFileContent();
bool isDefault = askToUser.isDefault();
QString infoWindowTitle = QObject::tr( "Save style to DB (%1)" ).arg( mLayer->providerType() );
QString msgError;
apply();
mLayer->saveStyleToDatabase( styleName, styleDesc, isDefault, uiFileContent, msgError );
if ( !msgError.isNull() )
QgsSaveStyleToDbDialog askToUser;
//Ask the user for a name and a description about the style
if ( askToUser.exec() == QDialog::Accepted )
{
QgisApp::instance()->messageBar()->pushMessage( infoWindowTitle, msgError, Qgis::Warning, QgisApp::instance()->messageTimeout() );
QString styleName = askToUser.getName();
QString styleDesc = askToUser.getDescription();
QString uiFileContent = askToUser.getUIFileContent();
bool isDefault = askToUser.isDefault();
apply();
mLayer->saveStyleToDatabase( styleName, styleDesc, isDefault, uiFileContent, msgError );
if ( !msgError.isNull() )
{
QgisApp::instance()->messageBar()->pushMessage( infoWindowTitle, msgError, Qgis::Warning, QgisApp::instance()->messageTimeout() );
}
else
{
QgisApp::instance()->messageBar()->pushMessage( infoWindowTitle, tr( "Style saved" ), Qgis::Info, QgisApp::instance()->messageTimeout() );
}
}
else
{
QgisApp::instance()->messageBar()->pushMessage( infoWindowTitle, tr( "Style saved" ), Qgis::Info, QgisApp::instance()->messageTimeout() );
return;
}
}
else
{
QString format, extension;
if ( styleType == SLD )
{
format = tr( "SLD File" ) + " (*.sld)";
extension = QStringLiteral( ".sld" );
}
else
{
format = tr( "QGIS Layer Style File" ) + " (*.qml)";
extension = QgsMapLayer::extensionPropertyType( QgsMapLayer::Style );
}
}
else
{
return;
}
}
else
{
QString myOutputFileName = QFileDialog::getSaveFileName( this, tr( "Save Layer Properties as Style File" ),
myLastUsedDir, format );
if ( myOutputFileName.isNull() ) //dialog canceled
{
return;
}
QString format, extension;
if ( styleType == SLD )
{
format = tr( "SLD File" ) + " (*.sld)";
extension = QStringLiteral( ".sld" );
}
else
{
format = tr( "QGIS Layer Style File" ) + " (*.qml)";
extension = QgsMapLayer::extensionPropertyType( QgsMapLayer::Style );
}
apply(); // make sure the style to save is uptodate
QString myOutputFileName = QFileDialog::getSaveFileName( this, tr( "Save Layer Properties as Style File" ),
myLastUsedDir, format );
if ( myOutputFileName.isNull() ) //dialog canceled
{
return;
}
QString myMessage;
bool defaultLoadedFlag = false;
apply(); // make sure the style to save is uptodate
//ensure the user never omitted the extension from the file name
if ( !myOutputFileName.endsWith( extension, Qt::CaseInsensitive ) )
{
myOutputFileName += extension;
}
QString myMessage;
bool defaultLoadedFlag = false;
if ( styleType == SLD )
{
// convert to SLD
myMessage = mLayer->saveSldStyle( myOutputFileName, defaultLoadedFlag );
}
else
{
myMessage = mLayer->saveNamedStyle( myOutputFileName, defaultLoadedFlag );
}
//ensure the user never omitted the extension from the file name
if ( !myOutputFileName.endsWith( extension, Qt::CaseInsensitive ) )
{
myOutputFileName += extension;
}
//reset if the default style was loaded OK only
if ( defaultLoadedFlag )
{
syncToLayer();
}
else
{
//let the user know what went wrong
QMessageBox::information( this, tr( "Save Style" ), myMessage );
}
if ( styleType == SLD )
{
// convert to SLD
myMessage = mLayer->saveSldStyle( myOutputFileName, defaultLoadedFlag );
QFileInfo myFI( myOutputFileName );
QString myPath = myFI.path();
// Persist last used dir
myQSettings.setValue( QStringLiteral( "style/lastStyleDir" ), myPath );
}
else
{
myMessage = mLayer->saveNamedStyle( myOutputFileName, defaultLoadedFlag );
}
//reset if the default style was loaded OK only
if ( defaultLoadedFlag )
{
syncToLayer();
}
else
{
//let the user know what went wrong
QMessageBox::information( this, tr( "Save Style" ), myMessage );
}
QFileInfo myFI( myOutputFileName );
QString myPath = myFI.path();
// Persist last used dir
myQSettings.setValue( QStringLiteral( "style/lastStyleDir" ), myPath );
}
*/
}
void QgsVectorLayerProperties::loadStyleMenuTriggered( QAction *action )
@ -1596,11 +1567,6 @@ void QgsVectorLayerProperties::updateSymbologyPage()
connect( mRendererDialog, &QgsRendererPropertiesDialog::showPanel, this, &QgsVectorLayerProperties::openPanel );
connect( mRendererDialog, &QgsRendererPropertiesDialog::layerVariablesChanged, this, &QgsVectorLayerProperties::updateVariableEditor );
connect( mRendererDialog, &QgsRendererPropertiesDialog::widgetChanged, this, [ = ] { updateAuxiliaryStoragePage(); } );
// display the menu to choose the output format (fix #5136)
mActionSaveStyleAs->setText( tr( "Save Style" ) );
mActionSaveStyleAs->setMenu( mSaveAsMenu );
disconnect( mActionSaveStyleAs, &QAction::triggered, this, &QgsVectorLayerProperties::saveStyleAs_clicked );
}
else
{

View File

@ -116,7 +116,6 @@ class APP_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private
void loadDefaultStyle_clicked();
void saveDefaultStyle_clicked();
void loadStyle_clicked();
void saveStyleAs_clicked();
void loadMetadata();
void saveMetadataAs();
void saveDefaultMetadata();
@ -144,7 +143,7 @@ class APP_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private
void toggleEditing();
//! Save the style based on selected format from the menu
void saveStyleAsMenuTriggered( QAction * );
void saveStyleAs();
//! Called when is possible to choice if load the style from filesystem or from db
void loadStyleMenuTriggered( QAction * );
@ -178,8 +177,6 @@ class APP_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private
Metadata,
};
void saveStyleAs( StyleType styleType );
//! When provider supports, it will list all the styles relative the layer in a dialog
void showListOfStylesFromDatabase();
@ -198,7 +195,6 @@ class APP_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private
QAction *mActionLoadMetadata = nullptr;
QAction *mActionSaveMetadataAs = nullptr;
QMenu *mSaveAsMenu = nullptr;
QMenu *mLoadStyleMenu = nullptr;
QAction *mActionLoadStyle = nullptr;

View File

@ -126,9 +126,9 @@ class CORE_EXPORT QgsMeshLayer : public QgsMapLayer
QgsRectangle extent() const override;
QgsMapLayerRenderer *createMapRenderer( QgsRenderContext &rendererContext ) override SIP_FACTORY;
bool readSymbology( const QDomNode &node, QString &errorMessage,
QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories ) override;
QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) override;
bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories ) const override;
const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) const override;
QString encodedSource( const QString &source, const QgsReadWriteContext &context ) const override;
QString decodedSource( const QString &source, const QString &provider, const QgsReadWriteContext &context ) const override;
bool readXml( const QDomNode &layer_node, QgsReadWriteContext &context ) override;

View File

@ -111,7 +111,7 @@ QgsMapLayer::ReadableStyleCategory QgsMapLayer::readableStyleCategory( QgsMapLay
case CustomProperties :
return ReadableStyleCategory( tr( "Custom Properties" ),
QgsApplication::getThemeIcon( QStringLiteral( "/mActionOptions.svg" ) ) );
case AllCategories :
case AllStyleCategories :
return ReadableStyleCategory( tr( "All Categories" ) );
}
}
@ -1138,7 +1138,7 @@ void QgsMapLayer::exportNamedMetadata( QDomDocument &doc, QString &errorMsg ) co
doc = myDocument;
}
void QgsMapLayer::exportNamedStyle( QDomDocument &doc, QString &errorMsg, QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories ) const
void QgsMapLayer::exportNamedStyle( QDomDocument &doc, QString &errorMsg, const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories ) const
{
QDomImplementation DomImplementation;
QDomDocumentType documentType = DomImplementation.createDocumentType( QStringLiteral( "qgis" ), QStringLiteral( "http://mrcc.com/qgis.dtd" ), QStringLiteral( "SYSTEM" ) );

View File

@ -37,13 +37,13 @@
#include "qgsmaplayerdependency.h"
#include "qgslayermetadata.h"
#include "qgsmaplayerstyle.h"
#include "qgsreadwritecontext.h"
class QgsAbstract3DRenderer;
class QgsDataProvider;
class QgsMapLayerLegend;
class QgsMapLayerRenderer;
class QgsMapLayerStyleManager;
class QgsReadWriteContext;
class QgsProject;
class QDomDocument;
@ -153,8 +153,8 @@ class CORE_EXPORT QgsMapLayer : public QObject
AttributeTable = 1 << 9, //!< Attribute table settings: choice and order of columns, conditional styling
Rendering = 1 << 10, //!< Rendering: scale visibility, simplify method, opacity
CustomProperties = 1 << 11, //!< Custom properties (by plugins for instance)
AllCategories = LayerConfiguration | Symbology | Labeling | Fields | Forms | Actions |
MapTips | Diagrams | AttributeTable | Rendering | CustomProperties,
AllStyleCategories = LayerConfiguration | Symbology | Symbology3D | Labeling | Fields | Forms | Actions |
MapTips | Diagrams | AttributeTable | Rendering | CustomProperties,
};
Q_ENUM( StyleCategory )
Q_DECLARE_FLAGS( StyleCategories, StyleCategory )
@ -793,17 +793,18 @@ class CORE_EXPORT QgsMapLayer : public QObject
* \since QGIS 2.8
*/
virtual bool importNamedStyle( QDomDocument &doc, QString &errorMsg SIP_OUT,
QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories );
QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories );
/**
* Export the properties of this layer as named style in a QDomDocument
* \param doc the target QDomDocument
* \param errorMsg this QString will be initialized on error
* \param context read write context
* \param categories the style categories to export
* during the execution of writeSymbology
*/
virtual void exportNamedStyle( QDomDocument &doc, QString &errorMsg SIP_OUT, QgsReadWriteContext &context,
QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories ) const;
virtual void exportNamedStyle( QDomDocument &doc, QString &errorMsg SIP_OUT, const QgsReadWriteContext &context = QgsReadWriteContext(),
QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) const;
/**
@ -871,22 +872,24 @@ class CORE_EXPORT QgsMapLayer : public QObject
* \param node node that will contain the symbology definition for this layer.
* \param errorMessage reference to string that will be updated with any error messages
* \param context reading context (used for transform from relative to absolute paths)
* \param categories the style categories to be read
* \returns true in case of success.
*/
virtual bool readSymbology( const QDomNode &node, QString &errorMessage,
QgsReadWriteContext &context, StyleCategories categories = AllCategories ) = 0;
QgsReadWriteContext &context, StyleCategories categories = AllStyleCategories ) = 0;
/**
* Read the style for the current layer from the DOM node supplied.
* \param node node that will contain the style definition for this layer.
* \param errorMessage reference to string that will be updated with any error messages
* \param context reading context (used for transform from relative to absolute paths)
* \param categories the style categories to be read
* \returns true in case of success.
* \note To be implemented in subclasses. Default implementation does nothing and returns false.
* \since QGIS 2.16
*/
virtual bool readStyle( const QDomNode &node, QString &errorMessage,
QgsReadWriteContext &context, StyleCategories categories = AllCategories );
QgsReadWriteContext &context, StyleCategories categories = AllStyleCategories );
/**
* Write the style for the layer into the docment provided.
@ -894,11 +897,12 @@ class CORE_EXPORT QgsMapLayer : public QObject
* \param doc the document that will have the QDomNode added.
* \param errorMessage reference to string that will be updated with any error messages
* \param context writing context (used for transform from absolute to relative paths)
* \param categories the style categories to be written
* \note There is a confusion of terms with the GUI. This method actually writes what is called a style in the application.
* \returns true in case of success.
*/
virtual bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context,
StyleCategories categories = AllCategories ) const = 0;
StyleCategories categories = AllStyleCategories ) const = 0;
/**
* Write just the symbology information for the layer into the document
@ -906,13 +910,14 @@ class CORE_EXPORT QgsMapLayer : public QObject
* \param doc the document that will have the QDomNode added.
* \param errorMessage reference to string that will be updated with any error messages
* \param context writing context (used for transform from absolute to relative paths)
* \param categories the style categories to be written
* \returns true in case of success.
* \note To be implemented in subclasses. Default implementation does nothing and returns false.
* \note There is a confusion of terms with the GUI. This method actually writes what is known as the symbology in the application.
* \since QGIS 2.16
*/
virtual bool writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage, const QgsReadWriteContext &context,
StyleCategories categories = AllCategories ) const;
StyleCategories categories = AllStyleCategories ) const;
//! Returns pointer to layer's undo stack
QUndoStack *undoStack();
@ -1359,14 +1364,14 @@ class CORE_EXPORT QgsMapLayer : public QObject
*/
void writeCommonStyle( QDomElement &layerElement, QDomDocument &document,
const QgsReadWriteContext &context,
StyleCategories categories = AllCategories ) const;
StyleCategories categories = AllStyleCategories ) const;
/**
* Read style data common to all layer types
* \since QGIS 3.0
*/
void readCommonStyle( const QDomElement &layerElement, const QgsReadWriteContext &context,
StyleCategories categories = AllCategories );
StyleCategories categories = AllStyleCategories );
#ifndef SIP_RUN
#if 0

View File

@ -881,7 +881,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
* \returns true in case of success.
*/
bool readSymbology( const QDomNode &layerNode, QString &errorMessage,
QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories ) override;
QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) override;
/**
* Read the style for the current layer from the Dom node supplied.
@ -891,7 +891,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
* \returns true in case of success.
*/
bool readStyle( const QDomNode &node, QString &errorMessage,
QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories ) override;
QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) override;
/**
* Write the symbology for the layer into the docment provided.
@ -902,7 +902,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
* \returns true in case of success.
*/
bool writeSymbology( QDomNode &node, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories ) const override;
const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) const override;
/**
* Write just the style information for the layer into the document
@ -913,7 +913,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
* \returns true in case of success.
*/
bool writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories ) const override;
const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) const override;
/**
* Writes the symbology of the layer into the document provided in SLD 1.1 format

View File

@ -404,13 +404,13 @@ class CORE_EXPORT QgsRasterLayer : public QgsMapLayer
void showStatusMessage( const QString &message );
protected:
bool readSymbology( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories ) override;
bool readStyle( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories ) override;
bool readSymbology( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) override;
bool readStyle( const QDomNode &node, QString &errorMessage, QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) override;
bool readXml( const QDomNode &layer_node, QgsReadWriteContext &context ) override;
bool writeSymbology( QDomNode &, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories ) const override;
const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) const override;
bool writeStyle( QDomNode &node, QDomDocument &doc, QString &errorMessage,
const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllCategories ) const override;
const QgsReadWriteContext &context, QgsMapLayer::StyleCategories categories = QgsMapLayer::AllStyleCategories ) const override;
bool writeXml( QDomNode &layer_node, QDomDocument &doc, const QgsReadWriteContext &context ) const override;
QString encodedSource( const QString &source, const QgsReadWriteContext &context ) const override;
QString decodedSource( const QString &source, const QString &provider, const QgsReadWriteContext &context ) const override;

View File

@ -0,0 +1,144 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsVectorLayerLoadSaveStyleDialog</class>
<widget class="QDialog" name="QgsVectorLayerLoadSaveStyleDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>733</width>
<height>775</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="4" column="0" colspan="2">
<widget class="QWidget" name="mSaveToDbWidget" native="true">
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
</layout>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="mStyleTypeComboBox"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="mModeLabel">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QWidget" name="mSaveToFileWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>File</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QgsFileWidget" name="mFileWidget" native="true"/>
</item>
<item row="1" column="1">
<widget class="QListWidget" name="mStyleCategoriesListWidget"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Categories</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QgsFileWidget</class>
<extends>QWidget</extends>
<header>qgsfilewidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>QgsVectorLayerLoadSaveStyleDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>QgsVectorLayerLoadSaveStyleDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -290,10 +290,10 @@ void TestQgsMapLayer::layerRefListUtils()
void TestQgsMapLayer::styleCategories()
{
// control that AllStyleCategories is actually complete
QgsMapLayer::StyleCategories allStyleCategories = QgsMapLayer::AllCategories;
QgsMapLayer::StyleCategories allStyleCategories = QgsMapLayer::AllStyleCategories;
for ( QgsMapLayer::StyleCategory category : qgsEnumMap<QgsMapLayer::StyleCategory>().keys() )
{
if ( category == QgsMapLayer::AllCategories )
if ( category == QgsMapLayer::AllStyleCategories )
continue;
QVERIFY( allStyleCategories.testFlag( category ) );