QGIS API Documentation  2.7.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 : blazek@itc.it
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 
44 #include <cmath>
45 
46 #define FONT_WORKAROUND_SCALE 10 //scale factor for upscaling fontsize and downscaling painter
47 
48 #ifndef M_DEG2RAD
49 #define M_DEG2RAD 0.0174532925
50 #endif
51 
52 QgsComposerItem::QgsComposerItem( QgsComposition* composition, bool manageZValue )
53  : QgsComposerObject( composition )
54  , QGraphicsRectItem( 0 )
55  , mRemovedFromComposition( false )
56  , mBoundingResizeRectangle( 0 )
57  , mHAlignSnapItem( 0 )
58  , mVAlignSnapItem( 0 )
59  , mFrame( false )
60  , mBackground( true )
61  , mBackgroundColor( QColor( 255, 255, 255, 255 ) )
62  , mFrameJoinStyle( Qt::MiterJoin )
63  , mItemPositionLocked( false )
64  , mLastValidViewScaleFactor( -1 )
65  , mItemRotation( 0 )
66  , mEvaluatedItemRotation( 0 )
67  , mBlendMode( QPainter::CompositionMode_SourceOver )
68  , mEffectsEnabled( true )
69  , mTransparency( 0 )
70  , mExcludeFromExports( false )
71  , mEvaluatedExcludeFromExports( false )
72  , mLastUsedPositionMode( UpperLeft )
73  , mIsGroupMember( false )
74  , mCurrentExportLayer( -1 )
75  , mId( "" )
76  , mUuid( QUuid::createUuid().toString() )
77 {
78  init( manageZValue );
79 }
80 
81 QgsComposerItem::QgsComposerItem( qreal x, qreal y, qreal width, qreal height, QgsComposition* composition, bool manageZValue )
82  : QgsComposerObject( composition )
83  , QGraphicsRectItem( 0, 0, width, height, 0 )
84  , mRemovedFromComposition( false )
85  , mBoundingResizeRectangle( 0 )
86  , mHAlignSnapItem( 0 )
87  , mVAlignSnapItem( 0 )
88  , mFrame( false )
89  , mBackground( true )
90  , mBackgroundColor( QColor( 255, 255, 255, 255 ) )
91  , mFrameJoinStyle( Qt::MiterJoin )
92  , mItemPositionLocked( false )
93  , mLastValidViewScaleFactor( -1 )
94  , mItemRotation( 0 )
95  , mEvaluatedItemRotation( 0 )
96  , mBlendMode( QPainter::CompositionMode_SourceOver )
97  , mEffectsEnabled( true )
98  , mTransparency( 0 )
99  , mExcludeFromExports( false )
100  , mEvaluatedExcludeFromExports( false )
101  , mLastUsedPositionMode( UpperLeft )
102  , mIsGroupMember( false )
103  , mCurrentExportLayer( -1 )
104  , mId( "" )
105  , mUuid( QUuid::createUuid().toString() )
106 {
107  init( manageZValue );
108  setPos( x, y );
109 }
110 
111 void QgsComposerItem::init( const bool manageZValue )
112 {
113  setFlag( QGraphicsItem::ItemIsSelectable, true );
114  //set default pen and brush
115  setBrush( QBrush( QColor( 255, 255, 255, 255 ) ) );
116  QPen defaultPen( QColor( 0, 0, 0 ) );
117  defaultPen.setWidthF( 0.3 );
118  defaultPen.setJoinStyle( mFrameJoinStyle );
119  setPen( defaultPen );
120  //let z-Value be managed by composition
121  if ( mComposition && manageZValue )
122  {
123  mCompositionManagesZValue = true;
124  mComposition->addItemToZList( this );
125  }
126  else
127  {
128  mCompositionManagesZValue = false;
129  }
130 
131  // Setup composer effect
132  mEffect = new QgsComposerEffect();
133  setGraphicsEffect( mEffect );
134 
135  // data defined strings
136  mDataDefinedNames.insert( QgsComposerObject::PageNumber, QString( "dataDefinedPageNumber" ) );
137  mDataDefinedNames.insert( QgsComposerObject::PositionX, QString( "dataDefinedPositionX" ) );
138  mDataDefinedNames.insert( QgsComposerObject::PositionY, QString( "dataDefinedPositionY" ) );
139  mDataDefinedNames.insert( QgsComposerObject::ItemWidth, QString( "dataDefinedWidth" ) );
140  mDataDefinedNames.insert( QgsComposerObject::ItemHeight, QString( "dataDefinedHeight" ) );
141  mDataDefinedNames.insert( QgsComposerObject::ItemRotation, QString( "dataDefinedRotation" ) );
142  mDataDefinedNames.insert( QgsComposerObject::Transparency, QString( "dataDefinedTransparency" ) );
143  mDataDefinedNames.insert( QgsComposerObject::BlendMode, QString( "dataDefinedBlendMode" ) );
144  mDataDefinedNames.insert( QgsComposerObject::ExcludeFromExports, QString( "dataDefinedExcludeExports" ) );
145 }
146 
148 {
149  if ( mComposition && mCompositionManagesZValue )
150  {
152  }
153 
155  delete mEffect;
156 
158 }
159 
161 {
162  QgsDebugMsg( "entered." );
163  QGraphicsRectItem::setSelected( s );
164  //inform model that id data has changed
165  if ( mComposition )
166  {
168  }
169  update(); //to draw selection boxes
170 }
171 
172 bool QgsComposerItem::_writeXML( QDomElement& itemElem, QDomDocument& doc ) const
173 {
174  if ( itemElem.isNull() )
175  {
176  return false;
177  }
178 
179  QDomElement composerItemElem = doc.createElement( "ComposerItem" );
180 
181  //frame
182  if ( mFrame )
183  {
184  composerItemElem.setAttribute( "frame", "true" );
185  }
186  else
187  {
188  composerItemElem.setAttribute( "frame", "false" );
189  }
190 
191  //background
192  if ( mBackground )
193  {
194  composerItemElem.setAttribute( "background", "true" );
195  }
196  else
197  {
198  composerItemElem.setAttribute( "background", "false" );
199  }
200 
201  //scene rect
202  QPointF pagepos = pagePos();
203  composerItemElem.setAttribute( "x", QString::number( pos().x() ) );
204  composerItemElem.setAttribute( "y", QString::number( pos().y() ) );
205  composerItemElem.setAttribute( "page", page() );
206  composerItemElem.setAttribute( "pagex", QString::number( pagepos.x() ) );
207  composerItemElem.setAttribute( "pagey", QString::number( pagepos.y() ) );
208  composerItemElem.setAttribute( "width", QString::number( rect().width() ) );
209  composerItemElem.setAttribute( "height", QString::number( rect().height() ) );
210  composerItemElem.setAttribute( "positionMode", QString::number(( int ) mLastUsedPositionMode ) );
211  composerItemElem.setAttribute( "zValue", QString::number( zValue() ) );
212  composerItemElem.setAttribute( "outlineWidth", QString::number( pen().widthF() ) );
213  composerItemElem.setAttribute( "frameJoinStyle", QgsSymbolLayerV2Utils::encodePenJoinStyle( mFrameJoinStyle ) );
214  composerItemElem.setAttribute( "itemRotation", QString::number( mItemRotation ) );
215  composerItemElem.setAttribute( "uuid", mUuid );
216  composerItemElem.setAttribute( "id", mId );
217  composerItemElem.setAttribute( "visibility", isVisible() );
218  //position lock for mouse moves/resizes
219  if ( mItemPositionLocked )
220  {
221  composerItemElem.setAttribute( "positionLock", "true" );
222  }
223  else
224  {
225  composerItemElem.setAttribute( "positionLock", "false" );
226  }
227 
228  composerItemElem.setAttribute( "lastValidViewScaleFactor", QString::number( mLastValidViewScaleFactor ) );
229 
230  //frame color
231  QDomElement frameColorElem = doc.createElement( "FrameColor" );
232  QColor frameColor = pen().color();
233  frameColorElem.setAttribute( "red", QString::number( frameColor.red() ) );
234  frameColorElem.setAttribute( "green", QString::number( frameColor.green() ) );
235  frameColorElem.setAttribute( "blue", QString::number( frameColor.blue() ) );
236  frameColorElem.setAttribute( "alpha", QString::number( frameColor.alpha() ) );
237  composerItemElem.appendChild( frameColorElem );
238 
239  //background color
240  QDomElement bgColorElem = doc.createElement( "BackgroundColor" );
241  QColor bgColor = brush().color();
242  bgColorElem.setAttribute( "red", QString::number( bgColor.red() ) );
243  bgColorElem.setAttribute( "green", QString::number( bgColor.green() ) );
244  bgColorElem.setAttribute( "blue", QString::number( bgColor.blue() ) );
245  bgColorElem.setAttribute( "alpha", QString::number( bgColor.alpha() ) );
246  composerItemElem.appendChild( bgColorElem );
247 
248  //blend mode
249  composerItemElem.setAttribute( "blendMode", QgsMapRenderer::getBlendModeEnum( mBlendMode ) );
250 
251  //transparency
252  composerItemElem.setAttribute( "transparency", QString::number( mTransparency ) );
253 
254  composerItemElem.setAttribute( "excludeFromExports", mExcludeFromExports );
255 
256  QgsComposerObject::writeXML( composerItemElem, doc );
257  itemElem.appendChild( composerItemElem );
258 
259  return true;
260 }
261 
262 bool QgsComposerItem::_readXML( const QDomElement& itemElem, const QDomDocument& doc )
263 {
264  Q_UNUSED( doc );
265  if ( itemElem.isNull() )
266  {
267  return false;
268  }
269 
270  QgsComposerObject::readXML( itemElem, doc );
271 
272  //rotation
273  setItemRotation( itemElem.attribute( "itemRotation", "0" ).toDouble() );
274 
275  //uuid
276  mUuid = itemElem.attribute( "uuid", QUuid::createUuid().toString() );
277 
278  // temporary for groups imported from templates
279  mTemplateUuid = itemElem.attribute( "templateUuid" );
280 
281  //id
282  QString id = itemElem.attribute( "id", "" );
283  setId( id );
284 
285  //frame
286  QString frame = itemElem.attribute( "frame" );
287  if ( frame.compare( "true", Qt::CaseInsensitive ) == 0 )
288  {
289  mFrame = true;
290  }
291  else
292  {
293  mFrame = false;
294  }
295 
296  //frame
297  QString background = itemElem.attribute( "background" );
298  if ( background.compare( "true", Qt::CaseInsensitive ) == 0 )
299  {
300  mBackground = true;
301  }
302  else
303  {
304  mBackground = false;
305  }
306 
307  //position lock for mouse moves/resizes
308  QString positionLock = itemElem.attribute( "positionLock" );
309  if ( positionLock.compare( "true", Qt::CaseInsensitive ) == 0 )
310  {
311  setPositionLock( true );
312  }
313  else
314  {
315  setPositionLock( false );
316  }
317 
318  //visibility
319  setVisibility( itemElem.attribute( "visibility", "1" ) != "0" );
320 
321  //position
322  int page;
323  double x, y, pagex, pagey, width, height;
324  bool xOk, yOk, pageOk, pagexOk, pageyOk, widthOk, heightOk, positionModeOK;
325 
326  x = itemElem.attribute( "x" ).toDouble( &xOk );
327  y = itemElem.attribute( "y" ).toDouble( &yOk );
328  page = itemElem.attribute( "page" ).toInt( &pageOk );
329  pagex = itemElem.attribute( "pagex" ).toDouble( &pagexOk );
330  pagey = itemElem.attribute( "pagey" ).toDouble( &pageyOk );
331  width = itemElem.attribute( "width" ).toDouble( &widthOk );
332  height = itemElem.attribute( "height" ).toDouble( &heightOk );
333  mLastUsedPositionMode = ( ItemPositionMode )itemElem.attribute( "positionMode" ).toInt( &positionModeOK );
334  if ( !positionModeOK )
335  {
337  }
338  if ( pageOk && pagexOk && pageyOk )
339  {
340  xOk = true;
341  yOk = true;
342  x = pagex;
343  y = ( page - 1 ) * ( mComposition->paperHeight() + composition()->spaceBetweenPages() ) + pagey;
344  }
345 
346  if ( !xOk || !yOk || !widthOk || !heightOk )
347  {
348  return false;
349  }
350 
351  mLastValidViewScaleFactor = itemElem.attribute( "lastValidViewScaleFactor", "-1" ).toDouble();
352 
353  setZValue( itemElem.attribute( "zValue" ).toDouble() );
354 
355  //pen
356  QDomNodeList frameColorList = itemElem.elementsByTagName( "FrameColor" );
357  if ( frameColorList.size() > 0 )
358  {
359  QDomElement frameColorElem = frameColorList.at( 0 ).toElement();
360  bool redOk, greenOk, blueOk, alphaOk, widthOk;
361  int penRed, penGreen, penBlue, penAlpha;
362  double penWidth;
363 
364  penWidth = itemElem.attribute( "outlineWidth" ).toDouble( &widthOk );
365  penRed = frameColorElem.attribute( "red" ).toDouble( &redOk );
366  penGreen = frameColorElem.attribute( "green" ).toDouble( &greenOk );
367  penBlue = frameColorElem.attribute( "blue" ).toDouble( &blueOk );
368  penAlpha = frameColorElem.attribute( "alpha" ).toDouble( &alphaOk );
369  mFrameJoinStyle = QgsSymbolLayerV2Utils::decodePenJoinStyle( itemElem.attribute( "frameJoinStyle", "miter" ) );
370 
371  if ( redOk && greenOk && blueOk && alphaOk && widthOk )
372  {
373  QPen framePen( QColor( penRed, penGreen, penBlue, penAlpha ) );
374  framePen.setWidthF( penWidth );
375  framePen.setJoinStyle( mFrameJoinStyle );
376  setPen( framePen );
377  }
378  }
379 
380  //brush
381  QDomNodeList bgColorList = itemElem.elementsByTagName( "BackgroundColor" );
382  if ( bgColorList.size() > 0 )
383  {
384  QDomElement bgColorElem = bgColorList.at( 0 ).toElement();
385  bool redOk, greenOk, blueOk, alphaOk;
386  int bgRed, bgGreen, bgBlue, bgAlpha;
387  bgRed = bgColorElem.attribute( "red" ).toDouble( &redOk );
388  bgGreen = bgColorElem.attribute( "green" ).toDouble( &greenOk );
389  bgBlue = bgColorElem.attribute( "blue" ).toDouble( &blueOk );
390  bgAlpha = bgColorElem.attribute( "alpha" ).toDouble( &alphaOk );
391  if ( redOk && greenOk && blueOk && alphaOk )
392  {
393  QColor brushColor( bgRed, bgGreen, bgBlue, bgAlpha );
394  setBackgroundColor( brushColor );
395  }
396  }
397 
398  //blend mode
399  setBlendMode( QgsMapRenderer::getCompositionMode(( QgsMapRenderer::BlendMode ) itemElem.attribute( "blendMode", "0" ).toUInt() ) );
400 
401  //transparency
402  setTransparency( itemElem.attribute( "transparency", "0" ).toInt() );
403 
404  mExcludeFromExports = itemElem.attribute( "excludeFromExports", "0" ).toInt();
406 
407  QRectF evaluatedRect = evalItemRect( QRectF( x, y, width, height ) );
408  setSceneRect( evaluatedRect );
409 
410  return true;
411 }
412 
413 void QgsComposerItem::setFrameEnabled( const bool drawFrame )
414 {
415  if ( drawFrame == mFrame )
416  {
417  //no change
418  return;
419  }
420 
421  mFrame = drawFrame;
422  emit frameChanged();
423 }
424 
425 void QgsComposerItem::setFrameOutlineColor( const QColor &color )
426 {
427  QPen itemPen = pen();
428  if ( itemPen.color() == color )
429  {
430  //no change
431  return;
432  }
433  itemPen.setColor( color );
434  setPen( itemPen );
435  emit frameChanged();
436 }
437 
439 {
440  QPen itemPen = pen();
441  if ( itemPen.widthF() == outlineWidth )
442  {
443  //no change
444  return;
445  }
446  itemPen.setWidthF( outlineWidth );
447  setPen( itemPen );
448  emit frameChanged();
449 }
450 
451 void QgsComposerItem::setFrameJoinStyle( const Qt::PenJoinStyle style )
452 {
453  if ( mFrameJoinStyle == style )
454  {
455  //no change
456  return;
457  }
458  mFrameJoinStyle = style;
459 
460  QPen itemPen = pen();
461  itemPen.setJoinStyle( mFrameJoinStyle );
462  setPen( itemPen );
463  emit frameChanged();
464 }
465 
467 {
468  if ( !hasFrame() )
469  {
470  return 0;
471  }
472 
473  return pen().widthF() / 2.0;
474 }
475 
477 {
478  double frameBleed = estimatedFrameBleed();
479  return rect().adjusted( -frameBleed, -frameBleed, frameBleed, frameBleed );
480 }
481 
483 {
484  if ( mComposition )
485  {
486  mComposition->beginCommand( this, commandText, c );
487  }
488 }
489 
491 {
492  if ( mComposition )
493  {
495  }
496 }
497 
499 {
500  if ( mComposition )
501  {
503  }
504 }
505 
507 {
508  Q_UNUSED( p );
510  {
511  return;
512  }
513 
514  if ( !isSelected() )
515  {
516  return;
517  }
518 
519  //logic for drawing additional graphics on selected items here (if required)
520 
521  //draw dotted border around locked, selected items
522  if ( positionLock() )
523  {
524  p->save();
525  p->setCompositionMode( QPainter::CompositionMode_Difference );
526 
527  // use a grey dashed pen - in difference mode this should always be visible
528  QPen selectedItemPen = QPen( QColor( 144, 144, 144, 255 ) );
529  selectedItemPen.setStyle( Qt::DotLine );
530  selectedItemPen.setWidth( 0 );
531  p->setPen( selectedItemPen );
532  p->setBrush( Qt::NoBrush );
533  p->drawPolygon( rect() );
534  p->restore();
535  }
536 
537 }
538 
539 void QgsComposerItem::drawFrame( QPainter* p )
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 
660  if ( mEvaluatedItemRotation == 0 )
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 )
712 {
713  QRectF result = newRect;
714 
715  //data defined position or size set? if so, update rect with data defined values
716  QVariant exprVal;
717  //evaulate width and height first, since they may affect position if non-top-left reference point set
719  {
720  bool ok;
721  double width = exprVal.toDouble( &ok );
722  QgsDebugMsg( QString( "exprVal Width:%1" ).arg( width ) );
723  if ( ok && !exprVal.isNull() )
724  {
725  result.setWidth( width );
726  }
727  }
729  {
730  bool ok;
731  double height = exprVal.toDouble( &ok );
732  QgsDebugMsg( QString( "exprVal Height:%1" ).arg( height ) );
733  if ( ok && !exprVal.isNull() )
734  {
735  result.setHeight( height );
736  }
737  }
738 
739  double x = result.left();
740  //initially adjust for position mode to get x coordinate
741  if ( !resizeOnly )
742  {
743  //adjust x-coordinate if placement is not done to a left point
745  {
746  x += newRect.width() / 2.0;
747  }
749  {
750  x += newRect.width();
751  }
752  }
753  else
754  {
756  {
757  x += rect().width() / 2.0;
758  }
760  {
761  x += rect().width();
762  }
763  }
765  {
766  bool ok;
767  double positionX = exprVal.toDouble( &ok );
768  QgsDebugMsg( QString( "exprVal Position X:%1" ).arg( positionX ) );
769  if ( ok && !exprVal.isNull() )
770  {
771  x = positionX;
772  }
773  }
774 
775  double y = result.top();
776  //initially adjust for position mode to get y coordinate
777  if ( !resizeOnly )
778  {
779  //adjust y-coordinate if placement is not done to an upper point
781  {
782  y += newRect.height() / 2.0;
783  }
785  {
786  y += newRect.height();
787  }
788  }
789  else
790  {
792  {
793  y += rect().height() / 2.0;
794  }
796  {
797  y += rect().height();
798  }
799  }
801  {
802  bool ok;
803  double positionY = exprVal.toDouble( &ok );
804  QgsDebugMsg( QString( "exprVal Position Y:%1" ).arg( positionY ) );
805  if ( ok && !exprVal.isNull() )
806  {
807  y = positionY;
808  }
809  }
810 
811  //adjust x-coordinate if placement is not done to a left point
813  {
814  x -= result.width() / 2.0;
815  }
817  {
818  x -= result.width();
819  }
820 
821  //adjust y-coordinate if placement is not done to an upper point
823  {
824  y -= result.height() / 2.0;
825  }
827  {
828  y -= result.height();
829  }
830 
831  result.moveLeft( x );
832  result.moveTop( y );
833 
834  return result;
835 }
836 
838 {
840  {
841  //preview mode or no composition, so ok to draw item
842  return true;
843  }
844 
845  //exporting composition, so check if item is excluded from exports
847 }
848 
850 {
851  if ( mBackground && p )
852  {
853  p->save();
854  p->setBrush( brush() );//this causes a problem in atlas generation
855  p->setPen( Qt::NoPen );
856  p->setRenderHint( QPainter::Antialiasing, true );
857  p->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
858  p->restore();
859  }
860 }
861 
862 void QgsComposerItem::drawArrowHead( QPainter *p, double x, double y, double angle, double arrowHeadWidth ) const
863 {
864  QgsComposerUtils::drawArrowHead( p, x, y, angle, arrowHeadWidth );
865 }
866 
867 double QgsComposerItem::angle( const QPointF &p1, const QPointF &p2 ) const
868 {
869  return QgsComposerUtils::angle( p1, p2 );
870 }
871 
872 void QgsComposerItem::setBackgroundColor( const QColor& backgroundColor )
873 {
875  setBrush( QBrush( mBackgroundColor, Qt::SolidPattern ) );
876 }
877 
878 void QgsComposerItem::setBlendMode( const QPainter::CompositionMode blendMode )
879 {
881  // Update the composer effect to use the new blend mode
882  refreshBlendMode();
883 }
884 
885 void QgsComposerItem::refreshBlendMode()
886 {
887  QPainter::CompositionMode blendMode = mBlendMode;
888 
889  //data defined blend mode set?
890  QVariant exprVal;
891  if ( dataDefinedEvaluate( QgsComposerObject::BlendMode, exprVal ) && !exprVal.isNull() )
892  {
893  QString blendstr = exprVal.toString().trimmed();
894  QPainter::CompositionMode blendModeD = QgsSymbolLayerV2Utils::decodeBlendMode( blendstr );
895 
896  QgsDebugMsg( QString( "exprVal BlendMode:%1" ).arg( blendModeD ) );
897  blendMode = blendModeD;
898  }
899 
900  // Update the composer effect to use the new blend mode
901  mEffect->setCompositionMode( blendMode );
902 }
903 
904 void QgsComposerItem::setTransparency( const int transparency )
905 {
907  refreshTransparency( true );
908 }
909 
910 void QgsComposerItem::refreshTransparency( const bool updateItem )
911 {
913 
914  //data defined transparency set?
915  QVariant exprVal;
917  {
918  bool ok;
919  int transparencyD = exprVal.toInt( &ok );
920  QgsDebugMsg( QString( "exprVal Transparency:%1" ).arg( transparencyD ) );
921  if ( ok && !exprVal.isNull() )
922  {
923  transparency = transparencyD;
924  }
925  }
926 
927  // Set the QGraphicItem's opacity
928  setOpacity( 1. - ( transparency / 100. ) );
929 
930  if ( updateItem )
931  {
932  update();
933  }
934 }
935 
936 void QgsComposerItem::setEffectsEnabled( const bool effectsEnabled )
937 {
938  //enable or disable the QgsComposerEffect applied to this item
940  mEffect->setEnabled( effectsEnabled );
941 }
942 
943 void QgsComposerItem::drawText( QPainter* p, double x, double y, const QString& text, const QFont& font, const QColor& c ) const
944 {
945  QgsComposerUtils::drawText( p, QPointF( x, y ), text, font, c );
946 }
947 
948 void QgsComposerItem::drawText( QPainter* p, const QRectF& rect, const QString& text, const QFont& font, Qt::AlignmentFlag halignment, Qt::AlignmentFlag valignment, int flags ) const
949 {
950  QgsComposerUtils::drawText( p, rect, text, font, QColor(), halignment, valignment, flags );
951 }
952 double QgsComposerItem::textWidthMillimeters( const QFont& font, const QString& text ) const
953 {
954  return QgsComposerUtils::textWidthMM( font, text );
955 }
956 
957 double QgsComposerItem::fontHeightCharacterMM( const QFont& font, const QChar& c ) const
958 {
959  return QgsComposerUtils::fontHeightCharacterMM( font, c );
960 }
961 
962 double QgsComposerItem::fontAscentMillimeters( const QFont& font ) const
963 {
964  return QgsComposerUtils::fontAscentMM( font );
965 }
966 
967 double QgsComposerItem::fontDescentMillimeters( const QFont& font ) const
968 {
969  return QgsComposerUtils::fontDescentMM( font );
970 }
971 
972 double QgsComposerItem::fontHeightMillimeters( const QFont& font ) const
973 {
974  return QgsComposerUtils::fontHeightMM( font );
975 }
976 
977 double QgsComposerItem::pixelFontSize( double pointSize ) const
978 {
979  return QgsComposerUtils::pointsToMM( pointSize );
980 }
981 
982 QFont QgsComposerItem::scaledFontPixelSize( const QFont& font ) const
983 {
985 }
986 
988 {
989  double result = -1;
990  if ( scene() )
991  {
992  QList<QGraphicsView*> viewList = scene()->views();
993  if ( viewList.size() > 0 ) //if not, probably this function was called from non-gui code
994  {
995  QGraphicsView* currentView = viewList.at( 0 );
996  if ( currentView->isVisible() )
997  {
998  result = currentView->transform().m11();
999  mLastValidViewScaleFactor = result;
1000  }
1001  }
1002  }
1003  return result;
1004 }
1005 
1007 {
1008  //size of symbol boxes depends on zoom level in composer view
1009  double viewScaleFactor = horizontalViewScaleFactor();
1010  double rectHandlerSize = 10.0 / viewScaleFactor;
1011 
1012  //make sure the boxes don't get too large
1013  if ( rectHandlerSize > ( rect().width() / 3 ) )
1014  {
1015  rectHandlerSize = rect().width() / 3;
1016  }
1017  if ( rectHandlerSize > ( rect().height() / 3 ) )
1018  {
1019  rectHandlerSize = rect().height() / 3;
1020  }
1021  return rectHandlerSize;
1022 }
1023 
1025 {
1026  double lockSymbolSize = 20.0 / horizontalViewScaleFactor();
1027 
1028  if ( lockSymbolSize > ( rect().width() / 3 ) )
1029  {
1030  lockSymbolSize = rect().width() / 3;
1031  }
1032  if ( lockSymbolSize > ( rect().height() / 3 ) )
1033  {
1034  lockSymbolSize = rect().height() / 3;
1035  }
1036  return lockSymbolSize;
1037 }
1038 
1039 void QgsComposerItem::setRotation( const double r )
1040 {
1041  //kept for api compatibility with QGIS 2.0
1042  //remove after 2.0 series
1043  setItemRotation( r, true );
1044 }
1045 
1046 void QgsComposerItem::setItemRotation( const double r, const bool adjustPosition )
1047 {
1048  if ( r >= 360 )
1049  {
1050  mItemRotation = (( int )r ) % 360;
1051  }
1052  else
1053  {
1054  mItemRotation = r;
1055  }
1056 
1057  refreshRotation( true, adjustPosition );
1058 }
1059 
1060 void QgsComposerItem::refreshRotation( const bool updateItem, const bool adjustPosition )
1061 {
1062  double rotation = mItemRotation;
1063 
1064  //data defined rotation set?
1065  QVariant exprVal;
1067  {
1068  bool ok;
1069  double rotD = exprVal.toDouble( &ok );
1070  QgsDebugMsg( QString( "exprVal Rotation:%1" ).arg( rotD ) );
1071  if ( ok && !exprVal.isNull() )
1072  {
1073  rotation = rotD;
1074  }
1075  }
1076 
1077  if ( rotation == mEvaluatedItemRotation )
1078  {
1079  return;
1080  }
1081 
1082  if ( adjustPosition )
1083  {
1084  //adjustPosition set, so shift the position of the item so that rotation occurs around item center
1085  //create a line from the centrepoint of the rect() to its origin, in scene coordinates
1086  QLineF refLine = QLineF( mapToScene( QPointF( rect().width() / 2.0, rect().height() / 2.0 ) ), mapToScene( QPointF( 0, 0 ) ) );
1087  //rotate this line by the current rotation angle
1088  refLine.setAngle( refLine.angle() - rotation + mEvaluatedItemRotation );
1089  //get new end point of line - this is the new item position
1090  QPointF rotatedReferencePoint = refLine.p2();
1091  setPos( rotatedReferencePoint );
1092  emit sizeChanged();
1093  }
1094 
1095  setTransformOriginPoint( 0, 0 );
1096  QGraphicsItem::setRotation( rotation );
1097 
1099 
1100  emit itemRotationChanged( rotation );
1101 
1102  //update bounds of scene, since rotation may affect this
1104 
1105  if ( updateItem )
1106  {
1107  update();
1108  }
1109 }
1110 
1111 bool QgsComposerItem::imageSizeConsideringRotation( double& width, double& height ) const
1112 {
1113  //kept for api compatibility with QGIS 2.0, use item rotation
1115  return imageSizeConsideringRotation( width, height, mEvaluatedItemRotation );
1117 }
1118 
1119 bool QgsComposerItem::imageSizeConsideringRotation( double& width, double& height, double rotation ) const
1120 {
1121  if ( qAbs( rotation ) <= 0.0 ) //width and height stays the same if there is no rotation
1122  {
1123  return true;
1124  }
1125 
1126  if ( qgsDoubleNear( qAbs( rotation ), 90 ) || qgsDoubleNear( qAbs( rotation ), 270 ) )
1127  {
1128  double tmp = width;
1129  width = height;
1130  height = tmp;
1131  return true;
1132  }
1133 
1134  double x1 = 0;
1135  double y1 = 0;
1136  double x2 = width;
1137  double y2 = 0;
1138  double x3 = width;
1139  double y3 = height;
1140  double x4 = 0;
1141  double y4 = height;
1142  double midX = width / 2.0;
1143  double midY = height / 2.0;
1144 
1146  if ( !cornerPointOnRotatedAndScaledRect( x1, y1, width, height, rotation ) )
1147  {
1148  return false;
1149  }
1150  if ( !cornerPointOnRotatedAndScaledRect( x2, y2, width, height, rotation ) )
1151  {
1152  return false;
1153  }
1154  if ( !cornerPointOnRotatedAndScaledRect( x3, y3, width, height, rotation ) )
1155  {
1156  return false;
1157  }
1158  if ( !cornerPointOnRotatedAndScaledRect( x4, y4, width, height, rotation ) )
1159  {
1160  return false;
1161  }
1163 
1164 
1165  //assume points 1 and 3 are on the rectangle boundaries. Calculate 2 and 4.
1166  double distM1 = sqrt(( x1 - midX ) * ( x1 - midX ) + ( y1 - midY ) * ( y1 - midY ) );
1167  QPointF p2 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( QPointF( midX, midY ), QPointF( x2, y2 ), distM1 );
1168 
1169  if ( p2.x() < width && p2.x() > 0 && p2.y() < height && p2.y() > 0 )
1170  {
1171  width = sqrt(( p2.x() - x1 ) * ( p2.x() - x1 ) + ( p2.y() - y1 ) * ( p2.y() - y1 ) );
1172  height = sqrt(( x3 - p2.x() ) * ( x3 - p2.x() ) + ( y3 - p2.y() ) * ( y3 - p2.y() ) );
1173  return true;
1174  }
1175 
1176  //else assume that points 2 and 4 are on the rectangle boundaries. Calculate 1 and 3
1177  double distM2 = sqrt(( x2 - midX ) * ( x2 - midX ) + ( y2 - midY ) * ( y2 - midY ) );
1178  QPointF p1 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( QPointF( midX, midY ), QPointF( x1, y1 ), distM2 );
1179  QPointF p3 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( QPointF( midX, midY ), QPointF( x3, y3 ), distM2 );
1180  width = sqrt(( x2 - p1.x() ) * ( x2 - p1.x() ) + ( y2 - p1.y() ) * ( y2 - p1.y() ) );
1181  height = sqrt(( p3.x() - x2 ) * ( p3.x() - x2 ) + ( p3.y() - y2 ) * ( p3.y() - y2 ) );
1182  return true;
1183 }
1184 
1185 QRectF QgsComposerItem::largestRotatedRectWithinBounds( QRectF originalRect, QRectF boundsRect, double rotation ) const
1186 {
1187  return QgsComposerUtils::largestRotatedRectWithinBounds( originalRect, boundsRect, rotation );
1188 }
1189 
1190 bool QgsComposerItem::cornerPointOnRotatedAndScaledRect( double& x, double& y, double width, double height ) const
1191 {
1192  //kept for api compatibility with QGIS 2.0, use item rotation
1194  return cornerPointOnRotatedAndScaledRect( x, y, width, height, mEvaluatedItemRotation );
1196 }
1197 
1198 bool QgsComposerItem::cornerPointOnRotatedAndScaledRect( double& x, double& y, double width, double height, double rotation ) const
1199 {
1200  //first rotate point clockwise
1201  double rotToRad = rotation * M_PI / 180.0;
1202  QPointF midpoint( width / 2.0, height / 2.0 );
1203  double xVector = x - midpoint.x();
1204  double yVector = y - midpoint.y();
1205  //double xRotated = cos(rotToRad) * xVector + sin(rotToRad) * yVector;
1206  //double yRotated = -sin(rotToRad) * xVector + cos(rotToRad) * yVector;
1207  double xRotated = cos( rotToRad ) * xVector - sin( rotToRad ) * yVector;
1208  double yRotated = sin( rotToRad ) * xVector + cos( rotToRad ) * yVector;
1209 
1210  //create line from midpoint to rotated point
1211  QLineF line( midpoint.x(), midpoint.y(), midpoint.x() + xRotated, midpoint.y() + yRotated );
1212 
1213  //intersect with all four borders and return result
1214  QList<QLineF> borders;
1215  borders << QLineF( 0, 0, width, 0 );
1216  borders << QLineF( width, 0, width, height );
1217  borders << QLineF( width, height, 0, height );
1218  borders << QLineF( 0, height, 0, 0 );
1219 
1220  QList<QLineF>::const_iterator it = borders.constBegin();
1221  QPointF intersectionPoint;
1222 
1223  for ( ; it != borders.constEnd(); ++it )
1224  {
1225  if ( line.intersect( *it, &intersectionPoint ) == QLineF::BoundedIntersection )
1226  {
1227  x = intersectionPoint.x();
1228  y = intersectionPoint.y();
1229  return true;
1230  }
1231  }
1232  return false;
1233 }
1234 
1235 void QgsComposerItem::sizeChangedByRotation( double& width, double& height )
1236 {
1237  //kept for api compatibility with QGIS 2.0, use item rotation
1239  return sizeChangedByRotation( width, height, mEvaluatedItemRotation );
1241 }
1242 
1243 void QgsComposerItem::sizeChangedByRotation( double& width, double& height, double rotation )
1244 {
1245  if ( rotation == 0.0 )
1246  {
1247  return;
1248  }
1249 
1250  //vector to p1
1251  double x1 = -width / 2.0;
1252  double y1 = -height / 2.0;
1253  QgsComposerUtils::rotate( rotation, x1, y1 );
1254  //vector to p2
1255  double x2 = width / 2.0;
1256  double y2 = -height / 2.0;
1257  QgsComposerUtils::rotate( rotation, x2, y2 );
1258  //vector to p3
1259  double x3 = width / 2.0;
1260  double y3 = height / 2.0;
1261  QgsComposerUtils::rotate( rotation, x3, y3 );
1262  //vector to p4
1263  double x4 = -width / 2.0;
1264  double y4 = height / 2.0;
1265  QgsComposerUtils::rotate( rotation, x4, y4 );
1266 
1267  //double midpoint
1268  QPointF midpoint( width / 2.0, height / 2.0 );
1269 
1270  QPolygonF rotatedRectPoly;
1271  rotatedRectPoly << QPointF( midpoint.x() + x1, midpoint.y() + y1 );
1272  rotatedRectPoly << QPointF( midpoint.x() + x2, midpoint.y() + y2 );
1273  rotatedRectPoly << QPointF( midpoint.x() + x3, midpoint.y() + y3 );
1274  rotatedRectPoly << QPointF( midpoint.x() + x4, midpoint.y() + y4 );
1275  QRectF boundingRect = rotatedRectPoly.boundingRect();
1276  width = boundingRect.width();
1277  height = boundingRect.height();
1278 }
1279 
1280 void QgsComposerItem::rotate( double angle, double& x, double& y ) const
1281 {
1282  QgsComposerUtils::rotate( angle, x, y );
1283 }
1284 
1286 {
1287  if ( !mHAlignSnapItem )
1288  {
1289  mHAlignSnapItem = new QGraphicsLineItem( 0 );
1290  mHAlignSnapItem->setPen( QPen( QColor( Qt::red ) ) );
1291  scene()->addItem( mHAlignSnapItem );
1292  mHAlignSnapItem->setZValue( 90 );
1293  }
1294  return mHAlignSnapItem;
1295 }
1296 
1298 {
1299  if ( !mVAlignSnapItem )
1300  {
1301  mVAlignSnapItem = new QGraphicsLineItem( 0 );
1302  mVAlignSnapItem->setPen( QPen( QColor( Qt::red ) ) );
1303  scene()->addItem( mVAlignSnapItem );
1304  mVAlignSnapItem->setZValue( 90 );
1305  }
1306  return mVAlignSnapItem;
1307 }
1308 
1310 {
1311  if ( mHAlignSnapItem )
1312  {
1313  scene()->removeItem( mHAlignSnapItem );
1314  delete mHAlignSnapItem;
1315  mHAlignSnapItem = 0;
1316  }
1317 }
1318 
1320 {
1321  if ( mVAlignSnapItem )
1322  {
1323  scene()->removeItem( mVAlignSnapItem );
1324  delete mVAlignSnapItem;
1325  mVAlignSnapItem = 0;
1326  }
1327 }
1328 
1330 {
1333 }
1334 
1336 {
1337  updateItem();
1338 }
1339 
1341 {
1342  //update data defined properties and redraw item to match
1343  if ( property == QgsComposerObject::PositionX || property == QgsComposerObject::PositionY ||
1344  property == QgsComposerObject::ItemWidth || property == QgsComposerObject::ItemHeight ||
1345  property == QgsComposerObject::AllProperties )
1346  {
1347  QRectF beforeRect = QRectF( pos().x(), pos().y(), rect().width(), rect().height() );
1348  QRectF evaluatedRect = evalItemRect( beforeRect );
1349  if ( evaluatedRect != beforeRect )
1350  {
1351  setSceneRect( evaluatedRect );
1352  }
1353  }
1354  if ( property == QgsComposerObject::ItemRotation || property == QgsComposerObject::AllProperties )
1355  {
1356  refreshRotation( false, true );
1357  }
1358  if ( property == QgsComposerObject::Transparency || property == QgsComposerObject::AllProperties )
1359  {
1360  refreshTransparency( false );
1361  }
1362  if ( property == QgsComposerObject::BlendMode || property == QgsComposerObject::AllProperties )
1363  {
1364  refreshBlendMode();
1365  }
1367  {
1368  bool exclude = mExcludeFromExports;
1369  //data defined exclude from exports set?
1370  QVariant exprVal;
1371  if ( dataDefinedEvaluate( QgsComposerObject::ExcludeFromExports, exprVal ) && !exprVal.isNull() )
1372  {
1373  exclude = exprVal.toBool();
1374  }
1375  mEvaluatedExcludeFromExports = exclude;
1376  }
1377 
1378  update();
1379 }
1380 
1381 void QgsComposerItem::setId( const QString& id )
1382 {
1383  if ( id == mId )
1384  {
1385  return;
1386  }
1387 
1388  setToolTip( id );
1389  mId = id;
1390 
1391  //inform model that id data has changed
1392  if ( mComposition )
1393  {
1395  }
1396 
1397  emit itemChanged();
1398 }
1399 
1400 void QgsComposerItem::setIsGroupMember( const bool isGroupMember )
1401 {
1403  setFlag( QGraphicsItem::ItemIsSelectable, !isGroupMember ); //item in groups cannot be selected
1404 }
1405 
1407 {
1408  //return id, if it's not empty
1409  if ( ! id().isEmpty() )
1410  {
1411  return id();
1412  }
1413 
1414  //for unnamed items, default to item type
1415  //(note some item types override this method to provide their own defaults)
1416  switch ( type() )
1417  {
1418  case ComposerArrow:
1419  return tr( "<arrow>" );
1420  case ComposerItemGroup:
1421  return tr( "<group>" );
1422  case ComposerLabel:
1423  return tr( "<label>" );
1424  case ComposerLegend:
1425  return tr( "<legend>" );
1426  case ComposerMap:
1427  return tr( "<map>" );
1428  case ComposerPicture:
1429  return tr( "<picture>" );
1430  case ComposerScaleBar:
1431  return tr( "<scale bar>" );
1432  case ComposerShape:
1433  return tr( "<shape>" );
1434  case ComposerTable:
1435  return tr( "<table>" );
1437  return tr( "<attribute table>" );
1438  case ComposerTextTable:
1439  return tr( "<text table>" );
1440  case ComposerFrame:
1441  return tr( "<frame>" );
1442  }
1443 
1444  return tr( "<item>" );
1445 }
1446 
1447 void QgsComposerItem::setVisibility( const bool visible )
1448 {
1449  if ( visible == isVisible() )
1450  {
1451  //nothing to do
1452  return;
1453  }
1454 
1455  QGraphicsItem::setVisible( visible );
1456 
1457  //inform model that id data has changed
1458  if ( mComposition )
1459  {
1461  }
1462 }
1463 
1465 {
1467 }
1468 
1469 void QgsComposerItem::setExcludeFromExports( const bool exclude )
1470 {
1471  mExcludeFromExports = exclude;
1473 }
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.
bool effectsEnabled() const
Returns whether effects (eg blend modes) are enabled for the item.
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...
double outlineWidth
Definition: qgssvgcache.cpp:78
virtual bool writeXML(QDomElement &elem, QDomDocument &doc) const
Stores item state in DOM element.
int mTransparency
Item transparency.
A base class for objects which belong to a map composition.
Q_DECL_DEPRECATED double fontHeightCharacterMM(const QFont &font, const QChar &c) const
Returns the font height of a character in millimeters.
void itemRotationChanged(double newRotation)
Is emitted on item rotation change.
Q_DECL_DEPRECATED double pixelFontSize(double pointSize) const
Calculates font size in mm from a font point size.
void addItemToZList(QgsComposerItem *item)
Adds item to z list.
virtual void setRotation(double r)
Sets the item rotation.
virtual double estimatedFrameBleed() const
Returns the estimated amount the item's frame bleeds outside the item's actual rectangle.
QgsComposerModel * itemsModel()
Returns the items model attached to the composition.
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
void itemChanged()
Emitted when the item changes.
Q_DECL_DEPRECATED double lockSymbolSize() const
Returns the size of the lock symbol depending on the composer zoom level and the item size...
QPointF pagePos() const
Returns the item's position relative to its current page.
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:439
void removeItemFromZList(QgsComposerItem *item)
Removes item from z list.
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.
static void drawText(QPainter *painter, const QPointF &pos, const QString &text, const QFont &font, const QColor &color=QColor())
Draws text on a painter at a specific position, taking care of composer specific issues (calculation ...
double mLastValidViewScaleFactor
Backup to restore item appearance if no view scale factor is available.
ItemPositionMode mLastUsedPositionMode
The item's position mode.
void updateBounds()
Updates the scene bounds of the composition.
void updateItemVisibility(QgsComposerItem *item)
Must be called when an item's visibility changes.
virtual void setSelected(bool s)
Set selected, selected item should be highlighted.
static double fontAscentMM(const QFont &font)
Calculate font ascent in millimeters, including workarounds for QT font rendering issues...
virtual void drawFrame(QPainter *p)
Draw black frame around item.
virtual void setFrameEnabled(const bool drawFrame)
Set whether this item has a frame drawn around it or not.
static QFont scaledFontPixelSize(const QFont &font)
Returns a font where size is set in pixels and the size has been upscaled with FONT_WORKAROUND_SCALE ...
DataDefinedProperty
Data defined properties for different item types.
QColor backgroundColor() const
Gets the background color for this item.
QPainter::CompositionMode mBlendMode
Composition blend mode for item.
void setCompositionMode(const QPainter::CompositionMode &compositionMode)
bool excludeFromExports(const QgsComposerObject::PropertyValueType valueType=QgsComposerObject::EvaluatedValue)
Returns whether the item should be excluded from composer exports and prints.
double spaceBetweenPages() const
Returns the vertical space between pages in a composer view.
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.
void setBlendMode(const QPainter::CompositionMode blendMode)
Sets the item's composition blending mode.
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Definition: qgis.h:325
void updateItemDisplayName(QgsComposerItem *item)
Must be called when an item's display name is modified.
bool dataDefinedEvaluate(const QgsComposerObject::DataDefinedProperty property, QVariant &expressionValue)
Evaluate a data defined property and return the calculated value.
void setItemPosition(double x, double y, ItemPositionMode itemPoint=UpperLeft, int page=-1)
Moves the item to a new position (in canvas coordinates)
virtual int type() const
return correct graphics item type.
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...
void updateItemLockStatus(QgsComposerItem *item)
Must be called when an item's lock status changes.
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.
void frameChanged()
Emitted if the item's frame style changes.
static QPainter::CompositionMode decodeBlendMode(const QString &s)
double horizontalViewScaleFactor() const
Returns the zoom factor of the graphics view.
void setFrameJoinStyle(const Qt::PenJoinStyle style)
Sets join style used when drawing the item's frame.
void cancelCommand()
Deletes current command.
Q_DECL_DEPRECATED QFont scaledFontPixelSize(const QFont &font) const
Returns a font where size is in pixel and font size is upscaled with FONT_WORKAROUND_SCALE.
int transparency() const
Returns the item's transparency.
virtual void refreshDataDefinedProperty(const QgsComposerObject::DataDefinedProperty property=QgsComposerObject::AllProperties)
Refreshes a data defined property for the item by reevaluating the property's value and redrawing the...
virtual void updateItem()
Updates item, with the possibility to do custom update for subclasses.
static double fontHeightCharacterMM(const QFont &font, const QChar &character)
Calculate font height in millimeters of a single character, including workarounds for QT font renderi...
virtual void drawSelectionBoxes(QPainter *p)
Draws additional graphics on selected items.
Q_DECL_DEPRECATED double textWidthMillimeters(const QFont &font, const QString &text) const
Returns the font width in millimeters (considers upscaling and downscaling with FONT_WORKAROUND_SCALE...
Q_DECL_DEPRECATED void rotate(double angle, double &x, double &y) const
Rotates a point / vector.
void endCommand()
Saves end state of item and pushes command to the undo history.
QGraphicsRectItem * mBoundingResizeRectangle
Rectangle used during move and resize actions.
Q_DECL_DEPRECATED QRectF largestRotatedRectWithinBounds(QRectF originalRect, 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 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.
const QgsComposition * composition() const
Returns the composition the item is attached to.
void endCommand()
Finish current command and push it onto the undo stack.
virtual void setFrameOutlineColor(const QColor &color)
Sets frame outline color.
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
#define M_PI
double mEvaluatedItemRotation
Temporary evaluated item rotation in degrees, clockwise.
PropertyValueType
Specifies whether the value returned by a function should be the original, user set value...
virtual ~QgsComposerItem()
void beginCommand(const QString &commandText, QgsComposerMergeCommand::Context c=QgsComposerMergeCommand::Unknown)
Starts new composer undo command.
bool shouldDrawItem() const
Returns whether the item should be drawn in the current context.
Graphics scene for map printing.
BlendMode
Blending modes enum defining the available composition modes that can be used when rendering a layer...
static void rotate(const double angle, double &x, double &y)
Rotates a point / vector around the origin.
double ANALYSIS_EXPORT angle(Point3D *p1, Point3D *p2, Point3D *p3, Point3D *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
virtual void setExcludeFromExports(const bool exclude)
Sets whether the item should be excluded from composer exports and prints.
virtual QString displayName() const
Get item display name.
virtual QRectF rectWithFrame() const
Returns the item's rectangular bounds, including any bleed caused by the item's frame.
QGraphicsLineItem * hAlignSnapItem()
Return horizontal align snap item.
static QPainter::CompositionMode getCompositionMode(const QgsMapRenderer::BlendMode &blendMode)
Returns a QPainter::CompositionMode corresponding to a BlendMode.
void setPositionLock(const bool lock)
Locks / unlocks the item position for mouse drags.
virtual void setFrameOutlineWidth(const double outlineWidth)
Sets frame outline width.
Q_DECL_DEPRECATED double rotation() const
Returns the rotation for the composer item.
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:440
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
static double fontHeightMM(const QFont &font)
Calculate font height in millimeters, including workarounds for QT font rendering issues The font hei...
QRectF evalItemRect(const QRectF &newRect, const bool resizeOnly=false)
Evaluates an item's bounding rect to consider data defined position and size of item and reference po...
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
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.
bool mItemPositionLocked
True if item position and size cannot be changed with mouse move.
QPainter::CompositionMode blendMode() const
Returns the item's composition blending mode.
virtual bool readXML(const QDomElement &itemElem, const QDomDocument &doc)
Sets item state from DOM element.
virtual void setItemRotation(const double r, const bool adjustPosition=false)
Sets the item rotation.
virtual void drawBackground(QPainter *p)
Draw background.
bool hasFrame() const
Whether this item has a frame or not.
virtual void setId(const QString &id)
Set item's id (which is not necessarly unique)
Q_DECL_DEPRECATED double fontHeightMillimeters(const QFont &font) const
Returns the font height in Millimeters (considers upscaling and downscaling with FONT_WORKAROUND_SCAL...
virtual void setSceneRect(const QRectF &rectangle)
Sets this items bound in scene coordinates such that 1 item size units corresponds to 1 scene size un...
Q_DECL_DEPRECATED double angle(const QPointF &p1, const QPointF &p2) const
Returns angle of the line from p1 to p2 (clockwise, starting at N)
void sizeChanged()
Emitted if the rectangle changes.
double paperHeight() const
Height of paper item.
void setIsGroupMember(const bool isGroupMember)
Sets whether this item is part of a group.
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.
static Qt::PenJoinStyle decodePenJoinStyle(QString str)
void setEffectsEnabled(const bool effectsEnabled)
Sets whether effects (eg blend modes) are enabled for the item.
void updateItemSelectStatus(QgsComposerItem *item)
Must be called when an item's selection status changes.
static QgsMapRenderer::BlendMode getBlendModeEnum(const QPainter::CompositionMode &blendMode)
Returns a BlendMode corresponding to a QPainter::CompositionMode.
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.
static double angle(const QPointF &p1, const QPointF &p2)
Calculates the angle of the line from p1 to p2 (counter clockwise, starting from a line from north to...
void lockChanged()
Emitted if the item's lock status changes.
QgsComposition::PlotStyle plotStyle() const
double rectHandlerBorderTolerance() const
Returns the current (zoom level dependent) tolerance to decide if mouse position is close enough to t...
static QPointF pointOnLineWithDistance(const QPointF &startPoint, const QPointF &directionPoint, double distance)
Returns a point on the line from startPoint to directionPoint that is a certain distance away from th...
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.
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.
QGraphicsLineItem * vAlignSnapItem()
Return vertical align snap item.
Q_DECL_DEPRECATED double fontAscentMillimeters(const QFont &font) const
Returns the font ascent in Millimeters (considers upscaling and downscaling with FONT_WORKAROUND_SCAL...
bool mEvaluatedExcludeFromExports
Temporary evaluated item exclusion.
void setTransparency(const int transparency)
Sets the item's transparency.
Q_DECL_DEPRECATED void sizeChangedByRotation(double &width, double &height, double rotation)
Calculates width / height of the bounding box of a rotated rectangle.
void beginCommand(QgsComposerItem *item, const QString &commandText, const QgsComposerMergeCommand::Context c=QgsComposerMergeCommand::Unknown)
Allocates new item command and saves initial state in it.
#define tr(sourceText)
QString id() const
Get item's id (which is not necessarly unique)