Skip to content
Permalink
Browse files

[composer] Fix page orientation and size ignored when printing

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 8ab0674f44427e70ee374a659fa9cddbe65c0760
Showing with 73 additions and 6 deletions.
  1. +4 −0 src/app/composer/qgscomposer.cpp
  2. +55 −6 src/core/composer/qgscomposition.cpp
  3. +14 −0 src/core/composer/qgscomposition.h
@@ -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 );
@@ -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 );
@@ -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
@@ -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 ;
@@ -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 );
}
}

@@ -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;
@@ -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 )
@@ -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
@@ -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();

0 comments on commit 8ab0674

Please sign in to comment.
You can’t perform that action at this time.