Skip to content

Commit 686f632

Browse files
committedSep 29, 2012
fix destruction of private members in atlas and add sip bindings (also adds
CORE_EXPORT)
1 parent 0c29b4b commit 686f632

File tree

3 files changed

+129
-81
lines changed

3 files changed

+129
-81
lines changed
 

‎python/core/composer/qgscomposition.sip

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,36 @@
1+
/** \ingroup MapComposer
2+
* Class used to render an Atlas, iterating over geometry features.
3+
* prepareForFeature() modifies the atlas map's extent to zoom on the given feature.
4+
* This class is used for printing, exporting to PDF and images.
5+
* */
6+
class QgsAtlasRendering
7+
{
8+
public:
9+
QgsAtlasRendering( QgsComposition* composition );
10+
~QgsAtlasRendering();
11+
12+
/** Begins the rendering. Sets an optional output filename pattern */
13+
void begin( const QString& filenamePattern = "" );
14+
/** Ends the rendering. Restores original extent*/
15+
void end();
16+
17+
/** Returns the number of features in the coverage layer */
18+
size_t numFeatures() const;
19+
20+
/** Prepare the atlas map for the given feature. Sets the extent and context variables */
21+
void prepareForFeature( size_t i );
22+
23+
/** Returns the current filename. Must be called after prepareForFeature( i ) */
24+
const QString& currentFilename() const;
25+
};
26+
127
/** \ingroup MapComposer
228
* Graphics scene for map printing. The class manages the paper item which always
329
* is the item in the back (z-value 0). It maintains the z-Values of the items and stores
430
* them in a list in ascending z-Order. This list can be changed to lower/raise items one position
531
* or to bring them to front/back.
632
* */
7-
class QgsComposition: QGraphicsScene
33+
class QgsComposition : QGraphicsScene
834
{
935
%TypeHeaderCode
1036
#include <qgscomposition.h>
@@ -67,20 +93,25 @@ class QgsComposition: QGraphicsScene
6793
/**Returns pointer to undo/redo command storage*/
6894
QUndoStack* undoStack();
6995

70-
/**Returns the topmose composer item. Ignores mPaperItem*/
96+
/**Returns the topmost composer item. Ignores mPaperItem*/
7197
QgsComposerItem* composerItemAt( const QPointF & position );
7298

99+
/** Returns the page number (0-bsaed) given a coordinate */
100+
int pageNumberAt( const QPointF& position ) const;
101+
102+
/** Returns on which page number (0-based) is displayed an item */
103+
int itemPageNumber( const QgsComposerItem* ) const;
104+
73105
QList<QgsComposerItem*> selectedComposerItems();
74106

75107
/**Returns pointers to all composer maps in the scene*/
76-
//todo: needs a new mapping for QList<const T*> ?
77-
// QList<const QgsComposerMap*> composerMapItems() const;
108+
QList<const QgsComposerMap*> composerMapItems() const;
78109

79110
/**Return composer items of a specific type*/
80111
// template<class T> void composerItems( QList<T*>& itemList );
81112

82113
/**Returns the composer map with specified id
83-
@return id or 0 pointer if the composer map item does not exist*/
114+
@return QgsComposerMap or 0 pointer if the composer map item does not exist*/
84115
const QgsComposerMap* getComposerMapById( int id ) const;
85116

86117
/*Returns the composer html with specified id (a string as named in the
@@ -111,7 +142,10 @@ class QgsComposition: QGraphicsScene
111142
/**Returns pointer to map renderer of qgis map canvas*/
112143
QgsMapRenderer* mapRenderer();
113144

114-
QgsComposition::PlotStyle plotStyle();
145+
QgsComposerMap* atlasMap();
146+
void setAtlasMap( QgsComposerMap* map );
147+
148+
QgsComposition::PlotStyle plotStyle() const;
115149
void setPlotStyle( QgsComposition::PlotStyle style );
116150

117151
/**Returns the pixel font size for a font that has point size set.
@@ -219,10 +253,19 @@ class QgsComposition: QGraphicsScene
219253

220254
//printing
221255

222-
void exportAsPDF( const QString& file );
256+
/** Prepare the printer for printing */
257+
void beginPrint( QPrinter& printer );
258+
/** Prepare the printer for printing in a PDF */
259+
void beginPrintAsPDF( QPrinter& printer, const QString& file );
260+
/** Print on a preconfigured printer */
261+
void doPrint( QPrinter& printer, QPainter& painter );
223262

263+
/** Convenience function that prepares the printer and prints */
224264
void print( QPrinter &printer );
225265

266+
/** Convenience function that prepares the printer for printing in PDF and prints */
267+
void exportAsPDF( const QString& file );
268+
226269
//! print composer page to image
227270
//! If the image does not fit into memory, a null image is returned
228271
QImage printPageAsRaster( int page );

‎src/core/composer/qgscomposition.cpp

Lines changed: 61 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,16 @@ struct QgsAtlasRendering::QgsAtlasRenderingImpl
6767

6868
QgsAtlasRendering::QgsAtlasRendering( QgsComposition* composition )
6969
{
70-
impl = std::auto_ptr<QgsAtlasRendering::QgsAtlasRenderingImpl>( new QgsAtlasRendering::QgsAtlasRenderingImpl() );
70+
impl = new QgsAtlasRendering::QgsAtlasRenderingImpl();
7171
impl->composition = composition;
7272
impl->nFeatures = 0;
7373
}
7474

75+
QgsAtlasRendering::~QgsAtlasRendering()
76+
{
77+
delete impl;
78+
}
79+
7580
void QgsAtlasRendering::begin( const QString& filenamePattern )
7681
{
7782
if ( !impl->composition || !impl->composition->atlasMap() || !impl->composition->atlasMap()->atlasCoverageLayer() )
@@ -131,7 +136,7 @@ void QgsAtlasRendering::begin( const QString& filenamePattern )
131136
}
132137

133138
// special columns for expressions
134-
QgsExpression::setSpecialColumn( "$numfeatures", QVariant( (int)impl->nFeatures ) );
139+
QgsExpression::setSpecialColumn( "$numfeatures", QVariant(( int )impl->nFeatures ) );
135140
}
136141

