Port data defined item position and size

This commit is contained in:
Nyall Dawson 2017-07-10 13:39:28 +10:00
parent 3f0a0cb063
commit 6fd06983a6
4 changed files with 368 additions and 11 deletions

View File

@ -91,6 +91,7 @@ class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem
.. seealso:: minimumSize()
.. seealso:: fixedSize()
.. seealso:: attemptMove()
.. seealso:: sizeWithUnits()
%End
virtual void attemptMove( const QgsLayoutPoint &point );
@ -102,6 +103,7 @@ class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem
as data defined item position may override the specified value.
.. seealso:: attemptResize()
.. seealso:: referencePoint()
.. seealso:: positionWithUnits()
%End
QgsLayoutPoint positionWithUnits() const;
@ -111,9 +113,18 @@ class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem
left corner of the item.
.. seealso:: attemptMove()
.. seealso:: referencePoint()
.. seealso:: sizeWithUnits()
:rtype: QgsLayoutPoint
%End
QgsLayoutSize sizeWithUnits() const;
%Docstring
Returns the item's current size, including units.
.. seealso:: attemptResize()
.. seealso:: positionWithUnits()
:rtype: QgsLayoutSize
%End
public slots:
virtual void refresh();
@ -123,6 +134,14 @@ class QgsLayoutItem : QgsLayoutObject, QGraphicsRectItem
recalculation of its position and size.
%End
virtual void refreshDataDefinedProperty( const QgsLayoutObject::DataDefinedProperty property = QgsLayoutObject::AllProperties );
%Docstring
Refreshes a data defined ``property`` for the item by reevaluating the property's value
and redrawing the item with this new value. If ``property`` is set to
QgsLayoutObject.AllProperties then all data defined properties for the item will be
refreshed.
%End
protected:
virtual void drawDebugRect( QPainter *painter );

View File

