Skip to content

Commit 41f7418

Browse files
author
Emilio Loi
committed
Added new option for saving styles on db for vector layers with postgres provider
1 parent 71c45c0 commit 41f7418

File tree

8 files changed

+310
-101
lines changed

8 files changed

+310
-101
lines changed

src/app/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ SET(QGIS_APP_SRCS
8181
qgsmaptoolsvgannotation.cpp
8282
qgsmaptooltextannotation.cpp
8383
qgsmaptoolvertexedit.cpp
84+
qgssavestyletodbdialog.cpp
8485

8586
nodetool/qgsmaptoolnodetool.cpp
8687
nodetool/qgsselectedfeature.cpp
@@ -227,6 +228,7 @@ SET (QGIS_APP_MOC_HDRS
227228
qgsmaptoolsimplify.h
228229
qgsmaptoolsplitfeatures.h
229230
qgsmaptoolvertexedit.h
231+
qgssavestyletodbdialog.h
230232

231233
nodetool/qgsmaptoolnodetool.h
232234
nodetool/qgsselectedfeature.h

src/app/qgsvectorlayerproperties.cpp

Lines changed: 85 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "qgspluginmetadata.h"
4141
#include "qgspluginregistry.h"
4242
#include "qgsproject.h"
43+
#include "qgssavestyletodbdialog.h"
4344
#include "qgsvectorlayer.h"
4445
#include "qgsvectorlayerproperties.h"
4546
#include "qgsconfig.h"
@@ -125,6 +126,13 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
125126
mSaveAsMenu = new QMenu( pbnSaveStyleAs );
126127
mSaveAsMenu->addAction( tr( "QGIS Layer Style File" ) );
127128
mSaveAsMenu->addAction( tr( "SLD File" ) );
129+
130+
//Only if the provider is PostgresProvider add action to save the style in the DB
131+
if( layer->providerType().compare( tr( "postgres" ) ) == 0 )
132+
{
133+
mSaveAsMenu->addAction( tr( "Save in Postgres") );
134+
}
135+
128136
QObject::connect( mSaveAsMenu, SIGNAL( triggered( QAction * ) ), this, SLOT( saveStyleAsMenuTriggered( QAction * ) ) );
129137

130138
mFieldsPropertiesDialog = new QgsFieldsProperties( layer, mFieldsFrame );
@@ -614,61 +622,93 @@ void QgsVectorLayerProperties::saveStyleAs( StyleType styleType )
614622
QSettings myQSettings; // where we keep last used filter in persistent state
615623
QString myLastUsedDir = myQSettings.value( "style/lastStyleDir", "." ).toString();
616624

617-
QString format, extension;
618-
if ( styleType == SLD )
619-
{
620-
format = tr( "SLD File" ) + " (*.sld)";
621-
extension = ".sld";
625+
if( styleType == DB )
626+
{
627+
QString infoWindowTitle = QObject::tr( "Save style to Postgres" );
628+
QString msgError, pluto;
629+
630+
QgsSaveStyleToDbDialog askToUser;
631+
//TODO retrieve user username
632+
askToUser.setOwner( QObject::tr( "Pippo!" ) );
633+
634+
if( askToUser.exec() == QDialog::Accepted )
635+
{
636+
layer->saveStyleToDatabase( askToUser.getName(), askToUser.getOwner(),
637+
askToUser.getDescription(), askToUser.isDefault(),
638+
msgError );
639+
if( !msgError.isNull() )
640+
{
641+
QMessageBox::warning( this, infoWindowTitle, msgError );
642+
}
643+
else
644+
{
645+
QMessageBox::information(this, infoWindowTitle, tr( "Successful!" ));
646+
}
647+
}
648+
else
649+
{
650+
return;
651+
}
622652
}
623653
else
624654
{
625-
format = tr( "QGIS Layer Style File" ) + " (*.qml)";
626-
extension = ".qml";
627-
}
628655

629-
QString myOutputFileName = QFileDialog::getSaveFileName( this, tr( "Save layer properties as style file" ),
630-
myLastUsedDir, format );
631-
if ( myOutputFileName.isNull() ) //dialog canceled
632-
{
633-
return;
634-
}
656+
QString format, extension;
657+
if ( styleType == SLD )
658+
{
659+
format = tr( "SLD File" ) + " (*.sld)";
660+
extension = ".sld";
661+
}
662+
else
663+
{
664+
format = tr( "QGIS Layer Style File" ) + " (*.qml)";
665+
extension = ".qml";
666+
}
635667

636-
apply(); // make sure the style to save is uptodate
668+
QString myOutputFileName = QFileDialog::getSaveFileName( this, tr( "Save layer properties as style file" ),
669+
myLastUsedDir, format );
670+
if ( myOutputFileName.isNull() ) //dialog canceled
671+
{
672+
return;
673+
}
637674

638-
QString myMessage;
639-
bool defaultLoadedFlag = false;
675+
apply(); // make sure the style to save is uptodate
640676

641-
//ensure the user never omitted the extension from the file name
642-
if ( !myOutputFileName.endsWith( extension, Qt::CaseInsensitive ) )
643-
{
644-
myOutputFileName += extension;
645-
}
677+
QString myMessage;
678+
bool defaultLoadedFlag = false;
646679

647-
if ( styleType == SLD )
648-
{
649-
// convert to SLD
650-
myMessage = layer->saveSldStyle( myOutputFileName, defaultLoadedFlag );
651-
}
652-
else
653-
{
654-
myMessage = layer->saveNamedStyle( myOutputFileName, defaultLoadedFlag );
655-
}
680+
//ensure the user never omitted the extension from the file name
681+
if ( !myOutputFileName.endsWith( extension, Qt::CaseInsensitive ) )
682+
{
683+
myOutputFileName += extension;
684+
}
656685

657-
//reset if the default style was loaded ok only
658-
if ( defaultLoadedFlag )
659-
{
660-
reset();
661-
}
662-
else
663-
{
664-
//let the user know what went wrong
665-
QMessageBox::information( this, tr( "Saved Style" ), myMessage );
666-
}
686+
if ( styleType == SLD )
687+
{
688+
// convert to SLD
689+
myMessage = layer->saveSldStyle( myOutputFileName, defaultLoadedFlag );
690+
}
691+
else
692+
{
693+
myMessage = layer->saveNamedStyle( myOutputFileName, defaultLoadedFlag );
694+
}
667695

668-
QFileInfo myFI( myOutputFileName );
669-
QString myPath = myFI.path();
670-
// Persist last used dir
671-
myQSettings.setValue( "style/lastStyleDir", myPath );
696+
//reset if the default style was loaded ok only
697+
if ( defaultLoadedFlag )
698+
{
699+
reset();
700+
}
701+
else
702+
{
703+
//let the user know what went wrong
704+
QMessageBox::information( this, tr( "Saved Style" ), myMessage );
705+
}
706+
707+
QFileInfo myFI( myOutputFileName );
708+
QString myPath = myFI.path();
709+
// Persist last used dir
710+
myQSettings.setValue( "style/lastStyleDir", myPath );
711+
}
672712
}
673713

674714
QList<QgsVectorOverlayPlugin*> QgsVectorLayerProperties::overlayPlugins() const

src/app/qgsvectorlayerproperties.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class QgsVectorLayerProperties : public QDialog, private Ui::QgsVectorLayerPrope
5050
{
5151
QML = 0,
5252
SLD,
53+
DB,
5354
};
5455

5556
QgsVectorLayerProperties( QgsVectorLayer *lyr = 0, QWidget *parent = 0, Qt::WFlags fl = QgisGui::ModalDialogFlags );

src/core/qgsmaplayer.cpp

Lines changed: 73 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -847,44 +847,47 @@ QString QgsMapLayer::loadNamedStyle( const QString theURI, bool &theResultFlag )
847847
return "";
848848
}
849849