137142
void QgsAtlasRendering::prepareForFeature( size_t featureI )
@@ -140,24 +145,24 @@ void QgsAtlasRendering::prepareForFeature( size_t featureI )
140145
return;
141146

142147
QgsFeature* fit = &impl->features[featureI];
143-
148+
144149
if ( impl->filenamePattern.size() > 0 )
145150
{
146-
QgsExpression::setSpecialColumn( "$feature", QVariant( (int)featureI + 1 ) );
151+
QgsExpression::setSpecialColumn( "$feature", QVariant(( int )featureI + 1 ) );
147152
QVariant filenameRes = impl->filenameExpr->evaluate( &*fit );
148153
if ( impl->filenameExpr->hasEvalError() )
149154
{
150155
throw std::runtime_error( "Filename eval error: " + impl->filenameExpr->evalErrorString().toStdString() );
151156
}
152-
157+
153158
impl->currentFilename = filenameRes.toString();
154159
}
155-
160+
156161
//
157162
// compute the new extent
158163
// keep the original aspect ratio
159164
// and apply a margin
160-
165+
161166
// QgsGeometry::boundingBox is expressed in the geometry"s native CRS
162167
// We have to transform the grometry to the destination CRS and ask for the bounding box
163168
// Note: we cannot directly take the transformation of the bounding box, since transformations are not linear
@@ -171,63 +176,63 @@ void QgsAtlasRendering::prepareForFeature( size_t featureI )
171176
double ya1 = geom_rect.yMinimum();
172177
double ya2 = geom_rect.yMaximum();
173178
QgsRectangle new_extent = geom_rect;
174-
179+
175180
// restore the original extent
176181
// (successive calls to setNewExtent tend to deform the original rectangle)
177182
impl->composition->atlasMap()->setNewExtent( impl->origExtent );
178-
183+
179184
if ( impl->composition->atlasMap()->atlasFixedScale() )
180185
{
181186
// only translate, keep the original scale (i.e. width x height)
182-
183-
double geom_center_x = (xa1 + xa2) / 2.0;
184-
double geom_center_y = (ya1 + ya2) / 2.0;
187+
188+
double geom_center_x = ( xa1 + xa2 ) / 2.0;
189+
double geom_center_y = ( ya1 + ya2 ) / 2.0;
185190
double xx = geom_center_x - impl->origExtent.width() / 2.0;
186191
double yy = geom_center_y - impl->origExtent.height() / 2.0;
187192
new_extent = QgsRectangle( xx,
188-
yy,
189-
xx + impl->origExtent.width(),
190-
yy + impl->origExtent.height() );
193+
yy,
194+
xx + impl->origExtent.width(),
195+
yy + impl->origExtent.height() );
191196
}
192197
else
193198
{
194199
// auto scale
195-
200+
196201
double geom_ratio = geom_rect.width() / geom_rect.height();
197202
double map_ratio = impl->origExtent.width() / impl->origExtent.height();
198-
203+
199204
// geometry height is too big
200205
if ( geom_ratio < map_ratio )
201206
{
202-
new_extent = QgsRectangle( (xa1 + xa2 + map_ratio * (ya1 - ya2)) / 2.0,
203-
ya1,
204-
xa1 + map_ratio * (ya2 - ya1),
205-
ya2);
207+
new_extent = QgsRectangle(( xa1 + xa2 + map_ratio * ( ya1 - ya2 ) ) / 2.0,
208+
ya1,
209+
xa1 + map_ratio * ( ya2 - ya1 ),
210+
ya2 );
206211
}
207212
// geometry width is too big
208213
else if ( geom_ratio > map_ratio )
209214
{
210215
new_extent = QgsRectangle( xa1,
211-
(ya1 + ya2 + (xa1 - xa2) / map_ratio) / 2.0,
212-
xa2,
213-
ya1 + (xa2 - xa1) / map_ratio);
216+
( ya1 + ya2 + ( xa1 - xa2 ) / map_ratio ) / 2.0,
217+
xa2,
218+
ya1 + ( xa2 - xa1 ) / map_ratio );
214219
}
215220
if ( impl->composition->atlasMap()->atlasMargin() > 0.0 )
216221
{
217222
new_extent.scale( 1 + impl->composition->atlasMap()->atlasMargin() );
218223
}
219224
}
220-
225+
221226
// evaluate label expressions
222227
QList<QgsComposerLabel*> labels;
223228
impl->composition->composerItems( labels );
224-
QgsExpression::setSpecialColumn( "$feature", QVariant( (int)featureI + 1 ) );
225-
229+
QgsExpression::setSpecialColumn( "$feature", QVariant(( int )featureI + 1 ) );
230+
226231
for ( QList<QgsComposerLabel*>::iterator lit = labels.begin(); lit != labels.end(); ++lit )
227232
{
228-
(*lit)->setExpressionContext( fit, impl->composition->atlasMap()->atlasCoverageLayer() );
233+
( *lit )->setExpressionContext( fit, impl->composition->atlasMap()->atlasCoverageLayer() );
229234
}
230-
235+
231236
// set the new extent (and render)
232237
impl->composition->atlasMap()->setNewExtent( new_extent );
233238
}
@@ -252,7 +257,7 @@ void QgsAtlasRendering::end()
252257
impl->composition->composerItems( labels );
253258
for ( QList<QgsComposerLabel*>::iterator lit = labels.begin(); lit != labels.end(); ++lit )
254259
{
255-
(*lit)->setExpressionContext( 0, 0 );
260+
( *lit )->setExpressionContext( 0, 0 );
256261
}
257262

