Skip to content

Commit be5aeac

Browse files
committed
[composer] Initial framework for data defined properties in compositions and composer items. Funded by Canton of Neuchâtel, Switzerland
1 parent 51408e1 commit be5aeac

File tree

8 files changed

+794
-11
lines changed

8 files changed

+794
-11
lines changed

python/core/composer/qgscomposeritem.sip

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,36 @@ class QgsComposerItem : QObject, QGraphicsRectItem
133133
LowerRight
134134
};
135135

136+
/** Data defined properties for different item types
137+
*/
138+
enum DataDefinedProperty
139+
{
140+
NoProperty = 0, /*< no property */
141+
AllProperties, /*< all properties for item */
142+
//composer page properties
143+
PresetPaperSize, /*< preset paper size for composition */
144+
PaperWidth, /*< paper width */
145+
PaperHeight, /*< paper height */
146+
NumPages, /*< number of pages in composition */
147+
PaperOrientation, /*< paper orientation */
148+
//general composer item properties
149+
PageNumber, /*< page number for item placement */
150+
PositionX, /*< x position on page */
151+
PositionY, /*< y position on page */
152+
ItemWidth, /*< width of item */
153+
ItemHeight, /*< height of item */
154+
ItemRotation, /*< rotation of item */
155+
Transparency, /*< item transparency */
156+
BlendMode, /*< item blend mode */
157+
//composer map
158+
MapRotation, /*< map rotation */
159+
MapScale, /*< map scale */
160+
MapXMin, /*< map extent x minimum */
161+
MapYMin, /*< map extent y minimum */
162+
MapXMax, /*< map extent x maximum */
163+
MapYMax /*< map extent y maximum */
164+
};
165+
136166
/**Constructor
137167
@param composition parent composition
138168
@param manageZValue true if the z-Value of this object should be managed by mComposition*/
@@ -481,22 +511,47 @@ class QgsComposerItem : QObject, QGraphicsRectItem
481511
*/
482512
void setCurrentExportLayer( int layerIdx = -1 );
483513

514+
/**Returns a reference to the data defined settings for one of the item's data defined properties.
515+
* @param property data defined property to return
516+
* @note this method was added in version 2.5
517+
*/
518+
QgsDataDefined* dataDefinedProperty( DataDefinedProperty property );
519+
520+
/**Sets parameters for a data defined property for the item
521+
* @param property data defined property to set
522+
* @param active true if data defined property is active, false if it is disabled
523+
* @param useExpression true if the expression should be used
524+
* @param expression expression for data defined property
525+
* @field field name if the data defined property should take its value from a field
526+
* @note this method was added in version 2.5
527+
*/
528+
void setDataDefinedProperty( DataDefinedProperty property, bool active, bool useExpression, const QString &expression, const QString &field );
529+
484530
public slots:
485531
/**Sets the item rotation
486532
* @deprecated Use setItemRotation( double rotation ) instead
487533
*/
488534
virtual void setRotation( double r );
489535

490536
/**Sets the item rotation
491-
@param r item rotation in degrees
492-
@param adjustPosition set to true if item should be shifted so that rotation occurs
493-
around item center. If false, rotation occurs around item origin
494-
@note this method was added in version 2.1
537+
* @param r item rotation in degrees
538+
* @param adjustPosition set to true if item should be shifted so that rotation occurs
539+
* around item center. If false, rotation occurs around item origin
540+
* @note this method was added in version 2.1
495541
*/
496542
virtual void setItemRotation( double r, bool adjustPosition = false );
497543

498544
void repaint();
499545

546+
/**Refreshes a data defined property for the item by reevaluating the property's value
547+
* and redrawing the item with this new value.
548+
* @param property data defined property to refresh. If property is set to
549+
* QgsComposerItem::AllProperties then all data defined properties for the item will be
550+
* refreshed.
551+
* @note this method was added in version 2.5
552+
*/
553+
virtual void refreshDataDefinedProperty( DataDefinedProperty property = AllProperties );
554+
500555
protected:
501556

502557
//event handlers
@@ -582,6 +637,14 @@ class QgsComposerItem : QObject, QGraphicsRectItem
582637
void deleteVAlignSnapItem();
583638
void deleteAlignItems();
584639

