Skip to content

Commit

Permalink
[composer] Initial framework for data defined properties in compositi…
Browse files Browse the repository at this point in the history
…ons and composer items. Funded by Canton of Neuchâtel, Switzerland
  • Loading branch information
nyalldawson committed Jul 5, 2014
1 parent 51408e1 commit be5aeac
Show file tree
Hide file tree
Showing 8 changed files with 794 additions and 11 deletions.
71 changes: 67 additions & 4 deletions python/core/composer/qgscomposeritem.sip
Expand Up @@ -133,6 +133,36 @@ class QgsComposerItem : QObject, QGraphicsRectItem
LowerRight
};

/** Data defined properties for different item types
*/
enum DataDefinedProperty
{
NoProperty = 0, /*< no property */
AllProperties, /*< all properties for item */
//composer page properties
PresetPaperSize, /*< preset paper size for composition */
PaperWidth, /*< paper width */
PaperHeight, /*< paper height */
NumPages, /*< number of pages in composition */
PaperOrientation, /*< paper orientation */
//general composer item properties
PageNumber, /*< page number for item placement */
PositionX, /*< x position on page */
PositionY, /*< y position on page */
ItemWidth, /*< width of item */
ItemHeight, /*< height of item */
ItemRotation, /*< rotation of item */
Transparency, /*< item transparency */
BlendMode, /*< item blend mode */
//composer map
MapRotation, /*< map rotation */
MapScale, /*< map scale */
MapXMin, /*< map extent x minimum */
MapYMin, /*< map extent y minimum */
MapXMax, /*< map extent x maximum */
MapYMax /*< map extent y maximum */
};

/**Constructor
@param composition parent composition
@param manageZValue true if the z-Value of this object should be managed by mComposition*/
Expand Down Expand Up @@ -481,22 +511,47 @@ class QgsComposerItem : QObject, QGraphicsRectItem
*/
void setCurrentExportLayer( int layerIdx = -1 );

/**Returns a reference to the data defined settings for one of the item's data defined properties.
* @param property data defined property to return
* @note this method was added in version 2.5
*/
QgsDataDefined* dataDefinedProperty( DataDefinedProperty property );

/**Sets parameters for a data defined property for the item
* @param property data defined property to set
* @param active true if data defined property is active, false if it is disabled
* @param useExpression true if the expression should be used
* @param expression expression for data defined property
* @field field name if the data defined property should take its value from a field
* @note this method was added in version 2.5
*/
void setDataDefinedProperty( DataDefinedProperty property, bool active, bool useExpression, const QString &expression, const QString &field );

public slots:
/**Sets the item rotation
* @deprecated Use setItemRotation( double rotation ) instead
*/
virtual void setRotation( double r );

/**Sets the item rotation
@param r item rotation in degrees
@param adjustPosition set to true if item should be shifted so that rotation occurs
around item center. If false, rotation occurs around item origin
@note this method was added in version 2.1
* @param r item rotation in degrees
* @param adjustPosition set to true if item should be shifted so that rotation occurs
* around item center. If false, rotation occurs around item origin
* @note this method was added in version 2.1
*/
virtual void setItemRotation( double r, bool adjustPosition = false );

void repaint();

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

protected:

//event handlers
Expand Down Expand Up @@ -582,6 +637,14 @@ class QgsComposerItem : QObject, QGraphicsRectItem
void deleteVAlignSnapItem();
void deleteAlignItems();

/**Evaluate a data defined property and return the calculated value
* @returns true if data defined property could be successfully evaluated
* @param property data defined property to evaluate
* @param expressionValue QVariant for storing the evaluated value
* @note this method was added in version 2.5
*/
bool dataDefinedEvaluate( QgsComposerItem::DataDefinedProperty property, QVariant &expressionValue );

signals:
/**Is emitted on item rotation change*/
void itemRotationChanged( double newRotation );
Expand Down
25 changes: 25 additions & 0 deletions python/core/composer/qgscomposition.sip
Expand Up @@ -444,6 +444,22 @@ class QgsComposition : QGraphicsScene
@note added in version 2.4*/
QList< QgsPaperItem* > pages();

/**Returns a reference to the data defined settings for one of the composition's data defined properties.
* @param property data defined property to return
* @note this method was added in version 2.5
*/
QgsDataDefined* dataDefinedProperty( QgsComposerItem::DataDefinedProperty property );

/**Sets parameters for a data defined property for the composition
* @param property data defined property to set
* @param active true if data defined property is active, false if it is disabled
* @param useExpression true if the expression should be used
* @param expression expression for data defined property
* @field field name if the data defined property should take its value from a field
* @note this method was added in version 2.5
*/
void setDataDefinedProperty( QgsComposerItem::DataDefinedProperty property, bool active, bool useExpression, const QString &expression, const QString &field );

public slots:
/**Casts object to the proper subclass type and calls corresponding itemAdded signal*/
void sendItemAddedSignal( QgsComposerItem* item );
Expand All @@ -463,6 +479,15 @@ class QgsComposition : QGraphicsScene
* @note added in version 2.3*/
void setSelectedItem( QgsComposerItem* item );

