23 #include <QSvgRenderer>
34 , mMarkerMode( DefaultMarker )
35 , mArrowHeadOutlineWidth( 1.0 )
36 , mArrowHeadOutlineColor(
Qt::black )
37 , mArrowHeadFillColor(
Qt::black )
38 , mBoundsBehaviour( 24 )
46 , mStartPoint( startPoint )
47 , mStopPoint( stopPoint )
48 , mMarkerMode( DefaultMarker )
49 , mArrowHeadOutlineWidth( 1.0 )
50 , mArrowHeadOutlineColor(
Qt::black )
51 , mArrowHeadFillColor(
Qt::black )
52 , mBoundsBehaviour( 24 )
55 mStartXIdx = mStopPoint.
x() < mStartPoint.
x();
56 mStartYIdx = mStopPoint.
y() < mStartPoint.
y();
66 void QgsComposerArrow::init()
69 mPen.
setColor( mArrowHeadOutlineColor );
71 mBrush.
setColor( mArrowHeadFillColor );
72 createDefaultLineSymbol();
79 void QgsComposerArrow::createDefaultLineSymbol()
83 properties.
insert(
"color",
"0,0,0,255" );
84 properties.
insert(
"width",
"1" );
85 properties.
insert(
"capstyle",
"square" );
91 Q_UNUSED( itemStyle );
93 if ( !painter || !painter->
device() )
119 drawHardcodedMarker( painter, EndMarker );
123 drawSVGMarker( painter, StartMarker, mStartMarkerFile );
124 drawSVGMarker( painter, EndMarker, mEndMarkerFile );
142 if ( evaluatedRect.
width() < 0 )
144 mStartXIdx = 1 - mStartXIdx;
146 if ( evaluatedRect.
height() < 0 )
148 mStartYIdx = 1 - mStartYIdx;
151 double margin = computeMarkerMargin();
157 double x[2] = {rect.
x(), rect.
x() + rect.
width()};
158 double y[2] = {rect.
y(), rect.
y() + rect.
height()};
160 double xsign = x[mStartXIdx] < x[1 - mStartXIdx] ? 1.0 : -1.0;
161 double ysign = y[mStartYIdx] < y[1 - mStartYIdx] ? 1.0 : -1.0;
163 mStartPoint =
QPointF( x[mStartXIdx] + xsign * margin, y[mStartYIdx] + ysign * margin );
164 mStopPoint =
QPointF( x[1 - mStartXIdx] - xsign * margin, y[1 - mStartYIdx] - ysign * margin );
169 void QgsComposerArrow::drawLine(
QPainter *painter )
179 double dotsPerMM = thePaintDevice->
logicalDpiX() / 25.4;
180 painter->
scale( 1 / dotsPerMM, 1 / dotsPerMM );
191 delete expressionContext;
195 line <<
QPointF( mStartPoint.
x() -
pos().
x(), mStartPoint.
y() -
pos().
y() ) * dotsPerMM
196 <<
QPointF( mStopPoint.
x() -
pos().
x(), mStopPoint.
y() -
pos().
y() ) * dotsPerMM;
205 void QgsComposerArrow::drawHardcodedMarker(
QPainter *p, MarkerType type )
208 if ( mBoundsBehaviour == 22 )
216 QPointF stop = mStopPoint + ( dir * 0.5 * mArrowHeadWidth ).toPointF();
221 void QgsComposerArrow::drawSVGMarker(
QPainter* p, MarkerType type,
const QString &markerPath )
223 Q_UNUSED( markerPath );
226 double arrowHeadHeight;
227 if ( type == StartMarker )
229 arrowHeadHeight = mStartArrowHeadHeight;
233 arrowHeadHeight = mStopArrowHeadHeight;
235 if ( mArrowHeadWidth <= 0 || arrowHeadHeight <= 0 )
242 imageFixPoint.
setX( mArrowHeadWidth / 2.0 );
244 if ( type == StartMarker )
246 canvasPoint =
QPointF( mStartPoint.
x() -
pos().
x(), mStartPoint.
y() -
pos().
y() );
247 imageFixPoint.
setY( mStartArrowHeadHeight );
252 imageFixPoint.
setY( 0 );
257 if ( type == StartMarker )
259 if ( mStartMarkerFile.
isEmpty() || !r.
load( mStartMarkerFile ) )
266 if ( mEndMarkerFile.
isEmpty() || !r.
load( mEndMarkerFile ) )
274 if ( mBoundsBehaviour == 22 )
279 if ( type == StartMarker )
281 fixPoint.
setX( 0 ); fixPoint.
setY( arrowHeadHeight / 2.0 );
285 fixPoint.
setX( 0 ); fixPoint.
setY( -arrowHeadHeight / 2.0 );
288 double angleRad = ang / 180 *
M_PI;
289 rotatedFixPoint.
setX( fixPoint.
x() * cos( angleRad ) + fixPoint.
y() * -sin( angleRad ) );
290 rotatedFixPoint.
setY( fixPoint.
x() * sin( angleRad ) + fixPoint.
y() * cos( angleRad ) );
291 p->
translate( canvasPoint.
x() - rotatedFixPoint.
x(), canvasPoint.
y() - rotatedFixPoint.
y() );
299 p->
translate( -mArrowHeadWidth / 2.0, -arrowHeadHeight / 2.0 );
300 r.
render( p,
QRectF( 0, 0, mArrowHeadWidth, arrowHeadHeight ) );
309 mStartMarkerFile = svgPath;
312 mStartArrowHeadHeight = 0;
318 mStartArrowHeadHeight = mArrowHeadWidth / viewBox.
width() * viewBox.
height();
320 adaptItemSceneRect();
326 mEndMarkerFile = svgPath;
329 mStopArrowHeadHeight = 0;
335 mStopArrowHeadHeight = mArrowHeadWidth / viewBox.
width() * viewBox.
height();
337 adaptItemSceneRect();
344 return mLineSymbol->
color();
356 mArrowHeadOutlineColor = c;
357 mArrowHeadFillColor = c;
364 mArrowHeadOutlineColor = color;
370 mArrowHeadFillColor = color;
380 mArrowHeadOutlineWidth = width;
381 mPen.
setWidthF( mArrowHeadOutlineWidth );
383 adaptItemSceneRect();
390 return mLineSymbol->
width();
398 mArrowHeadOutlineWidth = width;
399 mPen.
setWidthF( mArrowHeadOutlineWidth );
401 adaptItemSceneRect();
407 mLineSymbol = symbol;
412 mArrowHeadWidth = width;
415 adaptItemSceneRect();
418 double QgsComposerArrow::computeMarkerMargin()
const
422 if ( mBoundsBehaviour == 22 )
427 margin = mPen.
widthF() / 2.0 + mArrowHeadWidth / 2.0;
431 margin = mPen.
widthF() / 2.0;
435 double maxArrowHeight = qMax( mStartArrowHeadHeight, mStopArrowHeadHeight );
436 margin = mPen.
widthF() / 2 + qMax( mArrowHeadWidth / 2.0, maxArrowHeight / 2.0 );
443 margin = mPen.
widthF() / std::sqrt( 2.0 ) + mArrowHeadWidth / 2.0;
447 margin = mPen.
widthF() / std::sqrt( 2.0 );
451 double startMarkerMargin = std::sqrt( 0.25 * ( mStartArrowHeadHeight * mStartArrowHeadHeight + mArrowHeadWidth * mArrowHeadWidth ) );
452 double stopMarkerMargin = std::sqrt( 0.25 * ( mStopArrowHeadHeight * mStopArrowHeadHeight + mArrowHeadWidth * mArrowHeadWidth ) );
453 double markerMargin = qMax( startMarkerMargin, stopMarkerMargin );
454 margin = qMax( mPen.
widthF() / std::sqrt( 2.0 ), markerMargin );
460 void QgsComposerArrow::adaptItemSceneRect()
463 QRectF rect =
QRectF( qMin( mStartPoint.
x(), mStopPoint.
x() ), qMin( mStartPoint.
y(), mStopPoint.
y() ),
464 qAbs( mStopPoint.
x() - mStartPoint.
x() ), qAbs( mStopPoint.
y() - mStartPoint.
y() ) );
465 double enlarge = computeMarkerMargin();
466 rect.
adjust( -enlarge, -enlarge, enlarge, enlarge );
473 adaptItemSceneRect();
483 composerArrowElem.
setAttribute(
"markerMode", mMarkerMode );
484 composerArrowElem.
setAttribute(
"startMarkerFile", mStartMarkerFile );
485 composerArrowElem.
setAttribute(
"endMarkerFile", mEndMarkerFile );
506 return _writeXML( composerArrowElem, doc );
519 mBoundsBehaviour = itemElem.
attribute(
"boundsBehaviourVersion",
"22" ).
toInt();
523 if ( !styleElem.
isNull() )
526 if ( !lineStyleElem.
isNull() )
529 mLineSymbol = QgsSymbolLayerV2Utils::loadSymbol<QgsLineSymbolV2>( lineStyleElem );
538 properties.
insert(
"width", itemElem.
attribute(
"outlineWidth",
"1.0" ) );
540 if ( mBoundsBehaviour == 22 )
543 properties.
insert(
"capstyle",
"flat" );
547 properties.
insert(
"capstyle",
"square" );
555 if ( arrowColorList.
size() > 0 )
562 mArrowHeadFillColor =
QColor( red, green, blue, alpha );
563 mArrowHeadOutlineColor =
QColor( red, green, blue, alpha );
565 properties.
insert(
"color",
QString(
"%1,%2,%3,%4" ).arg( red ).arg( green ).arg( blue ).arg( alpha ) );
569 mPen.
setColor( mArrowHeadOutlineColor );
570 mPen.
setWidthF( mArrowHeadOutlineWidth );
571 mBrush.
setColor( mArrowHeadFillColor );
576 if ( composerItemList.
size() > 0 )
584 if ( startPointList.
size() > 0 )
593 if ( stopPointList.
size() > 0 )
600 mStartXIdx = mStopPoint.
x() < mStartPoint.
x();
601 mStartYIdx = mStopPoint.
y() < mStartPoint.
y();
603 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.
void setRenderHint(RenderHint hint, bool on)
QDomNode appendChild(const QDomNode &newChild)
void render(QPainter *painter)
QString attribute(const QString &name, const QString &defValue) const
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.
static QString encodeColor(const QColor &color)
const QgsMapSettings & mapSettings() const
Return setting of QGIS map canvas.
void scale(qreal sx, qreal sy)
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 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.
double toDouble(bool *ok) const
virtual QgsExpressionContext * createExpressionContext() const override
Creates an expression context relating to the objects'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.
Q_DECL_DEPRECATED double outlineWidth() const
Returns the pen width for drawing the line and 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.
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)
Q_DECL_DEPRECATED QColor arrowColor() const
Returns the color for the line and arrow head.
bool load(const QString &filename)
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 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...
QRectF evalItemRect(const QRectF &newRect, const bool resizeOnly=false, const QgsExpressionContext *context=0)
Evaluates an item's bounding rect to consider data defined position and size of item and reference po...
void renderPolyline(const QPolygonF &points, const QgsFeature *f, QgsRenderContext &context, int layer=-1, bool selected=false)
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.
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.
bool shouldDrawItem() const
Returns whether the item should be drawn in the current context.
void setColor(const QColor &color)
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.
QgsComposition * mComposition
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.
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.
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...
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