640+
/**Evaluate a data defined property and return the calculated value
641+
* @returns true if data defined property could be successfully evaluated
642+
* @param property data defined property to evaluate
643+
* @param expressionValue QVariant for storing the evaluated value
644+
* @note this method was added in version 2.5
645+
*/
646+
bool dataDefinedEvaluate( QgsComposerItem::DataDefinedProperty property, QVariant &expressionValue );
647+
585648
signals:
586649
/**Is emitted on item rotation change*/
587650
void itemRotationChanged( double newRotation );

python/core/composer/qgscomposition.sip

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,22 @@ class QgsComposition : QGraphicsScene
444444
@note added in version 2.4*/
445445
QList< QgsPaperItem* > pages();
446446

447+
/**Returns a reference to the data defined settings for one of the composition's data defined properties.
448+
* @param property data defined property to return
449+
* @note this method was added in version 2.5
450+
*/
451+
QgsDataDefined* dataDefinedProperty( QgsComposerItem::DataDefinedProperty property );
452+
453+
/**Sets parameters for a data defined property for the composition
454+
* @param property data defined property to set
455+
* @param active true if data defined property is active, false if it is disabled
456+
* @param useExpression true if the expression should be used
457+
* @param expression expression for data defined property
458+
* @field field name if the data defined property should take its value from a field
459+
* @note this method was added in version 2.5
460+
*/
461+
void setDataDefinedProperty( QgsComposerItem::DataDefinedProperty property, bool active, bool useExpression, const QString &expression, const QString &field );
462+
447463
public slots:
448464
/**Casts object to the proper subclass type and calls corresponding itemAdded signal*/
449465
void sendItemAddedSignal( QgsComposerItem* item );
@@ -463,6 +479,15 @@ class QgsComposition : QGraphicsScene
463479
* @note added in version 2.3*/
464480
void setSelectedItem( QgsComposerItem* item );
465481

482+
/**Refreshes a data defined property for the composition by reevaluating the property's value
483+
* and redrawing the composition with this new value.
484+
* @param property data defined property to refresh. If property is set to
485+
* QgsComposerItem::AllProperties then all data defined properties for the composition will be
486+
* refreshed.
487+
* @note this method was added in version 2.5
488+
*/
489+
void refreshDataDefinedProperty( QgsComposerItem::DataDefinedProperty property = QgsComposerItem::AllProperties );
490+
466491
protected:
467492
void init();
468493

src/app/composer/qgscomposeritemwidget.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
#include "qgscomposeritemwidget.h"
1919
#include "qgscomposeritem.h"
2020
#include "qgscomposermap.h"
21+
#include "qgsatlascomposition.h"
2122
#include "qgscomposition.h"
2223
#include "qgspoint.h"
24+
#include "qgsdatadefinedbutton.h"
2325
#include <QColorDialog>
2426
#include <QPen>
2527

@@ -36,6 +38,44 @@ QgsComposerItemBaseWidget::~QgsComposerItemBaseWidget()
3638

3739
}
3840

