Skip to content

Commit

Permalink
Added new option for saving styles on db for vector layers with postg…
Browse files Browse the repository at this point in the history
…res provider
  • Loading branch information
Emilio Loi committed Apr 12, 2013
1 parent 71c45c0 commit 41f7418
Show file tree
Hide file tree
Showing 8 changed files with 310 additions and 101 deletions.
2 changes: 2 additions & 0 deletions src/app/CMakeLists.txt
Expand Up @@ -81,6 +81,7 @@ SET(QGIS_APP_SRCS
qgsmaptoolsvgannotation.cpp
qgsmaptooltextannotation.cpp
qgsmaptoolvertexedit.cpp
qgssavestyletodbdialog.cpp

nodetool/qgsmaptoolnodetool.cpp
nodetool/qgsselectedfeature.cpp
Expand Down Expand Up @@ -227,6 +228,7 @@ SET (QGIS_APP_MOC_HDRS
qgsmaptoolsimplify.h
qgsmaptoolsplitfeatures.h
qgsmaptoolvertexedit.h
qgssavestyletodbdialog.h

nodetool/qgsmaptoolnodetool.h
nodetool/qgsselectedfeature.h
Expand Down
130 changes: 85 additions & 45 deletions src/app/qgsvectorlayerproperties.cpp
Expand Up @@ -40,6 +40,7 @@
#include "qgspluginmetadata.h"
#include "qgspluginregistry.h"
#include "qgsproject.h"
#include "qgssavestyletodbdialog.h"
#include "qgsvectorlayer.h"
#include "qgsvectorlayerproperties.h"
#include "qgsconfig.h"
Expand Down Expand Up @@ -125,6 +126,13 @@ QgsVectorLayerProperties::QgsVectorLayerProperties(
mSaveAsMenu = new QMenu( pbnSaveStyleAs );
mSaveAsMenu->addAction( tr( "QGIS Layer Style File" ) );
mSaveAsMenu->addAction( tr( "SLD File" ) );

//Only if the provider is PostgresProvider add action to save the style in the DB
if( layer->providerType().compare( tr( "postgres" ) ) == 0 )
{
mSaveAsMenu->addAction( tr( "Save in Postgres") );
}

QObject::connect( mSaveAsMenu, SIGNAL( triggered( QAction * ) ), this, SLOT( saveStyleAsMenuTriggered( QAction * ) ) );

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

QString format, extension;
if ( styleType == SLD )
{
format = tr( "SLD File" ) + " (*.sld)";
extension = ".sld";
if( styleType == DB )
{
QString infoWindowTitle = QObject::tr( "Save style to Postgres" );
QString msgError, pluto;

QgsSaveStyleToDbDialog askToUser;
//TODO retrieve user username
askToUser.setOwner( QObject::tr( "Pippo!" ) );

if( askToUser.exec() == QDialog::Accepted )
{
layer->saveStyleToDatabase( askToUser.getName(), askToUser.getOwner(),
askToUser.getDescription(), askToUser.isDefault(),
msgError );
if( !msgError.isNull() )
{
QMessageBox::warning( this, infoWindowTitle, msgError );
}
else
{
QMessageBox::information(this, infoWindowTitle, tr( "Successful!" ));
}
}
else
{
return;
}
}
else
{
format = tr( "QGIS Layer Style File" ) + " (*.qml)";
extension = ".qml";
}

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 = ".sld";
}
else
{
format = tr( "QGIS Layer Style File" ) + " (*.qml)";
extension = ".qml";
}

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 = layer->saveSldStyle( myOutputFileName, defaultLoadedFlag );
}
else
{
myMessage = layer->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 )
{
reset();
}
else
{
//let the user know what went wrong
QMessageBox::information( this, tr( "Saved Style" ), myMessage );
}
if ( styleType == SLD )
{
// convert to SLD
myMessage = layer->saveSldStyle( myOutputFileName, defaultLoadedFlag );
}
else
{
myMessage = layer->saveNamedStyle( myOutputFileName, defaultLoadedFlag );
}

QFileInfo myFI( myOutputFileName );
QString myPath = myFI.path();
// Persist last used dir
myQSettings.setValue( "style/lastStyleDir", myPath );
//reset if the default style was loaded ok only
if ( defaultLoadedFlag )
{
reset();
}
else
{
//let the user know what went wrong
QMessageBox::information( this, tr( "Saved Style" ), myMessage );
}

QFileInfo myFI( myOutputFileName );
QString myPath = myFI.path();
// Persist last used dir
myQSettings.setValue( "style/lastStyleDir", myPath );
}
}

