Skip to content

Commit

Permalink
Added option for custom dash-space pattern in simple line symbollayer
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@12788 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
mhugent committed Jan 18, 2010
1 parent 2405eb8 commit bde0672
Show file tree
Hide file tree
Showing 11 changed files with 438 additions and 40 deletions.
45 changes: 42 additions & 3 deletions src/core/symbology-ng/qgslinesymbollayerv2.cpp
Expand Up @@ -9,10 +9,11 @@
#include <cmath>

QgsSimpleLineSymbolLayerV2::QgsSimpleLineSymbolLayerV2( QColor color, double width, Qt::PenStyle penStyle )
: mPenStyle( penStyle ), mPenJoinStyle( DEFAULT_SIMPLELINE_JOINSTYLE ), mPenCapStyle( DEFAULT_SIMPLELINE_CAPSTYLE ), mOffset( 0 )
: mPenStyle( penStyle ), mPenJoinStyle( DEFAULT_SIMPLELINE_JOINSTYLE ), mPenCapStyle( DEFAULT_SIMPLELINE_CAPSTYLE ), mOffset( 0 ), mUseCustomDashPattern( false )
{
mColor = color;
mWidth = width;
mCustomDashVector << 5 << 2;
}


Expand All @@ -37,6 +38,15 @@ QgsSymbolLayerV2* QgsSimpleLineSymbolLayerV2::create( const QgsStringMap& props
l->setPenJoinStyle( QgsSymbolLayerV2Utils::decodePenJoinStyle( props["joinstyle"] ) );
if ( props.contains( "capstyle" ) )
l->setPenCapStyle( QgsSymbolLayerV2Utils::decodePenCapStyle( props["capstyle"] ) );

if ( props.contains( "use_custom_dash" ) )
{
l->setUseCustomDashPattern( props["use_custom_dash"].toInt() );
}
if ( props.contains( "customdash" ) )
{
l->setCustomDashVector( QgsSymbolLayerV2Utils::decodeRealVector( props["customdash"] ) );
}
return l;
}

Expand All @@ -50,8 +60,26 @@ QString QgsSimpleLineSymbolLayerV2::layerType() const
void QgsSimpleLineSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context )
{
mPen.setColor( mColor );
mPen.setWidthF( context.outputLineWidth( mWidth ) );
mPen.setStyle( mPenStyle );
double scaledWidth = context.outputLineWidth( mWidth );
mPen.setWidthF( scaledWidth );
if ( mUseCustomDashPattern )
{
mPen.setStyle( Qt::CustomDashLine );

//scale pattern vector
QVector<qreal> scaledVector;
QVector<qreal>::const_iterator it = mCustomDashVector.constBegin();
for ( ; it != mCustomDashVector.constEnd(); ++it )
{
//the dash is specified in terms of pen widths, therefore the division
scaledVector << context.outputLineWidth(( *it ) / scaledWidth );
}
mPen.setDashPattern( scaledVector );
}
else
{
mPen.setStyle( mPenStyle );
}
mPen.setJoinStyle( mPenJoinStyle );
mPen.setCapStyle( mPenCapStyle );
}
Expand Down Expand Up @@ -88,6 +116,15 @@ QgsStringMap QgsSimpleLineSymbolLayerV2::properties() const
map["joinstyle"] = QgsSymbolLayerV2Utils::encodePenJoinStyle( mPenJoinStyle );
map["capstyle"] = QgsSymbolLayerV2Utils::encodePenCapStyle( mPenCapStyle );
map["offset"] = QString::number( mOffset );
if ( mUseCustomDashPattern )
{
map["use_custom_dash"] = "1";
}
else
{
map["use_custom_dash"] = "0";
}
map["customdash"] = QgsSymbolLayerV2Utils::encodeRealVector( mCustomDashVector );
return map;
}

Expand All @@ -97,6 +134,8 @@ QgsSymbolLayerV2* QgsSimpleLineSymbolLayerV2::clone() const
l->setOffset( mOffset );
l->setPenJoinStyle( mPenJoinStyle );
l->setPenCapStyle( mPenCapStyle );
l->setUseCustomDashPattern( mUseCustomDashPattern );
l->setCustomDashVector( mCustomDashVector );
return l;
}