258263
// restore the coverage visibility
@@ -269,9 +274,9 @@ void QgsAtlasRendering::end()
269274
}
270275

271276
QgsComposition::QgsComposition( QgsMapRenderer* mapRenderer ) :
272-
QGraphicsScene( 0 ), mMapRenderer( mapRenderer ), mPlotStyle( QgsComposition::Preview ), mPageWidth( 297 ), mPageHeight( 210 ), mSpaceBetweenPages( 10 ), mPrintAsRaster( false ), mSelectionTolerance( 0.0 ),
273-
mSnapToGrid( false ), mSnapGridResolution( 0.0 ), mSnapGridOffsetX( 0.0 ), mSnapGridOffsetY( 0.0 ), mActiveItemCommand( 0 ), mActiveMultiFrameCommand( 0 ),
274-
mAtlasMap( 0 )
277+
QGraphicsScene( 0 ), mMapRenderer( mapRenderer ), mPlotStyle( QgsComposition::Preview ), mPageWidth( 297 ), mPageHeight( 210 ), mSpaceBetweenPages( 10 ), mPrintAsRaster( false ), mSelectionTolerance( 0.0 ),
278+
mSnapToGrid( false ), mSnapGridResolution( 0.0 ), mSnapGridOffsetX( 0.0 ), mSnapGridOffsetY( 0.0 ), mActiveItemCommand( 0 ), mActiveMultiFrameCommand( 0 ),
279+
mAtlasMap( 0 )
275280
{
276281
setBackgroundBrush( Qt::gray );
277282
addPaperItem();
@@ -280,23 +285,23 @@ QgsComposition::QgsComposition( QgsMapRenderer* mapRenderer ) :
280285
loadSettings();
281286

282287
// declare special columns with a default value
283-
QgsExpression::setSpecialColumn( "$page", QVariant((int)0) );
284-
QgsExpression::setSpecialColumn( "$feature", QVariant((int)0) );
285-
QgsExpression::setSpecialColumn( "$numpages", QVariant((int)0) );
286-
QgsExpression::setSpecialColumn( "$numfeatures", QVariant((int)0) );
288+
QgsExpression::setSpecialColumn( "$page", QVariant(( int )0 ) );
289+
QgsExpression::setSpecialColumn( "$feature", QVariant(( int )0 ) );
290+
QgsExpression::setSpecialColumn( "$numpages", QVariant(( int )0 ) );
291+
QgsExpression::setSpecialColumn( "$numfeatures", QVariant(( int )0 ) );
287292
}
288293

