QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
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 "qgsguiutils.h"
22
23#include <QTableWidgetItem>
24#include <QItemDelegate>
25#include <QSpinBox>
26#include <QDialogButtonBox>
27
28
30
31QgsSymbolLevelsWidget::QgsSymbolLevelsWidget( QgsFeatureRenderer *renderer, bool usingSymbolLevels, QWidget *parent )
32 : QgsSymbolLevelsWidget( renderer->legendSymbolItems(), usingSymbolLevels, parent )
33{
34 mRenderer = renderer;
35}
36
37QgsSymbolLevelsWidget::QgsSymbolLevelsWidget( const QgsLegendSymbolList &symbols, bool usingSymbolLevels, QWidget *parent )
38 : QgsPanelWidget( parent )
39{
40 setupUi( this );
41
42 tableLevels->setItemDelegate( new SpinBoxDelegate( this ) );
43
44 chkEnable->setChecked( usingSymbolLevels );
45
46 connect( chkEnable, &QAbstractButton::clicked, this, &QgsSymbolLevelsWidget::updateUi );
47
48 // only consider entries with symbols
49 for ( const QgsLegendSymbolItem &item : symbols )
50 {
51 if ( item.symbol() )
52 mLegendSymbols << item;
53 }
54
55 const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
56 int maxLayers = 0;
57 tableLevels->setRowCount( mLegendSymbols.count() );
58 for ( int i = 0; i < mLegendSymbols.count(); i++ )
59 {
60 QgsSymbol *sym = mLegendSymbols.at( i ).symbol();
61
62 // set icons for the rows
63 QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( sym, QSize( iconSize, iconSize ), 0, nullptr, QgsScreenProperties( screen() ) );
64 tableLevels->setVerticalHeaderItem( i, new QTableWidgetItem( icon, QString() ) );
65
66 // find out max. number of layers per symbol
67 int layers = sym->symbolLayerCount();
68 if ( layers > maxLayers )
69 maxLayers = layers;
70 }
71
72 tableLevels->setColumnCount( maxLayers + 1 );
73 tableLevels->setHorizontalHeaderItem( 0, new QTableWidgetItem( QString() ) );
74 for ( int i = 0; i < maxLayers; i++ )
75 {
76 QString name = tr( "Layer %1" ).arg( i );
77 tableLevels->setHorizontalHeaderItem( i + 1, new QTableWidgetItem( name ) );
78 }
79
80 mMaxLayers = maxLayers;
81
82 updateUi();
83
84 if ( !usingSymbolLevels )
85 setDefaultLevels();
86
87 populateTable();
88
89 connect( tableLevels, &QTableWidget::cellChanged, this, &QgsSymbolLevelsWidget::renderingPassChanged );
90}
91
92
93void QgsSymbolLevelsWidget::populateTable()
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 const 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 const 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
123void QgsSymbolLevelsWidget::updateUi()
124{
125 tableLevels->setEnabled( chkEnable->isChecked() );
126 emit widgetChanged();
127}
128
130{
131 if ( !mRenderer )
132 return;
133
134 for ( const QgsLegendSymbolItem &legendSymbol : std::as_const( mLegendSymbols ) )
135 {
136 QgsSymbol *sym = legendSymbol.symbol();
137 for ( int layer = 0; layer < sym->symbolLayerCount(); layer++ )
138 {
139 mRenderer->setLegendSymbolItem( legendSymbol.ruleKey(), sym->clone() );
140 }
141 }
142
143 mRenderer->setUsingSymbolLevels( usingLevels() );
144}
145
146void QgsSymbolLevelsWidget::setDefaultLevels()
147{
148 for ( const QgsLegendSymbolItem &item : std::as_const( mLegendSymbols ) )
149 {
150 QgsSymbol *sym = item.symbol();
151 for ( int layer = 0; layer < sym->symbolLayerCount(); layer++ )
152 {
153 sym->symbolLayer( layer )->setRenderingPass( layer );
154 }
155 }
156}
157
159{
160 return chkEnable->isChecked();
161}
162
164{
165 return mLegendSymbols;
166}
167
168void QgsSymbolLevelsWidget::renderingPassChanged( int row, int column )
169{
170 if ( row < 0 || row >= mLegendSymbols.count() )
171 return;
172 QgsSymbol *sym = mLegendSymbols.at( row ).symbol();
173 if ( column < 0 || column > sym->symbolLayerCount() )
174 return;
175 sym->symbolLayer( column - 1 )->setRenderingPass( tableLevels->item( row, column )->text().toInt() );
176
177 emit widgetChanged();
178}
179
181{
182 mForceOrderingEnabled = enabled;
183 if ( enabled )
184 {
185 chkEnable->setChecked( true );
186 chkEnable->hide();
187 }
188 else
189 chkEnable->show();
190}
191
192
193//
194// QgsSymbolLevelsDialog
195//
196
197QgsSymbolLevelsDialog::QgsSymbolLevelsDialog( QgsFeatureRenderer *renderer, bool usingSymbolLevels, QWidget *parent )
198 : QDialog( parent )
199{
200 QVBoxLayout *vLayout = new QVBoxLayout();
201 mWidget = new QgsSymbolLevelsWidget( renderer, usingSymbolLevels );
202 vLayout->addWidget( mWidget );
203 QDialogButtonBox *bbox = new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok, Qt::Horizontal );
204 connect( bbox, &QDialogButtonBox::accepted, this, &QgsSymbolLevelsDialog::accept );
205 connect( bbox, &QDialogButtonBox::rejected, this, &QgsSymbolLevelsDialog::reject );
206 connect( bbox, &QDialogButtonBox::helpRequested, this, &QgsSymbolLevelsDialog::showHelp );
207 vLayout->addWidget( bbox );
208 setLayout( vLayout );
209 setWindowTitle( tr( "Symbol Levels" ) );
210}
211
213{
214 mWidget->setForceOrderingEnabled( enabled );
215}
216
218{
219 return mWidget->usingLevels();
220}
221
223{
224 return mWidget->symbolLevels();
225}
226
227void QgsSymbolLevelsDialog::showHelp()
228{
229 QgsHelp::openHelp( QStringLiteral( "working_with_vector/vector_properties.html#symbols-levels" ) );
230}
231
233
234QWidget *SpinBoxDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &, const QModelIndex & ) const
235{
236 QSpinBox *editor = new QSpinBox( parent );
237 editor->setMinimum( 0 );
238 editor->setMaximum( 999 );
239 return editor;
240}
241
242void SpinBoxDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const
243{
244 int value = index.model()->data( index, Qt::EditRole ).toInt();
245 QSpinBox *spinBox = static_cast<QSpinBox *>( editor );
246 spinBox->setValue( value );
247}
248
249void SpinBoxDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
250{
251 QSpinBox *spinBox = static_cast<QSpinBox *>( editor );
252 spinBox->interpretText();
253 int value = spinBox->value();
254
255 model->setData( index, value, Qt::EditRole );
256}
257
258void SpinBoxDelegate::updateEditorGeometry( QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex & ) const
259{
260 editor->setGeometry( option.rect );
261}
262
263
@ Millimeters
Millimeters.
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:299
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:39
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.
Stores properties relating to a screen.
static QIcon symbolLayerPreviewIcon(const QgsSymbolLayer *layer, Qgis::RenderUnit u, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::SymbolType parentSymbolType=Qgis::SymbolType::Hybrid, QgsMapLayer *mapLayer=nullptr, const QgsScreenProperties &screen=QgsScreenProperties())
Draws a symbol layer preview to an icon.
static QIcon symbolPreviewIcon(const QgsSymbol *symbol, QSize size, int padding=0, QgsLegendPatchShape *shape=nullptr, const QgsScreenProperties &screen=QgsScreenProperties())
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:94
QgsSymbolLayer * symbolLayer(int layer)
Returns the symbol layer at the specified index.
Definition: qgssymbol.cpp:760
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:156
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