QGIS API Documentation  2.7.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
qgscomposerarrow.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscomposerarrow.cpp
3  ----------------------
4  begin : November 2009
5  copyright : (C) 2009 by Marco Hugentobler
6  email : marco@hugis.net
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 
18 #include "qgscomposerarrow.h"
19 #include "qgscomposition.h"
20 #include "qgscomposerutils.h"
21 #include "qgssymbollayerv2utils.h"
22 #include <QPainter>
23 #include <QSvgRenderer>
24 #include <QVector2D>
25 
26 #include <cmath>
27 
29  : QgsComposerItem( c )
30  , mStartPoint( 0, 0 )
31  , mStopPoint( 0, 0 )
32  , mStartXIdx( 0 )
33  , mStartYIdx( 0 )
34  , mMarkerMode( DefaultMarker )
35  , mArrowHeadOutlineWidth( 1.0 )
36  , mArrowHeadOutlineColor( Qt::black )
37  , mArrowHeadFillColor( Qt::black )
38  , mBoundsBehaviour( 24 )
39  , mLineSymbol( 0 )
40 {
41  init();
42 }
43 
44 QgsComposerArrow::QgsComposerArrow( const QPointF& startPoint, const QPointF& stopPoint, QgsComposition* c )
45  : QgsComposerItem( c )
46  , mStartPoint( startPoint )
47  , mStopPoint( stopPoint )
48  , mMarkerMode( DefaultMarker )
49  , mArrowHeadOutlineWidth( 1.0 )
50  , mArrowHeadOutlineColor( Qt::black )
51  , mArrowHeadFillColor( Qt::black )
52  , mBoundsBehaviour( 24 )
53  , mLineSymbol( 0 )
54 {
55  mStartXIdx = mStopPoint.x() < mStartPoint.x();
56  mStartYIdx = mStopPoint.y() < mStartPoint.y();
57  init();
58  adaptItemSceneRect();
59 }
60 
62 {
63  delete mLineSymbol;
64 }
65 
66 void QgsComposerArrow::init()
67 {
68  setArrowHeadWidth( 4 );
69  mPen.setColor( mArrowHeadOutlineColor );
70  mPen.setWidthF( 1 );
71  mBrush.setColor( mArrowHeadFillColor );
72  createDefaultLineSymbol();
73 
74  //default to no background
75  setBackgroundEnabled( false );
76 }
77 
78 
79 void QgsComposerArrow::createDefaultLineSymbol()
80 {
81  delete mLineSymbol;
82  QgsStringMap properties;
83  properties.insert( "color", "0,0,0,255" );
84  properties.insert( "width", "1" );
85  properties.insert( "capstyle", "square" );
86  mLineSymbol = QgsLineSymbolV2::createSimple( properties );
87 }
88 
89 void QgsComposerArrow::paint( QPainter* painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget )
90 {
91  Q_UNUSED( itemStyle );
92  Q_UNUSED( pWidget );
93  if ( !painter || !painter->device() )
94  {
95  return;
96  }
97  if ( !shouldDrawItem() )
98  {
99  return;
100  }
101 
102  drawBackground( painter );
103 
104  painter->save();
105  //antialiasing on
106  painter->setRenderHint( QPainter::Antialiasing, true );
107 
108  //draw line section
109  drawLine( painter );
110 
111  //draw arrowhead if required
112  if ( mMarkerMode != NoMarker )
113  {
114  painter->setBrush( mBrush );
115  painter->setPen( mPen );
116 
117  if ( mMarkerMode == DefaultMarker )
118  {
119  drawHardcodedMarker( painter, EndMarker );
120  }
121  else if ( mMarkerMode == SVGMarker )
122  {
123  drawSVGMarker( painter, StartMarker, mStartMarkerFile );
124  drawSVGMarker( painter, EndMarker, mEndMarkerFile );
125  }
126  }
127 
128  painter->restore();
129 
130  drawFrame( painter );
131  if ( isSelected() )
132  {
133  drawSelectionBoxes( painter );
134  }
135 }
136 
137 void QgsComposerArrow::setSceneRect( const QRectF& rectangle )
138 {
139  //update rect for data defined size and position
140  QRectF evaluatedRect = evalItemRect( rectangle );
141 
142  if ( evaluatedRect.width() < 0 )
143  {
144  mStartXIdx = 1 - mStartXIdx;
145  }
146  if ( evaluatedRect.height() < 0 )
147  {
148  mStartYIdx = 1 - mStartYIdx;
149  }
150 
151  double margin = computeMarkerMargin();
152 
153  // Ensure the rectangle is at least as large as needed to include the markers
154  QRectF rect = rectangle.united( QRectF( evaluatedRect.x(), evaluatedRect.y(), 2. * margin, 2. * margin ) );
155 
156  // Compute new start and stop positions
157  double x[2] = {rect.x(), rect.x() + rect.width()};
158  double y[2] = {rect.y(), rect.y() + rect.height()};
159 
160  double xsign = x[mStartXIdx] < x[1 - mStartXIdx] ? 1.0 : -1.0;
161  double ysign = y[mStartYIdx] < y[1 - mStartYIdx] ? 1.0 : -1.0;
162 
163  mStartPoint = QPointF( x[mStartXIdx] + xsign * margin, y[mStartYIdx] + ysign * margin );
164  mStopPoint = QPointF( x[1 - mStartXIdx] - xsign * margin, y[1 - mStartYIdx] - ysign * margin );
165 
167 }
168 
169 void QgsComposerArrow::drawLine( QPainter *painter )
170 {
171  if ( ! mLineSymbol || ! mComposition )
172  {
173  return;
174  }
175 
176  QPaintDevice* thePaintDevice = painter->device();
177  painter->save();
178  //setup painter scaling to dots so that raster symbology is drawn to scale
179  double dotsPerMM = thePaintDevice->logicalDpiX() / 25.4;
180  painter->scale( 1 / dotsPerMM, 1 / dotsPerMM ); //scale painter from mm to dots
181 
182  //setup render context
184  //context units should be in dots
185  ms.setOutputDpi( painter->device()->logicalDpiX() );
187  context.setForceVectorOutput( true );
188  context.setPainter( painter );
189 
190  //line scaled to dots
191  QPolygonF line;
192  line << QPointF( mStartPoint.x() - pos().x(), mStartPoint.y() - pos().y() ) * dotsPerMM
193  << QPointF( mStopPoint.x() - pos().x(), mStopPoint.y() - pos().y() ) * dotsPerMM;
194 
195  mLineSymbol->startRender( context );
196  mLineSymbol->renderPolyline( line, 0, context );
197  mLineSymbol->stopRender( context );
198  painter->restore();
199 
200 }
201 
202 void QgsComposerArrow::drawHardcodedMarker( QPainter *p, MarkerType type )
203 {
204  Q_UNUSED( type );
205  if ( mBoundsBehaviour == 22 )
206  {
207  //if arrow was created in versions prior to 2.4, use the old rendering style
208  QgsComposerUtils::drawArrowHead( p, mStopPoint.x() - pos().x(), mStopPoint.y() - pos().y(), QgsComposerUtils::angle( mStartPoint, mStopPoint ), mArrowHeadWidth );
209  }
210  else
211  {
212  QVector2D dir = QVector2D( mStopPoint - mStartPoint ).normalized();
213  QPointF stop = mStopPoint + ( dir * 0.5 * mArrowHeadWidth ).toPointF();
214  QgsComposerUtils::drawArrowHead( p, stop.x() - pos().x(), stop.y() - pos().y(), QgsComposerUtils::angle( mStartPoint, stop ), mArrowHeadWidth );
215  }
216 }
217 
218 void QgsComposerArrow::drawSVGMarker( QPainter* p, MarkerType type, const QString &markerPath )
219 {
220  Q_UNUSED( markerPath );
221  double ang = QgsComposerUtils::angle( mStartPoint, mStopPoint );
222 
223  double arrowHeadHeight;
224  if ( type == StartMarker )
225  {
226  arrowHeadHeight = mStartArrowHeadHeight;
227  }
228  else
229  {
230  arrowHeadHeight = mStopArrowHeadHeight;
231  }
232  if ( mArrowHeadWidth <= 0 || arrowHeadHeight <= 0 )
233  {
234  //bad image size
235  return;
236  }
237 
238  QPointF imageFixPoint;
239  imageFixPoint.setX( mArrowHeadWidth / 2.0 );
240  QPointF canvasPoint;
241  if ( type == StartMarker )
242  {
243  canvasPoint = QPointF( mStartPoint.x() - pos().x(), mStartPoint.y() - pos().y() );
244  imageFixPoint.setY( mStartArrowHeadHeight );
245  }
246  else //end marker
247  {
248  canvasPoint = QPointF( mStopPoint.x() - pos().x(), mStopPoint.y() - pos().y() );
249  imageFixPoint.setY( 0 );
250  }
251 
252  //rasterize svg
253  QSvgRenderer r;
254  if ( type == StartMarker )
255  {
256  if ( mStartMarkerFile.isEmpty() || !r.load( mStartMarkerFile ) )
257  {
258  return;
259  }
260  }
261  else //end marker
262  {
263  if ( mEndMarkerFile.isEmpty() || !r.load( mEndMarkerFile ) )
264  {
265  return;
266  }
267  }
268 
269  p->save();
270  p->setRenderHint( QPainter::Antialiasing );
271  if ( mBoundsBehaviour == 22 )
272  {
273  //if arrow was created in versions prior to 2.4, use the old rendering style
274  //rotate image fix point for backtransform
275  QPointF fixPoint;
276  if ( type == StartMarker )
277  {
278  fixPoint.setX( 0 ); fixPoint.setY( arrowHeadHeight / 2.0 );
279  }
280  else
281  {
282  fixPoint.setX( 0 ); fixPoint.setY( -arrowHeadHeight / 2.0 );
283  }
284  QPointF rotatedFixPoint;
285  double angleRad = ang / 180 * M_PI;
286  rotatedFixPoint.setX( fixPoint.x() * cos( angleRad ) + fixPoint.y() * -sin( angleRad ) );
287  rotatedFixPoint.setY( fixPoint.x() * sin( angleRad ) + fixPoint.y() * cos( angleRad ) );
288  p->translate( canvasPoint.x() - rotatedFixPoint.x(), canvasPoint.y() - rotatedFixPoint.y() );
289  }
290  else
291  {
292  p->translate( canvasPoint.x(), canvasPoint.y() );
293  }
294 
295  p->rotate( ang );
296  p->translate( -mArrowHeadWidth / 2.0, -arrowHeadHeight / 2.0 );
297  r.render( p, QRectF( 0, 0, mArrowHeadWidth, arrowHeadHeight ) );
298  p->restore();
299 
300  return;
301 }
302 
303 void QgsComposerArrow::setStartMarker( const QString& svgPath )
304 {
305  QSvgRenderer r;
306  mStartMarkerFile = svgPath;
307  if ( svgPath.isEmpty() || !r.load( svgPath ) )
308  {
309  mStartArrowHeadHeight = 0;
310  }
311  else
312  {
313  //calculate mArrowHeadHeight from svg file and mArrowHeadWidth
314  QRect viewBox = r.viewBox();
315  mStartArrowHeadHeight = mArrowHeadWidth / viewBox.width() * viewBox.height();
316  }
317  adaptItemSceneRect();
318 }
319 
320 void QgsComposerArrow::setEndMarker( const QString& svgPath )
321 {
322  QSvgRenderer r;
323  mEndMarkerFile = svgPath;
324  if ( svgPath.isEmpty() || !r.load( svgPath ) )
325  {
326  mStopArrowHeadHeight = 0;
327  }
328  else
329  {
330  //calculate mArrowHeadHeight from svg file and mArrowHeadWidth
331  QRect viewBox = r.viewBox();
332  mStopArrowHeadHeight = mArrowHeadWidth / viewBox.width() * viewBox.height();
333  }
334  adaptItemSceneRect();
335 }
336 
338 {
339  if ( mLineSymbol )
340  {
341  return mLineSymbol->color();
342  }
343 
344  return Qt::black;
345 }
346 
347 void QgsComposerArrow::setArrowColor( const QColor &c )
348 {
349  if ( mLineSymbol )
350  {
351  mLineSymbol->setColor( c );
352  }
353  mArrowHeadOutlineColor = c;
354  mArrowHeadFillColor = c;
355  mPen.setColor( c );
356  mBrush.setColor( c );
357 }
358 
360 {
361  mArrowHeadOutlineColor = color;
362  mPen.setColor( color );
363 }
364 
365 void QgsComposerArrow::setArrowHeadFillColor( const QColor &color )
366 {
367  mArrowHeadFillColor = color;
368  mBrush.setColor( color );
369 }
370 
372 {
373  if ( mLineSymbol )
374  {
375  mLineSymbol->setWidth( width );
376  }
377  mArrowHeadOutlineWidth = width;
378  mPen.setWidthF( mArrowHeadOutlineWidth );
379 
380  adaptItemSceneRect();
381 }
382 
384 {
385  if ( mLineSymbol )
386  {
387  return mLineSymbol->width();
388  }
389 
390  return 0;
391 }
392 
394 {
395  mArrowHeadOutlineWidth = width;
396  mPen.setWidthF( mArrowHeadOutlineWidth );
397 
398  adaptItemSceneRect();
399 }
400 
402 {
403  delete mLineSymbol;
404  mLineSymbol = symbol;
405 }
406 
408 {
409  mArrowHeadWidth = width;
410  setStartMarker( mStartMarkerFile );
411  setEndMarker( mEndMarkerFile );
412  adaptItemSceneRect();
413 }
414 
415 double QgsComposerArrow::computeMarkerMargin() const
416 {
417  double margin = 0;
418 
419  if ( mBoundsBehaviour == 22 )
420  {
421  //if arrow was created in versions prior to 2.4, use the old rendering style
422  if ( mMarkerMode == DefaultMarker )
423  {
424  margin = mPen.widthF() / 2.0 + mArrowHeadWidth / 2.0;
425  }
426  else if ( mMarkerMode == NoMarker )
427  {
428  margin = mPen.widthF() / 2.0;
429  }
430  else if ( mMarkerMode == SVGMarker )
431  {
432  double maxArrowHeight = qMax( mStartArrowHeadHeight, mStopArrowHeadHeight );
433  margin = mPen.widthF() / 2 + qMax( mArrowHeadWidth / 2.0, maxArrowHeight / 2.0 );
434  }
435  }
436  else
437  {
438  if ( mMarkerMode == DefaultMarker )
439  {
440  margin = mPen.widthF() / std::sqrt( 2.0 ) + mArrowHeadWidth / 2.0;
441  }
442  else if ( mMarkerMode == NoMarker )
443  {
444  margin = mPen.widthF() / std::sqrt( 2.0 );
445  }
446  else if ( mMarkerMode == SVGMarker )
447  {
448  double startMarkerMargin = std::sqrt( 0.25 * ( mStartArrowHeadHeight * mStartArrowHeadHeight + mArrowHeadWidth * mArrowHeadWidth ) );
449  double stopMarkerMargin = std::sqrt( 0.25 * ( mStopArrowHeadHeight * mStopArrowHeadHeight + mArrowHeadWidth * mArrowHeadWidth ) );
450  double markerMargin = qMax( startMarkerMargin, stopMarkerMargin );
451  margin = qMax( mPen.widthF() / std::sqrt( 2.0 ), markerMargin );
452  }
453  }
454  return margin;
455 }
456 
457 void QgsComposerArrow::adaptItemSceneRect()
458 {
459  //rectangle containing start and end point
460  QRectF rect = QRectF( qMin( mStartPoint.x(), mStopPoint.x() ), qMin( mStartPoint.y(), mStopPoint.y() ),
461  qAbs( mStopPoint.x() - mStartPoint.x() ), qAbs( mStopPoint.y() - mStartPoint.y() ) );
462  double enlarge = computeMarkerMargin();
463  rect.adjust( -enlarge, -enlarge, enlarge, enlarge );
465 }
466 
468 {
469  mMarkerMode = mode;
470  adaptItemSceneRect();
471 }
472 
473 bool QgsComposerArrow::writeXML( QDomElement& elem, QDomDocument & doc ) const
474 {
475  QDomElement composerArrowElem = doc.createElement( "ComposerArrow" );
476  composerArrowElem.setAttribute( "arrowHeadWidth", QString::number( mArrowHeadWidth ) );
477  composerArrowElem.setAttribute( "arrowHeadFillColor", QgsSymbolLayerV2Utils::encodeColor( mArrowHeadFillColor ) );
478  composerArrowElem.setAttribute( "arrowHeadOutlineColor", QgsSymbolLayerV2Utils::encodeColor( mArrowHeadOutlineColor ) );
479  composerArrowElem.setAttribute( "outlineWidth", QString::number( mArrowHeadOutlineWidth ) );
480  composerArrowElem.setAttribute( "markerMode", mMarkerMode );
481  composerArrowElem.setAttribute( "startMarkerFile", mStartMarkerFile );
482  composerArrowElem.setAttribute( "endMarkerFile", mEndMarkerFile );
483  composerArrowElem.setAttribute( "boundsBehaviourVersion", QString::number( mBoundsBehaviour ) );
484 
485  QDomElement styleElem = doc.createElement( "lineStyle" );
486  QDomElement lineStyleElem = QgsSymbolLayerV2Utils::saveSymbol( QString(), mLineSymbol, doc );
487  styleElem.appendChild( lineStyleElem );
488  composerArrowElem.appendChild( styleElem );
489 
490  //start point
491  QDomElement startPointElem = doc.createElement( "StartPoint" );
492  startPointElem.setAttribute( "x", QString::number( mStartPoint.x() ) );
493  startPointElem.setAttribute( "y", QString::number( mStartPoint.y() ) );
494  composerArrowElem.appendChild( startPointElem );
495 
496  //stop point
497  QDomElement stopPointElem = doc.createElement( "StopPoint" );
498  stopPointElem.setAttribute( "x", QString::number( mStopPoint.x() ) );
499  stopPointElem.setAttribute( "y", QString::number( mStopPoint.y() ) );
500  composerArrowElem.appendChild( stopPointElem );
501 
502  elem.appendChild( composerArrowElem );
503  return _writeXML( composerArrowElem, doc );
504 }
505 
506 bool QgsComposerArrow::readXML( const QDomElement& itemElem, const QDomDocument& doc )
507 {
508  mArrowHeadWidth = itemElem.attribute( "arrowHeadWidth", "2.0" ).toDouble();
509  mArrowHeadFillColor = QgsSymbolLayerV2Utils::decodeColor( itemElem.attribute( "arrowHeadFillColor", "0,0,0,255" ) );
510  mArrowHeadOutlineColor = QgsSymbolLayerV2Utils::decodeColor( itemElem.attribute( "arrowHeadOutlineColor", "0,0,0,255" ) );
511  mArrowHeadOutlineWidth = itemElem.attribute( "outlineWidth", "1.0" ).toDouble();
512  setStartMarker( itemElem.attribute( "startMarkerFile", "" ) );
513  setEndMarker( itemElem.attribute( "endMarkerFile", "" ) );
514  mMarkerMode = QgsComposerArrow::MarkerMode( itemElem.attribute( "markerMode", "0" ).toInt() );
515  //if bounds behaviour version is not set, default to 2.2 behaviour
516  mBoundsBehaviour = itemElem.attribute( "boundsBehaviourVersion", "22" ).toInt();
517 
518  //arrow style
519  QDomElement styleElem = itemElem.firstChildElement( "lineStyle" );
520  if ( !styleElem.isNull() )
521  {
522  QDomElement lineStyleElem = styleElem.firstChildElement( "symbol" );
523  if ( !lineStyleElem.isNull() )
524  {
525  delete mLineSymbol;
526  mLineSymbol = dynamic_cast<QgsLineSymbolV2*>( QgsSymbolLayerV2Utils::loadSymbol( lineStyleElem ) );
527  }
528  }
529  else
530  {
531  //old project file, read arrow width and color
532  delete mLineSymbol;
533 
534  QgsStringMap properties;
535  properties.insert( "width", itemElem.attribute( "outlineWidth", "1.0" ) );
536 
537  if ( mBoundsBehaviour == 22 )
538  {
539  //if arrow was created in versions prior to 2.4, use the old rendering style
540  properties.insert( "capstyle", "flat" );
541  }
542  else
543  {
544  properties.insert( "capstyle", "square" );
545  }
546  int red = 0;
547  int blue = 0;
548  int green = 0;
549  int alpha = 255;
550 
551  QDomNodeList arrowColorList = itemElem.elementsByTagName( "ArrowColor" );
552  if ( arrowColorList.size() > 0 )
553  {
554  QDomElement arrowColorElem = arrowColorList.at( 0 ).toElement();
555  red = arrowColorElem.attribute( "red", "0" ).toInt();
556  green = arrowColorElem.attribute( "green", "0" ).toInt();
557  blue = arrowColorElem.attribute( "blue", "0" ).toInt();
558  alpha = arrowColorElem.attribute( "alpha", "255" ).toInt();
559  mArrowHeadFillColor = QColor( red, green, blue, alpha );
560  mArrowHeadOutlineColor = QColor( red, green, blue, alpha );
561  }
562  properties.insert( "color", QString( "%1,%2,%3,%4" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
563  mLineSymbol = QgsLineSymbolV2::createSimple( properties );
564  }
565 
566  mPen.setColor( mArrowHeadOutlineColor );
567  mPen.setWidthF( mArrowHeadOutlineWidth );
568  mBrush.setColor( mArrowHeadFillColor );
569 
570  //restore general composer item properties
571  //needs to be before start point / stop point because setSceneRect()
572  QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" );
573  if ( composerItemList.size() > 0 )
574  {
575  QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
576  _readXML( composerItemElem, doc );
577  }
578 
579  //start point
580  QDomNodeList startPointList = itemElem.elementsByTagName( "StartPoint" );
581  if ( startPointList.size() > 0 )
582  {
583  QDomElement startPointElem = startPointList.at( 0 ).toElement();
584  mStartPoint.setX( startPointElem.attribute( "x", "0.0" ).toDouble() );
585  mStartPoint.setY( startPointElem.attribute( "y", "0.0" ).toDouble() );
586  }
587 
588  //stop point
589  QDomNodeList stopPointList = itemElem.elementsByTagName( "StopPoint" );
590  if ( stopPointList.size() > 0 )
591  {
592  QDomElement stopPointElem = stopPointList.at( 0 ).toElement();
593  mStopPoint.setX( stopPointElem.attribute( "x", "0.0" ).toDouble() );
594  mStopPoint.setY( stopPointElem.attribute( "y", "0.0" ).toDouble() );
595  }
596 
597  mStartXIdx = mStopPoint.x() < mStartPoint.x();
598  mStartYIdx = mStopPoint.y() < mStartPoint.y();
599 
600  adaptItemSceneRect();
601  emit itemChanged();
602  return true;
603 }
604 
605 
QgsComposerArrow(QgsComposition *c)
Constructor.
void setForceVectorOutput(bool force)
Q_DECL_DEPRECATED void setOutlineWidth(double width)
Sets the pen width for drawing the line and arrow head.
void setOutputDpi(int dpi)
Set DPI used for conversion between real world units (e.g. mm) and pixels.
void itemChanged()
Emitted when the item changes.
const QgsMapSettings & mapSettings() const
Return setting of QGIS map canvas.
A item that forms part of a map composition.
void setStartMarker(const QString &svgPath)
Sets the marker to draw at the start of the line.
static QColor decodeColor(QString str)
virtual void drawFrame(QPainter *p)
Draw black frame around item.
void setArrowHeadWidth(double width)
Sets the width of the arrow head in mm.
QMap< QString, QString > QgsStringMap
Definition: qgis.h:412
void setWidth(double width)
void setArrowHeadOutlineWidth(const double width)
Sets the pen width for the outline of the arrow head.
Q_DECL_DEPRECATED double outlineWidth() const
Returns the pen width for drawing the line and arrow head.
static QString encodeColor(QColor color)
The QgsMapSettings class contains configuration for rendering of the map.
bool _readXML(const QDomElement &itemElem, const QDomDocument &doc)
Reads parameter that are not subclass specific in document.
static QDomElement saveSymbol(QString symbolName, QgsSymbolV2 *symbol, QDomDocument &doc)
void setColor(const QColor &color)
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.
Q_DECL_DEPRECATED QColor arrowColor() const
Returns the color for the line and arrow head.
void startRender(QgsRenderContext &context, const QgsFields *fields=0)
virtual void drawSelectionBoxes(QPainter *p)
Draws additional graphics on selected items.
static QgsLineSymbolV2 * createSimple(const QgsStringMap &properties)
Create a line symbol with one symbol layer: SimpleLine with specified properties. ...
void renderPolyline(const QPolygonF &points, const QgsFeature *f, QgsRenderContext &context, int layer=-1, bool selected=false)
#define M_PI
void setPainter(QPainter *p)
void setArrowHeadOutlineColor(const QColor &color)
Sets the color used to draw the outline around the arrow head.
void paint(QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget)
Reimplementation of QCanvasItem::paint - draw on canvas.
bool readXML(const QDomElement &itemElem, const QDomDocument &doc)
Sets state from DOM document.
void setLineSymbol(QgsLineSymbolV2 *symbol)
Sets the line symbol used for drawing the line portion of the arrow.
void setMarkerMode(MarkerMode mode)
Sets the marker mode, which controls how the arrow endpoints are drawn.
Q_DECL_DEPRECATED void setArrowColor(const QColor &c)
Sets the color for the line and arrow head.
bool shouldDrawItem() const
Returns whether the item should be drawn in the current context.
void setBackgroundEnabled(const bool drawBackground)
Set whether this item has a Background drawn around it or not.
void setArrowHeadFillColor(const QColor &color)
Sets the color used to fill the arrow head.
Graphics scene for map printing.
void setSceneRect(const QRectF &rectangle)
Modifies position of start and endpoint and calls QgsComposerItem::setSceneRect.
QgsComposition * mComposition
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...
Contains information about the context of a rendering operation.
void stopRender(QgsRenderContext &context)
bool _writeXML(QDomElement &itemElem, QDomDocument &doc) const
Writes parameter that are not subclass specific in document.
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
virtual void drawBackground(QPainter *p)
Draw background.
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...
static QgsSymbolV2 * loadSymbol(QDomElement &element)
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 setEndMarker(const QString &svgPath)
Sets the marker to draw at the end of the line.
bool writeXML(QDomElement &elem, QDomDocument &doc) const
Stores state in DOM element.
QColor color() const