Skip to content

Commit 59e161e

Browse files
author
wonder
committed
[FEATURE] Allow the line symbol layers to be used for outline of polygon (fill) symbols
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@14855 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 6631321 commit 59e161e

File tree

6 files changed

+82
-8
lines changed

6 files changed

+82
-8
lines changed

python/core/symbology-ng-core.sip

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,9 @@ class QgsLineSymbolLayerV2 : QgsSymbolLayerV2
565565
public:
566566
virtual void renderPolyline(const QPolygonF& points, QgsSymbolV2RenderContext& context) = 0;
567567

568+
//! @note added in v1.7
569+
virtual void renderPolygonOutline( const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context );
570+
568571
void setWidth(double width);
569572
double width() const;
570573

src/core/symbology-ng/qgssymbollayerv2.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,17 @@ void QgsLineSymbolLayerV2::drawPreviewIcon( QgsSymbolV2RenderContext& context, Q
4545
stopRender( context );
4646
}
4747

48+
void QgsLineSymbolLayerV2::renderPolygonOutline( const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context )
49+
{
50+
renderPolyline( points, context );
51+
if ( rings )
52+
{
53+
foreach( const QPolygonF& ring, *rings )
54+
renderPolyline( ring, context );
55+
}
56+
}
57+
58+
4859
void QgsFillSymbolLayerV2::drawPreviewIcon( QgsSymbolV2RenderContext& context, QSize size )
4960
{
5061
QPolygonF poly = QRectF( QPointF( 0, 0 ), QPointF( size.width() - 1, size.height() - 1 ) );

src/core/symbology-ng/qgssymbollayerv2.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ class CORE_EXPORT QgsLineSymbolLayerV2 : public QgsSymbolLayerV2
9999
public:
100100
virtual void renderPolyline( const QPolygonF& points, QgsSymbolV2RenderContext& context ) = 0;
101101

102+
//! @note added in v1.7
103+
virtual void renderPolygonOutline( const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context );
104+
102105
virtual void setWidth( double width ) { mWidth = width; }
103106
virtual double width() const { return mWidth; }
104107

src/core/symbology-ng/qgssymbolv2.cpp

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ QgsSymbolV2::QgsSymbolV2( SymbolType type, QgsSymbolLayerV2List layers )
2828
{
2929
mLayers.removeAt( i-- );
3030
}
31-
else if ( mLayers[i]->type() != mType )
31+
else if ( !isSymbolLayerCompatible( mLayers[i]->type() ) )
3232
{
3333
delete mLayers[i];
3434
mLayers.removeAt( i-- );
@@ -69,12 +69,21 @@ QgsSymbolLayerV2* QgsSymbolV2::symbolLayer( int layer )
6969
}
7070

7171

72+
bool QgsSymbolV2::isSymbolLayerCompatible( SymbolType t )
73+
{
74+
// fill symbol can contain also line symbol layers for drawing of outlines
75+
if ( mType == Fill && t == Line )
76+
return true;
77+
78+
return mType == t;
79+
}
80+
7281

7382
bool QgsSymbolV2::insertSymbolLayer( int index, QgsSymbolLayerV2* layer )
7483
{
7584
if ( index < 0 || index > mLayers.count() ) // can be added also after the last index
7685
return false;
77-
if ( layer == NULL || layer->type() != mType )
86+
if ( layer == NULL || !isSymbolLayerCompatible( layer->type() ) )
7887
return false;
7988

8089
mLayers.insert( index, layer );
@@ -84,7 +93,7 @@ bool QgsSymbolV2::insertSymbolLayer( int index, QgsSymbolLayerV2* layer )
8493

8594
bool QgsSymbolV2::appendSymbolLayer( QgsSymbolLayerV2* layer )
8695
{
87-
if ( layer == NULL || layer->type() != mType )
96+
if ( layer == NULL || !isSymbolLayerCompatible( layer->type() ) )
8897
return false;
8998

9099
mLayers.append( layer );
@@ -116,7 +125,7 @@ bool QgsSymbolV2::changeSymbolLayer( int index, QgsSymbolLayerV2* layer )
116125
{
117126
if ( index < 0 || index >= mLayers.count() )
118127
return false;
119-
if ( layer == NULL || layer->type() != mType )
128+
if ( layer == NULL || !isSymbolLayerCompatible( layer->type() ) )
120129
return false;
121130

122131
delete mLayers[index]; // first delete the original layer
@@ -165,7 +174,20 @@ void QgsSymbolV2::drawPreviewIcon( QPainter* painter, QSize size )
165174
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha, false, mRenderHints );
166175
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
167176
{
168-
( *it )->drawPreviewIcon( symbolContext, size );
177+
if ( mType == Fill && ( *it )->type() == Line )
178+
{
179+
// line symbol layer would normally draw just a line
180+
// so we override this case to force it to draw a polygon outline
181+
QgsLineSymbolLayerV2* lsl = ( QgsLineSymbolLayerV2* ) * it;
182+
183+
// from QgsFillSymbolLayerV2::drawPreviewIcon()
184+
QPolygonF poly = QRectF( QPointF( 0, 0 ), QPointF( size.width() - 1, size.height() - 1 ) );
185+
lsl->startRender( symbolContext );
186+
lsl->renderPolygonOutline( poly, NULL, symbolContext );
187+
lsl->stopRender( symbolContext );
188+
}
189+
else
190+
( *it )->drawPreviewIcon( symbolContext, size );
169191
}
170192
}
171193

@@ -456,14 +478,29 @@ void QgsFillSymbolV2::renderPolygon( const QPolygonF& points, QList<QPolygonF>*
456478
if ( layer != -1 )
457479
{
458480
if ( layer >= 0 && layer < mLayers.count() )
459-
(( QgsFillSymbolLayerV2* ) mLayers[layer] )->renderPolygon( points, rings, symbolContext );
481+
{
482+
QgsSymbolV2::SymbolType layertype = mLayers.at( layer )->type();
483+
if ( layertype == QgsSymbolV2::Fill )
484+
(( QgsFillSymbolLayerV2* ) mLayers[layer] )->renderPolygon( points, rings, symbolContext );
485+
else if ( layertype == QgsSymbolV2::Line )
486+
(( QgsLineSymbolLayerV2* ) mLayers[layer] )->renderPolygonOutline( points, rings, symbolContext );
487+
}
460488
return;
461489
}
462490

463491
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
464492
{
465-
QgsFillSymbolLayerV2* layer = ( QgsFillSymbolLayerV2* ) * it;
466-
layer->renderPolygon( points, rings, symbolContext );
493+
QgsSymbolV2::SymbolType layertype = ( *it )->type();
494+
if ( layertype == QgsSymbolV2::Fill )
495+
{
496+
QgsFillSymbolLayerV2* layer = ( QgsFillSymbolLayerV2* ) * it;
497+
layer->renderPolygon( points, rings, symbolContext );
498+
}
499+
else if ( layertype == QgsSymbolV2::Line )
500+
{
501+
QgsLineSymbolLayerV2* layer = ( QgsLineSymbolLayerV2* ) * it;
502+
layer->renderPolygonOutline( points, rings, symbolContext );
503+
}
467504
}
468505
}
469506

src/core/symbology-ng/qgssymbolv2.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,11 @@ class CORE_EXPORT QgsSymbolV2
101101

102102
QgsSymbolLayerV2List cloneLayers() const;
103103

104+
//! check whether a symbol layer type can be used within the symbol
105+
//! (marker-marker, line-line, fill-fill/line)
106+
//! @note added in 1.7
107+
bool isSymbolLayerCompatible( SymbolType t );
108+
104109
SymbolType mType;
105110
QgsSymbolLayerV2List mLayers;
106111

src/gui/symbology-ng/qgssymbolv2propertiesdialog.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,17 @@ void QgsSymbolV2PropertiesDialog::populateLayerTypes()
164164
cboLayerType->clear();
165165
for ( int i = 0; i < types.count(); i++ )
166166
cboLayerType->addItem( QgsSymbolLayerV2Registry::instance()->symbolLayerMetadata( types[i] )->visibleName(), types[i] );
167+
168+
if ( mSymbol->type() == QgsSymbolV2::Fill )
169+
{
170+
QStringList typesLine = QgsSymbolLayerV2Registry::instance()->symbolLayersForType( QgsSymbolV2::Line );
171+
for ( int i = 0; i < typesLine.count(); i++ )
172+
{
173+
QString visibleName = QgsSymbolLayerV2Registry::instance()->symbolLayerMetadata( typesLine[i] )->visibleName();
174+
QString name = QString( tr( "Outline: %1" ) ).arg( visibleName );
175+
cboLayerType->addItem( name, typesLine[i] );
176+
}
177+
}
167178
}
168179

169180

@@ -223,6 +234,10 @@ void QgsSymbolV2PropertiesDialog::loadPropertyWidgets()
223234

224235
QStringList layerTypes = pReg->symbolLayersForType( mSymbol->type() );
225236

237+
// also load line symbol layers for fill symbols
238+
if ( mSymbol->type() == QgsSymbolV2::Fill )
239+
layerTypes += pReg->symbolLayersForType( QgsSymbolV2::Line );
240+
226241
for ( int i = 0; i < layerTypes.count(); i++ )
227242
{
228243
QString layerType = layerTypes[i];

0 commit comments

Comments
 (0)