QList<QgsVectorOverlayPlugin*> QgsVectorLayerProperties::overlayPlugins() const
Expand Down
1 change: 1 addition & 0 deletions src/app/qgsvectorlayerproperties.h
Expand Up @@ -50,6 +50,7 @@ class QgsVectorLayerProperties : public QDialog, private Ui::QgsVectorLayerPrope
{
QML = 0,
SLD,
DB,
};

QgsVectorLayerProperties( QgsVectorLayer *lyr = 0, QWidget *parent = 0, Qt::WFlags fl = QgisGui::ModalDialogFlags );
Expand Down
129 changes: 73 additions & 56 deletions src/core/qgsmaplayer.cpp
Expand Up @@ -847,44 +847,47 @@ QString QgsMapLayer::loadNamedStyle( const QString theURI, bool &theResultFlag )
return "";
}

void QgsMapLayer::exportNamedStyle(QDomDocument &doc, QString &errorMsg)
{
QDomImplementation DomImplementation;
QDomDocumentType documentType = DomImplementation.createDocumentType( "qgis", "http://mrcc.com/qgis.dtd", "SYSTEM" );
QDomDocument myDocument( documentType );

QDomElement myRootNode = myDocument.createElement( "qgis" );
myRootNode.setAttribute( "version", QString( "%1" ).arg( QGis::QGIS_VERSION ) );
myDocument.appendChild( myRootNode );

myRootNode.setAttribute( "hasScaleBasedVisibilityFlag", hasScaleBasedVisibility() ? 1 : 0 );
myRootNode.setAttribute( "minimumScale", QString::number( minimumScale() ) );
myRootNode.setAttribute( "maximumScale", QString::number( maximumScale() ) );

#if 0
// <transparencyLevelInt>
QDomElement transparencyLevelIntElement = myDocument.createElement( "transparencyLevelInt" );
QDomText transparencyLevelIntText = myDocument.createTextNode( QString::number( getTransparency() ) );
transparencyLevelIntElement.appendChild( transparencyLevelIntText );
myRootNode.appendChild( transparencyLevelIntElement );
#endif

if ( !writeSymbology( myRootNode, myDocument, errorMsg ) )
{
errorMsg = QObject::tr( "Could not save symbology because:\n%1" ).arg( errorMsg );
return;
}
doc = myDocument;
}

QString QgsMapLayer::saveDefaultStyle( bool & theResultFlag )
{
return saveNamedStyle( styleURI(), theResultFlag );
}

