mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-16 00:05:45 -04:00
[FEATURE][composer] Option to restrict image/SVG outputs to content
If selected, then the images output by composer will include only the area of the composition with content. There's also an option for margins to add around the item bounds if required. If the composition includes a single page, then the output will be sized to include EVERYTHING on the composition. If it's a multi-page composition, then each page will be cropped to only include the area of that page with items. A new image export options dialog has been added to facilitate this, which also includes handy shortcuts for overriding the print resolution or exported image dimensions. Sponsored by NIWA
This commit is contained in:
parent
2f343008c1
commit
dd759370bd
@ -601,18 +601,59 @@ class QgsComposition : QGraphicsScene
|
||||
*/
|
||||
bool exportAsPDF( const QString& file );
|
||||
|
||||
//! print composer page to image
|
||||
//! If the image does not fit into memory, a null image is returned
|
||||
/** Renders a composer page to an image.
|
||||
* @param page page number, 0 based such that the first page is page 0
|
||||
* @returns rendered image, or null image if image does not fit into available memory
|
||||
* @see renderRectAsRaster()
|
||||
* @see renderPage()
|
||||
*/
|
||||
QImage printPageAsRaster( int page );
|
||||
|
||||
/** Render a page to a paint device
|
||||
/** Renders a portion of the composition to an image. This method can be used to render
|
||||
* sections of pages rather than full pages.
|
||||
* @param rect region of composition to render
|
||||
* @returns rendered image, or null image if image does not fit into available memory
|
||||
* @note added in QGIS 2.12
|
||||
* @see printPageAsRaster()
|
||||
* @see renderRect()
|
||||
*/
|
||||
QImage renderRectAsRaster( const QRectF& rect );
|
||||
|
||||
/** Renders a full page to a paint device.
|
||||
* @param p destination painter
|
||||
* @param page page number, 0 based such that the first page is page 0 */
|
||||
* @param page page number, 0 based such that the first page is page 0
|
||||
* @see renderRect()
|
||||
* @see printPageAsRaster()
|
||||
*/
|
||||
void renderPage( QPainter* p, int page );
|
||||
|
||||
/** Compute world file parameters */
|
||||
/** Renders a portion of the composition to a paint device. This method can be used
|
||||
* to render sections of pages rather than full pages.
|
||||
* @param p destination painter
|
||||
* @param rect region of composition to render
|
||||
* @note added in QGIS 2.12
|
||||
* @see renderPage()
|
||||
* @see renderRectAsRaster()
|
||||
*/
|
||||
void renderRect( QPainter* p, const QRectF& rect );
|
||||
|
||||
/** Compute world file parameters. Assumes the whole page containing the associated map item
|
||||
* will be exported.
|
||||
*/
|
||||
void computeWorldFileParameters( double& a, double& b, double& c, double& d, double& e, double& f ) const;
|
||||
|
||||
/** Computes the world file parameters for a specified region of the composition.
|
||||
* @param exportRegion region of the composition which will be associated with world file
|
||||
* @param a
|
||||
* @param b
|
||||
* @param c
|
||||
* @param d
|
||||
* @param e
|
||||
* @param f
|
||||
* @note added in QGIS 2.12
|
||||
*/
|
||||
void computeWorldFileParameters( const QRectF& exportRegion, double& a, double& b, double& c, double& d, double& e, double& f ) const;
|
||||
|
||||
QgsAtlasComposition& atlasComposition();
|
||||
|
||||
/** Resizes a QRectF relative to the change from boundsBefore to boundsAfter
|
||||
@ -703,6 +744,20 @@ class QgsComposition : QGraphicsScene
|
||||
*/
|
||||
QStringList customProperties() const;
|
||||
|
||||
/** Returns the bounding box of the items contained on a specified page.
|
||||
* @param pageNumber page number, where 0 is the first page
|
||||
* @param visibleOnly set to true to only include visible items
|
||||
* @note added in QGIS 2.12
|
||||
*/
|
||||
QRectF pageItemBounds( int pageNumber, bool visibleOnly = false ) const;
|
||||
|
||||
/** Calculates the bounds of all non-gui items in the composition. Ignores snap lines and mouse handles.
|
||||
* @param ignorePages set to true to ignore page items
|
||||
* @param margin optional marginal (in percent, eg 0.05 = 5% ) to add around items
|
||||
*/
|
||||
QRectF compositionBounds( bool ignorePages = false, double margin = 0.0 ) const;
|
||||
|
||||
|
||||
public slots:
|
||||
/** Casts object to the proper subclass type and calls corresponding itemAdded signal*/
|
||||
void sendItemAddedSignal( QgsComposerItem* item );
|
||||
|
@ -124,6 +124,7 @@ SET(QGIS_APP_SRCS
|
||||
composer/qgscomposerarrowwidget.cpp
|
||||
composer/qgscomposerattributetablewidget.cpp
|
||||
composer/qgscomposerhtmlwidget.cpp
|
||||
composer/qgscomposerimageexportoptionsdialog.cpp
|
||||
composer/qgscomposeritemwidget.cpp
|
||||
composer/qgscomposerlabelwidget.cpp
|
||||
composer/qgscomposerpicturewidget.cpp
|
||||
@ -278,6 +279,7 @@ SET (QGIS_APP_MOC_HDRS
|
||||
composer/qgscomposerarrowwidget.h
|
||||
composer/qgscomposerattributetablewidget.h
|
||||
composer/qgscomposerhtmlwidget.h
|
||||
composer/qgscomposerimageexportoptionsdialog.h
|
||||
composer/qgscomposeritemwidget.h
|
||||
composer/qgscomposerlabelwidget.h
|
||||
composer/qgscomposerlegendwidget.h
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include "qgspaperitem.h"
|
||||
#include "qgsmaplayerregistry.h"
|
||||
#include "qgsprevieweffect.h"
|
||||
#include "qgscomposerimageexportoptionsdialog.h"
|
||||
#include "ui_qgssvgexportoptions.h"
|
||||
|
||||
#include <QCloseEvent>
|
||||
@ -1965,6 +1966,19 @@ void QgsComposer::exportCompositionAsImage( QgsComposer::OutputMode mode )
|
||||
return;
|
||||
}
|
||||
|
||||
//get some defaults from the composition
|
||||
bool cropToContents = mComposition->customProperty( "imageCropToContents", false ).toBool();
|
||||
int marginTop = mComposition->customProperty( "imageCropMarginTop", 0 ).toInt();
|
||||
int marginRight = mComposition->customProperty( "imageCropMarginRight", 0 ).toInt();
|
||||
int marginBottom = mComposition->customProperty( "imageCropMarginBottom", 0 ).toInt();
|
||||
int marginLeft = mComposition->customProperty( "imageCropMarginLeft", 0 ).toInt();
|
||||
|
||||
QgsComposerImageExportOptionsDialog imageDlg( this );
|
||||
imageDlg.setImageSize( QSizeF( mComposition->paperWidth(), mComposition->paperHeight() ) );
|
||||
imageDlg.setResolution( mComposition->printResolution() );
|
||||
imageDlg.setCropToContents( cropToContents );
|
||||
imageDlg.setCropMargins( marginTop, marginRight, marginBottom, marginLeft );
|
||||
|
||||
QgsAtlasComposition* atlasMap = &mComposition->atlasComposition();
|
||||
if ( mode == QgsComposer::Single )
|
||||
{
|
||||
@ -1983,6 +1997,17 @@ void QgsComposer::exportCompositionAsImage( QgsComposer::OutputMode mode )
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !imageDlg.exec() )
|
||||
return;
|
||||
|
||||
cropToContents = imageDlg.cropToContents();
|
||||
imageDlg.getCropMargins( marginTop, marginRight, marginBottom, marginLeft );
|
||||
mComposition->setCustomProperty( "imageCropToContents", cropToContents );
|
||||
mComposition->setCustomProperty( "imageCropMarginTop", marginTop );
|
||||
mComposition->setCustomProperty( "imageCropMarginRight", marginRight );
|
||||
mComposition->setCustomProperty( "imageCropMarginBottom", marginBottom );
|
||||
mComposition->setCustomProperty( "imageCropMarginLeft", marginLeft );
|
||||
|
||||
mView->setPaintingEnabled( false );
|
||||
|
||||
int worldFilePageNo = -1;
|
||||
@ -1997,7 +2022,38 @@ void QgsComposer::exportCompositionAsImage( QgsComposer::OutputMode mode )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QImage image = mComposition->printPageAsRaster( i );
|
||||
|
||||
QImage image;
|
||||
QRectF bounds;
|
||||
if ( cropToContents )
|
||||
{
|
||||
if ( mComposition->numPages() == 1 )
|
||||
{
|
||||
// single page, so include everything
|
||||
bounds = mComposition->compositionBounds( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
// multi page, so just clip to items on current page
|
||||
bounds = mComposition->pageItemBounds( i, true );
|
||||
}
|
||||
if ( bounds.width() <= 0 || bounds.height() <= 0 )
|
||||
{
|
||||
//invalid size, skip page
|
||||
continue;
|
||||
}
|
||||
double pixelToMm = 25.4 / mComposition->printResolution();
|
||||
bounds = bounds.adjusted( -marginLeft * pixelToMm,
|
||||
-marginTop * pixelToMm,
|
||||
marginRight * pixelToMm,
|
||||
marginBottom * pixelToMm );
|
||||
image = mComposition->renderRectAsRaster( bounds );
|
||||
}
|
||||
else
|
||||
{
|
||||
image = mComposition->printPageAsRaster( i );
|
||||
}
|
||||
|
||||
if ( image.isNull() )
|
||||
{
|
||||
QMessageBox::warning( 0, tr( "Memory Allocation Error" ),
|
||||
@ -2037,7 +2093,10 @@ void QgsComposer::exportCompositionAsImage( QgsComposer::OutputMode mode )
|
||||
{
|
||||
// should generate world file for this page
|
||||
double a, b, c, d, e, f;
|
||||
mComposition->computeWorldFileParameters( a, b, c, d, e, f );
|
||||
if ( bounds.isValid() )
|
||||
mComposition->computeWorldFileParameters( bounds, a, b, c, d, e, f );
|
||||
else
|
||||
mComposition->computeWorldFileParameters( a, b, c, d, e, f );
|
||||
|
||||
QFileInfo fi( outputFilePath );
|
||||
// build the world file name
|
||||
@ -2127,6 +2186,17 @@ void QgsComposer::exportCompositionAsImage( QgsComposer::OutputMode mode )
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !imageDlg.exec() )
|
||||
return;
|
||||
|
||||
cropToContents = imageDlg.cropToContents();
|
||||
imageDlg.getCropMargins( marginTop, marginRight, marginBottom, marginLeft );
|
||||
mComposition->setCustomProperty( "imageCropToContents", cropToContents );
|
||||
mComposition->setCustomProperty( "imageCropMarginTop", marginTop );
|
||||
mComposition->setCustomProperty( "imageCropMarginRight", marginRight );
|
||||
mComposition->setCustomProperty( "imageCropMarginBottom", marginBottom );
|
||||
mComposition->setCustomProperty( "imageCropMarginLeft", marginLeft );
|
||||
|
||||
myQSettings.setValue( "/UI/lastSaveAtlasAsImagesDir", dir );
|
||||
|
||||
// So, now we can render the atlas
|
||||
@ -2184,7 +2254,38 @@ void QgsComposer::exportCompositionAsImage( QgsComposer::OutputMode mode )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QImage image = mComposition->printPageAsRaster( i );
|
||||
|
||||
QImage image;
|
||||
QRectF bounds;
|
||||
if ( cropToContents )
|
||||
{
|
||||
if ( mComposition->numPages() == 1 )
|
||||
{
|
||||
// single page, so include everything
|
||||
bounds = mComposition->compositionBounds( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
// multi page, so just clip to items on current page
|
||||
bounds = mComposition->pageItemBounds( i, true );
|
||||
}
|
||||
if ( bounds.width() <= 0 || bounds.height() <= 0 )
|
||||
{
|
||||
//invalid size, skip page
|
||||
continue;
|
||||
}
|
||||
double pixelToMm = 25.4 / mComposition->printResolution();
|
||||
bounds = bounds.adjusted( -marginLeft * pixelToMm,
|
||||
-marginTop * pixelToMm,
|
||||
marginRight * pixelToMm,
|
||||
marginBottom * pixelToMm );
|
||||
image = mComposition->renderRectAsRaster( bounds );
|
||||
}
|
||||
else
|
||||
{
|
||||
image = mComposition->printPageAsRaster( i );
|
||||
}
|
||||
|
||||
QString imageFilename = filename;
|
||||
|
||||
if ( i != 0 )
|
||||
@ -2210,7 +2311,10 @@ void QgsComposer::exportCompositionAsImage( QgsComposer::OutputMode mode )
|
||||
{
|
||||
// should generate world file for this page
|
||||
double a, b, c, d, e, f;
|
||||
mComposition->computeWorldFileParameters( a, b, c, d, e, f );
|
||||
if ( bounds.isValid() )
|
||||
mComposition->computeWorldFileParameters( bounds, a, b, c, d, e, f );
|
||||
else
|
||||
mComposition->computeWorldFileParameters( a, b, c, d, e, f );
|
||||
|
||||
QFileInfo fi( imageFilename );
|
||||
// build the world file name
|
||||
@ -2317,6 +2421,11 @@ void QgsComposer::exportCompositionAsSVG( QgsComposer::OutputMode mode )
|
||||
QString outputDir;
|
||||
bool groupLayers = false;
|
||||
bool prevSettingLabelsAsOutlines = QgsProject::instance()->readBoolEntry( "PAL", "/DrawOutlineLabels", true );
|
||||
bool clipToContent = false;
|
||||
double marginTop = 0.0;
|
||||
double marginRight = 0.0;
|
||||
double marginBottom = 0.0;
|
||||
double marginLeft = 0.0;
|
||||
|
||||
if ( mode == QgsComposer::Single )
|
||||
{
|
||||
@ -2335,26 +2444,13 @@ void QgsComposer::exportCompositionAsSVG( QgsComposer::OutputMode mode )
|
||||
// open file dialog
|
||||
outputFileName = QFileDialog::getSaveFileName(
|
||||
this,
|
||||
tr( "Choose a file name to save the map as" ),
|
||||
tr( "Choose a file name to save the composition as" ),
|
||||
outputFileName,
|
||||
tr( "SVG Format" ) + " (*.svg *.SVG)" );
|
||||
|
||||
if ( outputFileName.isEmpty() )
|
||||
return;
|
||||
|
||||
// open otions dialog
|
||||
{
|
||||
QDialog dialog;
|
||||
Ui::QgsSvgExportOptionsDialog options;
|
||||
options.setupUi( &dialog );
|
||||
options.chkTextAsOutline->setChecked( prevSettingLabelsAsOutlines );
|
||||
|
||||
dialog.exec();
|
||||
groupLayers = options.chkMapLayersAsGroup->isChecked();
|
||||
//temporarily override label draw outlines setting
|
||||
QgsProject::instance()->writeEntry( "PAL", "/DrawOutlineLabels", options.chkTextAsOutline->isChecked() );
|
||||
}
|
||||
|
||||
if ( !outputFileName.endsWith( ".svg", Qt::CaseInsensitive ) )
|
||||
{
|
||||
outputFileName += ".svg";
|
||||
@ -2400,24 +2496,42 @@ void QgsComposer::exportCompositionAsSVG( QgsComposer::OutputMode mode )
|
||||
QMessageBox::Ok );
|
||||
return;
|
||||
}
|
||||
|
||||
// open otions dialog
|
||||
{
|
||||
QDialog dialog;
|
||||
Ui::QgsSvgExportOptionsDialog options;
|
||||
options.setupUi( &dialog );
|
||||
options.chkTextAsOutline->setChecked( prevSettingLabelsAsOutlines );
|
||||
|
||||
dialog.exec();
|
||||
groupLayers = options.chkMapLayersAsGroup->isChecked();
|
||||
//temporarily override label draw outlines setting
|
||||
QgsProject::instance()->writeEntry( "PAL", "/DrawOutlineLabels", options.chkTextAsOutline->isChecked() );
|
||||
}
|
||||
|
||||
|
||||
myQSettings.setValue( "/UI/lastSaveAtlasAsSvgDir", outputDir );
|
||||
}
|
||||
|
||||
// open options dialog
|
||||
QDialog dialog;
|
||||
Ui::QgsSvgExportOptionsDialog options;
|
||||
options.setupUi( &dialog );
|
||||
options.chkTextAsOutline->setChecked( prevSettingLabelsAsOutlines );
|
||||
options.chkMapLayersAsGroup->setChecked( mComposition->customProperty( "svgGroupLayers", false ).toBool() );
|
||||
options.mClipToContentGroupBox->setChecked( mComposition->customProperty( "svgCropToContents", false ).toBool() );
|
||||
options.mTopMarginSpinBox->setValue( mComposition->customProperty( "svgCropMarginTop", 0 ).toInt() );
|
||||
options.mRightMarginSpinBox->setValue( mComposition->customProperty( "svgCropMarginRight", 0 ).toInt() );
|
||||
options.mBottomMarginSpinBox->setValue( mComposition->customProperty( "svgCropMarginBottom", 0 ).toInt() );
|
||||
options.mLeftMarginSpinBox->setValue( mComposition->customProperty( "svgCropMarginLeft", 0 ).toInt() );
|
||||
|
||||
if ( dialog.exec() != QDialog::Accepted )
|
||||
return;
|
||||
|
||||
groupLayers = options.chkMapLayersAsGroup->isChecked();
|
||||
clipToContent = options.mClipToContentGroupBox->isChecked();
|
||||
marginTop = options.mTopMarginSpinBox->value();
|
||||
marginRight = options.mRightMarginSpinBox->value();
|
||||
marginBottom = options.mBottomMarginSpinBox->value();
|
||||
marginLeft = options.mLeftMarginSpinBox->value();
|
||||
|
||||
//save dialog settings
|
||||
mComposition->setCustomProperty( "svgGroupLayers", groupLayers );
|
||||
mComposition->setCustomProperty( "svgCropToContents", clipToContent );
|
||||
mComposition->setCustomProperty( "svgCropMarginTop", marginTop );
|
||||
mComposition->setCustomProperty( "svgCropMarginRight", marginRight );
|
||||
mComposition->setCustomProperty( "svgCropMarginBottom", marginBottom );
|
||||
mComposition->setCustomProperty( "svgCropMarginLeft", marginLeft );
|
||||
|
||||
//temporarily override label draw outlines setting
|
||||
QgsProject::instance()->writeEntry( "PAL", "/DrawOutlineLabels", options.chkTextAsOutline->isChecked() );
|
||||
|
||||
mView->setPaintingEnabled( false );
|
||||
|
||||
int featureI = 0;
|
||||
@ -2488,10 +2602,33 @@ void QgsComposer::exportCompositionAsSVG( QgsComposer::OutputMode mode )
|
||||
generator.setFileName( currentFileName );
|
||||
}
|
||||
|
||||
QRectF bounds;
|
||||
if ( clipToContent )
|
||||
{
|
||||
if ( mComposition->numPages() == 1 )
|
||||
{
|
||||
// single page, so include everything
|
||||
bounds = mComposition->compositionBounds( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
// multi page, so just clip to items on current page
|
||||
bounds = mComposition->pageItemBounds( i, true );
|
||||
}
|
||||
bounds = bounds.adjusted( -marginLeft, -marginTop, marginRight, marginBottom );
|
||||
}
|
||||
else
|
||||
bounds = QRectF( 0, 0, mComposition->paperWidth(), mComposition->paperHeight() );
|
||||
|
||||
//width in pixel
|
||||
int width = ( int )( mComposition->paperWidth() * mComposition->printResolution() / 25.4 );
|
||||
int width = ( int )( bounds.width() * mComposition->printResolution() / 25.4 );
|
||||
//height in pixel
|
||||
int height = ( int )( mComposition->paperHeight() * mComposition->printResolution() / 25.4 );
|
||||
int height = ( int )( bounds.height() * mComposition->printResolution() / 25.4 );
|
||||
if ( width == 0 || height == 0 )
|
||||
{
|
||||
//invalid size, skip this page
|
||||
continue;
|
||||
}
|
||||
generator.setSize( QSize( width, height ) );
|
||||
generator.setViewBox( QRect( 0, 0, width, height ) );
|
||||
generator.setResolution( mComposition->printResolution() ); //because the rendering is done in mm, convert the dpi
|
||||
@ -2509,15 +2646,18 @@ void QgsComposer::exportCompositionAsSVG( QgsComposer::OutputMode mode )
|
||||
return;
|
||||
}
|
||||
|
||||
mComposition->renderPage( &p, i );
|
||||
if ( clipToContent )
|
||||
mComposition->renderRect( &p, bounds );
|
||||
else
|
||||
mComposition->renderPage( &p, i );
|
||||
p.end();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//width and height in pixel
|
||||
const int width = ( int )( mComposition->paperWidth() * mComposition->printResolution() / 25.4 );
|
||||
const int height = ( int )( mComposition->paperHeight() * mComposition->printResolution() / 25.4 );
|
||||
const int pageWidth = ( int )( mComposition->paperWidth() * mComposition->printResolution() / 25.4 );
|
||||
const int pageHeight = ( int )( mComposition->paperHeight() * mComposition->printResolution() / 25.4 );
|
||||
QList< QgsPaperItem* > paperItems( mComposition->pages() );
|
||||
|
||||
for ( int i = 0; i < mComposition->numPages(); ++i )
|
||||
@ -2526,6 +2666,34 @@ void QgsComposer::exportCompositionAsSVG( QgsComposer::OutputMode mode )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int width = pageWidth;
|
||||
int height = pageHeight;
|
||||
|
||||
QRectF bounds;
|
||||
if ( clipToContent )
|
||||
{
|
||||
if ( mComposition->numPages() == 1 )
|
||||
{
|
||||
// single page, so include everything
|
||||
bounds = mComposition->compositionBounds( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
// multi page, so just clip to items on current page
|
||||
bounds = mComposition->pageItemBounds( i, true );
|
||||
}
|
||||
bounds = bounds.adjusted( -marginLeft, -marginTop, marginRight, marginBottom );
|
||||
width = bounds.width() * mComposition->printResolution() / 25.4;
|
||||
height = bounds.height() * mComposition->printResolution() / 25.4;
|
||||
}
|
||||
|
||||
if ( width == 0 || height == 0 )
|
||||
{
|
||||
//invalid size, skip this page
|
||||
continue;
|
||||
}
|
||||
|
||||
QDomDocument svg;
|
||||
QDomNode svgDocRoot;
|
||||
QgsPaperItem * paperItem = paperItems[i];
|
||||
@ -2581,7 +2749,10 @@ void QgsComposer::exportCompositionAsSVG( QgsComposer::OutputMode mode )
|
||||
generator.setResolution( mComposition->printResolution() ); //because the rendering is done in mm, convert the dpi
|
||||
|
||||
QPainter p( &generator );
|
||||
mComposition->renderPage( &p, i );
|
||||
if ( clipToContent )
|
||||
mComposition->renderRect( &p, bounds );
|
||||
else
|
||||
mComposition->renderPage( &p, i );
|
||||
}
|
||||
// post-process svg output to create groups in a single svg file
|
||||
// we create inkscape layers since it's nice and clean and free
|
||||
|
160
src/app/composer/qgscomposerimageexportoptionsdialog.cpp
Normal file
160
src/app/composer/qgscomposerimageexportoptionsdialog.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
/***************************************************************************
|
||||
qgscomposerimageexportoptionsdialog.cpp
|
||||
---------------------------------------
|
||||
begin : September 2015
|
||||
copyright : (C) 2015 by Nyall Dawson
|
||||
email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgscomposerimageexportoptionsdialog.h"
|
||||
#include <QSettings>
|
||||
#include <QCheckBox>
|
||||
#include <QPushButton>
|
||||
|
||||
QgsComposerImageExportOptionsDialog::QgsComposerImageExportOptionsDialog( QWidget* parent, Qt::WindowFlags flags )
|
||||
: QDialog( parent, flags )
|
||||
{
|
||||
setupUi( this );
|
||||
|
||||
connect( mClipToContentGroupBox, SIGNAL(toggled(bool)), this, SLOT(clipToContentsToggled(bool)));
|
||||
|
||||
QSettings settings;
|
||||
restoreGeometry( settings.value( "/Windows/ComposerImageExportOptionsDialog/geometry" ).toByteArray() );
|
||||
}
|
||||
|
||||
QgsComposerImageExportOptionsDialog::~QgsComposerImageExportOptionsDialog()
|
||||
{
|
||||
QSettings settings;
|
||||
settings.setValue( "/Windows/ComposerImageExportOptionsDialog/geometry", saveGeometry() );
|
||||
}
|
||||
|
||||
void QgsComposerImageExportOptionsDialog::setResolution(int resolution)
|
||||
{
|
||||
mResolutionSpinBox->setValue( resolution );
|
||||
|
||||
if ( mImageSize.isValid() )
|
||||
{
|
||||
mWidthSpinBox->blockSignals( true );
|
||||
mHeightSpinBox->blockSignals( true );
|
||||
mWidthSpinBox->setValue( mImageSize.width() * resolution / 25.4 );
|
||||
mHeightSpinBox->setValue( mImageSize.height() * resolution / 25.4 );
|
||||
mWidthSpinBox->blockSignals( false );
|
||||
mHeightSpinBox->blockSignals( false );
|
||||
}
|
||||
}
|
||||
|
||||
int QgsComposerImageExportOptionsDialog::resolution() const
|
||||
{
|
||||
return mResolutionSpinBox->value();
|
||||
}
|
||||
|
||||
void QgsComposerImageExportOptionsDialog::setImageSize( const QSizeF& size )
|
||||
{
|
||||
mImageSize = size;
|
||||
mWidthSpinBox->blockSignals( true );
|
||||
mHeightSpinBox->blockSignals( true );
|
||||
mWidthSpinBox->setValue( size.width() * mResolutionSpinBox->value() / 25.4 );
|
||||
mHeightSpinBox->setValue( size.height() * mResolutionSpinBox->value() / 25.4 );
|
||||
mWidthSpinBox->blockSignals( false );
|
||||
mHeightSpinBox->blockSignals( false );
|
||||
}
|
||||
|
||||
int QgsComposerImageExportOptionsDialog::width() const
|
||||
{
|
||||
return mWidthSpinBox->value();
|
||||
}
|
||||
|
||||
int QgsComposerImageExportOptionsDialog::height() const
|
||||
{
|
||||
return mHeightSpinBox->value();
|
||||
}
|
||||
|
||||
void QgsComposerImageExportOptionsDialog::setCropToContents(bool crop)
|
||||
{
|
||||
mClipToContentGroupBox->setChecked( crop );
|
||||
}
|
||||
|
||||
bool QgsComposerImageExportOptionsDialog::cropToContents() const
|
||||
{
|
||||
return mClipToContentGroupBox->isChecked();
|
||||
}
|
||||
|
||||
void QgsComposerImageExportOptionsDialog::getCropMargins(int& topMargin, int& rightMargin, int& bottomMargin, int& leftMargin) const
|
||||
{
|
||||
topMargin = mTopMarginSpinBox->value();
|
||||
rightMargin = mRightMarginSpinBox->value();
|
||||
bottomMargin = mBottomMarginSpinBox->value();
|
||||
leftMargin = mLeftMarginSpinBox->value();
|
||||
}
|
||||
|
||||
void QgsComposerImageExportOptionsDialog::setCropMargins(int topMargin, int rightMargin, int bottomMargin, int leftMargin)
|
||||
{
|
||||
mTopMarginSpinBox->setValue( topMargin );
|
||||
mRightMarginSpinBox->setValue( rightMargin );
|
||||
mBottomMarginSpinBox->setValue( bottomMargin );
|
||||
mLeftMarginSpinBox->setValue( leftMargin );
|
||||
}
|
||||
|
||||
void QgsComposerImageExportOptionsDialog::on_mWidthSpinBox_valueChanged(int value)
|
||||
{
|
||||
mHeightSpinBox->blockSignals( true );
|
||||
mResolutionSpinBox->blockSignals( true );
|
||||
mHeightSpinBox->setValue( mImageSize.height() * value / mImageSize.width() );
|
||||
mResolutionSpinBox->setValue( value * 25.4 / mImageSize.width() );
|
||||
mHeightSpinBox->blockSignals( false );
|
||||
mResolutionSpinBox->blockSignals( false);
|
||||
}
|
||||
|
||||
void QgsComposerImageExportOptionsDialog::on_mHeightSpinBox_valueChanged(int value)
|
||||
{
|
||||
mWidthSpinBox->blockSignals( true );
|
||||
mResolutionSpinBox->blockSignals( true );
|
||||
mWidthSpinBox->setValue( mImageSize.width() * value / mImageSize.height() );
|
||||
mResolutionSpinBox->setValue( value * 25.4 / mImageSize.height() );
|
||||
mWidthSpinBox->blockSignals( false );
|
||||
mResolutionSpinBox->blockSignals( false);
|
||||
}
|
||||
|
||||
void QgsComposerImageExportOptionsDialog::on_mResolutionSpinBox_valueChanged(int value)
|
||||
{
|
||||
mWidthSpinBox->blockSignals( true );
|
||||
mHeightSpinBox->blockSignals( true );
|
||||
mWidthSpinBox->setValue( mImageSize.width() * value / 25.4 );
|
||||
mHeightSpinBox->setValue( mImageSize.height() * value / 25.4 );
|
||||
mWidthSpinBox->blockSignals( false );
|
||||
mHeightSpinBox->blockSignals( false);
|
||||
}
|
||||
|
||||
void QgsComposerImageExportOptionsDialog::clipToContentsToggled(bool state)
|
||||
{
|
||||
mWidthSpinBox->setEnabled( !state );
|
||||
mHeightSpinBox->setEnabled( !state );
|
||||
|
||||
if ( state )
|
||||
{
|
||||
mWidthSpinBox->blockSignals( true );
|
||||
mWidthSpinBox->setValue( 0 );
|
||||
mWidthSpinBox->blockSignals( false );
|
||||
mHeightSpinBox->blockSignals( true );
|
||||
mHeightSpinBox->setValue( 0 );
|
||||
mHeightSpinBox->blockSignals( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
mWidthSpinBox->blockSignals( true );
|
||||
mWidthSpinBox->setValue( mImageSize.width() * mResolutionSpinBox->value() / 25.4 );
|
||||
mWidthSpinBox->blockSignals( false );
|
||||
mHeightSpinBox->blockSignals( true );
|
||||
mHeightSpinBox->setValue( mImageSize.height() * mResolutionSpinBox->value() / 25.4 );
|
||||
mHeightSpinBox->blockSignals( false );
|
||||
}
|
||||
}
|
112
src/app/composer/qgscomposerimageexportoptionsdialog.h
Normal file
112
src/app/composer/qgscomposerimageexportoptionsdialog.h
Normal file
@ -0,0 +1,112 @@
|
||||
/***************************************************************************
|
||||
qgscomposerimageexportoptionsdialog.h
|
||||
-------------------------------------
|
||||
begin : September 2015
|
||||
copyright : (C) 2015 by Nyall Dawson
|
||||
email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSCOMPOSERIMAGEEXPORTOPTIONSDIALOG_H
|
||||
#define QGSCOMPOSERIMAGEEXPORTOPTIONSDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "ui_qgscomposerimageexportoptions.h"
|
||||
#include "qgscomposertablev2.h"
|
||||
|
||||
|
||||
/** A dialog for customising the properties of an exported image file.
|
||||
* /note added in QGIS 2.12
|
||||
*/
|
||||
class QgsComposerImageExportOptionsDialog: public QDialog, private Ui::QgsComposerImageExportOptionsDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/** Constructor for QgsComposerImageExportOptionsDialog
|
||||
* @param parent parent widget
|
||||
* @param flags window flags
|
||||
*/
|
||||
QgsComposerImageExportOptionsDialog( QWidget* parent = 0, Qt::WindowFlags flags = 0 );
|
||||
|
||||
~QgsComposerImageExportOptionsDialog();
|
||||
|
||||
/** Sets the initial resolution displayed in the dialog.
|
||||
* @param resolution default resolution in DPI
|
||||
* @see resolution()
|
||||
*/
|
||||
void setResolution( int resolution );
|
||||
|
||||
/** Returns the selected resolution from the dialog.
|
||||
* @returns image resolution in DPI
|
||||
* @see setResolution()
|
||||
*/
|
||||
int resolution() const;
|
||||
|
||||
/** Sets the target image size. This is used to calculate the default size in pixels
|
||||
* and also for determining the image's width to height ratio.
|
||||
* @param size image size
|
||||
*/
|
||||
void setImageSize( const QSizeF& size );
|
||||
|
||||
/** Returns the user-set image width in pixels.
|
||||
* @see height
|
||||
*/
|
||||
int width() const;
|
||||
|
||||
/** Returns the user-set image height in pixels.
|
||||
* @see width
|
||||
*/
|
||||
int height() const;
|
||||
|
||||
/** Sets whether the crop to contents option should be checked in the dialog
|
||||
* @param crop set to true to check crop to contents
|
||||
* @see cropToContents()
|
||||
*/
|
||||
void setCropToContents( bool crop );
|
||||
|
||||
/** Returns whether the crop to contents option is checked in the dialog.
|
||||
* @see setCropToContents()
|
||||
*/
|
||||
bool cropToContents() const;
|
||||
|
||||
/** Fetches the current crop to contents margin values, in pixels.
|
||||
* @param topMargin destination for top margin
|
||||
* @param rightMargin destination for right margin
|
||||
* @param bottomMargin destination for bottom margin
|
||||
* @param leftMargin destination for left margin
|
||||
*/
|
||||
void getCropMargins( int& topMargin, int& rightMargin, int& bottomMargin, int& leftMargin ) const;
|
||||
|
||||
/** Sets the current crop to contents margin values, in pixels.
|
||||
* @param topMargin top margin
|
||||
* @param rightMargin right margin
|
||||
* @param bottomMargin bottom margin
|
||||
* @param leftMargin left margin
|
||||
*/
|
||||
void setCropMargins( int topMargin, int rightMargin, int bottomMargin, int leftMargin );
|
||||
|
||||
private slots:
|
||||
|
||||
void on_mWidthSpinBox_valueChanged( int value );
|
||||
void on_mHeightSpinBox_valueChanged( int value );
|
||||
void on_mResolutionSpinBox_valueChanged( int value );
|
||||
void clipToContentsToggled( bool state );
|
||||
|
||||
private:
|
||||
|
||||
QSizeF mImageSize;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // QGSCOMPOSERIMAGEEXPORTOPTIONSDIALOG_H
|
@ -325,6 +325,34 @@ QRectF QgsComposition::compositionBounds( bool ignorePages, double margin ) cons
|
||||
return bounds;
|
||||
}
|
||||
|
||||
QRectF QgsComposition::pageItemBounds( int pageNumber, bool visibleOnly ) const
|
||||
{
|
||||
//start with an empty rectangle
|
||||
QRectF bounds;
|
||||
|
||||
//add all QgsComposerItems on page
|
||||
QList<QGraphicsItem *> itemList = items();
|
||||
QList<QGraphicsItem *>::iterator itemIt = itemList.begin();
|
||||
for ( ; itemIt != itemList.end(); ++itemIt )
|
||||
{
|
||||
const QgsComposerItem* composerItem = dynamic_cast<const QgsComposerItem *>( *itemIt );
|
||||
const QgsPaperItem* paperItem = dynamic_cast<const QgsPaperItem*>( *itemIt );
|
||||
if ( composerItem && !paperItem && itemPageNumber( composerItem ) == pageNumber )
|
||||
{
|
||||
if ( visibleOnly && !composerItem->isVisible() )
|
||||
continue;
|
||||
|
||||
//expand bounds with current item's bounds
|
||||
if ( bounds.isValid() )
|
||||
bounds = bounds.united(( *itemIt )->sceneBoundingRect() );
|
||||
else
|
||||
bounds = ( *itemIt )->sceneBoundingRect();
|
||||
}
|
||||
}
|
||||
|
||||
return bounds;
|
||||
}
|
||||
|
||||
void QgsComposition::setPaperSize( const double width, const double height, bool keepRelativeItemPosition )
|
||||
{
|
||||
if ( width == mPageWidth && height == mPageHeight )
|
||||
@ -2877,6 +2905,23 @@ QImage QgsComposition::printPageAsRaster( int page )
|
||||
return image;
|
||||
}
|
||||
|
||||
QImage QgsComposition::renderRectAsRaster( const QRectF& rect )
|
||||
{
|
||||
int width = ( int )( printResolution() * rect.width() / 25.4 );
|
||||
int height = ( int )( printResolution() * rect.height() / 25.4 );
|
||||
QImage image( QSize( width, height ), QImage::Format_ARGB32 );
|
||||
if ( !image.isNull() )
|
||||
{
|
||||
image.setDotsPerMeterX( printResolution() / 25.4 * 1000 );
|
||||
image.setDotsPerMeterY( printResolution() / 25.4 * 1000 );
|
||||
image.fill( Qt::transparent );
|
||||
QPainter imagePainter( &image );
|
||||
renderRect( &imagePainter, rect );
|
||||
if ( !imagePainter.isActive() ) return QImage();
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
void QgsComposition::renderPage( QPainter* p, int page )
|
||||
{
|
||||
if ( mPages.size() <= page )
|
||||
@ -2890,21 +2935,25 @@ void QgsComposition::renderPage( QPainter* p, int page )
|
||||
return;
|
||||
}
|
||||
|
||||
QRectF paperRect = QRectF( paperItem->pos().x(), paperItem->pos().y(), paperItem->rect().width(), paperItem->rect().height() );
|
||||
renderRect( p, paperRect );
|
||||
}
|
||||
|
||||
void QgsComposition::renderRect( QPainter* p, const QRectF& rect )
|
||||
{
|
||||
QPaintDevice* paintDevice = p->device();
|
||||
if ( !paintDevice )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QRectF paperRect = QRectF( paperItem->pos().x(), paperItem->pos().y(), paperItem->rect().width(), paperItem->rect().height() );
|
||||
|
||||
QgsComposition::PlotStyle savedPlotStyle = mPlotStyle;
|
||||
mPlotStyle = QgsComposition::Print;
|
||||
|
||||
setSnapLinesVisible( false );
|
||||
//hide background before rendering
|
||||
setBackgroundBrush( Qt::NoBrush );
|
||||
render( p, QRectF( 0, 0, paintDevice->width(), paintDevice->height() ), paperRect );
|
||||
render( p, QRectF( 0, 0, paintDevice->width(), paintDevice->height() ), rect );
|
||||
//show background after rendering
|
||||
setBackgroundBrush( QColor( 215, 215, 215 ) );
|
||||
setSnapLinesVisible( true );
|
||||
@ -2937,6 +2986,19 @@ QGraphicsView *QgsComposition::graphicsView() const
|
||||
}
|
||||
|
||||
void QgsComposition::computeWorldFileParameters( double& a, double& b, double& c, double& d, double& e, double& f ) const
|
||||
{
|
||||
if ( !mWorldFileMap )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int pageNumber = mWorldFileMap->page() - 1;
|
||||
double pageY = pageNumber * ( mPageHeight + mSpaceBetweenPages );
|
||||
QRectF pageRect( 0, pageY, mPageWidth, mPageHeight );
|
||||
computeWorldFileParameters( pageRect, a, b, c, d, e, f );
|
||||
}
|
||||
|
||||
void QgsComposition::computeWorldFileParameters( const QRectF& exportRegion, double& a, double& b, double& c, double& d, double& e, double& f ) const
|
||||
{
|
||||
// World file parameters : affine transformation parameters from pixel coordinates to map coordinates
|
||||
|
||||
@ -2945,8 +3007,8 @@ void QgsComposition::computeWorldFileParameters( double& a, double& b, double& c
|
||||
return;
|
||||
}
|
||||
|
||||
double destinationHeight = paperHeight();
|
||||
double destinationWidth = paperWidth();
|
||||
double destinationHeight = exportRegion.height();
|
||||
double destinationWidth = exportRegion.width();
|
||||
|
||||
QRectF mapItemSceneRect = mWorldFileMap->mapRectToScene( mWorldFileMap->rect() );
|
||||
QgsRectangle mapExtent = *mWorldFileMap->currentMapExtent();
|
||||
@ -2959,10 +3021,14 @@ void QgsComposition::computeWorldFileParameters( double& a, double& b, double& c
|
||||
double xCenter = mapExtent.center().x();
|
||||
double yCenter = mapExtent.center().y();
|
||||
|
||||
// get the extent (in map units) for the page
|
||||
QPointF mapItemPosOnPage = mWorldFileMap->pagePos();
|
||||
double xmin = mapExtent.xMinimum() - mapItemPosOnPage.x() * xRatio;
|
||||
double ymax = mapExtent.yMaximum() + mapItemPosOnPage.y() * yRatio;
|
||||
// get the extent (in map units) for the region
|
||||
QPointF mapItemPos = mWorldFileMap->pos();
|
||||
//adjust item position so it is relative to export region
|
||||
mapItemPos.rx() -= exportRegion.left();
|
||||
mapItemPos.ry() -= exportRegion.top();
|
||||
|
||||
double xmin = mapExtent.xMinimum() - mapItemPos.x() * xRatio;
|
||||
double ymax = mapExtent.yMaximum() + mapItemPos.y() * yRatio;
|
||||
QgsRectangle paperExtent( xmin, ymax - destinationHeight * yRatio, xmin + destinationWidth * xRatio, ymax );
|
||||
|
||||
double X0 = paperExtent.xMinimum();
|
||||
|
@ -664,18 +664,59 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
|
||||
*/
|
||||
bool exportAsPDF( const QString& file );
|
||||
|
||||
//! print composer page to image
|
||||
//! If the image does not fit into memory, a null image is returned
|
||||
/** Renders a composer page to an image.
|
||||
* @param page page number, 0 based such that the first page is page 0
|
||||
* @returns rendered image, or null image if image does not fit into available memory
|
||||
* @see renderRectAsRaster()
|
||||
* @see renderPage()
|
||||
*/
|
||||
QImage printPageAsRaster( int page );
|
||||
|
||||
/** Render a page to a paint device
|
||||
/** Renders a portion of the composition to an image. This method can be used to render
|
||||
* sections of pages rather than full pages.
|
||||
* @param rect region of composition to render
|
||||
* @returns rendered image, or null image if image does not fit into available memory
|
||||
* @note added in QGIS 2.12
|
||||
* @see printPageAsRaster()
|
||||
* @see renderRect()
|
||||
*/
|
||||
QImage renderRectAsRaster( const QRectF& rect );
|
||||
|
||||
/** Renders a full page to a paint device.
|
||||
* @param p destination painter
|
||||
* @param page page number, 0 based such that the first page is page 0 */
|
||||
* @param page page number, 0 based such that the first page is page 0
|
||||
* @see renderRect()
|
||||
* @see printPageAsRaster()
|
||||
*/
|
||||
void renderPage( QPainter* p, int page );
|
||||
|
||||
/** Compute world file parameters */
|
||||
/** Renders a portion of the composition to a paint device. This method can be used
|
||||
* to render sections of pages rather than full pages.
|
||||
* @param p destination painter
|
||||
* @param rect region of composition to render
|
||||
* @note added in QGIS 2.12
|
||||
* @see renderPage()
|
||||
* @see renderRectAsRaster()
|
||||
*/
|
||||
void renderRect( QPainter* p, const QRectF& rect );
|
||||
|
||||
/** Compute world file parameters. Assumes the whole page containing the associated map item
|
||||
* will be exported.
|
||||
*/
|
||||
void computeWorldFileParameters( double& a, double& b, double& c, double& d, double& e, double& f ) const;
|
||||
|
||||
/** Computes the world file parameters for a specified region of the composition.
|
||||
* @param exportRegion region of the composition which will be associated with world file
|
||||
* @param a
|
||||
* @param b
|
||||
* @param c
|
||||
* @param d
|
||||
* @param e
|
||||
* @param f
|
||||
* @note added in QGIS 2.12
|
||||
*/
|
||||
void computeWorldFileParameters( const QRectF& exportRegion, double& a, double& b, double& c, double& d, double& e, double& f ) const;
|
||||
|
||||
QgsAtlasComposition& atlasComposition() { return mAtlasComposition; }
|
||||
|
||||
/** Resizes a QRectF relative to the change from boundsBefore to boundsAfter
|
||||
@ -766,6 +807,19 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
|
||||
*/
|
||||
QStringList customProperties() const;
|
||||
|
||||
/** Returns the bounding box of the items contained on a specified page.
|
||||
* @param pageNumber page number, where 0 is the first page
|
||||
* @param visibleOnly set to true to only include visible items
|
||||
* @note added in QGIS 2.12
|
||||
*/
|
||||
QRectF pageItemBounds( int pageNumber, bool visibleOnly = false ) const;
|
||||
|
||||
/** Calculates the bounds of all non-gui items in the composition. Ignores snap lines and mouse handles.
|
||||
* @param ignorePages set to true to ignore page items
|
||||
* @param margin optional marginal (in percent, eg 0.05 = 5% ) to add around items
|
||||
*/
|
||||
QRectF compositionBounds( bool ignorePages = false, double margin = 0.0 ) const;
|
||||
|
||||
public slots:
|
||||
/** Casts object to the proper subclass type and calls corresponding itemAdded signal*/
|
||||
void sendItemAddedSignal( QgsComposerItem* item );
|
||||
@ -894,12 +948,6 @@ class CORE_EXPORT QgsComposition : public QGraphicsScene
|
||||
|
||||
QgsComposition(); //default constructor is forbidden
|
||||
|
||||
/** Calculates the bounds of all non-gui items in the composition. Ignores snap lines and mouse handles.
|
||||
* @param ignorePages set to true to ignore page items
|
||||
* @param margin optional marginal (in percent, eg 0.05 = 5% ) to add around items
|
||||
*/
|
||||
QRectF compositionBounds( bool ignorePages = false, double margin = 0.0 ) const;
|
||||
|
||||
/** Reset z-values of items based on position in z list*/
|
||||
void updateZValues( const bool addUndoCommands = true );
|
||||
|
||||
|
317
src/ui/composer/qgscomposerimageexportoptions.ui
Normal file
317
src/ui/composer/qgscomposerimageexportoptions.ui
Normal file
@ -0,0 +1,317 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QgsComposerImageExportOptionsDialog</class>
|
||||
<widget class="QDialog" name="QgsComposerImageExportOptionsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>489</width>
|
||||
<height>325</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Image export options</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Export options</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Export resolution</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string>Page height</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" colspan="2">
|
||||
<widget class="QgsSpinBox" name="mResolutionSpinBox">
|
||||
<property name="suffix">
|
||||
<string> dpi</string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>3000</number>
|
||||
</property>
|
||||
<property name="showClearButton" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2" colspan="2">
|
||||
<widget class="QgsSpinBox" name="mWidthSpinBox">
|
||||
<property name="specialValueText">
|
||||
<string>Auto</string>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> px</string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>99999999</number>
|
||||
</property>
|
||||
<property name="showClearButton" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Page width</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2" colspan="2">
|
||||
<widget class="QgsSpinBox" name="mHeightSpinBox">
|
||||
<property name="specialValueText">
|
||||
<string>Auto</string>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> px</string>
|
||||
</property>
|
||||
<property name="prefix">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>99999999</number>
|
||||
</property>
|
||||
<property name="showClearButton" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<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>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QgsCollapsibleGroupBoxBasic" name="mClipToContentGroupBox">
|
||||
<property name="title">
|
||||
<string>Crop to content</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="1" column="0" colspan="4">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Left</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QgsSpinBox" name="mLeftMarginSpinBox">
|
||||
<property name="suffix">
|
||||
<string> px</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Right</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QgsSpinBox" name="mRightMarginSpinBox">
|
||||
<property name="suffix">
|
||||
<string> px</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>Bottom</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Top margin</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<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>
|
||||
<item row="0" column="2">
|
||||
<widget class="QgsSpinBox" name="mTopMarginSpinBox">
|
||||
<property name="suffix">
|
||||
<string> px</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QgsSpinBox" name="mBottomMarginSpinBox">
|
||||
<property name="suffix">
|
||||
<string> px</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<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>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QgsSpinBox</class>
|
||||
<extends>QSpinBox</extends>
|
||||
<header>qgsspinbox.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QgsCollapsibleGroupBoxBasic</class>
|
||||
<extends>QGroupBox</extends>
|
||||
<header location="global">qgscollapsiblegroupbox.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>mClipToContentGroupBox</tabstop>
|
||||
<tabstop>mTopMarginSpinBox</tabstop>
|
||||
<tabstop>mLeftMarginSpinBox</tabstop>
|
||||
<tabstop>mRightMarginSpinBox</tabstop>
|
||||
<tabstop>mBottomMarginSpinBox</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>QgsComposerImageExportOptionsDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>QgsComposerImageExportOptionsDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -6,56 +6,201 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>471</width>
|
||||
<height>103</height>
|
||||
<width>489</width>
|
||||
<height>282</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>SVG export options</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="chkMapLayersAsGroup">
|
||||
<property name="text">
|
||||
<string>Export map layers as svg groups (may affect label placement)</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="chkTextAsOutline">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Uncheck to render map labels as text objects. This will degrade the quality of the map labels but allow editing in vector illustration software.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Render map labels as outlines</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QgsCollapsibleGroupBoxBasic" name="groupBox">
|
||||
<property name="title">
|
||||
<string>SVG options</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="chkMapLayersAsGroup">
|
||||
<property name="text">
|
||||
<string>Export map layers as svg groups (may affect label placement)</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="chkTextAsOutline">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Uncheck to render map labels as text objects. This will degrade the quality of the map labels but allow editing in vector illustration software.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Render map labels as outlines</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QgsCollapsibleGroupBoxBasic" name="mClipToContentGroupBox">
|
||||
<property name="title">
|
||||
<string>Crop to content</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_5">
|
||||
<item row="0" column="2">
|
||||
<widget class="QgsDoubleSpinBox" name="mTopMarginSpinBox">
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="4">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Left</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QgsDoubleSpinBox" name="mLeftMarginSpinBox">
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Right</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QgsDoubleSpinBox" name="mRightMarginSpinBox">
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>Bottom</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QgsDoubleSpinBox" name="mBottomMarginSpinBox">
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Top margin (mm)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<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>
|
||||
</item>
|
||||
<item>
|
||||
<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>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QgsCollapsibleGroupBoxBasic</class>
|
||||
<extends>QGroupBox</extends>
|
||||
<header location="global">qgscollapsiblegroupbox.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QgsDoubleSpinBox</class>
|
||||
<extends>QDoubleSpinBox</extends>
|
||||
<header>qgsdoublespinbox.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>chkMapLayersAsGroup</tabstop>
|
||||
<tabstop>chkTextAsOutline</tabstop>
|
||||
<tabstop>mClipToContentGroupBox</tabstop>
|
||||
<tabstop>mTopMarginSpinBox</tabstop>
|
||||
<tabstop>mLeftMarginSpinBox</tabstop>
|
||||
<tabstop>mRightMarginSpinBox</tabstop>
|
||||
<tabstop>mBottomMarginSpinBox</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
|
@ -201,6 +201,17 @@ void TestQgsComposerMap::worldFileGeneration()
|
||||
QVERIFY( qgsDoubleNear( e, -4.17997, 0.001 ) );
|
||||
QVERIFY( qgsDoubleNear( f, 3.34241e+06, 1e+03 ) );
|
||||
|
||||
//test computing parameters for specific region
|
||||
mComposerMap->setItemPosition( 20, 20, QgsComposerItem::UpperLeft, 2 );
|
||||
mComposition->computeWorldFileParameters( QRectF( 10, 5, 260, 200 ), a, b, c, d, e, f );
|
||||
|
||||
QVERIFY( qgsDoubleNear( a, 4.18061, 0.001 ) );
|
||||
QVERIFY( qgsDoubleNear( b, 2.41321, 0.001 ) );
|
||||
QVERIFY( qgsDoubleNear( c, 773810, 1 ) );
|
||||
QVERIFY( qgsDoubleNear( d, 2.4137, 0.001 ) );
|
||||
QVERIFY( qgsDoubleNear( e, -4.1798, 0.001 ) );
|
||||
QVERIFY( qgsDoubleNear( f, 3.35331e+06, 1e+03 ) );
|
||||
|
||||
mComposition->setGenerateWorldFile( false );
|
||||
mComposerMap->setMapRotation( 0.0 );
|
||||
|
||||
|
@ -47,6 +47,7 @@ class TestQgsComposition : public QObject
|
||||
void pageIsEmpty(); //test the pageIsEmpty method
|
||||
void customProperties();
|
||||
void writeRetrieveCustomProperties();
|
||||
void bounds();
|
||||
void resizeToContents();
|
||||
void resizeToContentsMargin();
|
||||
void resizeToContentsMultiPage();
|
||||
@ -326,6 +327,64 @@ void TestQgsComposition::writeRetrieveCustomProperties()
|
||||
delete readComposition;
|
||||
}
|
||||
|
||||
void TestQgsComposition::bounds()
|
||||
{
|
||||
//add some items to a composition
|
||||
QgsComposition* composition = new QgsComposition( *mMapSettings );
|
||||
QgsComposerShape* shape1 = new QgsComposerShape( composition );
|
||||
shape1->setShapeType( QgsComposerShape::Rectangle );
|
||||
composition->addComposerShape( shape1 );
|
||||
shape1->setItemPosition( 90, 50, 90, 50, QgsComposerItem::UpperLeft, false, 1 );
|
||||
shape1->setItemRotation( 45 );
|
||||
QgsComposerShape* shape2 = new QgsComposerShape( composition );
|
||||
shape2->setShapeType( QgsComposerShape::Rectangle );
|
||||
composition->addComposerShape( shape2 );
|
||||
shape2->setItemPosition( 100, 150, 110, 50, QgsComposerItem::UpperLeft, false, 1 );
|
||||
QgsComposerShape* shape3 = new QgsComposerShape( composition );
|
||||
shape3->setShapeType( QgsComposerShape::Rectangle );
|
||||
composition->addComposerShape( shape3 );
|
||||
shape3->setItemPosition( 210, 30, 50, 100, QgsComposerItem::UpperLeft, false, 2 );
|
||||
QgsComposerShape* shape4 = new QgsComposerShape( composition );
|
||||
shape4->setShapeType( QgsComposerShape::Rectangle );
|
||||
composition->addComposerShape( shape4 );
|
||||
shape4->setItemPosition( 10, 120, 50, 30, QgsComposerItem::UpperLeft, false, 2 );
|
||||
shape4->setVisibility( false );
|
||||
|
||||
//check bounds
|
||||
QRectF compositionBounds = composition->compositionBounds( false );
|
||||
QVERIFY( qgsDoubleNear( compositionBounds.height(), 372.15, 0.01 ) );
|
||||
QVERIFY( qgsDoubleNear( compositionBounds.width(), 301.00, 0.01 ) );
|
||||
QVERIFY( qgsDoubleNear( compositionBounds.left(), -2, 0.01 ) );
|
||||
QVERIFY( qgsDoubleNear( compositionBounds.top(), -2, 0.01 ) );
|
||||
|
||||
QRectF compositionBoundsNoPage = composition->compositionBounds( true );
|
||||
QVERIFY( qgsDoubleNear( compositionBoundsNoPage.height(), 320.36, 0.01 ) );
|
||||
QVERIFY( qgsDoubleNear( compositionBoundsNoPage.width(), 250.30, 0.01 ) );
|
||||
QVERIFY( qgsDoubleNear( compositionBoundsNoPage.left(), 9.85, 0.01 ) );
|
||||
QVERIFY( qgsDoubleNear( compositionBoundsNoPage.top(), 49.79, 0.01 ) );
|
||||
|
||||
QRectF page1Bounds = composition->pageItemBounds( 0, true );
|
||||
QVERIFY( qgsDoubleNear( page1Bounds.height(), 150.36, 0.01 ) );
|
||||
QVERIFY( qgsDoubleNear( page1Bounds.width(), 155.72, 0.01 ) );
|
||||
QVERIFY( qgsDoubleNear( page1Bounds.left(), 54.43, 0.01 ) );
|
||||
QVERIFY( qgsDoubleNear( page1Bounds.top(), 49.79, 0.01 ) );
|
||||
|
||||
QRectF page2Bounds = composition->pageItemBounds( 1, true );
|
||||
QVERIFY( qgsDoubleNear( page2Bounds.height(), 100.30, 0.01 ) );
|
||||
QVERIFY( qgsDoubleNear( page2Bounds.width(), 50.30, 0.01 ) );
|
||||
QVERIFY( qgsDoubleNear( page2Bounds.left(), 209.85, 0.01 ) );
|
||||
QVERIFY( qgsDoubleNear( page2Bounds.top(), 249.85, 0.01 ) );
|
||||
|
||||
QRectF page2BoundsWithHidden = composition->pageItemBounds( 1, false );
|
||||
QVERIFY( qgsDoubleNear( page2BoundsWithHidden.height(), 120.30, 0.01 ) );
|
||||
QVERIFY( qgsDoubleNear( page2BoundsWithHidden.width(), 250.30, 0.01 ) );
|
||||
QVERIFY( qgsDoubleNear( page2BoundsWithHidden.left(), 9.85, 0.01 ) );
|
||||
QVERIFY( qgsDoubleNear( page2BoundsWithHidden.top(), 249.85, 0.01 ) );
|
||||
|
||||
delete composition;
|
||||
}
|
||||
|
||||
|
||||
void TestQgsComposition::resizeToContents()
|
||||
{
|
||||
//add some items to a composition
|
||||
|
Loading…
x
Reference in New Issue
Block a user