Skip to content

Commit

Permalink
[FEATURE][composer] Data defined page size, orientation and number of…
Browse files Browse the repository at this point in the history
… pages for compositions. Funded by Canton of Neuchâtel, Switzerland
  • Loading branch information
nyalldawson committed Jul 5, 2014
1 parent a914d43 commit 1e4ad28
Show file tree
Hide file tree
Showing 9 changed files with 511 additions and 111 deletions.
15 changes: 13 additions & 2 deletions python/core/composer/qgscomposition.sip
Expand Up @@ -34,6 +34,12 @@ class QgsComposition : QGraphicsScene
ZValueAbove
};

enum PaperOrientation
{
Portrait,
Landscape
};

//! @deprecated since 2.4 - use the constructor with QgsMapSettings
QgsComposition( QgsMapRenderer* mapRenderer ) /Deprecated/;
explicit QgsComposition( const QgsMapSettings& mapSettings );
Expand Down Expand Up @@ -403,8 +409,13 @@ class QgsComposition : QGraphicsScene
void beginPrint( QPrinter& printer );
/** Prepare the printer for printing in a PDF */
void beginPrintAsPDF( QPrinter& printer, const QString& file );
/** Print on a preconfigured printer */
void doPrint( QPrinter& printer, QPainter& painter );

/**Print on a preconfigured printer
* @param printer QPrinter destination
* @painter QPainter source
* @startNewPage set to true to begin the print on a new page
*/
void doPrint( QPrinter& printer, QPainter& painter, bool startNewPage = false );