289294
QgsComposition::QgsComposition():
290-
QGraphicsScene( 0 ), mMapRenderer( 0 ), mPlotStyle( QgsComposition::Preview ), mPageWidth( 297 ), mPageHeight( 210 ), mSpaceBetweenPages( 10 ), mPrintAsRaster( false ),
291-
mSelectionTolerance( 0.0 ), mSnapToGrid( false ), mSnapGridResolution( 0.0 ), mSnapGridOffsetX( 0.0 ), mSnapGridOffsetY( 0.0 ), mActiveItemCommand( 0 ), mActiveMultiFrameCommand( 0 ),
292-
mAtlasMap( 0 )
295+
QGraphicsScene( 0 ), mMapRenderer( 0 ), mPlotStyle( QgsComposition::Preview ), mPageWidth( 297 ), mPageHeight( 210 ), mSpaceBetweenPages( 10 ), mPrintAsRaster( false ),
296+
mSelectionTolerance( 0.0 ), mSnapToGrid( false ), mSnapGridResolution( 0.0 ), mSnapGridOffsetX( 0.0 ), mSnapGridOffsetY( 0.0 ), mActiveItemCommand( 0 ), mActiveMultiFrameCommand( 0 ),
297+
mAtlasMap( 0 )
293298
{
294299
loadSettings();
295300

296-
QgsExpression::setSpecialColumn( "$page", QVariant((int)0) );
297-
QgsExpression::setSpecialColumn( "$feature", QVariant((int)0) );
298-
QgsExpression::setSpecialColumn( "$numpages", QVariant((int)0) );
299-
QgsExpression::setSpecialColumn( "$numfeatures", QVariant((int)0) );
301+
QgsExpression::setSpecialColumn( "$page", QVariant(( int )0 ) );
302+
QgsExpression::setSpecialColumn( "$feature", QVariant(( int )0 ) );
303+
QgsExpression::setSpecialColumn( "$numpages", QVariant(( int )0 ) );
304+
QgsExpression::setSpecialColumn( "$numfeatures", QVariant(( int )0 ) );
300305
}
301306

