QGIS API Documentation  2.12.0-Lyon
qgscomposeritem.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscomposeritem.cpp
3  -------------------
4  begin : January 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 #include <QWidget>
18 #include <QDomNode>
19 #include <QFile>
20 #include <QGraphicsLineItem>
21 #include <QGraphicsScene>
22 #include <QGraphicsSceneMouseEvent>
23 #include <QGraphicsView>
24 #include <QPainter>
25 #include <QUuid>
26 #include <QGraphicsEffect>
27 
28 #include "qgsproject.h"
29 
30 #include "qgscomposition.h"
31 #include "qgscomposeritem.h"
32 #include "qgscomposerframe.h"
33 #include "qgsdatadefined.h"
34 #include "qgscomposerutils.h"
35 #include "qgscomposermodel.h"
36 
37 #include <limits>
38 #include "qgsapplication.h"
39 #include "qgsrectangle.h" //just for debugging
40 #include "qgslogger.h"
41 #include "qgssymbollayerv2utils.h" //for pointOnLineWithDistance
42 #include "qgsmaprenderer.h" //for getCompositionMode
43 #include "qgsexpressioncontext.h"
44 
45 #include <cmath>
46 
47 #define FONT_WORKAROUND_SCALE 10 //scale factor for upscaling fontsize and downscaling painter
48 
49 #ifndef M_DEG2RAD
50 #define M_DEG2RAD 0.0174532925
51 #endif
52 
53 QgsComposerItem::QgsComposerItem( QgsComposition* composition, bool manageZValue )
54  : QgsComposerObject( composition )
55  , QGraphicsRectItem( 0 )
56  , mRemovedFromComposition( false )
57  , mBoundingResizeRectangle( 0 )
58  , mHAlignSnapItem( 0 )
59  , mVAlignSnapItem( 0 )
60  , mFrame( false )
61  , mBackground( true )
62  , mBackgroundColor( QColor( 255, 255, 255, 255 ) )
63  , mFrameJoinStyle( Qt::MiterJoin )
64  , mItemPositionLocked( false )
65  , mLastValidViewScaleFactor( -1 )
66  , mItemRotation( 0 )
67  , mEvaluatedItemRotation( 0 )
68  , mBlendMode( QPainter::CompositionMode_SourceOver )
69  , mEffectsEnabled( true )
70  , mTransparency( 0 )
71  , mExcludeFromExports( false )
72  , mEvaluatedExcludeFromExports( false )
73  , mLastUsedPositionMode( UpperLeft )
74  , mIsGroupMember( false )
75  , mCurrentExportLayer( -1 )
76  , mId( "" )
77  , mUuid( QUuid::createUuid().toString() )
78 {
79  init( manageZValue );
80 }
81 
82 QgsComposerItem::QgsComposerItem( qreal x, qreal y, qreal width, qreal height, QgsComposition* composition, bool manageZValue )
83  : QgsComposerObject( composition )
84  , QGraphicsRectItem( 0, 0, width, height, 0 )
85  , mRemovedFromComposition( false )
86  , mBoundingResizeRectangle( 0 )
87  , mHAlignSnapItem( 0 )
88  , mVAlignSnapItem( 0 )
89  , mFrame( false )
90  , mBackground( true )
91  , mBackgroundColor( QColor( 255, 255, 255, 255 ) )
92  , mFrameJoinStyle( Qt::MiterJoin )
93  , mItemPositionLocked( false )
94  , mLastValidViewScaleFactor( -1 )
95  , mItemRotation( 0 )
96  , mEvaluatedItemRotation( 0 )
97  , mBlendMode( QPainter::CompositionMode_SourceOver )
98  , mEffectsEnabled( true )
99  , mTransparency( 0 )
100  , mExcludeFromExports( false )
101  , mEvaluatedExcludeFromExports( false )
102  , mLastUsedPositionMode( UpperLeft )
103  , mIsGroupMember( false )
104  , mCurrentExportLayer( -1 )
105  , mId( "" )
106  , mUuid( QUuid::createUuid().toString() )
107 {
108  init( manageZValue );
109  setPos( x, y );
110 }
111 
112 void QgsComposerItem::init( const bool manageZValue )
113 {
114  setFlag( QGraphicsItem::ItemIsSelectable, true );
115  //set default pen and brush
116  setBrush( QBrush( QColor( 255, 255, 255, 255 ) ) );
117  QPen defaultPen( QColor( 0, 0, 0 ) );
118  defaultPen.setWidthF( 0.3 );
119  defaultPen.setJoinStyle( mFrameJoinStyle );
120  setPen( defaultPen );
121  //let z-Value be managed by composition
122  if ( mComposition && manageZValue )
123  {
124  mCompositionManagesZValue = true;
125  mComposition->addItemToZList( this );
126  }
127  else
128  {
129  mCompositionManagesZValue = false;
130  }
131 
132  // Setup composer effect
133  mEffect = new QgsComposerEffect();
135 
136  // data defined strings
137  mDataDefinedNames.insert( QgsComposerObject::PageNumber, QString( "dataDefinedPageNumber" ) );
138  mDataDefinedNames.insert( QgsComposerObject::PositionX, QString( "dataDefinedPositionX" ) );
139  mDataDefinedNames.insert( QgsComposerObject::PositionY, QString( "dataDefinedPositionY" ) );
143  mDataDefinedNames.insert( QgsComposerObject::Transparency, QString( "dataDefinedTransparency" ) );
144  mDataDefinedNames.insert( QgsComposerObject::BlendMode, QString( "dataDefinedBlendMode" ) );
145  mDataDefinedNames.insert( QgsComposerObject::ExcludeFromExports, QString( "dataDefinedExcludeExports" ) );
146 }
147 
149 {
150  if ( mComposition && mCompositionManagesZValue )
151  {
153  }
154 
156  delete mEffect;
157 
159 }
160 
162 {
163  QgsDebugMsg( "entered." );
165  //inform model that id data has changed
166  if ( mComposition )
167  {
169  }
170  update(); //to draw selection boxes
171 }
172 
174 {
175  if ( itemElem.isNull() )
176  {
177  return false;
178  }
179 
180  QDomElement composerItemElem = doc.createElement( "ComposerItem" );
181 
182  //frame
183  if ( mFrame )
184  {
185  composerItemElem.setAttribute( "frame", "true" );
186  }
187  else
188  {
189  composerItemElem.setAttribute( "frame", "false" );
190  }
191 
192  //background
193  if ( mBackground )
194  {
195  composerItemElem.setAttribute( "background", "true" );
196  }
197  else
198  {
199  composerItemElem.setAttribute( "background", "false" );
200  }
201 
202  //scene rect
203  QPointF pagepos = pagePos();
204  composerItemElem.setAttribute( "x", QString::number( pos().x() ) );
205  composerItemElem.setAttribute( "y", QString::number( pos().y() ) );
206  composerItemElem.setAttribute( "page", page() );
207  composerItemElem.setAttribute( "pagex", QString::number( pagepos.x() ) );
208  composerItemElem.setAttribute( "pagey", QString::number( pagepos.y() ) );
209  composerItemElem.setAttribute( "width", QString::number( rect().width() ) );
210  composerItemElem.setAttribute( "height", QString::number( rect().height() ) );
211  composerItemElem.setAttribute( "positionMode", QString::number(( int ) mLastUsedPositionMode ) );
212  composerItemElem.setAttribute( "zValue", QString::number( zValue() ) );
213  composerItemElem.setAttribute( "outlineWidth", QString::number( pen().widthF() ) );
214  composerItemElem.setAttribute( "frameJoinStyle", QgsSymbolLayerV2Utils::encodePenJoinStyle( mFrameJoinStyle ) );
215  composerItemElem.setAttribute( "itemRotation", QString::number( mItemRotation ) );
216  composerItemElem.setAttribute( "uuid", mUuid );
217  composerItemElem.setAttribute( "id", mId );
218  composerItemElem.setAttribute( "visibility", isVisible() );
219  //position lock for mouse moves/resizes
220  if ( mItemPositionLocked )
221  {
222  composerItemElem.setAttribute( "positionLock", "true" );
223  }
224  else
225  {
226  composerItemElem.setAttribute( "positionLock", "false" );
227  }
228 
229  composerItemElem.setAttribute( "lastValidViewScaleFactor", QString::number( mLastValidViewScaleFactor ) );
230 
231  //frame color
232  QDomElement frameColorElem = doc.createElement( "FrameColor" );
233  QColor frameColor = pen().color();
234  frameColorElem.setAttribute( "red", QString::number( frameColor.red() ) );
235  frameColorElem.setAttribute( "green", QString::number( frameColor.green() ) );
236  frameColorElem.setAttribute( "blue", QString::number( frameColor.blue() ) );
237  frameColorElem.setAttribute( "alpha", QString::number( frameColor.alpha() ) );
238  composerItemElem.appendChild( frameColorElem );
239 
240  //background color
241  QDomElement bgColorElem = doc.createElement( "BackgroundColor" );
242  QColor bgColor = brush().color();
243  bgColorElem.setAttribute( "red", QString::number( bgColor.red() ) );
244  bgColorElem.setAttribute( "green", QString::number( bgColor.green() ) );
245  bgColorElem.setAttribute( "blue", QString::number( bgColor.blue() ) );
246  bgColorElem.setAttribute( "alpha", QString::number( bgColor.alpha() ) );
247  composerItemElem.appendChild( bgColorElem );
248 
249  //blend mode
250  composerItemElem.setAttribute( "blendMode", QgsMapRenderer::getBlendModeEnum( mBlendMode ) );
251 
252  //transparency
253  composerItemElem.setAttribute( "transparency", QString::number( mTransparency ) );
254 
255  composerItemElem.setAttribute( "excludeFromExports", mExcludeFromExports );
256 
257  QgsComposerObject::writeXML( composerItemElem, doc );
258  itemElem.appendChild( composerItemElem );
259 
260  return true;
261 }
262 
263 bool QgsComposerItem::_readXML( const QDomElement& itemElem, const QDomDocument& doc )
264 {
265  Q_UNUSED( doc );
266  if ( itemElem.isNull() )
267  {
268  return false;
269  }
270 
271  QgsComposerObject::readXML( itemElem, doc );
272 
273  //rotation
274  setItemRotation( itemElem.attribute( "itemRotation", "0" ).toDouble() );
275 
276  //uuid
277  mUuid = itemElem.attribute( "uuid", QUuid::createUuid().toString() );
278 
279  // temporary for groups imported from templates
280  mTemplateUuid = itemElem.attribute( "templateUuid" );
281 
282  //id
283  QString id = itemElem.attribute( "id", "" );
284  setId( id );
285 
286  //frame
287  QString frame = itemElem.attribute( "frame" );
288  if ( frame.compare( "true", Qt::CaseInsensitive ) == 0 )
289  {
290  mFrame = true;
291  }
292  else
293  {
294  mFrame = false;
295  }
296 
297  //frame
298  QString background = itemElem.attribute( "background" );
299  if ( background.compare( "true", Qt::CaseInsensitive ) == 0 )
300  {
301  mBackground = true;
302  }
303  else
304  {
305  mBackground = false;
306  }
307 
308  //position lock for mouse moves/resizes
309  QString positionLock = itemElem.attribute( "positionLock" );
310  if ( positionLock.compare( "true", Qt::CaseInsensitive ) == 0 )
311  {
312  setPositionLock( true );
313  }
314  else
315  {
316  setPositionLock( false );
317  }
318 
319  //visibility
320  setVisibility( itemElem.attribute( "visibility", "1" ) != "0" );
321 
322  //position
323  int page;
324  double x, y, pagex, pagey, width, height;
325  bool xOk, yOk, pageOk, pagexOk, pageyOk, widthOk, heightOk, positionModeOK;
326 
327  x = itemElem.attribute( "x" ).toDouble( &xOk );
328  y = itemElem.attribute( "y" ).toDouble( &yOk );
329  page = itemElem.attribute( "page" ).toInt( &pageOk );
330  pagex = itemElem.attribute( "pagex" ).toDouble( &pagexOk );
331  pagey = itemElem.attribute( "pagey" ).toDouble( &pageyOk );
332  width = itemElem.attribute( "width" ).toDouble( &widthOk );
333  height = itemElem.attribute( "height" ).toDouble( &heightOk );
334  mLastUsedPositionMode = ( ItemPositionMode )itemElem.attribute( "positionMode" ).toInt( &positionModeOK );
335  if ( !positionModeOK )
336  {
338  }
339  if ( pageOk && pagexOk && pageyOk )
340  {
341  xOk = true;
342  yOk = true;
343  x = pagex;
344  y = ( page - 1 ) * ( mComposition->paperHeight() + composition()->spaceBetweenPages() ) + pagey;
345  }
346 
347  if ( !xOk || !yOk || !widthOk || !heightOk )
348  {
349  return false;
350  }
351 
352  mLastValidViewScaleFactor = itemElem.attribute( "lastValidViewScaleFactor", "-1" ).toDouble();
353 
354  setZValue( itemElem.attribute( "zValue" ).toDouble() );
355 
356  //pen
357  QDomNodeList frameColorList = itemElem.elementsByTagName( "FrameColor" );
358  if ( frameColorList.size() > 0 )
359  {
360  QDomElement frameColorElem = frameColorList.at( 0 ).toElement();
361  bool redOk, greenOk, blueOk, alphaOk, widthOk;
362  int penRed, penGreen, penBlue, penAlpha;
363  double penWidth;
364 
365  penWidth = itemElem.attribute( "outlineWidth" ).toDouble( &widthOk );
366  penRed = frameColorElem.attribute( "red" ).toDouble( &redOk );
367  penGreen = frameColorElem.attribute( "green" ).toDouble( &greenOk );
368  penBlue = frameColorElem.attribute( "blue" ).toDouble( &blueOk );
369  penAlpha = frameColorElem.attribute( "alpha" ).toDouble( &alphaOk );
370  mFrameJoinStyle = QgsSymbolLayerV2Utils::decodePenJoinStyle( itemElem.attribute( "frameJoinStyle", "miter" ) );
371 
372  if ( redOk && greenOk && blueOk && alphaOk && widthOk )
373  {
374  QPen framePen( QColor( penRed, penGreen, penBlue, penAlpha ) );
375  framePen.setWidthF( penWidth );
376  framePen.setJoinStyle( mFrameJoinStyle );
377  setPen( framePen );
378  }
379  }
380 
381  //brush
382  QDomNodeList bgColorList = itemElem.elementsByTagName( "BackgroundColor" );
383  if ( bgColorList.size() > 0 )
384  {
385  QDomElement bgColorElem = bgColorList.at( 0 ).toElement();
386  bool redOk, greenOk, blueOk, alphaOk;
387  int bgRed, bgGreen, bgBlue, bgAlpha;
388  bgRed = bgColorElem.attribute( "red" ).toDouble( &redOk );
389  bgGreen = bgColorElem.attribute( "green" ).toDouble( &greenOk );
390  bgBlue = bgColorElem.attribute( "blue" ).toDouble( &blueOk );
391  bgAlpha = bgColorElem.attribute( "alpha" ).toDouble( &alphaOk );
392  if ( redOk && greenOk && blueOk && alphaOk )
393  {
394  QColor brushColor( bgRed, bgGreen, bgBlue, bgAlpha );
395  setBackgroundColor( brushColor );
396  }
397  }
398 
399  //blend mode
401 
402  //transparency
403  setTransparency( itemElem.attribute( "transparency", "0" ).toInt() );
404 
405  mExcludeFromExports = itemElem.attribute( "excludeFromExports", "0" ).toInt();
407 
408  QRectF evaluatedRect = evalItemRect( QRectF( x, y, width, height ) );
409  setSceneRect( evaluatedRect );
410 
411  return true;
412 }
413 
414 void QgsComposerItem::setFrameEnabled( const bool drawFrame )
415 {
416  if ( drawFrame == mFrame )
417  {
418  //no change
419  return;
420  }
421 
422  mFrame = drawFrame;
423  emit frameChanged();
424 }
425 
427 {
428  QPen itemPen = pen();
429  if ( itemPen.color() == color )
430  {
431  //no change
432  return;
433  }
434  itemPen.setColor( color );
435  setPen( itemPen );
436  emit frameChanged();
437 }
438 
439 void QgsComposerItem::setFrameOutlineWidth( const double outlineWidth )
440 {
441  QPen itemPen = pen();
442  if ( itemPen.widthF() == outlineWidth )
443  {
444  //no change
445  return;
446  }
447  itemPen.setWidthF( outlineWidth );
448  setPen( itemPen );
449  emit frameChanged();
450 }
451 
452 void QgsComposerItem::setFrameJoinStyle( const Qt::PenJoinStyle style )
453 {
454  if ( mFrameJoinStyle == style )
455  {
456  //no change
457  return;
458  }
459  mFrameJoinStyle = style;
460 
461  QPen itemPen = pen();
462  itemPen.setJoinStyle( mFrameJoinStyle );
463  setPen( itemPen );
464  emit frameChanged();
465 }
466 
468 {
469  if ( !hasFrame() )
470  {
471  return 0;
472  }
473 
474  return pen().widthF() / 2.0;
475 }
476 
478 {
479  double frameBleed = estimatedFrameBleed();
480  return rect().adjusted( -frameBleed, -frameBleed, frameBleed, frameBleed );
481 }
482 
484 {
485  if ( mComposition )
486  {
487  mComposition->beginCommand( this, commandText, c );
488  }
489 }
490 
492 {
493  if ( mComposition )
494  {
496  }
497 }
498 
500 {
501  if ( mComposition )
502  {
504  }
505 }
506 
508 {
509  Q_UNUSED( p );
511  {
512  return;
513  }
514 
515  if ( !isSelected() )
516  {
517  return;
518  }
519 
520  //logic for drawing additional graphics on selected items here (if required)
521 
522  //draw dotted border around locked, selected items
523  if ( positionLock() )
524  {
525  p->save();
526  p->setCompositionMode( QPainter::CompositionMode_Difference );
527 
528  // use a grey dashed pen - in difference mode this should always be visible
529  QPen selectedItemPen = QPen( QColor( 144, 144, 144, 255 ) );
530  selectedItemPen.setStyle( Qt::DotLine );
531  selectedItemPen.setWidth( 0 );
532  p->setPen( selectedItemPen );
533  p->setBrush( Qt::NoBrush );
534  p->drawPolygon( rect() );
535  p->restore();
536  }
537 
538 }
539 
541 {
542  if ( mFrame && p )
543  {
544  p->save();
545  p->setPen( pen() );
546  p->setBrush( Qt::NoBrush );
547  p->setRenderHint( QPainter::Antialiasing, true );
548  p->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
549  p->restore();
550  }
551 }
552 
553 void QgsComposerItem::setPositionLock( const bool lock )
554 {
555  if ( lock == mItemPositionLocked )
556  {
557  return;
558  }
559 
560  mItemPositionLocked = lock;
561 
562  //inform model that id data has changed
563  if ( mComposition )
564  {
566  }
567  update();
568  emit lockChanged();
569 }
570 
571 double QgsComposerItem::itemRotation( const PropertyValueType valueType ) const
572 {
574 }
575 
576 void QgsComposerItem::move( double dx, double dy )
577 {
578  QRectF newSceneRect( pos().x() + dx, pos().y() + dy, rect().width(), rect().height() );
579  setSceneRect( evalItemRect( newSceneRect ) );
580 }
581 
583 {
584  double y = pos().y();
585  double h = composition()->paperHeight() + composition()->spaceBetweenPages();
586  int page = 1;
587  while ( y - h >= 0. )
588  {
589  y -= h;
590  ++page;
591  }
592  return page;
593 }
594 
596 {
597  QPointF p = pos();
598  double h = composition()->paperHeight() + composition()->spaceBetweenPages();
599  p.ry() -= ( page() - 1 ) * h;
600  return p;
601 }
602 
603 void QgsComposerItem::updatePagePos( double newPageWidth, double newPageHeight )
604 {
605  Q_UNUSED( newPageWidth )
606  QPointF curPagePos = pagePos();
607  int curPage = page() - 1;
608 
609  double y = curPage * ( newPageHeight + composition()->spaceBetweenPages() ) + curPagePos.y();
610  QRectF newSceneRect( pos().x(), y, rect().width(), rect().height() );
611 
612  setSceneRect( evalItemRect( newSceneRect ) );
613  emit sizeChanged();
614 }
615 
616 void QgsComposerItem::setItemPosition( double x, double y, ItemPositionMode itemPoint, int page )
617 {
618  double width = rect().width();
619  double height = rect().height();
620  setItemPosition( x, y, width, height, itemPoint, false, page );
621 }
622 
623 void QgsComposerItem::setItemPosition( double x, double y, double width, double height, ItemPositionMode itemPoint, bool posIncludesFrame, int page )
624 {
625  double upperLeftX = x;
626  double upperLeftY = y;
627 
628  if ( page > 0 )
629  {
630  double h = composition()->paperHeight() + composition()->spaceBetweenPages();
631  upperLeftY += ( page - 1 ) * h;
632  }
633 
634  //store the item position mode
635  mLastUsedPositionMode = itemPoint;
636 
637  //adjust x-coordinate if placement is not done to a left point
638  if ( itemPoint == UpperMiddle || itemPoint == Middle || itemPoint == LowerMiddle )
639  {
640  upperLeftX -= width / 2.0;
641  }
642  else if ( itemPoint == UpperRight || itemPoint == MiddleRight || itemPoint == LowerRight )
643  {
644  upperLeftX -= width;
645  }
646 
647  //adjust y-coordinate if placement is not done to an upper point
648  if ( itemPoint == MiddleLeft || itemPoint == Middle || itemPoint == MiddleRight )
649  {
650  upperLeftY -= height / 2.0;
651  }
652  else if ( itemPoint == LowerLeft || itemPoint == LowerMiddle || itemPoint == LowerRight )
653  {
654  upperLeftY -= height;
655  }
656 
657  if ( posIncludesFrame )
658  {
659  //adjust position to account for frame size
660 
661  if ( mEvaluatedItemRotation == 0 )
662  {
663  upperLeftX += estimatedFrameBleed();
664  upperLeftY += estimatedFrameBleed();
665  }
666  else
667  {
668  //adjust position for item rotation
669  QLineF lineToItemOrigin = QLineF( 0, 0, estimatedFrameBleed(), estimatedFrameBleed() );
670  lineToItemOrigin.setAngle( -45 - mEvaluatedItemRotation );
671  upperLeftX += lineToItemOrigin.x2();
672  upperLeftY += lineToItemOrigin.y2();
673  }
674 
675  width -= 2 * estimatedFrameBleed();
676  height -= 2 * estimatedFrameBleed();
677  }
678 
679  //consider data defined item size and position before finalising rect
680  QRectF newRect = evalItemRect( QRectF( upperLeftX, upperLeftY, width, height ) );
681 
682  setSceneRect( newRect );
683 }
684 
685 void QgsComposerItem::setSceneRect( const QRectF& rectangle )
686 {
687  //setRect in item coordinates
688  double newWidth = rectangle.width();
689  double newHeight = rectangle.height();
690  double xTranslation = rectangle.x();
691  double yTranslation = rectangle.y();
692 
693  //correction if width and/or height are negative
694  if ( rectangle.width() < 0 )
695  {
696  newWidth = - rectangle.width();
697  xTranslation -= newWidth;
698  }
699 
700  if ( rectangle.height() < 0 )
701  {
702  newHeight = - rectangle.height();
703  yTranslation -= newHeight;
704  }
705 
706  QGraphicsRectItem::setRect( QRectF( 0, 0, newWidth, newHeight ) );
707  setPos( QPointF( xTranslation, yTranslation ) );
708 
709  emit sizeChanged();
710 }
711 
712 QRectF QgsComposerItem::evalItemRect( const QRectF &newRect, const bool resizeOnly, const QgsExpressionContext* context )
713 {
714  QRectF result = newRect;
715 
716  //TODO QGIS 3.0
717  //maintain pre 2.12 API. remove when API break allowed
719  const QgsExpressionContext* evalContext = context;
720  if ( !evalContext )
721  {
722  scopedContext.reset( createExpressionContext() );
723  evalContext = scopedContext.data();
724  }
725 
726  //data defined position or size set? if so, update rect with data defined values
727  QVariant exprVal;
728  //evaulate width and height first, since they may affect position if non-top-left reference point set
729  if ( dataDefinedEvaluate( QgsComposerObject::ItemWidth, exprVal, *evalContext ) )
730  {
731  bool ok;
732  double width = exprVal.toDouble( &ok );
733  QgsDebugMsg( QString( "exprVal Width:%1" ).arg( width ) );
734  if ( ok && !exprVal.isNull() )
735  {
736  result.setWidth( width );
737  }
738  }
739  if ( dataDefinedEvaluate( QgsComposerObject::ItemHeight, exprVal, *evalContext ) )
740  {
741  bool ok;
742  double height = exprVal.toDouble( &ok );
743  QgsDebugMsg( QString( "exprVal Height:%1" ).arg( height ) );
744  if ( ok && !exprVal.isNull() )
745  {
746  result.setHeight( height );
747  }
748  }
749 
750  double x = result.left();
751  //initially adjust for position mode to get x coordinate
752  if ( !resizeOnly )
753  {
754  //adjust x-coordinate if placement is not done to a left point
756  {
757  x += newRect.width() / 2.0;
758  }
760  {
761  x += newRect.width();
762  }
763  }
764  else
765  {
767  {
768  x += rect().width() / 2.0;
769  }
771  {
772  x += rect().width();
773  }
774  }
775  if ( dataDefinedEvaluate( QgsComposerObject::PositionX, exprVal, *evalContext ) )
776  {
777  bool ok;
778  double positionX = exprVal.toDouble( &ok );
779  QgsDebugMsg( QString( "exprVal Position X:%1" ).arg( positionX ) );
780  if ( ok && !exprVal.isNull() )
781  {
782  x = positionX;
783  }
784  }
785 
786  double y = result.top();
787  //initially adjust for position mode to get y coordinate
788  if ( !resizeOnly )
789  {
790  //adjust y-coordinate if placement is not done to an upper point
792  {
793  y += newRect.height() / 2.0;
794  }
796  {
797  y += newRect.height();
798  }
799  }
800  else
801  {
803  {
804  y += rect().height() / 2.0;
805  }
807  {
808  y += rect().height();
809  }
810  }
811  if ( dataDefinedEvaluate( QgsComposerObject::PositionY, exprVal, *evalContext ) )
812  {
813  bool ok;
814  double positionY = exprVal.toDouble( &ok );
815  QgsDebugMsg( QString( "exprVal Position Y:%1" ).arg( positionY ) );
816  if ( ok && !exprVal.isNull() )
817  {
818  y = positionY;
819  }
820  }
821 
822  //adjust x-coordinate if placement is not done to a left point
824  {
825  x -= result.width() / 2.0;
826  }
828  {
829  x -= result.width();
830  }
831 
832  //adjust y-coordinate if placement is not done to an upper point
834  {
835  y -= result.height() / 2.0;
836  }
838  {
839  y -= result.height();
840  }
841 
842  result.moveLeft( x );
843  result.moveTop( y );
844 
845  return result;
846 }
847 
849 {
851  {
852  //preview mode or no composition, so ok to draw item
853  return true;
854  }
855 
856  //exporting composition, so check if item is excluded from exports
858 }
859 
861 {
864  return context;
865 }
866 
868 {
869  if ( mBackground && p )
870  {
871  p->save();
872  p->setBrush( brush() );//this causes a problem in atlas generation
873  p->setPen( Qt::NoPen );
874  p->setRenderHint( QPainter::Antialiasing, true );
875  p->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
876  p->restore();
877  }
878 }
879 
880 void QgsComposerItem::drawArrowHead( QPainter *p, double x, double y, double angle, double arrowHeadWidth ) const
881 {
882  QgsComposerUtils::drawArrowHead( p, x, y, angle, arrowHeadWidth );
883 }
884 
885 double QgsComposerItem::angle( const QPointF &p1, const QPointF &p2 ) const
886 {
887  return QgsComposerUtils::angle( p1, p2 );
888 }
889 
890 void QgsComposerItem::setBackgroundColor( const QColor& backgroundColor )
891 {
893  setBrush( QBrush( mBackgroundColor, Qt::SolidPattern ) );
894 }
895 
896 void QgsComposerItem::setBlendMode( const QPainter::CompositionMode blendMode )
897 {
899  // Update the composer effect to use the new blend mode
901  refreshBlendMode( *context.data() );
902 }
903 
904 void QgsComposerItem::refreshBlendMode( const QgsExpressionContext& context )
905 {
906  QPainter::CompositionMode blendMode = mBlendMode;
907 
908  //data defined blend mode set?
909  QVariant exprVal;
910  if ( dataDefinedEvaluate( QgsComposerObject::BlendMode, exprVal, context ) && !exprVal.isNull() )
911  {
912  QString blendstr = exprVal.toString().trimmed();
913  QPainter::CompositionMode blendModeD = QgsSymbolLayerV2Utils::decodeBlendMode( blendstr );
914 
915  QgsDebugMsg( QString( "exprVal BlendMode:%1" ).arg( blendModeD ) );
916  blendMode = blendModeD;
917  }
918 
919  // Update the composer effect to use the new blend mode
920  mEffect->setCompositionMode( blendMode );
921 }
922 
923 void QgsComposerItem::setTransparency( const int transparency )
924 {
927  refreshTransparency( true, *context.data() );
928 }
929 
930 void QgsComposerItem::refreshTransparency( const bool updateItem, const QgsExpressionContext& context )
931 {
933 
934  //data defined transparency set?
935  QVariant exprVal;
936  if ( dataDefinedEvaluate( QgsComposerObject::Transparency, exprVal, context ) )
937  {
938  bool ok;
939  int transparencyD = exprVal.toInt( &ok );
940  QgsDebugMsg( QString( "exprVal Transparency:%1" ).arg( transparencyD ) );
941  if ( ok && !exprVal.isNull() )
942  {
943  transparency = transparencyD;
944  }
945  }
946 
947  // Set the QGraphicItem's opacity
948  setOpacity( 1. - ( transparency / 100. ) );
949 
950  if ( updateItem )
951  {
952  update();
953  }
954 }
955 
956 void QgsComposerItem::setEffectsEnabled( const bool effectsEnabled )
957 {
958  //enable or disable the QgsComposerEffect applied to this item
960  mEffect->setEnabled( effectsEnabled );
961 }
962 
963 void QgsComposerItem::drawText( QPainter* p, double x, double y, const QString& text, const QFont& font, const QColor& c ) const
964 {
965  QgsComposerUtils::drawText( p, QPointF( x, y ), text, font, c );
966 }
967 
968 void QgsComposerItem::drawText( QPainter* p, const QRectF& rect, const QString& text, const QFont& font, Qt::AlignmentFlag halignment, Qt::AlignmentFlag valignment, int flags ) const
969 {
970  QgsComposerUtils::drawText( p, rect, text, font, QColor(), halignment, valignment, flags );
971 }
972 double QgsComposerItem::textWidthMillimeters( const QFont& font, const QString& text ) const
973 {
974  return QgsComposerUtils::textWidthMM( font, text );
975 }
976 
977 double QgsComposerItem::fontHeightCharacterMM( const QFont& font, const QChar& c ) const
978 {
979  return QgsComposerUtils::fontHeightCharacterMM( font, c );
980 }
981 
983 {
984  return QgsComposerUtils::fontAscentMM( font );
985 }
986 
988 {
989  return QgsComposerUtils::fontDescentMM( font );
990 }
991 
993 {
994  return QgsComposerUtils::fontHeightMM( font );
995 }
996 
997 double QgsComposerItem::pixelFontSize( double pointSize ) const
998 {
999  return QgsComposerUtils::pointsToMM( pointSize );
1000 }
1001 
1003 {
1005 }
1006 
1008 {
1009  double result = -1;
1010  if ( scene() )
1011  {
1012  QList<QGraphicsView*> viewList = scene()->views();
1013  if ( viewList.size() > 0 ) //if not, probably this function was called from non-gui code
1014  {
1015  QGraphicsView* currentView = viewList.at( 0 );
1016  if ( currentView->isVisible() )
1017  {
1018  result = currentView->transform().m11();
1019  mLastValidViewScaleFactor = result;
1020  }
1021  }
1022  }
1023  return result;
1024 }
1025 
1027 {
1028  //size of symbol boxes depends on zoom level in composer view
1029  double viewScaleFactor = horizontalViewScaleFactor();
1030  double rectHandlerSize = 10.0 / viewScaleFactor;
1031 
1032  //make sure the boxes don't get too large
1033  if ( rectHandlerSize > ( rect().width() / 3 ) )
1034  {
1035  rectHandlerSize = rect().width() / 3;
1036  }
1037  if ( rectHandlerSize > ( rect().height() / 3 ) )
1038  {
1039  rectHandlerSize = rect().height() / 3;
1040  }
1041  return rectHandlerSize;
1042 }
1043 
1045 {
1046  double lockSymbolSize = 20.0 / horizontalViewScaleFactor();
1047 
1048  if ( lockSymbolSize > ( rect().width() / 3 ) )
1049  {
1050  lockSymbolSize = rect().width() / 3;
1051  }
1052  if ( lockSymbolSize > ( rect().height() / 3 ) )
1053  {
1054  lockSymbolSize = rect().height() / 3;
1055  }
1056  return lockSymbolSize;
1057 }
1058 
1059 void QgsComposerItem::setRotation( const double r )
1060 {
1061  //kept for api compatibility with QGIS 2.0
1062  //remove after 2.0 series
1063  setItemRotation( r, true );
1064 }
1065 
1066 void QgsComposerItem::setItemRotation( const double r, const bool adjustPosition )
1067 {
1068  if ( r >= 360 )
1069  {
1070  mItemRotation = (( int )r ) % 360;
1071  }
1072  else
1073  {
1074  mItemRotation = r;
1075  }
1076 
1078  refreshRotation( true, adjustPosition, *context.data() );
1079 }
1080 
1081 void QgsComposerItem::refreshRotation( const bool updateItem, const bool adjustPosition, const QgsExpressionContext& context )
1082 {
1083  double rotation = mItemRotation;
1084 
1085  //data defined rotation set?
1086  QVariant exprVal;
1087  if ( dataDefinedEvaluate( QgsComposerObject::ItemRotation, exprVal, context ) )
1088  {
1089  bool ok;
1090  double rotD = exprVal.toDouble( &ok );
1091  QgsDebugMsg( QString( "exprVal Rotation:%1" ).arg( rotD ) );
1092  if ( ok && !exprVal.isNull() )
1093  {
1094  rotation = rotD;
1095  }
1096  }
1097 
1098  if ( rotation == mEvaluatedItemRotation )
1099  {
1100  return;
1101  }
1102 
1103  if ( adjustPosition )
1104  {
1105  //adjustPosition set, so shift the position of the item so that rotation occurs around item center
1106  //create a line from the centrepoint of the rect() to its origin, in scene coordinates
1107  QLineF refLine = QLineF( mapToScene( QPointF( rect().width() / 2.0, rect().height() / 2.0 ) ), mapToScene( QPointF( 0, 0 ) ) );
1108  //rotate this line by the current rotation angle
1109  refLine.setAngle( refLine.angle() - rotation + mEvaluatedItemRotation );
1110  //get new end point of line - this is the new item position
1111  QPointF rotatedReferencePoint = refLine.p2();
1112  setPos( rotatedReferencePoint );
1113  emit sizeChanged();
1114  }
1115 
1116  setTransformOriginPoint( 0, 0 );
1117  QGraphicsItem::setRotation( rotation );
1118 
1120 
1121  emit itemRotationChanged( rotation );
1122 
1123  //update bounds of scene, since rotation may affect this
1125 
1126  if ( updateItem )
1127  {
1128  update();
1129  }
1130 }
1131 
1132 bool QgsComposerItem::imageSizeConsideringRotation( double& width, double& height ) const
1133 {
1134  //kept for api compatibility with QGIS 2.0, use item rotation
1136  return imageSizeConsideringRotation( width, height, mEvaluatedItemRotation );
1138 }
1139 
1140 bool QgsComposerItem::imageSizeConsideringRotation( double& width, double& height, double rotation ) const
1141 {
1142  if ( qAbs( rotation ) <= 0.0 ) //width and height stays the same if there is no rotation
1143  {
1144  return true;
1145  }
1146 
1147  if ( qgsDoubleNear( qAbs( rotation ), 90 ) || qgsDoubleNear( qAbs( rotation ), 270 ) )
1148  {
1149  double tmp = width;
1150  width = height;
1151  height = tmp;
1152  return true;
1153  }
1154 
1155  double x1 = 0;
1156  double y1 = 0;
1157  double x2 = width;
1158  double y2 = 0;
1159  double x3 = width;
1160  double y3 = height;
1161  double x4 = 0;
1162  double y4 = height;
1163  double midX = width / 2.0;
1164  double midY = height / 2.0;
1165 
1167  if ( !cornerPointOnRotatedAndScaledRect( x1, y1, width, height, rotation ) )
1168  {
1169  return false;
1170  }
1171  if ( !cornerPointOnRotatedAndScaledRect( x2, y2, width, height, rotation ) )
1172  {
1173  return false;
1174  }
1175  if ( !cornerPointOnRotatedAndScaledRect( x3, y3, width, height, rotation ) )
1176  {
1177  return false;
1178  }
1179  if ( !cornerPointOnRotatedAndScaledRect( x4, y4, width, height, rotation ) )
1180  {
1181  return false;
1182  }
1184 
1185 
1186  //assume points 1 and 3 are on the rectangle boundaries. Calculate 2 and 4.
1187  double distM1 = sqrt(( x1 - midX ) * ( x1 - midX ) + ( y1 - midY ) * ( y1 - midY ) );
1188  QPointF p2 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( QPointF( midX, midY ), QPointF( x2, y2 ), distM1 );
1189 
1190  if ( p2.x() < width && p2.x() > 0 && p2.y() < height && p2.y() > 0 )
1191  {
1192  width = sqrt(( p2.x() - x1 ) * ( p2.x() - x1 ) + ( p2.y() - y1 ) * ( p2.y() - y1 ) );
1193  height = sqrt(( x3 - p2.x() ) * ( x3 - p2.x() ) + ( y3 - p2.y() ) * ( y3 - p2.y() ) );
1194  return true;
1195  }
1196 
1197  //else assume that points 2 and 4 are on the rectangle boundaries. Calculate 1 and 3
1198  double distM2 = sqrt(( x2 - midX ) * ( x2 - midX ) + ( y2 - midY ) * ( y2 - midY ) );
1199  QPointF p1 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( QPointF( midX, midY ), QPointF( x1, y1 ), distM2 );
1200  QPointF p3 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( QPointF( midX, midY ), QPointF( x3, y3 ), distM2 );
1201  width = sqrt(( x2 - p1.x() ) * ( x2 - p1.x() ) + ( y2 - p1.y() ) * ( y2 - p1.y() ) );
1202  height = sqrt(( p3.x() - x2 ) * ( p3.x() - x2 ) + ( p3.y() - y2 ) * ( p3.y() - y2 ) );
1203  return true;
1204 }
1205 
1206 QRectF QgsComposerItem::largestRotatedRectWithinBounds( const QRectF& originalRect, const QRectF& boundsRect, double rotation ) const
1207 {
1208  return QgsComposerUtils::largestRotatedRectWithinBounds( originalRect, boundsRect, rotation );
1209 }
1210 
1211 bool QgsComposerItem::cornerPointOnRotatedAndScaledRect( double& x, double& y, double width, double height ) const
1212 {
1213  //kept for api compatibility with QGIS 2.0, use item rotation
1215  return cornerPointOnRotatedAndScaledRect( x, y, width, height, mEvaluatedItemRotation );
1217 }
1218 
1219 bool QgsComposerItem::cornerPointOnRotatedAndScaledRect( double& x, double& y, double width, double height, double rotation ) const
1220 {
1221  //first rotate point clockwise
1222  double rotToRad = rotation * M_PI / 180.0;
1223  QPointF midpoint( width / 2.0, height / 2.0 );
1224  double xVector = x - midpoint.x();
1225  double yVector = y - midpoint.y();
1226  //double xRotated = cos(rotToRad) * xVector + sin(rotToRad) * yVector;
1227  //double yRotated = -sin(rotToRad) * xVector + cos(rotToRad) * yVector;
1228  double xRotated = cos( rotToRad ) * xVector - sin( rotToRad ) * yVector;
1229  double yRotated = sin( rotToRad ) * xVector + cos( rotToRad ) * yVector;
1230 
1231  //create line from midpoint to rotated point
1232  QLineF line( midpoint.x(), midpoint.y(), midpoint.x() + xRotated, midpoint.y() + yRotated );
1233 
1234  //intersect with all four borders and return result
1235  QList<QLineF> borders;
1236  borders << QLineF( 0, 0, width, 0 );
1237  borders << QLineF( width, 0, width, height );
1238  borders << QLineF( width, height, 0, height );
1239  borders << QLineF( 0, height, 0, 0 );
1240 
1241  QList<QLineF>::const_iterator it = borders.constBegin();
1242  QPointF intersectionPoint;
1243 
1244  for ( ; it != borders.constEnd(); ++it )
1245  {
1246  if ( line.intersect( *it, &intersectionPoint ) == QLineF::BoundedIntersection )
1247  {
1248  x = intersectionPoint.x();
1249  y = intersectionPoint.y();
1250  return true;
1251  }
1252  }
1253  return false;
1254 }
1255 
1256 void QgsComposerItem::sizeChangedByRotation( double& width, double& height )
1257 {
1258  //kept for api compatibility with QGIS 2.0, use item rotation
1260  return sizeChangedByRotation( width, height, mEvaluatedItemRotation );
1262 }
1263 
1264 void QgsComposerItem::sizeChangedByRotation( double& width, double& height, double rotation )
1265 {
1266  if ( rotation == 0.0 )
1267  {
1268  return;
1269  }
1270 
1271  //vector to p1
1272  double x1 = -width / 2.0;
1273  double y1 = -height / 2.0;
1274  QgsComposerUtils::rotate( rotation, x1, y1 );
1275  //vector to p2
1276  double x2 = width / 2.0;
1277  double y2 = -height / 2.0;
1278  QgsComposerUtils::rotate( rotation, x2, y2 );
1279  //vector to p3
1280  double x3 = width / 2.0;
1281  double y3 = height / 2.0;
1282  QgsComposerUtils::rotate( rotation, x3, y3 );
1283  //vector to p4
1284  double x4 = -width / 2.0;
1285  double y4 = height / 2.0;
1286  QgsComposerUtils::rotate( rotation, x4, y4 );
1287 
1288  //double midpoint
1289  QPointF midpoint( width / 2.0, height / 2.0 );
1290 
1291  QPolygonF rotatedRectPoly;
1292  rotatedRectPoly << QPointF( midpoint.x() + x1, midpoint.y() + y1 );
1293  rotatedRectPoly << QPointF( midpoint.x() + x2, midpoint.y() + y2 );
1294  rotatedRectPoly << QPointF( midpoint.x() + x3, midpoint.y() + y3 );
1295  rotatedRectPoly << QPointF( midpoint.x() + x4, midpoint.y() + y4 );
1296  QRectF boundingRect = rotatedRectPoly.boundingRect();
1297  width = boundingRect.width();
1298  height = boundingRect.height();
1299 }
1300 
1301 void QgsComposerItem::rotate( double angle, double& x, double& y ) const
1302 {
1303  QgsComposerUtils::rotate( angle, x, y );
1304 }
1305 
1307 {
1308  if ( !mHAlignSnapItem )
1309  {
1311  mHAlignSnapItem->setPen( QPen( QColor( Qt::red ) ) );
1313  mHAlignSnapItem->setZValue( 90 );
1314  }
1315  return mHAlignSnapItem;
1316 }
1317 
1319 {
1320  if ( !mVAlignSnapItem )
1321  {
1323  mVAlignSnapItem->setPen( QPen( QColor( Qt::red ) ) );
1325  mVAlignSnapItem->setZValue( 90 );
1326  }
1327  return mVAlignSnapItem;
1328 }
1329 
1331 {
1332  if ( mHAlignSnapItem )
1333  {
1335  delete mHAlignSnapItem;
1336  mHAlignSnapItem = 0;
1337  }
1338 }
1339 
1341 {
1342  if ( mVAlignSnapItem )
1343  {
1345  delete mVAlignSnapItem;
1346  mVAlignSnapItem = 0;
1347  }
1348 }
1349 
1351 {
1354 }
1355 
1357 {
1358  updateItem();
1359 }
1360 
1362 {
1363  //maintain 2.10 API
1364  //TODO QGIS 3.0 - remove this
1365  const QgsExpressionContext* evalContext = context;
1367  if ( !evalContext )
1368  {
1369  scopedContext.reset( createExpressionContext() );
1370  evalContext = scopedContext.data();
1371  }
1372 
1373  //update data defined properties and redraw item to match
1374  if ( property == QgsComposerObject::PositionX || property == QgsComposerObject::PositionY ||
1375  property == QgsComposerObject::ItemWidth || property == QgsComposerObject::ItemHeight ||
1376  property == QgsComposerObject::AllProperties )
1377  {
1378  QRectF beforeRect = QRectF( pos().x(), pos().y(), rect().width(), rect().height() );
1379  QRectF evaluatedRect = evalItemRect( beforeRect, false, evalContext );
1380  if ( evaluatedRect != beforeRect )
1381  {
1382  setSceneRect( evaluatedRect );
1383  }
1384  }
1385  if ( property == QgsComposerObject::ItemRotation || property == QgsComposerObject::AllProperties )
1386  {
1387  refreshRotation( false, true, *evalContext );
1388  }
1389  if ( property == QgsComposerObject::Transparency || property == QgsComposerObject::AllProperties )
1390  {
1391  refreshTransparency( false, *evalContext );
1392  }
1393  if ( property == QgsComposerObject::BlendMode || property == QgsComposerObject::AllProperties )
1394  {
1395  refreshBlendMode( *evalContext );
1396  }
1398  {
1399  bool exclude = mExcludeFromExports;
1400  //data defined exclude from exports set?
1401  QVariant exprVal;
1402  if ( dataDefinedEvaluate( QgsComposerObject::ExcludeFromExports, exprVal, *evalContext ) && !exprVal.isNull() )
1403  {
1404  exclude = exprVal.toBool();
1405  }
1406  mEvaluatedExcludeFromExports = exclude;
1407  }
1408 
1409  update();
1410 }
1411 
1413 {
1414  if ( id == mId )
1415  {
1416  return;
1417  }
1418 
1419  setToolTip( id );
1420  mId = id;
1421 
1422  //inform model that id data has changed
1423  if ( mComposition )
1424  {
1426  }
1427 
1428  emit itemChanged();
1429 }
1430 
1431 void QgsComposerItem::setIsGroupMember( const bool isGroupMember )
1432 {
1434  setFlag( QGraphicsItem::ItemIsSelectable, !isGroupMember ); //item in groups cannot be selected
1435 }
1436 
1438 {
1439  //return id, if it's not empty
1440  if ( ! id().isEmpty() )
1441  {
1442  return id();
1443  }
1444 
1445  //for unnamed items, default to item type
1446  //(note some item types override this method to provide their own defaults)
1447  switch ( type() )
1448  {
1449  case ComposerArrow:
1450  return tr( "<arrow>" );
1451  case ComposerItemGroup:
1452  return tr( "<group>" );
1453  case ComposerLabel:
1454  return tr( "<label>" );
1455  case ComposerLegend:
1456  return tr( "<legend>" );
1457  case ComposerMap:
1458  return tr( "<map>" );
1459  case ComposerPicture:
1460  return tr( "<picture>" );
1461  case ComposerScaleBar:
1462  return tr( "<scale bar>" );
1463  case ComposerShape:
1464  return tr( "<shape>" );
1465  case ComposerTable:
1466  return tr( "<table>" );
1468  return tr( "<attribute table>" );
1469  case ComposerTextTable:
1470  return tr( "<text table>" );
1471  case ComposerFrame:
1472  return tr( "<frame>" );
1473  }
1474 
1475  return tr( "<item>" );
1476 }
1477 
1478 void QgsComposerItem::setVisibility( const bool visible )
1479 {
1480  if ( visible == isVisible() )
1481  {
1482  //nothing to do
1483  return;
1484  }
1485 
1486  QGraphicsItem::setVisible( visible );
1487 
1488  //inform model that id data has changed
1489  if ( mComposition )
1490  {
1492  }
1493 }
1494 
1496 {
1498 }
1499 
1500 void QgsComposerItem::setExcludeFromExports( const bool exclude )
1501 {
1502  mExcludeFromExports = exclude;
1504 }
bool positionLock() const
Returns whether position lock for mouse drags is enabled returns true if item is locked for mouse mov...
bool mExcludeFromExports
Whether item should be excluded in exports.
QDomNodeList elementsByTagName(const QString &tagname) const
void setSelected(bool selected)
bool effectsEnabled() const
Returns whether effects (eg blend modes) are enabled for the item.
qreal x() const
qreal y() const
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...
virtual bool writeXML(QDomElement &elem, QDomDocument &doc) const
Stores item state in DOM element.
void setStyle(Qt::PenStyle style)
virtual void refreshDataDefinedProperty(const QgsComposerObject::DataDefinedProperty property=QgsComposerObject::AllProperties, const QgsExpressionContext *context=0) override
Refreshes a data defined property for the item by reevaluating the property's value and redrawing the...
int mTransparency
Item transparency.
A base class for objects which belong to a map composition.
Q_DECL_DEPRECATED double fontHeightCharacterMM(const QFont &font, const QChar &c) const
Returns the font height of a character in millimeters.
void itemRotationChanged(double newRotation)
Is emitted on item rotation change.
Q_DECL_DEPRECATED double pixelFontSize(double pointSize) const
Calculates font size in mm from a font point size.
void setCompositionMode(CompositionMode mode)
void setRenderHint(RenderHint hint, bool on)
void setGraphicsEffect(QGraphicsEffect *effect)
QDomNode appendChild(const QDomNode &newChild)
void addItemToZList(QgsComposerItem *item)
Adds item to z list.
virtual void setRotation(double r)
Sets the item rotation.
void setFlag(GraphicsItemFlag flag, bool enabled)
virtual double estimatedFrameBleed() const
Returns the estimated amount the item's frame bleeds outside the item's actual rectangle.
qreal x() const
qreal y() const
QString attribute(const QString &name, const QString &defValue) const
QgsComposerModel * itemsModel()
Returns the items model attached to the composition.
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
void itemChanged()
Emitted when the item changes.
Q_DECL_DEPRECATED double lockSymbolSize() const
Returns the size of the lock symbol depending on the composer zoom level and the item size...
QPointF pagePos() const
Returns the item's position relative to its current page.
const T & at(int i) const
QMap< QgsComposerObject::DataDefinedProperty, QString > mDataDefinedNames
Map of data defined properties for the item to string name to use when exporting item to xml...
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:390
void removeItemFromZList(QgsComposerItem *item)
Removes item from z list.
bool isVisible() const
void save()
static void drawText(QPainter *painter, const QPointF &pos, const QString &text, const QFont &font, const QColor &color=QColor())
Draws text on a painter at a specific position, taking care of composer specific issues (calculation ...
double mLastValidViewScaleFactor
Backup to restore item appearance if no view scale factor is available.
ItemPositionMode mLastUsedPositionMode
The item's position mode.
void drawPolygon(const QPointF *points, int pointCount, Qt::FillRule fillRule)
void updateBounds()
Updates the scene bounds of the composition.
void setJoinStyle(Qt::PenJoinStyle style)
void updateItemVisibility(QgsComposerItem *item)
Must be called when an item's visibility changes.
qreal top() const
virtual void setSelected(bool s)
Set selected, selected item should be highlighted.
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
static double fontAscentMM(const QFont &font)
Calculate font ascent in millimeters, including workarounds for QT font rendering issues...
virtual void drawFrame(QPainter *p)
Draw black frame around item.
virtual void setFrameEnabled(const bool drawFrame)
Set whether this item has a frame drawn around it or not.
static QFont scaledFontPixelSize(const QFont &font)
Returns a font where size is set in pixels and the size has been upscaled with FONT_WORKAROUND_SCALE ...
DataDefinedProperty
Data defined properties for different item types.
QColor backgroundColor() const
Gets the background color for this item.
QPainter::CompositionMode mBlendMode
Composition blend mode for item.
void setCompositionMode(const QPainter::CompositionMode &compositionMode)
QGraphicsScene * scene() const
bool excludeFromExports(const QgsComposerObject::PropertyValueType valueType=QgsComposerObject::EvaluatedValue)
Returns whether the item should be excluded from composer exports and prints.
double toDouble(bool *ok) const
double spaceBetweenPages() const
Returns the vertical space between pages in a composer view.
virtual QgsExpressionContext * createExpressionContext() const override
Creates an expression context relating to the objects's current state.
static double fontDescentMM(const QFont &font)
Calculate font descent in millimeters, including workarounds for QT font rendering issues...
double itemRotation(const QgsComposerObject::PropertyValueType valueType=QgsComposerObject::EvaluatedValue) const
Returns the current rotation for the composer item.
QString tr(const char *sourceText, const char *disambiguation, int n)
void setEnabled(bool enable)
void setBlendMode(const QPainter::CompositionMode blendMode)
Sets the item's composition blending mode.
qreal left() const
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Definition: qgis.h:268
void update(const QRectF &rect)
void updateItemDisplayName(QgsComposerItem *item)
Must be called when an item's display name is modified.
int size() const
void setRect(const QRectF &rectangle)
void setHeight(qreal height)
void reset(T *other)
void setItemPosition(double x, double y, ItemPositionMode itemPoint=UpperLeft, int page=-1)
Moves the item to a new position (in canvas coordinates)
bool _readXML(const QDomElement &itemElem, const QDomDocument &doc)
Reads parameter that are not subclass specific in document.
Q_DECL_DEPRECATED double fontDescentMillimeters(const QFont &font) const
Returns the font descent in Millimeters (considers upscaling and downscaling with FONT_WORKAROUND_SCA...
const QColor & color() const
QDomElement toElement() const
void updateItemLockStatus(QgsComposerItem *item)
Must be called when an item's lock status changes.
void drawRect(const QRectF &rectangle)
virtual QRectF boundingRect() const
QColor color() const
static void drawArrowHead(QPainter *p, const double x, const double y, const double angle, const double arrowHeadWidth)
Draws an arrow head on to a QPainter.
QTransform transform() const
virtual QgsExpressionContext * createExpressionContext() const
Creates an expression context relating to the objects's current state.
qreal zValue() const
qreal y2() const
void frameChanged()
Emitted if the item's frame style changes.
QPointF pos() const
static QPainter::CompositionMode decodeBlendMode(const QString &s)
qreal x2() const
QString number(int n, int base)
qreal x() const
qreal y() const
double horizontalViewScaleFactor() const
Returns the zoom factor of the graphics view.
QPointF p2() const
void setFrameJoinStyle(const Qt::PenJoinStyle style)
Sets join style used when drawing the item's frame.
int toInt(bool *ok) const
bool isNull() const
void removeItem(QGraphicsItem *item)
void cancelCommand()
Deletes current command.
Q_DECL_DEPRECATED QFont scaledFontPixelSize(const QFont &font) const
Returns a font where size is in pixel and font size is upscaled with FONT_WORKAROUND_SCALE.
int transparency() const
Returns the item's transparency.
virtual void updateItem()
Updates item, with the possibility to do custom update for subclasses.
static double fontHeightCharacterMM(const QFont &font, const QChar &character)
Calculate font height in millimeters of a single character, including workarounds for QT font renderi...
virtual void drawSelectionBoxes(QPainter *p)
Draws additional graphics on selected items.
Q_DECL_DEPRECATED double textWidthMillimeters(const QFont &font, const QString &text) const
Returns the font width in millimeters (considers upscaling and downscaling with FONT_WORKAROUND_SCALE...
Q_DECL_DEPRECATED void rotate(double angle, double &x, double &y) const
Rotates a point / vector.
void endCommand()
Saves end state of item and pushes command to the undo history.
int red() const
QGraphicsRectItem * mBoundingResizeRectangle
Rectangle used during move and resize actions.
void setPen(const QColor &color)
void updatePagePos(double newPageWidth, double newPageHeight)
Moves the item so that it retains its relative position on the page when the paper size changes...
bool mFrame
True if item fram needs to be painted.
void setAttribute(const QString &name, const QString &value)
bool isSelected() const
void setPos(const QPointF &pos)
const QgsComposition * composition() const
Returns the composition the item is attached to.
QList< QGraphicsView * > views() const
qreal m11() const
int toInt(bool *ok, int base) const
void setAngle(qreal angle)
void endCommand()
Finish current command and push it onto the undo stack.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void setToolTip(const QString &toolTip)
virtual void setFrameOutlineColor(const QColor &color)
Sets frame outline color.
QRectF evalItemRect(const QRectF &newRect, const bool resizeOnly=false, const QgsExpressionContext *context=0)
Evaluates an item's bounding rect to consider data defined position and size of item and reference po...
QString trimmed() const
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
#define M_PI
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 setWidthF(qreal width)
void moveLeft(qreal x)
void setBrush(const QBrush &brush)
double mEvaluatedItemRotation
Temporary evaluated item rotation in degrees, clockwise.
void repaint() override
PropertyValueType
Specifies whether the value returned by a function should be the original, user set value...
virtual ~QgsComposerItem()
void beginCommand(const QString &commandText, QgsComposerMergeCommand::Context c=QgsComposerMergeCommand::Unknown)
Starts new composer undo command.
bool shouldDrawItem() const
Returns whether the item should be drawn in the current context.
void setOpacity(qreal opacity)
void setColor(const QColor &color)
static QgsExpressionContextScope * composerItemScope(const QgsComposerItem *composerItem)
Creates a new scope which contains variables and functions relating to a QgsComposerItem.
int alpha() const
Graphics scene for map printing.
Q_DECL_DEPRECATED QRectF largestRotatedRectWithinBounds(const QRectF &originalRect, const QRectF &boundsRect, double rotation) const
Calculates the largest scaled version of originalRect which fits within boundsRect, when it is rotated by a specified amount.
void setPen(const QPen &pen)
BlendMode
Blending modes enum defining the available composition modes that can be used when rendering a layer...
T * data() const
int green() const
static void rotate(const double angle, double &x, double &y)
Rotates a point / vector around the origin.
double ANALYSIS_EXPORT angle(Point3D *p1, Point3D *p2, Point3D *p3, Point3D *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
virtual void setExcludeFromExports(const bool exclude)
Sets whether the item should be excluded from composer exports and prints.
bool dataDefinedEvaluate(const QgsComposerObject::DataDefinedProperty property, QVariant &expressionValue, const QgsExpressionContext &context=QgsExpressionContext()) const
Evaluate a data defined property and return the calculated value.
virtual QString displayName() const
Get item display name.
virtual QRectF rectWithFrame() const
Returns the item's rectangular bounds, including any bleed caused by the item's frame.
bool isNull() const
QGraphicsLineItem * hAlignSnapItem()
Return horizontal align snap item.
static QPainter::CompositionMode getCompositionMode(const QgsMapRenderer::BlendMode &blendMode)
Returns a QPainter::CompositionMode corresponding to a BlendMode.
void setPositionLock(const bool lock)
Locks / unlocks the item position for mouse drags.
virtual void setFrameOutlineWidth(const double outlineWidth)
Sets frame outline width.
Q_DECL_DEPRECATED double rotation() const
Returns the rotation for the composer item.
void restore()
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:391
void setTransformOriginPoint(const QPointF &origin)
static double textWidthMM(const QFont &font, const QString &text)
Calculate font width in millimeters for a string, including workarounds for QT font rendering issues...
QgsComposition * mComposition
Qt::PenJoinStyle mFrameJoinStyle
Frame join style.
QColor mBackgroundColor
Background color.
QGraphicsLineItem * mVAlignSnapItem
int blue() const
static double fontHeightMM(const QFont &font)
Calculate font height in millimeters, including workarounds for QT font rendering issues The font hei...
bool isVisible() const
Q_DECL_DEPRECATED bool cornerPointOnRotatedAndScaledRect(double &x, double &y, double width, double height, double rotation) const
Calculates corner point after rotation and scaling.
QGraphicsLineItem * mHAlignSnapItem
QRectF boundingRect() const
QPointF mapToScene(const QPointF &point) const
qreal width() const
void setBackgroundColor(const QColor &backgroundColor)
Sets the background color for this item.
bool _writeXML(QDomElement &itemElem, QDomDocument &doc) const
Writes parameter that are not subclass specific in document.
void setWidth(int width)
void setPen(const QPen &pen)
bool mItemPositionLocked
True if item position and size cannot be changed with mouse move.
QPainter::CompositionMode blendMode() const
Returns the item's composition blending mode.
virtual bool readXML(const QDomElement &itemElem, const QDomDocument &doc)
Sets item state from DOM element.
virtual void setItemRotation(const double r, const bool adjustPosition=false)
Sets the item rotation.
void setWidth(qreal width)
virtual void drawBackground(QPainter *p)
Draw background.
bool hasFrame() const
Whether this item has a frame or not.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
virtual void setId(const QString &id)
Set item's id (which is not necessarly unique)
Q_DECL_DEPRECATED double fontHeightMillimeters(const QFont &font) const
Returns the font height in Millimeters (considers upscaling and downscaling with FONT_WORKAROUND_SCAL...
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...
Q_DECL_DEPRECATED double angle(const QPointF &p1, const QPointF &p2) const
Returns angle of the line from p1 to p2 (clockwise, starting at N)
void sizeChanged()
Emitted if the rectangle changes.
qreal & ry()
double paperHeight() const
Height of paper item.
void setIsGroupMember(const bool isGroupMember)
Sets whether this item is part of a group.
qreal widthF() const
bool toBool() const
static double pointsToMM(const double pointSize)
Returns the size in mm corresponding to a font point size.
int page() const
Gets the page the item is currently on.
qreal angle() const
void setVisible(bool visible)
void setEffectsEnabled(const bool effectsEnabled)
Sets whether effects (eg blend modes) are enabled for the item.
void updateItemSelectStatus(QgsComposerItem *item)
Must be called when an item's selection status changes.
QRectF adjusted(qreal dx1, qreal dy1, qreal dx2, qreal dy2) const
void setRotation(qreal angle)
qreal height() const
double toDouble(bool *ok) const
iterator insert(const Key &key, const T &value)
static QgsMapRenderer::BlendMode getBlendModeEnum(const QPainter::CompositionMode &blendMode)
Returns a BlendMode corresponding to a QPainter::CompositionMode.
void setBrush(const QBrush &brush)
QgsComposerEffect * mEffect
Q_DECL_DEPRECATED void drawArrowHead(QPainter *p, double x, double y, double angle, double arrowHeadWidth) const
Draws arrowhead.
int size() const
QgsComposerItem(QgsComposition *composition, bool manageZValue=true)
Constructor.
static double angle(const QPointF &p1, const QPointF &p2)
Calculates the angle of the line from p1 to p2 (counter clockwise, starting from a line from north to...
QDomElement createElement(const QString &tagName)
void lockChanged()
Emitted if the item's lock status changes.
void addItem(QGraphicsItem *item)
void moveTop(qreal y)
QgsComposition::PlotStyle plotStyle() const
double rectHandlerBorderTolerance() const
Returns the current (zoom level dependent) tolerance to decide if mouse position is close enough to t...
static QPointF pointOnLineWithDistance(const QPointF &startPoint, const QPointF &directionPoint, double distance)
Returns a point on the line from startPoint to directionPoint that is a certain distance away from th...
int compare(const QString &other) const
bool mBackground
True if item background needs to be painted.
void move(double dx, double dy)
Moves item in canvas coordinates.
bool isGroupMember() const
Returns whether this item is part of a group.
QString toString() const
void setZValue(qreal z)
virtual void setVisibility(const bool visible)
Sets visibility for item.
bool mIsGroupMember
Whether or not this item is part of a group.
Q_DECL_DEPRECATED void drawText(QPainter *p, double x, double y, const QString &text, const QFont &font, const QColor &c=QColor()) const
Draws Text.
double mItemRotation
Item rotation in degrees, clockwise.
QUuid createUuid()
QGraphicsLineItem * vAlignSnapItem()
Return vertical align snap item.
Q_DECL_DEPRECATED double fontAscentMillimeters(const QFont &font) const
Returns the font ascent in Millimeters (considers upscaling and downscaling with FONT_WORKAROUND_SCAL...
bool mEvaluatedExcludeFromExports
Temporary evaluated item exclusion.
void setTransparency(const int transparency)
Sets the item's transparency.
Q_DECL_DEPRECATED void sizeChangedByRotation(double &width, double &height, double rotation)
Calculates width / height of the bounding box of a rotated rectangle.
virtual int type() const override
Return correct graphics item type.
QDomNode at(int index) const
QRectF rect() const
uint toUInt(bool *ok, int base) const
void beginCommand(QgsComposerItem *item, const QString &commandText, const QgsComposerMergeCommand::Context c=QgsComposerMergeCommand::Unknown)
Allocates new item command and saves initial state in it.
QString id() const
Get item's id (which is not necessarly unique)