Skip to content
Permalink
Browse files
Port labeling to properties framework
  • Loading branch information
nyalldawson committed Jan 23, 2017
1 parent 1e0c62b commit 43bbf689432ef8120fde9b8f27e70db388d14699
@@ -1,83 +1,3 @@
// QMap<QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined*> is implemented as a Python dictionary.
%MappedType QMap<QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined*> /DocType="dict-of-QgsPalLayerSettings.DataDefinedProperties-QgsDataDefined*"/
{
%TypeHeaderCode
#include <qmap.h>
#include <qgspallabeling.h>
#include <qgsdatadefined.h>
%End
%ConvertFromTypeCode
// Create the dictionary.
PyObject *d = PyDict_New();
if (!d)
return NULL;
// Set the dictionary elements.
QMap<QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined*>::const_iterator i = sipCpp->constBegin();
while (i != sipCpp->constEnd())
{
QgsDataDefined *t = i.value();
PyObject *kobj = sipConvertFromEnum(i.key(), sipType_QgsPalLayerSettings_DataDefinedProperties);
PyObject *tobj = sipConvertFromType(t, sipType_QgsDataDefined, sipTransferObj);
if (kobj == NULL || tobj == NULL || PyDict_SetItem(d, kobj, tobj) < 0)
{
Py_DECREF(d);
if (kobj)
{
Py_DECREF(kobj);
}
if (tobj)
{
Py_DECREF(tobj);
}
else
{
delete t;
}
return NULL;
}
Py_DECREF(kobj);
Py_DECREF(tobj);
++i;
}
return d;
%End
%ConvertToTypeCode
PyObject *kobj, *tobj;
SIP_SSIZE_T i = 0;
// Check the type if that is all that is required.
if (sipIsErr == NULL)
{
if (!PyDict_Check(sipPy))
return 0;
while (PyDict_Next(sipPy, &i, &kobj, &tobj))
if (!sipCanConvertToType(tobj, sipType_QgsDataDefined, SIP_NOT_NONE))
return 0;
return 1;
}
QMap<QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined*> *qm = new QMap<QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined*>;

while (PyDict_Next(sipPy, &i, &kobj, &tobj))
{
int state, k = SIPLong_AsLong(kobj);
QgsDataDefined *t = reinterpret_cast<QgsDataDefined *>(sipConvertToType(tobj, sipType_QgsDataDefined, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr));

if (*sipIsErr)
{
sipReleaseType(t, sipType_QgsDataDefined, state);
delete qm;
return 0;
}
qm->insert(QgsPalLayerSettings::DataDefinedProperties(k), t);
sipReleaseType(t, sipType_QgsDataDefined, state);
}

*sipCppPtr = qm;

return sipGetState(sipTransferObj);
%End
};


class QgsLabelPosition
{
%TypeHeaderCode
@@ -239,7 +159,7 @@ class QgsPalLayerSettings
};