QString QgsMapLayer::saveNamedStyle( const QString theURI, bool & theResultFlag )
{
QString myErrorMessage;

QDomImplementation DomImplementation;
QDomDocumentType documentType =
DomImplementation.createDocumentType(
"qgis", "http://mrcc.com/qgis.dtd", "SYSTEM" );
QDomDocument myDocument( documentType );
QDomElement myRootNode = myDocument.createElement( "qgis" );
myRootNode.setAttribute( "version", QString( "%1" ).arg( QGis::QGIS_VERSION ) );
myDocument.appendChild( myRootNode );

// use scale dependent visibility flag
myRootNode.setAttribute( "hasScaleBasedVisibilityFlag", hasScaleBasedVisibility() ? 1 : 0 );
myRootNode.setAttribute( "minimumScale", QString::number( minimumScale() ) );
myRootNode.setAttribute( "maximumScale", QString::number( maximumScale() ) );

#if 0
// <transparencyLevelInt>
QDomElement transparencyLevelIntElement = myDocument.createElement( "transparencyLevelInt" );
QDomText transparencyLevelIntText = myDocument.createTextNode( QString::number( getTransparency() ) );
transparencyLevelIntElement.appendChild( transparencyLevelIntText );
myRootNode.appendChild( transparencyLevelIntElement );
#endif

// now append layer node to map layer node

QString errorMsg;
if ( !writeSymbology( myRootNode, myDocument, errorMsg ) )
{
return tr( "Could not save symbology because:\n%1" ).arg( errorMsg );
}
QString myErrorMessage;
QDomDocument myDocument;
exportNamedStyle( myDocument, myErrorMessage );

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

QString QgsMapLayer::saveSldStyle( const QString theURI, bool & theResultFlag )
{
QDomDocument myDocument = QDomDocument();
void QgsMapLayer::exportSldStyle( QDomDocument &doc, QString &errorMsg ){
QDomDocument myDocument = QDomDocument();

QDomNode header = myDocument.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" );
myDocument.appendChild( header );
QDomNode header = myDocument.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" );
myDocument.appendChild( header );

// Create the root element
QDomElement root = myDocument.createElementNS( "http://www.opengis.net/sld", "StyledLayerDescriptor" );
root.setAttribute( "version", "1.1.0" );
root.setAttribute( "xsi:schemaLocation", "http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd" );
root.setAttribute( "xmlns:ogc", "http://www.opengis.net/ogc" );
root.setAttribute( "xmlns:se", "http://www.opengis.net/se" );
root.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" );
root.setAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" );
myDocument.appendChild( root );
// Create the root element
QDomElement root = myDocument.createElementNS( "http://www.opengis.net/sld", "StyledLayerDescriptor" );
root.setAttribute( "version", "1.1.0" );
root.setAttribute( "xsi:schemaLocation", "http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd" );
root.setAttribute( "xmlns:ogc", "http://www.opengis.net/ogc" );
root.setAttribute( "xmlns:se", "http://www.opengis.net/se" );
root.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" );
root.setAttribute( "xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance" );
myDocument.appendChild( root );

// Create the NamedLayer element
QDomElement namedLayerNode = myDocument.createElement( "NamedLayer" );
root.appendChild( namedLayerNode );
// Create the NamedLayer element
QDomElement namedLayerNode = myDocument.createElement( "NamedLayer" );
root.appendChild( namedLayerNode );

QString errorMsg;
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( this );
if ( !vlayer )
{
theResultFlag = false;
return tr( "Could not save symbology because:\n%1" ).arg( "Non-vector layers not supported yet" );
}
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( this );
if ( !vlayer )
{
errorMsg = tr( "Could not save symbology because:\n%1" )
.arg( "Non-vector layers not supported yet" );
return;
}

if ( !vlayer->writeSld( namedLayerNode, myDocument, errorMsg ) )
if ( !vlayer->writeSld( namedLayerNode, myDocument, errorMsg ) )
{
errorMsg = tr( "Could not save symbology because:\n%1" ).arg( errorMsg );
return;
}

doc = myDocument;
}

QString QgsMapLayer::saveSldStyle( const QString theURI, bool & theResultFlag )
{
QString errorMsg;
QDomDocument myDocument;
exportSldStyle( myDocument, errorMsg );
if( !errorMsg.isNull() )
{
theResultFlag = false;
return tr( "Could not save symbology because:\n%1" ).arg( errorMsg );
return errorMsg;
}
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( this );

// check if the uri is a file or ends with .sld,
// which indicates that it should become one
Expand Down
18 changes: 18 additions & 0 deletions src/core/qgsmaplayer.h
Expand Up @@ -276,6 +276,24 @@ class CORE_EXPORT QgsMapLayer : public QObject

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

//TODO edit infos
/**
* 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
* during the execution of writeSymbology
*/
virtual void exportNamedStyle( QDomDocument &doc, QString &errorMsg );


/**
* Export the properties of this layer as SLD style in a QDomDocument
* @param doc the target QDomDocument
* @param errorMsg this QString will be initialized on error
* during the execution of writeSymbology
*/
virtual void exportSldStyle( QDomDocument &doc, QString &errorMsg );

/** Save the properties of this layer as the default style
* (either as a .qml file on disk or as a
* record in the users style table in their personal qgis.db)
Expand Down

0 comments on commit 41f7418

Please sign in to comment.