QGIS API Documentation  3.6.0-Noosa (5873452)
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"
24 
26  : QWidget( parent )
27 {
28  setupUi( this );
29  mDeleteButton->hide();
30  connect( mFieldCombo, &QgsFieldComboBox::fieldChanged, this, &QgsFieldConditionalFormatWidget::fieldChanged );
31  connect( fieldRadio, &QAbstractButton::clicked, this, &QgsFieldConditionalFormatWidget::reloadStyles );
32  connect( rowRadio, &QAbstractButton::clicked, this, &QgsFieldConditionalFormatWidget::reloadStyles );
33  connect( mNewButton, &QAbstractButton::clicked, this, &QgsFieldConditionalFormatWidget::addNewRule );
34  connect( mSaveRule, &QAbstractButton::clicked, this, &QgsFieldConditionalFormatWidget::saveRule );
35  connect( mCancelButton, &QAbstractButton::clicked, this, &QgsFieldConditionalFormatWidget::cancelRule );
36  connect( mDeleteButton, &QAbstractButton::clicked, this, &QgsFieldConditionalFormatWidget::deleteRule );
37  connect( listView, &QAbstractItemView::clicked, this, &QgsFieldConditionalFormatWidget::ruleClicked );
38  connect( btnBuildExpression, &QAbstractButton::clicked, this, &QgsFieldConditionalFormatWidget::setExpression );
39  connect( mPresetsList, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsFieldConditionalFormatWidget::presetSet );
40  btnBackgroundColor->setAllowOpacity( true );
41  btnBackgroundColor->setShowNoColor( true );
42  btnTextColor->setAllowOpacity( true );
43  btnTextColor->setShowNoColor( true );
44  mPresetsModel = new QStandardItemModel( listView );
45  mModel = new QStandardItemModel( listView );
46  listView->setModel( mModel );
47  mPresetsList->setModel( mPresetsModel );
48  btnChangeIcon->setSymbolType( QgsSymbol::Marker );
49  btnChangeIcon->setSymbol( QgsSymbol::defaultSymbol( QgsWkbTypes::PointGeometry ) );
50 
52 }
53 
54 void QgsFieldConditionalFormatWidget::setExpression()
55 {
57  context.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QStringLiteral( "value" ), 0, true ) );
58  context.setHighlightedVariables( QStringList() << QStringLiteral( "value" ) );
59 
60  QgsExpressionBuilderDialog dlg( mLayer, mRuleEdit->text(), this, QStringLiteral( "generic" ), context );
61  dlg.setWindowTitle( tr( "Conditional Style Rule Expression" ) );
62 
63  if ( dlg.exec() )
64  {
65  QString expression = dlg.expressionBuilder()->expressionText();
66  mRuleEdit->setText( expression );
67  }
68 }
69 
70 void QgsFieldConditionalFormatWidget::presetSet( int index )
71 {
72  if ( index == -1 || mPresets.isEmpty() )
73  return;
74 
75  QgsConditionalStyle style = mPresets.at( index );
76  setFormattingFromStyle( style );
77 }
78 
80 {
81  mLayer = layer;
82  mFieldCombo->setLayer( layer );
83  mFieldCombo->setCurrentIndex( 0 );
84 }
85 
86 void QgsFieldConditionalFormatWidget::ruleClicked( const QModelIndex &index )
87 {
88  QList<QgsConditionalStyle> styles = getStyles();
89  QgsConditionalStyle style = styles.at( index.row() );
90  editStyle( index.row(), style );
91 }
92 
94 {
95  pages->setCurrentIndex( 1 );
96  mEditIndex = editIndex;
97  mEditing = true;
98  mDeleteButton->show();
99  loadStyle( style );
100 }
101 
103 {
104  mRuleEdit->setText( style.rule() );
105  mNameEdit->setText( style.name() );
106  setFormattingFromStyle( style );
107 }
108 void QgsFieldConditionalFormatWidget::setFormattingFromStyle( const QgsConditionalStyle &style )
109 {
110  btnBackgroundColor->setColor( style.backgroundColor() );
111  btnTextColor->setColor( style.textColor() );
112  if ( style.symbol() )
113  {
114  btnChangeIcon->setSymbol( style.symbol()->clone() );
115  checkIcon->setChecked( true );
116  }
117  else
118  {
119  checkIcon->setChecked( false );
120  }
121  QFont font = style.font();
122  mFontBoldBtn->setChecked( font.bold() );
123  mFontItalicBtn->setChecked( font.italic() );
124  mFontStrikethroughBtn->setChecked( font.strikeOut() );
125  mFontUnderlineBtn->setChecked( font.underline() );
126  mFontFamilyCmbBx->setFont( font );
127 }
128 
129 QList<QgsConditionalStyle> QgsFieldConditionalFormatWidget::getStyles()
130 {
131  QList<QgsConditionalStyle> styles;
132  if ( fieldRadio->isChecked() )
133  {
134  styles = mLayer->conditionalStyles()->fieldStyles( mFieldCombo->currentField() );
135  }
136  if ( rowRadio->isChecked() )
137  {
138  styles = mLayer->conditionalStyles()->rowStyles();
139  }
140  return styles;
141 }
142 
143 void QgsFieldConditionalFormatWidget::deleteRule()
144 {
145  QList<QgsConditionalStyle> styles = getStyles();
146  styles.removeAt( mEditIndex );
147  QString fieldName;
148  if ( fieldRadio->isChecked() )
149  {
150  fieldName = mFieldCombo->currentField();
151  mLayer->conditionalStyles()->setFieldStyles( fieldName, styles );
152  }
153  if ( rowRadio->isChecked() )
154  {
155  mLayer->conditionalStyles()->setRowStyles( styles );
156  }
157 
158  pages->setCurrentIndex( 0 );
159  reloadStyles();
160  emit rulesUpdated( fieldName );
161 }
162 
163 void QgsFieldConditionalFormatWidget::cancelRule()
164 {
165  pages->setCurrentIndex( 0 );
166  reloadStyles();
167  reset();
168 }
169 
170 void QgsFieldConditionalFormatWidget::addNewRule()
171 {
172  pages->setCurrentIndex( 1 );
173  reset();
174 }
175 
177 {
178  mNameEdit->clear();
179  mRuleEdit->clear();
180  if ( fieldRadio->isChecked() )
181  {
182  mRuleEdit->setText( QStringLiteral( "@value " ) );
183  }
184  btnBackgroundColor->setColor( QColor() );
185  btnTextColor->setColor( QColor() );
186  mPresetsList->setCurrentIndex( 0 );
187  mDeleteButton->hide();
188  mEditing = false;
189  checkIcon->setChecked( false );
190  btnChangeIcon->setIcon( QIcon() );
191  btnBackgroundColor->setToNoColor();
192  btnTextColor->setToNoColor();
193 
194  mFontBoldBtn->setChecked( false );
195  mFontItalicBtn->setChecked( false );
196  mFontStrikethroughBtn->setChecked( false );
197  mFontUnderlineBtn->setChecked( false );
198 }
199 
200 
201 void QgsFieldConditionalFormatWidget::setPresets( const QList<QgsConditionalStyle> &styles )
202 {
203  mPresets.clear();
204  mPresetsModel->clear();
205  Q_FOREACH ( const QgsConditionalStyle &style, styles )
206  {
207  if ( style.isValid() )
208  {
209  QStandardItem *item = new QStandardItem( QStringLiteral( "abc - 123" ) );
210  if ( style.validBackgroundColor() )
211  item->setBackground( style.backgroundColor() );
212  if ( style.validTextColor() )
213  item->setForeground( style.textColor() );
214  if ( style.symbol() )
215  item->setIcon( style.icon() );
216  item->setFont( style.font() );
217  mPresetsModel->appendRow( item );
218  mPresets.append( style );
219  }
220  }
221  mPresetsList->setCurrentIndex( 0 );
222 }
223 
224 QList<QgsConditionalStyle> QgsFieldConditionalFormatWidget::defaultPresets() const
225 {
226  QList<QgsConditionalStyle> styles;
228  style.setBackgroundColor( QColor( 154, 216, 113 ) );
229  styles.append( style );
230  style = QgsConditionalStyle();
231  style.setBackgroundColor( QColor( 251, 193, 78 ) );
232  styles.append( style );
233  style = QgsConditionalStyle();
234  style.setBackgroundColor( QColor( 251, 154, 153 ) );
235  styles.append( style );
236  style = QgsConditionalStyle();
237  style.setTextColor( QColor( 154, 216, 113 ) );
238  styles.append( style );
239  style = QgsConditionalStyle();
240  style.setTextColor( QColor( 251, 193, 78 ) );
241  styles.append( style );
242  style = QgsConditionalStyle();
243  style.setTextColor( QColor( 251, 154, 153 ) );
244  styles.append( style );
245  return styles;
246 }
247 
248 void QgsFieldConditionalFormatWidget::saveRule()
249 {
250  QList<QgsConditionalStyle> styles = getStyles();
251 
253 
254  style.setRule( mRuleEdit->text() );
255  style.setName( mNameEdit->text() );
256 
257  QColor backColor = btnBackgroundColor->color();
258  QColor fontColor = btnTextColor->color();
259 
260  QFont font = mFontFamilyCmbBx->currentFont();
261  font.setBold( mFontBoldBtn->isChecked() );
262  font.setItalic( mFontItalicBtn->isChecked() );
263  font.setStrikeOut( mFontStrikethroughBtn->isChecked() );
264  font.setUnderline( mFontUnderlineBtn->isChecked() );
265  style.setFont( font );
266  style.setBackgroundColor( backColor );
267  style.setTextColor( fontColor );
268  if ( checkIcon->isChecked() )
269  {
270  style.setSymbol( btnChangeIcon->clonedSymbol< QgsMarkerSymbol >() );
271  }
272  else
273  {
274  style.setSymbol( nullptr );
275  }
276  if ( mEditing )
277  {
278  styles.replace( mEditIndex, style );
279  }
280  else
281  {
282  styles.append( style );
283  }
284 
285  QString fieldName;
286  if ( fieldRadio->isChecked() )
287  {
288  fieldName = mFieldCombo->currentField();
289  mLayer->conditionalStyles()->setFieldStyles( fieldName, styles );
290  }
291  if ( rowRadio->isChecked() )
292  {
293  mLayer->conditionalStyles()->setRowStyles( styles );
294  }
295  pages->setCurrentIndex( 0 );
296  reloadStyles();
297  emit rulesUpdated( fieldName );
298  reset();
299 }
300 
301 void QgsFieldConditionalFormatWidget::reloadStyles()
302 {
303  mModel->clear();
304 
305  Q_FOREACH ( const QgsConditionalStyle &style, getStyles() )
306  {
307  QStandardItem *item = new QStandardItem( style.displayText() );
308  item->setIcon( QIcon( style.renderPreview() ) );
309  mModel->appendRow( item );
310  }
311 }
312 
313 void QgsFieldConditionalFormatWidget::fieldChanged( const QString &fieldName )
314 {
315  Q_UNUSED( fieldName );
316  reloadStyles();
317 }
318 
320 {
321  pages->setCurrentIndex( 0 );
322 }
323 
324 bool QgsFieldConditionalFormatWidget::isCustomSet()
325 {
326  return ( btnBackgroundColor->color().isValid()
327  || btnTextColor->color().isValid()
328  || mFontButtons->checkedId() != -1 );
329 }
QString name() const
The name of the style.
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.
QList< QgsConditionalStyle > defaultPresets() const
The default presets for the widget.
void setRule(const QString &value)
Set the rule 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.
bool validBackgroundColor() const
Check if the background color is valid for render.
QPixmap icon() const
The icon set for style generated from the set symbol.
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
QgsConditionalLayerStyles * conditionalStyles() const
Returns the conditional styles that are set for this layer.
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:277
Conditional styling for a rule.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
bool isValid() const
isValid Check if this rule is valid.
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.
void setBackgroundColor(const QColor &value)
Set the background color for the style.
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.
QColor textColor() const
The text color set for style.
QPixmap renderPreview() const
Render a preview icon of the rule.
void setSymbol(QgsSymbol *value)
Set the icon for the style.
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
bool validTextColor() const
Check if the text color is valid for render.
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.
QgsSymbol * symbol() const
The symbol used to generate the icon for the style.
QString displayText() const
The name of the style.
QgsFieldConditionalFormatWidget(QWidget *parent SIP_TRANSFERTHIS=nullptr)
Constructor for QgsFieldConditionalFormatWidget.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user...
QFont font() const
The font 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 rule() const
The condition rule set for 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.