373 changes: 187 additions & 186 deletions src/app/qgsvectorlayerproperties.cpp

Large diffs are not rendered by default.

115 changes: 58 additions & 57 deletions src/core/qgsmaplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -840,34 +840,34 @@ QString QgsMapLayer::loadNamedStyle( const QString theURI, bool &theResultFlag )
return "";
}

void QgsMapLayer::exportNamedStyle(QDomDocument &doc, QString &errorMsg)
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;
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 )
Expand Down Expand Up @@ -1012,49 +1012,50 @@ QString QgsMapLayer::saveNamedStyle( const QString theURI, bool & theResultFlag
return myErrorMessage;
}

void QgsMapLayer::exportSldStyle( QDomDocument &doc, QString &errorMsg ){
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 );

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

doc = myDocument;
doc = myDocument;
}

QString QgsMapLayer::saveSldStyle( const QString theURI, bool & theResultFlag )
{
QString errorMsg;
QDomDocument myDocument;
exportSldStyle( myDocument, errorMsg );
if( !errorMsg.isNull() )
if ( !errorMsg.isNull() )
{
theResultFlag = false;
return errorMsg;
Expand Down
253 changes: 127 additions & 126 deletions src/core/qgsvectorlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,33 +79,33 @@
#endif

typedef bool saveStyle_t(
const QString& uri,
const QString& qmlStyle,
const QString& sldStyle,
const QString& styleName,
const QString& styleDescription,
const QString& uiFileContent,
bool useAsDefault,
QString& errCause
const QString& uri,
const QString& qmlStyle,
const QString& sldStyle,
const QString& styleName,
const QString& styleDescription,
const QString& uiFileContent,
bool useAsDefault,
QString& errCause
);

typedef QString loadStyle_t(
const QString& uri,
QString& errCause
const QString& uri,
QString& errCause
);

typedef int listStyles_t(
const QString& uri,
QVector<QString> &ids,
QVector<QString> &names,
QVector<QString> &descriptions,
QString& errCause
const QString& uri,
QVector<QString> &ids,
QVector<QString> &names,
QVector<QString> &descriptions,
QString& errCause
);

typedef QString getStyleById_t(
const QString& uri,
QString styleID,
QString& errCause
const QString& uri,
QString styleID,
QString& errCause
);


Expand Down Expand Up @@ -3732,145 +3732,146 @@ QDomElement QgsAttributeEditorField::toDomElement( QDomDocument& doc ) const

int QgsVectorLayer::listStylesInDatabase( QVector<QString> &ids, QVector<QString> &names, QVector<QString> &descriptions, QString &msgError )
{
QgsProviderRegistry * pReg = QgsProviderRegistry::instance();
QLibrary *myLib = pReg->providerLibrary( mProviderKey );
if ( !myLib )
{
msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
return -1;
}
listStyles_t* listStylesExternalMethod = ( listStyles_t * ) cast_to_fptr(myLib->resolve("listStyles"));
QgsProviderRegistry * pReg = QgsProviderRegistry::instance();
QLibrary *myLib = pReg->providerLibrary( mProviderKey );
if ( !myLib )
{
msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
return -1;
}
listStyles_t* listStylesExternalMethod = ( listStyles_t * ) cast_to_fptr( myLib->resolve( "listStyles" ) );

if ( !listStylesExternalMethod )
{
delete myLib;
msgError = QObject::tr( "Provider %1 has no listStyles method" ).arg( mProviderKey );
return -1;
}
if ( !listStylesExternalMethod )
{
delete myLib;
msgError = QObject::tr( "Provider %1 has no listStyles method" ).arg( mProviderKey );
return -1;
}

return listStylesExternalMethod(mDataSource, ids, names, descriptions, msgError);
return listStylesExternalMethod( mDataSource, ids, names, descriptions, msgError );
}

QString QgsVectorLayer::getStyleFromDatabase(QString styleId, QString &msgError)
QString QgsVectorLayer::getStyleFromDatabase( QString styleId, QString &msgError )
{
QgsProviderRegistry * pReg = QgsProviderRegistry::instance();
QLibrary *myLib = pReg->providerLibrary( mProviderKey );
if ( !myLib )
{
msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
return QObject::tr( "" );
}
getStyleById_t* getStyleByIdMethod = ( getStyleById_t * ) cast_to_fptr(myLib->resolve("getStyleById"));
QgsProviderRegistry * pReg = QgsProviderRegistry::instance();
QLibrary *myLib = pReg->providerLibrary( mProviderKey );
if ( !myLib )
{
msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
return QObject::tr( "" );
}
getStyleById_t* getStyleByIdMethod = ( getStyleById_t * ) cast_to_fptr( myLib->resolve( "getStyleById" ) );

if ( !getStyleByIdMethod )
{
delete myLib;
msgError = QObject::tr( "Provider %1 has no getStyleById method" ).arg( mProviderKey );
return QObject::tr( "" );
}
if ( !getStyleByIdMethod )
{
delete myLib;
msgError = QObject::tr( "Provider %1 has no getStyleById method" ).arg( mProviderKey );
return QObject::tr( "" );
}

return getStyleByIdMethod( mDataSource, styleId, msgError );
return getStyleByIdMethod( mDataSource, styleId, msgError );
}


void QgsVectorLayer::saveStyleToDatabase(QString name, QString description,
bool useAsDefault, QString uiFileContent, QString &msgError){
void QgsVectorLayer::saveStyleToDatabase( QString name, QString description,
bool useAsDefault, QString uiFileContent, QString &msgError )
{

QString sldStyle, qmlStyle;
QgsProviderRegistry * pReg = QgsProviderRegistry::instance();
QLibrary *myLib = pReg->providerLibrary( mProviderKey );
if ( !myLib )
{
msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
return;
}
saveStyle_t* saveStyleExternalMethod = ( saveStyle_t * ) cast_to_fptr(myLib->resolve("saveStyle"));
QString sldStyle, qmlStyle;
QgsProviderRegistry * pReg = QgsProviderRegistry::instance();
QLibrary *myLib = pReg->providerLibrary( mProviderKey );
if ( !myLib )
{
msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
return;
}
saveStyle_t* saveStyleExternalMethod = ( saveStyle_t * ) cast_to_fptr( myLib->resolve( "saveStyle" ) );

if ( !saveStyleExternalMethod )
{
delete myLib;
msgError = QObject::tr( "Provider %1 has no saveStyle method" ).arg( mProviderKey );
return;
}
if ( !saveStyleExternalMethod )
{
delete myLib;
msgError = QObject::tr( "Provider %1 has no saveStyle method" ).arg( mProviderKey );
return;
}

QDomDocument qmlDocument, sldDocument;
this->exportNamedStyle(qmlDocument, msgError);
if( !msgError.isNull() )
{
return;
}
qmlStyle = qmlDocument.toString();
QDomDocument qmlDocument, sldDocument;
this->exportNamedStyle( qmlDocument, msgError );
if ( !msgError.isNull() )
{
return;
}
qmlStyle = qmlDocument.toString();

this->exportSldStyle(sldDocument, msgError);
if( !msgError.isNull() )
{
return;
}
sldStyle = sldDocument.toString();
this->exportSldStyle( sldDocument, msgError );
if ( !msgError.isNull() )
{
return;
}
sldStyle = sldDocument.toString();

saveStyleExternalMethod(mDataSource, qmlStyle, sldStyle, name,
description, uiFileContent, useAsDefault, msgError);
saveStyleExternalMethod( mDataSource, qmlStyle, sldStyle, name,
description, uiFileContent, useAsDefault, msgError );
}




QString QgsVectorLayer::loadNamedStyle( const QString theURI, bool &theResultFlag , bool loadFromLocalDB )
{
QgsDataSourceURI dsUri( theURI );
if ( !loadFromLocalDB && !dsUri.database().isEmpty() )
QgsDataSourceURI dsUri( theURI );
if ( !loadFromLocalDB && !dsUri.database().isEmpty() )
{
QgsProviderRegistry * pReg = QgsProviderRegistry::instance();
QLibrary *myLib = pReg->providerLibrary( mProviderKey );
if ( myLib )
{
QgsProviderRegistry * pReg = QgsProviderRegistry::instance();
QLibrary *myLib = pReg->providerLibrary( mProviderKey );
if ( myLib )
loadStyle_t* loadStyleExternalMethod = ( loadStyle_t * ) cast_to_fptr( myLib->resolve( "loadStyle" ) );
if ( loadStyleExternalMethod )
{
QString qml, errorMsg;
qml = loadStyleExternalMethod( mDataSource, errorMsg );
if ( !qml.isEmpty() )
{
loadStyle_t* loadStyleExternalMethod = ( loadStyle_t * ) cast_to_fptr( myLib->resolve( "loadStyle" ) );
if ( loadStyleExternalMethod )
{
QString qml, errorMsg;
qml = loadStyleExternalMethod( mDataSource, errorMsg );
if( !qml.isEmpty() )
{
theResultFlag = this->applyNamedStyle( qml, errorMsg );
}
}
theResultFlag = this->applyNamedStyle( qml, errorMsg );
}

}
if( !theResultFlag )
{
return QgsMapLayer::loadNamedStyle( theURI, theResultFlag );
}
}
return QObject::tr( "Loaded from Provider" );

}
if ( !theResultFlag )
{
return QgsMapLayer::loadNamedStyle( theURI, theResultFlag );
}
return QObject::tr( "Loaded from Provider" );
}

bool QgsVectorLayer::applyNamedStyle(QString namedStyle, QString errorMsg )
bool QgsVectorLayer::applyNamedStyle( QString namedStyle, QString errorMsg )
{
QDomDocument myDocument( "qgis" );
myDocument.setContent( namedStyle );
QDomDocument myDocument( "qgis" );
myDocument.setContent( namedStyle );

QDomElement myRoot = myDocument.firstChildElement( "qgis" );
QDomElement myRoot = myDocument.firstChildElement( "qgis" );

if( myRoot.isNull() )
{
errorMsg = tr( "Error: qgis element could not be found" );
return false;
}
toggleScaleBasedVisibility( myRoot.attribute( "hasScaleBasedVisibilityFlag" ).toInt() == 1 );
setMinimumScale( myRoot.attribute( "minimumScale" ).toFloat() );
setMaximumScale( myRoot.attribute( "maximumScale" ).toFloat() );
if ( myRoot.isNull() )
{
errorMsg = tr( "Error: qgis element could not be found" );
return false;
}
toggleScaleBasedVisibility( myRoot.attribute( "hasScaleBasedVisibilityFlag" ).toInt() == 1 );
setMinimumScale( myRoot.attribute( "minimumScale" ).toFloat() );
setMaximumScale( myRoot.attribute( "maximumScale" ).toFloat() );

#if 0
//read transparency level
QDomNode transparencyNode = myRoot.namedItem( "transparencyLevelInt" );
if ( ! transparencyNode.isNull() )
{
// set transparency level only if it's in project
// (otherwise it sets the layer transparent)
QDomElement myElement = transparencyNode.toElement();
setTransparency( myElement.text().toInt() );
}
#endif
#if 0
//read transparency level
QDomNode transparencyNode = myRoot.namedItem( "transparencyLevelInt" );
if ( ! transparencyNode.isNull() )
{
// set transparency level only if it's in project
// (otherwise it sets the layer transparent)
QDomElement myElement = transparencyNode.toElement();
setTransparency( myElement.text().toInt() );
}
#endif

return readSymbology( myRoot, errorMsg );
return readSymbology( myRoot, errorMsg );
}
6 changes: 3 additions & 3 deletions src/core/qgsvectorlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -714,15 +714,15 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
* @return the number of styles related to current layer
*/
virtual int listStylesInDatabase( QVector<QString> &ids, QVector<QString> &names,
QVector<QString> &descriptions, QString &msgError );
QVector<QString> &descriptions, QString &msgError );

/**
* Will return the named style corresponding to style id provided
*/
virtual QString getStyleFromDatabase( QString styleId, QString &msgError );

virtual QString loadNamedStyle( const QString theURI, bool &theResultFlag, bool loadFromLocalDb=false );
virtual bool applyNamedStyle(QString namedStyle , QString errorMsg);
virtual QString loadNamedStyle( const QString theURI, bool &theResultFlag, bool loadFromLocalDb = false );
virtual bool applyNamedStyle( QString namedStyle , QString errorMsg );

/** convert a saved attribute editor element into a AttributeEditor structure as it's used internally.
* @param elem the DOM element
Expand Down
338 changes: 169 additions & 169 deletions src/providers/postgres/qgspostgresprovider.cpp

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/providers/postgres/qgspostgresprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ class QgsPostgresProvider : public QgsVectorDataProvider
/**
* It returns true. Saving style to db is supported by this provider
*/
virtual bool isSaveAndLoadStyleToDBSupported(){ return true; }
virtual bool isSaveAndLoadStyleToDBSupported() { return true; }

QgsAttributeList attributeIndexes();

Expand Down
46 changes: 23 additions & 23 deletions tests/src/python/test_qgsblendmodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
QgsRasterDataProvider,
QgsMultiBandColorRenderer,
QGis)

from utilities import (unitTestDataPath,
getQgisTestApp,
TestCase,
Expand All @@ -53,79 +53,79 @@ class TestQgsBlendModes(TestCase):
def __init__(self, methodName):
"""Run once on class initialisation."""
unittest.TestCase.__init__(self, methodName)

# initialize class MapRegistry, Canvas, MapRenderer, Map and PAL
self.mMapRegistry = QgsMapLayerRegistry.instance()

# create point layer
myShpFile = os.path.join(TEST_DATA_DIR, 'points.shp')
self.mPointLayer = QgsVectorLayer(myShpFile, 'Points', 'ogr')
self.mMapRegistry.addMapLayer(self.mPointLayer)

# create polygon layer
myShpFile = os.path.join(TEST_DATA_DIR, 'polys.shp')
self.mPolygonLayer = QgsVectorLayer(myShpFile, 'Polygons', 'ogr')
self.mPolygonLayer = QgsVectorLayer(myShpFile, 'Polygons', 'ogr')
self.mMapRegistry.addMapLayer(self.mPolygonLayer)

# create two raster layers
myRasterFile = os.path.join(TEST_DATA_DIR, 'landsat.tif')
myRasterFile = os.path.join(TEST_DATA_DIR, 'landsat.tif')
self.mRasterLayer1 = QgsRasterLayer(myRasterFile, "raster1")
self.mRasterLayer2 = QgsRasterLayer(myRasterFile, "raster2")
myMultiBandRenderer1 = QgsMultiBandColorRenderer(self.mRasterLayer1.dataProvider(), 2, 3, 4)
self.mRasterLayer1.setRenderer(myMultiBandRenderer1)
self.mMapRegistry.addMapLayer(self.mRasterLayer1)
myMultiBandRenderer2 = QgsMultiBandColorRenderer(self.mRasterLayer2.dataProvider(), 2, 3, 4)
myMultiBandRenderer2 = QgsMultiBandColorRenderer(self.mRasterLayer2.dataProvider(), 2, 3, 4)
self.mRasterLayer2.setRenderer(myMultiBandRenderer2)
self.mMapRegistry.addMapLayer(self.mRasterLayer2)
self.mMapRegistry.addMapLayer(self.mRasterLayer2)

# to match blend modes test comparisons background
self.mCanvas = CANVAS
self.mCanvas.setCanvasColor(QColor(152, 219, 249))
self.mMap = self.mCanvas.map()
self.mMap.resize(QSize(400, 400))
self.mMapRenderer = self.mCanvas.mapRenderer()
self.mMapRenderer.setOutputSize(QSize(400, 400), 72)

def testVectorBlending(self):
"""Test that blend modes work for vector layers."""

#Add vector layers to map
myLayers = QStringList()
myLayers.append(self.mPointLayer.id())
myLayers.append(self.mPolygonLayer.id())
myLayers.append(self.mPolygonLayer.id())
self.mMapRenderer.setLayerSet(myLayers)
self.mMapRenderer.setExtent(self.mPointLayer.extent())
self.mMapRenderer.setExtent(self.mPointLayer.extent())

#Set blending modes for both layers
self.mPointLayer.setBlendMode(QPainter.CompositionMode_Overlay)
self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_Multiply)
self.mPolygonLayer.setBlendMode(QPainter.CompositionMode_Multiply)

checker = QgsRenderChecker()
checker.setControlName("expected_vector_blendmodes")
checker.setMapRenderer(self.mMapRenderer)
checker.setMapRenderer(self.mMapRenderer)

myResult = checker.runTest("vector_blendmodes");
myMessage = ('vector blending failed')
assert myResult, myMessage

def testRasterBlending(self):
"""Test that blend modes work for raster layers."""
#Add raster layers to map
myLayers = QStringList()
myLayers.append(self.mRasterLayer1.id())
myLayers.append(self.mRasterLayer2.id())
myLayers.append(self.mRasterLayer2.id())
self.mMapRenderer.setLayerSet(myLayers)
self.mMapRenderer.setExtent(self.mRasterLayer1.extent())
self.mMapRenderer.setExtent(self.mRasterLayer1.extent())

#Set blending mode for top layer
self.mRasterLayer1.setBlendMode(QPainter.CompositionMode_Plus)
checker = QgsRenderChecker()
checker.setControlName("expected_raster_blendmodes")
checker.setMapRenderer(self.mMapRenderer)
checker.setMapRenderer(self.mMapRenderer)

myResult = checker.runTest("raster_blendmodes");
myMessage = ('raster blending failed')
assert myResult, myMessage
assert myResult, myMessage

if __name__ == '__main__':
unittest.main()