Skip to content

Commit fe5bd47

Browse files
committedDec 17, 2017
Work on resizing layouts to item bounds
1 parent f4f5f75 commit fe5bd47

File tree

7 files changed

+308
-38
lines changed

7 files changed

+308
-38
lines changed
 

‎python/core/layout/qgslayoutpagecollection.sip

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,16 @@ Returns the space between pages, in layout units.
282282
Returns the size of the page shadow, in layout units.
283283
%End
284284

285+
void resizeToContents( const QgsMargins &margins, QgsUnitTypes::LayoutUnit marginUnits );
286+
%Docstring
287+
Resizes the layout to a single page which fits the current contents of the layout.
288+
289+
Calling this method resets the number of pages to 1, with the size set to the
290+
minimum size required to fit all existing layout items. Items will also be
291+
repositioned so that the new top-left bounds of the layout is at the point
292+
(marginLeft, marginTop). An optional margin can be specified.
293+
%End
294+
285295
virtual bool writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context ) const;
286296

287297
%Docstring

‎src/app/layout/qgslayoutpropertieswidget.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@
1818
#include "qgslayout.h"
1919
#include "qgslayoutsnapper.h"
2020
#include "qgslayoutpagecollection.h"
21+
#include "qgslayoutundostack.h"
2122

2223
QgsLayoutPropertiesWidget::QgsLayoutPropertiesWidget( QWidget *parent, QgsLayout *layout )
2324
: QgsPanelWidget( parent )
2425
, mLayout( layout )
2526
{
27+
Q_ASSERT( mLayout );
28+
2629
setupUi( this );
2730
setPanelTitle( tr( "Layout properties" ) );
2831
blockSignals( true );
@@ -42,6 +45,30 @@ QgsLayoutPropertiesWidget::QgsLayoutPropertiesWidget( QWidget *parent, QgsLayout
4245
connect( mGridResolutionSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsLayoutPropertiesWidget::gridResolutionChanged );
4346
connect( mOffsetXSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsLayoutPropertiesWidget::gridOffsetXChanged );
4447
connect( mOffsetYSpinBox, static_cast < void ( QgsDoubleSpinBox::* )( double ) > ( &QgsDoubleSpinBox::valueChanged ), this, &QgsLayoutPropertiesWidget::gridOffsetYChanged );
48+
49+
double leftMargin = mLayout->customProperty( QStringLiteral( "resizeToContentsLeftMargin" ) ).toDouble();
50+
double topMargin = mLayout->customProperty( QStringLiteral( "resizeToContentsTopMargin" ) ).toDouble();
51+
double bottomMargin = mLayout->customProperty( QStringLiteral( "resizeToContentsBottomMargin" ) ).toDouble();
52+
double rightMargin = mLayout->customProperty( QStringLiteral( "resizeToContentsRightMargin" ) ).toDouble();
53+
QgsUnitTypes::LayoutUnit marginUnit = static_cast< QgsUnitTypes::LayoutUnit >(
54+
mLayout->customProperty( QStringLiteral( "imageCropMarginUnit" ), QgsUnitTypes::LayoutMillimeters ).toInt() );
55+
56+
mTopMarginSpinBox->setValue( topMargin );
57+
mMarginUnitsComboBox->linkToWidget( mTopMarginSpinBox );
58+
mRightMarginSpinBox->setValue( rightMargin );
59+
mMarginUnitsComboBox->linkToWidget( mRightMarginSpinBox );
60+
mBottomMarginSpinBox->setValue( bottomMargin );
61+
mMarginUnitsComboBox->linkToWidget( mBottomMarginSpinBox );
62+
mLeftMarginSpinBox->setValue( leftMargin );
63+
mMarginUnitsComboBox->linkToWidget( mLeftMarginSpinBox );
64+
mMarginUnitsComboBox->setUnit( marginUnit );
65+
mMarginUnitsComboBox->setConverter( &mLayout->context().measurementConverter() );
66+
67+
connect( mTopMarginSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPropertiesWidget::resizeMarginsChanged );
68+
connect( mRightMarginSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPropertiesWidget::resizeMarginsChanged );
69+
connect( mBottomMarginSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPropertiesWidget::resizeMarginsChanged );
70+
connect( mLeftMarginSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPropertiesWidget::resizeMarginsChanged );
71+
connect( mResizePageButton, &QPushButton::clicked, this, &QgsLayoutPropertiesWidget::resizeToContents );
4572
}
4673

4774
void QgsLayoutPropertiesWidget::updateSnappingElements()
@@ -101,6 +128,28 @@ void QgsLayoutPropertiesWidget::snapToleranceChanged( int tolerance )
101128
mLayout->snapper().setSnapTolerance( tolerance );
102129
}
103130

