Skip to content

Commit 0c59c74

Browse files
author
jef
committed
[FEATURE] symbology enhancements:
- add QgsMarkerCatalogue::refreshList() to refresh the symbol list w/o restart - allow refresh of symbols via popup menu on the renderer's symbol selection - add support for data define symbol(name)s - add support for font symbol markers (only data define - no gui yet) - pass QgsRenderContext to rendering methods - add symbol size in map units (ie. symbols that keep the size in mapunits independant of the mapscale) git-svn-id: http://svn.osgeo.org/qgis/trunk@11152 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent c3f6fb8 commit 0c59c74

28 files changed

+738
-410
lines changed

python/core/qgscontinuouscolorrenderer.sip

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ class QgsContinuousColorRenderer : QgsRenderer
1010
QgsContinuousColorRenderer(QGis::GeometryType type);
1111
QgsContinuousColorRenderer(const QgsContinuousColorRenderer& other);
1212
virtual ~QgsContinuousColorRenderer();
13-
/**Renders the feature using the minimum and maximum value of the classification field*/
14-
void renderFeature(QPainter* p, QgsFeature& f, QImage* img, bool selected, double widthScale = 1.0, double rasterScaleFactor = 1.0);
13+
/**Renders the feature using the minimum and maximum value of the classification field
14+
* added in 1.2 */
15+
void renderFeature(QgsRenderContext &renderContext, QgsFeature& f, QImage* img, bool selected);
1516
/**Returns the number of the classification field*/
1617
int classificationField() const;
1718
/**Sets the id of the classification field*/

python/core/qgsgraduatedsymbolrenderer.sip

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ class QgsGraduatedSymbolRenderer : QgsRenderer
4848
@param f a pointer to the feature to determine if rendering will happen*/
4949
bool willRenderFeature(QgsFeature *f);
5050

51-
/**Renders an OGRFeature
51+
/**Renders a feature
5252
\param p a painter (usually the one from the current map canvas)
5353
\param f a pointer to a feature to render
5454
\param t the transform object containing the information how to transform the map coordinates to screen coordinates*/
55-
void renderFeature(QPainter* p, QgsFeature& f, QImage* img, bool selected, double widthScale = 1.0, double rasterScaleFactor = 1.0);
55+
void renderFeature(QgsRenderContext &renderContext, QgsFeature& f, QImage* img, bool selected);
5656

5757
/**Sets the number of the classicifation field
5858
\param field the number of the field to classify*/

python/core/qgslabel.sip

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,24 @@ public:
4545
QgsPoint p;
4646
double angle;
4747
};
48-
48+
49+
4950
/** \brief render label
50-
* \param sizeScale global scale factor for size in pixels, labels in map units are not scaled
51-
*/
51+
\note deprecated
52+
*/
5253
void renderLabel ( QPainter* painter, QgsRectangle& viewExtent,
5354
QgsCoordinateTransform* coordinateTransform,
5455
QgsMapToPixel *transform,
5556
QgsFeature &feature, bool selected, QgsLabelAttributes *classAttributes=0, double sizeScale = 1, double rasterScaleFactor = 1);
57+
58+
/** \brief render label
59+
* \param renderContext renderer context
60+
* \param feature feature to render
61+
* \param selected is to be shown selected
62+
* \param classAttributes attributes to use for labeling
63+
* \note added in 1.2
64+
*/
65+
void renderLabel ( QgsRenderContext &renderContext, QgsFeature &feature, bool selected, QgsLabelAttributes *classAttributes=0);
5666

