QGIS API Documentation  2.17.0-Master (bf77d09)
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( nullptr )
36  , mEmbeddedRendererWidget( nullptr )
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 = nullptr;
48  setupBlankUi( layer->name() );
49  return;
50  }
51  setupUi( this );
52 
53  mDistanceUnitWidget->setUnits( QgsSymbolV2::OutputUnitList() << QgsSymbolV2::MM << QgsSymbolV2::MapUnit << QgsSymbolV2::Pixel );
54 
55  if ( renderer )
56  {
58  }
59  if ( !mRenderer )
60  {
61  mRenderer = new QgsPointDisplacementRenderer();
62  }
63 
64  blockAllSignals( true );
65 
66  mPlacementComboBox->addItem( tr( "Ring" ), QgsPointDisplacementRenderer::Ring );
67  mPlacementComboBox->addItem( tr( "Concentric rings" ), QgsPointDisplacementRenderer::ConcentricRings );
68 
69  //insert attributes into combo box
70  if ( layer )
71  {
72  Q_FOREACH ( const QgsField& f, layer->fields() )
73  {
74  mLabelFieldComboBox->addItem( f.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" )
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  emit widgetChanged();
193  }
194 }
195 
196 void QgsPointDisplacementRendererWidget::on_mRendererComboBox_currentIndexChanged( int index )
197 {
198  QString rendererId = mRendererComboBox->itemData( index ).toString();
200  if ( m )
201  {
202  delete mEmbeddedRendererWidget;
203  mEmbeddedRendererWidget = m->createRendererWidget( mLayer, mStyle, mRenderer->embeddedRenderer()->clone() );
204  mEmbeddedRendererWidget->setMapCanvas( mMapCanvas );
205  emit widgetChanged();
206  }
207 }
208 
209 void QgsPointDisplacementRendererWidget::on_mPlacementComboBox_currentIndexChanged( int index )
210 {
211  if ( !mRenderer )
212  return;
213 
214  mRenderer->setPlacement(( QgsPointDisplacementRenderer::Placement )mPlacementComboBox->itemData( index ).toInt() );
215  emit widgetChanged();
216 }
217 
218 void QgsPointDisplacementRendererWidget::on_mRendererSettingsButton_clicked()
219 {
220  if ( mEmbeddedRendererWidget )
221  {
222  //create a dialog with the embedded widget
223 #ifdef Q_OS_MAC
224  QDialog* d = new QDialog( this->window() );
225  d->setWindowModality( Qt::WindowModal );
226 #else
227  QDialog* d = new QDialog();
228 #endif
229  QGridLayout* layout = new QGridLayout( d );
230  mEmbeddedRendererWidget->setParent( d );
231  QDialogButtonBox* buttonBox = new QDialogButtonBox( d );
232  buttonBox->addButton( QDialogButtonBox::Ok );
233  QObject::connect( buttonBox, SIGNAL( accepted() ), d, SLOT( accept() ) );
234  layout->addWidget( mEmbeddedRendererWidget, 0, 0 );
235  layout->addWidget( buttonBox, 1, 0 );
236  d->exec();
237  mEmbeddedRendererWidget->setParent( nullptr );
238  delete d;
239  emit widgetChanged();
240  }
241 }
242 
243 void QgsPointDisplacementRendererWidget::on_mLabelFontButton_clicked()
244 {
245  if ( !mRenderer )
246  {
247  return;
248  }
249 
250  bool ok;
251  QFont newFont = QgisGui::getFont( ok, mRenderer->labelFont(), tr( "Label Font" ) );
252  if ( ok )
253  {
254  mRenderer->setLabelFont( newFont );
255  emit widgetChanged();
256  }
257 }
258 
259 void QgsPointDisplacementRendererWidget::on_mCircleWidthSpinBox_valueChanged( double d )
260 {
261  if ( mRenderer )
262  {
263  mRenderer->setCircleWidth( d );
264  emit widgetChanged();
265  }
266 }
267 
268 void QgsPointDisplacementRendererWidget::on_mCircleColorButton_colorChanged( const QColor& newColor )
269 {
270  if ( !mRenderer )
271  {
272  return;
273  }
274 
275  mRenderer->setCircleColor( newColor );
276  emit widgetChanged();
277 }
278 
279 void QgsPointDisplacementRendererWidget::on_mLabelColorButton_colorChanged( const QColor& newColor )
280 {
281  if ( !mRenderer )
282  {
283  return;
284  }
285 
286  mRenderer->setLabelColor( newColor );
287  emit widgetChanged();
288 }
289 
290 void QgsPointDisplacementRendererWidget::on_mCircleModificationSpinBox_valueChanged( double d )
291 {
292  if ( !mRenderer )
293  {
294  return;
295  }
296 
297  mRenderer->setCircleRadiusAddition( d );
298  emit widgetChanged();
299 }
300 
301 void QgsPointDisplacementRendererWidget::on_mDistanceSpinBox_valueChanged( double d )
302 {
303  if ( mRenderer )
304  {
305  mRenderer->setTolerance( d );
306  emit widgetChanged();
307  }
308 }
309 
310 void QgsPointDisplacementRendererWidget::on_mDistanceUnitWidget_changed()
311 {
312  if ( mRenderer )
313  {
314  mRenderer->setToleranceUnit( mDistanceUnitWidget->unit() );
315  mRenderer->setToleranceMapUnitScale( mDistanceUnitWidget->getMapUnitScale() );
316  emit widgetChanged();
317  }
318 }
319 
320 void QgsPointDisplacementRendererWidget::on_mScaleDependentLabelsCheckBox_stateChanged( int state )
321 {
322  if ( state == Qt::Unchecked )
323  {
324  mMaxScaleDenominatorEdit->setText( "-1" );
325  mMaxScaleDenominatorEdit->setEnabled( false );
326  }
327  else
328  {
329  mMaxScaleDenominatorEdit->setEnabled( true );
330  }
331 }
332 
333 void QgsPointDisplacementRendererWidget::on_mMaxScaleDenominatorEdit_textChanged( const QString & text )
334 {
335  if ( !mRenderer )
336  {
337  return;
338  }
339 
340  bool ok;
341  double scaleDenominator = text.toDouble( &ok );
342  if ( ok )
343  {
344  mRenderer->setMaxLabelScaleDenominator( scaleDenominator );
345  emit widgetChanged();
346  }
347 }
348 
349 void QgsPointDisplacementRendererWidget::blockAllSignals( bool block )
350 {
351  mLabelFieldComboBox->blockSignals( block );
352  mLabelFontButton->blockSignals( block );
353  mCircleWidthSpinBox->blockSignals( block );
354  mCircleColorButton->blockSignals( block );
355  mRendererComboBox->blockSignals( block );
356  mLabelColorButton->blockSignals( block );
357  mCircleModificationSpinBox->blockSignals( block );
358  mScaleDependentLabelsCheckBox->blockSignals( block );
359  mMaxScaleDenominatorEdit->blockSignals( block );
360  mCenterSymbolPushButton->blockSignals( block );
361  mDistanceSpinBox->blockSignals( block );
362  mDistanceUnitWidget->blockSignals( block );
363  mPlacementComboBox->blockSignals( block );
364 }
365 
366 void QgsPointDisplacementRendererWidget::on_mCenterSymbolPushButton_clicked()
367 {
368  if ( !mRenderer || !mRenderer->centerSymbol() )
369  {
370  return;
371  }
372  QgsMarkerSymbolV2* markerSymbol = mRenderer->centerSymbol()->clone();
373  QgsSymbolV2SelectorDialog dlg( markerSymbol, QgsStyleV2::defaultStyle(), mLayer, this );
374  dlg.setMapCanvas( mMapCanvas );
375  if ( dlg.exec() == QDialog::Rejected )
376  {
377  delete markerSymbol;
378  return;
379  }
380  mRenderer->setCenterSymbol( markerSymbol );
381  updateCenterIcon();
382  emit widgetChanged();
383 }
384 
385 void QgsPointDisplacementRendererWidget::updateCenterIcon()
386 {
387  QgsMarkerSymbolV2* symbol = mRenderer->centerSymbol();
388  if ( !symbol )
389  {
390  return;
391  }
392  QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( symbol, mCenterSymbolPushButton->iconSize() );
393  mCenterSymbolPushButton->setIcon( icon );
394 }
395 
396 void QgsPointDisplacementRendererWidget::setupBlankUi( const QString& layerName )
397 {
398  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 );
399  QVBoxLayout* layout = new QVBoxLayout( this );
400  layout->setContentsMargins( 0, 0, 0, 0 );
401  layout->addWidget( label );
402 }
QLayout * layout() const
static QgsRendererV2Registry * instance()
Returns a pointer to the QgsRendererV2Registry singleton.
static unsigned index
Placement
Placement methods for dispersing points.
void setContentsMargins(int left, int top, int right, int bottom)
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)
QStyle * style() const
void addButton(QAbstractButton *button, ButtonRole role)
The output shall be in pixels.
Definition: qgssymbolv2.h:70
QgsMapCanvas * mMapCanvas
const QgsMapUnitScale & toleranceMapUnitScale() const
Returns the map unit scale object for the distance tolerance.
int exec()
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:109
QgsRendererV2AbstractMetadata * rendererMetadata(const QString &rendererName)
Returns the metadata for a specified renderer.
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:92
virtual QgsFeatureRendererV2 * clone() const =0
The output shall be in millimeters.
Definition: qgssymbolv2.h:67
void addWidget(QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
QString number(int n, int base)
static QIcon symbolPreviewIcon(QgsSymbolV2 *symbol, QSize size)
QgsVectorLayer * mLayer
QString name() const
Gets the name of the field.
Definition: qgsfield.cpp:84
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:68
QgsFeatureRendererV2 * renderer() override
return pointer to the renderer (no transfer of ownership)
Placement placement() const
Returns the placement method used for dispersing the points.
void setPlacement(Placement placement)
Sets the placement method used for dispersing the points.
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:44
QgsPointDisplacementRendererWidget(QgsVectorLayer *layer, QgsStyleV2 *style, QgsFeatureRendererV2 *renderer)
void widgetChanged()
Emitted when the widget state changes.
A renderer that automatically displaces points with the same position.
void setEmbeddedRenderer(QgsFeatureRendererV2 *r) override
Sets an embedded renderer (subrenderer) for this feature renderer.
virtual QgsRendererV2Widget * createRendererWidget(QgsVectorLayer *layer, QgsStyleV2 *style, QgsFeatureRendererV2 *oldRenderer)
Return new instance of settings widget for the renderer.
void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the dialog.
Base class for renderer settings widgets.
QString name
Read property of QString layerName.
Definition: qgsmaplayer.h:53
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.
const QgsFeatureRendererV2 * embeddedRenderer() const override
Returns the current embedded renderer (subrenderer) for this feature renderer.
virtual QgsMarkerSymbolV2 * clone() const override
QStringList renderersList(QgsRendererV2AbstractMetadata::LayerTypes layerTypes=QgsRendererV2AbstractMetadata::All) const
Returns a list of available renderers.
void setTolerance(double t)
Sets the tolerance distance for grouping points.