24 #include <QSvgRenderer> 35 , mMarkerMode( DefaultMarker )
36 , mArrowHeadOutlineWidth( 1.0 )
37 , mArrowHeadOutlineColor(
Qt::black )
38 , mArrowHeadFillColor(
Qt::black )
39 , mBoundsBehaviour( 24 )
40 , mLineSymbol( nullptr )
47 , mStartPoint( startPoint )
48 , mStopPoint( stopPoint )
50 , mArrowHeadOutlineWidth( 1.0 )
51 , mArrowHeadOutlineColor(
Qt::black )
52 , mArrowHeadFillColor(
Qt::black )
53 , mBoundsBehaviour( 24 )
54 , mLineSymbol( nullptr )
56 mStartXIdx = mStopPoint.
x() < mStartPoint.
x();
57 mStartYIdx = mStopPoint.
y() < mStartPoint.
y();
67 void QgsComposerArrow::init()
70 mPen.
setColor( mArrowHeadOutlineColor );
72 mBrush.
setColor( mArrowHeadFillColor );
73 createDefaultLineSymbol();
80 void QgsComposerArrow::createDefaultLineSymbol()
84 properties.
insert(
"color",
"0,0,0,255" );
85 properties.
insert(
"width",
"1" );
86 properties.
insert(
"capstyle",
"square" );
92 Q_UNUSED( itemStyle );
94 if ( !painter || !painter->
device() )
120 drawHardcodedMarker( painter, EndMarker );
124 drawSVGMarker( painter, StartMarker, mStartMarkerFile );
125 drawSVGMarker( painter, EndMarker, mEndMarkerFile );
143 if ( evaluatedRect.
width() < 0 )
145 mStartXIdx = 1 - mStartXIdx;
147 if ( evaluatedRect.
height() < 0 )
149 mStartYIdx = 1 - mStartYIdx;
152 double margin = computeMarkerMargin();
158 double x[2] = {rect.
x(), rect.
x() + rect.
width()};
159 double y[2] = {rect.
y(), rect.
y() + rect.
height()};
161 double xsign = x[mStartXIdx] < x[1 - mStartXIdx] ? 1.0 : -1.0;
162 double ysign = y[mStartYIdx] < y[1 - mStartYIdx] ? 1.0 : -1.0;
164 mStartPoint =
QPointF( x[mStartXIdx] + xsign * margin, y[mStartYIdx] + ysign * margin );
165 mStopPoint =
QPointF( x[1 - mStartXIdx] - xsign * margin, y[1 - mStartYIdx] - ysign * margin );
170 void QgsComposerArrow::drawLine(
QPainter *painter )
180 double dotsPerMM = thePaintDevice->
logicalDpiX() / 25.4;
181 painter->
scale( 1 / dotsPerMM, 1 / dotsPerMM );
192 delete expressionContext;
196 line <<
QPointF( mStartPoint.
x() -
pos().
x(), mStartPoint.
y() -
pos().
y() ) * dotsPerMM
197 <<
QPointF( mStopPoint.
x() -
pos().
x(), mStopPoint.
y() -
pos().
y() ) * dotsPerMM;
206 void QgsComposerArrow::drawHardcodedMarker(
QPainter *p, MarkerType
type )
209 if ( mBoundsBehaviour == 22 )
217 QPointF stop = mStopPoint + ( dir * 0.5 * mArrowHeadWidth ).toPointF();
222 void QgsComposerArrow::drawSVGMarker(
QPainter* p, MarkerType
type,
const QString &markerPath )
224 Q_UNUSED( markerPath );
227 double arrowHeadHeight;
228 if (
type == StartMarker )
230 arrowHeadHeight = mStartArrowHeadHeight;
234 arrowHeadHeight = mStopArrowHeadHeight;
236 if ( mArrowHeadWidth <= 0 || arrowHeadHeight <= 0 )
243 imageFixPoint.
setX( mArrowHeadWidth / 2.0 );
245 if (
type == StartMarker )
247 canvasPoint =
QPointF( mStartPoint.
x() -
pos().
x(), mStartPoint.
y() -
pos().
y() );
248 imageFixPoint.
setY( mStartArrowHeadHeight );
253 imageFixPoint.
setY( 0 );
256 QString svgFileName = (
type == StartMarker ? mStartMarkerFile : mEndMarkerFile );
263 r.
load( svgContent );
267 if ( mBoundsBehaviour == 22 )
272 if (
type == StartMarker )
275 fixPoint.
setY( arrowHeadHeight / 2.0 );
280 fixPoint.
setY( -arrowHeadHeight / 2.0 );
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() );
294 p->
translate( -mArrowHeadWidth / 2.0, -arrowHeadHeight / 2.0 );
295 r.
render( p,
QRectF( 0, 0, mArrowHeadWidth, arrowHeadHeight ) );
304 mStartMarkerFile = svgPath;
307 mStartArrowHeadHeight = 0;
313 mStartArrowHeadHeight = mArrowHeadWidth / viewBox.
width() * viewBox.
height();
315 adaptItemSceneRect();
321 mEndMarkerFile = svgPath;
324 mStopArrowHeadHeight = 0;
330 mStopArrowHeadHeight = mArrowHeadWidth / viewBox.
width() * viewBox.
height();
332 adaptItemSceneRect();
339 return mLineSymbol->
color();
351 mArrowHeadOutlineColor = c;
352 mArrowHeadFillColor = c;
359 mArrowHeadOutlineColor = color;
365 mArrowHeadFillColor = color;
375 mArrowHeadOutlineWidth = width;
376 mPen.
setWidthF( mArrowHeadOutlineWidth );
378 adaptItemSceneRect();
385 return mLineSymbol->
width();
393 mArrowHeadOutlineWidth = width;
394 mPen.
setWidthF( mArrowHeadOutlineWidth );
396 adaptItemSceneRect();
402 mLineSymbol = symbol;
407 mArrowHeadWidth = width;
410 adaptItemSceneRect();
413 double QgsComposerArrow::computeMarkerMargin()
const 417 if ( mBoundsBehaviour == 22 )
422 margin = mPen.
widthF() / 2.0 + mArrowHeadWidth / 2.0;
426 margin = mPen.
widthF() / 2.0;
430 double maxArrowHeight = qMax( mStartArrowHeadHeight, mStopArrowHeadHeight );
431 margin = mPen.
widthF() / 2 + qMax( mArrowHeadWidth / 2.0, maxArrowHeight / 2.0 );
438 margin = mPen.
widthF() / std::sqrt( 2.0 ) + mArrowHeadWidth / 2.0;
442 margin = mPen.
widthF() / std::sqrt( 2.0 );
446 double startMarkerMargin = std::sqrt( 0.25 * ( mStartArrowHeadHeight * mStartArrowHeadHeight + mArrowHeadWidth * mArrowHeadWidth ) );
447 double stopMarkerMargin = std::sqrt( 0.25 * ( mStopArrowHeadHeight * mStopArrowHeadHeight + mArrowHeadWidth * mArrowHeadWidth ) );
448 double markerMargin = qMax( startMarkerMargin, stopMarkerMargin );
449 margin = qMax( mPen.
widthF() / std::sqrt( 2.0 ), markerMargin );
455 void QgsComposerArrow::adaptItemSceneRect()
458 QRectF rect =
QRectF( qMin( mStartPoint.
x(), mStopPoint.
x() ), qMin( mStartPoint.
y(), mStopPoint.
y() ),
459 qAbs( mStopPoint.
x() - mStartPoint.
x() ), qAbs( mStopPoint.
y() - mStartPoint.
y() ) );
460 double enlarge = computeMarkerMargin();
461 rect.
adjust( -enlarge, -enlarge, enlarge, enlarge );
468 adaptItemSceneRect();
478 composerArrowElem.
setAttribute(
"markerMode", mMarkerMode );
479 composerArrowElem.
setAttribute(
"startMarkerFile", mStartMarkerFile );
480 composerArrowElem.
setAttribute(
"endMarkerFile", mEndMarkerFile );
501 return _writeXML( composerArrowElem, doc );
514 mBoundsBehaviour = itemElem.
attribute(
"boundsBehaviourVersion",
"22" ).
toInt();
518 if ( !styleElem.
isNull() )
521 if ( !lineStyleElem.
isNull() )
524 mLineSymbol = QgsSymbolLayerV2Utils::loadSymbol<QgsLineSymbolV2>( lineStyleElem );
533 properties.
insert(
"width", itemElem.
attribute(
"outlineWidth",
"1.0" ) );
535 if ( mBoundsBehaviour == 22 )
538 properties.
insert(
"capstyle",
"flat" );
542 properties.
insert(
"capstyle",
"square" );
550 if ( !arrowColorList.
isEmpty() )
557 mArrowHeadFillColor =
QColor( red, green, blue, alpha );
558 mArrowHeadOutlineColor =
QColor( red, green, blue, alpha );
560 properties.
insert(
"color",
QString(
"%1,%2,%3,%4" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
564 mPen.
setColor( mArrowHeadOutlineColor );
565 mPen.
setWidthF( mArrowHeadOutlineWidth );
566 mBrush.
setColor( mArrowHeadFillColor );
571 if ( !composerItemList.
isEmpty() )
579 if ( !startPointList.
isEmpty() )
588 if ( !stopPointList.
isEmpty() )
595 mStartXIdx = mStopPoint.
x() < mStartPoint.
x();
596 mStartYIdx = mStopPoint.
y() < mStartPoint.
y();
598 adaptItemSceneRect();
QgsComposerArrow(QgsComposition *c)
Constructor.
void setForceVectorOutput(bool force)
QDomNodeList elementsByTagName(const QString &tagname) const
Q_DECL_DEPRECATED void setOutlineWidth(double width)
Sets the pen width for drawing the line and arrow head.
bool shouldDrawItem() const
Returns whether the item should be drawn in the current context.
void setRenderHint(RenderHint hint, bool on)
virtual int type() const override
Return composer item type.
QDomNode appendChild(const QDomNode &newChild)
void render(QPainter *painter)
QString attribute(const QString &name, const QString &defValue) const
static double angle(QPointF p1, QPointF p2)
Calculates the angle of the line from p1 to p2 (counter clockwise, starting from a line from north to...
void itemChanged()
Emitted when the item changes.
static QString encodeColor(const QColor &color)
void scale(qreal sx, qreal sy)
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'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.
static QDomElement saveSymbol(const QString &symbolName, QgsSymbolV2 *symbol, QDomDocument &doc)
virtual void drawFrame(QPainter *p)
Draw black frame around item.
void setArrowHeadWidth(double width)
Sets the width of the arrow head in mm.
bool _writeXML(QDomElement &itemElem, QDomDocument &doc) const
Writes parameter that are not subclass specific in document.
double toDouble(bool *ok) const
virtual QgsExpressionContext * createExpressionContext() const override
Creates an expression context relating to the item's current state.
void adjust(qreal dx1, qreal dy1, qreal dx2, qreal dy2)
void setWidth(double width)
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.
bool _readXML(const QDomElement &itemElem, const QDomDocument &doc)
Reads parameter that are not subclass specific in document.
static QgsSvgCache * instance()
QDomElement toElement() const
void setSceneRect(const QRectF &rectangle) override
Modifies position of start and endpoint and calls QgsComposerItem::setSceneRect.
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.
QString number(int n, int base)
bool load(const QString &filename)
void startRender(QgsRenderContext &context, const QgsFields *fields=nullptr)
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 setPen(const QColor &color)
void setAttribute(const QString &name, const QString &value)
int toInt(bool *ok, int base) const
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void renderPolyline(const QPolygonF &points, const QgsFeature *f, QgsRenderContext &context, int layer=-1, bool selected=false)
Q_DECL_DEPRECATED double outlineWidth() const
Returns the pen width for drawing the line and arrow head.
QPaintDevice * device() const
void setWidthF(qreal width)
void setBrush(const QBrush &brush)
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 setLineSymbol(QgsLineSymbolV2 *symbol)
Sets the line symbol used for drawing the line portion of the arrow.
QRectF united(const QRectF &rectangle) const
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.
void setColor(const QColor &color)
Q_DECL_DEPRECATED QColor arrowColor() const
Returns the color for the line and arrow head.
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.
QgsComposition * mComposition
Contains information about the context of a rendering operation.
void stopRender(QgsRenderContext &context)
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
virtual void drawBackground(QPainter *p)
Draw background.
QDomElement firstChildElement(const QString &tagName) const
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 translate(const QPointF &offset)
QVector2D normalized() const
static QColor decodeColor(const QString &str)
iterator insert(const Key &key, const T &value)
bool readXML(const QDomElement &itemElem, const QDomDocument &doc) override
Sets state from DOM document.
QDomElement createElement(const QString &tagName)
bool writeXML(QDomElement &elem, QDomDocument &doc) const override
Stores state in DOM element.
void setColor(const QColor &color)
void paint(QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget) override
Reimplementation of QCanvasItem::paint - draw on canvas.
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.
QDomNode at(int index) const