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 "qgsdatadefined.h"
29 #include <QDomDocument>
30 #include <QDomElement>
31 #include <QFileInfo>
32 #include <QImageReader>
33 #include <QPainter>
34 #include <QSvgRenderer>
35 #include <QNetworkRequest>
36 #include <QNetworkReply>
37 #include <QEventLoop>
38 #include <QCoreApplication>
39 
41  QgsComposerItem( composition ),
42  mMode( Unknown ),
43  mPictureRotation( 0 ),
44  mRotationMap( 0 ),
45  mResizeMode( QgsComposerPicture::Zoom ),
46  mPictureAnchor( UpperLeft ),
47  mHasExpressionError( false )
48 {
49  mPictureWidth = rect().width();
50  init();
51 }
52 
54  mMode( Unknown ),
55  mPictureRotation( 0 ),
56  mRotationMap( 0 ),
57  mResizeMode( QgsComposerPicture::Zoom ),
58  mPictureAnchor( UpperLeft ),
59  mHasExpressionError( false )
60 {
61  mPictureHeight = rect().height();
62  init();
63 }
64 
66 {
67  //default to no background
68  setBackgroundEnabled( false );
69 
70  //data defined strings
71  mDataDefinedNames.insert( QgsComposerObject::PictureSource, QString( "dataDefinedSource" ) );
72 
73  //insert PictureSource data defined property (only required due to deprecated API elements,
74  //remove after 3.0
75  setDataDefinedProperty( QgsComposerObject::PictureSource, false, true, QString(), QString() );
76 
77  //connect some signals
78 
79  //connect to atlas feature changing
80  //to update the picture source expression
81  connect( &mComposition->atlasComposition(), SIGNAL( featureChanged( QgsFeature* ) ), this, SLOT( refreshPicture() ) );
82 
83  //connect to composer print resolution changing
84  connect( mComposition, SIGNAL( printResolutionChanged() ), this, SLOT( recalculateSize() ) );
85 }
86 
88 {
89 
90 }
91 
92 void QgsComposerPicture::paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget )
93 {
94  Q_UNUSED( itemStyle );
95  Q_UNUSED( pWidget );
96  if ( !painter )
97  {
98  return;
99  }
100 
101  drawBackground( painter );
102 
103  //int newDpi = ( painter->device()->logicalDpiX() + painter->device()->logicalDpiY() ) / 2;
104 
105  //picture resizing
106  if ( mMode != Unknown )
107  {
108  double boundRectWidthMM;
109  double boundRectHeightMM;
110  QRect imageRect;
112  {
113  boundRectWidthMM = mPictureWidth;
114  boundRectHeightMM = mPictureHeight;
115  imageRect = QRect( 0, 0, mImage.width(), mImage.height() );
116  }
118  {
119  boundRectWidthMM = rect().width();
120  boundRectHeightMM = rect().height();
121  imageRect = QRect( 0, 0, mImage.width(), mImage.height() );
122  }
124  {
125  boundRectWidthMM = rect().width();
126  boundRectHeightMM = rect().height();
127  int imageRectWidthPixels = mImage.width();
128  int imageRectHeightPixels = mImage.height();
129  imageRect = clippedImageRect( boundRectWidthMM, boundRectHeightMM ,
130  QSize( imageRectWidthPixels, imageRectHeightPixels ) );
131  }
132  else
133  {
134  boundRectWidthMM = rect().width();
135  boundRectHeightMM = rect().height();
136  imageRect = QRect( 0, 0, rect().width() * mComposition->printResolution() / 25.4,
137  rect().height() * mComposition->printResolution() / 25.4 );
138  }
139  painter->save();
140  //antialiasing on
141  painter->setRenderHint( QPainter::Antialiasing, true );
142 
143  //zoom mode - calculate anchor point and rotation
144  if ( mResizeMode == Zoom )
145  {
146  //TODO - allow placement modes with rotation set. for now, setting a rotation
147  //always places picture in center of frame
148  if ( mPictureRotation != 0 )
149  {
150  painter->translate( rect().width() / 2.0, rect().height() / 2.0 );
151  painter->rotate( mPictureRotation );
152  painter->translate( -boundRectWidthMM / 2.0, -boundRectHeightMM / 2.0 );
153  }
154  else
155  {
156  //shift painter to edge/middle of frame depending on placement
157  double diffX = rect().width() - boundRectWidthMM;
158  double diffY = rect().height() - boundRectHeightMM;
159 
160  double dX = 0;
161  double dY = 0;
162  switch ( mPictureAnchor )
163  {
164  case UpperLeft:
165  case MiddleLeft:
166  case LowerLeft:
167  //nothing to do
168  break;
169  case UpperMiddle:
170  case Middle:
171  case LowerMiddle:
172  dX = diffX / 2.0;
173  break;
174  case UpperRight:
175  case MiddleRight:
176  case LowerRight:
177  dX = diffX;
178  break;
179  }
180  switch ( mPictureAnchor )
181  {
182  case UpperLeft:
183  case UpperMiddle:
184  case UpperRight:
185  //nothing to do
186  break;
187  case MiddleLeft:
188  case Middle:
189  case MiddleRight:
190  dY = diffY / 2.0;
191  break;
192  case LowerLeft:
193  case LowerMiddle:
194  case LowerRight:
195  dY = diffY;
196  break;
197  }
198  painter->translate( dX, dY );
199  }
200  }
201 
202  if ( mMode == SVG )
203  {
204  mSVG.render( painter, QRectF( 0, 0, boundRectWidthMM, boundRectHeightMM ) );
205  }
206  else if ( mMode == RASTER )
207  {
208  painter->drawImage( QRectF( 0, 0, boundRectWidthMM, boundRectHeightMM ), mImage, imageRect );
209  }
210 
211  painter->restore();
212  }
213 
214  //frame and selection boxes
215  drawFrame( painter );
216  if ( isSelected() )
217  {
218  drawSelectionBoxes( painter );
219  }
220 }
221 
222 QRect QgsComposerPicture::clippedImageRect( double &boundRectWidthMM, double &boundRectHeightMM, QSize imageRectPixels )
223 {
224  int boundRectWidthPixels = boundRectWidthMM * mComposition->printResolution() / 25.4;
225  int boundRectHeightPixels = boundRectHeightMM * mComposition->printResolution() / 25.4;
226 
227  //update boundRectWidth/Height so that they exactly match pixel bounds
228  boundRectWidthMM = boundRectWidthPixels * 25.4 / mComposition->printResolution();
229  boundRectHeightMM = boundRectHeightPixels * 25.4 / mComposition->printResolution();
230 
231  //calculate part of image which fits in bounds
232  int leftClip = 0;
233  int topClip = 0;
234 
235  //calculate left crop
236  switch ( mPictureAnchor )
237  {
238  case UpperLeft:
239  case MiddleLeft:
240  case LowerLeft:
241  leftClip = 0;
242  break;
243  case UpperMiddle:
244  case Middle:
245  case LowerMiddle:
246  leftClip = ( imageRectPixels.width() - boundRectWidthPixels ) / 2;
247  break;
248  case UpperRight:
249  case MiddleRight:
250  case LowerRight:
251  leftClip = imageRectPixels.width() - boundRectWidthPixels;
252  break;
253  }
254 
255  //calculate top crop
256  switch ( mPictureAnchor )
257  {
258  case UpperLeft:
259  case UpperMiddle:
260  case UpperRight:
261  topClip = 0;
262  break;
263  case MiddleLeft:
264  case Middle:
265  case MiddleRight:
266  topClip = ( imageRectPixels.height() - boundRectHeightPixels ) / 2;
267  break;
268  case LowerLeft:
269  case LowerMiddle:
270  case LowerRight:
271  topClip = imageRectPixels.height() - boundRectHeightPixels;
272  break;
273  }
274 
275  return QRect( leftClip, topClip, boundRectWidthPixels, boundRectHeightPixels );
276 }
277 
278 void QgsComposerPicture::setPictureFile( const QString& path )
279 {
280  setPicturePath( path );
281 }
282 
284 {
285  QString source = mSourcePath;
286 
287  //data defined source set?
288  mHasExpressionError = false;
289  QVariant exprVal;
291  {
293  {
294  source = exprVal.toString().trimmed();
295  QgsDebugMsg( QString( "exprVal PictureSource:%1" ).arg( source ) );
296  }
297  else
298  {
299  mHasExpressionError = true;
300  source = QString();
301  QgsMessageLog::logMessage( tr( "Picture expression eval error" ) );
302  }
303  }
304 
305  loadPicture( source );
306 }
307 
308 void QgsComposerPicture::loadRemotePicture( const QString &url )
309 {
310  //remote location
311 
312  QgsNetworkContentFetcher fetcher;
313  //pause until HTML fetch
314  mLoaded = false;
315  fetcher.fetchContent( QUrl( url ) );
316  connect( &fetcher, SIGNAL( finished() ), this, SLOT( remotePictureLoaded() ) );
317 
318  while ( !mLoaded )
319  {
320  qApp->processEvents();
321  }
322 
323  QNetworkReply* reply = fetcher.reply();
324  if ( reply )
325  {
326  QImageReader imageReader( reply );
327  mImage = imageReader.read();
328  mMode = RASTER;
329  reply->deleteLater();
330  }
331  else
332  {
333  mMode = Unknown;
334  }
335 }
336 
337 void QgsComposerPicture::loadLocalPicture( const QString &path )
338 {
339  QFile pic;
340  pic.setFileName( path );
341 
342  if ( !pic.exists() )
343  {
344  mMode = Unknown;
345  }
346  else
347  {
348  QFileInfo sourceFileInfo( pic );
349  QString sourceFileSuffix = sourceFileInfo.suffix();
350  if ( sourceFileSuffix.compare( "svg", Qt::CaseInsensitive ) == 0 )
351  {
352  //try to open svg
353  mSVG.load( pic.fileName() );
354  if ( mSVG.isValid() )
355  {
356  mMode = SVG;
357  QRect viewBox = mSVG.viewBox(); //take width/height ratio from view box instead of default size
358  mDefaultSvgSize.setWidth( viewBox.width() );
359  mDefaultSvgSize.setHeight( viewBox.height() );
360  }
361  else
362  {
363  mMode = Unknown;
364  }
365  }
366  else
367  {
368  //try to open raster with QImageReader
369  QImageReader imageReader( pic.fileName() );
370  if ( imageReader.read( &mImage ) )
371  {
372  mMode = RASTER;
373  }
374  else
375  {
376  mMode = Unknown;
377  }
378  }
379  }
380 
381 }
382 
384 {
385  mLoaded = true;
386 }
387 
388 void QgsComposerPicture::loadPicture( const QString &path )
389 {
390  if ( path.startsWith( "http" ) )
391  {
392  //remote location
393  loadRemotePicture( path );
394  }
395  else
396  {
397  //local location
398  loadLocalPicture( path );
399  }
400  if ( mMode != Unknown ) //make sure we start with a new QImage
401  {
402  recalculateSize();
403  }
404  else if ( mHasExpressionError || !( path.isEmpty() ) )
405  {
406  //trying to load an invalid file or bad expression, show cross picture
407  mMode = SVG;
408  QString badFile = QString( ":/images/composer/missing_image.svg" );
409  mSVG.load( badFile );
410  if ( mSVG.isValid() )
411  {
412  mMode = SVG;
413  QRect viewBox = mSVG.viewBox(); //take width/height ratio from view box instead of default size
414  mDefaultSvgSize.setWidth( viewBox.width() );
415  mDefaultSvgSize.setHeight( viewBox.height() );
416  recalculateSize();
417  }
418  }
419 
420  emit itemChanged();
421 }
422 
423 QRectF QgsComposerPicture::boundedImageRect( double deviceWidth, double deviceHeight )
424 {
425  double imageToDeviceRatio;
426  if ( mImage.width() / deviceWidth > mImage.height() / deviceHeight )
427  {
428  imageToDeviceRatio = deviceWidth / mImage.width();
429  double height = imageToDeviceRatio * mImage.height();
430  return QRectF( 0, 0, deviceWidth, height );
431  }
432  else
433  {
434  imageToDeviceRatio = deviceHeight / mImage.height();
435  double width = imageToDeviceRatio * mImage.width();
436  return QRectF( 0, 0, width, deviceHeight );
437  }
438 }
439 
440 QRectF QgsComposerPicture::boundedSVGRect( double deviceWidth, double deviceHeight )
441 {
442  double imageToSvgRatio;
443  if ( deviceWidth / mDefaultSvgSize.width() > deviceHeight / mDefaultSvgSize.height() )
444  {
445  imageToSvgRatio = deviceHeight / mDefaultSvgSize.height();
446  double width = mDefaultSvgSize.width() * imageToSvgRatio;
447  return QRectF( 0, 0, width, deviceHeight );
448  }
449  else
450  {
451  imageToSvgRatio = deviceWidth / mDefaultSvgSize.width();
452  double height = mDefaultSvgSize.height() * imageToSvgRatio;
453  return QRectF( 0, 0, deviceWidth, height );
454  }
455 }
456 
458 {
459  if ( mMode == SVG )
460  {
461  return mDefaultSvgSize;
462  }
463  else if ( mMode == RASTER )
464  {
465  return QSizeF( mImage.width(), mImage.height() );
466  }
467  else
468  {
469  return QSizeF( 0, 0 );
470  }
471 }
472 
473 #if 0
474 QRectF QgsComposerPicture::boundedSVGRect( double deviceWidth, double deviceHeight )
475 {
476  double imageToSvgRatio;
477  if ( deviceWidth / mDefaultSvgSize.width() < deviceHeight / mDefaultSvgSize.height() )
478  {
479  imageToSvgRatio = deviceWidth / mDefaultSvgSize.width();
480  double height = mDefaultSvgSize.height() * imageToSvgRatio;
481  return QRectF( 0, 0, deviceWidth, height );
482  }
483  else
484  {
485  imageToSvgRatio = deviceHeight / mDefaultSvgSize.height();
486  double width = mDefaultSvgSize.width() * imageToSvgRatio;
487  return QRectF( 0, 0, width, deviceHeight );
488  }
489 }
490 #endif //0
491 
492 void QgsComposerPicture::setSceneRect( const QRectF& rectangle )
493 {
494 
495  QSizeF currentPictureSize = pictureSize();
496 
498  {
499  QgsComposerItem::setSceneRect( rectangle );
500  mPictureWidth = rectangle.width();
501  mPictureHeight = rectangle.height();
502  return;
503  }
504 
505  QRectF newRect = rectangle;
506 
507  if ( mResizeMode == ZoomResizeFrame && !rect().isEmpty() && !( currentPictureSize.isEmpty() ) )
508  {
509  //if width has changed less than height, then fix width and set height correspondingly
510  //else, do the opposite
511  if ( qAbs( rect().width() - rectangle.width() ) <
512  qAbs( rect().height() - rectangle.height() ) )
513  {
514  newRect.setHeight( currentPictureSize.height() * newRect.width() / currentPictureSize.width() );
515  }
516  else
517  {
518  newRect.setWidth( currentPictureSize.width() * newRect.height() / currentPictureSize.height() );
519  }
520  }
521  else if ( mResizeMode == FrameToImageSize )
522  {
523  if ( !( currentPictureSize.isEmpty() ) )
524  {
525  newRect.setWidth( currentPictureSize.width() * 25.4 / mComposition->printResolution() );
526  newRect.setHeight( currentPictureSize.height() * 25.4 / mComposition->printResolution() );
527  }
528  }
529 
530  //find largest scaling of picture with this rotation which fits in item
531  if ( mResizeMode == Zoom )
532  {
533  QRectF rotatedImageRect = QgsComposerUtils::largestRotatedRectWithinBounds( QRectF( 0, 0, currentPictureSize.width(), currentPictureSize.height() ), newRect, mPictureRotation );
534  mPictureWidth = rotatedImageRect.width();
535  mPictureHeight = rotatedImageRect.height();
536  }
537  else
538  {
539  mPictureWidth = newRect.width();
540  mPictureHeight = newRect.height();
541  }
542 
544  emit itemChanged();
545 }
546 
548 {
549  //kept for compatibility for QGIS2.0 api
550  setPictureRotation( r );
551 }
552 
554 {
555  mPictureRotation = r;
556 
557  if ( mResizeMode == Zoom )
558  {
559  //find largest scaling of picture with this rotation which fits in item
560  QSizeF currentPictureSize = pictureSize();
561  QRectF rotatedImageRect = QgsComposerUtils::largestRotatedRectWithinBounds( QRectF( 0, 0, currentPictureSize.width(), currentPictureSize.height() ), rect(), mPictureRotation );
562  mPictureWidth = rotatedImageRect.width();
563  mPictureHeight = rotatedImageRect.height();
564  update();
565  }
566 
568 }
569 
570 void QgsComposerPicture::setRotationMap( int composerMapId )
571 {
572  if ( !mComposition )
573  {
574  return;
575  }
576 
577  if ( composerMapId == -1 ) //disable rotation from map
578  {
579  QObject::disconnect( mRotationMap, SIGNAL( mapRotationChanged( double ) ), this, SLOT( setPictureRotation( double ) ) );
580  mRotationMap = 0;
581  }
582 
583  const QgsComposerMap* map = mComposition->getComposerMapById( composerMapId );
584  if ( !map )
585  {
586  return;
587  }
588  if ( mRotationMap )
589  {
590  QObject::disconnect( mRotationMap, SIGNAL( mapRotationChanged( double ) ), this, SLOT( setPictureRotation( double ) ) );
591  }
592  mPictureRotation = map->mapRotation();
593  QObject::connect( map, SIGNAL( mapRotationChanged( double ) ), this, SLOT( setPictureRotation( double ) ) );
594  mRotationMap = map;
595  update();
597 }
598 
600 {
601  mResizeMode = mode;
603  || ( mode == QgsComposerPicture::Zoom && mPictureRotation != 0 ) )
604  {
605  //call set scene rect to force item to resize to fit picture
606  recalculateSize();
607  }
608  update();
609 }
610 
612 {
613  //call set scene rect with current position/size, as this will trigger the
614  //picture item to recalculate its frame and image size
615  setSceneRect( QRectF( pos().x(), pos().y(), rect().width(), rect().height() ) );
616 }
617 
619 {
621  {
622  refreshPicture();
623  }
624 
626 }
627 
629 {
631  refreshPicture();
632 }
633 
635 {
637  refreshPicture();
638 }
639 
641 {
642  return picturePath();
643 }
644 
645 void QgsComposerPicture::setPicturePath( const QString &path )
646 {
647  mSourcePath = path;
648  refreshPicture();
649 }
650 
652 {
653  return mSourcePath;
654 }
655 
656 bool QgsComposerPicture::writeXML( QDomElement& elem, QDomDocument & doc ) const
657 {
658  if ( elem.isNull() )
659  {
660  return false;
661  }
662  QDomElement composerPictureElem = doc.createElement( "ComposerPicture" );
663  composerPictureElem.setAttribute( "file", QgsProject::instance()->writePath( mSourcePath ) );
664  composerPictureElem.setAttribute( "pictureWidth", QString::number( mPictureWidth ) );
665  composerPictureElem.setAttribute( "pictureHeight", QString::number( mPictureHeight ) );
666  composerPictureElem.setAttribute( "resizeMode", QString::number(( int )mResizeMode ) );
667  composerPictureElem.setAttribute( "anchorPoint", QString::number(( int )mPictureAnchor ) );
668 
669  //rotation
670  composerPictureElem.setAttribute( "pictureRotation", QString::number( mPictureRotation ) );
671  if ( !mRotationMap )
672  {
673  composerPictureElem.setAttribute( "mapId", -1 );
674  }
675  else
676  {
677  composerPictureElem.setAttribute( "mapId", mRotationMap->id() );
678  }
679 
680  _writeXML( composerPictureElem, doc );
681  elem.appendChild( composerPictureElem );
682  return true;
683 }
684 
685 bool QgsComposerPicture::readXML( const QDomElement& itemElem, const QDomDocument& doc )
686 {
687  if ( itemElem.isNull() )
688  {
689  return false;
690  }
691 
692  mPictureWidth = itemElem.attribute( "pictureWidth", "10" ).toDouble();
693  mPictureHeight = itemElem.attribute( "pictureHeight", "10" ).toDouble();
694  mResizeMode = QgsComposerPicture::ResizeMode( itemElem.attribute( "resizeMode", "0" ).toInt() );
695  //when loading from xml, default to anchor point of middle to match pre 2.4 behaviour
696  mPictureAnchor = ( QgsComposerItem::ItemPositionMode ) itemElem.attribute( "anchorPoint", QString::number( QgsComposerItem::Middle ) ).toInt();
697 
698  QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" );
699  if ( composerItemList.size() > 0 )
700  {
701  QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
702 
703  if ( composerItemElem.attribute( "rotation", "0" ).toDouble() != 0 )
704  {
705  //in versions prior to 2.1 picture rotation was stored in the rotation attribute
706  mPictureRotation = composerItemElem.attribute( "rotation", "0" ).toDouble();
707  }
708 
709  _readXML( composerItemElem, doc );
710  }
711 
712  mDefaultSvgSize = QSize( 0, 0 );
713 
714  if ( itemElem.hasAttribute( "sourceExpression" ) )
715  {
716  //update pre 2.5 picture expression to use data defined expression
717  QString sourceExpression = itemElem.attribute( "sourceExpression", "" );
718  QString useExpression = itemElem.attribute( "useExpression" );
719  bool expressionActive;
720  if ( useExpression.compare( "true", Qt::CaseInsensitive ) == 0 )
721  {
722  expressionActive = true;
723  }
724  else
725  {
726  expressionActive = false;
727  }
728 
729  setDataDefinedProperty( QgsComposerObject::PictureSource, expressionActive, true, sourceExpression, QString() );
730  }
731 
732  mSourcePath = QgsProject::instance()->readPath( itemElem.attribute( "file" ) );
733 
734  //picture rotation
735  if ( itemElem.attribute( "pictureRotation", "0" ).toDouble() != 0 )
736  {
737  mPictureRotation = itemElem.attribute( "pictureRotation", "0" ).toDouble();
738  }
739 
740  //rotation map
741  int rotationMapId = itemElem.attribute( "mapId", "-1" ).toInt();
742  if ( rotationMapId == -1 )
743  {
744  mRotationMap = 0;
745  }
746  else if ( mComposition )
747  {
748 
749  if ( mRotationMap )
750  {
751  QObject::disconnect( mRotationMap, SIGNAL( mapRotationChanged( double ) ), this, SLOT( setRotation( double ) ) );
752  }
753  mRotationMap = mComposition->getComposerMapById( rotationMapId );
754  QObject::connect( mRotationMap, SIGNAL( mapRotationChanged( double ) ), this, SLOT( setRotation( double ) ) );
755  }
756 
757  refreshPicture();
758 
759  emit itemChanged();
760  return true;
761 }
762 
764 {
765  if ( !mRotationMap )
766  {
767  return -1;
768  }
769  else
770  {
771  return mRotationMap->id();
772  }
773 }
774 
776 {
777  mPictureAnchor = anchor;
778  update();
779 }
780 
782 {
784 }
785 
787 {
789 }
790 
791 bool QgsComposerPicture::imageSizeConsideringRotation( double& width, double& height ) const
792 {
793  //kept for api compatibility with QGIS 2.0 - use mPictureRotation
797 }
798 
799 bool QgsComposerPicture::cornerPointOnRotatedAndScaledRect( double& x, double& y, double width, double height ) const
800 {
801  //kept for api compatibility with QGIS 2.0 - use mPictureRotation
805 }
806 
807 void QgsComposerPicture::sizeChangedByRotation( double& width, double& height )
808 {
809  //kept for api compatibility with QGIS 2.0 - use mPictureRotation
813 }
void setActive(bool active)
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 readXML(const QDomElement &itemElem, const QDomDocument &doc)
Sets state from Dom document.
QSizeF pictureSize()
Returns size of current raster or svg picture.
#define QgsDebugMsg(str)
Definition: qgslogger.h:36
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).
QMap< QgsComposerObject::DataDefinedProperty, QString > mDataDefinedNames
Map of data defined properties for the item to string name to use when exporting item to xml...
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.
void fetchContent(const QUrl url)
Fetches content from a remote URL and handles redirects.
virtual void setRotation(double r)
Sets the picture rotation within the item bounds.
QString expressionString() const
QgsComposerItem::ItemPositionMode mPictureAnchor
virtual void drawFrame(QPainter *p)
Draw black frame around item.
QString picturePath() const
Returns the path of the source image.
QNetworkReply * reply()
Returns a reference to the network reply.
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
DataDefinedProperty
Data defined properties for different item types.
bool dataDefinedEvaluate(const QgsComposerObject::DataDefinedProperty property, QVariant &expressionValue)
Evaluate a data defined property and return the calculated value.
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.
QgsDataDefined * dataDefinedProperty(const DataDefinedProperty property) const
Returns a reference to the data defined settings for one of the item's data defined properties...
QRectF boundedSVGRect(double deviceWidth, double deviceHeight)
Calculates bounding rect for svg file (mSourcefile) such that aspect ratio is correct.
void loadPicture(const QString &path)
loads an image file into the picture item and redraws the item
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.
void loadLocalPicture(const QString &path)
Loads a local picture for the item.
virtual void refreshDataDefinedProperty(const QgsComposerObject::DataDefinedProperty property=QgsComposerObject::AllProperties)
Refreshes a data defined property for the item by reevaluating the property's value and redrawing the...
HTTP network content fetcher.
const QgsComposerMap * mRotationMap
Map that sets the rotation (or 0 if this picture uses map independent rotation)
virtual void drawSelectionBoxes(QPainter *p)
Draws additional graphics on selected items.
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.
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.
Object representing map window.
Q_DECL_DEPRECATED 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.
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:440
int id() const
Get identification number.
void loadRemotePicture(const QString &url)
Loads a remote picture for the item.
Q_DECL_DEPRECATED 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...
virtual void refreshDataDefinedProperty(const QgsComposerObject::DataDefinedProperty property=QgsComposerObject::AllProperties)
Q_DECL_DEPRECATED bool cornerPointOnRotatedAndScaledRect(double &x, double &y, double width, double height, double rotation) const
Calculates corner point after rotation and scaling.
bool _writeXML(QDomElement &itemElem, QDomDocument &doc) const
Writes parameter that are not subclass specific in document.
virtual void drawBackground(QPainter *p)
Draw background.
Q_DECL_DEPRECATED QString pictureExpression() const
Returns the expression the item is using for the picture source.
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...
void setDataDefinedProperty(const DataDefinedProperty property, const bool active, const bool useExpression, const QString &expression, const QString &field)
Sets parameters for a data defined property for the item.
double mPictureWidth
Width of the picture (in mm)
QgsAtlasComposition & atlasComposition()
void setRotationMap(int composerMapId)
Sets the map object for rotation (by id).
void setPicturePath(const QString &path)
Sets the source path of the image (may be svg or a raster format).
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.
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.
void init()
sets up the picture item and connects to relevant signals
void setExpressionString(const QString &expr)
bool isActive() const
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 bool usePictureExpression() const
Returns whether the picture item is using an expression for the image source.
Q_DECL_DEPRECATED void sizeChangedByRotation(double &width, double &height)
Calculates width / height of the bounding box of a rotated rectangle.
#define tr(sourceText)