QGIS API Documentation  2.14.0-Essen
qgsrendererv2propertiesdialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrendererv2propertiesdialog.cpp
3  ---------------------
4  begin : December 2009
5  copyright : (C) 2009 by Martin Dobias
6  email : wonder dot sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
16 
17 #include "qgsrendererv2.h"
18 #include "qgsrendererv2registry.h"
19 
20 #include "qgsrendererv2widget.h"
28 #include "qgs25drendererwidget.h"
29 
30 #include "qgsorderbydialog.h"
31 #include "qgsapplication.h"
32 #include "qgslogger.h"
33 #include "qgsvectorlayer.h"
34 
35 #include <QKeyEvent>
36 #include <QMessageBox>
37 
38 static bool _initRenderer( const QString& name, QgsRendererV2WidgetFunc f, const QString& iconName = QString() )
39 {
42  if ( !am )
43  return false;
44  QgsRendererV2Metadata* m = dynamic_cast<QgsRendererV2Metadata*>( am );
45  if ( !m )
46  return false;
47 
48  m->setWidgetFunction( f );
49 
50  if ( !iconName.isEmpty() )
51  {
53  QPixmap pix;
54  if ( pix.load( iconPath ) )
55  m->setIcon( pix );
56  }
57 
58  QgsDebugMsg( "Set for " + name );
59  return true;
60 }
61 
63 {
64  static bool initialized = false;
65  if ( initialized )
66  return;
67 
68  _initRenderer( "singleSymbol", QgsSingleSymbolRendererV2Widget::create, "rendererSingleSymbol.svg" );
69  _initRenderer( "categorizedSymbol", QgsCategorizedSymbolRendererV2Widget::create, "rendererCategorizedSymbol.svg" );
70  _initRenderer( "graduatedSymbol", QgsGraduatedSymbolRendererV2Widget::create, "rendererGraduatedSymbol.svg" );
71  _initRenderer( "RuleRenderer", QgsRuleBasedRendererV2Widget::create, "rendererRuleBasedSymbol.svg" );
72  _initRenderer( "pointDisplacement", QgsPointDisplacementRendererWidget::create, "rendererPointDisplacementSymbol.svg" );
73  _initRenderer( "invertedPolygonRenderer", QgsInvertedPolygonRendererWidget::create, "rendererInvertedSymbol.svg" );
74  _initRenderer( "heatmapRenderer", QgsHeatmapRendererWidget::create, "rendererHeatmapSymbol.svg" );
75  _initRenderer( "25dRenderer", Qgs25DRendererWidget::create, "renderer25dSymbol.svg" );
76  initialized = true;
77 }
78 
80  : mLayer( layer )
81  , mStyle( style )
82  , mActiveWidget( nullptr )
83  , mPaintEffect( nullptr )
84  , mMapCanvas( nullptr )
85 {
86  setupUi( this );
87 
88  // can be embedded in vector layer properties
89  if ( embedded )
90  {
91  buttonBox->hide();
92  layout()->setContentsMargins( 0, 0, 0, 0 );
93  }
94 
95  connect( buttonBox, SIGNAL( accepted() ), this, SLOT( onOK() ) );
96 
97  // initialize registry's widget functions
99 
100  // Blend mode
101  mBlendModeComboBox->setBlendMode( mLayer->blendMode() );
102 
103  // Feature blend mode
104  mFeatureBlendComboBox->setBlendMode( mLayer->featureBlendMode() );
105 
106  // Layer transparency
107  mLayerTransparencySlider->setValue( mLayer->layerTransparency() );
108  mLayerTransparencySpnBx->setValue( mLayer->layerTransparency() );
109 
110  // connect layer transparency slider and spin box
111  connect( mLayerTransparencySlider, SIGNAL( valueChanged( int ) ), mLayerTransparencySpnBx, SLOT( setValue( int ) ) );
112  connect( mLayerTransparencySpnBx, SIGNAL( valueChanged( int ) ), mLayerTransparencySlider, SLOT( setValue( int ) ) );
113 
114  //paint effect widget
115  if ( mLayer->rendererV2() )
116  {
117  if ( mLayer->rendererV2()->paintEffect() )
118  {
120  mEffectWidget->setPaintEffect( mPaintEffect );
121  }
122 
124  }
125 
127  QStringList renderers = reg->renderersList();
128  Q_FOREACH ( const QString& name, renderers )
129  {
131  cboRenderers->addItem( m->icon(), m->visibleName(), name );
132  }
133 
134  cboRenderers->setCurrentIndex( -1 ); // set no current renderer
135 
136  // setup slot rendererChanged()
137  connect( cboRenderers, SIGNAL( currentIndexChanged( int ) ), this, SLOT( rendererChanged() ) );
138  //setup order by
139  if ( mLayer->rendererV2()->orderByEnabled() )
140  {
141  checkboxEnableOrderBy->setChecked( true );
142  }
143  else
144  {
145  btnOrderBy->setEnabled( false );
146  checkboxEnableOrderBy->setChecked( false );
147  lineEditOrderBy->setEnabled( false );
148  }
149  lineEditOrderBy->setReadOnly( true );
150  connect( checkboxEnableOrderBy, SIGNAL( toggled( bool ) ), btnOrderBy, SLOT( setEnabled( bool ) ) );
151  connect( checkboxEnableOrderBy, SIGNAL( toggled( bool ) ), lineEditOrderBy, SLOT( setEnabled( bool ) ) );
152  connect( btnOrderBy, SIGNAL( clicked( bool ) ), this, SLOT( showOrderByDialog() ) );
153  lineEditOrderBy->setText( mOrderBy.dump() );
154 
155  // set current renderer from layer
156  QString rendererName = mLayer->rendererV2()->type();
157 
158  int rendererIdx = cboRenderers->findData( rendererName );
159  cboRenderers->setCurrentIndex( rendererIdx );
160 
161  // no renderer found... this mustn't happen
162  Q_ASSERT( rendererIdx != -1 && "there must be a renderer!" );
163 }
164 
166 {
167  delete mPaintEffect;
168 }
169 
171 {
172  mMapCanvas = canvas;
173  if ( mActiveWidget )
175 }
176 
177 
179 {
180 
181  if ( cboRenderers->currentIndex() == -1 )
182  {
183  QgsDebugMsg( "No current item -- this should never happen!" );
184  return;
185  }
186 
187  QString rendererName = cboRenderers->itemData( cboRenderers->currentIndex() ).toString();
188 
189  //Retrieve the previous renderer: from the old active widget if possible, otherwise from the layer
190  QgsFeatureRendererV2* oldRenderer;
192  {
193  oldRenderer = mActiveWidget->renderer()->clone();
194  }
195  else
196  {
197  oldRenderer = mLayer->rendererV2()->clone();
198  }
199 
200  // get rid of old active widget (if any)
201  if ( mActiveWidget )
202  {
203  stackedWidget->removeWidget( mActiveWidget );
204 
205  delete mActiveWidget;
206  mActiveWidget = nullptr;
207  }
208 
209  QgsRendererV2Widget* w = nullptr;
211  if ( m )
212  w = m->createRendererWidget( mLayer, mStyle, oldRenderer );
213  delete oldRenderer;
214 
215  if ( w )
216  {
217  // instantiate the widget and set as active
218  mActiveWidget = w;
219  stackedWidget->addWidget( mActiveWidget );
220  stackedWidget->setCurrentWidget( mActiveWidget );
221  if ( mActiveWidget->renderer() )
222  {
223  if ( mMapCanvas )
225  changeOrderBy( mActiveWidget->renderer()->orderBy(), mActiveWidget->renderer()->orderByEnabled() );
226  connect( mActiveWidget, SIGNAL( layerVariablesChanged() ), this, SIGNAL( layerVariablesChanged() ) );
227  }
228  }
229  else
230  {
231  // set default "no edit widget available" page
232  stackedWidget->setCurrentWidget( pageNoWidget );
233  }
234 }
235 
237 {
238  if ( !mActiveWidget || !mLayer )
239  {
240  return;
241  }
242 
244 
246  if ( renderer )
247  {
248  renderer->setPaintEffect( mPaintEffect->clone() );
249  // set the order by
250  renderer->setOrderBy( mOrderBy );
251  renderer->setOrderByEnabled( checkboxEnableOrderBy->isChecked() );
252 
253  mLayer->setRendererV2( renderer->clone() );
254  }
255 
256  // set the blend modes for the layer
257  mLayer->setBlendMode( mBlendModeComboBox->blendMode() );
258  mLayer->setFeatureBlendMode( mFeatureBlendComboBox->blendMode() );
259 
260  // set transparency for the layer
261  mLayer->setLayerTransparency( mLayerTransparencySlider->value() );
262 }
263 
265 {
266  apply();
267  accept();
268 }
269 
270 void QgsRendererV2PropertiesDialog::showOrderByDialog()
271 {
272  QgsOrderByDialog dlg( mLayer, this );
273 
274  dlg.setOrderBy( mOrderBy );
275  if ( dlg.exec() )
276  {
277  mOrderBy = dlg.orderBy();
278  lineEditOrderBy->setText( mOrderBy.dump() );
279  }
280 }
281 
282 void QgsRendererV2PropertiesDialog::changeOrderBy( const QgsFeatureRequest::OrderBy& orderBy, bool orderByEnabled )
283 {
284  mOrderBy = orderBy;
285  lineEditOrderBy->setText( mOrderBy.dump() );
286  checkboxEnableOrderBy->setChecked( orderByEnabled );
287 }
288 
289 
291 {
292  // Ignore the ESC key to avoid close the dialog without the properties window
293  if ( !isWindow() && e->key() == Qt::Key_Escape )
294  {
295  e->ignore();
296  }
297  else
298  {
300  }
301 }
QLayout * layout() const
void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the dialog.
static QgsRendererV2Registry * instance()
This is a dialog to build and manage a list of order by clauses.
void setContentsMargins(int left, int top, int right, int bottom)
void setupUi(QWidget *widget)
void setOrderBy(const QgsFeatureRequest::OrderBy &orderBy)
Set the order by to manage.
QgsFeatureRequest::OrderBy orderBy() const
Get the order in which features shall be processed by this renderer.
static QString defaultThemePath()
Returns the path to the default theme directory.
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
bool orderByEnabled() const
Returns whether custom ordering will be applied before features are processed by this renderer...
void setRendererV2(QgsFeatureRendererV2 *r)
Set renderer which will be invoked to represent this layer.
void setFeatureBlendMode(QPainter::CompositionMode blendMode)
Set the blending mode used for rendering each feature.
static QgsRendererV2Widget * create(QgsVectorLayer *layer, QgsStyleV2 *style, QgsFeatureRendererV2 *renderer)
void accepted()
int exec()
void setLayerTransparency(int layerTransparency)
Set the transparency for the vector layer.
Stores metadata about one renderer class.
QString iconPath(const QString &iconFile)
void setBlendMode(QPainter::CompositionMode blendMode)
Set the blending mode used for rendering a layer.
Registry of renderers.
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:105
QgsRendererV2AbstractMetadata * rendererMetadata(const QString &rendererName)
get metadata for particular renderer. Returns NULL if not found in registry.
virtual QgsPaintEffect * clone() const =0
Duplicates an effect by creating a deep copy of the effect.
void setIcon(const QIcon &icon)
static void _initRendererWidgetFunctions()
QString type() const
Definition: qgsrendererv2.h:83
void setWidgetFunction(QgsRendererV2WidgetFunc f)
QString CORE_EXPORT dump() const
Dumps the content to an SQL equivalent syntax.
const char * name() const
virtual QgsFeatureRendererV2 * clone() const =0
QgsFeatureRendererV2 * rendererV2()
Return renderer V2.
void setEnabled(bool)
QPainter::CompositionMode blendMode() const
Returns the current blending mode for a layer.
void ignore()
QPainter::CompositionMode featureBlendMode() const
Returns the current blending mode for features.
QStringList renderersList()
return a list of available renderers
void layerVariablesChanged()
Emitted when expression context variables on the associated vector layers have been changed...
static QgsRendererV2Widget * create(QgsVectorLayer *layer, QgsStyleV2 *style, QgsFeatureRendererV2 *renderer)
void setOrderByEnabled(bool enabled)
Sets whether custom ordering should be applied before features are processed by this renderer...
void setPaintEffect(QgsPaintEffect *effect)
Sets the current paint effect for the renderer.
static QgsRendererV2Widget * create(QgsVectorLayer *layer, QgsStyleV2 *style, QgsFeatureRendererV2 *renderer)
void applyChanges()
This method should be called whenever the renderer is actually set on the layer.
bool load(const QString &fileName, const char *format, QFlags< Qt::ImageConversionFlag > flags)
static QgsRendererV2Widget * create(QgsVectorLayer *layer, QgsStyleV2 *style, QgsFeatureRendererV2 *renderer)
virtual void accept()
bool isWindow() const
QgsRendererV2PropertiesDialog(QgsVectorLayer *layer, QgsStyleV2 *style, bool embedded=false)
int key() const
static bool _initRenderer(const QString &name, QgsRendererV2WidgetFunc f, const QString &iconName=QString())
static QgsRendererV2Widget * create(QgsVectorLayer *layer, QgsStyleV2 *style, QgsFeatureRendererV2 *renderer)
Static creation method.
void rendererChanged()
called when user changes renderer type
int layerTransparency() const
Returns the current transparency for the vector layer.
virtual void keyPressEvent(QKeyEvent *e)
static QgsRendererV2Widget * create(QgsVectorLayer *layer, QgsStyleV2 *style, QgsFeatureRendererV2 *renderer)
Static creation method.
void setOrderBy(const QgsFeatureRequest::OrderBy &orderBy)
Define the order in which features shall be processed by this renderer.
Convenience metadata class that uses static functions to create renderer and its widget.
void keyPressEvent(QKeyEvent *event) override
Reimplements dialog keyPress event so we can ignore it.
virtual QgsRendererV2Widget * createRendererWidget(QgsVectorLayer *layer, QgsStyleV2 *style, QgsFeatureRendererV2 *oldRenderer)
Return new instance of settings widget for the renderer.
QgsPaintEffect * paintEffect() const
Returns the current paint effect for the renderer.
Base class for renderer settings widgets.
static QgsRendererV2Widget * create(QgsVectorLayer *layer, QgsStyleV2 *style, QgsFeatureRendererV2 *renderer)
QgsFeatureRequest::OrderBy orderBy()
Get the order by defined in the dialog.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Represents a vector layer which manages a vector based data sets.
virtual QgsFeatureRendererV2 * renderer()=0
return pointer to the renderer (no transfer of ownership)
QgsRendererV2Widget *(* QgsRendererV2WidgetFunc)(QgsVectorLayer *, QgsStyleV2 *, QgsFeatureRendererV2 *)
virtual void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
Represents a list of OrderByClauses, with the most important first and the least important last...
static QgsRendererV2Widget * create(QgsVectorLayer *layer, QgsStyleV2 *style, QgsFeatureRendererV2 *renderer)
Static creation method.