Expand Down
10 changes: 10 additions & 0 deletions src/core/symbology-ng/qgslinesymbollayerv2.h
Expand Up @@ -52,12 +52,22 @@ class CORE_EXPORT QgsSimpleLineSymbolLayerV2 : public QgsLineSymbolLayerV2
double offset() const { return mOffset; }
void setOffset( double offset ) { mOffset = offset; }

bool useCustomDashPattern() const { return mUseCustomDashPattern; }
void setUseCustomDashPattern( bool b ) { mUseCustomDashPattern = b; }

QVector<qreal> customDashVector() const { return mCustomDashVector; }
void setCustomDashVector( const QVector<qreal>& vector ) { mCustomDashVector = vector; }

protected:
Qt::PenStyle mPenStyle;
Qt::PenJoinStyle mPenJoinStyle;
Qt::PenCapStyle mPenCapStyle;
QPen mPen;
double mOffset;
//use a custom dash dot pattern instead of the predefined ones
bool mUseCustomDashPattern;
/**Vector with an even number of entries for the */
QVector<qreal> mCustomDashVector;
};

/////////
Expand Down
32 changes: 30 additions & 2 deletions src/core/symbology-ng/qgssymbollayerv2utils.cpp
Expand Up @@ -176,6 +176,35 @@ QgsSymbolV2::OutputUnit QgsSymbolLayerV2Utils::decodeOutputUnit( QString str )
return QgsSymbolV2::MM;
}

QString QgsSymbolLayerV2Utils::encodeRealVector( const QVector<qreal>& v )
{
QString vectorString;
QVector<qreal>::const_iterator it = v.constBegin();
for ( ; it != v.constEnd(); ++it )
{
if ( it != v.constBegin() )
{
vectorString.append( ";" );
}
vectorString.append( QString::number( *it ) );
}
return vectorString;
}

QVector<qreal> QgsSymbolLayerV2Utils::decodeRealVector( const QString& s )
{
QVector<qreal> resultVector;

QStringList realList = s.split( ";" );
QStringList::const_iterator it = realList.constBegin();
for ( ; it != realList.constEnd(); ++it )
{
resultVector.append( it->toDouble() );
}

return resultVector;
}

