QGIS API Documentation  2.5.0-Master
 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 : radim.blazek@gmail.com
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 "qgscomposerutils.h"
20 #include "qgscomposermap.h"
21 #include "qgscomposition.h"
22 #include "qgsatlascomposition.h"
23 #include "qgsproject.h"
24 #include "qgsexpression.h"
25 #include "qgsvectorlayer.h"
26 #include "qgsmessagelog.h"
27 #include <QDomDocument>
28 #include <QDomElement>
29 #include <QFileInfo>
30 #include <QImageReader>
31 #include <QPainter>
32 #include <QSvgRenderer>
33 
34 
36  QgsComposerItem( composition ),
37  mMode( Unknown ),
38  mUseSourceExpression( false ),
39  mPictureRotation( 0 ),
40  mRotationMap( 0 ),
41  mResizeMode( QgsComposerPicture::Zoom ),
42  mPictureAnchor( UpperLeft ),
43  mPictureExpr( 0 )
44 {
45  mPictureWidth = rect().width();
46  init();
47 }
48 
50  mMode( Unknown ),
51  mUseSourceExpression( false ),
52  mPictureRotation( 0 ),
53  mRotationMap( 0 ),
54  mResizeMode( QgsComposerPicture::Zoom ),
55  mPictureAnchor( UpperLeft ),
56  mPictureExpr( 0 )
57 {
58  mPictureHeight = rect().height();
59  init();
60 }
61 
63 {
64  //default to no background
65  setBackgroundEnabled( false );
66 
67  //connect some signals
68 
69  //connect to atlas feature changing
70  //to update the picture source expression
71  connect( &mComposition->atlasComposition(), SIGNAL( featureChanged( QgsFeature* ) ), this, SLOT( refreshPicture() ) );
72 
73  //connect to composer print resolution changing
74  connect( mComposition, SIGNAL( printResolutionChanged() ), this, SLOT( recalculateSize() ) );
75 }
76 
78 {
79 
80 }
81 
82 void QgsComposerPicture::paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget )
83 {
84  Q_UNUSED( itemStyle );
85  Q_UNUSED( pWidget );
86  if ( !painter )
87  {
88  return;
89  }
90 
91  drawBackground( painter );
92 
93  //int newDpi = ( painter->device()->logicalDpiX() + painter->device()->logicalDpiY() ) / 2;
94 
95  //picture resizing
96  if ( mMode != Unknown )
97  {
98  double boundRectWidthMM;
99  double boundRectHeightMM;
100  QRect imageRect;
102  {
103  boundRectWidthMM = mPictureWidth;
104  boundRectHeightMM = mPictureHeight;
105  imageRect = QRect( 0, 0, mImage.width(), mImage.height() );
106  }
108  {
109  boundRectWidthMM = rect().width();
110  boundRectHeightMM = rect().height();
111  imageRect = QRect( 0, 0, mImage.width(), mImage.height() );
112  }
114  {
115  boundRectWidthMM = rect().width();
116  boundRectHeightMM = rect().height();
117  int imageRectWidthPixels = mImage.width();
118  int imageRectHeightPixels = mImage.height();
119  imageRect = clippedImageRect( boundRectWidthMM, boundRectHeightMM ,
120  QSize( imageRectWidthPixels, imageRectHeightPixels ) );
121  }
122  else
123  {
124  boundRectWidthMM = rect().width();
125  boundRectHeightMM = rect().height();
126  imageRect = QRect( 0, 0, rect().width() * mComposition->printResolution() / 25.4,
127  rect().height() * mComposition->printResolution() / 25.4 );
128  }
129  painter->save();
130  //antialiasing on
131  painter->setRenderHint( QPainter::Antialiasing, true );
132 
133  //zoom mode - calculate anchor point and rotation
134  if ( mResizeMode == Zoom )
135  {
136  //TODO - allow placement modes with rotation set. for now, setting a rotation
137  //always places picture in center of frame
138  if ( mPictureRotation != 0 )
139  {
140  painter->translate( rect().width() / 2.0, rect().height() / 2.0 );
141  painter->rotate( mPictureRotation );
142  painter->translate( -boundRectWidthMM / 2.0, -boundRectHeightMM / 2.0 );
143  }
144  else
145  {
146  //shift painter to edge/middle of frame depending on placement
147  double diffX = rect().width() - boundRectWidthMM;
148  double diffY = rect().height() - boundRectHeightMM;
149 
150  double dX = 0;
151  double dY = 0;
152  switch ( mPictureAnchor )
153  {
154  case UpperLeft:
155  case MiddleLeft:
156  case LowerLeft:
157  //nothing to do
158  break;
159  case UpperMiddle:
160  case Middle:
161  case LowerMiddle:
162  dX = diffX / 2.0;
163  break;
164  case UpperRight:
165  case MiddleRight:
166  case LowerRight:
167  dX = diffX;
168  break;
169  }
170  switch ( mPictureAnchor )
171  {
172  case UpperLeft:
173  case UpperMiddle:
174  case UpperRight:
175  //nothing to do
176  break;
177  case MiddleLeft:
178  case Middle:
179  case MiddleRight:
180  dY = diffY / 2.0;
181  break;
182  case LowerLeft:
183  case LowerMiddle:
184  case LowerRight:
185  dY = diffY;
186  break;
187  }
188  painter->translate( dX, dY );
189  }
190  }
191 
192  if ( mMode == SVG )
193  {
194  mSVG.render( painter, QRectF( 0, 0, boundRectWidthMM, boundRectHeightMM ) );
195  }
196  else if ( mMode == RASTER )
197  {
198  painter->drawImage( QRectF( 0, 0, boundRectWidthMM, boundRectHeightMM ), mImage, imageRect );
199  }
200 
201  painter->restore();
202  }
203 
204  //frame and selection boxes
205  drawFrame( painter );
206  if ( isSelected() )
207  {
208  drawSelectionBoxes( painter );
209  }
210 }
211 
212 QRect QgsComposerPicture::clippedImageRect( double &boundRectWidthMM, double &boundRectHeightMM, QSize imageRectPixels )
213 {
214  int boundRectWidthPixels = boundRectWidthMM * mComposition->printResolution() / 25.4;
215  int boundRectHeightPixels = boundRectHeightMM * mComposition->printResolution() / 25.4;
216 
217  //update boundRectWidth/Height so that they exactly match pixel bounds
218  boundRectWidthMM = boundRectWidthPixels * 25.4 / mComposition->printResolution();
219  boundRectHeightMM = boundRectHeightPixels * 25.4 / mComposition->printResolution();
220 
221  //calculate part of image which fits in bounds
222  int leftClip = 0;
223  int topClip = 0;
224 
225  //calculate left crop
226  switch ( mPictureAnchor )
227  {
228  case UpperLeft:
229  case MiddleLeft:
230  case LowerLeft:
231  leftClip = 0;
232  break;
233  case UpperMiddle:
234  case Middle:
235  case LowerMiddle:
236  leftClip = ( imageRectPixels.width() - boundRectWidthPixels ) / 2;
237  break;
238  case UpperRight:
239  case MiddleRight:
240  case LowerRight:
241  leftClip = imageRectPixels.width() - boundRectWidthPixels;
242  break;
243  }
244 
245  //calculate top crop
246  switch ( mPictureAnchor )
247  {
248  case UpperLeft:
249  case UpperMiddle:
250  case UpperRight:
251  topClip = 0;
252  break;
253  case MiddleLeft:
254  case Middle:
255  case MiddleRight:
256  topClip = ( imageRectPixels.height() - boundRectHeightPixels ) / 2;
257  break;
258  case LowerLeft:
259  case LowerMiddle:
260  case LowerRight:
261  topClip = imageRectPixels.height() - boundRectHeightPixels;
262  break;
263  }
264 
265 
266  return QRect( leftClip, topClip, boundRectWidthPixels, boundRectHeightPixels );
267 
268 }
269 
270 void QgsComposerPicture::setPictureFile( const QString& path )
271 {
272  mSourceFile.setFileName( path );
273  refreshPicture();
274 }
275 
277 {
278  QgsVectorLayer * vl = 0;
280  {
282  }
283 
284  if ( mSourceExpression.size() > 0 )
285  {
286  if ( mPictureExpr )
287  {
288  delete mPictureExpr;
289  }
291  // expression used to evaluate picture source
292  // test for evaluation errors
293  if ( mPictureExpr->hasParserError() )
294  {
295  QgsMessageLog::logMessage( tr( "Picture expression parsing error: %1" ).arg( mPictureExpr->parserErrorString() ), tr( "Composer" ) );
296  }
297 
298  if ( vl )
299  {
300  const QgsFields& fields = vl->pendingFields();
301  mPictureExpr->prepare( fields );
302  }
303  }
304 }
305 
307 {
308  //generate filename for picture
309  if ( mSourceExpression.size() > 0 && mUseSourceExpression )
310  {
311  if ( ! mPictureExpr )
312  {
313  return QString();
314  }
315 
316  QVariant filenameRes;
318  if ( atlas->enabled() )
319  {
320  //expression needs to be evaluated considering the current atlas feature
321  filenameRes = mPictureExpr->evaluate( atlas->currentFeature(),
322  atlas->coverageLayer()->pendingFields() );
323  }
324  else
325  {
326  filenameRes = mPictureExpr->evaluate();
327  }
328 
329  if ( mPictureExpr->hasEvalError() )
330  {
331  QgsMessageLog::logMessage( tr( "Picture expression eval error: %1" ).arg( mPictureExpr->evalErrorString() ), tr( "Composer" ) );
332  }
333 
334  return filenameRes.toString();
335  }
336  else
337  {
338  return QString();
339  }
340 }
341 
343 {
344  if ( mUseSourceExpression )
345  {
346  //using expression for picture source file
347 
348  //evaluate expression
349  QFile path;
350  path.setFileName( evalPictureExpression() );
351  loadPicture( path );
352  }
353  else
354  {
355  //using a static picture path
357  }
358 }
359 
361 {
362  if ( !file.exists()
364  {
365  mMode = Unknown;
366  }
367  else
368  {
369  QFileInfo sourceFileInfo( file );
370  QString sourceFileSuffix = sourceFileInfo.suffix();
371  if ( sourceFileSuffix.compare( "svg", Qt::CaseInsensitive ) == 0 )
372  {
373  //try to open svg
374  mSVG.load( file.fileName() );
375  if ( mSVG.isValid() )
376  {
377  mMode = SVG;
378  QRect viewBox = mSVG.viewBox(); //take width/height ratio from view box instead of default size
379  mDefaultSvgSize.setWidth( viewBox.width() );
380  mDefaultSvgSize.setHeight( viewBox.height() );
381  }
382  else
383  {
384  mMode = Unknown;
385  }
386  }
387  else
388  {
389  //try to open raster with QImageReader
390  QImageReader imageReader( file.fileName() );
391  if ( imageReader.read( &mImage ) )
392  {
393  mMode = RASTER;
394  }
395  else
396  {
397  mMode = Unknown;
398  }
399  }
400  }
401 
402  if ( mMode != Unknown ) //make sure we start with a new QImage
403  {
404  recalculateSize();
405  }
406  else if ( !( file.fileName().isEmpty() ) || ( mUseSourceExpression && mPictureExpr && mPictureExpr->hasEvalError() ) )
407  {
408  //trying to load an invalid file or bad expression, show cross picture
409  mMode = SVG;
410  QString badFile = QString( ":/images/composer/missing_image.svg" );
411  mSVG.load( badFile );
412  if ( mSVG.isValid() )
413  {
414  mMode = SVG;
415  QRect viewBox = mSVG.viewBox(); //take width/height ratio from view box instead of default size
416  mDefaultSvgSize.setWidth( viewBox.width() );
417  mDefaultSvgSize.setHeight( viewBox.height() );
418  recalculateSize();
419  }
420  }
421 
422  emit itemChanged();
423 }
424 
425 QRectF QgsComposerPicture::boundedImageRect( double deviceWidth, double deviceHeight )
426 {
427  double imageToDeviceRatio;
428  if ( mImage.width() / deviceWidth > mImage.height() / deviceHeight )
429  {
430  imageToDeviceRatio = deviceWidth / mImage.width();
431  double height = imageToDeviceRatio * mImage.height();
432  return QRectF( 0, 0, deviceWidth, height );
433  }
434  else
435  {
436  imageToDeviceRatio = deviceHeight / mImage.height();
437  double width = imageToDeviceRatio * mImage.width();
438  return QRectF( 0, 0, width, deviceHeight );
439  }
440 }
441 
442 QRectF QgsComposerPicture::boundedSVGRect( double deviceWidth, double deviceHeight )
443 {
444  double imageToSvgRatio;
445  if ( deviceWidth / mDefaultSvgSize.width() > deviceHeight / mDefaultSvgSize.height() )
446  {
447  imageToSvgRatio = deviceHeight / mDefaultSvgSize.height();
448  double width = mDefaultSvgSize.width() * imageToSvgRatio;
449  return QRectF( 0, 0, width, deviceHeight );
450  }
451  else
452  {
453  imageToSvgRatio = deviceWidth / mDefaultSvgSize.width();
454  double height = mDefaultSvgSize.height() * imageToSvgRatio;
455  return QRectF( 0, 0, deviceWidth, height );
456  }
457 }
458 
460 {
461  if ( mMode == SVG )
462  {
463  return mDefaultSvgSize;
464  }
465  else if ( mMode == RASTER )
466  {
467  return QSizeF( mImage.width(), mImage.height() );
468  }
469  else
470  {
471  return QSizeF( 0, 0 );
472  }
473 }
474 
475 #if 0
476 QRectF QgsComposerPicture::boundedSVGRect( double deviceWidth, double deviceHeight )
477 {
478  double imageToSvgRatio;
479  if ( deviceWidth / mDefaultSvgSize.width() < deviceHeight / mDefaultSvgSize.height() )
480  {
481  imageToSvgRatio = deviceWidth / mDefaultSvgSize.width();
482  double height = mDefaultSvgSize.height() * imageToSvgRatio;
483  return QRectF( 0, 0, deviceWidth, height );
484  }
485  else
486  {
487  imageToSvgRatio = deviceHeight / mDefaultSvgSize.height();
488  double width = mDefaultSvgSize.width() * imageToSvgRatio;
489  return QRectF( 0, 0, width, deviceHeight );
490  }
491 }
492 #endif //0
493 
494 void QgsComposerPicture::setSceneRect( const QRectF& rectangle )
495 {
496 
497  QSizeF currentPictureSize = pictureSize();
498 
500  {
501  QgsComposerItem::setSceneRect( rectangle );
502  mPictureWidth = rectangle.width();
503  mPictureHeight = rectangle.height();
504  return;
505  }
506 
507  QRectF newRect = rectangle;
508 
509  if ( mResizeMode == ZoomResizeFrame && !rect().isEmpty() && !( currentPictureSize.isEmpty() ) )
510  {
511  //if width has changed less than height, then fix width and set height correspondingly
512  //else, do the opposite
513  if ( qAbs( rect().width() - rectangle.width() ) <
514  qAbs( rect().height() - rectangle.height() ) )
515  {
516  newRect.setHeight( currentPictureSize.height() * newRect.width() / currentPictureSize.width() );
517  }
518  else
519  {
520  newRect.setWidth( currentPictureSize.width() * newRect.height() / currentPictureSize.height() );
521  }
522  }
523  else if ( mResizeMode == FrameToImageSize )
524  {
525  if ( !( currentPictureSize.isEmpty() ) )
526  {
527  newRect.setWidth( currentPictureSize.width() * 25.4 / mComposition->printResolution() );
528  newRect.setHeight( currentPictureSize.height() * 25.4 / mComposition->printResolution() );
529  }
530  }
531 
532  //find largest scaling of picture with this rotation which fits in item
533  if ( mResizeMode == Zoom )
534  {
535  QRectF rotatedImageRect = QgsComposerUtils::largestRotatedRectWithinBounds( QRectF( 0, 0, currentPictureSize.width(), currentPictureSize.height() ), newRect, mPictureRotation );
536  mPictureWidth = rotatedImageRect.width();
537  mPictureHeight = rotatedImageRect.height();
538  }
539  else
540  {
541  mPictureWidth = newRect.width();
542  mPictureHeight = newRect.height();
543  }
544 
546  emit itemChanged();
547 }
548 
550 {
551  //kept for compatibility for QGIS2.0 api
552  setPictureRotation( r );
553 }
554 
556 {
557  mPictureRotation = r;
558 
559  if ( mResizeMode == Zoom )
560  {
561  //find largest scaling of picture with this rotation which fits in item
562  QSizeF currentPictureSize = pictureSize();
563  QRectF rotatedImageRect = QgsComposerUtils::largestRotatedRectWithinBounds( QRectF( 0, 0, currentPictureSize.width(), currentPictureSize.height() ), rect(), mPictureRotation );
564  mPictureWidth = rotatedImageRect.width();
565  mPictureHeight = rotatedImageRect.height();
566  update();
567  }
568 
570 }
571 
572 void QgsComposerPicture::setRotationMap( int composerMapId )
573 {
574  if ( !mComposition )
575  {
576  return;
577  }
578 
579  if ( composerMapId == -1 ) //disable rotation from map
580  {
581  QObject::disconnect( mRotationMap, SIGNAL( mapRotationChanged( double ) ), this, SLOT( setPictureRotation( double ) ) );
582  mRotationMap = 0;
583  }
584 
585  const QgsComposerMap* map = mComposition->getComposerMapById( composerMapId );
586  if ( !map )
587  {
588  return;
589  }
590  if ( mRotationMap )
591  {
592  QObject::disconnect( mRotationMap, SIGNAL( mapRotationChanged( double ) ), this, SLOT( setPictureRotation( double ) ) );
593  }
594  mPictureRotation = map->mapRotation();
595  QObject::connect( map, SIGNAL( mapRotationChanged( double ) ), this, SLOT( setPictureRotation( double ) ) );
596  mRotationMap = map;
597  update();
599 }
600 
602 {
603  mResizeMode = mode;
605  || ( mode == QgsComposerPicture::Zoom && mPictureRotation != 0 ) )
606  {
607  //call set scene rect to force item to resize to fit picture
608  recalculateSize();
609  }
610  update();
611 }
612 
614 {
615  //call set scene rect with current position/size, as this will trigger the
616  //picture item to recalculate its frame and image size
617  setSceneRect( QRectF( pos().x(), pos().y(), rect().width(), rect().height() ) );
618 }
619 
621 {
622  if ( useExpression == mUseSourceExpression )
623  {
624  return;
625  }
626 
627  mUseSourceExpression = useExpression;
628  if ( useExpression )
629  {
631  }
632 
633  refreshPicture();
634 }
635 
637 {
638  if ( expression == mSourceExpression )
639  {
640  return;
641  }
642 
643  mSourceExpression = expression;
644 
645  if ( mUseSourceExpression )
646  {
648  refreshPicture();
649  }
650 }
651 
653 {
654  return mSourceFile.fileName();
655 }
656 
657 bool QgsComposerPicture::writeXML( QDomElement& elem, QDomDocument & doc ) const
658 {
659  if ( elem.isNull() )
660  {
661  return false;
662  }
663  QDomElement composerPictureElem = doc.createElement( "ComposerPicture" );
664  composerPictureElem.setAttribute( "file", QgsProject::instance()->writePath( mSourceFile.fileName() ) );
665  composerPictureElem.setAttribute( "pictureWidth", QString::number( mPictureWidth ) );
666  composerPictureElem.setAttribute( "pictureHeight", QString::number( mPictureHeight ) );
667  composerPictureElem.setAttribute( "resizeMode", QString::number(( int )mResizeMode ) );
668  composerPictureElem.setAttribute( "anchorPoint", QString::number(( int )mPictureAnchor ) );
669 
670  if ( mUseSourceExpression )
671  {
672  composerPictureElem.setAttribute( "useExpression", "true" );
673  }
674  else
675  {
676  composerPictureElem.setAttribute( "useExpression", "false" );
677  }
678  composerPictureElem.setAttribute( "sourceExpression", mSourceExpression );
679 
680  //rotation
681  composerPictureElem.setAttribute( "pictureRotation", QString::number( mPictureRotation ) );
682  if ( !mRotationMap )
683  {
684  composerPictureElem.setAttribute( "mapId", -1 );
685  }
686  else
687  {
688  composerPictureElem.setAttribute( "mapId", mRotationMap->id() );
689  }
690 
691  _writeXML( composerPictureElem, doc );
692  elem.appendChild( composerPictureElem );
693  return true;
694 }
695 
696 bool QgsComposerPicture::readXML( const QDomElement& itemElem, const QDomDocument& doc )
697 {
698  if ( itemElem.isNull() )
699  {
700  return false;
701  }
702 
703  mPictureWidth = itemElem.attribute( "pictureWidth", "10" ).toDouble();
704  mPictureHeight = itemElem.attribute( "pictureHeight", "10" ).toDouble();
705  mResizeMode = QgsComposerPicture::ResizeMode( itemElem.attribute( "resizeMode", "0" ).toInt() );
706  //when loading from xml, default to anchor point of middle to match pre 2.4 behaviour
707  mPictureAnchor = ( QgsComposerItem::ItemPositionMode ) itemElem.attribute( "anchorPoint", QString::number( QgsComposerItem::Middle ) ).toInt();
708 
709  QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" );
710  if ( composerItemList.size() > 0 )
711  {
712  QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
713 
714  if ( composerItemElem.attribute( "rotation", "0" ).toDouble() != 0 )
715  {
716  //in versions prior to 2.1 picture rotation was stored in the rotation attribute
717  mPictureRotation = composerItemElem.attribute( "rotation", "0" ).toDouble();
718  }
719 
720  _readXML( composerItemElem, doc );
721  }
722 
723  mDefaultSvgSize = QSize( 0, 0 );
724 
725 
726  mSourceExpression = itemElem.attribute( "sourceExpression", "" );
727  QString useExpression = itemElem.attribute( "useExpression" );
728  if ( useExpression.compare( "true", Qt::CaseInsensitive ) == 0 )
729  {
730  mUseSourceExpression = true;
732  }
733  else
734  {
735  mUseSourceExpression = false;
736  }
737 
738  QString fileName = QgsProject::instance()->readPath( itemElem.attribute( "file" ) );
739  mSourceFile.setFileName( fileName );
740 
741  //picture rotation
742  if ( itemElem.attribute( "pictureRotation", "0" ).toDouble() != 0 )
743  {
744  mPictureRotation = itemElem.attribute( "pictureRotation", "0" ).toDouble();
745  }
746 
747  //rotation map
748  int rotationMapId = itemElem.attribute( "mapId", "-1" ).toInt();
749  if ( rotationMapId == -1 )
750  {
751  mRotationMap = 0;
752  }
753  else if ( mComposition )
754  {
755 
756  if ( mRotationMap )
757  {
758  QObject::disconnect( mRotationMap, SIGNAL( mapRotationChanged( double ) ), this, SLOT( setRotation( double ) ) );
759  }
760  mRotationMap = mComposition->getComposerMapById( rotationMapId );
761  QObject::connect( mRotationMap, SIGNAL( mapRotationChanged( double ) ), this, SLOT( setRotation( double ) ) );
762  }
763 
764  refreshPicture();
765 
766  emit itemChanged();
767  return true;
768 }
769 
771 {
772  if ( !mRotationMap )
773  {
774  return -1;
775  }
776  else
777  {
778  return mRotationMap->id();
779  }
780 }
781 
783 {
784  mPictureAnchor = anchor;
785  update();
786 }
787 
788 bool QgsComposerPicture::imageSizeConsideringRotation( double& width, double& height ) const
789 {
790  //kept for api compatibility with QGIS 2.0 - use mPictureRotation
794 }
795 
796 bool QgsComposerPicture::cornerPointOnRotatedAndScaledRect( double& x, double& y, double width, double height ) const
797 {
798  //kept for api compatibility with QGIS 2.0 - use mPictureRotation
802 }
803 
804 void QgsComposerPicture::sizeChangedByRotation( double& width, double& height )
805 {
806  //kept for api compatibility with QGIS 2.0 - use mPictureRotation
810 }
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.
Q_DECL_DEPRECATED 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.
void itemChanged()
Emitted when the item changes.
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.
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:439
static QRectF largestRotatedRectWithinBounds(const QRectF originalRect, const QRectF boundsRect, const double rotation)
Calculates the largest scaled version of originalRect which fits within boundsRect, when it is rotated by a specified amount.
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
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.
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
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.
double mapRotation(QgsComposerObject::PropertyValueType valueType=QgsComposerObject::EvaluatedValue) const
Returns the rotation used for drawing the map within the composer item.
void setBackgroundEnabled(const bool drawBackground)
Set whether this item has a Background drawn around it or not.
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
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:440
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).
QgsComposition * mComposition
void refreshPicture()
Recalculates the source image (if using an expression for picture's source) and reloads and redraws t...
Q_DECL_DEPRECATED 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.
const QgsComposerMap * getComposerMapById(const int id) const
Returns the composer map with specified id.
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.
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.
Q_DECL_DEPRECATED 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)