// update mDataDefinedNames QMap in constructor when adding/deleting enum value
enum DataDefinedProperties
enum Property
{
// text style
Size,
@@ -507,67 +427,24 @@ class QgsPalLayerSettings
*/
QDomElement writeXml( QDomDocument& doc );

/** Get a data defined property pointer
* @note helpful for Python access
*/
QgsDataDefined* dataDefinedProperty( QgsPalLayerSettings::DataDefinedProperties p );

/** Set a property as data defined
* @note helpful for Python access
*/
void setDataDefinedProperty( QgsPalLayerSettings::DataDefinedProperties p,
bool active, bool useExpr, const QString& expr, const QString& field );

/** Set a property to static instead data defined */
void removeDataDefinedProperty( QgsPalLayerSettings::DataDefinedProperties p );

/** Clear all data-defined properties
* @note added in QGIS 2.12
*/
void removeAllDataDefinedProperties();

/** Convert old property value to new one as delimited values
* @note not available in python bindings; as temporary solution until refactoring of project settings
*/
QString updateDataDefinedString( const QString& value );

/** Get property value as separate values split into Qmap
* @note not available in python bindings
*/
QMap<QString, QString> dataDefinedMap( QgsPalLayerSettings::DataDefinedProperties p ) const;

/** Get data defined property value from expression string or attribute field name
* @returns value inside QVariant
* @note not available in python bindings
*/
//QVariant dataDefinedValue( QgsPalLayerSettings::DataDefinedProperties p, QgsFeature& f, const QgsFields& fields,
// const QgsExpressionContext* context = 0 ) const;

/** Get data defined property value from expression string or attribute field name
* @returns true/false whether result is null or invalid
* @note not available in python bindings
*/
//bool dataDefinedEvaluate( QgsPalLayerSettings::DataDefinedProperties p, QVariant& exprVal, const QgsExpressionContext* context = 0 ) const;

/** Whether data definition is active
*/
bool dataDefinedIsActive( QgsPalLayerSettings::DataDefinedProperties p ) const;

/** Whether data definition is set to use an expression
/** Returns a reference to the label's property collection, used for data defined overrides.
* @note added in QGIS 3.0
* @see setProperties()
*/
bool dataDefinedUseExpression( QgsPalLayerSettings::DataDefinedProperties p ) const;
QgsPropertyCollection& properties();

/** Map of current data defined properties
*
* Pointers to QgsDataDefined should never be null, the pointers are owned by this class
/** Returns a reference to the label's property collection, used for data defined overrides.
* @note added in QGIS 3.0
* @see setProperties()
*/
QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* > dataDefinedProperties;
//const QgsPropertyCollection& properties() const { return mProperties; }

/** Map of data defined enum to names and old-style indecies
* The QPair contains a new string for layer property key, and a reference to old-style numeric key (< QGIS 2.0)
* @note not available in python bindings;
/** Sets the label's property collection, used for data defined overrides.
* @param collection property collection. Existing properties will be replaced.
* @note added in QGIS 3.0
* @see properties()
*/
// QMap<QgsPalLayerSettings::DataDefinedProperties, QPair<QString, int> > dataDefinedNames() const;
void setProperties( const QgsPropertyCollection& collection );

/** Returns the label text formatting settings, e.g., font settings, buffer settings, etc.
* @see setFormat()
@@ -737,23 +614,23 @@ class QgsPalLabeling
protected:
// update temporary QgsPalLayerSettings with any data defined text style values
void dataDefinedTextStyle( QgsPalLayerSettings& tmpLyr,
const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues );
const QMap< QgsPalLayerSettings::Property, QVariant >& ddValues );

// update temporary QgsPalLayerSettings with any data defined text formatting values
void dataDefinedTextFormatting( QgsPalLayerSettings& tmpLyr,
const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues );
const QMap< QgsPalLayerSettings::Property, QVariant >& ddValues );

// update temporary QgsPalLayerSettings with any data defined text buffer values
void dataDefinedTextBuffer( QgsPalLayerSettings& tmpLyr,
const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues );
const QMap< QgsPalLayerSettings::Property, QVariant >& ddValues );

// update temporary QgsPalLayerSettings with any data defined shape background values
void dataDefinedShapeBackground( QgsPalLayerSettings& tmpLyr,
const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues );
const QMap< QgsPalLayerSettings::Property, QVariant >& ddValues );

// update temporary QgsPalLayerSettings with any data defined drop shadow values
void dataDefinedDropShadow( QgsPalLayerSettings& tmpLyr,
const QMap< QgsPalLayerSettings::DataDefinedProperties, QVariant >& ddValues );
const QMap< QgsPalLayerSettings::Property, QVariant >& ddValues );

void deleteTemporaryData();

@@ -123,6 +123,17 @@ class QgsAbstractProperty
*/
int valueAsInt( const QgsExpressionContext& context, int defaultValue = 0 ) const;

/**
* Calculates the current value of the property and interprets it as an boolean.
* @param context QgsExpressionContext to evaluate the property for.
* @param defaultValue default boolean to return if the property cannot be calculated as an boolean
* @returns value parsed to boolean
* @see value()
* @see valueAsDouble()
* @see valueAsColor()
*/
bool valueAsBool( const QgsExpressionContext& context, bool defaultValue = false ) const;

/** Writes the current state of the property into an XML element
* @param propertyElem destination element for the property's state
* @param doc DOM document
@@ -1,3 +1,5 @@
typedef QMap< int, QString > QgsPropertyDefinition;

/**
* \ingroup core
* \class QgsAbstractPropertyCollection
@@ -126,6 +128,20 @@ class QgsAbstractPropertyCollection
*/
int valueAsInt( int key, const QgsExpressionContext& context, int defaultValue = 0 ) const;

/**
* Calculates the current value of the property with the specified key and interprets it as an boolean.
* @param key integer key for property to return. The intended use case is that a context specific enum is cast to
* int and used for the key value.
* @param context QgsExpressionContext to evaluate the property for.
* @param defaultValue default boolean to return if the property cannot be calculated as a boolean
* @returns value parsed to bool
* @see value()
* @see valueAsDouble()
* @see valueAsColor()
*/
bool valueAsBool( int key, const QgsExpressionContext& context, bool defaultValue = false ) const;


/**
* Prepares the collection against a specified expression context. Calling prepare before evaluating the
* collection's properties multiple times allows precalculation of expensive setup tasks such as parsing expressions.
@@ -168,7 +184,7 @@ class QgsAbstractPropertyCollection
* to avoid writing the raw integer key values to XML, for readability and future-proofness.
* @see readXML()
*/
virtual bool writeXml( QDomElement& collectionElem, QDomDocument& doc, const QMap< int, QString >& propertyNameMap ) const = 0;
virtual bool writeXml( QDomElement& collectionElem, QDomDocument& doc, const QgsPropertyDefinition& propertyNameMap ) const = 0;

/**
* Reads property collection state from an XML element.
@@ -178,7 +194,7 @@ class QgsAbstractPropertyCollection
* the propertyNameMap specified when writeXML() was called.
* @see writeXML()
*/
virtual bool readXml( const QDomElement& collectionElem, const QDomDocument& doc, const QMap<int, QString> &propertyNameMap ) = 0;
virtual bool readXml( const QDomElement& collectionElem, const QDomDocument& doc, const QgsPropertyDefinition &propertyNameMap ) = 0;

};

