Skip to content
Permalink
Browse files

Add method to auto create a callout property in auxilliary storage

  • Loading branch information
nyalldawson committed Mar 15, 2021
1 parent f80a754 commit a1fa68d3e59ec508adea77d8d83ab286b79a64f7
@@ -190,6 +190,19 @@ activates this property in settings.
:param vlayer: The vector layer

:return: The index of the auxiliary field or -1
%End

static int createProperty( QgsCallout::Property property, QgsVectorLayer *vlayer );
%Docstring
Creates if necessary a new auxiliary field for a callout's property and
activates this property in settings.

:param property: The property to create
:param vlayer: The vector layer

:return: The index of the auxiliary field or -1

.. versionadded:: 3.20
%End

static QgsField createAuxiliaryField( const QgsPropertyDefinition &definition );
@@ -283,6 +283,42 @@ int QgsAuxiliaryLayer::createProperty( QgsDiagramLayerSettings::Property propert
return index;
}

int QgsAuxiliaryLayer::createProperty( QgsCallout::Property property, QgsVectorLayer *layer )
{
int index = -1;

if ( layer && layer->labeling() && layer->labeling()->settings().callout() && layer->auxiliaryLayer() )
{
// property definition are identical whatever the provider id
const QgsPropertyDefinition def = layer->labeling()->settings().callout()->propertyDefinitions()[property];
const QString fieldName = nameFromProperty( def, true );

layer->auxiliaryLayer()->addAuxiliaryField( def );

if ( layer->auxiliaryLayer()->indexOfPropertyDefinition( def ) >= 0 )
{
const QgsProperty prop = QgsProperty::fromField( fieldName );

const QStringList subProviderIds = layer->labeling()->subProviders();
for ( const QString &providerId : subProviderIds )
{
QgsPalLayerSettings *settings = new QgsPalLayerSettings( layer->labeling()->settings( providerId ) );
if ( settings->callout() )
{
QgsPropertyCollection c = settings->callout()->dataDefinedProperties();
c.setProperty( property, prop );
settings->callout()->setDataDefinedProperties( c );
}
layer->labeling()->setSettings( settings, providerId );
}
}

index = layer->fields().lookupField( fieldName );
}

return index;
}

bool QgsAuxiliaryLayer::isHiddenProperty( int index ) const
{
bool hidden = false;
@@ -26,6 +26,7 @@
#include "qgsproperty.h"
#include "qgsspatialiteutils.h"
#include "qgsvectorlayer.h"
#include "qgscallout.h"
#include <QString>

class QgsProject;
@@ -218,6 +219,18 @@ class CORE_EXPORT QgsAuxiliaryLayer : public QgsVectorLayer
*/
static int createProperty( QgsDiagramLayerSettings::Property property, QgsVectorLayer *vlayer );

/**
* Creates if necessary a new auxiliary field for a callout's property and
* activates this property in settings.
*
* \param property The property to create
* \param vlayer The vector layer
*
* \returns The index of the auxiliary field or -1
* \since QGIS 3.20
*/
static int createProperty( QgsCallout::Property property, QgsVectorLayer *vlayer );

/**
* Creates a new auxiliary field from a property definition.
*
@@ -21,11 +21,14 @@
QgsFeature,
QgsGeometry,
QgsPropertyDefinition,
QgsProperty,
QgsProject,
QgsFeatureRequest,
QgsPalLayerSettings,
QgsSymbolLayer,
QgsVectorLayerSimpleLabeling,
QgsCallout,
QgsSimpleLineCallout,
NULL)
from qgis.testing import start_app, unittest
from utilities import unitTestDataPath, writeShape
@@ -405,6 +408,60 @@ def testCreateProperty(self):
afIndex = vl.fields().indexOf(afName)
self.assertEqual(index, afIndex)

def testCreateCalloutProperty(self):
s = QgsAuxiliaryStorage()
self.assertTrue(s.isValid())

# Create a new auxiliary layer with 'pk' as key
vl = createLayer()
pkf = vl.fields().field(vl.fields().indexOf('pk'))
al = s.createAuxiliaryLayer(pkf, vl)
self.assertTrue(al.isValid())
vl.setAuxiliaryLayer(al)

# Create a new callout property on layer without labels
key = QgsCallout.DestinationX
index = QgsAuxiliaryLayer.createProperty(key, vl)
self.assertEqual(index, -1)

# Labeling, but no callouts
settings = QgsPalLayerSettings()
settings.setCallout(None)
vl.setLabeling(QgsVectorLayerSimpleLabeling(settings))
index = QgsAuxiliaryLayer.createProperty(key, vl)
self.assertEqual(index, -1)

# callouts
settings = QgsPalLayerSettings()
callout = QgsSimpleLineCallout()
callout.setEnabled(True)
settings.setCallout(callout)
vl.setLabeling(QgsVectorLayerSimpleLabeling(settings))

index = QgsAuxiliaryLayer.createProperty(key, vl)

p = QgsCallout.propertyDefinitions()[key]
afName = QgsAuxiliaryLayer.nameFromProperty(p, True)
afIndex = vl.fields().indexOf(afName)
self.assertEqual(index, afIndex)

settings = vl.labeling().settings()
self.assertEqual(settings.callout().dataDefinedProperties().property(key), QgsProperty.fromField('auxiliary_storage_callouts_destinationx'))

key2 = QgsCallout.DestinationY
index = QgsAuxiliaryLayer.createProperty(key2, vl)

p = QgsCallout.propertyDefinitions()[key2]
afName = QgsAuxiliaryLayer.nameFromProperty(p, True)
afIndex = vl.fields().indexOf(afName)
self.assertEqual(index, afIndex)

settings = vl.labeling().settings()
self.assertEqual(settings.callout().dataDefinedProperties().property(key),
QgsProperty.fromField('auxiliary_storage_callouts_destinationx'))
self.assertEqual(settings.callout().dataDefinedProperties().property(key2),
QgsProperty.fromField('auxiliary_storage_callouts_destinationy'))

def testCreateField(self):
s = QgsAuxiliaryStorage()
self.assertTrue(s.isValid())

0 comments on commit a1fa68d

Please sign in to comment.