Skip to content

Commit 005ac64

Browse files
author
mhugent
committed
Added option for custom dash-space pattern in simple line symbollayer
git-svn-id: http://svn.osgeo.org/qgis/trunk@12788 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent ffc9eb5 commit 005ac64

11 files changed

+438
-40
lines changed

src/core/symbology-ng/qgslinesymbollayerv2.cpp

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@
99
#include <cmath>
1010

1111
QgsSimpleLineSymbolLayerV2::QgsSimpleLineSymbolLayerV2( QColor color, double width, Qt::PenStyle penStyle )
12-
: mPenStyle( penStyle ), mPenJoinStyle( DEFAULT_SIMPLELINE_JOINSTYLE ), mPenCapStyle( DEFAULT_SIMPLELINE_CAPSTYLE ), mOffset( 0 )
12+
: mPenStyle( penStyle ), mPenJoinStyle( DEFAULT_SIMPLELINE_JOINSTYLE ), mPenCapStyle( DEFAULT_SIMPLELINE_CAPSTYLE ), mOffset( 0 ), mUseCustomDashPattern( false )
1313
{
1414
mColor = color;
1515
mWidth = width;
16+
mCustomDashVector << 5 << 2;
1617
}
1718

1819

@@ -37,6 +38,15 @@ QgsSymbolLayerV2* QgsSimpleLineSymbolLayerV2::create( const QgsStringMap& props
3738
l->setPenJoinStyle( QgsSymbolLayerV2Utils::decodePenJoinStyle( props["joinstyle"] ) );
3839
if ( props.contains( "capstyle" ) )
3940
l->setPenCapStyle( QgsSymbolLayerV2Utils::decodePenCapStyle( props["capstyle"] ) );
41+
42+
if ( props.contains( "use_custom_dash" ) )
43+
{
44+
l->setUseCustomDashPattern( props["use_custom_dash"].toInt() );
45+
}
46+
if ( props.contains( "customdash" ) )
47+
{
48+
l->setCustomDashVector( QgsSymbolLayerV2Utils::decodeRealVector( props["customdash"] ) );
49+
}
4050
return l;
4151
}
4252

@@ -50,8 +60,26 @@ QString QgsSimpleLineSymbolLayerV2::layerType() const
5060
void QgsSimpleLineSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context )
5161
{
5262
mPen.setColor( mColor );
53-
mPen.setWidthF( context.outputLineWidth( mWidth ) );
54-
mPen.setStyle( mPenStyle );
63+
double scaledWidth = context.outputLineWidth( mWidth );
64+
mPen.setWidthF( scaledWidth );
65+
if ( mUseCustomDashPattern )
66+
{
67+
mPen.setStyle( Qt::CustomDashLine );
68+
69+
//scale pattern vector
70+
QVector<qreal> scaledVector;
71+
QVector<qreal>::const_iterator it = mCustomDashVector.constBegin();
72+
for ( ; it != mCustomDashVector.constEnd(); ++it )
73+
{
74+
//the dash is specified in terms of pen widths, therefore the division
75+
scaledVector << context.outputLineWidth(( *it ) / scaledWidth );
76+
}
77+
mPen.setDashPattern( scaledVector );
78+
}
79+
else
80+
{
81+
mPen.setStyle( mPenStyle );
82+
}
5583
mPen.setJoinStyle( mPenJoinStyle );
5684
mPen.setCapStyle( mPenCapStyle );
5785
}
@@ -88,6 +116,15 @@ QgsStringMap QgsSimpleLineSymbolLayerV2::properties() const
88116
map["joinstyle"] = QgsSymbolLayerV2Utils::encodePenJoinStyle( mPenJoinStyle );
89117
map["capstyle"] = QgsSymbolLayerV2Utils::encodePenCapStyle( mPenCapStyle );
90118
map["offset"] = QString::number( mOffset );
119+
if ( mUseCustomDashPattern )
120+
{
121+
map["use_custom_dash"] = "1";
122+
}
123+
else
124+
{
125+
map["use_custom_dash"] = "0";
126+
}
127+
map["customdash"] = QgsSymbolLayerV2Utils::encodeRealVector( mCustomDashVector );
91128
return map;
92129
}
93130

@@ -97,6 +134,8 @@ QgsSymbolLayerV2* QgsSimpleLineSymbolLayerV2::clone() const
97134
l->setOffset( mOffset );
98135
l->setPenJoinStyle( mPenJoinStyle );
99136
l->setPenCapStyle( mPenCapStyle );
137+
l->setUseCustomDashPattern( mUseCustomDashPattern );
138+
l->setCustomDashVector( mCustomDashVector );
100139
return l;
101140
}
102141

src/core/symbology-ng/qgslinesymbollayerv2.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,22 @@ class CORE_EXPORT QgsSimpleLineSymbolLayerV2 : public QgsLineSymbolLayerV2
5252
double offset() const { return mOffset; }
5353
void setOffset( double offset ) { mOffset = offset; }
5454

