QGIS API Documentation  3.4.15-Madeira (e83d02e274)
qgsfieldconditionalformatwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsfieldconditionalformatwidget.cpp
3  ---------------------
4  begin : August 2015
5  copyright : (C) 2015 by Nathan Woodrow
6  email : woodrow dot nathan 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  ***************************************************************************/
16 
18 #include "qgssymbol.h"
20 #include "qgssymbollayerutils.h"
21 #include "qgsstyle.h"
22 #include "qgsvectorlayer.h"
23 
25  : QWidget( parent )
26 {
27  setupUi( this );
28  mDeleteButton->hide();
29  connect( mFieldCombo, &QgsFieldComboBox::fieldChanged, this, &QgsFieldConditionalFormatWidget::fieldChanged );
30  connect( fieldRadio, &QAbstractButton::clicked, this, &QgsFieldConditionalFormatWidget::reloadStyles );
31  connect( rowRadio, &QAbstractButton::clicked, this, &QgsFieldConditionalFormatWidget::reloadStyles );
32  connect( mNewButton, &QAbstractButton::clicked, this, &QgsFieldConditionalFormatWidget::addNewRule );
33  connect( mSaveRule, &QAbstractButton::clicked, this, &QgsFieldConditionalFormatWidget::saveRule );
34  connect( mCancelButton, &QAbstractButton::clicked, this, &QgsFieldConditionalFormatWidget::cancelRule );
35  connect( mDeleteButton, &QAbstractButton::clicked, this, &QgsFieldConditionalFormatWidget::deleteRule );
36  connect( listView, &QAbstractItemView::clicked, this, &QgsFieldConditionalFormatWidget::ruleClicked );
37  connect( btnBuildExpression, &QAbstractButton::clicked, this, &QgsFieldConditionalFormatWidget::setExpression );
38  connect( mPresetsList, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFieldConditionalFormatWidget::presetSet );
39  btnBackgroundColor->setAllowOpacity( true );
40  btnBackgroundColor->setShowNoColor( true );
41  btnTextColor->setAllowOpacity( true );
42  btnTextColor->setShowNoColor( true );
43  mPresetsModel = new QStandardItemModel( listView );
44  mModel = new QStandardItemModel( listView );
45  listView->setModel( mModel );
46  mPresetsList->setModel( mPresetsModel );
47  btnChangeIcon->setSymbolType( QgsSymbol::Marker );
48  btnChangeIcon->setSymbol( QgsSymbol::defaultSymbol( QgsWkbTypes::PointGeometry ) );
49 
51 }
52 
53 void QgsFieldConditionalFormatWidget::setExpression()
54 {
56  context.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "value" ), 0, true ) );
57  context.setHighlightedVariables( QStringList() << QStringLiteral( "value" ) );
58 
59  QgsExpressionBuilderDialog dlg( mLayer, mRuleEdit->text(), this, QStringLiteral( "generic" ), context );
60  dlg.setWindowTitle( tr( "Conditional Style Rule Expression" ) );
61 
62  if ( dlg.exec() )
63  {
64  QString expression = dlg.expressionBuilder()->expressionText();
65  mRuleEdit->setText( expression );
66  }
67 }
68 
69 void QgsFieldConditionalFormatWidget::presetSet( int index )
70 {
71  if ( index == -1 || mPresets.isEmpty() )
72  return;
73 
74  QgsConditionalStyle style = mPresets.at( index );
75  setFormattingFromStyle( style );
76 }
77 
79 {
80  mLayer = layer;
81  mFieldCombo->setLayer( layer );
82  mFieldCombo->setCurrentIndex( 0 );
83 }
84 
85 void QgsFieldConditionalFormatWidget::ruleClicked( const QModelIndex &index )
86 {
87  QList<QgsConditionalStyle> styles = getStyles();
88  QgsConditionalStyle style = styles.at( index.row() );
89  editStyle( index.row(), style );
90 }
91 
93 {
94  pages->setCurrentIndex( 1 );
95  mEditIndex = editIndex;
96  mEditing = true;
97  mDeleteButton->show();
98  loadStyle( style );
99 }
100 
102 {
103  mRuleEdit->setText( style.rule() );
104  mNameEdit->setText( style.name() );
105  setFormattingFromStyle( style );
106 }
107 void QgsFieldConditionalFormatWidget::setFormattingFromStyle( const QgsConditionalStyle &style )
108 {
109  btnBackgroundColor->setColor( style.backgroundColor() );
110  btnTextColor->setColor( style.textColor() );
111  if ( style.symbol() )
112  {
113  btnChangeIcon->setSymbol( style.symbol()->clone() );
114  checkIcon->setChecked( true );
115  }
116  else
117  {
118  checkIcon->setChecked( false );
119  }
120  QFont font = style.font();
121  mFontBoldBtn->setChecked( font.bold() );
122  mFontItalicBtn->setChecked( font.italic() );
123  mFontStrikethroughBtn->setChecked( font.strikeOut() );
124  mFontUnderlineBtn->setChecked( font.underline() );
125  mFontFamilyCmbBx->setFont( font );
126 }
127 
128 QList<QgsConditionalStyle> QgsFieldConditionalFormatWidget::getStyles()
129 {
130  QList<QgsConditionalStyle> styles;
131  if ( fieldRadio->isChecked() )
132  {
133  styles = mLayer->conditionalStyles()->fieldStyles( mFieldCombo->currentField() );
134  }
135  if ( rowRadio->isChecked() )
136  {
137  styles = mLayer->conditionalStyles()->rowStyles();
138  }
139  return styles;
140 }
141 
142 void QgsFieldConditionalFormatWidget::deleteRule()
143 {
144  QList<QgsConditionalStyle> styles = getStyles();
145  styles.removeAt( mEditIndex );
146  QString fieldName;
147  if ( fieldRadio->isChecked() )
148  {
149  fieldName = mFieldCombo->currentField();
150  mLayer->conditionalStyles()->setFieldStyles( fieldName, styles );
151  }
152  if ( rowRadio->isChecked() )
153  {
154  mLayer->conditionalStyles()->setRowStyles( styles );
155  }
156 
157  pages->setCurrentIndex( 0 );
158  reloadStyles();
159  emit rulesUpdated( fieldName );
160 }
161 
162 void QgsFieldConditionalFormatWidget::cancelRule()
163 {
164  pages->setCurrentIndex( 0 );
165  reloadStyles();
166  reset();
167 }
168 
169 void QgsFieldConditionalFormatWidget::addNewRule()
170 {
171  pages->setCurrentIndex( 1 );
172  reset();
173 }
174 
176 {
177  mNameEdit->clear();
178  mRuleEdit->clear();
179  if ( fieldRadio->isChecked() )
180  {
181  mRuleEdit->setText( QStringLiteral( "@value " ) );
182  }
183  btnBackgroundColor->setColor( QColor() );
184  btnTextColor->setColor( QColor() );
185  mPresetsList->setCurrentIndex( 0 );
186  mDeleteButton->hide();
187  mEditing = false;
188  checkIcon->setChecked( false );
189  btnChangeIcon->setIcon( QIcon() );
190  btnBackgroundColor->setToNoColor();
191  btnTextColor->setToNoColor();
192 
193  mFontBoldBtn->setChecked( false );
194  mFontItalicBtn->setChecked( false );
195  mFontStrikethroughBtn->setChecked( false );
196  mFontUnderlineBtn->setChecked( false );
197 }
198 
199 
200 void QgsFieldConditionalFormatWidget::setPresets( const QList<QgsConditionalStyle> &styles )
201 {
202  mPresets.clear();
203  mPresetsModel->clear();
204  Q_FOREACH ( const QgsConditionalStyle &style, styles )
205  {
206  if ( style.isValid() )
207  {
208  QStandardItem *item = new QStandardItem( QStringLiteral( "abc - 123" ) );
209  if ( style.validBackgroundColor() )
210  item->setBackground( style.backgroundColor() );
211  if ( style.validTextColor() )
212  item->setForeground( style.textColor() );
213  if ( style.symbol() )
214  item->setIcon( style.icon() );
215  item->setFont( style.font() );
216  mPresetsModel->appendRow( item );
217  mPresets.append( style );
218  }
219  }
220  mPresetsList->setCurrentIndex( 0 );
221 }
222 
223 QList<QgsConditionalStyle> QgsFieldConditionalFormatWidget::defaultPresets() const
224 {
225  QList<QgsConditionalStyle> styles;
227  style.setBackgroundColor( QColor( 154, 216, 113 ) );
228  styles.append( style );
229  style = QgsConditionalStyle();
230  style.setBackgroundColor( QColor( 251, 193, 78 ) );
231  styles.append( style );
232  style = QgsConditionalStyle();
233  style.setBackgroundColor( QColor( 251, 154, 153 ) );
234  styles.append( style );
235  style = QgsConditionalStyle();
236  style.setTextColor( QColor( 154, 216, 113 ) );
237  styles.append( style );
238  style = QgsConditionalStyle();
239  style.setTextColor( QColor( 251, 193, 78 ) );
240  styles.append( style );
241  style = QgsConditionalStyle();
242  style.setTextColor( QColor( 251, 154, 153 ) );
243  styles.append( style );
244  return styles;
245 }
246 
247 void QgsFieldConditionalFormatWidget::saveRule()
248 {
249  QList<QgsConditionalStyle> styles = getStyles();
250 
252 
253  style.setRule( mRuleEdit->text() );
254  style.setName( mNameEdit->text() );
255 
256  QColor backColor = btnBackgroundColor->color();
257  QColor fontColor = btnTextColor->color();
258 
259  QFont font = mFontFamilyCmbBx->currentFont();
260  font.setBold( mFontBoldBtn->isChecked() );
261  font.setItalic( mFontItalicBtn->isChecked() );
262  font.setStrikeOut( mFontStrikethroughBtn->isChecked() );
263  font.setUnderline( mFontUnderlineBtn->isChecked() );
264  style.setFont( font );
265  style.setBackgroundColor( backColor );
266  style.setTextColor( fontColor );
267  if ( checkIcon->isChecked() )
268  {
269  style.setSymbol( btnChangeIcon->clonedSymbol< QgsMarkerSymbol >() );
270  }
271  else
272  {
273  style.setSymbol( nullptr );
274  }
275  if ( mEditing )
276  {
277  styles.replace( mEditIndex, style );
278  }
279  else
280  {
281  styles.append( style );
282  }
283 
284  QString fieldName;
285  if ( fieldRadio->isChecked() )
286  {
287  fieldName = mFieldCombo->currentField();
288  mLayer->conditionalStyles()->setFieldStyles( fieldName, styles );
289  }
290  if ( rowRadio->isChecked() )
291  {
292  mLayer->conditionalStyles()->setRowStyles( styles );
293  }
294  pages->setCurrentIndex( 0 );
295  reloadStyles();
296  emit rulesUpdated( fieldName );
297  reset();
298 }
299 
300 void QgsFieldConditionalFormatWidget::reloadStyles()
301 {
302  mModel->clear();
303 
304  Q_FOREACH ( const QgsConditionalStyle &style, getStyles() )
305  {
306  QStandardItem *item = new QStandardItem( style.displayText() );
307  item->setIcon( QIcon( style.renderPreview() ) );
308  mModel->appendRow( item );
309  }
310 }
311 
312 void QgsFieldConditionalFormatWidget::fieldChanged( const QString &fieldName )
313 {
314  Q_UNUSED( fieldName );
315  reloadStyles();
316 }
317 
319 {
320  pages->setCurrentIndex( 0 );
321 }
322 
323 bool QgsFieldConditionalFormatWidget::isCustomSet()
324 {
325  return ( btnBackgroundColor->color().isValid()
326  || btnTextColor->color().isValid()
327  || mFontButtons->checkedId() != -1 );
328 }
void setName(const QString &value)
Set the name of the style.
Single variable definition for use within a QgsExpressionContextScope.
void setPresets(const QList< QgsConditionalStyle > &styles)
Set the presets that can be used for quick pick.
bool validTextColor() const
Check if the text color is valid for render.
QColor textColor() const
The text color set for style.
bool validBackgroundColor() const
Check if the background color is valid for render.
void setRule(const QString &value)
Set the rule for the style.
QFont font() const
The font for the style.
QList< QgsConditionalStyle > fieldStyles(const QString &fieldName)
Returns the conditional styles set for the field UI properties.
QgsExpressionBuilderWidget * expressionBuilder()
The builder widget that is used by the dialog.
void setLayer(QgsVectorLayer *layer)
Sets the vector layer associated with the widget.
QgsConditionalLayerStyles * conditionalStyles() const
Returns the conditional styles that are set for this layer.
QList< QgsConditionalStyle > defaultPresets() const
The default presets for the widget.
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
A marker symbol type, for rendering Point and MultiPoint geometries.
Definition: qgssymbol.h:732
QList< QgsConditionalStyle > rowStyles()
void viewRules()
Switches the widget to the rules page.
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
void reset()
Resets the formatting options to their default state.
static QgsSymbol * defaultSymbol(QgsWkbTypes::GeometryType geomType)
Returns a new default symbol for the specified geometry type.
Definition: qgssymbol.cpp:275
QPixmap icon() const
The icon set for style generated from the set symbol.
Conditional styling for a rule.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QgsFieldConditionalFormatWidget(QWidget *parent=nullptr)
Constructor for QgsFieldConditionalFormatWidget.
void fieldChanged(const QString &fieldName)
the signal is emitted when the currently selected field changes
QColor backgroundColor() const
The background color for style.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer&#39;s project and layer.
QString name() const
The name of the style.
void setBackgroundColor(const QColor &value)
Set the background color for the style.
QPixmap renderPreview() const
Render a preview icon of the rule.
void setFont(const QFont &value)
Set the font for the style.
Marker symbol.
Definition: qgssymbol.h:85
void setRowStyles(const QList< QgsConditionalStyle > &styles)
Set the conditional styles that apply to full rows of data in the attribute table.
void setSymbol(QgsSymbol *value)
Set the icon for the style.
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
void editStyle(int index, const QgsConditionalStyle &style)
Switches the widget to the edit style mode for the specified style.
QString expressionText()
Gets the expression string that has been set in the expression area.
QString rule() const
The condition rule set for the style.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user...
bool isValid() const
isValid Check if this rule is valid.
QgsSymbol * symbol() const
The symbol used to generate the icon for the style.
void setFieldStyles(const QString &fieldName, const QList< QgsConditionalStyle > &styles)
Set the conditional styles for the field UI properties.
Represents a vector layer which manages a vector based data sets.
QString displayText() const
The name of the style.
A generic dialog for building expression strings.
void loadStyle(const QgsConditionalStyle &style)
void rulesUpdated(const QString &fieldName)
Emitted when the conditional styling rules are updated.
void setTextColor(const QColor &value)
Set the text color for the style.