5767
/** Reads the renderer configuration from an XML file
5868
@param rnode the Dom node to read

python/core/qgsmarkercatalogue.sip

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
/** Catalogue of point symbols */
3-
class QgsMarkerCatalogue /NoDefaultCtors/
3+
class QgsMarkerCatalogue : QObject /NoDefaultCtors/
44
{
55
%TypeHeaderCode
66
#include <qgsmarkercatalogue.h>
@@ -29,5 +29,15 @@ public:
2929
/** Returns a pixmap given a file name of a svg marker
3030
* NOTE: this method needs to be public static for QgsMarkerDialog::visualizeMarkers */
3131
static void svgMarker (QPainter * thepPainter, QString name, int size );
32+
33+
public slots:
34+
// reload the symbols
35+
// added in 1.2
36+
void refreshList();
37+
38+
signals:
39+
// symbols were reloaded
40+
// added in 1.2
41+
void markersRefreshed();
3242
};
3343

python/core/qgsrenderer.sip

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,22 @@ class QgsRenderer
1515
@param p the painter storing brush and pen
1616
@param f a pointer to the feature to be rendered
1717
@param pic pointer to a marker from SVG (is only used by marker renderers)
18-
@param scalefactor pointer to the scale factor for the marker image*/
19-
virtual void renderFeature(QPainter* p, QgsFeature& f,QImage* pic, bool selected, double widthScale = 1.0, double rasterScaleFactor = 1.0)=0;
18+
@param selected feature is to be shown selected
19+
@param widthScale scale factor
20+
@param rasterScaleFactor scale factor for rasters
21+
22+
deprecated */
23+
void renderFeature(QPainter* p, QgsFeature& f,QImage* pic, bool selected, double widthScale = 1.0, double rasterScaleFactor = 1.0);
24+
25+
/**A vector layer passes features to a renderer object to change the brush ans pen of the qpainter
26+
@param renderContext context of the rendering operation
27+
@param f the feature to render
28+
@param pic pointer to marker to render (is only used by marker renderers)
29+
@param selected the feature is to be shown selected
30+
31+
added in 1.2 */
32+
virtual void renderFeature(QgsRenderContext &renderContext, QgsFeature& f,QImage* pic, bool selected)=0;
33+
2034
/**Reads the renderer configuration from an XML file
2135
@param rnode the Dom node to read
2236
@param vl the vector layer which will be associated with the renderer*/

python/core/qgssinglesymbolrenderer.sip

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@ class QgsSingleSymbolRenderer : QgsRenderer
99
QgsSingleSymbolRenderer(QGis::GeometryType type);
1010
QgsSingleSymbolRenderer(const QgsSingleSymbolRenderer& other);
1111
virtual ~QgsSingleSymbolRenderer();
12+
1213
/**Replaces the current mSymbol by sy*/
1314
void addSymbol(QgsSymbol* sy /Transfer/);
1415
/*Returns a pointer to mSymbol*/
1516
const QgsSymbol* symbol() const;
16-
/**Renders an OGRFeature*/
17-
void renderFeature(QPainter* p, QgsFeature& f, QImage* img, bool selected, double widthScale = 1.0, double rasterScaleFactor = 1.0);
17+
18+
/**Renders a feature added in 1.2 */
19+
void renderFeature(QgsRenderContext &renderContext, QgsFeature& f, QImage* img, bool selected);
20+
1821
/**Reads the renderer configuration from an XML file
1922
@param rnode the Dom node to read
2023
@param vl the vector layer which will be associated with the renderer*/

python/core/qgsuniquevaluerenderer.sip

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ class QgsUniqueValueRenderer : QgsRenderer
1111
/** Determines if a feature will be rendered or not
1212
@param f a pointer to the feature to determine if rendering will happen*/
1313
bool willRenderFeature(QgsFeature *f);
14-
void renderFeature(QPainter* p, QgsFeature& f, QImage* img, bool selected, double widthScale = 1.0, double rasterScaleFactor = 1.0);
14+
15+
/* render feature
16+
* added in 1.2 */
17+
void renderFeature(QgsRenderContext &renderContext, QgsFeature& f, QImage* img, bool selected);
18+
1519
/**Reads the renderer configuration from an XML file
1620
@param rnode the Dom node to read
1721
@param vl the vector layer which will be associated with the renderer*/