55+
bool useCustomDashPattern() const { return mUseCustomDashPattern; }
56+
void setUseCustomDashPattern( bool b ) { mUseCustomDashPattern = b; }
57+
58+
QVector<qreal> customDashVector() const { return mCustomDashVector; }
59+
void setCustomDashVector( const QVector<qreal>& vector ) { mCustomDashVector = vector; }
60+
5561
protected:
5662
Qt::PenStyle mPenStyle;
5763
Qt::PenJoinStyle mPenJoinStyle;
5864
Qt::PenCapStyle mPenCapStyle;
5965
QPen mPen;
6066
double mOffset;
67+
//use a custom dash dot pattern instead of the predefined ones
68+
bool mUseCustomDashPattern;
69+
/**Vector with an even number of entries for the */
70+
QVector<qreal> mCustomDashVector;
6171
};
6272

6373
/////////

src/core/symbology-ng/qgssymbollayerv2utils.cpp

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,35 @@ QgsSymbolV2::OutputUnit QgsSymbolLayerV2Utils::decodeOutputUnit( QString str )
176176
return QgsSymbolV2::MM;
177177
}
178178

179+
QString QgsSymbolLayerV2Utils::encodeRealVector( const QVector<qreal>& v )
180+
{
181+
QString vectorString;
182+
QVector<qreal>::const_iterator it = v.constBegin();
183+
for ( ; it != v.constEnd(); ++it )
184+
{
185+
if ( it != v.constBegin() )
186+
{
187+
vectorString.append( ";" );
188+
}
189+
vectorString.append( QString::number( *it ) );
190+
}
191+
return vectorString;
192+
}
193+
194+
QVector<qreal> QgsSymbolLayerV2Utils::decodeRealVector( const QString& s )
195+
{
196+
QVector<qreal> resultVector;
197+
198+
QStringList realList = s.split( ";" );
199+
QStringList::const_iterator it = realList.constBegin();
200+
for ( ; it != realList.constEnd(); ++it )
201+
{
202+
resultVector.append( it->toDouble() );
203+
}
204+
205+
return resultVector;
206+
}
207+
179208
QIcon QgsSymbolLayerV2Utils::symbolPreviewIcon( QgsSymbolV2* symbol, QSize size )
180209
{
181210
return QIcon( symbolPreviewPixmap( symbol, size ) );
@@ -201,8 +230,7 @@ QIcon QgsSymbolLayerV2Utils::symbolLayerPreviewIcon( QgsSymbolLayerV2* layer, Qg
201230
painter.begin( &pixmap );
202231
painter.setRenderHint( QPainter::Antialiasing );
203232
painter.eraseRect( QRect( QPoint( 0, 0 ), size ) );
204-
QgsRenderContext renderContext;
205-
renderContext.setPainter( &painter );
233+
QgsRenderContext renderContext = createRenderContext( &painter );
206234
QgsSymbolV2RenderContext symbolContext( renderContext, u );
207235
layer->drawPreviewIcon( symbolContext, size );
208236
painter.end();

src/core/symbology-ng/qgssymbollayerv2utils.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ class CORE_EXPORT QgsSymbolLayerV2Utils
4444
static QString encodePoint( QPointF point );
4545
static QPointF decodePoint( QString str );
4646

47+
static QString encodeRealVector( const QVector<qreal>& v );
48+
static QVector<qreal> decodeRealVector( const QString& s );
49+
4750
static QString encodeOutputUnit( QgsSymbolV2::OutputUnit unit );
4851
static QgsSymbolV2::OutputUnit decodeOutputUnit( QString str );
4952

@@ -75,6 +78,8 @@ class CORE_EXPORT QgsSymbolLayerV2Utils
7578
static double pixelSizeScaleFactor( QgsRenderContext& c, QgsSymbolV2::OutputUnit u );
7679
/**Creates a render context for a pixel based device*/
7780
static QgsRenderContext createRenderContext( QPainter* p );
81+
82+
static QString iconPath( QString iconFile );
7883
};
7984

8085
class QPolygonF;

src/gui/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
SET(QGIS_GUI_SRCS
33

44
symbology-ng/qgsbrushstylecombobox.cpp
5+
symbology-ng/qgsdashspacedialog.cpp
56
symbology-ng/qgspenstylecombobox.cpp
67
symbology-ng/qgssymbollayerv2widget.cpp
78
symbology-ng/qgssymbolv2propertiesdialog.cpp
@@ -50,6 +51,7 @@ qgsludialog.cpp
5051

5152
SET(QGIS_GUI_MOC_HDRS
5253

54+
symbology-ng/qgsdashspacedialog.h
5355
symbology-ng/qgssymbollayerv2widget.h
5456
symbology-ng/qgssymbolv2propertiesdialog.h
5557
symbology-ng/qgssinglesymbolrendererv2widget.h
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/***************************************************************************
2+
qgsdashspacedialog.cpp
3+
----------------------
4+
begin : January 2010
5+
copyright : (C) 2010 by Marco Hugentobler
6+
email : marco at hugis dot net
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#include "qgsdashspacedialog.h"
17+
#include "qgsapplication.h"
18+
#include <QFile>
19+
20+
QString iconPath( QString iconFile )
21+
{
22+
// try active theme
23+
QString path = QgsApplication::activeThemePath();
24+
if ( QFile::exists( path + iconFile ) )
25+
return path + iconFile;
26+
27+
// use default theme
28+
return QgsApplication::defaultThemePath() + iconFile;
29+
}
30+
31+
QgsDashSpaceDialog::QgsDashSpaceDialog( const QVector<qreal>& v, QWidget* parent, Qt::WindowFlags f ): QDialog( parent, f )
32+
{
33+
setupUi( this );
34+
35+
mAddButton->setIcon( QIcon( iconPath( "symbologyAdd.png" ) ) );
36+
mRemoveButton->setIcon( QIcon( iconPath( "symbologyRemove.png" ) ) );
37+
38+
double dash = 0;
39+
double space = 0;
40+
for ( int i = 0; i < ( v.size() - 1 ); ++i )
41+
{
42+
dash = v.at( i );
43+
++i;
44+
space = v.at( i );
45+
QTreeWidgetItem* entry = new QTreeWidgetItem();
46+
entry->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled );
47+
entry->setText( 0, QString::number( dash ) );
48+
entry->setText( 1, QString::number( space ) );
49+
mDashSpaceTreeWidget->addTopLevelItem( entry );
50+
}
51+
}
52+
53+
QgsDashSpaceDialog::~QgsDashSpaceDialog()
54+
{
55+
56+
}
57+
58+
void QgsDashSpaceDialog::on_mAddButton_clicked()
59+
{
60+
//add new (default) item
61+
QTreeWidgetItem* entry = new QTreeWidgetItem();
62+
entry->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled );
63+
entry->setText( 0, "5" );
64+
entry->setText( 1, "2" );
65+
mDashSpaceTreeWidget->addTopLevelItem( entry );
66+
}
67+
68+
void QgsDashSpaceDialog::on_mRemoveButton_clicked()
69+
{
70+
//get active item
71+
QTreeWidgetItem* currentItem = mDashSpaceTreeWidget->currentItem();
72+
if ( currentItem )
73+
{
74+
mDashSpaceTreeWidget->takeTopLevelItem( mDashSpaceTreeWidget->indexOfTopLevelItem( currentItem ) );
75+
}
76+
}
77+
78+
QVector<qreal> QgsDashSpaceDialog::dashDotVector() const
79+
{
80+
QVector<qreal> dashVector;
81+
int nTopLevelItems = mDashSpaceTreeWidget->topLevelItemCount();
82+
for ( int i = 0; i < nTopLevelItems; ++i )
83+
{
84+
QTreeWidgetItem* currentItem = mDashSpaceTreeWidget->topLevelItem( i );
85+
if ( currentItem )
86+
{
87+
dashVector << currentItem->text( 0 ).toDouble() << currentItem->text( 1 ).toDouble();
88+
}
89+
}
90+
return dashVector;
91+
}
92+
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/***************************************************************************
2+
qgsdashspacedialog.h
3+
---------------------
4+
begin : January 2010
5+
copyright : (C) 2010 by Marco Hugentobler
6+
email : marco at hugis dot net
7+
***************************************************************************
8+
* *
9+
* This program is free software; you can redistribute it and/or modify *
10+
* it under the terms of the GNU General Public License as published by *
11+
* the Free Software Foundation; either version 2 of the License, or *
12+
* (at your option) any later version. *
13+
* *
14+
***************************************************************************/
15+
16+
#ifndef QGSDASHSPACEDIALOG_H
17+
#define QGSDASHSPACEDIALOG_H
18+
19+
#include "ui_qgsdashspacedialogbase.h"
20+
21+
/**A dialog to enter a custom dash space pattern for lines*/
22+
class QgsDashSpaceDialog: public QDialog, private Ui::QgsDashSpaceDialogBase
23+
{
24+
Q_OBJECT
25+
public:
26+
QgsDashSpaceDialog( const QVector<qreal>& v, QWidget * parent = 0, Qt::WindowFlags f = 0 );
27+
~QgsDashSpaceDialog();
28+
29+
QVector<qreal> dashDotVector() const;
30+
31+
private slots:
32+
void on_mAddButton_clicked();
33+
void on_mRemoveButton_clicked();
34+
};
35+
36+
#endif // QGSDASHSPACEDIALOG_H

0 commit comments

Comments
 (0)