@ -67,6 +67,7 @@ void QgsLayoutItem::setReferencePoint( const QgsLayoutItem::ReferencePoint &poin
//also need to adjust stored position
QPointF positionReferencePointLayoutUnits = adjustPointForReferencePosition( pos(), QSizeF( -rect().width(), -rect().height() ) );
mItemPosition = mLayout->convertFromLayoutUnits( positionReferencePointLayoutUnits, mItemPosition.units() );
refreshItemPosition();
}
void QgsLayoutItem::attemptResize( const QgsLayoutSize &size )
@ -78,7 +79,8 @@ void QgsLayoutItem::attemptResize( const QgsLayoutSize &size )
return;
}
QSizeF targetSizeLayoutUnits = mLayout->convertToLayoutUnits( size );
QgsLayoutSize evaluatedSize = applyDataDefinedSize( size );
QSizeF targetSizeLayoutUnits = mLayout->convertToLayoutUnits( evaluatedSize );
QSizeF actualSizeLayoutUnits = applyMinimumSize( targetSizeLayoutUnits );
actualSizeLayoutUnits = applyFixedSize( actualSizeLayoutUnits );
@ -103,27 +105,71 @@ void QgsLayoutItem::attemptMove( const QgsLayoutPoint &point )
return;
}
QPointF targetPointLayoutUnits = mLayout->convertToLayoutUnits( point );
//TODO - apply data defined position here
targetPointLayoutUnits = adjustPointForReferencePosition( targetPointLayoutUnits, rect().size() );
QPointF actualPointLayoutUnits = targetPointLayoutUnits;
if ( actualPointLayoutUnits == pos() )
QgsLayoutPoint evaluatedPoint = applyDataDefinedPosition( point );
QPointF evaluatedPointLayoutUnits = mLayout->convertToLayoutUnits( evaluatedPoint );
QPointF topLeftPointLayoutUnits = adjustPointForReferencePosition( evaluatedPointLayoutUnits, rect().size() );
if ( topLeftPointLayoutUnits == pos() && point.units() == mItemPosition.units() )
{
//TODO - add test for second condition
return;
}
QgsLayoutPoint actualPointTargetUnits = mLayout->convertFromLayoutUnits( actualPointLayoutUnits, point.units() );
mItemPosition = actualPointTargetUnits;
QgsLayoutPoint referencePointTargetUnits = mLayout->convertFromLayoutUnits( evaluatedPointLayoutUnits, point.units() );
mItemPosition = referencePointTargetUnits;
setPos( targetPointLayoutUnits );
setPos( topLeftPointLayoutUnits );
}
QgsLayoutPoint QgsLayoutItem::applyDataDefinedPosition( const QgsLayoutPoint &position )
{
if ( !mLayout )
{
return position;
}
QgsExpressionContext context = createExpressionContext();
double evaluatedX = mDataDefinedProperties.valueAsDouble( QgsLayoutObject::PositionX, context, position.x() );
double evaluatedY = mDataDefinedProperties.valueAsDouble( QgsLayoutObject::PositionY, context, position.y() );
return QgsLayoutPoint( evaluatedX, evaluatedY, position.units() );
}
QgsLayoutSize QgsLayoutItem::applyDataDefinedSize( const QgsLayoutSize &size )
{
if ( !mLayout )
{
return size;
}
QgsExpressionContext context = createExpressionContext();
double evaluatedWidth = mDataDefinedProperties.valueAsDouble( QgsLayoutObject::ItemWidth, context, size.width() );
double evaluatedHeight = mDataDefinedProperties.valueAsDouble( QgsLayoutObject::ItemHeight, context, size.height() );
return QgsLayoutSize( evaluatedWidth, evaluatedHeight, size.units() );
}
void QgsLayoutItem::refreshDataDefinedProperty( const QgsLayoutObject::DataDefinedProperty property )
{
//update data defined properties and update item to match
//evaluate width and height first, since they may affect position if non-top-left reference point set
if ( property == QgsLayoutObject::ItemWidth || property == QgsLayoutObject::ItemHeight ||
property == QgsLayoutObject::AllProperties )
{
refreshItemSize();
}
if ( property == QgsLayoutObject::PositionX || property == QgsLayoutObject::PositionY ||
property == QgsLayoutObject::AllProperties )
{
refreshItemPosition();
}
}
void QgsLayoutItem::refresh()
{
QgsLayoutObject::refresh();
refreshItemSize();
refreshItemPosition();
refreshDataDefinedProperty();
}
void QgsLayoutItem::drawDebugRect( QPainter *painter )

View File

