Skip to content

Commit

Permalink
[layouts][needs-docs] Add control for whether pages should be
Browse files Browse the repository at this point in the history
exported, including data defined setting

This replaces the 2.x data-defined "number of pages" setting.
Instead of requiring users to develop an expression to return
the number of pages, instead we allow individual pages to have
a data defined control of whether that page should be included
in the export.

This is more flexible, and works correctly with the mixed page
size model for layouts.
  • Loading branch information
nyalldawson committed Dec 17, 2017
1 parent 3704c48 commit f649f1f
Show file tree
Hide file tree
Showing 13 changed files with 204 additions and 38 deletions.
3 changes: 0 additions & 3 deletions python/core/layout/qgslayout.sip
Expand Up @@ -580,9 +580,6 @@ Emitted when the layout's name is changed.

};




/************************************************************************
* This file has been generated automatically from *
* *
Expand Down
6 changes: 6 additions & 0 deletions src/app/layout/qgslayoutdesignerdialog.cpp
Expand Up @@ -1511,6 +1511,9 @@ void QgsLayoutDesignerDialog::exportToRaster()
mView->setPaintingEnabled( false );
QApplication::setOverrideCursor( Qt::BusyCursor );

// force a refresh, to e.g. update data defined properties, tables, etc
mLayout->refresh();

QgsLayoutExporter exporter( mLayout );

QgsLayoutExporter::ImageExportSettings settings;
Expand Down Expand Up @@ -1624,6 +1627,9 @@ void QgsLayoutDesignerDialog::exportToPdf()
pdfSettings.rasterizeWholeImage = mLayout->customProperty( QStringLiteral( "rasterise" ), false ).toBool();
pdfSettings.forceVectorOutput = mLayout->customProperty( QStringLiteral( "forceVector" ), false ).toBool();

// force a refresh, to e.g. update data defined properties, tables, etc
mLayout->refresh();

QgsLayoutExporter exporter( mLayout );
switch ( exporter.exportToPdf( outputFileName, pdfSettings ) )
{
Expand Down
11 changes: 11 additions & 0 deletions src/app/layout/qgslayoutpagepropertieswidget.cpp
Expand Up @@ -39,6 +39,7 @@ QgsLayoutPagePropertiesWidget::QgsLayoutPagePropertiesWidget( QWidget *parent, Q
mWidthSpin->setValue( mPage->pageSize().width() );
mHeightSpin->setValue( mPage->pageSize().height() );
mSizeUnitsComboBox->setUnit( mPage->pageSize().units() );
mExcludePageCheckBox->setChecked( mPage->excludeFromExports() );

mPageOrientationComboBox->setCurrentIndex( mPageOrientationComboBox->findData( mPage->orientation() ) );

Expand All @@ -59,11 +60,14 @@ QgsLayoutPagePropertiesWidget::QgsLayoutPagePropertiesWidget( QWidget *parent, Q
connect( mHeightSpin, static_cast< void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPagePropertiesWidget::updatePageSize );
connect( mWidthSpin, static_cast< void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPagePropertiesWidget::setToCustomSize );
connect( mHeightSpin, static_cast< void ( QDoubleSpinBox::* )( double )>( &QDoubleSpinBox::valueChanged ), this, &QgsLayoutPagePropertiesWidget::setToCustomSize );
connect( mExcludePageCheckBox, &QCheckBox::toggled, this, &QgsLayoutPagePropertiesWidget::excludeExportsToggled );

connect( mSymbolButton, &QgsSymbolButton::changed, this, &QgsLayoutPagePropertiesWidget::symbolChanged );
registerDataDefinedButton( mPaperSizeDDBtn, QgsLayoutObject::PresetPaperSize );
registerDataDefinedButton( mWidthDDBtn, QgsLayoutObject::ItemWidth );
registerDataDefinedButton( mHeightDDBtn, QgsLayoutObject::ItemHeight );
registerDataDefinedButton( mExcludePageDDBtn, QgsLayoutObject::ExcludeFromExports );
mExcludePageDDBtn->registerEnabledWidget( mExcludePageCheckBox, false );

showCurrentPageSize();
}
Expand Down Expand Up @@ -155,6 +159,13 @@ void QgsLayoutPagePropertiesWidget::symbolChanged()
mPage->layout()->undoStack()->endCommand();
}

void QgsLayoutPagePropertiesWidget::excludeExportsToggled( bool checked )
{
mPage->beginCommand( !checked ? tr( "Include Page in Exports" ) : tr( "Exclude Page from Exports" ) );
mPage->setExcludeFromExports( checked );
mPage->endCommand();
}

void QgsLayoutPagePropertiesWidget::showCurrentPageSize()
{
QgsLayoutSize paperSize = mPage->pageSize();
Expand Down
1 change: 1 addition & 0 deletions src/app/layout/qgslayoutpagepropertieswidget.h
Expand Up @@ -48,6 +48,7 @@ class QgsLayoutPagePropertiesWidget : public QgsLayoutItemBaseWidget, private Ui
void updatePageSize();
void setToCustomSize();
void symbolChanged();
void excludeExportsToggled( bool checked );

private:

Expand Down
3 changes: 0 additions & 3 deletions src/core/layout/qgslayout.h
Expand Up @@ -672,6 +672,3 @@ class CORE_EXPORT QgsLayout : public QGraphicsScene, public QgsExpressionContext
};

#endif //QGSLAYOUT_H



3 changes: 2 additions & 1 deletion src/core/layout/qgslayoutcontext.h
Expand Up @@ -236,7 +236,8 @@ class CORE_EXPORT QgsLayoutContext : public QObject
bool mPagesVisible = true;

friend class QgsLayoutExporter;
friend class LayoutItemCacheSettingRestorer;
friend class TestQgsLayout;
friend class LayoutContextPreviewSettingRestorer;


};
Expand Down
43 changes: 39 additions & 4 deletions src/core/layout/qgslayoutexporter.cpp
Expand Up @@ -26,6 +26,30 @@
#include "gdal.h"
#include "cpl_conv.h"

///@cond PRIVATE
class LayoutContextPreviewSettingRestorer
{
public:

LayoutContextPreviewSettingRestorer( QgsLayout *layout )
: mLayout( layout )
, mPreviousSetting( layout->context().mIsPreviewRender )
{
mLayout->context().mIsPreviewRender = false;
}

~LayoutContextPreviewSettingRestorer()
{
mLayout->context().mIsPreviewRender = mPreviousSetting;
}

private:
QgsLayout *mLayout = nullptr;
bool mPreviousSetting = false;
};

///@endcond PRIVATE

QgsLayoutExporter::QgsLayoutExporter( QgsLayout *layout )
: mLayout( layout )
{
Expand Down Expand Up @@ -53,6 +77,9 @@ void QgsLayoutExporter::renderPage( QPainter *painter, int page ) const
return;
}

LayoutContextPreviewSettingRestorer restorer( mLayout );
( void )restorer;

QRectF paperRect = QRectF( pageItem->pos().x(), pageItem->pos().y(), pageItem->rect().width(), pageItem->rect().height() );
renderRegion( painter, paperRect );
}
Expand All @@ -73,6 +100,9 @@ QImage QgsLayoutExporter::renderPageToImage( int page, QSize imageSize, double d
return QImage();
}

LayoutContextPreviewSettingRestorer restorer( mLayout );
( void )restorer;

QRectF paperRect = QRectF( pageItem->pos().x(), pageItem->pos().y(), pageItem->rect().width(), pageItem->rect().height() );
return renderRegionToImage( paperRect, imageSize, dpi );
}
Expand All @@ -85,8 +115,6 @@ class LayoutItemCacheSettingRestorer
LayoutItemCacheSettingRestorer( QgsLayout *layout )
: mLayout( layout )
{
mLayout->context().mIsPreviewRender = false;

const QList< QGraphicsItem * > items = mLayout->items();
for ( QGraphicsItem *item : items )
{
Expand All @@ -101,8 +129,6 @@ class LayoutItemCacheSettingRestorer
{
it.key()->setCacheMode( it.value() );
}

mLayout->context().mIsPreviewRender = true;
}

private:
Expand All @@ -122,6 +148,8 @@ void QgsLayoutExporter::renderRegion( QPainter *painter, const QRectF &region )

LayoutItemCacheSettingRestorer cacheRestorer( mLayout );
( void )cacheRestorer;
LayoutContextPreviewSettingRestorer restorer( mLayout );
( void )restorer;

#if 0 //TODO
setSnapLinesVisible( false );
Expand All @@ -138,6 +166,9 @@ void QgsLayoutExporter::renderRegion( QPainter *painter, const QRectF &region )

QImage QgsLayoutExporter::renderRegionToImage( const QRectF &region, QSize imageSize, double dpi ) const
{
LayoutContextPreviewSettingRestorer restorer( mLayout );
( void )restorer;

double resolution = mLayout->context().dpi();
double oneInchInLayoutUnits = mLayout->convertToLayoutUnits( QgsLayoutMeasurement( 1, QgsUnitTypes::LayoutInches ) );
if ( imageSize.isValid() )
Expand Down Expand Up @@ -219,6 +250,8 @@ QgsLayoutExporter::ExportResult QgsLayoutExporter::exportToImage( const QString
pageDetails.baseName = fi.baseName();
pageDetails.extension = fi.completeSuffix();

LayoutContextPreviewSettingRestorer restorer( mLayout );
( void )restorer;
LayoutContextSettingsRestorer dpiRestorer( mLayout );
( void )dpiRestorer;
mLayout->context().setDpi( settings.dpi );
Expand Down Expand Up @@ -303,6 +336,8 @@ QgsLayoutExporter::ExportResult QgsLayoutExporter::exportToPdf( const QString &f

mErrorFileName.clear();

LayoutContextPreviewSettingRestorer restorer( mLayout );
( void )restorer;
LayoutContextSettingsRestorer contextRestorer( mLayout );
( void )contextRestorer;
mLayout->context().setDpi( settings.dpi );
Expand Down
10 changes: 5 additions & 5 deletions src/core/layout/qgslayoutitem.h
Expand Up @@ -831,6 +831,11 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
*/
void cancelCommand();