src/app/qgssinglesymboldialog.cpp

Lines changed: 71 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ QgsSingleSymbolDialog::QgsSingleSymbolDialog(): QDialog(), mVectorLayer( 0 )
4040
QgsDebugMsg( "entered." );
4141
}
4242

43-
QgsSingleSymbolDialog::QgsSingleSymbolDialog( QgsVectorLayer * layer, bool disabled ): QDialog(), mVectorLayer( layer )
43+
QgsSingleSymbolDialog::QgsSingleSymbolDialog( QgsVectorLayer * layer, bool disabled ): QDialog(), mVectorLayer( layer ), mDisabled( disabled )
4444
{
4545
setupUi( this );
4646
QgsDebugMsg( "entered." );
@@ -59,6 +59,43 @@ QgsSingleSymbolDialog::QgsSingleSymbolDialog( QgsVectorLayer * layer, bool disab
5959
// loops can be removed now with changes I have made to use combo
6060
// boxes for line style and fill style...test and remove if poss.
6161

62+
QAction *refreshAction = new QAction( tr( "Refresh markers" ), lstSymbols );
63+
lstSymbols->addAction( refreshAction );
64+
connect( refreshAction, SIGNAL( triggered() ), QgsMarkerCatalogue::instance(), SLOT( refreshList() ) );
65+
connect( QgsMarkerCatalogue::instance(), SIGNAL( markersRefreshed() ), this, SLOT( refreshMarkers() ) );
66+
lstSymbols->setContextMenuPolicy( Qt::ActionsContextMenu );
67+
68+
//do the signal/slot connections
69+
connect( btnOutlineColor, SIGNAL( clicked() ), this, SLOT( selectOutlineColor() ) );
70+
connect( btnFillColor, SIGNAL( clicked() ), this, SLOT( selectFillColor() ) );
71+
connect( outlinewidthspinbox, SIGNAL( valueChanged( double ) ), this, SLOT( resendSettingsChanged() ) );
72+
connect( mLabelEdit, SIGNAL( textChanged( const QString& ) ), this, SLOT( resendSettingsChanged() ) );
73+
connect( lstSymbols, SIGNAL( currentItemChanged( QListWidgetItem *, QListWidgetItem * ) ),
74+
this, SLOT( symbolChanged( QListWidgetItem *, QListWidgetItem * ) ) );
75+
connect( mPointSizeSpinBox, SIGNAL( valueChanged( double ) ), this, SLOT( resendSettingsChanged() ) );
76+
connect( mPointSizeUnitsCheckBox, SIGNAL( toggled() ), this, SLOT( resendSettingsChanged() ) );
77+
connect( mRotationClassificationComboBox, SIGNAL( currentIndexChanged( const QString & ) ),
78+
this, SLOT( resendSettingsChanged() ) );
79+
connect( mScaleClassificationComboBox, SIGNAL( currentIndexChanged( const QString & ) ),
80+
this, SLOT( resendSettingsChanged() ) );
81+
connect( mSymbolComboBox, SIGNAL( currentIndexChanged( const QString & ) ),
82+
this, SLOT( resendSettingsChanged() ) );
83+
connect( cboOutlineStyle, SIGNAL(
84+
currentIndexChanged( const QString & ) ), this, SLOT( resendSettingsChanged() ) );
85+
connect( cboFillStyle, SIGNAL(
86+
currentIndexChanged( const QString & ) ), this, SLOT( resendSettingsChanged() ) );
87+
//need this to deal with when texture fill is selected or deselected
88+
connect( cboFillStyle, SIGNAL(
89+
currentIndexChanged( int ) ), this, SLOT( fillStyleChanged( int ) ) );
90+
connect( toolSelectTexture, SIGNAL( clicked() ), this, SLOT( selectTextureImage() ) );
91+
92+
refreshMarkers();
93+
}
94+
95+
void QgsSingleSymbolDialog::refreshMarkers()
96+
{
97+
lstSymbols->blockSignals( true );
98+
lstSymbols->clear();
6299

63100
QPen pen( QColor( 0, 0, 255 ) );
64101
QBrush brush( QColor( 220, 220, 220 ), Qt::SolidPattern );
@@ -73,17 +110,18 @@ QgsSingleSymbolDialog::QgsSingleSymbolDialog( QgsVectorLayer * layer, bool disab
73110
myIcon.addPixmap( myPixmap );
74111
mypItem->setIcon( myIcon );
75112
mypItem->setText( "" );
113+
mypItem->setToolTip( *it );
76114
//store the symbol offset in the UserData role for later retrieval
77115
mypItem->setData( Qt::UserRole, *it );
78116
mypItem->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled );
79-
if ( layer->geometryType() != QGis::Point )
117+
if ( mVectorLayer && mVectorLayer->geometryType() != QGis::Point )
80118
{
81119
break;
82120
}
83121
++myCounter;
84122
}
85123

86-
// Find out the numerical fields of mVectorLayer, and populate the ComboBox
124+
// Find out the numerical fields of mVectorLayer, and populate the ComboBoxes
87125
QgsVectorDataProvider *provider = mVectorLayer->dataProvider();
88126
if ( provider )
89127
{
@@ -92,6 +130,7 @@ QgsSingleSymbolDialog::QgsSingleSymbolDialog( QgsVectorLayer * layer, bool disab
92130

93131
mRotationClassificationComboBox->addItem( DO_NOT_USE_STR, -1 );
94132
mScaleClassificationComboBox->addItem( DO_NOT_USE_STR, -1 );
133+
mSymbolComboBox->addItem( DO_NOT_USE_STR, -1 );
95134
for ( QgsFieldMap::const_iterator it = fields.begin();
96135
it != fields.end();
97136
++it )
@@ -102,6 +141,10 @@ QgsSingleSymbolDialog::QgsSingleSymbolDialog( QgsVectorLayer * layer, bool disab
102141
mRotationClassificationComboBox->addItem( it->name(), it.key() );
103142
mScaleClassificationComboBox->addItem( it->name(), it.key() );
104143
}
144+
else if ( type == QVariant::String )
145+
{
146+
mSymbolComboBox->addItem( it->name(), it.key() );
147+
}
105148
}
106149
}
107150
else
@@ -139,13 +182,13 @@ QgsSingleSymbolDialog::QgsSingleSymbolDialog( QgsVectorLayer * layer, bool disab
139182
cboFillStyle->addItem( QIcon( QgsSymbologyUtils::char2PatternPixmap( "NoBrush" ) ), tr( "No Brush" ), "NoBrush" );
140183
cboFillStyle->addItem( QIcon( QgsSymbologyUtils::char2PatternPixmap( "TexturePattern" ) ), tr( "Texture" ), "TexturePattern" );
141184

142-
if ( mVectorLayer && layer->geometryType() != QGis::Point )
185+
if ( mVectorLayer && mVectorLayer->geometryType() != QGis::Point )
143186
{
144187
mGroupPoint->setVisible( false );
145188
mGroupPoint->setEnabled( false );
146189
}
147190

148-
if ( disabled )
191+
if ( mDisabled )
149192
{
150193
unset();
151194
}
@@ -173,27 +216,7 @@ QgsSingleSymbolDialog::QgsSingleSymbolDialog( QgsVectorLayer * layer, bool disab
173216
}
174217
}
175218

176-
//do the signal/slot connections
177-
connect( btnOutlineColor, SIGNAL( clicked() ), this, SLOT( selectOutlineColor() ) );
178-
connect( btnFillColor, SIGNAL( clicked() ), this, SLOT( selectFillColor() ) );
179-
connect( outlinewidthspinbox, SIGNAL( valueChanged( double ) ), this, SLOT( resendSettingsChanged() ) );
180-
connect( mLabelEdit, SIGNAL( textChanged( const QString& ) ), this, SLOT( resendSettingsChanged() ) );
181-
connect( lstSymbols, SIGNAL( currentItemChanged( QListWidgetItem *, QListWidgetItem * ) ),
182-
this, SLOT( symbolChanged( QListWidgetItem *, QListWidgetItem * ) ) );
183-
connect( mPointSizeSpinBox, SIGNAL( valueChanged( double ) ), this, SLOT( resendSettingsChanged() ) );
184-
connect( mRotationClassificationComboBox, SIGNAL( currentIndexChanged( const QString & ) ),
185-
this, SLOT( resendSettingsChanged() ) );
186-
connect( mScaleClassificationComboBox, SIGNAL( currentIndexChanged( const QString & ) ),
187-
this, SLOT( resendSettingsChanged() ) );
188-
connect( cboOutlineStyle, SIGNAL(
189-
currentIndexChanged( const QString & ) ), this, SLOT( resendSettingsChanged() ) );
190-
connect( cboFillStyle, SIGNAL(
191-
currentIndexChanged( const QString & ) ), this, SLOT( resendSettingsChanged() ) );
192-
//need this to deal with when texture fill is selected or deselected
193-
connect( cboFillStyle, SIGNAL(
194-
currentIndexChanged( int ) ), this, SLOT( fillStyleChanged( int ) ) );
195-
connect( toolSelectTexture, SIGNAL( clicked() ), this, SLOT( selectTextureImage() ) );
196-
219+
lstSymbols->blockSignals( false );
197220
}
198221

