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