QGIS API Documentation  2.4.0-Chugiak
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups 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 : [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 
34 #include <limits>
35 #include "qgsapplication.h"
36 #include "qgsrectangle.h" //just for debugging
37 #include "qgslogger.h"
38 #include "qgssymbollayerv2utils.h" //for pointOnLineWithDistance
39 #include "qgsmaprenderer.h" //for getCompositionMode
40 
41 #include <cmath>
42 
43 #define FONT_WORKAROUND_SCALE 10 //scale factor for upscaling fontsize and downscaling painter
44 
45 #ifndef M_DEG2RAD
46 #define M_DEG2RAD 0.0174532925
47 #endif
48 
49 QgsComposerItem::QgsComposerItem( QgsComposition* composition, bool manageZValue )
50  : QObject( 0 )
51  , QGraphicsRectItem( 0 )
52  , mComposition( composition )
53  , mBoundingResizeRectangle( 0 )
54  , mHAlignSnapItem( 0 )
55  , mVAlignSnapItem( 0 )
56  , mFrame( false )
57  , mBackground( true )
58  , mBackgroundColor( QColor( 255, 255, 255, 255 ) )
59  , mFrameJoinStyle( Qt::MiterJoin )
60  , mItemPositionLocked( false )
61  , mLastValidViewScaleFactor( -1 )
62  , mItemRotation( 0 )
63  , mBlendMode( QPainter::CompositionMode_SourceOver )
64  , mEffectsEnabled( true )
65  , mTransparency( 0 )
66  , mLastUsedPositionMode( UpperLeft )
67  , mCurrentExportLayer( -1 )
68  , mId( "" )
69  , mUuid( QUuid::createUuid().toString() )
70 {
71  init( manageZValue );
72 }
73 
74 QgsComposerItem::QgsComposerItem( qreal x, qreal y, qreal width, qreal height, QgsComposition* composition, bool manageZValue )
75  : QObject( 0 )
76  , QGraphicsRectItem( 0, 0, width, height, 0 )
77  , mComposition( composition )
78  , mBoundingResizeRectangle( 0 )
79  , mHAlignSnapItem( 0 )
80  , mVAlignSnapItem( 0 )
81  , mFrame( false )
82  , mBackground( true )
83  , mBackgroundColor( QColor( 255, 255, 255, 255 ) )
84  , mFrameJoinStyle( Qt::MiterJoin )
85  , mItemPositionLocked( false )
86  , mLastValidViewScaleFactor( -1 )
87  , mItemRotation( 0 )
88  , mBlendMode( QPainter::CompositionMode_SourceOver )
89  , mEffectsEnabled( true )
90  , mTransparency( 0 )
91  , mLastUsedPositionMode( UpperLeft )
92  , mCurrentExportLayer( -1 )
93  , mId( "" )
94  , mUuid( QUuid::createUuid().toString() )
95 {
96  init( manageZValue );
97  setPos( x, y );
98 }
99 
100 void QgsComposerItem::init( bool manageZValue )
101 {
102  setFlag( QGraphicsItem::ItemIsSelectable, true );
103  //set default pen and brush
104  setBrush( QBrush( QColor( 255, 255, 255, 255 ) ) );
105  QPen defaultPen( QColor( 0, 0, 0 ) );
106  defaultPen.setWidthF( 0.3 );
107  defaultPen.setJoinStyle( mFrameJoinStyle );
108  setPen( defaultPen );
109  //let z-Value be managed by composition
110  if ( mComposition && manageZValue )
111  {
112  mComposition->addItemToZList( this );
113  }
114 
115  // Setup composer effect
116  mEffect = new QgsComposerEffect();
117  setGraphicsEffect( mEffect );
118 }
119 
121 {
122  if ( mComposition )
123  {
125  }
126 
128  delete mEffect;
130 }
131 
133 {
134  QgsDebugMsg( "entered." );
135  QGraphicsRectItem::setSelected( s );
136  update(); //to draw selection boxes
137 }
138 
139 bool QgsComposerItem::writeSettings( void ) { return true; }
140 
141 bool QgsComposerItem::readSettings( void ) { return true; }
142 
143 bool QgsComposerItem::removeSettings( void ) { return true; }
144 
145 bool QgsComposerItem::_writeXML( QDomElement& itemElem, QDomDocument& doc ) const
146 {
147  if ( itemElem.isNull() )
148  {
149  return false;
150  }
151 
152  QDomElement composerItemElem = doc.createElement( "ComposerItem" );
153 
154  //frame
155  if ( mFrame )
156  {
157  composerItemElem.setAttribute( "frame", "true" );
158  }
159  else
160  {
161  composerItemElem.setAttribute( "frame", "false" );
162  }
163 
164  //frame
165  if ( mBackground )
166  {
167  composerItemElem.setAttribute( "background", "true" );
168  }
169  else
170  {
171  composerItemElem.setAttribute( "background", "false" );
172  }
173 
174  //scene rect
175  QPointF pagepos = pagePos();
176  composerItemElem.setAttribute( "x", QString::number( pos().x() ) );
177  composerItemElem.setAttribute( "y", QString::number( pos().y() ) );
178  composerItemElem.setAttribute( "page", page() );
179  composerItemElem.setAttribute( "pagex", QString::number( pagepos.x() ) );
180  composerItemElem.setAttribute( "pagey", QString::number( pagepos.y() ) );
181  composerItemElem.setAttribute( "width", QString::number( rect().width() ) );
182  composerItemElem.setAttribute( "height", QString::number( rect().height() ) );
183  composerItemElem.setAttribute( "positionMode", QString::number(( int ) mLastUsedPositionMode ) );
184  composerItemElem.setAttribute( "zValue", QString::number( zValue() ) );
185  composerItemElem.setAttribute( "outlineWidth", QString::number( pen().widthF() ) );
186  composerItemElem.setAttribute( "frameJoinStyle", QgsSymbolLayerV2Utils::encodePenJoinStyle( mFrameJoinStyle ) );
187  composerItemElem.setAttribute( "itemRotation", QString::number( mItemRotation ) );
188  composerItemElem.setAttribute( "uuid", mUuid );
189  composerItemElem.setAttribute( "id", mId );
190  //position lock for mouse moves/resizes
191  if ( mItemPositionLocked )
192  {
193  composerItemElem.setAttribute( "positionLock", "true" );
194  }
195  else
196  {
197  composerItemElem.setAttribute( "positionLock", "false" );
198  }
199 
200  composerItemElem.setAttribute( "lastValidViewScaleFactor", QString::number( mLastValidViewScaleFactor ) );
201 
202 
203  //frame color
204  QDomElement frameColorElem = doc.createElement( "FrameColor" );
205  QColor frameColor = pen().color();
206  frameColorElem.setAttribute( "red", QString::number( frameColor.red() ) );
207  frameColorElem.setAttribute( "green", QString::number( frameColor.green() ) );
208  frameColorElem.setAttribute( "blue", QString::number( frameColor.blue() ) );
209  frameColorElem.setAttribute( "alpha", QString::number( frameColor.alpha() ) );
210  composerItemElem.appendChild( frameColorElem );
211 
212  //background color
213  QDomElement bgColorElem = doc.createElement( "BackgroundColor" );
214  QColor bgColor = brush().color();
215  bgColorElem.setAttribute( "red", QString::number( bgColor.red() ) );
216  bgColorElem.setAttribute( "green", QString::number( bgColor.green() ) );
217  bgColorElem.setAttribute( "blue", QString::number( bgColor.blue() ) );
218  bgColorElem.setAttribute( "alpha", QString::number( bgColor.alpha() ) );
219  composerItemElem.appendChild( bgColorElem );
220 
221  //blend mode
222  composerItemElem.setAttribute( "blendMode", QgsMapRenderer::getBlendModeEnum( mBlendMode ) );
223 
224  //transparency
225  composerItemElem.setAttribute( "transparency", QString::number( mTransparency ) );
226 
227  itemElem.appendChild( composerItemElem );
228 
229  return true;
230 }
231 
232 bool QgsComposerItem::_readXML( const QDomElement& itemElem, const QDomDocument& doc )
233 {
234  Q_UNUSED( doc );
235  if ( itemElem.isNull() )
236  {
237  return false;
238  }
239 
240  //rotation
241  setItemRotation( itemElem.attribute( "itemRotation", "0" ).toDouble() );
242 
243  //uuid
244  mUuid = itemElem.attribute( "uuid", QUuid::createUuid().toString() );
245 
246  // temporary for groups imported from templates
247  mTemplateUuid = itemElem.attribute( "templateUuid" );
248 
249  //id
250  QString id = itemElem.attribute( "id", "" );
251  setId( id );
252 
253  //frame
254  QString frame = itemElem.attribute( "frame" );
255  if ( frame.compare( "true", Qt::CaseInsensitive ) == 0 )
256  {
257  mFrame = true;
258  }
259  else
260  {
261  mFrame = false;
262  }
263 
264  //frame
265  QString background = itemElem.attribute( "background" );
266  if ( background.compare( "true", Qt::CaseInsensitive ) == 0 )
267  {
268  mBackground = true;
269  }
270  else
271  {
272  mBackground = false;
273  }
274 
275  //position lock for mouse moves/resizes
276  QString positionLock = itemElem.attribute( "positionLock" );
277  if ( positionLock.compare( "true", Qt::CaseInsensitive ) == 0 )
278  {
279  setPositionLock( true );
280  }
281  else
282  {
283  setPositionLock( false );
284  }
285 
286  //position
287  int page;
288  double x, y, pagex, pagey, width, height;
289  bool xOk, yOk, pageOk, pagexOk, pageyOk, widthOk, heightOk, positionModeOK;
290 
291  x = itemElem.attribute( "x" ).toDouble( &xOk );
292  y = itemElem.attribute( "y" ).toDouble( &yOk );
293  page = itemElem.attribute( "page" ).toInt( &pageOk );
294  pagex = itemElem.attribute( "pagex" ).toDouble( &pagexOk );
295  pagey = itemElem.attribute( "pagey" ).toDouble( &pageyOk );
296  width = itemElem.attribute( "width" ).toDouble( &widthOk );
297  height = itemElem.attribute( "height" ).toDouble( &heightOk );
298  mLastUsedPositionMode = ( ItemPositionMode )itemElem.attribute( "positionMode" ).toInt( &positionModeOK );
299  if ( !positionModeOK )
300  {
302  }
303  if ( pageOk && pagexOk && pageyOk )
304  {
305  xOk = true;
306  yOk = true;
307  x = pagex;
308  y = ( page - 1 ) * ( mComposition->paperHeight() + composition()->spaceBetweenPages() ) + pagey;
309  }
310 
311  if ( !xOk || !yOk || !widthOk || !heightOk )
312  {
313  return false;
314  }
315 
316  mLastValidViewScaleFactor = itemElem.attribute( "lastValidViewScaleFactor", "-1" ).toDouble();
317 
318  setSceneRect( QRectF( x, y, width, height ) );
319  setZValue( itemElem.attribute( "zValue" ).toDouble() );
320 
321  //pen
322  QDomNodeList frameColorList = itemElem.elementsByTagName( "FrameColor" );
323  if ( frameColorList.size() > 0 )
324  {
325  QDomElement frameColorElem = frameColorList.at( 0 ).toElement();
326  bool redOk, greenOk, blueOk, alphaOk, widthOk;
327  int penRed, penGreen, penBlue, penAlpha;
328  double penWidth;
329 
330  penWidth = itemElem.attribute( "outlineWidth" ).toDouble( &widthOk );
331  penRed = frameColorElem.attribute( "red" ).toDouble( &redOk );
332  penGreen = frameColorElem.attribute( "green" ).toDouble( &greenOk );
333  penBlue = frameColorElem.attribute( "blue" ).toDouble( &blueOk );
334  penAlpha = frameColorElem.attribute( "alpha" ).toDouble( &alphaOk );
335  mFrameJoinStyle = QgsSymbolLayerV2Utils::decodePenJoinStyle( itemElem.attribute( "frameJoinStyle", "miter" ) );
336 
337  if ( redOk && greenOk && blueOk && alphaOk && widthOk )
338  {
339  QPen framePen( QColor( penRed, penGreen, penBlue, penAlpha ) );
340  framePen.setWidthF( penWidth );
341  framePen.setJoinStyle( mFrameJoinStyle );
342  setPen( framePen );
343  }
344  }
345 
346  //brush
347  QDomNodeList bgColorList = itemElem.elementsByTagName( "BackgroundColor" );
348  if ( bgColorList.size() > 0 )
349  {
350  QDomElement bgColorElem = bgColorList.at( 0 ).toElement();
351  bool redOk, greenOk, blueOk, alphaOk;
352  int bgRed, bgGreen, bgBlue, bgAlpha;
353  bgRed = bgColorElem.attribute( "red" ).toDouble( &redOk );
354  bgGreen = bgColorElem.attribute( "green" ).toDouble( &greenOk );
355  bgBlue = bgColorElem.attribute( "blue" ).toDouble( &blueOk );
356  bgAlpha = bgColorElem.attribute( "alpha" ).toDouble( &alphaOk );
357  if ( redOk && greenOk && blueOk && alphaOk )
358  {
359  QColor brushColor( bgRed, bgGreen, bgBlue, bgAlpha );
360  setBackgroundColor( brushColor );
361  }
362  }
363 
364  //blend mode
365  setBlendMode( QgsMapRenderer::getCompositionMode(( QgsMapRenderer::BlendMode ) itemElem.attribute( "blendMode", "0" ).toUInt() ) );
366 
367  //transparency
368  setTransparency( itemElem.attribute( "transparency" , "0" ).toInt() );
369 
370  return true;
371 }
372 
373 void QgsComposerItem::setFrameEnabled( bool drawFrame )
374 {
375  mFrame = drawFrame;
376  emit frameChanged();
377 }
378 
380 {
381  QPen itemPen = pen();
382  if ( itemPen.widthF() == outlineWidth )
383  {
384  //no change
385  return;
386  }
387  itemPen.setWidthF( outlineWidth );
388  setPen( itemPen );
389  emit frameChanged();
390 }
391 
392 void QgsComposerItem::setFrameJoinStyle( Qt::PenJoinStyle style )
393 {
394  if ( mFrameJoinStyle == style )
395  {
396  //no change
397  return;
398  }
399  mFrameJoinStyle = style;
400 
401  QPen itemPen = pen();
402  itemPen.setJoinStyle( mFrameJoinStyle );
403  setPen( itemPen );
404  emit frameChanged();
405 }
406 
408 {
409  if ( !hasFrame() )
410  {
411  return 0;
412  }
413 
414  return pen().widthF() / 2.0;
415 }
416 
418 {
419  double frameBleed = estimatedFrameBleed();
420  return rect().adjusted( -frameBleed, -frameBleed, frameBleed, frameBleed );
421 }
422 
424 {
425  if ( mComposition )
426  {
427  mComposition->beginCommand( this, commandText, c );
428  }
429 }
430 
432 {
433  if ( mComposition )
434  {
436  }
437 }
438 
440 {
441  if ( mComposition )
442  {
444  }
445 }
446 
448 {
449 
450  if ( !mComposition )
451  {
452  return;
453  }
454 
456  {
457  double sizeLockSymbol = lockSymbolSize();
458 
459  if ( mItemPositionLocked )
460  {
461  //draw lock symbol at upper left edge. Use QImage to be independent of the graphic system
462  QString lockIconPath = QgsApplication::activeThemePath() + "/mIconLock.png";
463  if ( !QFile::exists( lockIconPath ) )
464  {
465  lockIconPath = QgsApplication::defaultThemePath() + "/mIconLock.png";
466  }
467 
468  QImage lockImage( lockIconPath );
469  if ( !lockImage.isNull() )
470  {
471  p->drawImage( QRectF( 0, 0, sizeLockSymbol, sizeLockSymbol ), lockImage, QRectF( 0, 0, lockImage.width(), lockImage.height() ) );
472  }
473  }
474  }
475 }
476 
477 void QgsComposerItem::drawFrame( QPainter* p )
478 {
479  if ( mFrame && p )
480  {
481  p->setPen( pen() );
482  p->setBrush( Qt::NoBrush );
483  p->setRenderHint( QPainter::Antialiasing, true );
484  p->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
485  }
486 }
487 
489 {
490  mItemPositionLocked = lock;
491 }
492 
493 void QgsComposerItem::move( double dx, double dy )
494 {
495  QRectF newSceneRect( pos().x() + dx, pos().y() + dy, rect().width(), rect().height() );
496  setSceneRect( newSceneRect );
497 }
498 
500 {
501  double y = pos().y();
502  double h = composition()->paperHeight() + composition()->spaceBetweenPages();
503  int page = 1;
504  while ( y - h >= 0. )
505  {
506  y -= h;
507  ++page;
508  }
509  return page;
510 }
511 
513 {
514  QPointF p = pos();
515  double h = composition()->paperHeight() + composition()->spaceBetweenPages();
516  p.ry() -= ( page() - 1 ) * h;
517  return p;
518 }
519 
520 void QgsComposerItem::updatePagePos( double newPageWidth, double newPageHeight )
521 {
522  Q_UNUSED( newPageWidth )
523  QPointF curPagePos = pagePos();
524  int curPage = page() - 1;
525  setY( curPage * ( newPageHeight + composition()->spaceBetweenPages() ) + curPagePos.y() );
526  emit sizeChanged();
527 }
528 
529 void QgsComposerItem::setItemPosition( double x, double y, ItemPositionMode itemPoint, int page )
530 {
531  double width = rect().width();
532  double height = rect().height();
533  setItemPosition( x, y, width, height, itemPoint, false, page );
534 }
535 
536 void QgsComposerItem::setItemPosition( double x, double y, double width, double height, ItemPositionMode itemPoint, bool posIncludesFrame, int page )
537 {
538  double upperLeftX = x;
539  double upperLeftY = y;
540 
541  if ( page > 0 )
542  {
543  double h = composition()->paperHeight() + composition()->spaceBetweenPages();
544  upperLeftY += ( page - 1 ) * h;
545  }
546 
547  //store the item position mode
548  mLastUsedPositionMode = itemPoint;
549 
550  //adjust x-coordinate if placement is not done to a left point
551  if ( itemPoint == UpperMiddle || itemPoint == Middle || itemPoint == LowerMiddle )
552  {
553  upperLeftX -= width / 2.0;
554  }
555  else if ( itemPoint == UpperRight || itemPoint == MiddleRight || itemPoint == LowerRight )
556  {
557  upperLeftX -= width;
558  }
559 
560  //adjust y-coordinate if placement is not done to an upper point
561  if ( itemPoint == MiddleLeft || itemPoint == Middle || itemPoint == MiddleRight )
562  {
563  upperLeftY -= height / 2.0;
564  }
565  else if ( itemPoint == LowerLeft || itemPoint == LowerMiddle || itemPoint == LowerRight )
566  {
567  upperLeftY -= height;
568  }
569 
570  if ( posIncludesFrame )
571  {
572  //adjust position to account for frame size
573 
574  if ( mItemRotation == 0 )
575  {
576  upperLeftX += estimatedFrameBleed();
577  upperLeftY += estimatedFrameBleed();
578  }
579  else
580  {
581  //adjust position for item rotation
582  QLineF lineToItemOrigin = QLineF( 0, 0, estimatedFrameBleed(), estimatedFrameBleed() );
583  lineToItemOrigin.setAngle( -45 - mItemRotation );
584  upperLeftX += lineToItemOrigin.x2();
585  upperLeftY += lineToItemOrigin.y2();
586  }
587 
588  width -= 2 * estimatedFrameBleed();
589  height -= 2 * estimatedFrameBleed();
590  }
591 
592  setSceneRect( QRectF( upperLeftX, upperLeftY, width, height ) );
593 }
594 
595 void QgsComposerItem::setSceneRect( const QRectF& rectangle )
596 {
597  //setRect in item coordinates
598  double newWidth = rectangle.width();
599  double newHeight = rectangle.height();
600  double xTranslation = rectangle.x();
601  double yTranslation = rectangle.y();
602 
603  //correction if width and/or height are negative
604  if ( rectangle.width() < 0 )
605  {
606  newWidth = - rectangle.width();
607  xTranslation -= newWidth;
608  }
609 
610  if ( rectangle.height() < 0 )
611  {
612  newHeight = - rectangle.height();
613  yTranslation -= newHeight;
614  }
615 
616  QRectF newRect( 0, 0, newWidth, newHeight );
617  QGraphicsRectItem::setRect( newRect );
618  setPos( xTranslation, yTranslation );
619 
620  emit sizeChanged();
621 }
622 
624 {
625  if ( mBackground && p )
626  {
627  p->setBrush( brush() );//this causes a problem in atlas generation
628  p->setPen( Qt::NoPen );
629  p->setRenderHint( QPainter::Antialiasing, true );
630  p->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
631  }
632 }
633 
634 void QgsComposerItem::setBackgroundColor( const QColor& backgroundColor )
635 {
637  setBrush( QBrush( mBackgroundColor, Qt::SolidPattern ) );
638 }
639 
640 void QgsComposerItem::setBlendMode( QPainter::CompositionMode blendMode )
641 {
643  // Update the composer effect to use the new blend mode
645 }
646 
647 void QgsComposerItem::setTransparency( int transparency )
648 {
650  // Set the QGraphicItem's opacity
651  setOpacity( 1. - ( transparency / 100. ) );
652 }
653 
654 void QgsComposerItem::setEffectsEnabled( bool effectsEnabled )
655 {
656  //enable or disable the QgsComposerEffect applied to this item
658  mEffect->setEnabled( effectsEnabled );
659 }
660 
661 void QgsComposerItem::drawText( QPainter* p, double x, double y, const QString& text, const QFont& font ) const
662 {
663  QFont textFont = scaledFontPixelSize( font );
664 
665  p->save();
666  p->setFont( textFont );
667  double scaleFactor = 1.0 / FONT_WORKAROUND_SCALE;
668  p->scale( scaleFactor, scaleFactor );
669  p->drawText( QPointF( x * FONT_WORKAROUND_SCALE, y * FONT_WORKAROUND_SCALE ), text );
670  p->restore();
671 }
672 
673 void QgsComposerItem::drawText( QPainter* p, const QRectF& rect, const QString& text, const QFont& font, Qt::AlignmentFlag halignment, Qt::AlignmentFlag valignment, int flags ) const
674 {
675  QFont textFont = scaledFontPixelSize( font );
676 
677  QRectF scaledRect( rect.x() * FONT_WORKAROUND_SCALE, rect.y() * FONT_WORKAROUND_SCALE,
678  rect.width() * FONT_WORKAROUND_SCALE, rect.height() * FONT_WORKAROUND_SCALE );
679 
680  p->save();
681  p->setFont( textFont );
682  double scaleFactor = 1.0 / FONT_WORKAROUND_SCALE;
683  p->scale( scaleFactor, scaleFactor );
684  p->drawText( scaledRect, halignment | valignment | flags, text );
685  p->restore();
686 }
687 void QgsComposerItem::drawArrowHead( QPainter* p, double x, double y, double angle, double arrowHeadWidth ) const
688 {
689  if ( !p )
690  {
691  return;
692  }
693  double angleRad = angle / 180.0 * M_PI;
694  QPointF middlePoint( x, y );
695  //rotate both arrow points
696  QPointF p1 = QPointF( -arrowHeadWidth / 2.0, arrowHeadWidth );
697  QPointF p2 = QPointF( arrowHeadWidth / 2.0, arrowHeadWidth );
698 
699  QPointF p1Rotated, p2Rotated;
700  p1Rotated.setX( p1.x() * cos( angleRad ) + p1.y() * -sin( angleRad ) );
701  p1Rotated.setY( p1.x() * sin( angleRad ) + p1.y() * cos( angleRad ) );
702  p2Rotated.setX( p2.x() * cos( angleRad ) + p2.y() * -sin( angleRad ) );
703  p2Rotated.setY( p2.x() * sin( angleRad ) + p2.y() * cos( angleRad ) );
704 
705  QPolygonF arrowHeadPoly;
706  arrowHeadPoly << middlePoint;
707  arrowHeadPoly << QPointF( middlePoint.x() + p1Rotated.x(), middlePoint.y() + p1Rotated.y() );
708  arrowHeadPoly << QPointF( middlePoint.x() + p2Rotated.x(), middlePoint.y() + p2Rotated.y() );
709 
710  p->save();
711 
712  QPen arrowPen = p->pen();
713  arrowPen.setJoinStyle( Qt::RoundJoin );
714  QBrush arrowBrush = p->brush();
715  arrowBrush.setStyle( Qt::SolidPattern );
716  p->setPen( arrowPen );
717  p->setBrush( arrowBrush );
718  arrowBrush.setStyle( Qt::SolidPattern );
719  p->drawPolygon( arrowHeadPoly );
720 
721  p->restore();
722 }
723 
724 double QgsComposerItem::textWidthMillimeters( const QFont& font, const QString& text ) const
725 {
726  QFont metricsFont = scaledFontPixelSize( font );
727  QFontMetricsF fontMetrics( metricsFont );
728  return ( fontMetrics.width( text ) / FONT_WORKAROUND_SCALE );
729 }
730 
731 double QgsComposerItem::fontHeightCharacterMM( const QFont& font, const QChar& c ) const
732 {
733  QFont metricsFont = scaledFontPixelSize( font );
734  QFontMetricsF fontMetrics( metricsFont );
735  return ( fontMetrics.boundingRect( c ).height() / FONT_WORKAROUND_SCALE );
736 }
737 
738 double QgsComposerItem::fontAscentMillimeters( const QFont& font ) const
739 {
740  QFont metricsFont = scaledFontPixelSize( font );
741  QFontMetricsF fontMetrics( metricsFont );
742  return ( fontMetrics.ascent() / FONT_WORKAROUND_SCALE );
743 }
744 
745 double QgsComposerItem::fontDescentMillimeters( const QFont& font ) const
746 {
747  QFont metricsFont = scaledFontPixelSize( font );
748  QFontMetricsF fontMetrics( metricsFont );
749  return ( fontMetrics.descent() / FONT_WORKAROUND_SCALE );
750 }
751 
752 double QgsComposerItem::fontHeightMillimeters( const QFont& font ) const
753 {
754  QFont metricsFont = scaledFontPixelSize( font );
755  QFontMetricsF fontMetrics( metricsFont );
756  return ( fontMetrics.height() / FONT_WORKAROUND_SCALE );
757 }
758 
759 double QgsComposerItem::pixelFontSize( double pointSize ) const
760 {
761  return ( pointSize * 0.3527 );
762 }
763 
764 QFont QgsComposerItem::scaledFontPixelSize( const QFont& font ) const
765 {
766  QFont scaledFont = font;
767  double pixelSize = pixelFontSize( font.pointSizeF() ) * FONT_WORKAROUND_SCALE + 0.5;
768  scaledFont.setPixelSize( pixelSize );
769  return scaledFont;
770 }
771 
772 double QgsComposerItem::angle( const QPointF& p1, const QPointF& p2 ) const
773 {
774  double xDiff = p2.x() - p1.x();
775  double yDiff = p2.y() - p1.y();
776  double length = sqrt( xDiff * xDiff + yDiff * yDiff );
777  if ( length <= 0 )
778  {
779  return 0;
780  }
781 
782  double angle = acos(( -yDiff * length ) / ( length * length ) ) * 180 / M_PI;
783  if ( xDiff < 0 )
784  {
785  return ( 360 - angle );
786  }
787  return angle;
788 }
789 
791 {
792  double result = -1;
793  if ( scene() )
794  {
795  QList<QGraphicsView*> viewList = scene()->views();
796  if ( viewList.size() > 0 ) //if not, probably this function was called from non-gui code
797  {
798  QGraphicsView* currentView = viewList.at( 0 );
799  if ( currentView->isVisible() )
800  {
801  result = currentView->transform().m11();
802  mLastValidViewScaleFactor = result;
803  }
804  }
805  }
806  return result;
807 }
808 
810 {
811  //size of symbol boxes depends on zoom level in composer view
812  double viewScaleFactor = horizontalViewScaleFactor();
813  double rectHandlerSize = 10.0 / viewScaleFactor;
814 
815  //make sure the boxes don't get too large
816  if ( rectHandlerSize > ( rect().width() / 3 ) )
817  {
818  rectHandlerSize = rect().width() / 3;
819  }
820  if ( rectHandlerSize > ( rect().height() / 3 ) )
821  {
822  rectHandlerSize = rect().height() / 3;
823  }
824  return rectHandlerSize;
825 }
826 
828 {
829  double lockSymbolSize = 20.0 / horizontalViewScaleFactor();
830 
831  if ( lockSymbolSize > ( rect().width() / 3 ) )
832  {
833  lockSymbolSize = rect().width() / 3;
834  }
835  if ( lockSymbolSize > ( rect().height() / 3 ) )
836  {
837  lockSymbolSize = rect().height() / 3;
838  }
839  return lockSymbolSize;
840 }
841 
843 {
844  //kept for api compatibility with QGIS 2.0
845  //remove after 2.0 series
846  setItemRotation( r, true );
847 }
848 
849 void QgsComposerItem::setItemRotation( double r, bool adjustPosition )
850 {
851  if ( adjustPosition )
852  {
853  //adjustPosition set, so shift the position of the item so that rotation occurs around item center
854  //create a line from the centrepoint of the rect() to its origin, in scene coordinates
855  QLineF refLine = QLineF( mapToScene( QPointF( rect().width() / 2.0, rect().height() / 2.0 ) ) , mapToScene( QPointF( 0 , 0 ) ) );
856  //rotate this line by the current rotation angle
857  refLine.setAngle( refLine.angle() - r + mItemRotation );
858  //get new end point of line - this is the new item position
859  QPointF rotatedReferencePoint = refLine.p2();
860  setPos( rotatedReferencePoint );
861  emit sizeChanged();
862  }
863 
864  if ( r > 360 )
865  {
866  mItemRotation = (( int )r ) % 360;
867  }
868  else
869  {
870  mItemRotation = r;
871  }
872 
873  setTransformOriginPoint( 0, 0 );
874  QGraphicsItem::setRotation( mItemRotation );
875 
876  emit itemRotationChanged( r );
877  update();
878 }
879 
880 bool QgsComposerItem::imageSizeConsideringRotation( double& width, double& height ) const
881 {
882  //kept for api compatibility with QGIS 2.0, use item rotation
883  return imageSizeConsideringRotation( width, height, mItemRotation );
884 }
885 
886 QRectF QgsComposerItem::largestRotatedRectWithinBounds( QRectF originalRect, QRectF boundsRect, double rotation ) const
887 {
888  double originalWidth = originalRect.width();
889  double originalHeight = originalRect.height();
890  double boundsWidth = boundsRect.width();
891  double boundsHeight = boundsRect.height();
892  double ratioBoundsRect = boundsWidth / boundsHeight;
893 
894  //shortcut for some rotation values
895  if ( rotation == 0 || rotation == 90 || rotation == 180 || rotation == 270 )
896  {
897  double originalRatio = originalWidth / originalHeight;
898  double rectScale = originalRatio > ratioBoundsRect ? boundsWidth / originalWidth : boundsHeight / originalHeight;
899  double rectScaledWidth = rectScale * originalWidth;
900  double rectScaledHeight = rectScale * originalHeight;
901 
902  if ( rotation == 0 || rotation == 180 )
903  {
904  return QRectF(( boundsWidth - rectScaledWidth ) / 2.0, ( boundsHeight - rectScaledHeight ) / 2.0, rectScaledWidth, rectScaledHeight );
905  }
906  else
907  {
908  return QRectF(( boundsWidth - rectScaledHeight ) / 2.0, ( boundsHeight - rectScaledWidth ) / 2.0, rectScaledHeight, rectScaledWidth );
909  }
910  }
911 
912  //convert angle to radians and flip
913  double angleRad = -rotation * M_DEG2RAD;
914  double cosAngle = cos( angleRad );
915  double sinAngle = sin( angleRad );
916 
917  //calculate size of bounds of rotated rectangle
918  double widthBoundsRotatedRect = originalWidth * fabs( cosAngle ) + originalHeight * fabs( sinAngle );
919  double heightBoundsRotatedRect = originalHeight * fabs( cosAngle ) + originalWidth * fabs( sinAngle );
920 
921  //compare ratio of rotated rect with bounds rect and calculate scaling of rotated
922  //rect to fit within bounds
923  double ratioBoundsRotatedRect = widthBoundsRotatedRect / heightBoundsRotatedRect;
924  double rectScale = ratioBoundsRotatedRect > ratioBoundsRect ? boundsWidth / widthBoundsRotatedRect : boundsHeight / heightBoundsRotatedRect;
925  double rectScaledWidth = rectScale * originalWidth;
926  double rectScaledHeight = rectScale * originalHeight;
927 
928  //now calculate offset so that rotated rectangle is centered within bounds
929  //first calculate min x and y coordinates
930  double currentCornerX = 0;
931  double minX = 0;
932  currentCornerX += rectScaledWidth * cosAngle;
933  minX = minX < currentCornerX ? minX : currentCornerX;
934  currentCornerX += rectScaledHeight * sinAngle;
935  minX = minX < currentCornerX ? minX : currentCornerX;
936  currentCornerX -= rectScaledWidth * cosAngle;
937  minX = minX < currentCornerX ? minX : currentCornerX;
938 
939  double currentCornerY = 0;
940  double minY = 0;
941  currentCornerY -= rectScaledWidth * sinAngle;
942  minY = minY < currentCornerY ? minY : currentCornerY;
943  currentCornerY += rectScaledHeight * cosAngle;
944  minY = minY < currentCornerY ? minY : currentCornerY;
945  currentCornerY += rectScaledWidth * sinAngle;
946  minY = minY < currentCornerY ? minY : currentCornerY;
947 
948  //now calculate offset position of rotated rectangle
949  double offsetX = ratioBoundsRotatedRect > ratioBoundsRect ? 0 : ( boundsWidth - rectScale * widthBoundsRotatedRect ) / 2.0;
950  offsetX += fabs( minX );
951  double offsetY = ratioBoundsRotatedRect > ratioBoundsRect ? ( boundsHeight - rectScale * heightBoundsRotatedRect ) / 2.0 : 0;
952  offsetY += fabs( minY );
953 
954  return QRectF( offsetX, offsetY, rectScaledWidth, rectScaledHeight );
955 }
956 
957 bool QgsComposerItem::imageSizeConsideringRotation( double& width, double& height, double rotation ) const
958 {
959  if ( qAbs( rotation ) <= 0.0 ) //width and height stays the same if there is no rotation
960  {
961  return true;
962  }
963 
964  if ( qgsDoubleNear( qAbs( rotation ), 90 ) || qgsDoubleNear( qAbs( rotation ), 270 ) )
965  {
966  double tmp = width;
967  width = height;
968  height = tmp;
969  return true;
970  }
971 
972  double x1 = 0;
973  double y1 = 0;
974  double x2 = width;
975  double y2 = 0;
976  double x3 = width;
977  double y3 = height;
978  double x4 = 0;
979  double y4 = height;
980  double midX = width / 2.0;
981  double midY = height / 2.0;
982 
983  if ( !cornerPointOnRotatedAndScaledRect( x1, y1, width, height, rotation ) )
984  {
985  return false;
986  }
987  if ( !cornerPointOnRotatedAndScaledRect( x2, y2, width, height, rotation ) )
988  {
989  return false;
990  }
991  if ( !cornerPointOnRotatedAndScaledRect( x3, y3, width, height, rotation ) )
992  {
993  return false;
994  }
995  if ( !cornerPointOnRotatedAndScaledRect( x4, y4, width, height, rotation ) )
996  {
997  return false;
998  }
999 
1000 
1001  //assume points 1 and 3 are on the rectangle boundaries. Calculate 2 and 4.
1002  double distM1 = sqrt(( x1 - midX ) * ( x1 - midX ) + ( y1 - midY ) * ( y1 - midY ) );
1003  QPointF p2 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( QPointF( midX, midY ), QPointF( x2, y2 ), distM1 );
1004 
1005  if ( p2.x() < width && p2.x() > 0 && p2.y() < height && p2.y() > 0 )
1006  {
1007  width = sqrt(( p2.x() - x1 ) * ( p2.x() - x1 ) + ( p2.y() - y1 ) * ( p2.y() - y1 ) );
1008  height = sqrt(( x3 - p2.x() ) * ( x3 - p2.x() ) + ( y3 - p2.y() ) * ( y3 - p2.y() ) );
1009  return true;
1010  }
1011 
1012  //else assume that points 2 and 4 are on the rectangle boundaries. Calculate 1 and 3
1013  double distM2 = sqrt(( x2 - midX ) * ( x2 - midX ) + ( y2 - midY ) * ( y2 - midY ) );
1014  QPointF p1 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( QPointF( midX, midY ), QPointF( x1, y1 ), distM2 );
1015  QPointF p3 = QgsSymbolLayerV2Utils::pointOnLineWithDistance( QPointF( midX, midY ), QPointF( x3, y3 ), distM2 );
1016  width = sqrt(( x2 - p1.x() ) * ( x2 - p1.x() ) + ( y2 - p1.y() ) * ( y2 - p1.y() ) );
1017  height = sqrt(( p3.x() - x2 ) * ( p3.x() - x2 ) + ( p3.y() - y2 ) * ( p3.y() - y2 ) );
1018  return true;
1019 }
1020 
1021 bool QgsComposerItem::cornerPointOnRotatedAndScaledRect( double& x, double& y, double width, double height ) const
1022 {
1023  //kept for api compatibility with QGIS 2.0, use item rotation
1024  return cornerPointOnRotatedAndScaledRect( x, y, width, height, mItemRotation );
1025 }
1026 
1027 bool QgsComposerItem::cornerPointOnRotatedAndScaledRect( double& x, double& y, double width, double height, double rotation ) const
1028 {
1029  //first rotate point clockwise
1030  double rotToRad = rotation * M_PI / 180.0;
1031  QPointF midpoint( width / 2.0, height / 2.0 );
1032  double xVector = x - midpoint.x();
1033  double yVector = y - midpoint.y();
1034  //double xRotated = cos(rotToRad) * xVector + sin(rotToRad) * yVector;
1035  //double yRotated = -sin(rotToRad) * xVector + cos(rotToRad) * yVector;
1036  double xRotated = cos( rotToRad ) * xVector - sin( rotToRad ) * yVector;
1037  double yRotated = sin( rotToRad ) * xVector + cos( rotToRad ) * yVector;
1038 
1039  //create line from midpoint to rotated point
1040  QLineF line( midpoint.x(), midpoint.y(), midpoint.x() + xRotated, midpoint.y() + yRotated );
1041 
1042  //intersect with all four borders and return result
1043  QList<QLineF> borders;
1044  borders << QLineF( 0, 0, width, 0 );
1045  borders << QLineF( width, 0, width, height );
1046  borders << QLineF( width, height, 0, height );
1047  borders << QLineF( 0, height, 0, 0 );
1048 
1049  QList<QLineF>::const_iterator it = borders.constBegin();
1050  QPointF intersectionPoint;
1051 
1052  for ( ; it != borders.constEnd(); ++it )
1053  {
1054  if ( line.intersect( *it, &intersectionPoint ) == QLineF::BoundedIntersection )
1055  {
1056  x = intersectionPoint.x();
1057  y = intersectionPoint.y();
1058  return true;
1059  }
1060  }
1061  return false;
1062 }
1063 
1064 void QgsComposerItem::sizeChangedByRotation( double& width, double& height )
1065 {
1066  //kept for api compatibility with QGIS 2.0, use item rotation
1067  return sizeChangedByRotation( width, height, mItemRotation );
1068 }
1069 
1070 void QgsComposerItem::sizeChangedByRotation( double& width, double& height, double rotation )
1071 {
1072  if ( rotation == 0.0 )
1073  {
1074  return;
1075  }
1076 
1077  //vector to p1
1078  double x1 = -width / 2.0;
1079  double y1 = -height / 2.0;
1080  rotate( rotation, x1, y1 );
1081  //vector to p2
1082  double x2 = width / 2.0;
1083  double y2 = -height / 2.0;
1084  rotate( rotation, x2, y2 );
1085  //vector to p3
1086  double x3 = width / 2.0;
1087  double y3 = height / 2.0;
1088  rotate( rotation, x3, y3 );
1089  //vector to p4
1090  double x4 = -width / 2.0;
1091  double y4 = height / 2.0;
1092  rotate( rotation, x4, y4 );
1093 
1094  //double midpoint
1095  QPointF midpoint( width / 2.0, height / 2.0 );
1096 
1097  QPolygonF rotatedRectPoly;
1098  rotatedRectPoly << QPointF( midpoint.x() + x1, midpoint.y() + y1 );
1099  rotatedRectPoly << QPointF( midpoint.x() + x2, midpoint.y() + y2 );
1100  rotatedRectPoly << QPointF( midpoint.x() + x3, midpoint.y() + y3 );
1101  rotatedRectPoly << QPointF( midpoint.x() + x4, midpoint.y() + y4 );
1102  QRectF boundingRect = rotatedRectPoly.boundingRect();
1103  width = boundingRect.width();
1104  height = boundingRect.height();
1105 }
1106 
1107 void QgsComposerItem::rotate( double angle, double& x, double& y ) const
1108 {
1109  double rotToRad = angle * M_PI / 180.0;
1110  double xRot, yRot;
1111  xRot = x * cos( rotToRad ) - y * sin( rotToRad );
1112  yRot = x * sin( rotToRad ) + y * cos( rotToRad );
1113  x = xRot;
1114  y = yRot;
1115 }
1116 
1118 {
1119  if ( !mHAlignSnapItem )
1120  {
1121  mHAlignSnapItem = new QGraphicsLineItem( 0 );
1122  mHAlignSnapItem->setPen( QPen( QColor( Qt::red ) ) );
1123  scene()->addItem( mHAlignSnapItem );
1124  mHAlignSnapItem->setZValue( 90 );
1125  }
1126  return mHAlignSnapItem;
1127 }
1128 
1130 {
1131  if ( !mVAlignSnapItem )
1132  {
1133  mVAlignSnapItem = new QGraphicsLineItem( 0 );
1134  mVAlignSnapItem->setPen( QPen( QColor( Qt::red ) ) );
1135  scene()->addItem( mVAlignSnapItem );
1136  mVAlignSnapItem->setZValue( 90 );
1137  }
1138  return mVAlignSnapItem;
1139 }
1140 
1142 {
1143  if ( mHAlignSnapItem )
1144  {
1145  scene()->removeItem( mHAlignSnapItem );
1146  delete mHAlignSnapItem;
1147  mHAlignSnapItem = 0;
1148  }
1149 }
1150 
1152 {
1153  if ( mVAlignSnapItem )
1154  {
1155  scene()->removeItem( mVAlignSnapItem );
1156  delete mVAlignSnapItem;
1157  mVAlignSnapItem = 0;
1158  }
1159 }
1160 
1162 {
1165 }
1166 
1168 {
1169  update();
1170 }
1171 
1172 void QgsComposerItem::setId( const QString& id )
1173 {
1174  setToolTip( id );
1175  mId = id;
1176 }
bool positionLock() const
Returns position lock for mouse drags (true means locked)
bool effectsEnabled() const
Returns true if effects (eg blend modes) are enabled for the item.
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
int mTransparency
Item transparency.
void setEffectsEnabled(bool effectsEnabled)
Sets whether effects (eg blend modes) are enabled for the item.
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.
static const QString activeThemePath()
Returns the path to the currently active theme directory.
double pixelFontSize(double pointSize) const
Calculates font to from point size to pixel 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.
virtual bool removeSettings()
delete settings from project file
#define QgsDebugMsg(str)
Definition: qgslogger.h:36
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.
void removeItemFromZList(QgsComposerItem *item)
Removes item from z list.
#define FONT_WORKAROUND_SCALE
double mLastValidViewScaleFactor
Backup to restore item appearance if no view scale factor is available.
ItemPositionMode mLastUsedPositionMode
The item's position mode.
virtual void setSelected(bool s)
Set selected, selected item should be highlighted.
virtual void drawFrame(QPainter *p)
Draw black frame around item.
QColor backgroundColor() const
Gets the background color for this item.
QPainter::CompositionMode mBlendMode
Composition blend mode for item.
void setCompositionMode(const QPainter::CompositionMode &compositionMode)
double spaceBetweenPages() const
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Definition: qgis.h:324
BlendMode
Blending modes enum defining the available composition modes that can be used when rendering a layer...
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.
double fontDescentMillimeters(const QFont &font) const
Returns the font descent in Millimeters (considers upscaling and downscaling with FONT_WORKAROUND_SCA...
void setTransparency(int transparency)
Sets the item's transparency.
void frameChanged()
Emitted if the item's frame style changes.
double horizontalViewScaleFactor() const
Returns the zoom factor of the graphics view.
void cancelCommand()
Deletes current command.
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 drawSelectionBoxes(QPainter *p)
Draw selection boxes around item.
double textWidthMillimeters(const QFont &font, const QString &text) const
Returns the font width in millimeters (considers upscaling and downscaling with FONT_WORKAROUND_SCALE...
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.
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.
void endCommand()
Finish current command and push it onto the undo stack.
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
virtual void setFrameOutlineWidth(double outlineWidth)
Sets frame outline width.
#define M_PI
static const QString defaultThemePath()
Returns the path to the default theme directory.
virtual bool writeSettings()
stores state in project
virtual ~QgsComposerItem()
void drawText(QPainter *p, double x, double y, const QString &text, const QFont &font) const
Draws Text.
void beginCommand(const QString &commandText, QgsComposerMergeCommand::Context c=QgsComposerMergeCommand::Unknown)
Starts new composer undo command.
void setFrameJoinStyle(Qt::PenJoinStyle style)
Sets join style used when drawing the item's frame.
QgsComposition * mComposition
Graphics scene for map printing.
virtual void setItemRotation(double r, bool adjustPosition=false)
Sets the item rotation.
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)
void setPositionLock(bool lock)
Locks / unlocks the item position for mouse drags.
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 Added in 1.9.
Qt::PenJoinStyle mFrameJoinStyle
Frame join style.
QColor mBackgroundColor
Background color.
QGraphicsLineItem * mVAlignSnapItem
bool cornerPointOnRotatedAndScaledRect(double &x, double &y, double width, double height, double rotation) const
Calculates corner point after rotation and scaling.
QGraphicsLineItem * mHAlignSnapItem
virtual bool readSettings()
read state from project
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 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)
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...
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.
const QgsComposition * composition() const
double paperHeight() const
Returns height of paper item.
int page() const
Gets the page the item is currently on.
static Qt::PenJoinStyle decodePenJoinStyle(QString str)
void setBlendMode(QPainter::CompositionMode blendMode)
Sets the item's composition blending mode.
static QgsMapRenderer::BlendMode getBlendModeEnum(const QPainter::CompositionMode &blendMode)
Returns a BlendMode corresponding to a QPainter::CompositionMode Added in 1.9.
QgsComposerEffect * mEffect
void drawArrowHead(QPainter *p, double x, double y, double angle, double arrowHeadWidth) const
Draws arrowhead.
QgsComposerItem(QgsComposition *composition, bool manageZValue=true)
Constructor.
void init(bool manageZValue)
QgsComposition::PlotStyle plotStyle() const
double rectHandlerBorderTolerance() const
Returns the current (zoom level dependent) tolerance to decide if mouse position is close enough to t...
#define M_DEG2RAD
void setFrameEnabled(bool drawFrame)
Set whether this item has a frame drawn around it or not.
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.
double mItemRotation
Item rotation in degrees, clockwise.
QGraphicsLineItem * vAlignSnapItem()
Return vertical align snap item.
double fontAscentMillimeters(const QFont &font) const
Returns the font ascent in Millimeters (considers upscaling and downscaling with FONT_WORKAROUND_SCAL...
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, QgsComposerMergeCommand::Context c=QgsComposerMergeCommand::Unknown)
Allocates new item command and saves initial state in it.
QString id() const
Get item's id (which is not necessarly unique)