850+
void QgsMapLayer::exportNamedStyle(QDomDocument &doc, QString &errorMsg)
851+
{
852+
QDomImplementation DomImplementation;
853+
QDomDocumentType documentType = DomImplementation.createDocumentType( "qgis", "http://mrcc.com/qgis.dtd", "SYSTEM" );
854+
QDomDocument myDocument( documentType );
855+
856+
QDomElement myRootNode = myDocument.createElement( "qgis" );
857+
myRootNode.setAttribute( "version", QString( "%1" ).arg( QGis::QGIS_VERSION ) );
858+
myDocument.appendChild( myRootNode );
859+
860+
myRootNode.setAttribute( "hasScaleBasedVisibilityFlag", hasScaleBasedVisibility() ? 1 : 0 );
861+
myRootNode.setAttribute( "minimumScale", QString::number( minimumScale() ) );
862+
myRootNode.setAttribute( "maximumScale", QString::number( maximumScale() ) );
863+
864+
#if 0
865+
// <transparencyLevelInt>
866+
QDomElement transparencyLevelIntElement = myDocument.createElement( "transparencyLevelInt" );
867+
QDomText transparencyLevelIntText = myDocument.createTextNode( QString::number( getTransparency() ) );
868+
transparencyLevelIntElement.appendChild( transparencyLevelIntText );
869+
myRootNode.appendChild( transparencyLevelIntElement );
870+
#endif
871+
872+
if ( !writeSymbology( myRootNode, myDocument, errorMsg ) )
873+
{
874+
errorMsg = QObject::tr( "Could not save symbology because:\n%1" ).arg( errorMsg );
875+
return;
876+
}
877+
doc = myDocument;
878+
}
879+
850880
QString QgsMapLayer::saveDefaultStyle( bool & theResultFlag )
851881
{
852882
return saveNamedStyle( styleURI(), theResultFlag );
853883
}
854884

