QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
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 "qgsguiutils.h"
19#include "qgssymbol.h"
20#include "qgssymbollayer.h"
21#include "qgssymbollayerutils.h"
22
23#include <QDialogButtonBox>
24#include <QItemDelegate>
25#include <QSpinBox>
26#include <QString>
27#include <QTableWidgetItem>
28
29#include "moc_qgssymbollevelsdialog.cpp"
30
31using namespace Qt::StringLiterals;
32
34
35QgsSymbolLevelsWidget::QgsSymbolLevelsWidget( QgsFeatureRenderer *renderer, bool usingSymbolLevels, QWidget *parent )
36 : QgsSymbolLevelsWidget( renderer->legendSymbolItems(), usingSymbolLevels, parent )
37{
38 mRenderer = renderer;
39}
40
41QgsSymbolLevelsWidget::QgsSymbolLevelsWidget( const QgsLegendSymbolList &symbols, bool usingSymbolLevels, QWidget *parent )
42 : QgsPanelWidget( parent )
43{
44 setupUi( this );
45
46 tableLevels->setItemDelegate( new SpinBoxDelegate( this ) );
47
48 chkEnable->setChecked( usingSymbolLevels );
49
50 connect( chkEnable, &QAbstractButton::clicked, this, &QgsSymbolLevelsWidget::updateUi );
51
52 // only consider entries with symbols
53 for ( const QgsLegendSymbolItem &item : symbols )
54 {
55 if ( item.symbol() )
56 mLegendSymbols << item;
57 }
58
59 const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
60 int maxLayers = 0;
61 tableLevels->setRowCount( mLegendSymbols.count() );
62 for ( int i = 0; i < mLegendSymbols.count(); i++ )
63 {
64 QgsSymbol *sym = mLegendSymbols.at( i ).symbol();
65
66 // set icons for the rows
67 QIcon icon = QgsSymbolLayerUtils::symbolPreviewIcon( sym, QSize( iconSize, iconSize ), 0, nullptr, QgsScreenProperties( screen() ) );
68 tableLevels->setVerticalHeaderItem( i, new QTableWidgetItem( icon, QString() ) );
69
70 // find out max. number of layers per symbol
71 int layers = sym->symbolLayerCount();
72 if ( layers > maxLayers )
73 maxLayers = layers;
74 }
75
76 tableLevels->setColumnCount( maxLayers + 1 );
77 tableLevels->setHorizontalHeaderItem( 0, new QTableWidgetItem( QString() ) );
78 for ( int i = 0; i < maxLayers; i++ )
79 {
80 QString name = tr( "Layer %1" ).arg( i );
81 tableLevels->setHorizontalHeaderItem( i + 1, new QTableWidgetItem( name ) );
82 }
83
84 mMaxLayers = maxLayers;
85
86 updateUi();
87
88 if ( !usingSymbolLevels )
89 setDefaultLevels();
90
91 populateTable();
92
93 connect( tableLevels, &QTableWidget::cellChanged, this, &QgsSymbolLevelsWidget::renderingPassChanged );
94}
95
96
97void QgsSymbolLevelsWidget::populateTable()
98{
99 const int iconSize = QgsGuiUtils::scaleIconSize( 16 );
100 for ( int row = 0; row < mLegendSymbols.count(); row++ )
101 {
102 QgsSymbol *sym = mLegendSymbols.at( row ).symbol();
103 const QString label = mLegendSymbols.at( row ).label();
104 QTableWidgetItem *itemLabel = new QTableWidgetItem( label );
105 itemLabel->setFlags( itemLabel->flags() ^ Qt::ItemIsEditable );
106 tableLevels->setItem( row, 0, itemLabel );
107 for ( int layer = 0; layer < mMaxLayers; layer++ )
108 {
109 QTableWidgetItem *item = nullptr;
110 if ( layer >= sym->symbolLayerCount() )
111 {
112 item = new QTableWidgetItem();
113 item->setFlags( Qt::ItemFlags() );
114 }
115 else
116 {
117 const QgsSymbolLayer *sl = sym->symbolLayer( layer );
118 const QIcon icon = QgsSymbolLayerUtils::symbolLayerPreviewIcon( sl, Qgis::RenderUnit::Millimeters, QSize( iconSize, iconSize ), QgsMapUnitScale(), sym->type(), nullptr, QgsScreenProperties( screen() ) );
119 item = new QTableWidgetItem( icon, QString::number( sl->renderingPass() ) );
120 }
121 tableLevels->setItem( row, layer + 1, item );
122 tableLevels->resizeColumnToContents( 0 );
123 }
124 }
125}
126
127void QgsSymbolLevelsWidget::updateUi()
128{
129 tableLevels->setEnabled( chkEnable->isChecked() );
130 emit widgetChanged();
131}
132
134{
135 if ( !mRenderer )
136 return;
137
138 for ( const QgsLegendSymbolItem &legendSymbol : std::as_const( mLegendSymbols ) )
139 {
140 QgsSymbol *sym = legendSymbol.symbol();
141 for ( int layer = 0; layer < sym->symbolLayerCount(); layer++ )
142 {
143 mRenderer->setLegendSymbolItem( legendSymbol.ruleKey(), sym->clone() );
144 }
145 }
146
147 mRenderer->setUsingSymbolLevels( usingLevels() );
148}
149
150void QgsSymbolLevelsWidget::setDefaultLevels()
151{
152 for ( const QgsLegendSymbolItem &item : std::as_const( mLegendSymbols ) )
153 {
154 QgsSymbol *sym = item.symbol();
155 for ( int layer = 0; layer < sym->symbolLayerCount(); layer++ )
156 {
157 sym->symbolLayer( layer )->setRenderingPass( layer );
158 }
159 }
160}
161
163{
164 return chkEnable->isChecked();
165}
166
168{
169 return mLegendSymbols;
170}
171
172void QgsSymbolLevelsWidget::renderingPassChanged( int row, int column )
173{
174 if ( row < 0 || row >= mLegendSymbols.count() )
175 return;
176 QgsSymbol *sym = mLegendSymbols.at( row ).symbol();
177 if ( column < 0 || column > sym->symbolLayerCount() )
178 return;
179 sym->symbolLayer( column - 1 )->setRenderingPass( tableLevels->item( row, column )->text().toInt() );
180
181 emit widgetChanged();
182}
183
185{
186 mForceOrderingEnabled = enabled;
187 if ( enabled )
188 {
189 chkEnable->setChecked( true );
190 chkEnable->hide();
191 }
192 else
193 chkEnable->show();
194}
195
196
197//
198// QgsSymbolLevelsDialog
199//
200
201QgsSymbolLevelsDialog::QgsSymbolLevelsDialog( QgsFeatureRenderer *renderer, bool usingSymbolLevels, QWidget *parent )
202 : QDialog( parent )
203{
204 QVBoxLayout *vLayout = new QVBoxLayout();
205 mWidget = new QgsSymbolLevelsWidget( renderer, usingSymbolLevels );
206 vLayout->addWidget( mWidget );
207 QDialogButtonBox *bbox = new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok, Qt::Horizontal );
208 connect( bbox, &QDialogButtonBox::accepted, this, &QgsSymbolLevelsDialog::accept );
209 connect( bbox, &QDialogButtonBox::rejected, this, &QgsSymbolLevelsDialog::reject );
210 connect( bbox, &QDialogButtonBox::helpRequested, this, &QgsSymbolLevelsDialog::showHelp );
211 vLayout->addWidget( bbox );
212 setLayout( vLayout );
213 setWindowTitle( tr( "Symbol Levels" ) );
214}
215
217{
218 mWidget->setForceOrderingEnabled( enabled );
219}
220
222{
223 return mWidget->usingLevels();
224}
225
227{
228 return mWidget->symbolLevels();
229}
230
231void QgsSymbolLevelsDialog::showHelp()
232{
233 QgsHelp::openHelp( u"working_with_vector/vector_properties.html#symbols-levels"_s );
234}
235
237
238QWidget *SpinBoxDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &, const QModelIndex & ) const
239{
240 QSpinBox *editor = new QSpinBox( parent );
241 editor->setMinimum( 0 );
242 editor->setMaximum( 999 );
243 return editor;
244}
245
246void SpinBoxDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const
247{
248 int value = index.model()->data( index, Qt::EditRole ).toInt();
249 QSpinBox *spinBox = static_cast<QSpinBox *>( editor );
250 spinBox->setValue( value );
251}
252
253void SpinBoxDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
254{
255 QSpinBox *spinBox = static_cast<QSpinBox *>( editor );
256 spinBox->interpretText();
257 int value = spinBox->value();
258
259 model->setData( index, value, Qt::EditRole );
260}
261
262void SpinBoxDelegate::updateEditorGeometry( QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex & ) const
263{
264 editor->setGeometry( option.rect );
265}
266
267
@ Millimeters
Millimeters.
Definition qgis.h:5256
Abstract base class for all 2D vector feature renderers.
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition qgshelp.cpp:41
Stores information about one class/rule of a vector layer renderer in a unified way that can be used ...
QgsPanelWidget(QWidget *parent=nullptr)
Base class for any widget that can be shown as an 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:231
QgsSymbolLayer * symbolLayer(int layer)
Returns the symbol layer at the specified index.
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:353
Qgis::SymbolType type() const
Returns the symbol's type.
Definition qgssymbol.h:294
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
QList< QgsLegendSymbolItem > QgsLegendSymbolList