/**Refreshes a data defined property for the composition by reevaluating the property's value
* and redrawing the composition with this new value.
* @param property data defined property to refresh. If property is set to
* QgsComposerItem::AllProperties then all data defined properties for the composition will be
* refreshed.
* @note this method was added in version 2.5
*/
void refreshDataDefinedProperty( QgsComposerItem::DataDefinedProperty property = QgsComposerItem::AllProperties );

protected:
void init();

Expand Down
66 changes: 66 additions & 0 deletions src/app/composer/qgscomposeritemwidget.cpp
Expand Up @@ -18,8 +18,10 @@
#include "qgscomposeritemwidget.h"
#include "qgscomposeritem.h"
#include "qgscomposermap.h"
#include "qgsatlascomposition.h"
#include "qgscomposition.h"
#include "qgspoint.h"
#include "qgsdatadefinedbutton.h"
#include <QColorDialog>
#include <QPen>

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

}

void QgsComposerItemBaseWidget::updateDataDefinedProperty()
{
//match data defined button to item's data defined property
QgsDataDefinedButton* ddButton = dynamic_cast<QgsDataDefinedButton*>( sender() );
if ( !ddButton )
{
return;
}
QgsComposerItem::DataDefinedProperty property = ddPropertyForWidget( ddButton );
if ( property == QgsComposerItem::NoProperty )
{
return;
}

//set the data defined property and refresh the item
setDataDefinedProperty( ddButton, property );
mItem->refreshDataDefinedProperty( property );
}

void QgsComposerItemBaseWidget::setDataDefinedProperty( const QgsDataDefinedButton *ddBtn, QgsComposerItem::DataDefinedProperty p )
{
if ( !mItem )
{
return;
}

const QMap< QString, QString >& map = ddBtn->definedProperty();
mItem->setDataDefinedProperty( p, map.value( "active" ).toInt(), map.value( "useexpr" ).toInt(), map.value( "expression" ), map.value( "field" ) );
}

QgsComposerItem::DataDefinedProperty QgsComposerItemBaseWidget::ddPropertyForWidget( QgsDataDefinedButton *widget )
{
Q_UNUSED( widget );

//base implementation, return no property
return QgsComposerItem::NoProperty;
}

QgsAtlasComposition* QgsComposerItemBaseWidget::atlasComposition() const
{
if ( !mItem )
Expand Down Expand Up @@ -98,6 +138,17 @@ QgsComposerItemWidget::QgsComposerItemWidget( QWidget* parent, QgsComposerItem*

connect( mTransparencySlider, SIGNAL( valueChanged( int ) ), mTransparencySpnBx, SLOT( setValue( int ) ) );
connect( mTransparencySpnBx, SIGNAL( valueChanged( int ) ), mTransparencySlider, SLOT( setValue( int ) ) );

//connect atlas signals to data defined buttons
QgsAtlasComposition* atlas = atlasComposition();
if ( atlas )
{
//repopulate data defined buttons if atlas layer changes
connect( atlas, SIGNAL( coverageLayerChanged( QgsVectorLayer* ) ),
this, SLOT( populateDataDefinedButtons() ) );
connect( atlas, SIGNAL( toggled( bool ) ), this, SLOT( populateDataDefinedButtons() ) );
}

}

QgsComposerItemWidget::QgsComposerItemWidget(): QgsComposerItemBaseWidget( 0, 0 )
Expand Down Expand Up @@ -449,6 +500,20 @@ void QgsComposerItemWidget::setValuesForGuiNonPositionElements()
mItemRotationSpinBox->blockSignals( false );
}

void QgsComposerItemWidget::populateDataDefinedButtons()
{
//QgsVectorLayer* vl = atlasCoverageLayer();

//block signals from data defined buttons

//initialise buttons to use atlas coverage layer

//initial state of controls - disable related controls when dd buttons are active

//unblock signals from data defined buttons

}

void QgsComposerItemWidget::setValuesForGuiElements()
{
if ( !mItem )
Expand All @@ -463,6 +528,7 @@ void QgsComposerItemWidget::setValuesForGuiElements()

setValuesForGuiPositionElements();
setValuesForGuiNonPositionElements();
populateDataDefinedButtons();
}

void QgsComposerItemWidget::on_mBlendModeCombo_currentIndexChanged( int index )
Expand Down
15 changes: 15 additions & 0 deletions src/app/composer/qgscomposeritemwidget.h
Expand Up @@ -23,6 +23,7 @@

class QgsComposerItem;
class QgsAtlasComposition;
class QgsDataDefinedButton;

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

protected slots:
/**Must be called when a data defined button changes*/
void updateDataDefinedProperty();

protected:
/**Sets a data defined property for the item from its current data defined button settings*/
void setDataDefinedProperty( const QgsDataDefinedButton *ddBtn, QgsComposerItem::DataDefinedProperty p );

/**Returns the data defined property corresponding to a data defined button widget*/
virtual QgsComposerItem::DataDefinedProperty ddPropertyForWidget( QgsDataDefinedButton* widget );

/**Returns the current atlas coverage layer (if set)*/
QgsVectorLayer* atlasCoverageLayer() const;

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

protected slots:
/**Initializes data defined buttons to current atlas coverage layer*/
void populateDataDefinedButtons();

private:
QgsComposerItemWidget();
// void changeItemTransparency( int value );
Expand Down

0 comments on commit be5aeac

Please sign in to comment.