QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
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.
QGis::WkbType wkbType() const
Returns the WKBType or WKBUnknown in case of error.
void setContentsMargins(int left, int top, int right, int bottom)
void setupUi(QWidget *widget)
QString name
Definition: qgsfield.h:52
const QgsMapUnitScale & toleranceMapUnitScale() const
Returns the map unit scale object for the distance tolerance.
void addWidget(QWidget *widget, int row, int column, QFlags< Qt::AlignmentFlag > alignment)
QWidget * window() const
QgsSymbolV2::OutputUnit toleranceUnit() const
Returns the units for the tolerance distance.
void setWindowModality(Qt::WindowModality windowModality)
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
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 tolerance() const
Returns the tolerance distance for grouping points.
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.
void setToleranceUnit(QgsSymbolV2::OutputUnit unit)
Sets the units for the tolerance distance.
QgsFields fields() const
Returns the list of fields of this layer.
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
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
QString type() const
Definition: qgsrendererv2.h:92
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)
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.
QStringList renderersList(QgsRendererV2AbstractMetadata::LayerTypes layerTypes=QgsRendererV2AbstractMetadata::All) const
Returns a list of available renderers.
static QgsRendererV2Widget * create(QgsVectorLayer *layer, QgsStyleV2 *style, QgsFeatureRendererV2 *renderer)
Placement placement() const
Returns the placement method used for dispersing the points.
const_iterator constEnd() const
const_iterator constBegin() const
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
void setTolerance(double t)
Sets the tolerance distance for grouping points.