@ -105,6 +105,7 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
* \see minimumSize()
* \see fixedSize()
* \see attemptMove()
* \see sizeWithUnits()
*/
virtual void attemptResize( const QgsLayoutSize &size );
@ -116,6 +117,7 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
* as data defined item position may override the specified value.
* \see attemptResize()
* \see referencePoint()
* \see positionWithUnits()
*/
virtual void attemptMove( const QgsLayoutPoint &point );
@ -125,9 +127,17 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
* left corner of the item.
* \see attemptMove()
* \see referencePoint()
* \see sizeWithUnits()
*/
QgsLayoutPoint positionWithUnits() const { return mItemPosition; }
/**
* Returns the item's current size, including units.
* \see attemptResize()
* \see positionWithUnits()
*/
QgsLayoutSize sizeWithUnits() const { return mItemSize; }
public slots:
/**
@ -136,6 +146,14 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
*/
void refresh() override;
/**
* Refreshes a data defined \a property for the item by reevaluating the property's value
* and redrawing the item with this new value. If \a property is set to
* QgsLayoutObject::AllProperties then all data defined properties for the item will be
* refreshed.
*/
virtual void refreshDataDefinedProperty( const QgsLayoutObject::DataDefinedProperty property = QgsLayoutObject::AllProperties );
protected:
/** Draws a debugging rectangle of the item's current bounds within the specified
@ -205,6 +223,8 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
QSizeF applyMinimumSize( const QSizeF &targetSize );
QSizeF applyFixedSize( const QSizeF &targetSize );
QgsLayoutPoint applyDataDefinedPosition( const QgsLayoutPoint &position );
QgsLayoutSize applyDataDefinedSize( const QgsLayoutSize &size );
friend class TestQgsLayoutItem;
};

View File

@ -49,6 +49,10 @@ class TestQgsLayoutItem: public QObject
void minSize();
void move();
void positionWithUnits();
void sizeWithUnits();
void dataDefinedPosition();
void dataDefinedSize();
void combinedDataDefinedPositionAndSize();
private:
@ -334,6 +338,274 @@ void TestQgsLayoutItem::positionWithUnits()
QCOMPARE( item->positionWithUnits().units(), QgsUnitTypes::LayoutPixels );
}
void TestQgsLayoutItem::sizeWithUnits()
{
QgsProject p;
QgsLayout l( &p );
TestItem *item = new TestItem( &l );
item->attemptResize( QgsLayoutSize( 60.0, 15.0, QgsUnitTypes::LayoutMillimeters ) );
QCOMPARE( item->sizeWithUnits().width(), 60.0 );
QCOMPARE( item->sizeWithUnits().height(), 15.0 );
QCOMPARE( item->sizeWithUnits().units(), QgsUnitTypes::LayoutMillimeters );
item->attemptResize( QgsLayoutSize( 50.0, 100.0, QgsUnitTypes::LayoutPixels ) );
QCOMPARE( item->sizeWithUnits().width(), 50.0 );
QCOMPARE( item->sizeWithUnits().height(), 100.0 );
QCOMPARE( item->sizeWithUnits().units(), QgsUnitTypes::LayoutPixels );
delete item;
}
void TestQgsLayoutItem::dataDefinedPosition()
{
QgsProject p;
QgsLayout l( &p );
//test setting data defined position
TestItem *item = new TestItem( &l );
l.setUnits( QgsUnitTypes::LayoutMillimeters );
item->attemptMove( QgsLayoutPoint( 6.0, 1.50, QgsUnitTypes::LayoutCentimeters ) );
item->attemptResize( QgsLayoutSize( 2.0, 4.0, QgsUnitTypes::LayoutCentimeters ) );
// position x
item->dataDefinedProperties().setProperty( QgsLayoutObject::PositionX, QgsProperty::fromExpression( QStringLiteral( "4+7" ) ) );
item->refreshDataDefinedProperty( QgsLayoutObject::PositionX );
QCOMPARE( item->positionWithUnits().x(), 11.0 );
QCOMPARE( item->positionWithUnits().units(), QgsUnitTypes::LayoutCentimeters );
QCOMPARE( item->pos().x(), 110.0 ); //mm
//position y
item->dataDefinedProperties().setProperty( QgsLayoutObject::PositionY, QgsProperty::fromExpression( QStringLiteral( "2+3" ) ) );
item->refreshDataDefinedProperty( QgsLayoutObject::PositionY );
QCOMPARE( item->positionWithUnits().y(), 5.0 );
QCOMPARE( item->positionWithUnits().units(), QgsUnitTypes::LayoutCentimeters );
QCOMPARE( item->pos().y(), 50.0 ); //mm
//refreshPosition should also respect data defined positioning
item->setPos( 0, 0 );
item->dataDefinedProperties().setProperty( QgsLayoutObject::PositionX, QgsProperty::fromExpression( QStringLiteral( "4+8" ) ) );
item->dataDefinedProperties().setProperty( QgsLayoutObject::PositionY, QgsProperty::fromExpression( QStringLiteral( "2+4" ) ) );
item->refreshItemPosition();
QCOMPARE( item->positionWithUnits().x(), 12.0 );
QCOMPARE( item->positionWithUnits().y(), 6.0 );
QCOMPARE( item->positionWithUnits().units(), QgsUnitTypes::LayoutCentimeters );
QCOMPARE( item->pos().x(), 120.0 ); //mm
QCOMPARE( item->pos().y(), 60.0 ); //mm
//also check that data defined position overrides when attempting to move
item->attemptMove( QgsLayoutPoint( 6.0, 1.50, QgsUnitTypes::LayoutCentimeters ) );
QCOMPARE( item->positionWithUnits().x(), 12.0 );
QCOMPARE( item->positionWithUnits().y(), 6.0 );
QCOMPARE( item->positionWithUnits().units(), QgsUnitTypes::LayoutCentimeters );
QCOMPARE( item->pos().x(), 120.0 ); //mm
QCOMPARE( item->pos().y(), 60.0 ); //mm
//restriction only for x position
item->dataDefinedProperties().setProperty( QgsLayoutObject::PositionX, QgsProperty::fromExpression( QStringLiteral( "4+8" ) ) );
item->dataDefinedProperties().setProperty( QgsLayoutObject::PositionY, QgsProperty() );
item->attemptMove( QgsLayoutPoint( 6.0, 1.5, QgsUnitTypes::LayoutCentimeters ) );
QCOMPARE( item->positionWithUnits().x(), 12.0 );
QCOMPARE( item->positionWithUnits().y(), 1.5 );
QCOMPARE( item->positionWithUnits().units(), QgsUnitTypes::LayoutCentimeters );
QCOMPARE( item->pos().x(), 120.0 ); //mm
QCOMPARE( item->pos().y(), 15.0 ); //mm
//restriction only for y position
item->dataDefinedProperties().setProperty( QgsLayoutObject::PositionX, QgsProperty() );
item->dataDefinedProperties().setProperty( QgsLayoutObject::PositionY, QgsProperty::fromExpression( QStringLiteral( "2+4" ) ) );
item->attemptMove( QgsLayoutPoint( 7.0, 1.5, QgsUnitTypes::LayoutCentimeters ) );
QCOMPARE( item->positionWithUnits().x(), 7.0 );
QCOMPARE( item->positionWithUnits().y(), 6.0 );
QCOMPARE( item->positionWithUnits().units(), QgsUnitTypes::LayoutCentimeters );
QCOMPARE( item->pos().x(), 70.0 ); //mm
QCOMPARE( item->pos().y(), 60.0 ); //mm
//check change of units should apply to data defined position
item->dataDefinedProperties().setProperty( QgsLayoutObject::PositionX, QgsProperty::fromExpression( QStringLiteral( "4+8" ) ) );
item->dataDefinedProperties().setProperty( QgsLayoutObject::PositionY, QgsProperty::fromExpression( QStringLiteral( "2+4" ) ) );
//first set to same as existing position, but with different units
item->attemptMove( QgsLayoutPoint( 120.0, 60.0, QgsUnitTypes::LayoutMillimeters ) );
//data defined position should utilize new units
QCOMPARE( item->positionWithUnits().x(), 12.0 ); //mm
QCOMPARE( item->positionWithUnits().y(), 6.0 ); //mm
QCOMPARE( item->positionWithUnits().units(), QgsUnitTypes::LayoutMillimeters );
QCOMPARE( item->pos().x(), 12.0 ); //mm
QCOMPARE( item->pos().y(), 6.0 ); //mm
//test that data defined position applies to item's reference point
item->attemptMove( QgsLayoutPoint( 12.0, 6.0, QgsUnitTypes::LayoutCentimeters ) );
item->setReferencePoint( QgsLayoutItem::LowerRight );
QCOMPARE( item->positionWithUnits().x(), 12.0 ); //cm
QCOMPARE( item->positionWithUnits().y(), 6.0 ); //cm
QCOMPARE( item->positionWithUnits().units(), QgsUnitTypes::LayoutCentimeters );
QCOMPARE( item->pos().x(), 100.0 ); //mm
QCOMPARE( item->pos().y(), 20.0 ); //mm
//also check setting data defined position AFTER setting reference point
item->setPos( 0, 0 );
item->dataDefinedProperties().setProperty( QgsLayoutObject::PositionX, QgsProperty::fromExpression( QStringLiteral( "6+10" ) ) );
item->dataDefinedProperties().setProperty( QgsLayoutObject::PositionY, QgsProperty::fromExpression( QStringLiteral( "2+6" ) ) );
item->refreshItemPosition();
QCOMPARE( item->positionWithUnits().x(), 16.0 ); //cm
QCOMPARE( item->positionWithUnits().y(), 8.0 ); //cm
QCOMPARE( item->positionWithUnits().units(), QgsUnitTypes::LayoutCentimeters );
QCOMPARE( item->pos().x(), 140.0 ); //mm
QCOMPARE( item->pos().y(), 40.0 ); //mm
delete item;
}
void TestQgsLayoutItem::dataDefinedSize()
{
QgsProject p;
QgsLayout l( &p );
//test setting data defined size
TestItem *item = new TestItem( &l );
l.setUnits( QgsUnitTypes::LayoutMillimeters );
item->attemptMove( QgsLayoutPoint( 6.0, 1.50, QgsUnitTypes::LayoutCentimeters ) );
item->attemptResize( QgsLayoutSize( 2.0, 4.0, QgsUnitTypes::LayoutCentimeters ) );
//width
item->dataDefinedProperties().setProperty( QgsLayoutObject::ItemWidth, QgsProperty::fromExpression( QStringLiteral( "4+7" ) ) );
item->refreshDataDefinedProperty( QgsLayoutObject::ItemWidth );
QCOMPARE( item->sizeWithUnits().width(), 11.0 );
QCOMPARE( item->sizeWithUnits().units(), QgsUnitTypes::LayoutCentimeters );
QCOMPARE( item->rect().width(), 110.0 ); //mm
//height
item->dataDefinedProperties().setProperty( QgsLayoutObject::ItemHeight, QgsProperty::fromExpression( QStringLiteral( "2+3" ) ) );
item->refreshDataDefinedProperty( QgsLayoutObject::ItemHeight );
QCOMPARE( item->sizeWithUnits().height(), 5.0 );
QCOMPARE( item->sizeWithUnits().units(), QgsUnitTypes::LayoutCentimeters );
QCOMPARE( item->rect().height(), 50.0 ); //mm
//refreshSize should also respect data defined size
item->setRect( 0.0, 0.0, 9.0, 8.0 );
item->dataDefinedProperties().setProperty( QgsLayoutObject::ItemWidth, QgsProperty::fromExpression( QStringLiteral( "4+8" ) ) );
item->dataDefinedProperties().setProperty( QgsLayoutObject::ItemHeight, QgsProperty::fromExpression( QStringLiteral( "2+4" ) ) );
item->refreshItemSize();
QCOMPARE( item->sizeWithUnits().width(), 12.0 );
QCOMPARE( item->sizeWithUnits().height(), 6.0 );
QCOMPARE( item->sizeWithUnits().units(), QgsUnitTypes::LayoutCentimeters );
QCOMPARE( item->rect().width(), 120.0 ); //mm
QCOMPARE( item->rect().height(), 60.0 ); //mm
//also check that data defined size overrides when attempting to resize
item->attemptResize( QgsLayoutSize( 6.0, 1.50, QgsUnitTypes::LayoutCentimeters ) );
QCOMPARE( item->sizeWithUnits().width(), 12.0 );
QCOMPARE( item->sizeWithUnits().height(), 6.0 );
QCOMPARE( item->sizeWithUnits().units(), QgsUnitTypes::LayoutCentimeters );
QCOMPARE( item->rect().width(), 120.0 ); //mm
QCOMPARE( item->rect().height(), 60.0 ); //mm
//restriction only for width
item->dataDefinedProperties().setProperty( QgsLayoutObject::ItemWidth, QgsProperty::fromExpression( QStringLiteral( "4+8" ) ) );
item->dataDefinedProperties().setProperty( QgsLayoutObject::ItemHeight, QgsProperty() );
item->attemptResize( QgsLayoutSize( 6.0, 1.50, QgsUnitTypes::LayoutCentimeters ) );
QCOMPARE( item->sizeWithUnits().width(), 12.0 );
QCOMPARE( item->sizeWithUnits().height(), 1.5 );
QCOMPARE( item->sizeWithUnits().units(), QgsUnitTypes::LayoutCentimeters );
QCOMPARE( item->rect().width(), 120.0 ); //mm
QCOMPARE( item->rect().height(), 15.0 ); //mm
//restriction only for y position
item->dataDefinedProperties().setProperty( QgsLayoutObject::ItemWidth, QgsProperty() );
item->dataDefinedProperties().setProperty( QgsLayoutObject::ItemHeight, QgsProperty::fromExpression( QStringLiteral( "2+4" ) ) );
item->attemptResize( QgsLayoutSize( 7.0, 1.50, QgsUnitTypes::LayoutCentimeters ) );
QCOMPARE( item->sizeWithUnits().width(), 7.0 );
QCOMPARE( item->sizeWithUnits().height(), 6.0 );
QCOMPARE( item->sizeWithUnits().units(), QgsUnitTypes::LayoutCentimeters );
QCOMPARE( item->rect().width(), 70.0 ); //mm
QCOMPARE( item->rect().height(), 60.0 ); //mm
//check change of units should apply to data defined size
item->dataDefinedProperties().setProperty( QgsLayoutObject::ItemWidth, QgsProperty::fromExpression( QStringLiteral( "4+8" ) ) );
item->dataDefinedProperties().setProperty( QgsLayoutObject::ItemHeight, QgsProperty::fromExpression( QStringLiteral( "2+4" ) ) );
//first set to same as existing size, but with different units
item->attemptResize( QgsLayoutSize( 120.0, 60.0, QgsUnitTypes::LayoutMillimeters ) );
//data defined size should utilize new units
QCOMPARE( item->sizeWithUnits().width(), 12.0 ); //mm
QCOMPARE( item->sizeWithUnits().height(), 6.0 ); //mm
QCOMPARE( item->sizeWithUnits().units(), QgsUnitTypes::LayoutMillimeters );
QCOMPARE( item->rect().width(), 12.0 ); //mm
QCOMPARE( item->rect().height(), 6.0 ); //mm
//test that data defined size applies to item's reference point
item->dataDefinedProperties().setProperty( QgsLayoutObject::ItemWidth, QgsProperty() );
item->dataDefinedProperties().setProperty( QgsLayoutObject::ItemHeight, QgsProperty() );
item->attemptResize( QgsLayoutSize( 10.0, 5.0, QgsUnitTypes::LayoutMillimeters ) );
item->attemptMove( QgsLayoutPoint( 20.0, 10.0, QgsUnitTypes::LayoutMillimeters ) );
item->dataDefinedProperties().setProperty( QgsLayoutObject::ItemWidth, QgsProperty::fromExpression( QStringLiteral( "5" ) ) );
item->dataDefinedProperties().setProperty( QgsLayoutObject::ItemHeight, QgsProperty::fromExpression( QStringLiteral( "6" ) ) );
item->setReferencePoint( QgsLayoutItem::LowerRight );
item->refreshItemSize();
QCOMPARE( item->pos().x(), 25.0 ); //mm
QCOMPARE( item->pos().y(), 9.0 ); //mm
//test that data defined size applied after setting item's reference point respects reference
item->dataDefinedProperties().setProperty( QgsLayoutObject::ItemWidth, QgsProperty() );
item->dataDefinedProperties().setProperty( QgsLayoutObject::ItemHeight, QgsProperty() );
item->setReferencePoint( QgsLayoutItem::UpperLeft );
item->attemptResize( QgsLayoutSize( 10.0, 5.0, QgsUnitTypes::LayoutMillimeters ) );
item->attemptMove( QgsLayoutPoint( 20.0, 10.0, QgsUnitTypes::LayoutMillimeters ) );
item->setReferencePoint( QgsLayoutItem::LowerRight );
item->dataDefinedProperties().setProperty( QgsLayoutObject::ItemWidth, QgsProperty::fromExpression( QStringLiteral( "7" ) ) );
item->dataDefinedProperties().setProperty( QgsLayoutObject::ItemHeight, QgsProperty::fromExpression( QStringLiteral( "9" ) ) );
item->refreshItemSize();
QCOMPARE( item->pos().x(), 23.0 ); //mm
QCOMPARE( item->pos().y(), 6.0 ); //mm
delete item;
}
void TestQgsLayoutItem::combinedDataDefinedPositionAndSize()
{
QgsProject p;
QgsLayout l( &p );
//test setting data defined size
TestItem *item = new TestItem( &l );
l.setUnits( QgsUnitTypes::LayoutMillimeters );
item->attemptMove( QgsLayoutPoint( 6.0, 1.50, QgsUnitTypes::LayoutCentimeters ) );
item->attemptResize( QgsLayoutSize( 2.0, 4.0, QgsUnitTypes::LayoutCentimeters ) );
//test item with all of data defined x, y, width, height set
item->dataDefinedProperties().setProperty( QgsLayoutObject::PositionX, QgsProperty::fromExpression( QStringLiteral( "4+7" ) ) );
item->dataDefinedProperties().setProperty( QgsLayoutObject::PositionY, QgsProperty::fromExpression( QStringLiteral( "2+3" ) ) );
item->dataDefinedProperties().setProperty( QgsLayoutObject::ItemWidth, QgsProperty::fromExpression( QStringLiteral( "4+9" ) ) );
item->dataDefinedProperties().setProperty( QgsLayoutObject::ItemHeight, QgsProperty::fromExpression( QStringLiteral( "2+4" ) ) );
item->refreshDataDefinedProperty( QgsLayoutObject::AllProperties );
QCOMPARE( item->positionWithUnits().x(), 11.0 );
QCOMPARE( item->positionWithUnits().y(), 5.0 );
QCOMPARE( item->positionWithUnits().units(), QgsUnitTypes::LayoutCentimeters );
QCOMPARE( item->sizeWithUnits().width(), 13.0 );
QCOMPARE( item->sizeWithUnits().height(), 6.0 );
QCOMPARE( item->sizeWithUnits().units(), QgsUnitTypes::LayoutCentimeters );
QCOMPARE( item->pos().x(), 110.0 ); //mm
QCOMPARE( item->pos().y(), 50.0 ); //mm
QCOMPARE( item->rect().width(), 130.0 ); //mm
QCOMPARE( item->rect().height(), 60.0 ); //mm
//also try with reference point set
item->setReferencePoint( QgsLayoutItem::Middle );
item->dataDefinedProperties().setProperty( QgsLayoutObject::PositionX, QgsProperty::fromExpression( QStringLiteral( "4+8" ) ) );
item->dataDefinedProperties().setProperty( QgsLayoutObject::PositionY, QgsProperty::fromExpression( QStringLiteral( "2+4" ) ) );
item->dataDefinedProperties().setProperty( QgsLayoutObject::ItemWidth, QgsProperty::fromExpression( QStringLiteral( "3+7" ) ) );
item->dataDefinedProperties().setProperty( QgsLayoutObject::ItemHeight, QgsProperty::fromExpression( QStringLiteral( "1+3" ) ) );
item->refreshDataDefinedProperty( QgsLayoutObject::AllProperties );
QCOMPARE( item->positionWithUnits().x(), 12.0 );
QCOMPARE( item->positionWithUnits().y(), 6.0 );
QCOMPARE( item->positionWithUnits().units(), QgsUnitTypes::LayoutCentimeters );
QCOMPARE( item->sizeWithUnits().width(), 10.0 );
QCOMPARE( item->sizeWithUnits().height(), 4.0 );
QCOMPARE( item->sizeWithUnits().units(), QgsUnitTypes::LayoutCentimeters );
QCOMPARE( item->pos().x(), 70.0 ); //mm
QCOMPARE( item->pos().y(), 40.0 ); //mm
QCOMPARE( item->rect().width(), 100.0 ); //mm
QCOMPARE( item->rect().height(), 40.0 ); //mm
delete item;
}
//TODO rotation
void TestQgsLayoutItem::resize()
{
QgsProject p;