131+
void QgsLayoutPropertiesWidget::resizeMarginsChanged()
132+
{
133+
mLayout->setCustomProperty( QStringLiteral( "resizeToContentsLeftMargin" ), mLeftMarginSpinBox->value() );
134+
mLayout->setCustomProperty( QStringLiteral( "resizeToContentsTopMargin" ), mTopMarginSpinBox->value() );
135+
mLayout->setCustomProperty( QStringLiteral( "resizeToContentsBottomMargin" ), mBottomMarginSpinBox->value() );
136+
mLayout->setCustomProperty( QStringLiteral( "resizeToContentsRightMargin" ), mRightMarginSpinBox->value() );
137+
mLayout->setCustomProperty( QStringLiteral( "imageCropMarginUnit" ), mMarginUnitsComboBox->unit() );
138+
}
139+
140+
void QgsLayoutPropertiesWidget::resizeToContents()
141+
{
142+
mLayout->undoStack()->beginMacro( tr( "Resize to Contents" ) );
143+
144+
mLayout->pageCollection()->resizeToContents( QgsMargins( mLeftMarginSpinBox->value(),
145+
mTopMarginSpinBox->value(),
146+
mRightMarginSpinBox->value(),
147+
mBottomMarginSpinBox->value() ),
148+
mMarginUnitsComboBox->unit() );
149+
150+
mLayout->undoStack()->endMacro();
151+
}
152+
104153
void QgsLayoutPropertiesWidget::blockSignals( bool block )
105154
{
106155
mGridResolutionSpinBox->blockSignals( block );

‎src/app/layout/qgslayoutpropertieswidget.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ class QgsLayoutPropertiesWidget: public QgsPanelWidget, private Ui::QgsLayoutWid
3636
void gridOffsetYChanged( double d );
3737
void gridOffsetUnitsChanged( QgsUnitTypes::LayoutUnit unit );
3838
void snapToleranceChanged( int tolerance );
39+
void resizeMarginsChanged();
40+
void resizeToContents();
3941

4042
private:
4143

‎src/core/layout/qgslayoutpagecollection.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,77 @@ double QgsLayoutPageCollection::pageShadowWidth() const
199199
return spaceBetweenPages() / 2;
200200
}
201201

