Skip to content

Commit d6c7569

Browse files
committed
[FEATURE][composer] Data definable item frame and background colors
1 parent ad23240 commit d6c7569

9 files changed

Lines changed: 206 additions & 31 deletions

File tree

‎python/core/composer/qgscomposerobject.sip‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ class QgsComposerObject : QObject, QgsExpressionContextGenerator
3232
Transparency, /*!< item transparency */
3333
BlendMode, /*!< item blend mode */
3434
ExcludeFromExports, /*!< exclude item from exports */
35+
FrameColor, //!< Item frame color
36+
BackgroundColor, //!< Item background color
3537
//composer map
3638
MapRotation, /*!< map rotation */
3739
MapScale, /*!< map scale */

‎src/app/composer/qgscomposeritemwidget.cpp‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,10 @@ void QgsComposerItemWidget::populateDataDefinedButtons()
541541
QgsDataDefinedButtonV2::String, QgsDataDefinedButtonV2::blendModesDesc() );
542542
mConfigObject->registerDataDefinedButton( mExcludePrintsDDBtn, QgsComposerObject::ExcludeFromExports,
543543
QgsDataDefinedButtonV2::String, QgsDataDefinedButtonV2::boolDesc() );
544+
mConfigObject->registerDataDefinedButton( mItemFrameColorDDBtn, QgsComposerObject::FrameColor,
545+
QgsDataDefinedButtonV2::String, QgsDataDefinedButtonV2::colorAlphaDesc() );
546+
mConfigObject->registerDataDefinedButton( mItemBackgroundColorDDBtn, QgsComposerObject::BackgroundColor,
547+
QgsDataDefinedButtonV2::String, QgsDataDefinedButtonV2::colorAlphaDesc() );
544548
}
545549

546550
void QgsComposerItemWidget::setValuesForGuiElements()

‎src/core/composer/qgscomposeritem.cpp‎