855885
QString QgsMapLayer::saveNamedStyle( const QString theURI, bool & theResultFlag )
856886
{
857-
QString myErrorMessage;
858-
859-
QDomImplementation DomImplementation;
860-
QDomDocumentType documentType =
861-
DomImplementation.createDocumentType(
862-
"qgis", "http://mrcc.com/qgis.dtd", "SYSTEM" );
863-
QDomDocument myDocument( documentType );
864-
QDomElement myRootNode = myDocument.createElement( "qgis" );
865-
myRootNode.setAttribute( "version", QString( "%1" ).arg( QGis::QGIS_VERSION ) );
866-
myDocument.appendChild( myRootNode );
867-
868-
// use scale dependent visibility flag
869-
myRootNode.setAttribute( "hasScaleBasedVisibilityFlag", hasScaleBasedVisibility() ? 1 : 0 );
870-
myRootNode.setAttribute( "minimumScale", QString::number( minimumScale() ) );
871-
myRootNode.setAttribute( "maximumScale", QString::number( maximumScale() ) );
872-
873-
#if 0
874-
// <transparencyLevelInt>
875-
QDomElement transparencyLevelIntElement = myDocument.createElement( "transparencyLevelInt" );
876-
QDomText transparencyLevelIntText = myDocument.createTextNode( QString::number( getTransparency() ) );
877-
transparencyLevelIntElement.appendChild( transparencyLevelIntText );
878-
myRootNode.appendChild( transparencyLevelIntElement );
879-
#endif
880-
881-
// now append layer node to map layer node
882887

883-
QString errorMsg;
884-
if ( !writeSymbology( myRootNode, myDocument, errorMsg ) )
885-
{
886-
return tr( "Could not save symbology because:\n%1" ).arg( errorMsg );
887-
}
888+
QString myErrorMessage;
889+
QDomDocument myDocument;
890+
exportNamedStyle( myDocument, myErrorMessage );
888891

889892
// check if the uri is a file or ends with .qml,
890893
// which indicates that it should become one
@@ -1017,40 +1020,54 @@ QString QgsMapLayer::saveNamedStyle( const QString theURI, bool & theResultFlag
10171020
return myErrorMessage;
10181021
}
10191022

1020-
QString QgsMapLayer::saveSldStyle( const QString theURI, bool & theResultFlag )
1021-
{
1022-
QDomDocument myDocument = QDomDocument();
1023+
void QgsMapLayer::exportSldStyle( QDomDocument &doc, QString &errorMsg ){
1024+
QDomDocument myDocument = QDomDocument();
10231025

1024-
QDomNode header = myDocument.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" );
1025-
myDocument.appendChild( header );
1026+
QDomNode header = myDocument.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" );
1027+
myDocument.appendChild( header );
10261028

1027-
// Create the root element
1028-
QDomElement root = myDocument.createElementNS( "http://www.opengis.net/sld", "StyledLayerDescriptor" );
1029-
root.setAttribute( "version", "1.1.0" );
1030-
root.setAttribute( "xsi:schemaLocation", "http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd" );
1031-
root.setAttribute( "xmlns:ogc", "http://www.opengis.net/ogc" );
1032-
root.setAttribute( "xmlns:se", "http://www.opengis.net/se" );
1033-
root.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" );
1034-
root.setAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" );
1035-
myDocument.appendChild( root );
1029+
// Create the root element
1030+
QDomElement root = myDocument.createElementNS( "http://www.opengis.net/sld", "StyledLayerDescriptor" );
1031+
root.setAttribute( "version", "1.1.0" );
1032+
root.setAttribute( "xsi:schemaLocation", "http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd" );
1033+
root.setAttribute( "xmlns:ogc", "http://www.opengis.net/ogc" );
1034+
root.setAttribute( "xmlns:se", "http://www.opengis.net/se" );
1035+
root.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" );
1036+
root.setAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" );
1037+
myDocument.appendChild( root );
10361038

1037-
// Create the NamedLayer element
1038-
QDomElement namedLayerNode = myDocument.createElement( "NamedLayer" );
1039-
root.appendChild( namedLayerNode );
1039+
// Create the NamedLayer element
1040+
QDomElement namedLayerNode = myDocument.createElement( "NamedLayer" );
1041+
root.appendChild( namedLayerNode );
10401042

1041-
QString errorMsg;
1042-
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( this );
1043-
if ( !vlayer )
1044-
{
1045-
theResultFlag = false;
1046-
return tr( "Could not save symbology because:\n%1" ).arg( "Non-vector layers not supported yet" );
1047-
}
1043+
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( this );
1044+
if ( !vlayer )
1045+
{
1046+
errorMsg = tr( "Could not save symbology because:\n%1" )
1047+
.arg( "Non-vector layers not supported yet" );
1048+
return;
1049+
}
10481050

1049-
if ( !vlayer->writeSld( namedLayerNode, myDocument, errorMsg ) )
1051+
if ( !vlayer->writeSld( namedLayerNode, myDocument, errorMsg ) )
1052+
{
1053+
errorMsg = tr( "Could not save symbology because:\n%1" ).arg( errorMsg );
1054+
return;
1055+
}
1056+
1057+
doc = myDocument;
1058+
}
1059+
1060+
QString QgsMapLayer::saveSldStyle( const QString theURI, bool & theResultFlag )
1061+
{
1062+
QString errorMsg;
1063+
QDomDocument myDocument;
1064+
exportSldStyle( myDocument, errorMsg );
1065+
if( !errorMsg.isNull() )
10501066
{
10511067
theResultFlag = false;
1052-
return tr( "Could not save symbology because:\n%1" ).arg( errorMsg );
1068+
return errorMsg;
10531069
}
1070+
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( this );
10541071

10551072
// check if the uri is a file or ends with .sld,
10561073
// which indicates that it should become one

src/core/qgsmaplayer.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,24 @@ class CORE_EXPORT QgsMapLayer : public QObject
276276

277277
virtual bool loadNamedStyleFromDb( const QString db, const QString theURI, QString &qml );
278278

279+
//TODO edit infos
280+
/**
281+
* Export the properties of this layer as named style in a QDomDocument
282+
* @param doc the target QDomDocument
283+
* @param errorMsg this QString will be initialized on error
284+
* during the execution of writeSymbology
285+
*/
286+
virtual void exportNamedStyle( QDomDocument &doc, QString &errorMsg );
287+
288+
289+
/**
290+
* Export the properties of this layer as SLD style in a QDomDocument
291+
* @param doc the target QDomDocument
292+
* @param errorMsg this QString will be initialized on error
293+
* during the execution of writeSymbology
294+
*/
295+
virtual void exportSldStyle( QDomDocument &doc, QString &errorMsg );
296+
279297
/** Save the properties of this layer as the default style
280298
* (either as a .qml file on disk or as a
281299
* record in the users style table in their personal qgis.db)

0 commit comments

Comments
 (0)