302307
QgsComposition::~QgsComposition()
@@ -356,7 +361,7 @@ void QgsComposition::setNumPages( int pages )
356361
}
357362

358363
// update the corresponding variable
359-
QgsExpression::setSpecialColumn( "$numpages", QVariant((int)numPages()) );
364+
QgsExpression::setSpecialColumn( "$numpages", QVariant(( int )numPages() ) );
360365

361366
emit nPagesChanged();
362367
}
@@ -394,12 +399,12 @@ QgsComposerItem* QgsComposition::composerItemAt( const QPointF & position )
394399

395400
int QgsComposition::pageNumberAt( const QPointF& position ) const
396401
{
397-
return position.y() / (paperHeight() + spaceBetweenPages() );
402+
return position.y() / ( paperHeight() + spaceBetweenPages() );
398403
}
399404

400405
int QgsComposition::itemPageNumber( const QgsComposerItem* item ) const
401406
{
402-
return pageNumberAt( QPointF( item->transform().dx(), item->transform().dy()) );
407+
return pageNumberAt( QPointF( item->transform().dx(), item->transform().dy() ) );
403408
}
404409

405410
QList<QgsComposerItem*> QgsComposition::selectedComposerItems()
@@ -1715,7 +1720,7 @@ void QgsComposition::addPaperItem()
17151720
paperItem->setZValue( 0 );
17161721
mPages.push_back( paperItem );
17171722

1718-
QgsExpression::setSpecialColumn( "$numpages", QVariant((int)mPages.size()) );
1723+
QgsExpression::setSpecialColumn( "$numpages", QVariant(( int )mPages.size() ) );
17191724
}
17201725

17211726
void QgsComposition::removePaperItems()
@@ -1725,7 +1730,7 @@ void QgsComposition::removePaperItems()
17251730
delete mPages.at( i );
17261731
}
17271732
mPages.clear();
1728-
QgsExpression::setSpecialColumn( "$numpages", QVariant((int)0) );
1733+
QgsExpression::setSpecialColumn( "$numpages", QVariant(( int )0 ) );
17291734
}
17301735

17311736
void QgsComposition::deleteAndRemoveMultiFrames()
@@ -1756,7 +1761,7 @@ void QgsComposition::exportAsPDF( const QString& file )
17561761

17571762
void QgsComposition::doPrint( QPrinter& printer, QPainter& p )
17581763
{
1759-
//QgsComposition starts page numbering at 0
1764+
//QgsComposition starts page numbering at 0
17601765
int fromPage = ( printer.fromPage() < 1 ) ? 0 : printer.fromPage() - 1 ;
17611766
int toPage = ( printer.toPage() < 1 ) ? numPages() - 1 : printer.toPage() - 1;
17621767

@@ -1859,11 +1864,11 @@ void QgsComposition::setAtlasMap( QgsComposerMap* map )
18591864
mAtlasMap = map;
18601865
if ( map != 0 )
18611866
{
1862-
QObject::connect( map, SIGNAL( atlasCoverageLayerChanged( QgsVectorLayer* )), this, SLOT( onAtlasCoverageChanged( QgsVectorLayer* ) ) );
1867+
QObject::connect( map, SIGNAL( atlasCoverageLayerChanged( QgsVectorLayer* ) ), this, SLOT( onAtlasCoverageChanged( QgsVectorLayer* ) ) );
18631868
}
18641869
else
18651870
{
1866-
QObject::disconnect( map, SIGNAL( atlasCoverageLayerChanged( QgsVectorLayer* )), this, SLOT( onAtlasCoverageChanged( QgsVectorLayer* ) ) );
1871+
QObject::disconnect( map, SIGNAL( atlasCoverageLayerChanged( QgsVectorLayer* ) ), this, SLOT( onAtlasCoverageChanged( QgsVectorLayer* ) ) );
18671872
}
18681873
}
18691874

