QGIS API Documentation  2.17.0-Master (f49f7ce)
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  p->drawPolygon( rect() );
528  p->restore();
529  }
530 
531 }
532 
534 {
535  if ( mFrame && p )
536  {
537  p->save();
538  p->setPen( pen() );
539  p->setBrush( Qt::NoBrush );
540  p->setRenderHint( QPainter::Antialiasing, true );
541  p->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
542  p->restore();
543  }
544 }
545 
546 void QgsComposerItem::setPositionLock( const bool lock )
547 {
548  if ( lock == mItemPositionLocked )
549  {
550  return;
551  }
552 
553  mItemPositionLocked = lock;
554 
555  //inform model that id data has changed
556  if ( mComposition )
557  {
559  }
560  update();
561  emit lockChanged();
562 }
563 
564 double QgsComposerItem::itemRotation( const PropertyValueType valueType ) const
565 {
567 }
568 
569 void QgsComposerItem::move( double dx, double dy )
570 {
571  QRectF newSceneRect( pos().x() + dx, pos().y() + dy, rect().width(), rect().height() );
572  setSceneRect( evalItemRect( newSceneRect ) );
573 }
574 
576 {
577  double y = pos().y();
578  double h = composition()->paperHeight() + composition()->spaceBetweenPages();
579  int page = 1;
580  while ( y - h >= 0. )
581  {
582  y -= h;
583  ++page;
584  }
585  return page;
586 }
587 
589 {
590  QPointF p = pos();
591  double h = composition()->paperHeight() + composition()->spaceBetweenPages();
592  p.ry() -= ( page() - 1 ) * h;
593  return p;
594 }
595 
596 void QgsComposerItem::updatePagePos( double newPageWidth, double newPageHeight )
597 {
598  Q_UNUSED( newPageWidth )
599  QPointF curPagePos = pagePos();
600  int curPage = page() - 1;
601 
602  double y = curPage * ( newPageHeight + composition()->spaceBetweenPages() ) + curPagePos.y();
603  QRectF newSceneRect( pos().x(), y, rect().width(), rect().height() );
604 
605  setSceneRect( evalItemRect( newSceneRect ) );
606  emit sizeChanged();
607 }
608 
609 void QgsComposerItem::setItemPosition( double x, double y, ItemPositionMode itemPoint, int page )
610 {
611  double width = rect().width();
612  double height = rect().height();
613  setItemPosition( x, y, width, height, itemPoint, false, page );
614 }
615 
616 void QgsComposerItem::setItemPosition( double x, double y, double width, double height, ItemPositionMode itemPoint, bool posIncludesFrame, int page )
617 {
618  double upperLeftX = x;
619  double upperLeftY = y;
620 
621  if ( page > 0 )
622  {
623  double h = composition()->paperHeight() + composition()->spaceBetweenPages();
624  upperLeftY += ( page - 1 ) * h;
625  }
626 
627  //store the item position mode
628  mLastUsedPositionMode = itemPoint;
629 
630  //adjust x-coordinate if placement is not done to a left point
631  if ( itemPoint == UpperMiddle || itemPoint == Middle || itemPoint == LowerMiddle )
632  {
633  upperLeftX -= width / 2.0;
634  }
635  else if ( itemPoint == UpperRight || itemPoint == MiddleRight || itemPoint == LowerRight )
636  {
637  upperLeftX -= width;
638  }
639 
640  //adjust y-coordinate if placement is not done to an upper point
641  if ( itemPoint == MiddleLeft || itemPoint == Middle || itemPoint == MiddleRight )
642  {
643  upperLeftY -= height / 2.0;
644  }
645  else if ( itemPoint == LowerLeft || itemPoint == LowerMiddle || itemPoint == LowerRight )
646  {
647  upperLeftY -= height;
648  }
649 
650  if ( posIncludesFrame )
651  {
652  //adjust position to account for frame size
653 
655  {
656  upperLeftX += estimatedFrameBleed();
657  upperLeftY += estimatedFrameBleed();
658  }
659  else
660  {
661  //adjust position for item rotation
662  QLineF lineToItemOrigin = QLineF( 0, 0, estimatedFrameBleed(), estimatedFrameBleed() );
663  lineToItemOrigin.setAngle( -45 - mEvaluatedItemRotation );
664  upperLeftX += lineToItemOrigin.x2();
665  upperLeftY += lineToItemOrigin.y2();
666  }
667 
668  width -= 2 * estimatedFrameBleed();
669  height -= 2 * estimatedFrameBleed();
670  }
671 
672  //consider data defined item size and position before finalising rect
673  QRectF newRect = evalItemRect( QRectF( upperLeftX, upperLeftY, width, height ) );
674 
675  setSceneRect( newRect );
676 }
677 
678 void QgsComposerItem::setSceneRect( const QRectF& rectangle )
679 {
680  //setRect in item coordinates
681  double newWidth = rectangle.width();
682  double newHeight = rectangle.height();
683  double xTranslation = rectangle.x();
684  double yTranslation = rectangle.y();
685 
686  //correction if width and/or height are negative
687  if ( rectangle.width() < 0 )
688  {
689  newWidth = - rectangle.width();
690  xTranslation -= newWidth;
691  }
692 
693  if ( rectangle.height() < 0 )
694  {
695  newHeight = - rectangle.height();
696  yTranslation -= newHeight;
697  }
698 
699  QGraphicsRectItem::setRect( QRectF( 0, 0, newWidth, newHeight ) );
700  setPos( QPointF( xTranslation, yTranslation ) );
701 
702  emit sizeChanged();
703 }
704 
705 QRectF QgsComposerItem::evalItemRect( const QRectF &newRect, const bool resizeOnly, const QgsExpressionContext* context )
706 {
707  QRectF result = newRect;
708 
709  //TODO QGIS 3.0
710  //maintain pre 2.12 API. remove when API break allowed
712  const QgsExpressionContext* evalContext = context;
713  if ( !evalContext )
714  {
715  scopedContext.reset( createExpressionContext() );
716  evalContext = scopedContext.data();
717  }
718 
719  //data defined position or size set? if so, update rect with data defined values
720  QVariant exprVal;
721  //evaulate width and height first, since they may affect position if non-top-left reference point set
722  if ( dataDefinedEvaluate( QgsComposerObject::ItemWidth, exprVal, *evalContext ) )
723  {
724  bool ok;
725  double width = exprVal.toDouble( &ok );
726  QgsDebugMsg( QString( "exprVal Width:%1" ).arg( width ) );
727  if ( ok && !exprVal.isNull() )
728  {
729  result.setWidth( width );
730  }
731  }
732  if ( dataDefinedEvaluate( QgsComposerObject::ItemHeight, exprVal, *evalContext ) )
733  {
734  bool ok;
735  double height = exprVal.toDouble( &ok );
736  QgsDebugMsg( QString( "exprVal Height:%1" ).arg( height ) );
737  if ( ok && !exprVal.isNull() )
738  {
739  result.setHeight( height );
740  }
741  }
742 
743  double x = result.left();
744  //initially adjust for position mode to get x coordinate
745  if ( !resizeOnly )
746  {
747  //adjust x-coordinate if placement is not done to a left point
749  {
750  x += newRect.width() / 2.0;
751  }
753  {
754  x += newRect.width();
755  }
756  }
757  else
758  {
760  {
761  x += rect().width() / 2.0;
762  }
764  {
765  x += rect().width();
766  }
767  }
768  if ( dataDefinedEvaluate( QgsComposerObject::PositionX, exprVal, *evalContext ) )
769  {
770  bool ok;
771  double positionX = exprVal.toDouble( &ok );
772  QgsDebugMsg( QString( "exprVal Position X:%1" ).arg( positionX ) );
773  if ( ok && !exprVal.isNull() )
774  {
775  x = positionX;
776  }
777  }
778 
779  double y = result.top();
780  //initially adjust for position mode to get y coordinate
781  if ( !resizeOnly )
782  {
783  //adjust y-coordinate if placement is not done to an upper point
785  {
786  y += newRect.height() / 2.0;
787  }
789  {
790  y += newRect.height();
791  }
792  }
793  else
794  {
796  {
797  y += rect().height() / 2.0;
798  }
800  {
801  y += rect().height();
802  }
803  }
804  if ( dataDefinedEvaluate( QgsComposerObject::PositionY, exprVal, *evalContext ) )
805  {
806  bool ok;
807  double positionY = exprVal.toDouble( &ok );
808  QgsDebugMsg( QString( "exprVal Position Y:%1" ).arg( positionY ) );
809  if ( ok && !exprVal.isNull() )
810  {
811  y = positionY;
812  }
813  }
814 
815  //adjust x-coordinate if placement is not done to a left point
817  {
818  x -= result.width() / 2.0;
819  }
821  {
822  x -= result.width();
823  }
824 
825  //adjust y-coordinate if placement is not done to an upper point
827  {
828  y -= result.height() / 2.0;
829  }
831  {
832  y -= result.height();
833  }
834 
835  result.moveLeft( x );
836  result.moveTop( y );
837 
838  return result;
839 }
840 
842 {
844  {
845  //preview mode or no composition, so ok to draw item
846  return true;
847  }
848 
849  //exporting composition, so check if item is excluded from exports
851 }
852 
854 {
857  return context;
858 }
859 
861 {
862  if ( mBackground && p )
863  {
864  p->save();
865  p->setBrush( brush() );//this causes a problem in atlas generation
866  p->setPen( Qt::NoPen );
867  p->setRenderHint( QPainter::Antialiasing, true );
868  p->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
869  p->restore();
870  }
871 }
872 
873 void QgsComposerItem::drawArrowHead( QPainter *p, double x, double y, double angle, double arrowHeadWidth ) const
874 {
875  QgsComposerUtils::drawArrowHead( p, x, y, angle, arrowHeadWidth );
876 }
877 
878 double QgsComposerItem::angle( QPointF p1, QPointF p2 ) const
879 {
880  return QgsComposerUtils::angle( p1, p2 );
881 }
882 
884 {
886  setBrush( QBrush( mBackgroundColor, Qt::SolidPattern ) );
887 }
888 
889 void QgsComposerItem::setBlendMode( const QPainter::CompositionMode blendMode )
890 {
892  // Update the composer effect to use the new blend mode
894  refreshBlendMode( *context.data() );
895 }
896 
897 void QgsComposerItem::refreshBlendMode( const QgsExpressionContext& context )
898 {
899  QPainter::CompositionMode blendMode = mBlendMode;
900 
901  //data defined blend mode set?
902  QVariant exprVal;
903  if ( dataDefinedEvaluate( QgsComposerObject::BlendMode, exprVal, context ) && !exprVal.isNull() )
904  {
905  QString blendstr = exprVal.toString().trimmed();
906  QPainter::CompositionMode blendModeD = QgsSymbolLayerV2Utils::decodeBlendMode( blendstr );
907 
908  QgsDebugMsg( QString( "exprVal BlendMode:%1" ).arg( blendModeD ) );
909  blendMode = blendModeD;
910  }
911 
912  // Update the composer effect to use the new blend mode
913  mEffect->setCompositionMode( blendMode );
914 }
915 
917 {
920  refreshTransparency( true, *context.data() );
921 }
922 
923 void QgsComposerItem::refreshTransparency( const bool updateItem, const QgsExpressionContext& context )
924 {
926 
927  //data defined transparency set?
928  QVariant exprVal;
929  if ( dataDefinedEvaluate( QgsComposerObject::Transparency, exprVal, context ) )
930  {
931  bool ok;
932  int transparencyD = exprVal.toInt( &ok );
933  QgsDebugMsg( QString( "exprVal Transparency:%1" ).arg( transparencyD ) );
934  if ( ok && !exprVal.isNull() )
935  {
936  transparency = transparencyD;
937  }
938  }
939 
940  // Set the QGraphicItem's opacity
941  setOpacity( 1. - ( transparency / 100. ) );
942 
943  if ( updateItem )
944  {
945  update();
946  }
947 }
948 
950 {
951  //enable or disable the QgsComposerEffect applied to this item
953  mEffect->setEnabled( effectsEnabled );
954 }
955 
956 void QgsComposerItem::drawText( QPainter* p, double x, double y, const QString& text, const QFont& font, const QColor& c ) const
957 {
958  QgsComposerUtils::drawText( p, QPointF( x, y ), text, font, c );
959 }
960 
961 void QgsComposerItem::drawText( QPainter* p, const QRectF& rect, const QString& text, const QFont& font, Qt::AlignmentFlag halignment, Qt::AlignmentFlag valignment, int flags ) const
962 {
963  QgsComposerUtils::drawText( p, rect, text, font, QColor(), halignment, valignment, flags );
964 }
965 double QgsComposerItem::textWidthMillimeters( const QFont& font, const QString& text ) const
966 {
967  return QgsComposerUtils::textWidthMM( font, text );
968 }
969 
970 double QgsComposerItem::fontHeightCharacterMM( const QFont& font, QChar c ) const
971 {
972  return QgsComposerUtils::fontHeightCharacterMM( font, c );
973 }
974 
976 {
977  return QgsComposerUtils::fontAscentMM( font );
978 }
979 
981 {
982  return QgsComposerUtils::fontDescentMM( font );
983 }
984 
986 {
987  return QgsComposerUtils::fontHeightMM( font );
988 }
989 
990 double QgsComposerItem::pixelFontSize( double pointSize ) const
991 {
992  return QgsComposerUtils::pointsToMM( pointSize );
993 }
994 
996 {
998 }
999 
1001 {
1002  double result = -1;
1003  if ( scene() )
1004  {
1005  QList<QGraphicsView*> viewList = scene()->views();
1006  if ( !viewList.isEmpty() ) //if not, probably this function was called from non-gui code
1007  {
1008  QGraphicsView* currentView = viewList.at( 0 );
1009  if ( currentView->isVisible() )
1010  {
1011  result = currentView->transform().m11();
1012  mLastValidViewScaleFactor = result;
1013  }
1014  }
1015  }
1016  return result;
1017 }
1018 
1020 {
1021  //size of symbol boxes depends on zoom level in composer view
1022  double viewScaleFactor = horizontalViewScaleFactor();
1023  double rectHandlerSize = 10.0 / viewScaleFactor;
1024 
1025  //make sure the boxes don't get too large
1026  if ( rectHandlerSize > ( rect().width() / 3 ) )
1027  {
1028  rectHandlerSize = rect().width() / 3;
1029  }
1030  if ( rectHandlerSize > ( rect().height() / 3 ) )
1031  {
1032  rectHandlerSize = rect().height() / 3;
1033  }
1034  return rectHandlerSize;
1035 }
1036 
1038 {
1039  double lockSymbolSize = 20.0 / horizontalViewScaleFactor();
1040 
1041  if ( lockSymbolSize > ( rect().width() / 3 ) )
1042  {
1043  lockSymbolSize = rect().width() / 3;
1044  }
1045  if ( lockSymbolSize > ( rect().height() / 3 ) )
1046  {
1047  lockSymbolSize = rect().height() / 3;
1048  }
1049  return lockSymbolSize;
1050 }
1051 
1052 void QgsComposerItem::setRotation( const double r )
1053 {
1054  //kept for api compatibility with QGIS 2.0
1055  //remove after 2.0 series
1056  setItemRotation( r, true );
1057 }
1058 
1059 void QgsComposerItem::setItemRotation( const double r, const bool adjustPosition )
1060 {
1061  if ( r >= 360 )
1062  {
1063  mItemRotation = ( static_cast< int >( r ) ) % 360;
1064  }
1065  else
1066  {
1067  mItemRotation = r;
1068  }
1069 
1071  refreshRotation( true, adjustPosition, *context.data() );
1072 }
1073 
1074 void QgsComposerItem::refreshRotation( const bool updateItem, const bool adjustPosition, const QgsExpressionContext& context )
1075 {
1076  double rotation = mItemRotation;
1077 
1078  //data defined rotation set?
1079  QVariant exprVal;
1080  if ( dataDefinedEvaluate( QgsComposerObject::ItemRotation, exprVal, context ) )
1081  {
1082  bool ok;
1083  double rotD = exprVal.toDouble( &ok );
1084  QgsDebugMsg( QString( "exprVal Rotation:%1" ).arg( rotD ) );
1085  if ( ok && !exprVal.isNull() )
1086  {
1087  rotation = rotD;
1088  }
1089  }
1090 
1091  if ( qgsDoubleNear( rotation, mEvaluatedItemRotation ) )
1092  {
1093  return;
1094  }
1095 
1096  if ( adjustPosition )
1097  {
1098  //adjustPosition set, so shift the position of the item so that rotation occurs around item center
1099  //create a line from the centrepoint of the rect() to its origin, in scene coordinates
1100  QLineF refLine = QLineF( mapToScene( QPointF( rect().width() / 2.0, rect().height() / 2.0 ) ), mapToScene( QPointF( 0, 0 ) ) );
1101  //rotate this line by the current rotation angle
1102  refLine.setAngle( refLine.angle() - rotation + mEvaluatedItemRotation );
1103  //get new end point of line - this is the new item position
1104  QPointF rotatedReferencePoint = refLine.p2();
1105  setPos( rotatedReferencePoint );
1106  emit sizeChanged();
1107  }
1108 
1109  setTransformOriginPoint( 0, 0 );
1110  QGraphicsItem::setRotation( rotation );
1111 
1113 
1114  emit itemRotationChanged( rotation );
1115 
1116  //update bounds of scene, since rotation may affect this
1118 
1119  if ( updateItem )
1120  {
1121  update();
1122  }
1123 }
1124 
1125 bool QgsComposerItem::imageSizeConsideringRotation( double& width, double& height ) const
1126 {
1127  //kept for api compatibility with QGIS 2.0, use item rotation
1129  return imageSizeConsideringRotation( width, height, mEvaluatedItemRotation );
1131 }
1132 
1133 bool QgsComposerItem::imageSizeConsideringRotation( double& width, double& height, double rotation ) const
1134 {
1135  if ( qAbs( rotation ) <= 0.0 ) //width and height stays the same if there is no rotation
1136  {
1137  return true;
1138  }
1139 
1140  if ( qgsDoubleNear( qAbs( rotation ), 90 ) || qgsDoubleNear( qAbs( rotation ), 270 ) )
1141  {
1142  double tmp = width;
1143  width = height;
1144  height = tmp;
1145  return true;
1146  }
1147 
1148  double x1 = 0;
1149  double y1 = 0;
1150  double x2 = width;
1151  double y2 = 0;
1152  double x3 = width;
1153  double y3 = height;
1154  double x4 = 0;
1155  double y4 = height;
1156  double midX = width / 2.0;
1157  double midY = height / 2.0;
1158 
1160  if ( !cornerPointOnRotatedAndScaledRect( x1, y1, width, height, rotation ) )
1161  {
1162  return false;
1163  }
1164  if ( !cornerPointOnRotatedAndScaledRect( x2, y2, width, height, rotation ) )
1165  {
1166  return false;
1167  }
1168  if ( !cornerPointOnRotatedAndScaledRect( x3, y3, width, height, rotation ) )
1169  {
1170  return false;
1171  }
1172  if ( !cornerPointOnRotatedAndScaledRect( x4, y4, width, height, rotation ) )
1173  {
1174  return false;
1175  }
1177 
1178 
1179  //assume points 1 and 3 are on the rectangle boundaries. Calculate 2 and 4.
1180  double distM1 = sqrt(( x1 - midX ) * ( x1 - midX ) + ( y1 - midY ) * ( y1 - midY ) );
1181  QPointF p2 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( QPointF( midX, midY ), QPointF( x2, y2 ), distM1 );
1182 
1183  if ( p2.x() < width && p2.x() > 0 && p2.y() < height && p2.y() > 0 )
1184  {
1185  width = sqrt(( p2.x() - x1 ) * ( p2.x() - x1 ) + ( p2.y() - y1 ) * ( p2.y() - y1 ) );
1186  height = sqrt(( x3 - p2.x() ) * ( x3 - p2.x() ) + ( y3 - p2.y() ) * ( y3 - p2.y() ) );
1187  return true;
1188  }
1189 
1190  //else assume that points 2 and 4 are on the rectangle boundaries. Calculate 1 and 3
1191  double distM2 = sqrt(( x2 - midX ) * ( x2 - midX ) + ( y2 - midY ) * ( y2 - midY ) );
1192  QPointF p1 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( QPointF( midX, midY ), QPointF( x1, y1 ), distM2 );
1193  QPointF p3 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( QPointF( midX, midY ), QPointF( x3, y3 ), distM2 );
1194  width = sqrt(( x2 - p1.x() ) * ( x2 - p1.x() ) + ( y2 - p1.y() ) * ( y2 - p1.y() ) );
1195  height = sqrt(( p3.x() - x2 ) * ( p3.x() - x2 ) + ( p3.y() - y2 ) * ( p3.y() - y2 ) );
1196  return true;
1197 }
1198 
1199 QRectF QgsComposerItem::largestRotatedRectWithinBounds( const QRectF& originalRect, const QRectF& boundsRect, double rotation ) const
1200 {
1201  return QgsComposerUtils::largestRotatedRectWithinBounds( originalRect, boundsRect, rotation );
1202 }
1203 
1204 bool QgsComposerItem::cornerPointOnRotatedAndScaledRect( double& x, double& y, double width, double height ) const
1205 {
1206  //kept for api compatibility with QGIS 2.0, use item rotation
1208  return cornerPointOnRotatedAndScaledRect( x, y, width, height, mEvaluatedItemRotation );
1210 }
1211 
1212 bool QgsComposerItem::cornerPointOnRotatedAndScaledRect( double& x, double& y, double width, double height, double rotation ) const
1213 {
1214  //first rotate point clockwise
1215  double rotToRad = rotation * M_PI / 180.0;
1216  QPointF midpoint( width / 2.0, height / 2.0 );
1217  double xVector = x - midpoint.x();
1218  double yVector = y - midpoint.y();
1219  //double xRotated = cos(rotToRad) * xVector + sin(rotToRad) * yVector;
1220  //double yRotated = -sin(rotToRad) * xVector + cos(rotToRad) * yVector;
1221  double xRotated = cos( rotToRad ) * xVector - sin( rotToRad ) * yVector;
1222  double yRotated = sin( rotToRad ) * xVector + cos( rotToRad ) * yVector;
1223 
1224  //create line from midpoint to rotated point
1225  QLineF line( midpoint.x(), midpoint.y(), midpoint.x() + xRotated, midpoint.y() + yRotated );
1226 
1227  //intersect with all four borders and return result
1228  QList<QLineF> borders;
1229  borders << QLineF( 0, 0, width, 0 );
1230  borders << QLineF( width, 0, width, height );
1231  borders << QLineF( width, height, 0, height );
1232  borders << QLineF( 0, height, 0, 0 );
1233 
1234  QList<QLineF>::const_iterator it = borders.constBegin();
1235  QPointF intersectionPoint;
1236 
1237  for ( ; it != borders.constEnd(); ++it )
1238  {
1239  if ( line.intersect( *it, &intersectionPoint ) == QLineF::BoundedIntersection )
1240  {
1241  x = intersectionPoint.x();
1242  y = intersectionPoint.y();
1243  return true;
1244  }
1245  }
1246  return false;
1247 }
1248 
1249 void QgsComposerItem::sizeChangedByRotation( double& width, double& height )
1250 {
1251  //kept for api compatibility with QGIS 2.0, use item rotation
1253  return sizeChangedByRotation( width, height, mEvaluatedItemRotation );
1255 }
1256 
1257 void QgsComposerItem::sizeChangedByRotation( double& width, double& height, double rotation )
1258 {
1259  if ( rotation == 0.0 )
1260  {
1261  return;
1262  }
1263 
1264  //vector to p1
1265  double x1 = -width / 2.0;
1266  double y1 = -height / 2.0;
1267  QgsComposerUtils::rotate( rotation, x1, y1 );
1268  //vector to p2
1269  double x2 = width / 2.0;
1270  double y2 = -height / 2.0;
1271  QgsComposerUtils::rotate( rotation, x2, y2 );
1272  //vector to p3
1273  double x3 = width / 2.0;
1274  double y3 = height / 2.0;
1275  QgsComposerUtils::rotate( rotation, x3, y3 );
1276  //vector to p4
1277  double x4 = -width / 2.0;
1278  double y4 = height / 2.0;
1279  QgsComposerUtils::rotate( rotation, x4, y4 );
1280 
1281  //double midpoint
1282  QPointF midpoint( width / 2.0, height / 2.0 );
1283 
1284  QPolygonF rotatedRectPoly;
1285  rotatedRectPoly << QPointF( midpoint.x() + x1, midpoint.y() + y1 );
1286  rotatedRectPoly << QPointF( midpoint.x() + x2, midpoint.y() + y2 );
1287  rotatedRectPoly << QPointF( midpoint.x() + x3, midpoint.y() + y3 );
1288  rotatedRectPoly << QPointF( midpoint.x() + x4, midpoint.y() + y4 );
1289  QRectF boundingRect = rotatedRectPoly.boundingRect();
1290  width = boundingRect.width();
1291  height = boundingRect.height();
1292 }
1293 
1294 void QgsComposerItem::rotate( double angle, double& x, double& y ) const
1295 {
1296  QgsComposerUtils::rotate( angle, x, y );
1297 }
1298 
1300 {
1301  if ( !mHAlignSnapItem )
1302  {
1303  mHAlignSnapItem = new QGraphicsLineItem( nullptr );
1304  mHAlignSnapItem->setPen( QPen( QColor( Qt::red ) ) );
1306  mHAlignSnapItem->setZValue( 90 );
1307  }
1308  return mHAlignSnapItem;
1309 }
1310 
1312 {
1313  if ( !mVAlignSnapItem )
1314  {
1315  mVAlignSnapItem = new QGraphicsLineItem( nullptr );
1316  mVAlignSnapItem->setPen( QPen( QColor( Qt::red ) ) );
1318  mVAlignSnapItem->setZValue( 90 );
1319  }
1320  return mVAlignSnapItem;
1321 }
1322 
1324 {
1325  if ( mHAlignSnapItem )
1326  {
1328  delete mHAlignSnapItem;
1329  mHAlignSnapItem = nullptr;
1330  }
1331 }
1332 
1334 {
1335  if ( mVAlignSnapItem )
1336  {
1338  delete mVAlignSnapItem;
1339  mVAlignSnapItem = nullptr;
1340  }
1341 }
1342 
1344 {
1347 }
1348 
1350 {
1351  updateItem();
1352 }
1353 
1355 {
1356  //maintain 2.10 API
1357  //TODO QGIS 3.0 - remove this
1358  const QgsExpressionContext* evalContext = context;
1360  if ( !evalContext )
1361  {
1362  scopedContext.reset( createExpressionContext() );
1363  evalContext = scopedContext.data();
1364  }
1365 
1366  //update data defined properties and redraw item to match
1367  if ( property == QgsComposerObject::PositionX || property == QgsComposerObject::PositionY ||
1368  property == QgsComposerObject::ItemWidth || property == QgsComposerObject::ItemHeight ||
1369  property == QgsComposerObject::AllProperties )
1370  {
1371  QRectF beforeRect = QRectF( pos().x(), pos().y(), rect().width(), rect().height() );
1372  QRectF evaluatedRect = evalItemRect( beforeRect, false, evalContext );
1373  if ( evaluatedRect != beforeRect )
1374  {
1375  setSceneRect( evaluatedRect );
1376  }
1377  }
1378  if ( property == QgsComposerObject::ItemRotation || property == QgsComposerObject::AllProperties )
1379  {
1380  refreshRotation( false, true, *evalContext );
1381  }
1382  if ( property == QgsComposerObject::Transparency || property == QgsComposerObject::AllProperties )
1383  {
1384  refreshTransparency( false, *evalContext );
1385  }
1386  if ( property == QgsComposerObject::BlendMode || property == QgsComposerObject::AllProperties )
1387  {
1388  refreshBlendMode( *evalContext );
1389  }
1391  {
1392  bool exclude = mExcludeFromExports;
1393  //data defined exclude from exports set?
1394  QVariant exprVal;
1395  if ( dataDefinedEvaluate( QgsComposerObject::ExcludeFromExports, exprVal, *evalContext ) && !exprVal.isNull() )
1396  {
1397  exclude = exprVal.toBool();
1398  }
1399  mEvaluatedExcludeFromExports = exclude;
1400  }
1401 
1402  update();
1403 }
1404 
1406 {
1407  if ( id == mId )
1408  {
1409  return;
1410  }
1411 
1412  setToolTip( id );
1413  mId = id;
1414 
1415  //inform model that id data has changed
1416  if ( mComposition )
1417  {
1419  }
1420 
1421  emit itemChanged();
1422 }
1423 
1425 {
1427  setFlag( QGraphicsItem::ItemIsSelectable, !isGroupMember ); //item in groups cannot be selected
1428 }
1429 
1431 {
1432  //return id, if it's not empty
1433  if ( ! id().isEmpty() )
1434  {
1435  return id();
1436  }
1437 
1438  //for unnamed items, default to item type
1439  //(note some item types override this method to provide their own defaults)
1440  switch ( type() )
1441  {
1442  case ComposerArrow:
1443  return tr( "<arrow>" );
1444  case ComposerItemGroup:
1445  return tr( "<group>" );
1446  case ComposerLabel:
1447  return tr( "<label>" );
1448  case ComposerLegend:
1449  return tr( "<legend>" );
1450  case ComposerMap:
1451  return tr( "<map>" );
1452  case ComposerPicture:
1453  return tr( "<picture>" );
1454  case ComposerScaleBar:
1455  return tr( "<scale bar>" );
1456  case ComposerShape:
1457  return tr( "<shape>" );
1458  case ComposerTable:
1459  return tr( "<table>" );
1461  return tr( "<attribute table>" );
1462  case ComposerTextTable:
1463  return tr( "<text table>" );
1464  case ComposerFrame:
1465  return tr( "<frame>" );
1466  }
1467 
1468  return tr( "<item>" );
1469 }
1470 
1471 void QgsComposerItem::setVisibility( const bool visible )
1472 {
1473  if ( visible == isVisible() )
1474  {
1475  //nothing to do
1476  return;
1477  }
1478 
1479  QGraphicsItem::setVisible( visible );
1480 
1481  //inform model that id data has changed
1482  if ( mComposition )
1483  {
1485  }
1486 }
1487 
1489 {
1491 }
1492 
1493 void QgsComposerItem::setExcludeFromExports( const bool exclude )
1494 {
1495  mExcludeFromExports = exclude;
1497 }
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: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 ...
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 item&#39;s current state.
static double fontDescentMM(const QFont &font)
Calculate font descent in millimeters, including workarounds for QT font rendering issues...
double itemRotation(const QgsComposerObject::PropertyValueType valueType=QgsComposerObject::EvaluatedValue) const
Returns the current rotation for the composer item.
QString tr(const char *sourceText, const char *disambiguation, int n)
void setEnabled(bool enable)
void setBlendMode(const QPainter::CompositionMode blendMode)
Sets the item&#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)
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: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
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)