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