Lines changed: 89 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ QgsComposerItem::QgsComposerItem( QgsComposition* composition, bool manageZValue
5454
, mFrame( false )
5555
, mBackground( true )
5656
, mBackgroundColor( QColor( 255, 255, 255, 255 ) )
57-
, mFrameJoinStyle( Qt::MiterJoin )
5857
, mItemPositionLocked( false )
5958
, mLastValidViewScaleFactor( -1 )
6059
, mItemRotation( 0 )
@@ -81,9 +80,9 @@ QgsComposerItem::QgsComposerItem( qreal x, qreal y, qreal width, qreal height, Q
8180
, mHAlignSnapItem( nullptr )
8281
, mVAlignSnapItem( nullptr )
8382
, mFrame( false )
83+
, mFrameColor( QColor( 0, 0, 0 ) )
8484
, mBackground( true )
8585
, mBackgroundColor( QColor( 255, 255, 255, 255 ) )
86-
, mFrameJoinStyle( Qt::MiterJoin )
8786
, mItemPositionLocked( false )
8887
, mLastValidViewScaleFactor( -1 )
8988
, mItemRotation( 0 )
@@ -107,9 +106,9 @@ void QgsComposerItem::init( const bool manageZValue )
107106
{
108107
setFlag( QGraphicsItem::ItemIsSelectable, true );
109108
//set default pen and brush
110-
setBrush( QBrush( QColor( 255, 255, 255, 255 ) ) );
111-
QPen defaultPen( QColor( 0, 0, 0 ) );
112-
defaultPen.setWidthF( 0.3 );
109+
setBrush( mBackgroundColor );
110+
QPen defaultPen( mFrameColor );
111+
defaultPen.setWidthF( mFrameWidth );
113112
defaultPen.setJoinStyle( mFrameJoinStyle );
114113
setPen( defaultPen );
115114
//let z-Value be managed by composition
@@ -192,7 +191,7 @@ bool QgsComposerItem::_writeXml( QDomElement& itemElem, QDomDocument& doc ) cons
192191
composerItemElem.setAttribute( QStringLiteral( "height" ), QString::number( rect().height() ) );
193192
composerItemElem.setAttribute( QStringLiteral( "positionMode" ), QString::number( static_cast< int >( mLastUsedPositionMode ) ) );
194193
composerItemElem.setAttribute( QStringLiteral( "zValue" ), QString::number( zValue() ) );
195-
composerItemElem.setAttribute( QStringLiteral( "outlineWidth" ), QString::number( pen().widthF() ) );
194+
composerItemElem.setAttribute( QStringLiteral( "outlineWidth" ), QString::number( mFrameWidth ) );
196195
composerItemElem.setAttribute( QStringLiteral( "frameJoinStyle" ), QgsSymbolLayerUtils::encodePenJoinStyle( mFrameJoinStyle ) );
197196
composerItemElem.setAttribute( QStringLiteral( "itemRotation" ), QString::number( mItemRotation ) );
198197
composerItemElem.setAttribute( QStringLiteral( "uuid" ), mUuid );
@@ -212,20 +211,18 @@ bool QgsComposerItem::_writeXml( QDomElement& itemElem, QDomDocument& doc ) cons
212211

213212
//frame color
214213
QDomElement frameColorElem = doc.createElement( QStringLiteral( "FrameColor" ) );
215-
QColor frameColor = pen().color();
216-
frameColorElem.setAttribute( QStringLiteral( "red" ), QString::number( frameColor.red() ) );
217-
frameColorElem.setAttribute( QStringLiteral( "green" ), QString::number( frameColor.green() ) );
218-
frameColorElem.setAttribute( QStringLiteral( "blue" ), QString::number( frameColor.blue() ) );
219-
frameColorElem.setAttribute( QStringLiteral( "alpha" ), QString::number( frameColor.alpha() ) );
214+
frameColorElem.setAttribute( QStringLiteral( "red" ), QString::number( mFrameColor.red() ) );
215+
frameColorElem.setAttribute( QStringLiteral( "green" ), QString::number( mFrameColor.green() ) );
216+
frameColorElem.setAttribute( QStringLiteral( "blue" ), QString::number( mFrameColor.blue() ) );
217+
frameColorElem.setAttribute( QStringLiteral( "alpha" ), QString::number( mFrameColor.alpha() ) );
220218
composerItemElem.appendChild( frameColorElem );
221219

222220
//background color
223221
QDomElement bgColorElem = doc.createElement( QStringLiteral( "BackgroundColor" ) );
224-
QColor bgColor = brush().color();
225-
bgColorElem.setAttribute( QStringLiteral( "red" ), QString::number( bgColor.red() ) );
226-
bgColorElem.setAttribute( QStringLiteral( "green" ), QString::number( bgColor.green() ) );
227-
bgColorElem.setAttribute( QStringLiteral( "blue" ), QString::number( bgColor.blue() ) );
228-
bgColorElem.setAttribute( QStringLiteral( "alpha" ), QString::number( bgColor.alpha() ) );
222+
bgColorElem.setAttribute( QStringLiteral( "red" ), QString::number( mBackgroundColor.red() ) );
223+
bgColorElem.setAttribute( QStringLiteral( "green" ), QString::number( mBackgroundColor.green() ) );
224+
bgColorElem.setAttribute( QStringLiteral( "blue" ), QString::number( mBackgroundColor.blue() ) );
225+
bgColorElem.setAttribute( QStringLiteral( "alpha" ), QString::number( mBackgroundColor.alpha() ) );
229226
composerItemElem.appendChild( bgColorElem );
230227

231228
//blend mode
@@ -335,6 +332,8 @@ bool QgsComposerItem::_readXml( const QDomElement& itemElem, const QDomDocument&
335332

336333
setZValue( itemElem.attribute( QStringLiteral( "zValue" ) ).toDouble() );
337334

335+
QgsExpressionContext context = createExpressionContext();
336+
338337
//pen
339338
QDomNodeList frameColorList = itemElem.elementsByTagName( QStringLiteral( "FrameColor" ) );
340339
if ( !frameColorList.isEmpty() )
@@ -353,10 +352,14 @@ bool QgsComposerItem::_readXml( const QDomElement& itemElem, const QDomDocument&
353352

354353
if ( redOk && greenOk && blueOk && alphaOk && widthOk )
355354
{
356-
QPen framePen( QColor( penRed, penGreen, penBlue, penAlpha ) );
357-
framePen.setWidthF( penWidth );
355+
mFrameColor = QColor( penRed, penGreen, penBlue, penAlpha );
356+
mFrameWidth = penWidth;
357+
QPen framePen( mFrameColor );
358+
framePen.setWidthF( mFrameWidth );
358359
framePen.setJoinStyle( mFrameJoinStyle );
359360
setPen( framePen );
361+
//apply any data defined settings
362+
refreshFrameColor( false, context );
360363
}
361364
}
362365

@@ -373,9 +376,11 @@ bool QgsComposerItem::_readXml( const QDomElement& itemElem, const QDomDocument&
373376
bgAlpha = bgColorElem.attribute( QStringLiteral( "alpha" ) ).toDouble( &alphaOk );
374377
if ( redOk && greenOk && blueOk && alphaOk )
375378
{
376-
QColor brushColor( bgRed, bgGreen, bgBlue, bgAlpha );
377-
setBackgroundColor( brushColor );
379+
mBackgroundColor = QColor( bgRed, bgGreen, bgBlue, bgAlpha );
380+
setBrush( QBrush( mBackgroundColor, Qt::SolidPattern ) );
378381
}
382+
//apply any data defined settings
383+
refreshBackgroundColor( false, context );
379384
}
380385

381386
//blend mode
@@ -407,26 +412,31 @@ void QgsComposerItem::setFrameEnabled( const bool drawFrame )
407412

408413
void QgsComposerItem::setFrameOutlineColor( const QColor &color )
409414
{
410-
QPen itemPen = pen();
411-
if ( itemPen.color() == color )
415+
if ( mFrameColor == color )
412416
{
413417
//no change
414418
return;
415419
}
416-
itemPen.setColor( color );
420+
mFrameColor = color;
421+
QPen itemPen = pen();
422+
itemPen.setColor( mFrameColor );
417423
setPen( itemPen );
424+
// apply any datadefined overrides
425+
QgsExpressionContext context = createExpressionContext();
426+
refreshFrameColor( true, context );
418427
emit frameChanged();
419428
}
420429

421430
void QgsComposerItem::setFrameOutlineWidth( const double outlineWidth )
422431
{
423-
QPen itemPen = pen();
424-
if ( qgsDoubleNear( itemPen.widthF(), outlineWidth ) )
432+
if ( qgsDoubleNear( mFrameWidth, outlineWidth ) )
425433
{
426434
//no change
427435
return;
428436
}
429-
itemPen.setWidthF( outlineWidth );
437+
mFrameWidth = outlineWidth;
438+
QPen itemPen = pen();
439+
itemPen.setWidthF( mFrameWidth );
430440
setPen( itemPen );
431441
emit frameChanged();
432442
}
@@ -844,6 +854,9 @@ void QgsComposerItem::setBackgroundColor( const QColor& backgroundColor )
844854
{
845855
mBackgroundColor = backgroundColor;
846856
setBrush( QBrush( mBackgroundColor, Qt::SolidPattern ) );
857+
// apply any datadefined overrides
858+
QgsExpressionContext context = createExpressionContext();
859+
refreshBackgroundColor( true, context );
847860
}
848861

849862
void QgsComposerItem::setBlendMode( const QPainter::CompositionMode blendMode )
@@ -897,6 +910,48 @@ void QgsComposerItem::refreshTransparency( const bool updateItem, const QgsExpre
897910
}
898911
}
899912

913+
void QgsComposerItem::refreshFrameColor( const bool updateItem, const QgsExpressionContext& context )
914+
{
915+
//data defined outline color set?
916+
bool ok = false;
917+
QColor frameColor = mProperties.valueAsColor( QgsComposerObject::FrameColor, context, mFrameColor, &ok );
918+
if ( ok )
919+
{
920+
QPen itemPen = pen();
921+
itemPen.setColor( frameColor );
922+
setPen( itemPen );
923+
}
924+
else
925+
{
926+
QPen itemPen = pen();
927+
itemPen.setColor( mFrameColor );
928+
setPen( itemPen );
929+
}
930+
if ( updateItem )
931+
{
932+
update();
933+
}
934+
}
935+
936+
void QgsComposerItem::refreshBackgroundColor( const bool updateItem, const QgsExpressionContext& context )
937+
{
938+
//data defined color set?
939+
bool ok = false;
940+
QColor backgroundColor = mProperties.valueAsColor( QgsComposerObject::BackgroundColor, context, mBackgroundColor, &ok );
941+
if ( ok )
942+
{
943+
setBrush( QBrush( backgroundColor, Qt::SolidPattern ) );
944+
}
945+
else
946+
{
947+
setBrush( QBrush( mBackgroundColor, Qt::SolidPattern ) );
948+
}
949+
if ( updateItem )
950+
{
951+
update();
952+
}
953+
}
954+
900955
void QgsComposerItem::setEffectsEnabled( const bool effectsEnabled )
901956
{
902957
//enable or disable the QgsComposerEffect applied to this item
@@ -1087,6 +1142,14 @@ void QgsComposerItem::refreshDataDefinedProperty( const QgsComposerObject::DataD
10871142
{
10881143
refreshBlendMode( *evalContext );
10891144
}
1145+
if ( property == QgsComposerObject::FrameColor || property == QgsComposerObject::AllProperties )
1146+
{
1147+
refreshFrameColor( false, *evalContext );
1148+
}
1149+
if ( property == QgsComposerObject::BackgroundColor || property == QgsComposerObject::AllProperties )
1150+
{
1151+
refreshBackgroundColor( false, *evalContext );
1152+
}
10901153
if ( property == QgsComposerObject::ExcludeFromExports || property == QgsComposerObject::AllProperties )
10911154
{
10921155
bool exclude = mExcludeFromExports;

‎src/core/composer/qgscomposeritem.h‎

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ class CORE_EXPORT QgsComposerItem: public QgsComposerObject, public QGraphicsRec
260260
* @see frameJoinStyle
261261
* @see setFrameOutlineColor
262262
*/
263-
QColor frameOutlineColor() const { return pen().color(); }
263+
QColor frameOutlineColor() const { return mFrameColor; }
264264

265265
/** Sets frame outline width
266266
* @param outlineWidth new width for outline frame
@@ -280,7 +280,7 @@ class CORE_EXPORT QgsComposerItem: public QgsComposerObject, public QGraphicsRec
280280
* @see frameJoinStyle
281281
* @see frameOutlineColor
282282
*/
283-
double frameOutlineWidth() const { return pen().widthF(); }
283+
double frameOutlineWidth() const { return mFrameWidth; }
284284

285285
/** Returns the join style used for drawing the item's frame
286286
* @returns Join style for outline frame
@@ -564,12 +564,17 @@ class CORE_EXPORT QgsComposerItem: public QgsComposerObject, public QGraphicsRec
564564

565565
//! True if item fram needs to be painted
566566
bool mFrame;
567+
//! Item frame color
568+
QColor mFrameColor;
569+
//! Item frame width
570+
double mFrameWidth = 0.3;
571+
//! Frame join style
572+
Qt::PenJoinStyle mFrameJoinStyle = Qt::MiterJoin;
573+
567574
//! True if item background needs to be painted
568575
bool mBackground;
569576
//! Background color
570577
QColor mBackgroundColor;
571-
//! Frame join style
572-
Qt::PenJoinStyle mFrameJoinStyle;
573578

574579
/** True if item position and size cannot be changed with mouse move
575580
*/
@@ -706,6 +711,20 @@ class CORE_EXPORT QgsComposerItem: public QgsComposerObject, public QGraphicsRec
706711
*/
707712
void refreshTransparency( const bool updateItem = true, const QgsExpressionContext &context = QgsExpressionContext() );
708713

714+
/** Refresh item's frame color, considering data defined transparency
715+
* @param updateItem set to false to prevent the item being automatically updated
716+
* after the frame color is set
717+
* @param context expression context for evaulating data defined transparency
718+
*/
719+
void refreshFrameColor( const bool updateItem = true, const QgsExpressionContext &context = QgsExpressionContext() );
720+
721+
/** Refresh item's transparency, considering data defined transparency
722+
* @param updateItem set to false to prevent the item being automatically updated
723+
* after the background color is set
724+
* @param context expression context for evaulating data defined transparency
725+
*/
726+
void refreshBackgroundColor( const bool updateItem = true, const QgsExpressionContext &context = QgsExpressionContext() );
727+
709728
/** Refresh item's blend mode, considering data defined blend mode
710729
* @note this method was added in version 2.5
711730
*/

‎src/core/composer/qgscomposerobject.cpp‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ const QgsPropertyDefinition QgsComposerObject::sPropertyNameMap
4040
{ QgsComposerObject::Transparency, "dataDefinedTransparency" },
4141
{ QgsComposerObject::BlendMode, "dataDefinedBlendMode" },
4242
{ QgsComposerObject::ExcludeFromExports, "dataDefinedExcludeExports"},
43+
{ QgsComposerObject::FrameColor, "dataDefinedFrameColor"},
44+
{ QgsComposerObject::BackgroundColor, "dataDefinedBackgroundColor"},
4345
{ QgsComposerObject::MapRotation, "dataDefinedMapRotation" },
4446
{ QgsComposerObject::MapScale, "dataDefinedMapScale" },
4547
{ QgsComposerObject::MapXMin, "dataDefinedMapXMin" },

‎src/core/composer/qgscomposerobject.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ class CORE_EXPORT QgsComposerObject: public QObject, public QgsExpressionContext
5959
Transparency, //!< Item transparency
6060
BlendMode, //!< Item blend mode
6161
ExcludeFromExports, //!< Exclude item from exports
62+
FrameColor, //!< Item frame color
63+
BackgroundColor, //!< Item background color
6264
//composer map
6365
MapRotation, //!< Map rotation
6466
MapScale, //!< Map scale

‎src/ui/composer/qgscomposeritemwidgetbase.ui‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<x>0</x>
88
<y>0</y>
99
<width>290</width>
10-
<height>847</height>
10+
<height>1017</height>
1111
</rect>
1212
</property>
1313
<property name="windowTitle">
@@ -453,6 +453,13 @@
453453
</property>
454454
</spacer>
455455
</item>
456+
<item>
457+
<widget class="QgsDataDefinedButtonV2" name="mItemFrameColorDDBtn">
458+
<property name="text">
459+
<string>...</string>
460+
</property>
461+
</widget>
462+
</item>
456463
</layout>
457464
</item>
458465
<item row="1" column="0">
@@ -572,6 +579,13 @@
572579
</property>
573580
</spacer>
574581
</item>
582+
<item>
583+
<widget class="QgsDataDefinedButtonV2" name="mItemBackgroundColorDDBtn">
584+
<property name="text">
585+
<string>...</string>
586+
</property>
587+
</widget>
588+
</item>
575589
</layout>
576590
</item>
577591
</layout>
@@ -816,10 +830,12 @@
816830
<tabstop>mItemRotationDDBtn</tabstop>
817831
<tabstop>mFrameGroupBox</tabstop>
818832
<tabstop>mFrameColorButton</tabstop>
833+
<tabstop>mItemFrameColorDDBtn</tabstop>
819834
<tabstop>mOutlineWidthSpinBox</tabstop>
820835
<tabstop>mFrameJoinStyleCombo</tabstop>
821836
<tabstop>mBackgroundGroupBox</tabstop>
822837
<tabstop>mBackgroundColorButton</tabstop>
838+
<tabstop>mItemBackgroundColorDDBtn</tabstop>
823839
<tabstop>groupBox</tabstop>
824840
<tabstop>mItemIdLineEdit</tabstop>
825841
<tabstop>groupRendering</tabstop>

‎tests/src/python/CMakeLists.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ ADD_PYTHON_TEST(PyQgsColorScheme test_qgscolorscheme.py)
2525
ADD_PYTHON_TEST(PyQgsColorSchemeRegistry test_qgscolorschemeregistry.py)
2626
ADD_PYTHON_TEST(PyQgsComposerEffects test_qgscomposereffects.py)
2727
ADD_PYTHON_TEST(PyQgsComposerHtml test_qgscomposerhtml.py)
28+
ADD_PYTHON_TEST(PyQgsComposerItem test_qgscomposeritem.py)
2829
ADD_PYTHON_TEST(PyQgsComposerLabel test_qgscomposerlabel.py)
2930
ADD_PYTHON_TEST(PyQgsComposerLegend test_qgscomposerlegend.py)
3031
ADD_PYTHON_TEST(PyQgsComposerMap test_qgscomposermap.py)

0 commit comments

Comments
 (0)