/**Convenience function that prepares the printer and prints
* @returns true if print was successful
Expand Down
14 changes: 4 additions & 10 deletions src/app/composer/qgscomposer.cpp
Expand Up @@ -1467,11 +1467,8 @@ void QgsComposer::exportCompositionAsPDF( QgsComposer::OutputMode mode )
}
else
{
if ( featureI > 0 )
{
printer.newPage();
}
mComposition->doPrint( printer, painter );
//start print on a new page if we're not on the first feature
mComposition->doPrint( printer, painter, featureI > 0 );
}
}
atlasMap->endRender();
Expand Down Expand Up @@ -1604,11 +1601,8 @@ void QgsComposer::printComposition( QgsComposer::OutputMode mode )
return;
}

if ( i > 0 )
{
mPrinter.newPage();
}
mComposition->doPrint( mPrinter, painter );
//start print on a new page if we're not on the first feature
mComposition->doPrint( mPrinter, painter, i > 0 );
}
atlasMap->endRender();
painter.end();
Expand Down
123 changes: 123 additions & 0 deletions src/app/composer/qgscompositionwidget.cpp
Expand Up @@ -85,7 +85,33 @@ QgsCompositionWidget::QgsCompositionWidget( QWidget* parent, QgsComposition* c )
mGridResolutionSpinBox->setValue( mComposition->snapGridResolution() );
mOffsetXSpinBox->setValue( mComposition->snapGridOffsetX() );
mOffsetYSpinBox->setValue( mComposition->snapGridOffsetY() );

QgsAtlasComposition* atlas = &mComposition->atlasComposition();
if ( atlas )
{
// repopulate data defined buttons if atlas layer changes
connect( atlas, SIGNAL( coverageLayerChanged( QgsVectorLayer* ) ),
this, SLOT( populateDataDefinedButtons() ) );
connect( atlas, SIGNAL( toggled( bool ) ), this, SLOT( populateDataDefinedButtons() ) );
}
}

connect( mPaperSizeDDBtn, SIGNAL( dataDefinedChanged( const QString& ) ), this, SLOT( updateDataDefinedProperty( ) ) );
connect( mPaperSizeDDBtn, SIGNAL( dataDefinedActivated( bool ) ), this, SLOT( updateDataDefinedProperty( ) ) );
connect( mPaperSizeDDBtn, SIGNAL( dataDefinedActivated( bool ) ), mPaperSizeComboBox, SLOT( setDisabled( bool ) ) );
connect( mPaperWidthDDBtn, SIGNAL( dataDefinedChanged( const QString& ) ), this, SLOT( updateDataDefinedProperty( ) ) );
connect( mPaperWidthDDBtn, SIGNAL( dataDefinedActivated( bool ) ), this, SLOT( updateDataDefinedProperty( ) ) );
connect( mPaperWidthDDBtn, SIGNAL( dataDefinedActivated( bool ) ), mPaperWidthDoubleSpinBox, SLOT( setDisabled( bool ) ) );
connect( mPaperHeightDDBtn, SIGNAL( dataDefinedChanged( const QString& ) ), this, SLOT( updateDataDefinedProperty( ) ) );
connect( mPaperHeightDDBtn, SIGNAL( dataDefinedActivated( bool ) ), this, SLOT( updateDataDefinedProperty( ) ) );
connect( mPaperHeightDDBtn, SIGNAL( dataDefinedActivated( bool ) ), mPaperHeightDoubleSpinBox, SLOT( setDisabled( bool ) ) );
connect( mNumPagesDDBtn, SIGNAL( dataDefinedChanged( const QString& ) ), this, SLOT( updateDataDefinedProperty( ) ) );
connect( mNumPagesDDBtn, SIGNAL( dataDefinedActivated( bool ) ), this, SLOT( updateDataDefinedProperty( ) ) );
connect( mNumPagesDDBtn, SIGNAL( dataDefinedActivated( bool ) ), mNumPagesSpinBox, SLOT( setDisabled( bool ) ) );
connect( mPaperOrientationDDBtn, SIGNAL( dataDefinedChanged( const QString& ) ), this, SLOT( updateDataDefinedProperty( ) ) );
connect( mPaperOrientationDDBtn, SIGNAL( dataDefinedActivated( bool ) ), this, SLOT( updateDataDefinedProperty( ) ) );
connect( mPaperOrientationDDBtn, SIGNAL( dataDefinedActivated( bool ) ), mPaperOrientationComboBox, SLOT( setDisabled( bool ) ) );

blockSignals( false );
}

Expand All @@ -99,6 +125,103 @@ QgsCompositionWidget::~QgsCompositionWidget()

}

void QgsCompositionWidget::populateDataDefinedButtons()
{
if ( !mComposition )
{
return;
}

QgsVectorLayer* vl = 0;
QgsAtlasComposition* atlas = &mComposition->atlasComposition();

if ( atlas && atlas->enabled() )
{
vl = atlas->coverageLayer();
}

mPaperSizeDDBtn->blockSignals( true );
mPaperWidthDDBtn->blockSignals( true );
mPaperHeightDDBtn->blockSignals( true );
mNumPagesDDBtn->blockSignals( true );
mPaperOrientationDDBtn->blockSignals( true );

mPaperSizeDDBtn->init( vl, mComposition->dataDefinedProperty( QgsComposerItem::PresetPaperSize ),
QgsDataDefinedButton::String, QgsDataDefinedButton::paperSizeDesc() );
mPaperWidthDDBtn->init( vl, mComposition->dataDefinedProperty( QgsComposerItem::PaperWidth ),
QgsDataDefinedButton::Double, QgsDataDefinedButton::doublePosDesc() );
mPaperHeightDDBtn->init( vl, mComposition->dataDefinedProperty( QgsComposerItem::PaperHeight ),
QgsDataDefinedButton::Double, QgsDataDefinedButton::doublePosDesc() );
mNumPagesDDBtn->init( vl, mComposition->dataDefinedProperty( QgsComposerItem::NumPages ),
QgsDataDefinedButton::Int, QgsDataDefinedButton::intPosOneDesc() );
mPaperOrientationDDBtn->init( vl, mComposition->dataDefinedProperty( QgsComposerItem::PaperOrientation ),
QgsDataDefinedButton::String, QgsDataDefinedButton::paperOrientationDesc() );

//initial state of controls - disable related controls when dd buttons are active
mPaperSizeComboBox->setEnabled( !mPaperSizeDDBtn->isActive() );

mPaperSizeDDBtn->blockSignals( false );
mPaperWidthDDBtn->blockSignals( false );
mPaperHeightDDBtn->blockSignals( false );
mNumPagesDDBtn->blockSignals( false );
mPaperOrientationDDBtn->blockSignals( false );
}

void QgsCompositionWidget::setDataDefinedProperty( const QgsDataDefinedButton* ddBtn, QgsComposerItem::DataDefinedProperty property )
{
if ( !mComposition )
{
return;
}

const QMap< QString, QString >& map = ddBtn->definedProperty();
mComposition->setDataDefinedProperty( property, map.value( "active" ).toInt(), map.value( "useexpr" ).toInt(), map.value( "expression" ), map.value( "field" ) );
}

QgsComposerItem::DataDefinedProperty QgsCompositionWidget::ddPropertyForWidget( QgsDataDefinedButton *widget )
{
if ( widget == mPaperSizeDDBtn )
{
return QgsComposerItem::PresetPaperSize;
}
else if ( widget == mPaperWidthDDBtn )
{
return QgsComposerItem::PaperWidth;
}
else if ( widget == mPaperHeightDDBtn )
{
return QgsComposerItem::PaperHeight;
}
else if ( widget == mNumPagesDDBtn )
{
return QgsComposerItem::NumPages;
}
else if ( widget == mPaperOrientationDDBtn )
{
return QgsComposerItem::PaperOrientation;
}

return QgsComposerItem::NoProperty;
}

void QgsCompositionWidget::updateDataDefinedProperty()
{
QgsDataDefinedButton* ddButton = dynamic_cast<QgsDataDefinedButton*>( sender() );
if ( !ddButton || !mComposition )
{
return;
}

QgsComposerItem::DataDefinedProperty property = ddPropertyForWidget( ddButton );
if ( property == QgsComposerItem::NoProperty )
{
return;
}

setDataDefinedProperty( ddButton, property );
mComposition->refreshDataDefinedProperty( property );
}

void QgsCompositionWidget::createPaperEntries()
{
QList<QgsCompositionPaper> formats;
Expand Down
16 changes: 15 additions & 1 deletion src/app/composer/qgscompositionwidget.h
Expand Up @@ -15,10 +15,11 @@
***************************************************************************/

