Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[layouts] Correctly set data defined html url or attribute table
source property on the parent multiframe object, not the child frame

Fixes #41590
Fixes #36647

(cherry picked from commit 8324317)
  • Loading branch information
nyalldawson committed Mar 19, 2021
1 parent 2ac8d09 commit 03d8ed3
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 1 deletion.
12 changes: 12 additions & 0 deletions python/core/auto_generated/layout/qgslayoutobject.sip.in
Expand Up @@ -185,6 +185,18 @@ A base class for objects which belong to a layout.
static const QgsPropertiesDefinition &propertyDefinitions();
%Docstring
Returns the layout object property definitions.
%End

static bool propertyAssociatesWithParentMultiframe( DataDefinedProperty property );
%Docstring
Returns ``True`` if the specified ``property`` key is normally associated with the parent
QgsLayoutMultiFrame object instead of a child QgsLayoutFrame object.

While some properties like QgsLayoutObject.DataDefinedProperty.PositionX and QgsLayoutObject.DataDefinedProperty.ItemWidth
are typically associated with a direct QgsLayoutItem subclass (including QgsLayoutFrame objects), other properties
are instead associated with a QgsLayoutMultiFrame object (such as QgsLayoutObject.DataDefinedProperty.SourceUrl or QgsLayoutObject.DataDefinedProperty.AttributeTableSourceLayer).

.. versionadded:: 3.18.1
%End

explicit QgsLayoutObject( QgsLayout *layout );
Expand Down
74 changes: 74 additions & 0 deletions src/core/layout/qgslayoutobject.cpp
Expand Up @@ -110,6 +110,80 @@ const QgsPropertiesDefinition &QgsLayoutObject::propertyDefinitions()
return sPropertyDefinitions;
}

bool QgsLayoutObject::propertyAssociatesWithParentMultiframe( QgsLayoutObject::DataDefinedProperty property )
{
switch ( property )
{
case QgsLayoutObject::SourceUrl:
case QgsLayoutObject::AttributeTableSourceLayer:
return true;

case QgsLayoutObject::NoProperty:
case QgsLayoutObject::AllProperties:
case QgsLayoutObject::TestProperty:
case QgsLayoutObject::PresetPaperSize:
case QgsLayoutObject::PaperWidth:
case QgsLayoutObject::PaperHeight:
case QgsLayoutObject::NumPages:
case QgsLayoutObject::PaperOrientation:
case QgsLayoutObject::PageNumber:
case QgsLayoutObject::PositionX:
case QgsLayoutObject::PositionY:
case QgsLayoutObject::ItemWidth:
case QgsLayoutObject::ItemHeight:
case QgsLayoutObject::ItemRotation:
case QgsLayoutObject::Transparency:
case QgsLayoutObject::Opacity:
case QgsLayoutObject::BlendMode:
case QgsLayoutObject::ExcludeFromExports:
case QgsLayoutObject::FrameColor:
case QgsLayoutObject::BackgroundColor:
case QgsLayoutObject::MapRotation:
case QgsLayoutObject::MapScale:
case QgsLayoutObject::MapXMin:
case QgsLayoutObject::MapYMin:
case QgsLayoutObject::MapXMax:
case QgsLayoutObject::MapYMax:
case QgsLayoutObject::MapAtlasMargin:
case QgsLayoutObject::MapLayers:
case QgsLayoutObject::MapStylePreset:
case QgsLayoutObject::MapLabelMargin:
case QgsLayoutObject::MapGridEnabled:
case QgsLayoutObject::MapGridIntervalX:
case QgsLayoutObject::MapGridIntervalY:
case QgsLayoutObject::MapGridOffsetX:
case QgsLayoutObject::MapGridOffsetY:
case QgsLayoutObject::MapGridFrameSize:
case QgsLayoutObject::MapGridFrameMargin:
case QgsLayoutObject::MapGridLabelDistance:
case QgsLayoutObject::MapGridCrossSize:
case QgsLayoutObject::MapGridFrameLineThickness:
case QgsLayoutObject::MapGridAnnotationDisplayLeft:
case QgsLayoutObject::MapGridAnnotationDisplayRight:
case QgsLayoutObject::MapGridAnnotationDisplayTop:
case QgsLayoutObject::MapGridAnnotationDisplayBottom:
case QgsLayoutObject::MapGridFrameDivisionsLeft:
case QgsLayoutObject::MapGridFrameDivisionsRight:
case QgsLayoutObject::MapGridFrameDivisionsTop:
case QgsLayoutObject::MapGridFrameDivisionsBottom:
case QgsLayoutObject::PictureSource:
case QgsLayoutObject::PictureSvgBackgroundColor:
case QgsLayoutObject::PictureSvgStrokeColor:
case QgsLayoutObject::PictureSvgStrokeWidth:
case QgsLayoutObject::LegendTitle:
case QgsLayoutObject::LegendColumnCount:
case QgsLayoutObject::ScalebarFillColor:
case QgsLayoutObject::ScalebarFillColor2:
case QgsLayoutObject::ScalebarLineColor:
case QgsLayoutObject::ScalebarLineWidth:
case QgsLayoutObject::MapCrs:
case QgsLayoutObject::StartDateTime:
case QgsLayoutObject::EndDateTime:
return false;
}
return false;
}