QIcon QgsSymbolLayerV2Utils::symbolPreviewIcon( QgsSymbolV2* symbol, QSize size )
{
return QIcon( symbolPreviewPixmap( symbol, size ) );
Expand All @@ -201,8 +230,7 @@ QIcon QgsSymbolLayerV2Utils::symbolLayerPreviewIcon( QgsSymbolLayerV2* layer, Qg
painter.begin( &pixmap );
painter.setRenderHint( QPainter::Antialiasing );
painter.eraseRect( QRect( QPoint( 0, 0 ), size ) );
QgsRenderContext renderContext;
renderContext.setPainter( &painter );
QgsRenderContext renderContext = createRenderContext( &painter );
QgsSymbolV2RenderContext symbolContext( renderContext, u );
layer->drawPreviewIcon( symbolContext, size );
painter.end();
Expand Down
5 changes: 5 additions & 0 deletions src/core/symbology-ng/qgssymbollayerv2utils.h
Expand Up @@ -44,6 +44,9 @@ class CORE_EXPORT QgsSymbolLayerV2Utils
static QString encodePoint( QPointF point );
static QPointF decodePoint( QString str );

static QString encodeRealVector( const QVector<qreal>& v );
static QVector<qreal> decodeRealVector( const QString& s );

static QString encodeOutputUnit( QgsSymbolV2::OutputUnit unit );
static QgsSymbolV2::OutputUnit decodeOutputUnit( QString str );

Expand Down Expand Up @@ -75,6 +78,8 @@ class CORE_EXPORT QgsSymbolLayerV2Utils
static double pixelSizeScaleFactor( QgsRenderContext& c, QgsSymbolV2::OutputUnit u );
/**Creates a render context for a pixel based device*/
static QgsRenderContext createRenderContext( QPainter* p );

static QString iconPath( QString iconFile );
};

class QPolygonF;
Expand Down
2 changes: 2 additions & 0 deletions src/gui/CMakeLists.txt
Expand Up @@ -2,6 +2,7 @@
SET(QGIS_GUI_SRCS

symbology-ng/qgsbrushstylecombobox.cpp
symbology-ng/qgsdashspacedialog.cpp
symbology-ng/qgspenstylecombobox.cpp
symbology-ng/qgssymbollayerv2widget.cpp
symbology-ng/qgssymbolv2propertiesdialog.cpp
Expand Down Expand Up @@ -50,6 +51,7 @@ qgsludialog.cpp

SET(QGIS_GUI_MOC_HDRS

symbology-ng/qgsdashspacedialog.h
symbology-ng/qgssymbollayerv2widget.h
symbology-ng/qgssymbolv2propertiesdialog.h
symbology-ng/qgssinglesymbolrendererv2widget.h
Expand Down
92 changes: 92 additions & 0 deletions src/gui/symbology-ng/qgsdashspacedialog.cpp
@@ -0,0 +1,92 @@
/***************************************************************************
qgsdashspacedialog.cpp
----------------------
begin : January 2010
copyright : (C) 2010 by Marco Hugentobler
email : marco at hugis dot net
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsdashspacedialog.h"
#include "qgsapplication.h"
#include <QFile>

QString iconPath( QString iconFile )
{
// try active theme
QString path = QgsApplication::activeThemePath();
if ( QFile::exists( path + iconFile ) )
return path + iconFile;

// use default theme
return QgsApplication::defaultThemePath() + iconFile;
}

QgsDashSpaceDialog::QgsDashSpaceDialog( const QVector<qreal>& v, QWidget* parent, Qt::WindowFlags f ): QDialog( parent, f )
{
setupUi( this );

mAddButton->setIcon( QIcon( iconPath( "symbologyAdd.png" ) ) );
mRemoveButton->setIcon( QIcon( iconPath( "symbologyRemove.png" ) ) );

double dash = 0;
double space = 0;
for ( int i = 0; i < ( v.size() - 1 ); ++i )
{
dash = v.at( i );
++i;
space = v.at( i );
QTreeWidgetItem* entry = new QTreeWidgetItem();
entry->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled );
entry->setText( 0, QString::number( dash ) );
entry->setText( 1, QString::number( space ) );
mDashSpaceTreeWidget->addTopLevelItem( entry );
}
}

QgsDashSpaceDialog::~QgsDashSpaceDialog()
{

}

void QgsDashSpaceDialog::on_mAddButton_clicked()
{
//add new (default) item
QTreeWidgetItem* entry = new QTreeWidgetItem();
entry->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled );
entry->setText( 0, "5" );
entry->setText( 1, "2" );
mDashSpaceTreeWidget->addTopLevelItem( entry );
}

void QgsDashSpaceDialog::on_mRemoveButton_clicked()
{
//get active item
QTreeWidgetItem* currentItem = mDashSpaceTreeWidget->currentItem();
if ( currentItem )
{
mDashSpaceTreeWidget->takeTopLevelItem( mDashSpaceTreeWidget->indexOfTopLevelItem( currentItem ) );
}
}

QVector<qreal> QgsDashSpaceDialog::dashDotVector() const
{
QVector<qreal> dashVector;
int nTopLevelItems = mDashSpaceTreeWidget->topLevelItemCount();
for ( int i = 0; i < nTopLevelItems; ++i )
{
QTreeWidgetItem* currentItem = mDashSpaceTreeWidget->topLevelItem( i );
if ( currentItem )
{
dashVector << currentItem->text( 0 ).toDouble() << currentItem->text( 1 ).toDouble();
}
}
return dashVector;
}

36 changes: 36 additions & 0 deletions src/gui/symbology-ng/qgsdashspacedialog.h
@@ -0,0 +1,36 @@
/***************************************************************************
qgsdashspacedialog.h
---------------------
begin : January 2010
copyright : (C) 2010 by Marco Hugentobler
email : marco at hugis dot net
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSDASHSPACEDIALOG_H
#define QGSDASHSPACEDIALOG_H

#include "ui_qgsdashspacedialogbase.h"

/**A dialog to enter a custom dash space pattern for lines*/
class QgsDashSpaceDialog: public QDialog, private Ui::QgsDashSpaceDialogBase
{
Q_OBJECT
public:
QgsDashSpaceDialog( const QVector<qreal>& v, QWidget * parent = 0, Qt::WindowFlags f = 0 );
~QgsDashSpaceDialog();

QVector<qreal> dashDotVector() const;

private slots:
void on_mAddButton_clicked();
void on_mRemoveButton_clicked();
};

#endif // QGSDASHSPACEDIALOG_H

0 comments on commit bde0672

Please sign in to comment.