199222
QgsSingleSymbolDialog::~QgsSingleSymbolDialog()
@@ -264,6 +287,8 @@ void QgsSingleSymbolDialog::apply( QgsSymbol *sy )
264287
if ( mPointSizeSpinBox->isEnabled() )
265288
sy->setPointSize( mPointSizeSpinBox->value() );
266289

290+
if ( mPointSizeUnitsCheckBox->isEnabled() )
291+
sy->setPointSizeUnits( mPointSizeUnitsCheckBox->isChecked() );
267292

268293
std::map<QString, int>::iterator iter;
269294
if ( mRotationClassificationComboBox->isEnabled() )
@@ -276,6 +301,11 @@ void QgsSingleSymbolDialog::apply( QgsSymbol *sy )
276301
sy->setScaleClassificationField( mScaleClassificationComboBox->itemData( mScaleClassificationComboBox->currentIndex() ).toInt() );
277302
}
278303

304+
if ( mSymbolComboBox->isEnabled() )
305+
{
306+
sy->setSymbolField( mSymbolComboBox->itemData( mSymbolComboBox->currentIndex() ).toInt() );
307+
}
308+
279309
//
280310
// Apply the line style
281311
//
@@ -323,8 +353,10 @@ void QgsSingleSymbolDialog::unset()
323353
mLabelEdit->setEnabled( false );
324354
lstSymbols->setEnabled( false );
325355
mPointSizeSpinBox->setEnabled( false );
356+
mPointSizeUnitsCheckBox->setEnabled( false );
326357
mRotationClassificationComboBox->setEnabled( false );
327358
mScaleClassificationComboBox->setEnabled( false );
359+
mSymbolComboBox->setEnabled( false );
328360
outlinewidthspinbox->setEnabled( false );
329361
btnOutlineColor->setEnabled( false );
330362
cboOutlineStyle->setEnabled( false );
@@ -350,6 +382,7 @@ void QgsSingleSymbolDialog::set( const QgsSymbol *sy )
350382
}
351383
}
352384
mPointSizeSpinBox->setValue( sy->pointSize() );
385+
mPointSizeUnitsCheckBox->setChecked( sy->pointSizeUnits() );
353386

