Skip to content

Commit

Permalink
[composer] Fix page orientation and size ignored when printing
Browse files Browse the repository at this point in the history
Turns out QPrinter::setPaperSize silently flips the width and height
of a page if the printer orientation is set to landscape. So, make sure
we manually set the orientation to portrait before setting the page size
so that we can be sure the QPrinter is set to the correct page size.

This also restores the 2.4 behaviour where users could override
printed page size in the printer properties dialog (but only if
no data defined page size settings are active).

(fix #11352)
  • Loading branch information
nyalldawson committed Oct 20, 2014
1 parent 4906d56 commit 8ab0674
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 6 deletions.
4 changes: 4 additions & 0 deletions src/app/composer/qgscomposer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1456,6 +1456,8 @@ void QgsComposer::exportCompositionAsPDF( QgsComposer::OutputMode mode )
}
if ( atlasOnASingleFile )
{
//prepare for first feature, so that we know paper size to begin with
atlasMap->prepareForFeature( 0 );
mComposition->beginPrintAsPDF( printer, outputFileName );
// set the correct resolution
mComposition->beginPrint( printer );
Expand Down Expand Up @@ -1615,6 +1617,8 @@ void QgsComposer::printComposition( QgsComposer::OutputMode mode )
}
else
{
//prepare for first feature, so that we know paper size to begin with
atlasMap->prepareForFeature( 0 );

mComposition->beginPrint( mPrinter, true );
QPainter painter( &mPrinter );
Expand Down
61 changes: 55 additions & 6 deletions src/core/composer/qgscomposition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2620,8 +2620,11 @@ void QgsComposition::beginPrintAsPDF( QPrinter& printer, const QString& file )
// https://bugreports.qt-project.org/browse/QTBUG-33583 - PDF output converts text to outline
// Also an issue with PDF paper size using QPrinter::NativeFormat on Mac (always outputs portrait letter-size)
printer.setOutputFormat( QPrinter::PdfFormat );
printer.setOutputFileName( file );

refreshPageSize();
//must set orientation to portrait before setting paper size, otherwise size will be flipped
//for landscape sized outputs (#11352)
printer.setOrientation( QPrinter::Portrait );
printer.setPaperSize( QSizeF( paperWidth(), paperHeight() ), QPrinter::Millimeter );

// TODO: add option for this in Composer
Expand All @@ -2640,9 +2643,15 @@ bool QgsComposition::exportAsPDF( const QString& file )

void QgsComposition::doPrint( QPrinter& printer, QPainter& p, bool startNewPage )
{
//set the page size again so that data defined page size takes effect
refreshPageSize();
printer.setPaperSize( QSizeF( paperWidth(), paperHeight() ), QPrinter::Millimeter );
if ( ddPageSizeActive() )
{
//set the page size again so that data defined page size takes effect
refreshPageSize();
//must set orientation to portrait before setting paper size, otherwise size will be flipped
//for landscape sized outputs (#11352)
printer.setOrientation( QPrinter::Portrait );
printer.setPaperSize( QSizeF( paperWidth(), paperHeight() ), QPrinter::Millimeter );
}

//QgsComposition starts page numbering at 0
int fromPage = ( printer.fromPage() < 1 ) ? 0 : printer.fromPage() - 1 ;
Expand Down Expand Up @@ -2699,12 +2708,14 @@ void QgsComposition::beginPrint( QPrinter &printer, const bool evaluateDDPageSiz
//set user-defined resolution
printer.setResolution( printResolution() );

if ( evaluateDDPageSize )
if ( evaluateDDPageSize && ddPageSizeActive() )
{
//set data defined page size
refreshPageSize();
//must set orientation to portrait before setting paper size, otherwise size will be flipped
//for landscape sized outputs (#11352)
printer.setOrientation( QPrinter::Portrait );
printer.setPaperSize( QSizeF( paperWidth(), paperHeight() ), QPrinter::Millimeter );
printer.setOrientation( paperWidth() > paperHeight() ? QPrinter::Landscape : QPrinter::Portrait );
}
}

Expand Down Expand Up @@ -2885,6 +2896,15 @@ bool QgsComposition::setAtlasMode( const AtlasMode mode )
return true;
}

bool QgsComposition::ddPageSizeActive() const
{
//check if any data defined page settings are active
return dataDefinedActive( QgsComposerObject::PresetPaperSize, &mDataDefinedProperties ) ||
dataDefinedActive( QgsComposerObject::PaperWidth, &mDataDefinedProperties ) ||
dataDefinedActive( QgsComposerObject::PaperHeight, &mDataDefinedProperties ) ||
dataDefinedActive( QgsComposerObject::PaperOrientation, &mDataDefinedProperties );
}

void QgsComposition::refreshPageSize()
{
double pageWidth = mPageWidth;
Expand Down Expand Up @@ -3042,6 +3062,35 @@ bool QgsComposition::dataDefinedEvaluate( QgsComposerObject::DataDefinedProperty
return false;
}

bool QgsComposition::dataDefinedActive( const QgsComposerObject::DataDefinedProperty property, const QMap<QgsComposerObject::DataDefinedProperty, QgsDataDefined *> *dataDefinedProperties ) const
{
if ( property == QgsComposerObject::AllProperties || property == QgsComposerObject::NoProperty )
{
//invalid property
return false;
}
if ( !dataDefinedProperties->contains( property ) )
{
//missing property
return false;
}

QgsDataDefined* dd = 0;
QMap< QgsComposerObject::DataDefinedProperty, QgsDataDefined* >::const_iterator it = dataDefinedProperties->find( property );
if ( it != dataDefinedProperties->constEnd() )
{
dd = it.value();
}

if ( !dd )
{
return false;
}

//found the data defined property, return whether it is active
return dd->isActive();
}

QVariant QgsComposition::dataDefinedValue( QgsComposerObject::DataDefinedProperty property, const QgsFeature *feature, const QgsFields *fields, QMap<QgsComposerObject::DataDefinedProperty, QgsDataDefined *> *dataDefinedProperties ) const
{
if ( property == QgsComposerObject::AllProperties || property == QgsComposerObject::NoProperty )
Expand Down
14 changes: 14 additions & 0 deletions src/core/composer/qgscomposition.h
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,14 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
bool dataDefinedEvaluate( QgsComposerObject::DataDefinedProperty property, QVariant &expressionValue,
QMap< QgsComposerObject::DataDefinedProperty, QgsDataDefined* >* dataDefinedProperties );

/**Returns whether a data defined property has been set and is currently active.
* @param property data defined property to test
* @param dataDefinedProperties map of data defined properties to QgsDataDefined
* @note this method was added in version 2.5
*/
bool dataDefinedActive( const QgsComposerObject::DataDefinedProperty property,
const QMap<QgsComposerObject::DataDefinedProperty, QgsDataDefined *> *dataDefinedProperties ) const;

/**Evaluates a data defined property and returns the calculated value.
* @param property data defined property to evaluate
* @param feature current atlas feature to evaluate property for
Expand All @@ -834,6 +842,12 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
*/
void prepareDataDefinedExpression( QgsDataDefined *dd, QMap< QgsComposerObject::DataDefinedProperty, QgsDataDefined* >* dataDefinedProperties ) const;

/**Check whether any data defined page settings are active.
* @returns true if any data defined page settings are active.
* @note this method was added in version 2.5
*/
bool ddPageSizeActive() const;

private slots:
/*Prepares all data defined expressions*/
void prepareAllDataDefinedExpressions();
Expand Down

0 comments on commit 8ab0674

Please sign in to comment.