@@ -227,8 +243,8 @@ class QgsPropertyCollection : QgsAbstractPropertyCollection
bool isActive( int key ) const;
bool hasActiveProperties() const;
bool hasActiveDynamicProperties() const;
bool writeXml( QDomElement& collectionElem, QDomDocument& doc, const QMap< int, QString >& propertyNameMap ) const;
bool readXml( const QDomElement& collectionElem, const QDomDocument& doc, const QMap<int, QString> &propertyNameMap );
bool writeXml( QDomElement& collectionElem, QDomDocument& doc, const QgsPropertyDefinition& propertyNameMap ) const;
bool readXml( const QDomElement& collectionElem, const QDomDocument& doc, const QgsPropertyDefinition& propertyNameMap );

/** Adds a property to the collection and takes ownership of it.
* @param key integer key for property. Any existing property with the same key will be deleted
@@ -353,7 +369,7 @@ class QgsPropertyCollectionStack : QgsAbstractPropertyCollection

QSet<int> propertyKeys() const;
bool hasProperty( int key ) const;
bool writeXml( QDomElement& collectionElem, QDomDocument& doc, const QMap< int, QString >& propertyNameMap ) const;
bool readXml( const QDomElement& collectionElem, const QDomDocument& doc, const QMap<int, QString> &propertyNameMap );
bool writeXml( QDomElement& collectionElem, QDomDocument& doc, const QgsPropertyDefinition& propertyNameMap ) const;
bool readXml( const QDomElement& collectionElem, const QDomDocument& doc, const QgsPropertyDefinition &propertyNameMap );
};

@@ -42,6 +42,7 @@
#include "qgsgenericprojectionselector.h"
#include "qgsmessagelog.h"
#include "qgslogger.h"
#include "qgsproperty.h"


struct CursorOverride
@@ -358,14 +359,13 @@ void QgsDwgImportDialog::createGroup( QgsLayerTreeGroup *group, QString name, QS
pls.drawLabels = true;
pls.fieldName = "text";
pls.wrapChar = "\\P";
pls.setDataDefinedProperty( QgsPalLayerSettings::Size, true, false, "", "height" );
pls.setDataDefinedProperty( QgsPalLayerSettings::Color, true, false, "", "color" );
pls.setDataDefinedProperty( QgsPalLayerSettings::MultiLineHeight, true, true, "CASE WHEN interlin<0 THEN 1 ELSE interlin*1.5 END", "" );
pls.placement = QgsPalLayerSettings::OrderedPositionsAroundPoint;
pls.setDataDefinedProperty( QgsPalLayerSettings::PositionX, true, true, "$x", "" );
pls.setDataDefinedProperty( QgsPalLayerSettings::PositionY, true, true, "$y", "" );
pls.setDataDefinedProperty( QgsPalLayerSettings::Hali, true, true, QString(
"CASE"

pls.properties().setProperty( QgsPalLayerSettings::Size, new QgsFieldBasedProperty( QStringLiteral( "height" ) ) );
pls.properties().setProperty( QgsPalLayerSettings::Color, new QgsFieldBasedProperty( QStringLiteral( "color" ) ) );
pls.properties().setProperty( QgsPalLayerSettings::MultiLineHeight, new QgsExpressionBasedProperty( QStringLiteral( "CASE WHEN interlin<0 THEN 1 ELSE interlin*1.5 END" ) ) );
pls.properties().setProperty( QgsPalLayerSettings::PositionX, new QgsExpressionBasedProperty( QStringLiteral( "$x" ) ) );
pls.properties().setProperty( QgsPalLayerSettings::PositionY, new QgsExpressionBasedProperty( QStringLiteral( "$y" ) ) );
pls.properties().setProperty( QgsPalLayerSettings::Hali, new QgsExpressionBasedProperty( QStringLiteral( "CASE"
" WHEN etype=%1 THEN"
" CASE"
" WHEN alignv IN (1,4,7) THEN 'Left'"
@@ -380,10 +380,8 @@ void QgsDwgImportDialog::createGroup( QgsLayerTreeGroup *group, QString name, QS
" WHEN alignh=3 THEN 'Left'"
" WHEN alignh=4 THEN 'Left'"
" END "
" END" ).arg( DRW::MTEXT ), "" );

pls.setDataDefinedProperty( QgsPalLayerSettings::Vali, true, true, QString(
"CASE"
" END" ).arg( DRW::MTEXT ) ) );
pls.properties().setProperty( QgsPalLayerSettings::Vali, new QgsExpressionBasedProperty( QStringLiteral( "CASE"
" WHEN etype=%1 THEN"
" CASE"
" WHEN alignv < 4 THEN 'Top'"
@@ -397,10 +395,10 @@ void QgsDwgImportDialog::createGroup( QgsLayerTreeGroup *group, QString name, QS
" WHEN alignv=2 THEN 'Half'"
" WHEN alignv=3 THEN 'Top'"
" END"
" END" ).arg( DRW::MTEXT ), "" );

pls.setDataDefinedProperty( QgsPalLayerSettings::Rotation, true, true, "angle*180.0/pi()", "" );
" END" ).arg( DRW::MTEXT ) ) );
pls.properties().setProperty( QgsPalLayerSettings::Rotation, new QgsExpressionBasedProperty( QStringLiteral( "angle*180.0/pi()" ) ) );

pls.placement = QgsPalLayerSettings::OrderedPositionsAroundPoint;
pls.writeToLayer( l );
}

0 comments on commit 43bbf68

Please sign in to comment.