354387
int index;
355388

@@ -359,6 +392,9 @@ void QgsSingleSymbolDialog::set( const QgsSymbol *sy )
359392
index = mScaleClassificationComboBox->findData( sy->scaleClassificationField() );
360393
mScaleClassificationComboBox->setCurrentIndex( index < 0 ? 0 : index );
361394

395+
index = mSymbolComboBox->findData( sy->symbolField() );
396+
mSymbolComboBox->setCurrentIndex( index < 0 ? 0 : index );
397+
362398
outlinewidthspinbox->setValue( sy->pen().widthF() );
363399

364400
//set line width 1 as minimum to avoid confusion between line width 0 and no pen line style
@@ -418,8 +454,10 @@ void QgsSingleSymbolDialog::set( const QgsSymbol *sy )
418454
mLabelEdit->setEnabled( true );
419455
lstSymbols->setEnabled( true );
420456
mPointSizeSpinBox->setEnabled( true );
457+
mPointSizeUnitsCheckBox->setEnabled( true );
421458
mRotationClassificationComboBox->setEnabled( true );
422459
mScaleClassificationComboBox->setEnabled( true );
460+
mSymbolComboBox->setEnabled( true );
423461
outlinewidthspinbox->setEnabled( true );
424462
btnOutlineColor->setEnabled( true );
425463
cboOutlineStyle->setEnabled( true );
@@ -442,6 +480,9 @@ void QgsSingleSymbolDialog::updateSet( const QgsSymbol *sy )
442480
if ( mPointSizeSpinBox->isEnabled() && mPointSizeSpinBox->value() != sy->pointSize() )
443481
mPointSizeSpinBox->setEnabled( false );
444482

