QGIS API Documentation 4.1.0-Master (5bf3c20f3c9)
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
119 = QgsSymbolLayerUtils::symbolLayerPreviewIcon( sl, Qgis::RenderUnit::Millimeters, QSize( iconSize, iconSize ), QgsMapUnitScale(), sym->type(), nullptr, QgsScreenProperties( screen() ) );
120 item = new QTableWidgetItem( icon, QString::number( sl->renderingPass() ) );
121 }
122 tableLevels->setItem( row, layer + 1, item );
123 tableLevels->resizeColumnToContents( 0 );
124 }
125 }
126}
127
128void QgsSymbolLevelsWidget::updateUi()
129{
130 tableLevels->setEnabled( chkEnable->isChecked() );
131 emit widgetChanged();
132}
133
135{
136 if ( !mRenderer )
137 return;
138
139 for ( const QgsLegendSymbolItem &legendSymbol : std::as_const( mLegendSymbols ) )
140 {
141 QgsSymbol *sym = legendSymbol.symbol();
142 for ( int layer = 0; layer < sym->symbolLayerCount(); layer++ )
143 {
144 mRenderer->setLegendSymbolItem( legendSymbol.ruleKey(), sym->clone() );
145 }
146 }
147
148 mRenderer->setUsingSymbolLevels( usingLevels() );
149}
150
151void QgsSymbolLevelsWidget::setDefaultLevels()
152{
153 for ( const QgsLegendSymbolItem &item : std::as_const( mLegendSymbols ) )
154 {
155 QgsSymbol *sym = item.symbol();
156 for ( int layer = 0; layer < sym->symbolLayerCount(); layer++ )
157 {
158 sym->symbolLayer( layer )->setRenderingPass( layer );
159 }
160 }
161}
162
164{
165 return chkEnable->isChecked();
166}
167
169{
170 return mLegendSymbols;
171}
172
173void QgsSymbolLevelsWidget::renderingPassChanged( int row, int column )
174{
175 if ( row < 0 || row >= mLegendSymbols.count() )
176 return;
177 QgsSymbol *sym = mLegendSymbols.at( row ).symbol();
178 if ( column < 0 || column > sym->symbolLayerCount() )
179 return;
180 sym->symbolLayer( column - 1 )->setRenderingPass( tableLevels->item( row, column )->text().toInt() );
181
182 emit widgetChanged();
183}
184
186{
187 mForceOrderingEnabled = enabled;
188 if ( enabled )
189 {
190 chkEnable->setChecked( true );
191 chkEnable->hide();
192 }
193 else
194 chkEnable->show();
195}
196
197
198//
199// QgsSymbolLevelsDialog
200//
201
202QgsSymbolLevelsDialog::QgsSymbolLevelsDialog( QgsFeatureRenderer *renderer, bool usingSymbolLevels, QWidget *parent )
203 : QDialog( parent )
204{
205 QVBoxLayout *vLayout = new QVBoxLayout();
206 mWidget = new QgsSymbolLevelsWidget( renderer, usingSymbolLevels );
207 vLayout->addWidget( mWidget );
208 QDialogButtonBox *bbox = new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok, Qt::Horizontal );
209 connect( bbox, &QDialogButtonBox::accepted, this, &QgsSymbolLevelsDialog::accept );
210 connect( bbox, &QDialogButtonBox::rejected, this, &QgsSymbolLevelsDialog::reject );
211 connect( bbox, &QDialogButtonBox::helpRequested, this, &QgsSymbolLevelsDialog::showHelp );
212 vLayout->addWidget( bbox );
213 setLayout( vLayout );
214 setWindowTitle( tr( "Symbol Levels" ) );
215}
216
218{
219 mWidget->setForceOrderingEnabled( enabled );
220}
221
223{
224 return mWidget->usingLevels();
225}
226
228{
229 return mWidget->symbolLevels();
230}
231
232void QgsSymbolLevelsDialog::showHelp()
233{
234 QgsHelp::openHelp( u"working_with_vector/vector_properties.html#symbols-levels"_s );
235}
236
238
239QWidget *SpinBoxDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &, const QModelIndex & ) const
240{
241 QSpinBox *editor = new QSpinBox( parent );
242 editor->setMinimum( 0 );
243 editor->setMaximum( 999 );
244 return editor;
245}
246
247void SpinBoxDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const
248{
249 int value = index.model()->data( index, Qt::EditRole ).toInt();
250 QSpinBox *spinBox = static_cast<QSpinBox *>( editor );
251 spinBox->setValue( value );
252}
253
254void SpinBoxDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const
255{
256 QSpinBox *spinBox = static_cast<QSpinBox *>( editor );
257 spinBox->interpretText();
258 int value = spinBox->value();
259
260 model->setData( index, value, Qt::EditRole );
261}
262
263void SpinBoxDelegate::updateEditorGeometry( QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex & ) const
264{
265 editor->setGeometry( option.rect );
266}
267
268
@ Millimeters
Millimeters.
Definition qgis.h:5341
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:227
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:357
Qgis::SymbolType type() const
Returns the symbol's type.
Definition qgssymbol.h:296
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
QList< QgsLegendSymbolItem > QgsLegendSymbolList