202+
void QgsLayoutPageCollection::resizeToContents( const QgsMargins &margins, QgsUnitTypes::LayoutUnit marginUnits )
203+
{
204+
if ( !mBlockUndoCommands )
205+
mLayout->undoStack()->beginCommand( this, tr( "Resize to Contents" ) );
206+
207+
//calculate current bounds
208+
QRectF bounds = mLayout->layoutBounds( true, 0.0 );
209+
210+
for ( int page = mPages.count() - 1; page > 0; page-- )
211+
{
212+
deletePage( page );
213+
}
214+
215+
if ( mPages.empty() )
216+
{
217+
std::unique_ptr< QgsLayoutItemPage > page = qgis::make_unique< QgsLayoutItemPage >( mLayout );
218+
addPage( page.release() );
219+
}
220+
221+
QgsLayoutItemPage *page = mPages.at( 0 );
222+
223+
double marginLeft = mLayout->convertToLayoutUnits( QgsLayoutMeasurement( margins.left(), marginUnits ) );
224+
double marginTop = mLayout->convertToLayoutUnits( QgsLayoutMeasurement( margins.top(), marginUnits ) );
225+
double marginBottom = mLayout->convertToLayoutUnits( QgsLayoutMeasurement( margins.bottom(), marginUnits ) );
226+
double marginRight = mLayout->convertToLayoutUnits( QgsLayoutMeasurement( margins.right(), marginUnits ) );
227+
228+
bounds.setWidth( bounds.width() + marginLeft + marginRight );
229+
bounds.setHeight( bounds.height() + marginTop + marginBottom );
230+
231+
QgsLayoutSize newPageSize = mLayout->convertFromLayoutUnits( bounds.size(), mLayout->units() );
232+
page->setPageSize( newPageSize );
233+
234+
reflow();
235+
236+
//also move all items so that top-left of bounds is at marginLeft, marginTop
237+
double diffX = marginLeft - bounds.left();
238+
double diffY = marginTop - bounds.top();
239+
240+
const QList<QGraphicsItem *> itemList = mLayout->items();
241+
for ( QGraphicsItem *item : itemList )
242+
{
243+
if ( QgsLayoutItem *layoutItem = dynamic_cast<QgsLayoutItem *>( item ) )
244+
{
245+
QgsLayoutItemPage *pageItem = dynamic_cast<QgsLayoutItemPage *>( layoutItem );
246+
if ( !pageItem )
247+
{
248+
layoutItem->beginCommand( tr( "Move Item" ) );
249+
layoutItem->attemptMoveBy( diffX, diffY );
250+
layoutItem->endCommand();
251+
}
252+
}
253+
}
254+
255+
//also move guides
256+
mLayout->undoStack()->beginCommand( &mLayout->guides(), tr( "Move Guides" ) );
257+
const QList< QgsLayoutGuide * > verticalGuides = mLayout->guides().guides( Qt::Vertical );
258+
for ( QgsLayoutGuide *guide : verticalGuides )
259+
{
260+
guide->setLayoutPosition( guide->layoutPosition() + diffX );
261+
}
262+
const QList< QgsLayoutGuide * > horizontalGuides = mLayout->guides().guides( Qt::Horizontal );
263+
for ( QgsLayoutGuide *guide : horizontalGuides )
264+
{
265+
guide->setLayoutPosition( guide->layoutPosition() + diffY );
266+
}
267+
mLayout->undoStack()->endCommand();
268+
269+
if ( !mBlockUndoCommands )
270+
mLayout->undoStack()->endCommand();
271+
}
272+
202273
bool QgsLayoutPageCollection::writeXml( QDomElement &parentElement, QDomDocument &document, const QgsReadWriteContext &context ) const
203274
{
204275
QDomElement element = document.createElement( QStringLiteral( "PageCollection" ) );

‎src/core/layout/qgslayoutpagecollection.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,16 @@ class CORE_EXPORT QgsLayoutPageCollection : public QObject, public QgsLayoutSeri
306306
*/
307307
double pageShadowWidth() const;
308308

309+
/**
310+
* Resizes the layout to a single page which fits the current contents of the layout.
311+
*
312+
* Calling this method resets the number of pages to 1, with the size set to the
313+
* minimum size required to fit all existing layout items. Items will also be
314+
* repositioned so that the new top-left bounds of the layout is at the point
315+
* (marginLeft, marginTop). An optional margin can be specified.
316+
*/
317+
void resizeToContents( const QgsMargins &margins, QgsUnitTypes::LayoutUnit marginUnits );
318+
309319
/**
310320
* Stores the collection's state in a DOM element. The \a parentElement should refer to the parent layout's DOM element.
311321
* \see readXml()

‎src/ui/layout/qgslayoutwidgetbase.ui

Lines changed: 136 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,126 @@
175175
</layout>
176176
</widget>
177177
</item>
178+
<item>
179+
<widget class="QgsCollapsibleGroupBoxBasic" name="groupBox_5">
180+
<property name="title">
181+
<string>Resize layout to content</string>
182+
</property>
183+
<layout class="QVBoxLayout" name="verticalLayout_5">
184+
<item>
185+
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1">
186+
<item>
187+
<widget class="QLabel" name="label">
188+
<property name="text">
189+
<string>Margin units</string>
190+
</property>
191+
</widget>
192+
</item>
193+
<item>
194+
<widget class="QgsLayoutUnitsComboBox" name="mMarginUnitsComboBox"/>
195+
</item>
196+
</layout>
197+
</item>
198+
<item>
199+
<layout class="QGridLayout" name="gridLayout_5">
200+
<item row="0" column="1">
201+
<widget class="QLabel" name="label_4">
202+
<property name="text">
203+
<string>Top margin</string>
204+
</property>
205+
</widget>
206+
</item>
207+
<item row="0" column="0">
208+
<spacer name="horizontalSpacer">
209+
<property name="orientation">
210+
<enum>Qt::Horizontal</enum>
211+
</property>
212+
<property name="sizeHint" stdset="0">
213+
<size>
214+
<width>40</width>
215+
<height>20</height>
216+
</size>
217+
</property>
218+
</spacer>
219+
</item>
220+
<item row="0" column="3">
221+
<spacer name="horizontalSpacer_2">
222+
<property name="orientation">
223+
<enum>Qt::Horizontal</enum>
224+
</property>
225+
<property name="sizeHint" stdset="0">
226+
<size>
227+
<width>40</width>
228+
<height>20</height>
229+
</size>
230+
</property>
231+
</spacer>
232+
</item>
233+
<item row="0" column="2">
234+
<widget class="QgsDoubleSpinBox" name="mTopMarginSpinBox">
235+
<property name="singleStep">
236+
<double>0.100000000000000</double>
237+
</property>
238+
</widget>
239+
</item>
240+
<item row="1" column="0" colspan="4">
241+
<layout class="QHBoxLayout" name="horizontalLayout_7">
242+
<item>
243+
<widget class="QLabel" name="label_5">
244+
<property name="text">
245+
<string>Left</string>
246+
</property>
247+
</widget>
248+
</item>
249+
<item>
250+
<widget class="QgsDoubleSpinBox" name="mLeftMarginSpinBox">
251+
<property name="singleStep">
252+
<double>0.100000000000000</double>
253+
</property>
254+
</widget>
255+
</item>
256+
<item>
257+
<widget class="QLabel" name="label_11">
258+
<property name="text">
259+
<string>Right</string>
260+
</property>
261+
</widget>
262+
</item>
263+
<item>
264+
<widget class="QgsDoubleSpinBox" name="mRightMarginSpinBox">
265+
<property name="singleStep">
266+
<double>0.100000000000000</double>
267+
</property>
268+
</widget>
269+
</item>
270+
</layout>
271+
</item>
272+
<item row="2" column="1">
273+
<widget class="QLabel" name="label_12">
274+
<property name="text">
275+
<string>Bottom</string>
276+
</property>
277+
</widget>
278+
</item>
279+
<item row="2" column="2">
280+
<widget class="QgsDoubleSpinBox" name="mBottomMarginSpinBox">
281+
<property name="singleStep">
282+
<double>0.100000000000000</double>
283+
</property>
284+
</widget>
285+
</item>
286+
<item row="3" column="1" colspan="2">
287+
<widget class="QPushButton" name="mResizePageButton">
288+
<property name="text">
289+
<string>Resize layout</string>
290+
</property>
291+
</widget>
292+
</item>
293+
</layout>
294+
</item>
295+
</layout>
296+
</widget>
297+
</item>
178298
<item>
179299
<spacer name="verticalSpacer">
180300
<property name="orientation">
@@ -196,16 +316,6 @@
196316
</widget>
197317
<layoutdefault spacing="6" margin="11"/>
198318
<customwidgets>
199-
<customwidget>
200-
<class>QgsDoubleSpinBox</class>
201-
<extends>QDoubleSpinBox</extends>
202-
<header>qgsdoublespinbox.h</header>
203-
</customwidget>
204-
<customwidget>
205-
<class>QgsLayoutUnitsComboBox</class>
206-
<extends>QComboBox</extends>
207-
<header>qgslayoutunitscombobox.h</header>
208-
</customwidget>
209319
<customwidget>
210320
<class>QgsScrollArea</class>
211321
<extends>QScrollArea</extends>
@@ -218,6 +328,16 @@
218328
<header>qgscollapsiblegroupbox.h</header>
219329
<container>1</container>
220330
</customwidget>
331+
<customwidget>
332+
<class>QgsDoubleSpinBox</class>
333+
<extends>QDoubleSpinBox</extends>
334+
<header>qgsdoublespinbox.h</header>
335+
</customwidget>
336+
<customwidget>
337+
<class>QgsLayoutUnitsComboBox</class>
338+
<extends>QComboBox</extends>
339+
<header>qgslayoutunitscombobox.h</header>
340+
</customwidget>
221341
<customwidget>
222342
<class>QgsSpinBox</class>
223343
<extends>QSpinBox</extends>
@@ -233,6 +353,12 @@
233353
<tabstop>mOffsetYSpinBox</tabstop>
234354
<tabstop>mGridOffsetUnitsComboBox</tabstop>
235355
<tabstop>mSnapToleranceSpinBox</tabstop>
356+
<tabstop>mMarginUnitsComboBox</tabstop>
357+
<tabstop>mTopMarginSpinBox</tabstop>
358+
<tabstop>mLeftMarginSpinBox</tabstop>
359+
<tabstop>mRightMarginSpinBox</tabstop>
360+
<tabstop>mBottomMarginSpinBox</tabstop>
361+
<tabstop>mResizePageButton</tabstop>
236362
</tabstops>
237363
<resources/>
238364
<connections/>

‎tests/src/core/testqgslayout.cpp

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,12 @@ void TestQgsLayout::bounds()
267267
//add some items to a layout
268268
QgsProject p;
269269
QgsLayout l( &p );
270-
l.initializeDefaults();
270+
QgsLayoutItemPage *page = new QgsLayoutItemPage( &l );
271+
page->setPageSize( "A4", QgsLayoutItemPage::Landscape );
272+
l.pageCollection()->addPage( page );
273+
QgsLayoutItemPage *page2 = new QgsLayoutItemPage( &l );
274+
page2->setPageSize( "A4", QgsLayoutItemPage::Landscape );
275+
l.pageCollection()->addPage( page2 );
271276

272277
QgsLayoutItemShape *shape1 = new QgsLayoutItemShape( &l );
273278
shape1->attemptResize( QgsLayoutSize( 90, 50 ) );
@@ -276,44 +281,41 @@ void TestQgsLayout::bounds()
276281
l.addLayoutItem( shape1 );
277282
QgsLayoutItemShape *shape2 = new QgsLayoutItemShape( &l );
278283
shape2->attemptResize( QgsLayoutSize( 110, 50 ) );
279-
shape2->attemptMove( QgsLayoutPoint( 100, 150 ) );
284+
shape2->attemptMove( QgsLayoutPoint( 100, 150 ), true, false, 0 );
280285
l.addLayoutItem( shape2 );
281-
282-
#if 0
283-
QgsLayoutItemRectangularShape *shape3 = new QgsLayoutItemRectangularShape( &l );
284-
l.addLayoutItem( shape3 );
285-
shape3->setItemPosition( 210, 30, 50, 100, QgsComposerItem::UpperLeft, false, 2 );
286-
QgsLayoutItemRectangularShape *shape4 = new QgsLayoutItemRectangularShape( &l );
287-
l.addLayoutItem( shape4 );
288-
shape4->setItemPosition( 10, 120, 50, 30, QgsComposerItem::UpperLeft, false, 2 );
286+
QgsLayoutItemShape *shape3 = new QgsLayoutItemShape( &l );
287+
// l.addLayoutItem( shape3 );
288+
shape3->attemptResize( QgsLayoutSize( 50, 100 ) );
289+
shape3->attemptMove( QgsLayoutPoint( 210, 30 ), true, false, 1 );
290+
QgsLayoutItemShape *shape4 = new QgsLayoutItemShape( &l );
291+
// l.addLayoutItem( shape4 );
292+
shape4->attemptResize( QgsLayoutSize( 50, 30 ) );
293+
shape4->attemptMove( QgsLayoutPoint( 10, 120 ), true, false, 1 );
289294
shape4->setVisibility( false );
290-
#endif
291295

292296
//check bounds
293297
QRectF layoutBounds = l.layoutBounds( false );
294-
#if 0 // correct values when 2nd page items are added back in
295-
QGSCOMPARENEAR( layoutBounds.height(), 372.15, 0.01 );
296-
QGSCOMPARENEAR( layoutBounds.width(), 301.00, 0.01 );
297-
QGSCOMPARENEAR( layoutBounds.left(), -2, 0.01 );
298-
QGSCOMPARENEAR( layoutBounds.top(), -2, 0.01 );
299-
300-
QRectF compositionBoundsNoPage = l.layoutBounds( true );
301-
QGSCOMPARENEAR( compositionBoundsNoPage.height(), 320.36, 0.01 );
302-
QGSCOMPARENEAR( compositionBoundsNoPage.width(), 250.30, 0.01 );
303-
QGSCOMPARENEAR( compositionBoundsNoPage.left(), 9.85, 0.01 );
304-
QGSCOMPARENEAR( compositionBoundsNoPage.top(), 49.79, 0.01 );
305-
#endif
298+
// QGSCOMPARENEAR( layoutBounds.height(), 430, 0.01 );
299+
// QGSCOMPARENEAR( layoutBounds.width(), 297.00, 0.01 );
300+
// QGSCOMPARENEAR( layoutBounds.left(), 0.0, 0.01 );
301+
// QGSCOMPARENEAR( layoutBounds.top(), 0.0, 0.01 );
302+
303+
QRectF layoutBoundsNoPage = l.layoutBounds( true );
304+
QGSCOMPARENEAR( layoutBoundsNoPage.height(), 320.36, 0.01 );
305+
QGSCOMPARENEAR( layoutBoundsNoPage.width(), 250.30, 0.01 );
306+
QGSCOMPARENEAR( layoutBoundsNoPage.left(), 9.85, 0.01 );
307+
QGSCOMPARENEAR( layoutBoundsNoPage.top(), 49.79, 0.01 );
306308

307309
QGSCOMPARENEAR( layoutBounds.height(), 210.000000, 0.01 );
308310
QGSCOMPARENEAR( layoutBounds.width(), 297.000000, 0.01 );
309311
QGSCOMPARENEAR( layoutBounds.left(), 0.00000, 0.01 );
310312
QGSCOMPARENEAR( layoutBounds.top(), 0.00000, 0.01 );
311313

312-
QRectF compositionBoundsNoPage = l.layoutBounds( true );
313-
QGSCOMPARENEAR( compositionBoundsNoPage.height(), 174.859607, 0.01 );
314-
QGSCOMPARENEAR( compositionBoundsNoPage.width(), 124.859607, 0.01 );
315-
QGSCOMPARENEAR( compositionBoundsNoPage.left(), 85.290393, 0.01 );
316-
QGSCOMPARENEAR( compositionBoundsNoPage.top(), 25.290393, 0.01 );
314+
layoutBoundsNoPage = l.layoutBounds( true );
315+
QGSCOMPARENEAR( layoutBoundsNoPage.height(), 174.859607, 0.01 );
316+
QGSCOMPARENEAR( layoutBoundsNoPage.width(), 124.859607, 0.01 );
317+
QGSCOMPARENEAR( layoutBoundsNoPage.left(), 85.290393, 0.01 );
318+
QGSCOMPARENEAR( layoutBoundsNoPage.top(), 25.290393, 0.01 );
317319

318320
#if 0
319321
QRectF page1Bounds = composition->pageItemBounds( 0, true );

0 commit comments

Comments
 (0)
Please sign in to comment.