@@ -1873,14 +1878,14 @@ void QgsComposition::onAtlasCoverageChanged( QgsVectorLayer* )
18731878
if ( mAtlasMap != 0 && mAtlasMap->atlasCoverageLayer() != 0 )
18741879
{
18751880
QgsVectorDataProvider* provider = mAtlasMap->atlasCoverageLayer()->dataProvider();
1876-
QgsExpression::setSpecialColumn( "$numfeatures", QVariant( (int)provider->featureCount() ) );
1881+
QgsExpression::setSpecialColumn( "$numfeatures", QVariant(( int )provider->featureCount() ) );
18771882
}
18781883
else
18791884
{
1880-
QgsExpression::setSpecialColumn( "$numfeatures", QVariant( (int)0 ) );
1885+
QgsExpression::setSpecialColumn( "$numfeatures", QVariant(( int )0 ) );
18811886
}
1882-
//
1883-
QgsExpression::setSpecialColumn( "$numpages", QVariant( (int)numPages() ) );
1887+
//
1888+
QgsExpression::setSpecialColumn( "$numpages", QVariant(( int )numPages() ) );
18841889
}
18851890

18861891
QString QgsComposition::encodeStringForXML( const QString& str )

‎src/core/composer/qgscomposition.h

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -55,29 +55,30 @@ class QgsVectorLayer;
5555
* prepareForFeature() modifies the atlas map's extent to zoom on the given feature.
5656
* This class is used for printing, exporting to PDF and images.
5757
* */
58-
class QgsAtlasRendering
58+
class CORE_EXPORT QgsAtlasRendering
5959
{
60-
public:
61-
QgsAtlasRendering( QgsComposition* composition );
60+
public:
61+
QgsAtlasRendering( QgsComposition* composition );
62+
~QgsAtlasRendering();
6263

63-
/** Begins the rendering. Sets an optional output filename pattern */
64-
void begin( const QString& filenamePattern = "" );
65-
/** Ends the rendering. Restores original extent*/
66-
void end();
64+
/** Begins the rendering. Sets an optional output filename pattern */
65+
void begin( const QString& filenamePattern = "" );
66+
/** Ends the rendering. Restores original extent*/
67+
void end();
6768

68-
/** Returns the number of features in the coverage layer */
69-
size_t numFeatures() const;
69+
/** Returns the number of features in the coverage layer */
70+
size_t numFeatures() const;
7071

71-
/** Prepare the atlas map for the given feature. Sets the extent and context variables */
72-
void prepareForFeature( size_t i );
72+
/** Prepare the atlas map for the given feature. Sets the extent and context variables */
73+
void prepareForFeature( size_t i );
7374

74-
/** Returns the current filename. Must be called after prepareForFeature( i ) */
75-
const QString& currentFilename() const;
75+
/** Returns the current filename. Must be called after prepareForFeature( i ) */
76+
const QString& currentFilename() const;
7677

77-
private:
78-
// Use the PImpl idiom for private members.
79-
struct QgsAtlasRenderingImpl;
80-
std::auto_ptr<QgsAtlasRenderingImpl> impl;
78+
private:
79+
struct QgsAtlasRenderingImpl;
80+
// Use the PImpl idiom for private members.
81+
QgsAtlasRenderingImpl *impl;
8182
};
8283

8384
/** \ingroup MapComposer
@@ -159,7 +160,6 @@ class CORE_EXPORT QgsComposition: public QGraphicsScene
159160
QList<QgsComposerItem*> selectedComposerItems();
160161

161162
/**Returns pointers to all composer maps in the scene
162-
@note not available in python bindings
163163
*/
164164
QList<const QgsComposerMap*> composerMapItems() const;
165165

0 commit comments

Comments
 (0)
Please sign in to comment.