QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
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 "qgssymbolv2.h"
20 #include "qgssymbollayerv2utils.h"
21 #include "qgsstylev2.h"
22 
24  : QWidget( parent )
25  , mLayer( nullptr )
26  , mEditIndex( 0 )
27  , mEditing( false )
28  , mSymbol( nullptr )
29 {
30  setupUi( this );
31  mDeleteButton->hide();
32  connect( mFieldCombo, SIGNAL( fieldChanged( QString ) ), SLOT( fieldChanged( QString ) ) );
33  connect( fieldRadio, SIGNAL( clicked() ), SLOT( reloadStyles() ) );
34  connect( rowRadio, SIGNAL( clicked() ), SLOT( reloadStyles() ) );
35  connect( mNewButton, SIGNAL( clicked() ), SLOT( addNewRule() ) );
36  connect( mSaveRule, SIGNAL( clicked() ), SLOT( saveRule() ) );
37  connect( mCancelButton, SIGNAL( clicked() ), SLOT( cancelRule() ) );
38  connect( mDeleteButton, SIGNAL( clicked() ), SLOT( deleteRule() ) );
39  connect( listView, SIGNAL( clicked( QModelIndex ) ), SLOT( ruleClicked( QModelIndex ) ) );
40  connect( btnChangeIcon , SIGNAL( clicked() ), SLOT( updateIcon() ) );
41  connect( btnBuildExpression , SIGNAL( clicked() ), SLOT( setExpression() ) );
42  connect( mPresetsList , SIGNAL( currentIndexChanged( int ) ), SLOT( presetSet( int ) ) );
43  btnBackgroundColor->setAllowAlpha( true );
44  btnBackgroundColor->setShowNoColor( true );
45  btnTextColor->setAllowAlpha( true );
46  btnTextColor->setShowNoColor( true );
47  mPresetsModel = new QStandardItemModel( listView );
48  mModel = new QStandardItemModel( listView );
49  listView->setModel( mModel );
50  mPresetsList->setModel( mPresetsModel );
51 
53 }
54 
56 {
57  delete mSymbol;
58 }
59 
60 void QgsFieldConditionalFormatWidget::updateIcon()
61 {
63 
64  QgsSymbolV2SelectorDialog dlg( mSymbol, QgsStyleV2::defaultStyle(), nullptr, this );
65  if ( !dlg.exec() )
66  {
67  return;
68  }
69 
70  QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( mSymbol, btnChangeIcon->iconSize() );
71  btnChangeIcon->setIcon( icon );
72 }
73 
74 void QgsFieldConditionalFormatWidget::setExpression()
75 {
76  QgsExpressionContext context;
80  context.lastScope()->addVariable( QgsExpressionContextScope::StaticVariable( QString( "value" ), 0, true ) );
81  context.setHighlightedVariables( QStringList() << "value" );
82 
83  QgsExpressionBuilderDialog dlg( mLayer, mRuleEdit->text(), this, "generic", context );
84  dlg.setWindowTitle( tr( "Conditional style rule expression" ) );
85 
86  if ( dlg.exec() )
87  {
88  QString expression = dlg.expressionBuilder()->expressionText();
89  mRuleEdit->setText( expression );
90  }
91 }
92 
93 void QgsFieldConditionalFormatWidget::presetSet( int index )
94 {
95  if ( index == -1 || mPresets.isEmpty() )
96  return;
97 
98  QgsConditionalStyle style = mPresets.at( index );
99  setFormattingFromStyle( style );
100 }
101 
103 {
104  mLayer = theLayer;
105  mFieldCombo->setLayer( theLayer );
106  mFieldCombo->setCurrentIndex( 0 );
107 }
108 
109 void QgsFieldConditionalFormatWidget::ruleClicked( const QModelIndex& index )
110 {
111  QList<QgsConditionalStyle> styles = getStyles();
112  QgsConditionalStyle style = styles.at( index.row() );
113  editStyle( index.row(), style );
114 }
115 
117 {
118  pages->setCurrentIndex( 1 );
119  mEditIndex = editIndex;
120  mEditing = true;
121  mDeleteButton->show();
122  loadStyle( style );
123 }
124 
126 {
127  mRuleEdit->setText( style.rule() );
128  mNameEdit->setText( style.name() );
129  setFormattingFromStyle( style );
130 }
131 void QgsFieldConditionalFormatWidget::setFormattingFromStyle( const QgsConditionalStyle& style )
132 {
133  btnBackgroundColor->setColor( style.backgroundColor() );
134  btnTextColor->setColor( style.textColor() );
135  if ( !style.icon().isNull() )
136  {
137  checkIcon->setChecked( true );
138  QIcon icon( style.icon() );
139  btnChangeIcon->setIcon( icon );
140  }
141  else
142  {
143  checkIcon->setChecked( false );
144  btnChangeIcon->setIcon( QIcon() );
145  }
146  if ( style.symbol() )
147  {
148  mSymbol = style.symbol()->clone();
149  }
150  else
151  {
152  mSymbol = nullptr;
153  }
154  QFont font = style.font();
155  mFontBoldBtn->setChecked( font.bold() );
156  mFontItalicBtn->setChecked( font.italic() );
157  mFontStrikethroughBtn->setChecked( font.strikeOut() );
158  mFontUnderlineBtn->setChecked( font.underline() );
159  mFontFamilyCmbBx->setFont( font );
160 }
161 
162 QList<QgsConditionalStyle> QgsFieldConditionalFormatWidget::getStyles()
163 {
165  if ( fieldRadio->isChecked() )
166  {
167  styles = mLayer->conditionalStyles()->fieldStyles( mFieldCombo->currentField() );
168  }
169  if ( rowRadio->isChecked() )
170  {
171  styles = mLayer->conditionalStyles()->rowStyles();
172  }
173  return styles;
174 }
175 
176 void QgsFieldConditionalFormatWidget::deleteRule()
177 {
178  QList<QgsConditionalStyle> styles = getStyles();
179  styles.removeAt( mEditIndex );
180  QString fieldName;
181  if ( fieldRadio->isChecked() )
182  {
183  fieldName = mFieldCombo->currentField();
184  mLayer->conditionalStyles()->setFieldStyles( fieldName, styles );
185  }
186  if ( rowRadio->isChecked() )
187  {
188  mLayer->conditionalStyles()->setRowStyles( styles );
189  }
190 
191  pages->setCurrentIndex( 0 );
192  reloadStyles();
193  emit rulesUpdated( fieldName );
194 }
195 
196 void QgsFieldConditionalFormatWidget::cancelRule()
197 {
198  pages->setCurrentIndex( 0 );
199  reloadStyles();
200  reset();
201 }
202 
203 void QgsFieldConditionalFormatWidget::addNewRule()
204 {
205  pages->setCurrentIndex( 1 );
206  reset();
207 }
208 
210 {
211  mSymbol = nullptr;
212  mNameEdit->clear();
213  mRuleEdit->clear();
214  if ( fieldRadio->isChecked() )
215  {
216  mRuleEdit->setText( "@value " );
217  }
218  btnBackgroundColor->setColor( QColor() );
219  btnTextColor->setColor( QColor() );
220  mPresetsList->setCurrentIndex( 0 );
221  mDeleteButton->hide();
222  mEditing = false;
223  checkIcon->setChecked( false );
224  btnChangeIcon->setIcon( QIcon() );
225  btnBackgroundColor->setToNoColor();
226  btnTextColor->setToNoColor();
227 
228  mFontBoldBtn->setChecked( false );
229  mFontItalicBtn->setChecked( false );
230  mFontStrikethroughBtn->setChecked( false );
231  mFontUnderlineBtn->setChecked( false );
232 }
233 
234 
236 {
237  mPresets.clear();
238  mPresetsModel->clear();
239  Q_FOREACH ( const QgsConditionalStyle& style, styles )
240  {
241  if ( style.isValid() )
242  {
243  QStandardItem* item = new QStandardItem( "abc - 123" );
244  if ( style.backgroundColor().isValid() )
245  item->setBackground( style.backgroundColor() );
246  if ( style.textColor().isValid() )
247  item->setForeground( style.textColor() );
248  if ( style.symbol() )
249  item->setIcon( style.icon() );
250  item->setFont( style.font() );
251  mPresetsModel->appendRow( item );
252  mPresets.append( style );
253  }
254  }
255  mPresetsList->setCurrentIndex( 0 );
256 }
257 
259 {
262  style.setBackgroundColor( QColor( 154, 216, 113 ) );
263  styles.append( style );
264  style = QgsConditionalStyle();
265  style.setBackgroundColor( QColor( 251, 193, 78 ) );
266  styles.append( style );
267  style = QgsConditionalStyle();
268  style.setBackgroundColor( QColor( 251, 154, 153 ) );
269  styles.append( style );
270  style = QgsConditionalStyle();
271  style.setTextColor( QColor( 154, 216, 113 ) );
272  styles.append( style );
273  style = QgsConditionalStyle();
274  style.setTextColor( QColor( 251, 193, 78 ) );
275  styles.append( style );
276  style = QgsConditionalStyle();
277  style.setTextColor( QColor( 251, 154, 153 ) );
278  styles.append( style );
279  return styles;
280 }
281 
282 void QgsFieldConditionalFormatWidget::saveRule()
283 {
284  QList<QgsConditionalStyle> styles = getStyles();
285 
287 
288  style.setRule( mRuleEdit->text() );
289  style.setName( mNameEdit->text() );
290 
291  QColor backColor = btnBackgroundColor->color();
292  QColor fontColor = btnTextColor->color();
293 
294  QFont font = mFontFamilyCmbBx->currentFont();
295  font.setBold( mFontBoldBtn->isChecked() );
296  font.setItalic( mFontItalicBtn->isChecked() );
297  font.setStrikeOut( mFontStrikethroughBtn->isChecked() );
298  font.setUnderline( mFontUnderlineBtn->isChecked() );
299  style.setFont( font );
300  style.setBackgroundColor( backColor );
301  style.setTextColor( fontColor );
302  if ( mSymbol && checkIcon->isChecked() )
303  {
304  style.setSymbol( mSymbol );
305  }
306  else
307  {
308  style.setSymbol( nullptr );
309  }
310  if ( mEditing )
311  {
312  styles.replace( mEditIndex, style );
313  }
314  else
315  {
316  styles.append( style );
317  }
318 
319  QString fieldName;
320  if ( fieldRadio->isChecked() )
321  {
322  fieldName = mFieldCombo->currentField();
323  mLayer->conditionalStyles()->setFieldStyles( fieldName, styles );
324  }
325  if ( rowRadio->isChecked() )
326  {
327  mLayer->conditionalStyles()->setRowStyles( styles );
328  }
329  pages->setCurrentIndex( 0 );
330  reloadStyles();
331  emit rulesUpdated( fieldName );
332  reset();
333 }
334 
335 void QgsFieldConditionalFormatWidget::reloadStyles()
336 {
337  mModel->clear();
338 
339  Q_FOREACH ( const QgsConditionalStyle& style, getStyles() )
340  {
341  QStandardItem* item = new QStandardItem( style.displayText() );
342  item->setIcon( QIcon( style.renderPreview() ) );
343  mModel->appendRow( item );
344  }
345 }
346 
347 void QgsFieldConditionalFormatWidget::fieldChanged( const QString& fieldName )
348 {
349  Q_UNUSED( fieldName );
350  reloadStyles();
351 }
352 
354 {
355  pages->setCurrentIndex( 0 );
356 }
357 
358 bool QgsFieldConditionalFormatWidget::isCustomSet()
359 {
360  return ( btnBackgroundColor->color().isValid()
361  || btnTextColor->color().isValid()
362  || mFontButtons->checkedId() != -1 );
363 }
void clear()
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.
static unsigned index
void setPresets(const QList< QgsConditionalStyle > &styles)
Set the presets that can be used for quick pick.
void setupUi(QWidget *widget)
void setIcon(const QIcon &icon)
QList< QgsConditionalStyle > defaultPresets() const
The default presets for the widget.
void setRule(const QString &value)
Set the rule for the style.
void setBackground(const QBrush &brush)
virtual QgsSymbolV2 * clone() const =0
QStyle * style() const
QList< QgsConditionalStyle > fieldStyles(const QString &fieldName)
Returns the conditional styles set for the field UI properties.
const T & at(int i) const
void removeAt(int i)
void setUnderline(bool enable)
int exec()
QPixmap icon() const
The icon set for style generated from the set symbol.
const QPixmap * icon() const
QString tr(const char *sourceText, const char *disambiguation, int n)
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
bool bold() const
bool italic() const
QgsConditionalLayerStyles * conditionalStyles() const
Return the conditional styles that are set for this layer.
void setBold(bool enable)
void setColor(const QColor &color)
QList< QgsConditionalStyle > rowStyles()
void viewRules()
Switches the widget to the rules page.
QgsExpressionContextScope * lastScope()
Returns the last scope added to the context.
static QIcon symbolPreviewIcon(QgsSymbolV2 *symbol, QSize size)
void reset()
Resets the formatting options to their default state.
void append(const T &value)
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
Conditional styling for a rule.
bool isEmpty() const
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.
static QgsStyleV2 * defaultStyle()
return default application-wide style
Definition: qgsstylev2.cpp:51
int row() const
QgsFieldConditionalFormatWidget(QWidget *parent=nullptr)
Constructor for QgsFieldConditionalFormatWidget.
QColor backgroundColor() const
The background color for style.
bool underline() const
void setLayer(QgsVectorLayer *theLayer)
Sets the vector layer associated with the widget.
void setFont(const QFont &font)
bool isNull() const
void setBackgroundColor(const QColor &value)
Set the background color for the style.
const QFont & font() const
void setItalic(bool enable)
void setFont(const QFont &value)
Set the font for the the style.
void setRowStyles(const QList< QgsConditionalStyle > &styles)
Set the conditional styles that apply to full rows of data in the attribute table.
void setForeground(const QBrush &brush)
QColor textColor() const
The text color set for style.
QPixmap renderPreview() const
Render a preview icon of the rule.
void setSymbol(QgsSymbolV2 *value)
Set the icon for the style.
static QgsSymbolV2 * defaultSymbol(QGis::GeometryType geomType)
return new default symbol for specified geometry type
void setWindowTitle(const QString &)
void editStyle(int index, const QgsConditionalStyle &style)
Switches the widget to the edit style mode for the specified style.
void setStrikeOut(bool enable)
QString displayText() const
The name of the style.
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user...
static QgsExpressionContextScope * projectScope()
Creates a new scope which contains variables and functions relating to the current QGIS project...
QgsSymbolV2 * symbol() const
The symbol used to generate the icon for the style.
QFont font() const
The font for the style.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
void setFieldStyles(const QString &fieldName, const QList< QgsConditionalStyle > &styles)
Set the conditional styles for the field UI properties.
bool strikeOut() const
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Represents a vector layer which manages a vector based data sets.
QString rule() const
The condition rule set for the style.
void appendRow(const QList< QStandardItem * > &items)
A generic dialog for building expression strings.
void loadStyle(const QgsConditionalStyle &style)
bool isValid() const
void replace(int i, const T &value)
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.