41+
void QgsComposerItemBaseWidget::updateDataDefinedProperty()
42+
{
43+
//match data defined button to item's data defined property
44+
QgsDataDefinedButton* ddButton = dynamic_cast<QgsDataDefinedButton*>( sender() );
45+
if ( !ddButton )
46+
{
47+
return;
48+
}
49+
QgsComposerItem::DataDefinedProperty property = ddPropertyForWidget( ddButton );
50+
if ( property == QgsComposerItem::NoProperty )
51+
{
52+
return;
53+
}
54+
55+
//set the data defined property and refresh the item
56+
setDataDefinedProperty( ddButton, property );
57+
mItem->refreshDataDefinedProperty( property );
58+
}
59+
60+
void QgsComposerItemBaseWidget::setDataDefinedProperty( const QgsDataDefinedButton *ddBtn, QgsComposerItem::DataDefinedProperty p )
61+
{
62+
if ( !mItem )
63+
{
64+
return;
65+
}
66+
67+
const QMap< QString, QString >& map = ddBtn->definedProperty();
68+
mItem->setDataDefinedProperty( p, map.value( "active" ).toInt(), map.value( "useexpr" ).toInt(), map.value( "expression" ), map.value( "field" ) );
69+
}
70+
71+
QgsComposerItem::DataDefinedProperty QgsComposerItemBaseWidget::ddPropertyForWidget( QgsDataDefinedButton *widget )
72+
{
73+
Q_UNUSED( widget );
74+
75+
//base implementation, return no property
76+
return QgsComposerItem::NoProperty;
77+
}
78+
3979
QgsAtlasComposition* QgsComposerItemBaseWidget::atlasComposition() const
4080
{
4181
if ( !mItem )
@@ -98,6 +138,17 @@ QgsComposerItemWidget::QgsComposerItemWidget( QWidget* parent, QgsComposerItem*
98138

99139
connect( mTransparencySlider, SIGNAL( valueChanged( int ) ), mTransparencySpnBx, SLOT( setValue( int ) ) );
100140
connect( mTransparencySpnBx, SIGNAL( valueChanged( int ) ), mTransparencySlider, SLOT( setValue( int ) ) );
141+
142+
//connect atlas signals to data defined buttons
143+
QgsAtlasComposition* atlas = atlasComposition();
144+
if ( atlas )
145+
{
146+
//repopulate data defined buttons if atlas layer changes
147+
connect( atlas, SIGNAL( coverageLayerChanged( QgsVectorLayer* ) ),
148+
this, SLOT( populateDataDefinedButtons() ) );
149+
connect( atlas, SIGNAL( toggled( bool ) ), this, SLOT( populateDataDefinedButtons() ) );
150+
}
151+
101152
}
102153

103154
QgsComposerItemWidget::QgsComposerItemWidget(): QgsComposerItemBaseWidget( 0, 0 )
@@ -449,6 +500,20 @@ void QgsComposerItemWidget::setValuesForGuiNonPositionElements()
449500
mItemRotationSpinBox->blockSignals( false );
450501
}
451502

503+
void QgsComposerItemWidget::populateDataDefinedButtons()
504+
{
505+
//QgsVectorLayer* vl = atlasCoverageLayer();
506+
507+
//block signals from data defined buttons
508+
509+
//initialise buttons to use atlas coverage layer
510+
511+
//initial state of controls - disable related controls when dd buttons are active
512+
513+
//unblock signals from data defined buttons
514+
515+
}
516+
452517
void QgsComposerItemWidget::setValuesForGuiElements()
453518
{
454519
if ( !mItem )
@@ -463,6 +528,7 @@ void QgsComposerItemWidget::setValuesForGuiElements()
463528

464529
setValuesForGuiPositionElements();
465530
setValuesForGuiNonPositionElements();
531+
populateDataDefinedButtons();
466532
}
467533

468534
void QgsComposerItemWidget::on_mBlendModeCombo_currentIndexChanged( int index )

src/app/composer/qgscomposeritemwidget.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
class QgsComposerItem;
2525
class QgsAtlasComposition;
26+
class QgsDataDefinedButton;
2627

2728
/**A base class for property widgets for composer items. All composer item widgets should inherit from
2829
* this base class.
@@ -34,7 +35,17 @@ class QgsComposerItemBaseWidget: public QWidget
3435
QgsComposerItemBaseWidget( QWidget* parent, QgsComposerItem* item );
3536
~QgsComposerItemBaseWidget();
3637

38+
protected slots:
39+
/**Must be called when a data defined button changes*/
40+
void updateDataDefinedProperty();
41+
3742
protected:
43+
/**Sets a data defined property for the item from its current data defined button settings*/
44+
void setDataDefinedProperty( const QgsDataDefinedButton *ddBtn, QgsComposerItem::DataDefinedProperty p );
45+
46+
/**Returns the data defined property corresponding to a data defined button widget*/
47+
virtual QgsComposerItem::DataDefinedProperty ddPropertyForWidget( QgsDataDefinedButton* widget );
48+
3849
/**Returns the current atlas coverage layer (if set)*/
3950
QgsVectorLayer* atlasCoverageLayer() const;
4051

@@ -108,6 +119,10 @@ class QgsComposerItemWidget: public QgsComposerItemBaseWidget, private Ui::QgsCo
108119
//sets the values for all non-position related elements
109120
void setValuesForGuiNonPositionElements();
110121

122+
protected slots:
123+
/**Initializes data defined buttons to current atlas coverage layer*/
124+
void populateDataDefinedButtons();
125+
111126
private:
112127
QgsComposerItemWidget();
113128
// void changeItemTransparency( int value );

0 commit comments

Comments
 (0)