QGIS API Documentation  2.15.0-Master (af20121)
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  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  Q_FOREACH ( const QgsField& f, layer->fields() )
72  {
73  mLabelFieldComboBox->addItem( f.name() );
74  }
75  mLabelFieldComboBox->addItem( tr( "None" ) );
76 
77  QString currentLabelAttribute = mRenderer->labelAttributeName();
78  if ( !currentLabelAttribute.isEmpty() )
79  {
80  mLabelFieldComboBox->setCurrentIndex( mLabelFieldComboBox->findText( currentLabelAttribute ) );
81  }
82  else
83  {
84  mLabelFieldComboBox->setCurrentIndex( mLabelFieldComboBox->findText( tr( "None" ) ) );
85  }
86  }
87 
88  //insert possible renderer types
90  QStringList::const_iterator it = rendererList.constBegin();
91  for ( ; it != rendererList.constEnd(); ++it )
92  {
93  if ( *it != "pointDisplacement" && *it != "heatmapRenderer" && *it != "invertedPolygonRenderer" )
94  {
96  mRendererComboBox->addItem( m->icon(), m->visibleName(), *it );
97  }
98  }
99 
100  mCircleColorButton->setColorDialogTitle( tr( "Select color" ) );
101  mCircleColorButton->setContext( "symbology" );
102  mCircleColorButton->setAllowAlpha( true );
103  mCircleColorButton->setShowNoColor( true );
104  mCircleColorButton->setNoColorString( tr( "No outline" ) );
105  mLabelColorButton->setContext( "symbology" );
106  mLabelColorButton->setColorDialogTitle( tr( "Select color" ) );
107  mLabelColorButton->setAllowAlpha( true );
108 
109  mCircleWidthSpinBox->setValue( mRenderer->circleWidth() );
110  mCircleColorButton->setColor( mRenderer->circleColor() );
111  mLabelColorButton->setColor( mRenderer->labelColor() );
112  mCircleModificationSpinBox->setClearValue( 0.0 );
113  mCircleModificationSpinBox->setValue( mRenderer->circleRadiusAddition() );
114  mDistanceSpinBox->setValue( mRenderer->tolerance() );
115  mDistanceUnitWidget->setUnit( mRenderer->toleranceUnit() );
116  mDistanceUnitWidget->setMapUnitScale( mRenderer->toleranceMapUnitScale() );
117 
118  mPlacementComboBox->setCurrentIndex( mPlacementComboBox->findData( mRenderer->placement() ) );
119 
120  //scale dependent labelling
121  mMaxScaleDenominatorEdit->setText( QString::number( mRenderer->maxLabelScaleDenominator() ) );
122  mMaxScaleDenominatorEdit->setValidator( new QDoubleValidator( mMaxScaleDenominatorEdit ) );
123  if ( mRenderer->maxLabelScaleDenominator() > 0 )
124  {
125  mScaleDependentLabelsCheckBox->setCheckState( Qt::Checked );
126  }
127  else
128  {
129  mScaleDependentLabelsCheckBox->setCheckState( Qt::Unchecked );
130  mMaxScaleDenominatorEdit->setEnabled( false );
131  }
132 
133 
134  blockAllSignals( false );
135 
136  //set the appropriate renderer dialog
137  if ( mRenderer->embeddedRenderer() )
138  {
139  QString rendererName = mRenderer->embeddedRenderer()->type();
140  int rendererIndex = mRendererComboBox->findData( rendererName );
141  if ( rendererIndex != -1 )
142  {
143  mRendererComboBox->setCurrentIndex( rendererIndex );
144  on_mRendererComboBox_currentIndexChanged( rendererIndex );
145  }
146  }
147 
148  updateCenterIcon();
149 }
150 
152 {
153  delete mRenderer;
154  delete mEmbeddedRendererWidget;
155 }
156 
158 {
159  if ( mRenderer && mEmbeddedRendererWidget )
160  {
161  QgsFeatureRendererV2* embeddedRenderer = mEmbeddedRendererWidget->renderer();
162  if ( embeddedRenderer )
163  {
164  mRenderer->setEmbeddedRenderer( embeddedRenderer->clone() );
165  }
166  }
167  return mRenderer;
168 }
169 
171 {
173  if ( mDistanceUnitWidget )
174  mDistanceUnitWidget->setMapCanvas( canvas );
175  if ( mEmbeddedRendererWidget )
176  mEmbeddedRendererWidget->setMapCanvas( canvas );
177 }
178 
179 void QgsPointDisplacementRendererWidget::on_mLabelFieldComboBox_currentIndexChanged( const QString& text )
180 {
181  if ( mRenderer )
182  {
183  if ( text == tr( "None" ) )
184  {
185  mRenderer->setLabelAttributeName( "" );
186  }
187  else
188  {
189  mRenderer->setLabelAttributeName( text );
190  }
191  }
192 }
193 
194 void QgsPointDisplacementRendererWidget::on_mRendererComboBox_currentIndexChanged( int index )
195 {
196  QString rendererId = mRendererComboBox->itemData( index ).toString();
198  if ( m )
199  {
200  delete mEmbeddedRendererWidget;
201  mEmbeddedRendererWidget = m->createRendererWidget( mLayer, mStyle, mRenderer->embeddedRenderer()->clone() );
202  mEmbeddedRendererWidget->setMapCanvas( mMapCanvas );
203  }
204 }
205 
206 void QgsPointDisplacementRendererWidget::on_mPlacementComboBox_currentIndexChanged( int index )
207 {
208  if ( !mRenderer )
209  return;
210 
211  mRenderer->setPlacement(( QgsPointDisplacementRenderer::Placement )mPlacementComboBox->itemData( index ).toInt() );
212 }
213 
214 void QgsPointDisplacementRendererWidget::on_mRendererSettingsButton_clicked()
215 {
216  if ( mEmbeddedRendererWidget )
217  {
218  //create a dialog with the embedded widget
219 #ifdef Q_OS_MAC
220  QDialog* d = new QDialog( this->window() );
221  d->setWindowModality( Qt::WindowModal );
222 #else
223  QDialog* d = new QDialog();
224 #endif
225  QGridLayout* layout = new QGridLayout( d );
226  mEmbeddedRendererWidget->setParent( d );
227  QDialogButtonBox* buttonBox = new QDialogButtonBox( d );
228  buttonBox->addButton( QDialogButtonBox::Ok );
229  QObject::connect( buttonBox, SIGNAL( accepted() ), d, SLOT( accept() ) );
230  layout->addWidget( mEmbeddedRendererWidget, 0, 0 );
231  layout->addWidget( buttonBox, 1, 0 );
232  d->exec();
233  mEmbeddedRendererWidget->setParent( nullptr );
234  delete d;
235  }
236 }
237 
238 void QgsPointDisplacementRendererWidget::on_mLabelFontButton_clicked()
239 {
240  if ( !mRenderer )
241  {
242  return;
243  }
244 
245  bool ok;
246  QFont newFont = QgisGui::getFont( ok, mRenderer->labelFont(), tr( "Label Font" ) );
247  if ( ok )
248  {
249  mRenderer->setLabelFont( newFont );
250  }
251 }
252 
253 void QgsPointDisplacementRendererWidget::on_mCircleWidthSpinBox_valueChanged( double d )
254 {
255  if ( mRenderer )
256  {
257  mRenderer->setCircleWidth( d );
258  }
259 }
260 
261 void QgsPointDisplacementRendererWidget::on_mCircleColorButton_colorChanged( const QColor& newColor )
262 {
263  if ( !mRenderer )
264  {
265  return;
266  }
267 
268  mRenderer->setCircleColor( newColor );
269 }
270 
271 void QgsPointDisplacementRendererWidget::on_mLabelColorButton_colorChanged( const QColor& newColor )
272 {
273  if ( !mRenderer )
274  {
275  return;
276  }
277 
278  mRenderer->setLabelColor( newColor );
279 }
280 
281 void QgsPointDisplacementRendererWidget::on_mCircleModificationSpinBox_valueChanged( double d )
282 {
283  if ( !mRenderer )
284  {
285  return;
286  }
287 
288  mRenderer->setCircleRadiusAddition( d );
289 }
290 
291 void QgsPointDisplacementRendererWidget::on_mDistanceSpinBox_valueChanged( double d )
292 {
293  if ( mRenderer )
294  {
295  mRenderer->setTolerance( d );
296  }
297 }
298 
299 void QgsPointDisplacementRendererWidget::on_mDistanceUnitWidget_changed()
300 {
301  if ( mRenderer )
302  {
303  mRenderer->setToleranceUnit( mDistanceUnitWidget->unit() );
304  mRenderer->setToleranceMapUnitScale( mDistanceUnitWidget->getMapUnitScale() );
305  }
306 }
307 
308 void QgsPointDisplacementRendererWidget::on_mScaleDependentLabelsCheckBox_stateChanged( int state )
309 {
310  if ( state == Qt::Unchecked )
311  {
312  mMaxScaleDenominatorEdit->setText( "-1" );
313  mMaxScaleDenominatorEdit->setEnabled( false );
314  }
315  else
316  {
317  mMaxScaleDenominatorEdit->setEnabled( true );
318  }
319 }
320 
321 void QgsPointDisplacementRendererWidget::on_mMaxScaleDenominatorEdit_textChanged( const QString & text )
322 {
323  if ( !mRenderer )
324  {
325  return;
326  }
327 
328  bool ok;
329  double scaleDenominator = text.toDouble( &ok );
330  if ( ok )
331  {
332  mRenderer->setMaxLabelScaleDenominator( scaleDenominator );
333  }
334 }
335 
336 void QgsPointDisplacementRendererWidget::blockAllSignals( bool block )
337 {
338  mLabelFieldComboBox->blockSignals( block );
339  mLabelFontButton->blockSignals( block );
340  mCircleWidthSpinBox->blockSignals( block );
341  mCircleColorButton->blockSignals( block );
342  mRendererComboBox->blockSignals( block );
343  mLabelColorButton->blockSignals( block );
344  mCircleModificationSpinBox->blockSignals( block );
345  mScaleDependentLabelsCheckBox->blockSignals( block );
346  mMaxScaleDenominatorEdit->blockSignals( block );
347  mCenterSymbolPushButton->blockSignals( block );
348  mDistanceSpinBox->blockSignals( block );
349  mDistanceUnitWidget->blockSignals( block );
350  mPlacementComboBox->blockSignals( block );
351 }
352 
353 void QgsPointDisplacementRendererWidget::on_mCenterSymbolPushButton_clicked()
354 {
355  if ( !mRenderer || !mRenderer->centerSymbol() )
356  {
357  return;
358  }
359  QgsMarkerSymbolV2* markerSymbol = mRenderer->centerSymbol()->clone();
360  QgsSymbolV2SelectorDialog dlg( markerSymbol, QgsStyleV2::defaultStyle(), mLayer, this );
361  dlg.setMapCanvas( mMapCanvas );
362  if ( dlg.exec() == QDialog::Rejected )
363  {
364  delete markerSymbol;
365  return;
366  }
367  mRenderer->setCenterSymbol( markerSymbol );
368  updateCenterIcon();
369 }
370 
371 void QgsPointDisplacementRendererWidget::updateCenterIcon()
372 {
373  QgsMarkerSymbolV2* symbol = mRenderer->centerSymbol();
374  if ( !symbol )
375  {
376  return;
377  }
378  QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( symbol, mCenterSymbolPushButton->iconSize() );
379  mCenterSymbolPushButton->setIcon( icon );
380 }
381 
382 void QgsPointDisplacementRendererWidget::setupBlankUi( const QString& layerName )
383 {
384  QGridLayout* layout = new QGridLayout( this );
385  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 );
386  layout->addWidget( label );
387 }
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.
QString name() const
Get the display name of the layer.
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:67
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:108
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:86
virtual QgsFeatureRendererV2 * clone() const =0
The output shall be in millimeters.
Definition: qgssymbolv2.h:64
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
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:65
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)
QgsFeatureRendererV2 * embeddedRenderer() const
A renderer that automatically displaces points with the same position.
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.
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.
virtual QgsMarkerSymbolV2 * clone() const override
void setTolerance(double t)
Sets the tolerance distance for grouping points.