QGIS API Documentation  2.4.0-Chugiak
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgscomposerpicture.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscomposerpicture.cpp
3  -------------------
4  begin : September 2005
5  copyright : (C) 2005 by Radim Blazek
6  email : [email protected]
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "qgscomposerpicture.h"
19 #include "qgscomposermap.h"
20 #include "qgscomposition.h"
21 #include "qgsatlascomposition.h"
22 #include "qgsproject.h"
23 #include "qgsexpression.h"
24 #include "qgsvectorlayer.h"
25 #include "qgsmessagelog.h"
26 #include <QDomDocument>
27 #include <QDomElement>
28 #include <QFileInfo>
29 #include <QImageReader>
30 #include <QPainter>
31 #include <QSvgRenderer>
32 
33 
35  QgsComposerItem( composition ),
36  mMode( Unknown ),
37  mUseSourceExpression( false ),
38  mPictureRotation( 0 ),
39  mRotationMap( 0 ),
40  mResizeMode( QgsComposerPicture::Zoom ),
41  mPictureAnchor( UpperLeft ),
42  mPictureExpr( 0 )
43 {
44  mPictureWidth = rect().width();
45  init();
46 }
47 
49  mMode( Unknown ),
50  mUseSourceExpression( false ),
51  mPictureRotation( 0 ),
52  mRotationMap( 0 ),
53  mResizeMode( QgsComposerPicture::Zoom ),
54  mPictureAnchor( UpperLeft ),
55  mPictureExpr( 0 )
56 {
57  mPictureHeight = rect().height();
58  init();
59 }
60 
62 {
63  //connect some signals
64 
65  //connect to atlas feature changing
66  //to update the picture source expression
67  connect( &mComposition->atlasComposition(), SIGNAL( featureChanged( QgsFeature* ) ), this, SLOT( refreshPicture() ) );
68 
69  //connect to composer print resolution changing
70  connect( mComposition, SIGNAL( printResolutionChanged() ), this, SLOT( recalculateSize() ) );
71 }
72 
74 {
75 
76 }
77 
78 void QgsComposerPicture::paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget )
79 {
80  Q_UNUSED( itemStyle );
81  Q_UNUSED( pWidget );
82  if ( !painter )
83  {
84  return;
85  }
86 
87  drawBackground( painter );
88 
89  //int newDpi = ( painter->device()->logicalDpiX() + painter->device()->logicalDpiY() ) / 2;
90 
91  //picture resizing
92  if ( mMode != Unknown )
93  {
94  double boundRectWidthMM;
95  double boundRectHeightMM;
96  QRect imageRect;
98  {
99  boundRectWidthMM = mPictureWidth;
100  boundRectHeightMM = mPictureHeight;
101  imageRect = QRect( 0, 0, mImage.width(), mImage.height() );
102  }
104  {
105  boundRectWidthMM = rect().width();
106  boundRectHeightMM = rect().height();
107  imageRect = QRect( 0, 0, mImage.width(), mImage.height() );
108  }
110  {
111  boundRectWidthMM = rect().width();
112  boundRectHeightMM = rect().height();
113  int imageRectWidthPixels = mImage.width();
114  int imageRectHeightPixels = mImage.height();
115  imageRect = clippedImageRect( boundRectWidthMM, boundRectHeightMM ,
116  QSize( imageRectWidthPixels, imageRectHeightPixels ) );
117  }
118  else
119  {
120  boundRectWidthMM = rect().width();
121  boundRectHeightMM = rect().height();
122  imageRect = QRect( 0, 0, rect().width() * mComposition->printResolution() / 25.4,
123  rect().height() * mComposition->printResolution() / 25.4 );
124  }
125  painter->save();
126 
127  //zoom mode - calculate anchor point and rotation
128  if ( mResizeMode == Zoom )
129  {
130  //TODO - allow placement modes with rotation set. for now, setting a rotation
131  //always places picture in center of frame
132  if ( mPictureRotation != 0 )
133  {
134  painter->translate( rect().width() / 2.0, rect().height() / 2.0 );
135  painter->rotate( mPictureRotation );
136  painter->translate( -boundRectWidthMM / 2.0, -boundRectHeightMM / 2.0 );
137  }
138  else
139  {
140  //shift painter to edge/middle of frame depending on placement
141  double diffX = rect().width() - boundRectWidthMM;
142  double diffY = rect().height() - boundRectHeightMM;
143 
144  double dX = 0;
145  double dY = 0;
146  switch ( mPictureAnchor )
147  {
148  case UpperLeft:
149  case MiddleLeft:
150  case LowerLeft:
151  //nothing to do
152  break;
153  case UpperMiddle:
154  case Middle:
155  case LowerMiddle:
156  dX = diffX / 2.0;
157  break;
158  case UpperRight:
159  case MiddleRight:
160  case LowerRight:
161  dX = diffX;
162  break;
163  }
164  switch ( mPictureAnchor )
165  {
166  case UpperLeft:
167  case UpperMiddle:
168  case UpperRight:
169  //nothing to do
170  break;
171  case MiddleLeft:
172  case Middle:
173  case MiddleRight:
174  dY = diffY / 2.0;
175  break;
176  case LowerLeft:
177  case LowerMiddle:
178  case LowerRight:
179  dY = diffY;
180  break;
181  }
182  painter->translate( dX, dY );
183  }
184  }
185 
186  if ( mMode == SVG )
187  {
188  mSVG.render( painter, QRectF( 0, 0, boundRectWidthMM, boundRectHeightMM ) );
189  }
190  else if ( mMode == RASTER )
191  {
192  painter->drawImage( QRectF( 0, 0, boundRectWidthMM, boundRectHeightMM ), mImage, imageRect );
193  }
194 
195  painter->restore();
196  }
197 
198  //frame and selection boxes
199  drawFrame( painter );
200  if ( isSelected() )
201  {
202  drawSelectionBoxes( painter );
203  }
204 }
205 
206 QRect QgsComposerPicture::clippedImageRect( double &boundRectWidthMM, double &boundRectHeightMM, QSize imageRectPixels )
207 {
208  int boundRectWidthPixels = boundRectWidthMM * mComposition->printResolution() / 25.4;
209  int boundRectHeightPixels = boundRectHeightMM * mComposition->printResolution() / 25.4;
210 
211  //update boundRectWidth/Height so that they exactly match pixel bounds
212  boundRectWidthMM = boundRectWidthPixels * 25.4 / mComposition->printResolution();
213  boundRectHeightMM = boundRectHeightPixels * 25.4 / mComposition->printResolution();
214 
215  //calculate part of image which fits in bounds
216  int leftClip = 0;
217  int topClip = 0;
218 
219  //calculate left crop
220  switch ( mPictureAnchor )
221  {
222  case UpperLeft:
223  case MiddleLeft:
224  case LowerLeft:
225  leftClip = 0;
226  break;
227  case UpperMiddle:
228  case Middle:
229  case LowerMiddle:
230  leftClip = ( imageRectPixels.width() - boundRectWidthPixels ) / 2;
231  break;
232  case UpperRight:
233  case MiddleRight:
234  case LowerRight:
235  leftClip = imageRectPixels.width() - boundRectWidthPixels;
236  break;
237  }
238 
239  //calculate top crop
240  switch ( mPictureAnchor )
241  {
242  case UpperLeft:
243  case UpperMiddle:
244  case UpperRight:
245  topClip = 0;
246  break;
247  case MiddleLeft:
248  case Middle:
249  case MiddleRight:
250  topClip = ( imageRectPixels.height() - boundRectHeightPixels ) / 2;
251  break;
252  case LowerLeft:
253  case LowerMiddle:
254  case LowerRight:
255  topClip = imageRectPixels.height() - boundRectHeightPixels;
256  break;
257  }
258 
259 
260  return QRect( leftClip, topClip, boundRectWidthPixels, boundRectHeightPixels );
261 
262 }
263 
264 void QgsComposerPicture::setPictureFile( const QString& path )
265 {
266  mSourceFile.setFileName( path );
267  refreshPicture();
268 }
269 
271 {
272  QgsVectorLayer * vl = 0;
274  {
276  }
277 
278  if ( mSourceExpression.size() > 0 )
279  {
280  if ( mPictureExpr )
281  {
282  delete mPictureExpr;
283  }
285  // expression used to evaluate picture source
286  // test for evaluation errors
287  if ( mPictureExpr->hasParserError() )
288  {
289  QgsMessageLog::logMessage( tr( "Picture expression parsing error: %1" ).arg( mPictureExpr->parserErrorString() ), tr( "Composer" ) );
290  }
291 
292  if ( vl )
293  {
294  const QgsFields& fields = vl->pendingFields();
295  mPictureExpr->prepare( fields );
296  }
297  }
298 }
299 
301 {
302  //generate filename for picture
303  if ( mSourceExpression.size() > 0 && mUseSourceExpression )
304  {
305  if ( ! mPictureExpr )
306  {
307  return QString();
308  }
309 
310  QVariant filenameRes;
312  if ( atlas->enabled() )
313  {
314  //expression needs to be evaluated considering the current atlas feature
315  filenameRes = mPictureExpr->evaluate( atlas->currentFeature(),
316  atlas->coverageLayer()->pendingFields() );
317  }
318  else
319  {
320  filenameRes = mPictureExpr->evaluate();
321  }
322 
323  if ( mPictureExpr->hasEvalError() )
324  {
325  QgsMessageLog::logMessage( tr( "Picture expression eval error: %1" ).arg( mPictureExpr->evalErrorString() ), tr( "Composer" ) );
326  }
327 
328  return filenameRes.toString();
329  }
330  else
331  {
332  return QString();
333  }
334 }
335 
337 {
338  if ( mUseSourceExpression )
339  {
340  //using expression for picture source file
341 
342  //evaluate expression
343  QFile path;
344  path.setFileName( evalPictureExpression() );
345  loadPicture( path );
346  }
347  else
348  {
349  //using a static picture path
351  }
352 }
353 
355 {
356  if ( !file.exists()
358  {
359  mMode = Unknown;
360  }
361  else
362  {
363  QFileInfo sourceFileInfo( file );
364  QString sourceFileSuffix = sourceFileInfo.suffix();
365  if ( sourceFileSuffix.compare( "svg", Qt::CaseInsensitive ) == 0 )
366  {
367  //try to open svg
368  mSVG.load( file.fileName() );
369  if ( mSVG.isValid() )
370  {
371  mMode = SVG;
372  QRect viewBox = mSVG.viewBox(); //take width/height ratio from view box instead of default size
373  mDefaultSvgSize.setWidth( viewBox.width() );
374  mDefaultSvgSize.setHeight( viewBox.height() );
375  }
376  else
377  {
378  mMode = Unknown;
379  }
380  }
381  else
382  {
383  //try to open raster with QImageReader
384  QImageReader imageReader( file.fileName() );
385  if ( imageReader.read( &mImage ) )
386  {
387  mMode = RASTER;
388  }
389  else
390  {
391  mMode = Unknown;
392  }
393  }
394  }
395 
396  if ( mMode != Unknown ) //make sure we start with a new QImage
397  {
398  recalculateSize();
399  }
400  else if ( !( file.fileName().isEmpty() ) || ( mUseSourceExpression && mPictureExpr && mPictureExpr->hasEvalError() ) )
401  {
402  //trying to load an invalid file or bad expression, show cross picture
403  mMode = SVG;
404  QString badFile = QString( ":/images/composer/missing_image.svg" );
405  mSVG.load( badFile );
406  if ( mSVG.isValid() )
407  {
408  mMode = SVG;
409  QRect viewBox = mSVG.viewBox(); //take width/height ratio from view box instead of default size
410  mDefaultSvgSize.setWidth( viewBox.width() );
411  mDefaultSvgSize.setHeight( viewBox.height() );
412  recalculateSize();
413  }
414  }
415 
416  emit itemChanged();
417 }
418 
419 QRectF QgsComposerPicture::boundedImageRect( double deviceWidth, double deviceHeight )
420 {
421  double imageToDeviceRatio;
422  if ( mImage.width() / deviceWidth > mImage.height() / deviceHeight )
423  {
424  imageToDeviceRatio = deviceWidth / mImage.width();
425  double height = imageToDeviceRatio * mImage.height();
426  return QRectF( 0, 0, deviceWidth, height );
427  }
428  else
429  {
430  imageToDeviceRatio = deviceHeight / mImage.height();
431  double width = imageToDeviceRatio * mImage.width();
432  return QRectF( 0, 0, width, deviceHeight );
433  }
434 }
435 
436 QRectF QgsComposerPicture::boundedSVGRect( double deviceWidth, double deviceHeight )
437 {
438  double imageToSvgRatio;
439  if ( deviceWidth / mDefaultSvgSize.width() > deviceHeight / mDefaultSvgSize.height() )
440  {
441  imageToSvgRatio = deviceHeight / mDefaultSvgSize.height();
442  double width = mDefaultSvgSize.width() * imageToSvgRatio;
443  return QRectF( 0, 0, width, deviceHeight );
444  }
445  else
446  {
447  imageToSvgRatio = deviceWidth / mDefaultSvgSize.width();
448  double height = mDefaultSvgSize.height() * imageToSvgRatio;
449  return QRectF( 0, 0, deviceWidth, height );
450  }
451 }
452 
454 {
455  if ( mMode == SVG )
456  {
457  return mDefaultSvgSize;
458  }
459  else if ( mMode == RASTER )
460  {
461  return QSizeF( mImage.width(), mImage.height() );
462  }
463  else
464  {
465  return QSizeF( 0, 0 );
466  }
467 }
468 
469 #if 0
470 QRectF QgsComposerPicture::boundedSVGRect( double deviceWidth, double deviceHeight )
471 {
472  double imageToSvgRatio;
473  if ( deviceWidth / mDefaultSvgSize.width() < deviceHeight / mDefaultSvgSize.height() )
474  {
475  imageToSvgRatio = deviceWidth / mDefaultSvgSize.width();
476  double height = mDefaultSvgSize.height() * imageToSvgRatio;
477  return QRectF( 0, 0, deviceWidth, height );
478  }
479  else
480  {
481  imageToSvgRatio = deviceHeight / mDefaultSvgSize.height();
482  double width = mDefaultSvgSize.width() * imageToSvgRatio;
483  return QRectF( 0, 0, width, deviceHeight );
484  }
485 }
486 #endif //0
487 
488 void QgsComposerPicture::setSceneRect( const QRectF& rectangle )
489 {
490 
491  QSizeF currentPictureSize = pictureSize();
492 
494  {
495  QgsComposerItem::setSceneRect( rectangle );
496  mPictureWidth = rectangle.width();
497  mPictureHeight = rectangle.height();
498  return;
499  }
500 
501  QRectF newRect = rectangle;
502 
503  if ( mResizeMode == ZoomResizeFrame && !rect().isEmpty() && !( currentPictureSize.isEmpty() ) )
504  {
505  //if width has changed less than height, then fix width and set height correspondingly
506  //else, do the opposite
507  if ( qAbs( rect().width() - rectangle.width() ) <
508  qAbs( rect().height() - rectangle.height() ) )
509  {
510  newRect.setHeight( currentPictureSize.height() * newRect.width() / currentPictureSize.width() );
511  }
512  else
513  {
514  newRect.setWidth( currentPictureSize.width() * newRect.height() / currentPictureSize.height() );
515  }
516  }
517  else if ( mResizeMode == FrameToImageSize )
518  {
519  if ( !( currentPictureSize.isEmpty() ) )
520  {
521  newRect.setWidth( currentPictureSize.width() * 25.4 / mComposition->printResolution() );
522  newRect.setHeight( currentPictureSize.height() * 25.4 / mComposition->printResolution() );
523  }
524  }
525 
526  //find largest scaling of picture with this rotation which fits in item
527  if ( mResizeMode == Zoom )
528  {
529  QRectF rotatedImageRect = largestRotatedRectWithinBounds( QRectF( 0, 0, currentPictureSize.width(), currentPictureSize.height() ), newRect, mPictureRotation );
530  mPictureWidth = rotatedImageRect.width();
531  mPictureHeight = rotatedImageRect.height();
532  }
533  else
534  {
535  mPictureWidth = newRect.width();
536  mPictureHeight = newRect.height();
537  }
538 
540  emit itemChanged();
541 }
542 
544 {
545  //kept for compatibility for QGIS2.0 api
546  setPictureRotation( r );
547 }
548 
550 {
551  mPictureRotation = r;
552 
553  if ( mResizeMode == Zoom )
554  {
555  //find largest scaling of picture with this rotation which fits in item
556  QSizeF currentPictureSize = pictureSize();
557  QRectF rotatedImageRect = largestRotatedRectWithinBounds( QRectF( 0, 0, currentPictureSize.width(), currentPictureSize.height() ), rect(), mPictureRotation );
558  mPictureWidth = rotatedImageRect.width();
559  mPictureHeight = rotatedImageRect.height();
560  update();
561  }
562 
564 }
565 
566 void QgsComposerPicture::setRotationMap( int composerMapId )
567 {
568  if ( !mComposition )
569  {
570  return;
571  }
572 
573  if ( composerMapId == -1 ) //disable rotation from map
574  {
575  QObject::disconnect( mRotationMap, SIGNAL( mapRotationChanged( double ) ), this, SLOT( setPictureRotation( double ) ) );
576  mRotationMap = 0;
577  }
578 
579  const QgsComposerMap* map = mComposition->getComposerMapById( composerMapId );
580  if ( !map )
581  {
582  return;
583  }
584  if ( mRotationMap )
585  {
586  QObject::disconnect( mRotationMap, SIGNAL( mapRotationChanged( double ) ), this, SLOT( setPictureRotation( double ) ) );
587  }
588  mPictureRotation = map->mapRotation();
589  QObject::connect( map, SIGNAL( mapRotationChanged( double ) ), this, SLOT( setPictureRotation( double ) ) );
590  mRotationMap = map;
591  update();
593 }
594 
596 {
597  mResizeMode = mode;
599  || ( mode == QgsComposerPicture::Zoom && mPictureRotation != 0 ) )
600  {
601  //call set scene rect to force item to resize to fit picture
602  recalculateSize();
603  }
604  update();
605 }
606 
608 {
609  //call set scene rect with current position/size, as this will trigger the
610  //picture item to recalculate its frame and image size
611  setSceneRect( QRectF( pos().x(), pos().y(), rect().width(), rect().height() ) );
612 }
613 
615 {
616  if ( useExpression == mUseSourceExpression )
617  {
618  return;
619  }
620 
621  mUseSourceExpression = useExpression;
622  if ( useExpression )
623  {
625  }
626 
627  refreshPicture();
628 }
629 
631 {
632  if ( expression == mSourceExpression )
633  {
634  return;
635  }
636 
637  mSourceExpression = expression;
638 
639  if ( mUseSourceExpression )
640  {
642  refreshPicture();
643  }
644 }
645 
647 {
648  return mSourceFile.fileName();
649 }
650 
651 bool QgsComposerPicture::writeXML( QDomElement& elem, QDomDocument & doc ) const
652 {
653  if ( elem.isNull() )
654  {
655  return false;
656  }
657  QDomElement composerPictureElem = doc.createElement( "ComposerPicture" );
658  composerPictureElem.setAttribute( "file", QgsProject::instance()->writePath( mSourceFile.fileName() ) );
659  composerPictureElem.setAttribute( "pictureWidth", QString::number( mPictureWidth ) );
660  composerPictureElem.setAttribute( "pictureHeight", QString::number( mPictureHeight ) );
661  composerPictureElem.setAttribute( "resizeMode", QString::number(( int )mResizeMode ) );
662  composerPictureElem.setAttribute( "anchorPoint", QString::number(( int )mPictureAnchor ) );
663 
664  if ( mUseSourceExpression )
665  {
666  composerPictureElem.setAttribute( "useExpression", "true" );
667  }
668  else
669  {
670  composerPictureElem.setAttribute( "useExpression", "false" );
671  }
672  composerPictureElem.setAttribute( "sourceExpression", mSourceExpression );
673 
674  //rotation
675  composerPictureElem.setAttribute( "pictureRotation", QString::number( mPictureRotation ) );
676  if ( !mRotationMap )
677  {
678  composerPictureElem.setAttribute( "mapId", -1 );
679  }
680  else
681  {
682  composerPictureElem.setAttribute( "mapId", mRotationMap->id() );
683  }
684 
685  _writeXML( composerPictureElem, doc );
686  elem.appendChild( composerPictureElem );
687  return true;
688 }
689 
690 bool QgsComposerPicture::readXML( const QDomElement& itemElem, const QDomDocument& doc )
691 {
692  if ( itemElem.isNull() )
693  {
694  return false;
695  }
696 
697  mPictureWidth = itemElem.attribute( "pictureWidth", "10" ).toDouble();
698  mPictureHeight = itemElem.attribute( "pictureHeight", "10" ).toDouble();
699  mResizeMode = QgsComposerPicture::ResizeMode( itemElem.attribute( "resizeMode", "0" ).toInt() );
700  //when loading from xml, default to anchor point of middle to match pre 2.4 behaviour
701  mPictureAnchor = ( QgsComposerItem::ItemPositionMode ) itemElem.attribute( "anchorPoint", QString::number( QgsComposerItem::Middle ) ).toInt();
702 
703  QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" );
704  if ( composerItemList.size() > 0 )
705  {
706  QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
707 
708  if ( composerItemElem.attribute( "rotation", "0" ).toDouble() != 0 )
709  {
710  //in versions prior to 2.1 picture rotation was stored in the rotation attribute
711  mPictureRotation = composerItemElem.attribute( "rotation", "0" ).toDouble();
712  }
713 
714  _readXML( composerItemElem, doc );
715  }
716 
717  mDefaultSvgSize = QSize( 0, 0 );
718 
719 
720  mSourceExpression = itemElem.attribute( "sourceExpression", "" );
721  QString useExpression = itemElem.attribute( "useExpression" );
722  if ( useExpression.compare( "true", Qt::CaseInsensitive ) == 0 )
723  {
724  mUseSourceExpression = true;
726  }
727  else
728  {
729  mUseSourceExpression = false;
730  }
731 
732  QString fileName = QgsProject::instance()->readPath( itemElem.attribute( "file" ) );
733  mSourceFile.setFileName( fileName );
734 
735  //picture rotation
736  if ( itemElem.attribute( "pictureRotation", "0" ).toDouble() != 0 )
737  {
738  mPictureRotation = itemElem.attribute( "pictureRotation", "0" ).toDouble();
739  }
740 
741  //rotation map
742  int rotationMapId = itemElem.attribute( "mapId", "-1" ).toInt();
743  if ( rotationMapId == -1 )
744  {
745  mRotationMap = 0;
746  }
747  else if ( mComposition )
748  {
749 
750  if ( mRotationMap )
751  {
752  QObject::disconnect( mRotationMap, SIGNAL( mapRotationChanged( double ) ), this, SLOT( setRotation( double ) ) );
753  }
754  mRotationMap = mComposition->getComposerMapById( rotationMapId );
755  QObject::connect( mRotationMap, SIGNAL( mapRotationChanged( double ) ), this, SLOT( setRotation( double ) ) );
756  }
757 
758  refreshPicture();
759 
760  emit itemChanged();
761  return true;
762 }
763 
765 {
766  if ( !mRotationMap )
767  {
768  return -1;
769  }
770  else
771  {
772  return mRotationMap->id();
773  }
774 }
775 
777 {
778  mPictureAnchor = anchor;
779  update();
780 }
781 
782 bool QgsComposerPicture::imageSizeConsideringRotation( double& width, double& height ) const
783 {
784  //kept for api compatibility with QGIS 2.0 - use mPictureRotation
786 }
787 
788 bool QgsComposerPicture::cornerPointOnRotatedAndScaledRect( double& x, double& y, double width, double height ) const
789 {
790  //kept for api compatibility with QGIS 2.0 - use mPictureRotation
792 }
793 
794 void QgsComposerPicture::sizeChangedByRotation( double& width, double& height )
795 {
796  //kept for api compatibility with QGIS 2.0 - use mPictureRotation
798 }
Class for parsing and evaluation of expressions (formerly called "search strings").
Definition: qgsexpression.h:89
bool hasEvalError() const
Returns true if an error occurred when evaluating last input.
bool imageSizeConsideringRotation(double &width, double &height, double rotation) const
Calculates width and hight of the picture (in mm) such that it fits into the item frame with the give...
void setSceneRect(const QRectF &rectangle)
Sets this items bound in scene coordinates such that 1 item size units corresponds to 1 scene size un...
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
Definition: qgsexpression.h:96
bool readXML(const QDomElement &itemElem, const QDomDocument &doc)
sets state from Dom document
QVariant evaluate(const QgsFeature *f=NULL)
Evaluate the feature and return the result.
bool prepare(const QgsFields &fields)
Get the expression ready for evaluation - find out column indexes.
QSizeF pictureSize()
Returns size of current raster or svg picture.
Q_DECL_DEPRECATED bool imageSizeConsideringRotation(double &width, double &height) const
Calculates width and hight of the picture (in mm) such that it fits into the item frame with the give...
Mode mode() const
Returns the current picture mode (image format).
A item that forms part of a map composition.
bool enabled() const
Returns whether the atlas generation is enabled.
virtual void setRotation(double r)
Sets the picture rotation within the item bounds.
Container of fields for a vector layer.
Definition: qgsfield.h:161
QgsComposerItem::ItemPositionMode mPictureAnchor
virtual void drawFrame(QPainter *p)
Draw black frame around item.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:113
double mapRotation() const
Returns the rotation used for drawing the map within the composer item.
QString readPath(QString filename) const
turn filename read from the project file to an absolute path
A composer class that displays svg files or raster format (jpg, png, ...)
static void logMessage(QString message, QString tag=QString::null, MessageLevel level=WARNING)
add a message to the instance (and create it if necessary)
void recalculateSize()
Forces a recalculation of the picture's frame size.
void itemChanged()
Used e.g.
bool _readXML(const QDomElement &itemElem, const QDomDocument &doc)
Reads parameter that are not subclass specific in document.
QRectF boundedSVGRect(double deviceWidth, double deviceHeight)
Calculates bounding rect for svg file (mSourcefile) such that aspect ratio is correct.
void setPictureAnchor(QgsComposerItem::ItemPositionMode anchor)
Sets the picture's anchor point, which controls how it is placed within the picture item's frame...
void paint(QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget)
Reimplementation of QCanvasItem::paint.
const QgsComposerMap * mRotationMap
Map that sets the rotation (or 0 if this picture uses map independent rotation)
virtual void drawSelectionBoxes(QPainter *p)
Draw selection boxes around item.
double mPictureHeight
Height of the picture (in mm)
int printResolution() const
QRectF largestRotatedRectWithinBounds(QRectF originalRect, QRectF boundsRect, double rotation) const
Calculates the largest scaled version of originalRect which fits within boundsRect, when it is rotated by a specified amount.
virtual void setResizeMode(ResizeMode mode)
Sets the resize mode used for drawing the picture within the item bounds.
void updatePictureExpression()
Prepares the picture's source expression after it is altered or the compositions atlas coverage layer...
virtual void setUsePictureExpression(bool useExpression)
Sets whether the picture should use an expression based image source path.
QRect clippedImageRect(double &boundRectWidthMM, double &boundRectHeightMM, QSize imageRectPixels)
Returns part of a raster image which will be shown, given current picture anchor settings.
QgsComposition * mComposition
Graphics scene for map printing.
QgsFeature * currentFeature()
Returns the current atlas feature.
Object representing map window.
QString pictureFile() const
Returns the path of the source image file.
bool writeXML(QDomElement &elem, QDomDocument &doc) const
stores state in Dom element
Q_DECL_DEPRECATED bool cornerPointOnRotatedAndScaledRect(double &x, double &y, double width, double height) const
Calculates corner point after rotation and scaling.
void pictureRotationChanged(double newRotation)
Is emitted on picture rotation change.
QString file
Definition: qgssvgcache.cpp:76
int id() const
Get identification number.
void setPictureFile(const QString &path)
Sets the source file of the image (may be svg or a raster format).
void refreshPicture()
Recalculates the source image (if using an expression for picture's source) and reloads and redraws t...
bool cornerPointOnRotatedAndScaledRect(double &x, double &y, double width, double height, double rotation) const
Calculates corner point after rotation and scaling.
QString evalPictureExpression()
evaluates the picture expression and returns the calculated image path
bool _writeXML(QDomElement &itemElem, QDomDocument &doc) const
Writes parameter that are not subclass specific in document.
virtual void drawBackground(QPainter *p)
Draw background.
static QgsProject * instance()
access to canonical QgsProject instance
Definition: qgsproject.cpp:362
virtual void setSceneRect(const QRectF &rectangle)
Sets this items bound in scene coordinates such that 1 item size units corresponds to 1 scene size un...
double mPictureWidth
Width of the picture (in mm)
void loadPicture(const QFile &file)
loads an image file into the picture item and redraws the item
Class used to render an Atlas, iterating over geometry features.
QgsAtlasComposition & atlasComposition()
void setRotationMap(int composerMapId)
Sets the map object for rotation (by id).
QgsVectorLayer * coverageLayer() const
Returns the coverage layer used for the atlas features.
const QgsFields & pendingFields() const
returns field list in the to-be-committed state
virtual void setPictureRotation(double r)
Sets the picture rotation within the item bounds.
Represents a vector layer which manages a vector based data sets.
double mPictureRotation
Image rotation.
int rotationMap() const
Returns the id of the rotation map.
QRectF boundedImageRect(double deviceWidth, double deviceHeight)
Calculates bounding rect for image such that aspect ratio is correct.
const QgsComposerMap * getComposerMapById(int id) const
Returns the composer map with specified id.
QString parserErrorString() const
Returns parser error.
Definition: qgsexpression.h:98
void init()
sets up the picture item and connects to relevant signals
QString evalErrorString() const
Returns evaluation error.
virtual void setPictureExpression(QString expression)
Sets an expression to use for the picture source.
void sizeChangedByRotation(double &width, double &height, double rotation)
Calculates width / height of the bounding box of a rotated rectangle.
Q_DECL_DEPRECATED void sizeChangedByRotation(double &width, double &height)
Calculates width / height of the bounding box of a rotated rectangle.
QgsExpression * mPictureExpr
#define tr(sourceText)