QGIS API Documentation  2.12.0-Lyon
qgspointdisplacementrendererwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgspointdisplacementrendererwidget.cpp
3  --------------------------------------
4  begin : January 26, 2010
5  copyright : (C) 2010 by Marco Hugentobler
6  email : marco at hugis dot net
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
20 #include "qgsrendererv2registry.h"
21 #include "qgsfield.h"
22 #include "qgsstylev2.h"
24 #include "qgssymbollayerv2utils.h"
25 #include "qgsvectorlayer.h"
26 #include "qgisgui.h"
27 
29 {
30  return new QgsPointDisplacementRendererWidget( layer, style, renderer );
31 }
32 
34  : QgsRendererV2Widget( layer, style )
35  , mRenderer( NULL )
36  , mEmbeddedRendererWidget( 0 )
37 {
38  if ( !layer )
39  {
40  return;
41  }
42 
43  //the renderer only applies to point vector layers
44  if ( layer->wkbType() != QGis::WKBPoint && layer->wkbType() != QGis::WKBPoint25D )
45  {
46  //setup blank dialog
47  mRenderer = 0;
48  setupBlankUi( layer->name() );
49  return;
50  }
51  setupUi( this );
52  mDistanceUnitWidget->setUnits( QgsSymbolV2::OutputUnitList() << QgsSymbolV2::MM << QgsSymbolV2::MapUnit << QgsSymbolV2::Pixel );
53 
54  if ( renderer )
55  {
57  }
58  if ( !mRenderer )
59  {
60  mRenderer = new QgsPointDisplacementRenderer();
61  }
62 
63  blockAllSignals( true );
64 
65  mPlacementComboBox->addItem( tr( "Ring" ), QgsPointDisplacementRenderer::Ring );
66  mPlacementComboBox->addItem( tr( "Concentric rings" ), QgsPointDisplacementRenderer::ConcentricRings );
67 
68  //insert attributes into combo box
69  if ( layer )
70  {
71  const QgsFields& layerAttributes = layer->fields();
72  for ( int idx = 0; idx < layerAttributes.count(); ++idx )
73  {
74  mLabelFieldComboBox->addItem( layerAttributes[idx].name() );
75  }
76  mLabelFieldComboBox->addItem( tr( "None" ) );
77 
78  QString currentLabelAttribute = mRenderer->labelAttributeName();
79  if ( !currentLabelAttribute.isEmpty() )
80  {
81  mLabelFieldComboBox->setCurrentIndex( mLabelFieldComboBox->findText( currentLabelAttribute ) );
82  }
83  else
84  {
85  mLabelFieldComboBox->setCurrentIndex( mLabelFieldComboBox->findText( tr( "None" ) ) );
86  }
87  }
88 
89  //insert possible renderer types
91  QStringList::const_iterator it = rendererList.constBegin();
92  for ( ; it != rendererList.constEnd(); ++it )
93  {
94  if ( *it != "pointDisplacement" && *it != "heatmapRenderer" && *it != "invertedPolygonRenderer" )
95  {
97  mRendererComboBox->addItem( m->icon(), m->visibleName(), *it );
98  }
99  }
100 
101  mCircleColorButton->setColorDialogTitle( tr( "Select color" ) );
102  mCircleColorButton->setContext( "symbology" );
103  mCircleColorButton->setAllowAlpha( true );
104  mCircleColorButton->setShowNoColor( true );
105  mCircleColorButton->setNoColorString( tr( "No outline" ) );
106  mLabelColorButton->setContext( "symbology" );
107  mLabelColorButton->setColorDialogTitle( tr( "Select color" ) );
108  mLabelColorButton->setAllowAlpha( true );
109 
110  mCircleWidthSpinBox->setValue( mRenderer->circleWidth() );
111  mCircleColorButton->setColor( mRenderer->circleColor() );
112  mLabelColorButton->setColor( mRenderer->labelColor() );
113  mCircleModificationSpinBox->setClearValue( 0.0 );
114  mCircleModificationSpinBox->setValue( mRenderer->circleRadiusAddition() );
115  mDistanceSpinBox->setValue( mRenderer->tolerance() );
116  mDistanceUnitWidget->setUnit( mRenderer->toleranceUnit() );
117  mDistanceUnitWidget->setMapUnitScale( mRenderer->toleranceMapUnitScale() );
118 
119  mPlacementComboBox->setCurrentIndex( mPlacementComboBox->findData( mRenderer->placement() ) );
120 
121  //scale dependent labelling
122  mMaxScaleDenominatorEdit->setText( QString::number( mRenderer->maxLabelScaleDenominator() ) );
123  mMaxScaleDenominatorEdit->setValidator( new QDoubleValidator( mMaxScaleDenominatorEdit ) );
124  if ( mRenderer->maxLabelScaleDenominator() > 0 )
125  {
126  mScaleDependentLabelsCheckBox->setCheckState( Qt::Checked );
127  }
128  else
129  {
130  mScaleDependentLabelsCheckBox->setCheckState( Qt::Unchecked );
131  mMaxScaleDenominatorEdit->setEnabled( false );
132  }
133 
134 
135  blockAllSignals( false );
136 
137  //set the appropriate renderer dialog
138  if ( mRenderer->embeddedRenderer() )
139  {
140  QString rendererName = mRenderer->embeddedRenderer()->type();
141  int rendererIndex = mRendererComboBox->findData( rendererName );
142  if ( rendererIndex != -1 )
143  {
144  mRendererComboBox->setCurrentIndex( rendererIndex );
145  on_mRendererComboBox_currentIndexChanged( rendererIndex );
146  }
147  }
148 
149  updateCenterIcon();
150 }
151 
153 {
154  delete mRenderer;
155  delete mEmbeddedRendererWidget;
156 }
157 
159 {
160  if ( mRenderer && mEmbeddedRendererWidget )
161  {
162  QgsFeatureRendererV2* embeddedRenderer = mEmbeddedRendererWidget->renderer();
163  if ( embeddedRenderer )
164  {
165  mRenderer->setEmbeddedRenderer( embeddedRenderer->clone() );
166  }
167  }
168  return mRenderer;
169 }
170 
172 {
174  if ( mDistanceUnitWidget )
175  mDistanceUnitWidget->setMapCanvas( canvas );
176  if ( mEmbeddedRendererWidget )
177  mEmbeddedRendererWidget->setMapCanvas( canvas );
178 }
179 
180 void QgsPointDisplacementRendererWidget::on_mLabelFieldComboBox_currentIndexChanged( const QString& text )
181 {
182  if ( mRenderer )
183  {
184  if ( text == tr( "None" ) )
185  {
186  mRenderer->setLabelAttributeName( "" );
187  }
188  else
189  {
190  mRenderer->setLabelAttributeName( text );
191  }
192  }
193 }
194 
195 void QgsPointDisplacementRendererWidget::on_mRendererComboBox_currentIndexChanged( int index )
196 {
197  QString rendererId = mRendererComboBox->itemData( index ).toString();
199  if ( m )
200  {
201  delete mEmbeddedRendererWidget;
202  mEmbeddedRendererWidget = m->createRendererWidget( mLayer, mStyle, mRenderer->embeddedRenderer()->clone() );
203  mEmbeddedRendererWidget->setMapCanvas( mMapCanvas );
204  }
205 }
206 
207 void QgsPointDisplacementRendererWidget::on_mPlacementComboBox_currentIndexChanged( int index )
208 {
209  if ( !mRenderer )
210  return;
211 
212  mRenderer->setPlacement(( QgsPointDisplacementRenderer::Placement )mPlacementComboBox->itemData( index ).toInt() );
213 }
214 
215 void QgsPointDisplacementRendererWidget::on_mRendererSettingsButton_clicked()
216 {
217  if ( mEmbeddedRendererWidget )
218  {
219  //create a dialog with the embedded widget
220 #ifdef Q_OS_MAC
221  QDialog* d = new QDialog( this->window() );
222  d->setWindowModality( Qt::WindowModal );
223 #else
224  QDialog* d = new QDialog();
225 #endif
226  QGridLayout* layout = new QGridLayout( d );
227  mEmbeddedRendererWidget->setParent( d );
228  QDialogButtonBox* buttonBox = new QDialogButtonBox( d );
229  buttonBox->addButton( QDialogButtonBox::Ok );
230  QObject::connect( buttonBox, SIGNAL( accepted() ), d, SLOT( accept() ) );
231  layout->addWidget( mEmbeddedRendererWidget, 0, 0 );
232  layout->addWidget( buttonBox, 1, 0 );
233  d->exec();
234  mEmbeddedRendererWidget->setParent( 0 );
235  delete d;
236  }
237 }
238 
239 void QgsPointDisplacementRendererWidget::on_mLabelFontButton_clicked()
240 {
241  if ( !mRenderer )
242  {
243  return;
244  }
245 
246  bool ok;
247  QFont newFont = QgisGui::getFont( ok, mRenderer->labelFont(), tr( "Label Font" ) );
248  if ( ok )
249  {
250  mRenderer->setLabelFont( newFont );
251  }
252 }
253 
254 void QgsPointDisplacementRendererWidget::on_mCircleWidthSpinBox_valueChanged( double d )
255 {
256  if ( mRenderer )
257  {
258  mRenderer->setCircleWidth( d );
259  }
260 }
261 
262 void QgsPointDisplacementRendererWidget::on_mCircleColorButton_colorChanged( const QColor& newColor )
263 {
264  if ( !mRenderer )
265  {
266  return;
267  }
268 
269  mRenderer->setCircleColor( newColor );
270 }
271 
272 void QgsPointDisplacementRendererWidget::on_mLabelColorButton_colorChanged( const QColor& newColor )
273 {
274  if ( !mRenderer )
275  {
276  return;
277  }
278 
279  mRenderer->setLabelColor( newColor );
280 }
281 
282 void QgsPointDisplacementRendererWidget::on_mCircleModificationSpinBox_valueChanged( double d )
283 {
284  if ( !mRenderer )
285  {
286  return;
287  }
288 
289  mRenderer->setCircleRadiusAddition( d );
290 }
291 
292 void QgsPointDisplacementRendererWidget::on_mDistanceSpinBox_valueChanged( double d )
293 {
294  if ( mRenderer )
295  {
296  mRenderer->setTolerance( d );
297  }
298 }
299 
300 void QgsPointDisplacementRendererWidget::on_mDistanceUnitWidget_changed()
301 {
302  if ( mRenderer )
303  {
304  mRenderer->setToleranceUnit( mDistanceUnitWidget->unit() );
305  mRenderer->setToleranceMapUnitScale( mDistanceUnitWidget->getMapUnitScale() );
306  }
307 }
308 
309 void QgsPointDisplacementRendererWidget::on_mScaleDependentLabelsCheckBox_stateChanged( int state )
310 {
311  if ( state == Qt::Unchecked )
312  {
313  mMaxScaleDenominatorEdit->setText( "-1" );
314  mMaxScaleDenominatorEdit->setEnabled( false );
315  }
316  else
317  {
318  mMaxScaleDenominatorEdit->setEnabled( true );
319  }
320 }
321 
322 void QgsPointDisplacementRendererWidget::on_mMaxScaleDenominatorEdit_textChanged( const QString & text )
323 {
324  if ( !mRenderer )
325  {
326  return;
327  }
328 
329  bool ok;
330  double scaleDenominator = text.toDouble( &ok );
331  if ( ok )
332  {
333  mRenderer->setMaxLabelScaleDenominator( scaleDenominator );
334  }
335 }
336 
337 void QgsPointDisplacementRendererWidget::blockAllSignals( bool block )
338 {
339  mLabelFieldComboBox->blockSignals( block );
340  mLabelFontButton->blockSignals( block );
341  mCircleWidthSpinBox->blockSignals( block );
342  mCircleColorButton->blockSignals( block );
343  mRendererComboBox->blockSignals( block );
344  mLabelColorButton->blockSignals( block );
345  mCircleModificationSpinBox->blockSignals( block );
346  mScaleDependentLabelsCheckBox->blockSignals( block );
347  mMaxScaleDenominatorEdit->blockSignals( block );
348  mCenterSymbolPushButton->blockSignals( block );
349  mDistanceSpinBox->blockSignals( block );
350  mDistanceUnitWidget->blockSignals( block );
351  mPlacementComboBox->blockSignals( block );
352 }
353 
354 void QgsPointDisplacementRendererWidget::on_mCenterSymbolPushButton_clicked()
355 {
356  if ( !mRenderer || !mRenderer->centerSymbol() )
357  {
358  return;
359  }
360  QgsMarkerSymbolV2* markerSymbol = dynamic_cast<QgsMarkerSymbolV2*>( mRenderer->centerSymbol()->clone() );
361  QgsSymbolV2SelectorDialog dlg( markerSymbol, QgsStyleV2::defaultStyle(), mLayer, this );
362  dlg.setMapCanvas( mMapCanvas );
363  if ( dlg.exec() == QDialog::Rejected )
364  {
365  delete markerSymbol;
366  return;
367  }
368  mRenderer->setCenterSymbol( markerSymbol );
369  updateCenterIcon();
370 }
371 
372 void QgsPointDisplacementRendererWidget::updateCenterIcon()
373 {
374  QgsMarkerSymbolV2* symbol = mRenderer->centerSymbol();
375  if ( !symbol )
376  {
377  return;
378  }
379  QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( symbol, mCenterSymbolPushButton->iconSize() );
380  mCenterSymbolPushButton->setIcon( icon );
381 }
382 
383 void QgsPointDisplacementRendererWidget::setupBlankUi( const QString& layerName )
384 {
385  QGridLayout* layout = new QGridLayout( this );
386  QLabel* label = new QLabel( tr( "The point displacement renderer only applies to (single) point layers. \n'%1' is not a point layer and cannot be displayed by the point displacement renderer" ).arg( layerName ), this );
387  layout->addWidget( label );
388 }
QLayout * layout() const
static QgsRendererV2Registry * instance()
static unsigned index
Placement
Placement methods for dispersing points.
void setupUi(QWidget *widget)
double tolerance() const
Returns the tolerance distance for grouping points.
void addWidget(QWidget *widget, int row, int column, QFlags< Qt::AlignmentFlag > alignment)
QWidget * window() const
void setWindowModality(Qt::WindowModality windowModality)
QgsFields fields() const
Returns the list of fields of this layer.
void setLabelAttributeName(const QString &name)
QFont getFont(bool &ok, const QFont &initial, const QString &title)
Show font selection dialog.
Definition: qgisgui.cpp:191
void setCenterSymbol(QgsMarkerSymbolV2 *symbol)
Sets the center symbol (takes ownership)
void addButton(QAbstractButton *button, ButtonRole role)
The output shall be in pixels.
Definition: qgssymbolv2.h:60
QgsMapCanvas * mMapCanvas
const QgsMapUnitScale & toleranceMapUnitScale() const
Returns the map unit scale object for the distance tolerance.
int exec()
Container of fields for a vector layer.
Definition: qgsfield.h:177
static QgsPointDisplacementRenderer * convertFromRenderer(const QgsFeatureRendererV2 *renderer)
creates a QgsPointDisplacementRenderer from an existing renderer.
Stores metadata about one renderer class.
const QPixmap * icon() const
double toDouble(bool *ok) const
QString tr(const char *sourceText, const char *disambiguation, int n)
void setParent(QWidget *parent)
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:107
QgsRendererV2AbstractMetadata * rendererMetadata(const QString &rendererName)
get metadata for particular renderer. Returns NULL if not found in registry.
QGis::WkbType wkbType() const
Returns the WKBType or WKBUnknown in case of error.
void setToleranceUnit(QgsSymbolV2::OutputUnit unit)
Sets the units for the tolerance distance.
QString type() const
Definition: qgsrendererv2.h:82
const QString & name() const
Get the display name of the layer.
const char * name() const
virtual QgsFeatureRendererV2 * clone() const =0
The output shall be in millimeters.
Definition: qgssymbolv2.h:57
QString number(int n, int base)
static QIcon symbolPreviewIcon(QgsSymbolV2 *symbol, QSize size)
QgsVectorLayer * mLayer
void setEmbeddedRenderer(QgsFeatureRendererV2 *r)
Sets embedded renderer (takes ownership)
QStringList renderersList()
return a list of available renderers
void setMapCanvas(QgsMapCanvas *canvas) override
Sets the map canvas associated with the widget.
static QgsStyleV2 * defaultStyle()
return default application-wide style
Definition: qgsstylev2.cpp:51
bool isEmpty() const
The output shall be in map unitx.
Definition: qgssymbolv2.h:58
virtual QgsSymbolV2 * clone() const override
QgsFeatureRendererV2 * renderer() override
return pointer to the renderer (no transfer of ownership)
Placement placement() const
Returns the placement method used for dispersing the points.
int count() const
Return number of items.
Definition: qgsfield.cpp:311
void setPlacement(Placement placement)
Sets the placement method used for dispersing the points.
QgsPointDisplacementRendererWidget(QgsVectorLayer *layer, QgsStyleV2 *style, QgsFeatureRendererV2 *renderer)
QgsFeatureRendererV2 * embeddedRenderer() const
A renderer that automatically displaces points with the same position.
Base class for renderer settings widgets.
virtual QgsRendererV2Widget * createRendererWidget(QgsVectorLayer *layer, QgsStyleV2 *style, QgsFeatureRendererV2 *renderer)
Return new instance of settings widget for the renderer.
void setToleranceMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the distance tolerance.
static QgsRendererV2Widget * create(QgsVectorLayer *layer, QgsStyleV2 *style, QgsFeatureRendererV2 *renderer)
const_iterator constEnd() const
const_iterator constBegin() const
QgsSymbolV2::OutputUnit toleranceUnit() const
Returns the units for the tolerance distance.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QgsMarkerSymbolV2 * centerSymbol()
Returns the symbol for the center of a displacement group (but not ownership of the symbol) ...
Represents a vector layer which manages a vector based data sets.
virtual QgsFeatureRendererV2 * renderer()=0
return pointer to the renderer (no transfer of ownership)
virtual void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
void setTolerance(double t)
Sets the tolerance distance for grouping points.