#include "ui_qgscompositionwidgetbase.h"
#include "qgscomposeritem.h"

class QgsComposition;
class QgsComposerMap;
class QgsComposerItem;
class QgsDataDefinedButton;

/** \ingroup MapComposer
* Struct to hold map composer paper properties.
Expand Down Expand Up @@ -76,6 +77,12 @@ class QgsCompositionWidget: public QWidget, private Ui::QgsCompositionWidgetBase
/* when a map is deleted */
void onItemRemoved( QgsComposerItem* );

/**Must be called when a data defined button changes*/
void updateDataDefinedProperty();

/**Initializes data defined buttons to current atlas coverage layer*/
void populateDataDefinedButtons();

private:
QgsComposition* mComposition;
QMap<QString, QgsCompositionPaper> mPaperMap;
Expand All @@ -99,4 +106,11 @@ class QgsCompositionWidget: public QWidget, private Ui::QgsCompositionWidgetBase
void setSize( QDoubleSpinBox *spin, double v );
/**Blocks / unblocks the signals of all items*/
void blockSignals( bool block );

/**Sets a data defined property for the item from its current data defined button settings*/
void setDataDefinedProperty( const QgsDataDefinedButton *ddBtn, QgsComposerItem::DataDefinedProperty property );

/**Returns the data defined property corresponding to a data defined button widget*/
virtual QgsComposerItem::DataDefinedProperty ddPropertyForWidget( QgsDataDefinedButton* widget );

};

0 comments on commit 1e4ad28

Please sign in to comment.