QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgssymbollevelsdialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgssymbollevelsdialog.cpp
3  ---------------------
4  begin : November 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  ***************************************************************************/
15 
16 #include "qgssymbollevelsdialog.h"
17 
18 #include "qgssymbollayerutils.h"
19 #include "qgssymbollayer.h"
20 #include "qgssymbol.h"
21 #include "qgssettings.h"
22 #include "qgsguiutils.h"
23 
24 #include <QTableWidgetItem>
25 #include <QItemDelegate>
26 #include <QSpinBox>
27 #include <QDialogButtonBox>
28 
29 
31 
32 QgsSymbolLevelsWidget::QgsSymbolLevelsWidget( QgsFeatureRenderer *renderer, bool usingSymbolLevels, QWidget *parent )
33  : QgsPanelWidget( parent )
34  , mRenderer( renderer )
35  , mForceOrderingEnabled( false )
36 {
37  setupUi( this );
38 
39  tableLevels->setItemDelegate( new SpinBoxDelegate( this ) );
40 
41  chkEnable->setChecked( usingSymbolLevels );
42 
43  connect( chkEnable, &QAbstractButton::clicked, this, &QgsSymbolLevelsWidget::updateUi );
44 
45  if ( mRenderer )
46  {
47  // only consider entries with symbols
48  const auto constLegendSymbolItems = mRenderer->legendSymbolItems();
49  for ( const QgsLegendSymbolItem &item : constLegendSymbolItems )
50  {
51  if ( item.symbol() )
52  mLegendSymbols << item;
53  }
54  }
55 
56  const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
57  int maxLayers = 0;
58  tableLevels->setRowCount( mLegendSymbols.count() );
59  for ( int i = 0; i < mLegendSymbols.count(); i++ )
60  {
61  QgsSymbol *sym = mLegendSymbols.at( i ).symbol();
62 
63  // set icons for the rows
64  QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( sym, QSize( iconSize, iconSize ) );
65  tableLevels->setVerticalHeaderItem( i, new QTableWidgetItem( icon, QString() ) );
66 
67  // find out max. number of layers per symbol
68  int layers = sym->symbolLayerCount();
69  if ( layers > maxLayers )
70  maxLayers = layers;
71  }
72 
73  tableLevels->setColumnCount( maxLayers + 1 );
74  tableLevels->setHorizontalHeaderItem( 0, new QTableWidgetItem( QString() ) );
75  for ( int i = 0; i < maxLayers; i++ )
76  {
77  QString name = tr( "Layer %1" ).arg( i );
78  tableLevels->setHorizontalHeaderItem( i + 1, new QTableWidgetItem( name ) );
79  }
80 
81  mMaxLayers = maxLayers;
82 
83  updateUi();
84 
85  if ( !usingSymbolLevels )
87 
88  populateTable();
89 
90  connect( tableLevels, &QTableWidget::cellChanged, this, &QgsSymbolLevelsWidget::renderingPassChanged );
91 }
92 
94 {
95  const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
96  for ( int row = 0; row < mLegendSymbols.count(); row++ )
97  {
98  QgsSymbol *sym = mLegendSymbols.at( row ).symbol();
99  QString label = mLegendSymbols.at( row ).label();
100  QTableWidgetItem *itemLabel = new QTableWidgetItem( label );
101  itemLabel->setFlags( itemLabel->flags() ^ Qt::ItemIsEditable );
102  tableLevels->setItem( row, 0, itemLabel );
103  for ( int layer = 0; layer < mMaxLayers; layer++ )
104  {
105  QTableWidgetItem *item = nullptr;
106  if ( layer >= sym->symbolLayerCount() )
107  {
108  item = new QTableWidgetItem();
109  item->setFlags( Qt::ItemFlags() );
110  }
111  else
112  {
113  QgsSymbolLayer *sl = sym->symbolLayer( layer );
115  item = new QTableWidgetItem( icon, QString::number( sl->renderingPass() ) );
116  }
117  tableLevels->setItem( row, layer + 1, item );
118  tableLevels->resizeColumnToContents( 0 );
119  }
120  }
121 
122 }
123 
124 void QgsSymbolLevelsWidget::updateUi()
125 {
126  tableLevels->setEnabled( chkEnable->isChecked() );
127  emit widgetChanged();
128 }
129 
131 {
132  for ( const QgsLegendSymbolItem &legendSymbol : qgis::as_const( mLegendSymbols ) )
133  {
134  QgsSymbol *sym = legendSymbol.symbol();
135  for ( int layer = 0; layer < sym->symbolLayerCount(); layer++ )
136  {
137  mRenderer->setLegendSymbolItem( legendSymbol.ruleKey(), sym->clone() );
138  }
139  }
140 
142 }
143 
145 {
146  for ( int i = 0; i < mLegendSymbols.count(); i++ )
147  {
148  QgsSymbol *sym = mLegendSymbols.at( i ).symbol();
149  for ( int layer = 0; layer < sym->symbolLayerCount(); layer++ )
150  {
151  sym->symbolLayer( layer )->setRenderingPass( layer );
152  }
153  }
154 }
155 
157 {
158  return chkEnable->isChecked();
159 }
160 
161 void QgsSymbolLevelsWidget::renderingPassChanged( int row, int column )
162 {
163  if ( row < 0 || row >= mLegendSymbols.count() )
164  return;
165  QgsSymbol *sym = mLegendSymbols.at( row ).symbol();
166  if ( column < 0 || column > sym->symbolLayerCount() )
167  return;
168  sym->symbolLayer( column - 1 )->setRenderingPass( tableLevels->item( row, column )->text().toInt() );
169 
170  emit widgetChanged();
171 }
172 
174 {
175  mForceOrderingEnabled = enabled;
176  if ( enabled )
177  {
178  chkEnable->setChecked( true );
179  chkEnable->hide();
180  }
181  else
182  chkEnable->show();
183 }
184 
185 QgsSymbolLevelsDialog::QgsSymbolLevelsDialog( QgsFeatureRenderer *renderer, bool usingSymbolLevels, QWidget *parent )
186  : QDialog( parent )
187 {
188  QVBoxLayout *vLayout = new QVBoxLayout();
189  mWidget = new QgsSymbolLevelsWidget( renderer, usingSymbolLevels );
190  vLayout->addWidget( mWidget );
191  QDialogButtonBox *bbox = new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok, Qt::Horizontal );
192  connect( bbox, &QDialogButtonBox::accepted, mWidget, &QgsSymbolLevelsWidget::apply );
193  connect( bbox, &QDialogButtonBox::accepted, this, &QgsSymbolLevelsDialog::accept );
194  connect( bbox, &QDialogButtonBox::rejected, this, &QgsSymbolLevelsDialog::reject );
195  connect( bbox, &QDialogButtonBox::helpRequested, this, &QgsSymbolLevelsDialog::showHelp );
196  vLayout->addWidget( bbox );
197  setLayout( vLayout );
198  setWindowTitle( tr( "Symbol Levels" ) );
199 }
200 
202 {
203  mWidget->setForceOrderingEnabled( enabled );
204 }
205 
206 void QgsSymbolLevelsDialog::showHelp()
207 {
208  QgsHelp::openHelp( QStringLiteral( "working_with_vector/vector_properties.html#symbols-levels" ) );
209 }
210 
212 
213 QWidget *SpinBoxDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &, const QModelIndex & ) const
214 {
215  QSpinBox *editor = new QSpinBox( parent );
216  editor->setMinimum( 0 );
217  editor->setMaximum( 999 );
218  return editor;
219 }
220 
221 void SpinBoxDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const
222 {
223  int value = index.model()->data( index, Qt::EditRole ).toInt();
224  QSpinBox *spinBox = static_cast<QSpinBox *>( editor );
225  spinBox->setValue( value );
226 }
227 
228 void SpinBoxDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
229 {
230  QSpinBox *spinBox = static_cast<QSpinBox *>( editor );
231  spinBox->interpretText();
232  int value = spinBox->value();
233 
234  model->setData( index, value, Qt::EditRole );
235 }
236 
237 void SpinBoxDelegate::updateEditorGeometry( QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex & ) const
238 {
239  editor->setGeometry( option.rect );
240 }
241 
242 
QgsFeatureRenderer::setLegendSymbolItem
virtual void setLegendSymbolItem(const QString &key, QgsSymbol *symbol)
Sets the symbol to be used for a legend symbol item.
Definition: qgsrenderer.cpp:347
QgsSymbolLevelsWidget::usingLevels
bool usingLevels() const
Returns whether the level ordering is enabled.
Definition: qgssymbollevelsdialog.cpp:156
QgsSymbolLevelsWidget::mLegendSymbols
QgsLegendSymbolList mLegendSymbols
Definition: qgssymbollevelsdialog.h:72
qgssymbollayerutils.h
QgsSymbolLayer::setRenderingPass
void setRenderingPass(int renderingPass)
Specifies the rendering pass in which this symbol layer should be rendered.
Definition: qgssymbollayer.cpp:237
QgsSymbolLevelsWidget::apply
void apply()
Apply button.
Definition: qgssymbollevelsdialog.cpp:130
QgsUnitTypes::RenderMillimeters
@ RenderMillimeters
Millimeters.
Definition: qgsunittypes.h:168
QgsFeatureRenderer::legendSymbolItems
virtual QgsLegendSymbolList legendSymbolItems() const
Returns a list of symbology items for the legend.
Definition: qgsrenderer.cpp:353
QgsSymbol
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:64
QgsSymbol::symbolLayer
QgsSymbolLayer * symbolLayer(int layer)
Returns the symbol layer at the specified index.
Definition: qgssymbol.cpp:385
qgssymbollevelsdialog.h
QgsSymbolLevelsWidget
A widget which allows the user to modify the rendering order of symbol layers.
Definition: qgssymbollevelsdialog.h:38
QgsGuiUtils::iconSize
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
Definition: qgsguiutils.cpp:250
QgsSymbolLayerUtils::symbolPreviewIcon
static QIcon symbolPreviewIcon(const QgsSymbol *symbol, QSize size, int padding=0, QgsLegendPatchShape *shape=nullptr)
Returns an icon preview for a color ramp.
Definition: qgssymbollayerutils.cpp:762
QgsLegendSymbolItem
The class stores information about one class/rule of a vector layer renderer in a unified way that ca...
Definition: qgslegendsymbolitem.h:37
QgsSymbolLayer
Definition: qgssymbollayer.h:53
QgsPanelWidget
Base class for any widget that can be shown as a inline panel.
Definition: qgspanelwidget.h:30
QgsSymbolLayer::renderingPass
int renderingPass() const
Specifies the rendering pass in which this symbol layer should be rendered.
Definition: qgssymbollayer.cpp:242
QgsFeatureRenderer::setUsingSymbolLevels
void setUsingSymbolLevels(bool usingSymbolLevels)
Definition: qgsrenderer.h:284
QgsSymbolLevelsWidget::setDefaultLevels
void setDefaultLevels()
Definition: qgssymbollevelsdialog.cpp:144
QgsSymbolLevelsWidget::mForceOrderingEnabled
bool mForceOrderingEnabled
whether symbol layers always should be used (default false)
Definition: qgssymbollevelsdialog.h:75
QgsSymbolLevelsWidget::QgsSymbolLevelsWidget
QgsSymbolLevelsWidget(QgsFeatureRenderer *renderer, bool usingSymbolLevels, QWidget *parent=nullptr)
Constructor for QgsSymbolLevelsWidget.
Definition: qgssymbollevelsdialog.cpp:32
QgsSymbolLevelsWidget::setForceOrderingEnabled
void setForceOrderingEnabled(bool enabled)
Sets whether the level ordering is always forced on and hide the checkbox (used by rule-based rendere...
Definition: qgssymbollevelsdialog.cpp:173
QgsSymbolLevelsWidget::populateTable
void populateTable()
Definition: qgssymbollevelsdialog.cpp:93
QgsSymbolLevelsDialog::QgsSymbolLevelsDialog
QgsSymbolLevelsDialog(QgsFeatureRenderer *renderer, bool usingSymbolLevels, QWidget *parent=nullptr)
Constructor for QgsSymbolLevelsDialog.
Definition: qgssymbollevelsdialog.cpp:185
QgsPanelWidget::widgetChanged
void widgetChanged()
Emitted when the widget state changes.
QgsSymbolLevelsWidget::mMaxLayers
int mMaxLayers
maximal number of layers from all symbols
Definition: qgssymbollevelsdialog.h:69
QgsSymbolLevelsDialog::setForceOrderingEnabled
void setForceOrderingEnabled(bool enabled)
Definition: qgssymbollevelsdialog.cpp:201
qgssymbollayer.h
QgsSymbolLevelsWidget::mRenderer
QgsFeatureRenderer * mRenderer
Definition: qgssymbollevelsdialog.h:71
QgsSymbol::clone
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
QgsFeatureRenderer
Definition: qgsrenderer.h:103
QgsHelp::openHelp
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:36
qgssettings.h
qgsguiutils.h
QgsGuiUtils::scaleIconSize
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
Definition: qgsguiutils.cpp:245
QgsSymbolLayerUtils::symbolLayerPreviewIcon
static QIcon symbolLayerPreviewIcon(const QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit u, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale())
Draws a symbol layer preview to an icon.
Definition: qgssymbollayerutils.cpp:851
qgssymbol.h
QgsSymbol::symbolLayerCount
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
Definition: qgssymbol.h:183