QgsLayoutObject::QgsLayoutObject( QgsLayout *layout )
: QObject( nullptr )
, mLayout( layout )
Expand Down
12 changes: 12 additions & 0 deletions src/core/layout/qgslayoutobject.h
Expand Up @@ -220,6 +220,18 @@ class CORE_EXPORT QgsLayoutObject: public QObject, public QgsExpressionContextGe
*/
static const QgsPropertiesDefinition &propertyDefinitions();

/**
* Returns TRUE if the specified \a property key is normally associated with the parent
* QgsLayoutMultiFrame object instead of a child QgsLayoutFrame object.
*
* While some properties like QgsLayoutObject::DataDefinedProperty::PositionX and QgsLayoutObject::DataDefinedProperty::ItemWidth
* are typically associated with a direct QgsLayoutItem subclass (including QgsLayoutFrame objects), other properties
* are instead associated with a QgsLayoutMultiFrame object (such as QgsLayoutObject::DataDefinedProperty::SourceUrl or QgsLayoutObject::DataDefinedProperty::AttributeTableSourceLayer).
*
* \since QGIS 3.18.1
*/
static bool propertyAssociatesWithParentMultiframe( DataDefinedProperty property );

/**
* Constructor for QgsLayoutObject, with the specified parent \a layout.
* \note While ownership of a QgsLayoutObject is not passed to the layout,
Expand Down
21 changes: 20 additions & 1 deletion src/gui/layout/qgslayoutitemwidget.cpp
Expand Up @@ -26,6 +26,7 @@
#include "qgsfontbutton.h"
#include "qgslayoutdesignerinterface.h"
#include "qgslayoutpagecollection.h"
#include "qgslayoutmultiframe.h"
#include <QButtonGroup>

//
Expand Down Expand Up @@ -65,8 +66,26 @@ void QgsLayoutConfigObject::updateDataDefinedProperty()
return;
}

const bool propertyAssociatesWithMultiFrame = QgsLayoutObject::propertyAssociatesWithParentMultiframe( key );

//set the data defined property and refresh the item
if ( mLayoutObject )
if ( propertyAssociatesWithMultiFrame )
{
if ( QgsLayoutFrame *frame = dynamic_cast< QgsLayoutFrame * >( mLayoutObject.data() ) )
{
if ( QgsLayoutMultiFrame *multiFrame = frame->multiFrame() )
{
multiFrame->dataDefinedProperties().setProperty( key, ddButton->toProperty() );
multiFrame->refresh();
}
}
else if ( QgsLayoutMultiFrame *multiFrame = dynamic_cast< QgsLayoutMultiFrame * >( mLayoutObject.data() ) )
{
multiFrame->dataDefinedProperties().setProperty( key, ddButton->toProperty() );
multiFrame->refresh();
}
}
else if ( mLayoutObject )
{
mLayoutObject->dataDefinedProperties().setProperty( key, ddButton->toProperty() );
mLayoutObject->refresh();
Expand Down

0 comments on commit 03d8ed3

Please sign in to comment.