483+
if ( mPointSizeUnitsCheckBox->isEnabled() && mPointSizeUnitsCheckBox->isChecked() != sy->pointSizeUnits() )
484+
mPointSizeUnitsCheckBox->setEnabled( false );
485+
445486
if ( mRotationClassificationComboBox->isEnabled() &&
446487
mRotationClassificationComboBox->itemData( mRotationClassificationComboBox->currentIndex() ).toInt() != sy->rotationClassificationField() )
447488
mRotationClassificationComboBox->setEnabled( false );
@@ -450,6 +491,10 @@ void QgsSingleSymbolDialog::updateSet( const QgsSymbol *sy )
450491
mScaleClassificationComboBox->itemData( mScaleClassificationComboBox->currentIndex() ).toInt() != sy->scaleClassificationField() )
451492
mScaleClassificationComboBox->setEnabled( false );
452493

494+
if ( mSymbolComboBox->isEnabled() &&
495+
mSymbolComboBox->itemData( mSymbolComboBox->currentIndex() ).toInt() != sy->symbolField() )
496+
mSymbolComboBox->setEnabled( false );
497+
453498
if ( outlinewidthspinbox->isEnabled() && outlinewidthspinbox->value() != sy->pen().widthF() )
454499
outlinewidthspinbox->setEnabled( false );
455500

src/app/qgssinglesymboldialog.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class QgsSingleSymbolDialog: public QDialog, private Ui::QgsSingleSymbolDialogBa
4848

4949
protected:
5050
QgsVectorLayer* mVectorLayer;
51+
bool mDisabled;
5152

5253
public slots:
5354
/* arrange the widgets on this dialog to reflect the current state of QgsSymbol */
@@ -65,6 +66,8 @@ class QgsSingleSymbolDialog: public QDialog, private Ui::QgsSingleSymbolDialogBa
6566
*/
6667
void fillStyleChanged( int theIndex );
6768

69+
void refreshMarkers();
70+
6871
protected slots:
6972
void selectOutlineColor();
7073
void selectFillColor();

src/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ composer/qgscomposerpicture.h
182182
composer/qgscomposerscalebar.h
183183
composer/qgscomposeritemgroup.h
184184
composer/qgslegendmodel.h
185+
symbology/qgsmarkercatalogue.h
185186
raster/qgsrasterlayer.h
186187
)
187188

0 commit comments

Comments
 (0)