QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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
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
32QgsSymbolLevelsWidget::QgsSymbolLevelsWidget( QgsFeatureRenderer *renderer, bool usingSymbolLevels, QWidget *parent )
33 : QgsSymbolLevelsWidget( renderer->legendSymbolItems(), usingSymbolLevels, parent )
34{
35 mRenderer = renderer;
36}
37
38QgsSymbolLevelsWidget::QgsSymbolLevelsWidget( const QgsLegendSymbolList &symbols, bool usingSymbolLevels, QWidget *parent )
39 : QgsPanelWidget( parent )
40{
41 setupUi( this );
42
43 tableLevels->setItemDelegate( new SpinBoxDelegate( this ) );
44
45 chkEnable->setChecked( usingSymbolLevels );
46
47 connect( chkEnable, &QAbstractButton::clicked, this, &QgsSymbolLevelsWidget::updateUi );
48
49 // only consider entries with symbols
50 for ( const QgsLegendSymbolItem &item : symbols )
51 {
52 if ( item.symbol() )
53 mLegendSymbols << item;
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 )
86 setDefaultLevels();
87
88 populateTable();
89
90 connect( tableLevels, &QTableWidget::cellChanged, this, &QgsSymbolLevelsWidget::renderingPassChanged );
91}
92
93
94void QgsSymbolLevelsWidget::populateTable()
95{
96 const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
97 for ( int row = 0; row < mLegendSymbols.count(); row++ )
98 {
99 QgsSymbol *sym = mLegendSymbols.at( row ).symbol();
100 const QString label = mLegendSymbols.at( row ).label();
101 QTableWidgetItem *itemLabel = new QTableWidgetItem( label );
102 itemLabel->setFlags( itemLabel->flags() ^ Qt::ItemIsEditable );
103 tableLevels->setItem( row, 0, itemLabel );
104 for ( int layer = 0; layer < mMaxLayers; layer++ )
105 {
106 QTableWidgetItem *item = nullptr;
107 if ( layer >= sym->symbolLayerCount() )
108 {
109 item = new QTableWidgetItem();
110 item->setFlags( Qt::ItemFlags() );
111 }
112 else
113 {
114 const QgsSymbolLayer *sl = sym->symbolLayer( layer );
116 item = new QTableWidgetItem( icon, QString::number( sl->renderingPass() ) );
117 }
118 tableLevels->setItem( row, layer + 1, item );
119 tableLevels->resizeColumnToContents( 0 );
120 }
121 }
122}
123
124void QgsSymbolLevelsWidget::updateUi()
125{
126 tableLevels->setEnabled( chkEnable->isChecked() );
127 emit widgetChanged();
128}
129
131{
132 if ( !mRenderer )
133 return;
134
135 for ( const QgsLegendSymbolItem &legendSymbol : std::as_const( mLegendSymbols ) )
136 {
137 QgsSymbol *sym = legendSymbol.symbol();
138 for ( int layer = 0; layer < sym->symbolLayerCount(); layer++ )
139 {
140 mRenderer->setLegendSymbolItem( legendSymbol.ruleKey(), sym->clone() );
141 }
142 }
143
144 mRenderer->setUsingSymbolLevels( usingLevels() );
145}
146
147void QgsSymbolLevelsWidget::setDefaultLevels()
148{
149 for ( const QgsLegendSymbolItem &item : std::as_const( mLegendSymbols ) )
150 {
151 QgsSymbol *sym = item.symbol();
152 for ( int layer = 0; layer < sym->symbolLayerCount(); layer++ )
153 {
154 sym->symbolLayer( layer )->setRenderingPass( layer );
155 }
156 }
157}
158
160{
161 return chkEnable->isChecked();
162}
163
165{
166 return mLegendSymbols;
167}
168
169void QgsSymbolLevelsWidget::renderingPassChanged( int row, int column )
170{
171 if ( row < 0 || row >= mLegendSymbols.count() )
172 return;
173 QgsSymbol *sym = mLegendSymbols.at( row ).symbol();
174 if ( column < 0 || column > sym->symbolLayerCount() )
175 return;
176 sym->symbolLayer( column - 1 )->setRenderingPass( tableLevels->item( row, column )->text().toInt() );
177
178 emit widgetChanged();
179}
180
182{
183 mForceOrderingEnabled = enabled;
184 if ( enabled )
185 {
186 chkEnable->setChecked( true );
187 chkEnable->hide();
188 }
189 else
190 chkEnable->show();
191}
192
193
194//
195// QgsSymbolLevelsDialog
196//
197
198QgsSymbolLevelsDialog::QgsSymbolLevelsDialog( QgsFeatureRenderer *renderer, bool usingSymbolLevels, QWidget *parent )
199 : QDialog( parent )
200{
201 QVBoxLayout *vLayout = new QVBoxLayout();
202 mWidget = new QgsSymbolLevelsWidget( renderer, usingSymbolLevels );
203 vLayout->addWidget( mWidget );
204 QDialogButtonBox *bbox = new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok, Qt::Horizontal );
205 connect( bbox, &QDialogButtonBox::accepted, this, &QgsSymbolLevelsDialog::accept );
206 connect( bbox, &QDialogButtonBox::rejected, this, &QgsSymbolLevelsDialog::reject );
207 connect( bbox, &QDialogButtonBox::helpRequested, this, &QgsSymbolLevelsDialog::showHelp );
208 vLayout->addWidget( bbox );
209 setLayout( vLayout );
210 setWindowTitle( tr( "Symbol Levels" ) );
211}
212
214{
215 mWidget->setForceOrderingEnabled( enabled );
216}
217
219{
220 return mWidget->usingLevels();
221}
222
224{
225 return mWidget->symbolLevels();
226}
227
228void QgsSymbolLevelsDialog::showHelp()
229{
230 QgsHelp::openHelp( QStringLiteral( "working_with_vector/vector_properties.html#symbols-levels" ) );
231}
232
234
235QWidget *SpinBoxDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &, const QModelIndex & ) const
236{
237 QSpinBox *editor = new QSpinBox( parent );
238 editor->setMinimum( 0 );
239 editor->setMaximum( 999 );
240 return editor;
241}
242
243void SpinBoxDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const
244{
245 int value = index.model()->data( index, Qt::EditRole ).toInt();
246 QSpinBox *spinBox = static_cast<QSpinBox *>( editor );
247 spinBox->setValue( value );
248}
249
250void SpinBoxDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
251{
252 QSpinBox *spinBox = static_cast<QSpinBox *>( editor );
253 spinBox->interpretText();
254 int value = spinBox->value();
255
256 model->setData( index, value, Qt::EditRole );
257}
258
259void SpinBoxDelegate::updateEditorGeometry( QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex & ) const
260{
261 editor->setGeometry( option.rect );
262}
263
264
virtual void setLegendSymbolItem(const QString &key, QgsSymbol *symbol)
Sets the symbol to be used for a legend symbol item.
void setUsingSymbolLevels(bool usingSymbolLevels)
Definition: qgsrenderer.h:293
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:38
The class stores information about one class/rule of a vector layer renderer in a unified way that ca...
Struct for storing maximum and minimum scales for measurements in map units.
Base class for any widget that can be shown as a inline panel.
void widgetChanged()
Emitted when the widget state changes.
static QIcon symbolLayerPreviewIcon(const QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit u, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::SymbolType parentSymbolType=Qgis::SymbolType::Hybrid, QgsMapLayer *mapLayer=nullptr)
Draws a symbol layer preview to an icon.
static QIcon symbolPreviewIcon(const QgsSymbol *symbol, QSize size, int padding=0, QgsLegendPatchShape *shape=nullptr)
Returns an icon preview for a color ramp.
void setRenderingPass(int renderingPass)
Specifies the rendering pass in which this symbol layer should be rendered.
int renderingPass() const
Specifies the rendering pass in which this symbol layer should be rendered.
QgsLegendSymbolList symbolLevels() const
Returns the current legend symbols with rendering passes set, as defined in the widget.
QgsSymbolLevelsDialog(QgsFeatureRenderer *renderer, bool usingSymbolLevels, QWidget *parent=nullptr)
Constructor for QgsSymbolLevelsDialog.
bool usingLevels() const
Returns whether the level ordering is enabled.
void setForceOrderingEnabled(bool enabled)
A widget which allows the user to modify the rendering order of symbol layers.
QgsSymbolLevelsWidget(QgsFeatureRenderer *renderer, bool usingSymbolLevels, QWidget *parent=nullptr)
Constructor for QgsSymbolLevelsWidget.
void setForceOrderingEnabled(bool enabled)
Sets whether the level ordering is always forced on and hide the checkbox (used by rule-based rendere...
bool usingLevels() const
Returns whether the level ordering is enabled.
Q_DECL_DEPRECATED void apply()
Apply button.
QgsLegendSymbolList symbolLevels() const
Returns the current legend symbols with rendering passes set, as defined in the widget.
Abstract base class for all rendered symbols.
Definition: qgssymbol.h:93
QgsSymbolLayer * symbolLayer(int layer)
Returns the symbol layer at the specified index.
Definition: qgssymbol.cpp:756
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
Definition: qgssymbol.h:215
Qgis::SymbolType type() const
Returns the symbol's type.
Definition: qgssymbol.h:152
@ RenderMillimeters
Millimeters.
Definition: qgsunittypes.h:169
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
QList< QgsLegendSymbolItem > QgsLegendSymbolList