/**
* Returns whether the item should be drawn in the current context.
*/
bool shouldDrawItem() const;

public slots:

/**
Expand Down Expand Up @@ -1049,11 +1054,6 @@ class CORE_EXPORT QgsLayoutItem : public QgsLayoutObject, public QGraphicsRectIt
*/
virtual bool readPropertiesFromElement( const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context );

/**
* Returns whether the item should be drawn in the current context.
*/
bool shouldDrawItem() const;

/**
* Applies any present data defined size overrides to the specified layout \a size.
*/
Expand Down
4 changes: 4 additions & 0 deletions src/core/layout/qgslayoutpagecollection.cpp
Expand Up @@ -482,6 +482,10 @@ bool QgsLayoutPageCollection::shouldExportPage( int page ) const
return false;
}

QgsLayoutItemPage *pageItem = mPages.at( page );
if ( !pageItem->shouldDrawItem() )
return false;

//check all frame items on page
QList<QgsLayoutFrame *> frames;
itemsOnPage( frames, page );
Expand Down
82 changes: 61 additions & 21 deletions src/ui/layout/qgslayoutpagepropertieswidget.ui
Expand Up @@ -14,27 +14,7 @@
<string>New Item Properties</string>
</property>
<layout class="QGridLayout" name="gridLayout_2" columnstretch="0,1">
<item row="3" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Background</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="4" column="1">
<widget class="QgsSymbolButton" name="mSymbolButton">
<property name="enabled">
<bool>true</bool>
Expand All @@ -56,6 +36,13 @@
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Background</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QGroupBox" name="groupBox">
<property name="title">
Expand Down Expand Up @@ -204,6 +191,56 @@
</layout>
</widget>
</item>
<item row="5" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QCheckBox" name="mExcludePageCheckBox">
<property name="toolTip">
<string>If checked, this page will not be included when exporting the layout</string>
</property>
<property name="text">
<string>Exclude page from exports</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QgsPropertyOverrideButton" name="mExcludePageDDBtn">
<property name="text">
<string>…</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
Expand Down Expand Up @@ -244,6 +281,9 @@
<tabstop>mHeightSpin</tabstop>
<tabstop>mHeightDDBtn</tabstop>
<tabstop>mSizeUnitsComboBox</tabstop>
<tabstop>mExcludePageCheckBox</tabstop>
<tabstop>mExcludePageDDBtn</tabstop>
<tabstop>mSymbolButton</tabstop>
</tabstops>
<resources/>
<connections/>
Expand Down
2 changes: 1 addition & 1 deletion src/ui/qgisapp.ui
Expand Up @@ -17,7 +17,7 @@
<x>0</x>
<y>0</y>
<width>1018</width>
<height>20</height>
<height>25</height>
</rect>
</property>
<property name="toolTip">
Expand Down
28 changes: 28 additions & 0 deletions tests/src/core/testqgslayout.cpp
Expand Up @@ -613,6 +613,7 @@ void TestQgsLayout::shouldExportPage()
QgsLayoutItemPage *page2 = new QgsLayoutItemPage( &l );
page2->setPageSize( "A4" );
l.pageCollection()->addPage( page2 );
l.context().mIsPreviewRender = false;

