QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
qgslayerpropertieswidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayerpropertieswidget.cpp
3  ----------------------------
4  begin : June 2012
5  copyright : (C) 2012 by Arunmozhi
6  email : aruntheguy at gmail.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  ***************************************************************************/
15 
17 
18 #include <QFile>
19 #include <QStandardItem>
20 #include <QKeyEvent>
21 #include <QMessageBox>
22 #include <QPicture>
23 
24 #include "qgssymbollayerv2.h"
26 
27 #include "qgsapplication.h"
28 #include "qgslogger.h"
29 
30 #include "qgssymbollayerv2widget.h"
34 #include "qgssymbolv2.h" //for the unit
35 #include "qgspanelwidget.h"
36 
38 {
40 
41  QgsSymbolLayerV2AbstractMetadata* abstractMetadata = reg->symbolLayerMetadata( name );
42  if ( !abstractMetadata )
43  {
44  QgsDebugMsg( "Failed to find symbol layer's entry in registry: " + name );
45  return false;
46  }
47  QgsSymbolLayerV2Metadata* metadata = dynamic_cast<QgsSymbolLayerV2Metadata*>( abstractMetadata );
48  if ( !metadata )
49  {
50  QgsDebugMsg( "Failed to cast symbol layer's metadata: " + name );
51  return false;
52  }
53  metadata->setWidgetFunction( f );
54  return true;
55 }
56 
57 static void _initWidgetFunctions()
58 {
59  static bool initialized = false;
60  if ( initialized )
61  return;
62 
66 
73 
82 
84 
85  initialized = true;
86 }
87 
88 
90  : QgsPanelWidget( parent )
91  , mPresetExpressionContext( nullptr )
92  , mMapCanvas( nullptr )
93 {
94 
95  mLayer = layer;
96  mSymbol = symbol;
97  mVectorLayer = vl;
98 
99  setupUi( this );
100  // initialize the sub-widgets
101  // XXX Should this thing be here this way? Initialize all the widgets just for the sake of one layer?
102  // TODO Make this on demand creation
104 
105  // TODO Algorithm
106  //
107  // 3. populate the combo box with the supported layer type
108  // 4. set the present layer type
109  // 5. create the widget for the present layer type and set inn stacked widget
110  // 6. connect comboBox type changed to two things
111  // 1. emit signal that type has beed changed
112  // 2. remove the widget and place the new widget corresponding to the changed layer type
113  //
115  // update layer type combo box
116  int idx = cboLayerType->findData( mLayer->layerType() );
117  cboLayerType->setCurrentIndex( idx );
118  // set the corresponding widget
119  updateSymbolLayerWidget( layer );
120  connect( cboLayerType, SIGNAL( currentIndexChanged( int ) ), this, SLOT( layerTypeChanged() ) );
121 
122  connect( mEffectWidget, SIGNAL( changed() ), this, SLOT( emitSignalChanged() ) );
123 
124  this->connectChildPanel( mEffectWidget );
125 
126  mEffectWidget->setPaintEffect( mLayer->paintEffect() );
127 }
128 
130 {
131  mMapCanvas = canvas;
132  QgsSymbolLayerV2Widget* w = dynamic_cast< QgsSymbolLayerV2Widget* >( stackedWidget->currentWidget() );
133  if ( w )
134  w->setMapCanvas( mMapCanvas );
135 }
136 
138 {
139  QgsPanelWidget::setDockMode( dockMode );
140  mEffectWidget->setDockMode( this->dockMode() );
141 }
142 
144 {
145  mPresetExpressionContext = context;
146 
147  QgsSymbolLayerV2Widget* w = dynamic_cast< QgsSymbolLayerV2Widget* >( stackedWidget->currentWidget() );
148  if ( w )
149  w->setExpressionContext( mPresetExpressionContext );
150 }
151 
153 {
155 
156  Q_FOREACH ( const QString& symbolLayerId, symbolLayerIds )
157  cboLayerType->addItem( QgsSymbolLayerV2Registry::instance()->symbolLayerMetadata( symbolLayerId )->visibleName(), symbolLayerId );
158 
159  if ( mSymbol->type() == QgsSymbolV2::Fill )
160  {
162  Q_FOREACH ( const QString& lineLayerId, lineLayerIds )
163  {
165  if ( layerInfo->type() != QgsSymbolV2::Hybrid )
166  {
167  QString visibleName = layerInfo->visibleName();
168  QString name = QString( tr( "Outline: %1" ) ).arg( visibleName );
169  cboLayerType->addItem( name, lineLayerId );
170  }
171  }
172  }
173 }
174 
176 {
177  if ( stackedWidget->currentWidget() != pageDummy )
178  {
179  // stop updating from the original widget
180  disconnect( stackedWidget->currentWidget(), SIGNAL( changed() ), this, SLOT( emitSignalChanged() ) );
181  stackedWidget->removeWidget( stackedWidget->currentWidget() );
182  }
183 
185 
186  QString layerType = layer->layerType();
187  QgsSymbolLayerV2AbstractMetadata* am = pReg->symbolLayerMetadata( layerType );
188  if ( am )
189  {
191  if ( w )
192  {
193  w->setExpressionContext( mPresetExpressionContext );
194  if ( mMapCanvas )
195  w->setMapCanvas( mMapCanvas );
196  w->setSymbolLayer( layer );
197  stackedWidget->addWidget( w );
198  stackedWidget->setCurrentWidget( w );
199  // start receiving updates from widget
200  connect( w, SIGNAL( changed() ), this, SLOT( emitSignalChanged() ) );
201  connect( w, SIGNAL( symbolChanged() ), this, SLOT( reloadLayer() ) );
202  return;
203  }
204  }
205  // When anything is not right
206  stackedWidget->setCurrentWidget( pageDummy );
207 }
208 
210 {
211  QgsSymbolLayerV2* layer = mLayer;
212  if ( !layer )
213  return;
214  QString newLayerType = cboLayerType->itemData( cboLayerType->currentIndex() ).toString();
215  if ( layer->layerType() == newLayerType )
216  return;
217 
218  // get creation function for new layer from registry
220  QgsSymbolLayerV2AbstractMetadata* am = pReg->symbolLayerMetadata( newLayerType );
221  if ( !am ) // check whether the metadata is assigned
222  return;
223 
224  // change layer to a new (with different type)
225  // base new layer on existing layer's properties
226  QgsSymbolLayerV2* newLayer = am->createSymbolLayer( layer->properties() );
227  if ( !newLayer )
228  return;
229 
230  updateSymbolLayerWidget( newLayer );
231  emit changeLayer( newLayer );
232 }
233 
235 {
236  emit changed();
237 
238  // also update paint effect preview
239  mEffectWidget->setPreviewPicture( QgsSymbolLayerV2Utils::symbolLayerPreviewPicture( mLayer, QgsSymbolV2::MM, QSize( 80, 80 ) ) );
240  emit widgetChanged();
241 }
242 
243 void QgsLayerPropertiesWidget::reloadLayer()
244 {
245  emit changeLayer( mLayer );
246 }
virtual void setSymbolLayer(QgsSymbolLayerV2 *layer)=0
void connectChildPanel(QgsPanelWidget *panel)
Connect the given sub panel widgets showPanel signals to this current panels main showPanel event to ...
static QgsSymbolLayerV2Widget * create(const QgsVectorLayer *vl)
void setupUi(QWidget *widget)
bool dockMode()
Return the dock mode state.
QgsSymbolLayerV2AbstractMetadata * symbolLayerMetadata(const QString &name) const
return metadata for specified symbol layer. Returns NULL if not found
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
QgsPaintEffect * paintEffect() const
Returns the current paint effect for the layer.
static QgsSymbolLayerV2Widget * create(const QgsVectorLayer *vl)
virtual void setDockMode(bool dockMode) override
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs...
static QgsSymbolLayerV2Widget * create(const QgsVectorLayer *vl)
static QgsSymbolLayerV2Widget * create(const QgsVectorLayer *vl)
Stores metadata about one symbol layer class.
QgsLayerPropertiesWidget(QgsSymbolLayerV2 *layer, const QgsSymbolV2 *symbol, const QgsVectorLayer *vl, QWidget *parent=nullptr)
SymbolType type() const
Definition: qgssymbolv2.h:107
Line symbol.
Definition: qgssymbolv2.h:82
static QgsSymbolLayerV2Registry * instance()
return the single instance of this class (instantiate it if not exists)
Base class for any widget that can be shown as a inline panel.
static QgsSymbolLayerV2Widget * create(const QgsVectorLayer *vl)
static QgsSymbolLayerV2Widget * create(const QgsVectorLayer *vl)
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
QString tr(const char *sourceText, const char *disambiguation, int n)
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:109
static QgsSymbolLayerV2Widget * create(const QgsVectorLayer *vl)
static void _initWidgetFunctions()
virtual void setDockMode(bool dockMode)
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs...
static QgsSymbolLayerV2Widget * create(const QgsVectorLayer *vl)
virtual void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
const char * name() const
The output shall be in millimeters.
Definition: qgssymbolv2.h:67
static QgsSymbolLayerV2Widget * create(const QgsVectorLayer *vl)
void changeLayer(QgsSymbolLayerV2 *)
void setExpressionContext(QgsExpressionContext *context)
Sets the optional expression context used for the widget.
virtual QgsSymbolLayerV2Widget * createSymbolLayerWidget(const QgsVectorLayer *)
Create widget for symbol layer of this type.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QgsSymbolV2::SymbolType type() const
static QgsSymbolLayerV2Widget * create(const QgsVectorLayer *vl)
virtual void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
virtual QgsStringMap properties() const =0
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void widgetChanged()
Emitted when the widget state changes.
static QgsSymbolLayerV2Widget * create(const QgsVectorLayer *vl)
static QgsSymbolLayerV2Widget * create(const QgsVectorLayer *vl)
virtual QString layerType() const =0
Returns a string that represents this layer type.
static QgsSymbolLayerV2Widget * create(const QgsVectorLayer *vl)
QgsSymbolLayerV2Widget *(* QgsSymbolLayerV2WidgetFunc)(const QgsVectorLayer *)
Hybrid symbol.
Definition: qgssymbolv2.h:84
QStringList symbolLayersForType(QgsSymbolV2::SymbolType type)
return a list of available symbol layers for a specified symbol type
static QgsSymbolLayerV2Widget * create(const QgsVectorLayer *layer)
Static creation method.
virtual QgsSymbolLayerV2 * createSymbolLayer(const QgsStringMap &map)=0
Create a symbol layer of this type given the map of properties.
Fill symbol.
Definition: qgssymbolv2.h:83
static QgsSymbolLayerV2Widget * create(const QgsVectorLayer *vl)
static QPicture symbolLayerPreviewPicture(QgsSymbolLayerV2 *layer, QgsSymbolV2::OutputUnit units, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale())
Draws a symbol layer preview to a QPicture.
void updateSymbolLayerWidget(QgsSymbolLayerV2 *layer)
static QgsSymbolLayerV2Widget * create(const QgsVectorLayer *vl)
Will be registered as factory.
void setWidgetFunction(QgsSymbolLayerV2WidgetFunc f)
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.
static QgsSymbolLayerV2Widget * create(const QgsVectorLayer *vl)
Creates a new QgsFilledMarkerSymbolLayerWidget.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
Registry of available symbol layer classes.
static bool _initWidgetFunction(const QString &name, QgsSymbolLayerV2WidgetFunc f)
static QgsSymbolLayerV2Widget * create(const QgsVectorLayer *vl)
Convenience metadata class that uses static functions to create symbol layer and its widget...
void setExpressionContext(QgsExpressionContext *context)
Sets the optional expression context used for the widget.
const QgsVectorLayer * mVectorLayer