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