QgsLayoutItemHtml *htmlItem = new QgsLayoutItemHtml( &l );
//frame on page 1
Expand Down Expand Up @@ -645,6 +646,33 @@ void TestQgsLayout::shouldExportPage()

QVERIFY( l.pageCollection()->shouldExportPage( 0 ) );
QVERIFY( !l.pageCollection()->shouldExportPage( 1 ) );

// get rid of frames
l.removeItem( frame1 );
l.removeItem( frame2 );
l.removeMultiFrame( htmlItem );
delete htmlItem;
QgsApplication::sendPostedEvents( nullptr, QEvent::DeferredDelete );

QVERIFY( l.pageCollection()->shouldExportPage( 0 ) );
QVERIFY( l.pageCollection()->shouldExportPage( 1 ) );

// explicitly set exclude from exports
l.pageCollection()->page( 0 )->setExcludeFromExports( true );
QVERIFY( !l.pageCollection()->shouldExportPage( 0 ) );
QVERIFY( l.pageCollection()->shouldExportPage( 1 ) );

l.pageCollection()->page( 0 )->setExcludeFromExports( false );
l.pageCollection()->page( 1 )->setExcludeFromExports( true );
QVERIFY( l.pageCollection()->shouldExportPage( 0 ) );
QVERIFY( !l.pageCollection()->shouldExportPage( 1 ) );

l.pageCollection()->page( 1 )->setExcludeFromExports( false );
l.pageCollection()->page( 0 )->dataDefinedProperties().setProperty( QgsLayoutObject::ExcludeFromExports, QgsProperty::fromExpression( "1" ) );
l.pageCollection()->page( 1 )->dataDefinedProperties().setProperty( QgsLayoutObject::ExcludeFromExports, QgsProperty::fromValue( true ) );
l.refresh();
QVERIFY( !l.pageCollection()->shouldExportPage( 0 ) );
QVERIFY( !l.pageCollection()->shouldExportPage( 1 ) );
}

void TestQgsLayout::pageIsEmpty()
Expand Down

0 comments on commit f649f1f

Please sign in to comment.