QGIS API Documentation  2.14.0-Essen
qgsdatadefinedbutton.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsdatadefinedbutton.cpp - Data defined selector button
3  --------------------------------------
4  Date : 27-April-2013
5  Copyright : (C) 2013 by Larry Shaffer
6  Email : larrys at dakcarto 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 
16 #include "qgsdatadefinedbutton.h"
17 
18 #include <qgsapplication.h>
19 #include <qgsdatadefined.h>
21 #include <qgsexpression.h>
22 #include <qgsmessageviewer.h>
23 #include <qgsvectorlayer.h>
24 
25 #include <QClipboard>
26 #include <QMenu>
27 #include <QMouseEvent>
28 #include <QPointer>
29 #include <QGroupBox>
30 
31 
32 QIcon QgsDataDefinedButton::mIconDataDefine;
33 QIcon QgsDataDefinedButton::mIconDataDefineOn;
34 QIcon QgsDataDefinedButton::mIconDataDefineError;
35 QIcon QgsDataDefinedButton::mIconDataDefineExpression;
36 QIcon QgsDataDefinedButton::mIconDataDefineExpressionOn;
37 QIcon QgsDataDefinedButton::mIconDataDefineExpressionError;
38 
40  const QgsVectorLayer* vl,
41  const QgsDataDefined* datadefined,
42  const DataTypes& datatypes,
43  const QString& description )
44  : QToolButton( parent )
45  , mExpressionContextCallback( nullptr )
46  , mExpressionContextCallbackContext( nullptr )
47 {
48  // set up static icons
49  if ( mIconDataDefine.isNull() )
50  {
51  mIconDataDefine = QgsApplication::getThemeIcon( "/mIconDataDefine.svg" );
52  mIconDataDefineOn = QgsApplication::getThemeIcon( "/mIconDataDefineOn.svg" );
53  mIconDataDefineError = QgsApplication::getThemeIcon( "/mIconDataDefineError.svg" );
54  mIconDataDefineExpression = QgsApplication::getThemeIcon( "/mIconDataDefineExpression.svg" );
55  mIconDataDefineExpressionOn = QgsApplication::getThemeIcon( "/mIconDataDefineExpressionOn.svg" );
56  mIconDataDefineExpressionError = QgsApplication::getThemeIcon( "/mIconDataDefineExpressionError.svg" );
57  }
58 
59  setFocusPolicy( Qt::StrongFocus );
60 
61  // set default tool button icon properties
62  setFixedSize( 30, 26 );
63  setStyleSheet( QString( "QToolButton{ background: none; border: 1px solid rgba(0, 0, 0, 0%);} QToolButton:focus { border: 1px solid palette(highlight); }" ) );
64  setIconSize( QSize( 24, 24 ) );
65  setPopupMode( QToolButton::InstantPopup );
66 
67  mDefineMenu = new QMenu( this );
68  connect( mDefineMenu, SIGNAL( aboutToShow() ), this, SLOT( aboutToShowMenu() ) );
69  connect( mDefineMenu, SIGNAL( triggered( QAction* ) ), this, SLOT( menuActionTriggered( QAction* ) ) );
70  setMenu( mDefineMenu );
71 
72  mFieldsMenu = new QMenu( this );
73  mActionDataTypes = new QAction( this );
74  // list fields and types in submenu, since there may be many
75  mActionDataTypes->setMenu( mFieldsMenu );
76 
77  mActionVariables = new QAction( tr( "Variable" ), this );
78  mVariablesMenu = new QMenu( this );
79  mActionVariables->setMenu( mVariablesMenu );
80 
81  mActionActive = new QAction( this );
82  QFont f = mActionActive->font();
83  f.setBold( true );
84  mActionActive->setFont( f );
85 
86  mActionDescription = new QAction( tr( "Description..." ), this );
87 
88  mActionExpDialog = new QAction( tr( "Edit..." ), this );
89  mActionExpression = nullptr;
90  mActionPasteExpr = new QAction( tr( "Paste" ), this );
91  mActionCopyExpr = new QAction( tr( "Copy" ), this );
92  mActionClearExpr = new QAction( tr( "Clear" ), this );
93  mActionAssistant = new QAction( tr( "Assistant..." ), this );
94  QFont assistantFont = mActionAssistant->font();
95  assistantFont.setBold( true );
96  mActionAssistant->setFont( assistantFont );
97  mDefineMenu->addAction( mActionAssistant );
98 
99  // set up sibling widget connections
100  connect( this, SIGNAL( dataDefinedActivated( bool ) ), this, SLOT( disableEnabledWidgets( bool ) ) );
101  connect( this, SIGNAL( dataDefinedActivated( bool ) ), this, SLOT( checkCheckedWidgets( bool ) ) );
102 
103  init( vl, datadefined, datatypes, description );
104 }
105 
107 {
108  mEnabledWidgets.clear();
109  mCheckedWidgets.clear();
110 }
111 
113  const QgsDataDefined* datadefined,
114  const DataTypes& datatypes,
115  const QString& description )
116 {
117  mVectorLayer = vl;
118  // construct default property if none or incorrect passed in
119  if ( !datadefined )
120  {
121  mProperty.insert( "active", "0" );
122  mProperty.insert( "useexpr", "0" );
123  mProperty.insert( "expression", QString() );
124  mProperty.insert( "field", QString() );
125  }
126  else
127  {
128  mProperty.insert( "active", datadefined->isActive() ? "1" : "0" );
129  mProperty.insert( "useexpr", datadefined->useExpression() ? "1" : "0" );
130  mProperty.insert( "expression", datadefined->expressionString() );
131  mProperty.insert( "field", datadefined->field() );
132  }
133 
134  mDataTypes = datatypes;
135  mFieldNameList.clear();
136  mFieldTypeList.clear();
137 
138  mInputDescription = description;
139  mFullDescription.clear();
140  mUsageInfo.clear();
141  mCurrentDefinition.clear();
142 
143  // set up data types string
144  mDataTypesString.clear();
145 
146  QStringList ts;
147  if ( mDataTypes.testFlag( String ) )
148  {
149  ts << tr( "string" );
150  }
151  if ( mDataTypes.testFlag( Int ) )
152  {
153  ts << tr( "int" );
154  }
155  if ( mDataTypes.testFlag( Double ) )
156  {
157  ts << tr( "double" );
158  }
159 
160  if ( !ts.isEmpty() )
161  {
162  mDataTypesString = ts.join( ", " );
163  mActionDataTypes->setText( tr( "Field type: " ) + mDataTypesString );
164  }
165 
166  if ( mVectorLayer )
167  {
168  // store just a list of fields of unknown type or those that match the expected type
169  const QgsFields& fields = mVectorLayer->fields();
170  for ( int i = 0; i < fields.count(); ++i )
171  {
172  const QgsField& f = fields.at( i );
173  bool fieldMatch = false;
174  // NOTE: these are the only QVariant enums supported at this time (see QgsField)
175  QString fieldType;
176  switch ( f.type() )
177  {
178  case QVariant::String:
179  fieldMatch = mDataTypes.testFlag( String );
180  fieldType = tr( "string" );
181  break;
182  case QVariant::Int:
183  fieldMatch = mDataTypes.testFlag( Int ) || mDataTypes.testFlag( Double );
184  fieldType = tr( "integer" );
185  break;
186  case QVariant::Double:
187  fieldMatch = mDataTypes.testFlag( Double );
188  fieldType = tr( "double" );
189  break;
190  case QVariant::Invalid:
191  default:
192  fieldMatch = true; // field type is unknown
193  fieldType = tr( "unknown type" );
194  }
195  if ( fieldMatch || mDataTypes.testFlag( AnyType ) )
196  {
197  mFieldNameList << f.name();
198  mFieldTypeList << fieldType;
199  }
200  }
201  }
202 
203  updateGui();
204 }
205 
207 {
208  if ( !dd )
209  return;
210 
211  dd->setActive( isActive() );
213  dd->setField( getField() );
215 }
216 
218 {
219  QgsDataDefined dd;
220  updateDataDefined( &dd );
221  return dd;
222 }
223 
225 {
226  // Ctrl-click to toggle activated state
227  if (( event->modifiers() & ( Qt::ControlModifier ) )
228  || event->button() == Qt::RightButton )
229  {
230  setActive( !isActive() );
231  updateGui();
232  event->ignore();
233  return;
234  }
235 
236  // pass to default behaviour
238 }
239 
240 void QgsDataDefinedButton::aboutToShowMenu()
241 {
242  mDefineMenu->clear();
243 
244  bool hasExp = !getExpression().isEmpty();
245  bool hasField = !getField().isEmpty();
246  QString ddTitle = tr( "Data defined override" );
247 
248  QAction* ddTitleAct = mDefineMenu->addAction( ddTitle );
249  QFont titlefont = ddTitleAct->font();
250  titlefont.setItalic( true );
251  ddTitleAct->setFont( titlefont );
252  ddTitleAct->setEnabled( false );
253 
254  bool addActiveAction = false;
255  if ( useExpression() && hasExp )
256  {
257  QgsExpression exp( getExpression() );
258  // whether expression is parse-able
259  addActiveAction = !exp.hasParserError();
260  }
261  else if ( !useExpression() && hasField )
262  {
263  // whether field exists
264  addActiveAction = mFieldNameList.contains( getField() );
265  }
266 
267  if ( addActiveAction )
268  {
269  ddTitleAct->setText( ddTitle + " (" + ( useExpression() ? tr( "expression" ) : tr( "field" ) ) + ')' );
270  mDefineMenu->addAction( mActionActive );
271  mActionActive->setText( isActive() ? tr( "Deactivate" ) : tr( "Activate" ) );
272  mActionActive->setData( QVariant( isActive() ? false : true ) );
273  }
274 
275  if ( !mFullDescription.isEmpty() )
276  {
277  mDefineMenu->addAction( mActionDescription );
278  }
279 
280  mDefineMenu->addSeparator();
281 
282  bool fieldActive = false;
283  if ( !mDataTypesString.isEmpty() )
284  {
285  QAction* fieldTitleAct = mDefineMenu->addAction( tr( "Attribute field" ) );
286  fieldTitleAct->setFont( titlefont );
287  fieldTitleAct->setEnabled( false );
288 
289  mDefineMenu->addAction( mActionDataTypes );
290 
291  mFieldsMenu->clear();
292 
293  if ( !mFieldNameList.isEmpty() )
294  {
295 
296  for ( int j = 0; j < mFieldNameList.count(); ++j )
297  {
298  QString fldname = mFieldNameList.at( j );
299  QAction* act = mFieldsMenu->addAction( fldname + " (" + mFieldTypeList.at( j ) + ')' );
300  act->setData( QVariant( fldname ) );
301  if ( getField() == fldname )
302  {
303  act->setCheckable( true );
304  act->setChecked( !useExpression() );
305  fieldActive = !useExpression();
306  }
307  }
308  }
309  else
310  {
311  QAction* act = mFieldsMenu->addAction( tr( "No matching field types found" ) );
312  act->setEnabled( false );
313  }
314 
315  mDefineMenu->addSeparator();
316  }
317 
318  mFieldsMenu->menuAction()->setCheckable( true );
319  mFieldsMenu->menuAction()->setChecked( fieldActive );
320 
321  QAction* exprTitleAct = mDefineMenu->addAction( tr( "Expression" ) );
322  exprTitleAct->setFont( titlefont );
323  exprTitleAct->setEnabled( false );
324 
325  mVariablesMenu->clear();
326  bool variableActive = false;
327  if ( mExpressionContextCallback )
328  {
329  QgsExpressionContext context = mExpressionContextCallback( mExpressionContextCallbackContext );
330  QStringList variables = context.variableNames();
331  Q_FOREACH ( const QString& variable, variables )
332  {
333  if ( context.isReadOnly( variable ) ) //only want to show user-set variables
334  continue;
335  if ( variable.startsWith( '_' ) ) //no hidden variables
336  continue;
337 
338  QAction* act = mVariablesMenu->addAction( variable );
339  act->setData( QVariant( variable ) );
340 
341  if ( useExpression() && hasExp && getExpression() == '@' + variable )
342  {
343  act->setCheckable( true );
344  act->setChecked( true );
345  variableActive = true;
346  }
347  }
348  }
349 
350  if ( mVariablesMenu->actions().isEmpty() )
351  {
352  QAction* act = mVariablesMenu->addAction( tr( "No variables set" ) );
353  act->setEnabled( false );
354  }
355 
356  mDefineMenu->addAction( mActionVariables );
357  mVariablesMenu->menuAction()->setCheckable( true );
358  mVariablesMenu->menuAction()->setChecked( variableActive );
359 
360  if ( hasExp )
361  {
362  QString expString = getExpression();
363  if ( expString.length() > 35 )
364  {
365  expString.truncate( 35 );
366  expString.append( "..." );
367  }
368 
369  expString.prepend( tr( "Current: " ) );
370 
371  if ( !mActionExpression )
372  {
373  mActionExpression = new QAction( expString, this );
374  mActionExpression->setCheckable( true );
375  }
376  else
377  {
378  mActionExpression->setText( expString );
379  }
380  mDefineMenu->addAction( mActionExpression );
381  mActionExpression->setChecked( useExpression() && !variableActive );
382 
383  mDefineMenu->addAction( mActionExpDialog );
384  mDefineMenu->addAction( mActionCopyExpr );
385  mDefineMenu->addAction( mActionPasteExpr );
386  mDefineMenu->addAction( mActionClearExpr );
387  }
388  else
389  {
390  mDefineMenu->addAction( mActionExpDialog );
391  mDefineMenu->addAction( mActionPasteExpr );
392  }
393 
394  if ( mAssistant.data() )
395  {
396  mDefineMenu->addSeparator();
397  mDefineMenu->addAction( mActionAssistant );
398  }
399 }
400 
401 void QgsDataDefinedButton::menuActionTriggered( QAction* action )
402 {
403  if ( action == mActionActive )
404  {
405  setActive( mActionActive->data().toBool() );
406  updateGui();
407  }
408  else if ( action == mActionDescription )
409  {
410  showDescriptionDialog();
411  }
412  else if ( action == mActionExpDialog )
413  {
414  showExpressionDialog();
415  }
416  else if ( action == mActionExpression )
417  {
418  setUseExpression( true );
419  setActive( true );
420  updateGui();
421  }
422  else if ( action == mActionCopyExpr )
423  {
425  }
426  else if ( action == mActionPasteExpr )
427  {
428  QString exprString = QApplication::clipboard()->text();
429  if ( !exprString.isEmpty() )
430  {
431  setExpression( exprString );
432  setUseExpression( true );
433  setActive( true );
434  updateGui();
435  }
436  }
437  else if ( action == mActionClearExpr )
438  {
439  // only deactivate if defined expression is being used
440  if ( isActive() && useExpression() )
441  {
442  setUseExpression( false );
443  setActive( false );
444  }
445  setExpression( QString() );
446  updateGui();
447  }
448  else if ( action == mActionAssistant )
449  {
450  showAssistant();
451  }
452  else if ( mFieldsMenu->actions().contains( action ) ) // a field name clicked
453  {
454  if ( action->isEnabled() )
455  {
456  if ( getField() != action->text() )
457  {
458  setField( action->data().toString() );
459  }
460  setUseExpression( false );
461  setActive( true );
462  updateGui();
463  }
464  }
465  else if ( mVariablesMenu->actions().contains( action ) ) // a variable name clicked
466  {
467  if ( getExpression() != action->text().prepend( "@" ) )
468  {
469  setExpression( action->data().toString().prepend( "@" ) );
470  }
471  setUseExpression( true );
472  setActive( true );
473  updateGui();
474  }
475 }
476 
477 void QgsDataDefinedButton::showDescriptionDialog()
478 {
479  QgsMessageViewer* mv = new QgsMessageViewer( this );
480  mv->setWindowTitle( tr( "Data definition description" ) );
481  mv->setMessageAsHtml( mFullDescription );
482  mv->exec();
483 }
484 
485 void QgsDataDefinedButton::showAssistant()
486 {
487  if ( !mAssistant.data() )
488  return;
489 
490  if ( mAssistant->exec() == QDialog::Accepted )
491  {
492  QgsDataDefined dd = mAssistant->dataDefined();
494  setActive( dd.isActive() );
495  if ( dd.isActive() && dd.useExpression() )
497  else if ( dd.isActive() )
498  setField( dd.field() );
499  updateGui();
500  }
501  activateWindow(); // reset focus to parent window
502 }
503 
504 void QgsDataDefinedButton::showExpressionDialog()
505 {
506  QgsExpressionContext context = mExpressionContextCallback ? mExpressionContextCallback( mExpressionContextCallbackContext ) : QgsExpressionContext();
507 
508  QgsExpressionBuilderDialog d( const_cast<QgsVectorLayer*>( mVectorLayer ), getExpression(), this, "generic", context );
509  if ( d.exec() == QDialog::Accepted )
510  {
511  QString newExp = d.expressionText();
513  bool hasExp = !newExp.isEmpty();
514 
515  setUseExpression( hasExp );
516  setActive( hasExp );
517  updateGui();
518  }
519  activateWindow(); // reset focus to parent window
520 }
521 
522 void QgsDataDefinedButton::updateGui()
523 {
524  QString oldDef = mCurrentDefinition;
525  QString newDef( "" );
526  bool hasExp = !getExpression().isEmpty();
527  bool hasField = !getField().isEmpty();
528 
529  if ( useExpression() && !hasExp )
530  {
531  setActive( false );
532  setUseExpression( false );
533  }
534  else if ( !useExpression() && !hasField )
535  {
536  setActive( false );
537  }
538 
539  QIcon icon = mIconDataDefine;
540  QString deftip = tr( "undefined" );
541  if ( useExpression() && hasExp )
542  {
543  icon = isActive() ? mIconDataDefineExpressionOn : mIconDataDefineExpression;
544  newDef = deftip = getExpression();
545 
546  QgsExpression exp( getExpression() );
547  if ( exp.hasParserError() )
548  {
549  setActive( false );
550  icon = mIconDataDefineExpressionError;
551  deftip = tr( "Parse error: %1" ).arg( exp.parserErrorString() );
552  newDef = "";
553  }
554  }
555  else if ( !useExpression() && hasField )
556  {
557  icon = isActive() ? mIconDataDefineOn : mIconDataDefine;
558  newDef = deftip = getField();
559 
560  if ( !mFieldNameList.contains( getField() ) )
561  {
562  setActive( false );
563  icon = mIconDataDefineError;
564  deftip = tr( "'%1' field missing" ).arg( getField() );
565  newDef = "";
566  }
567  }
568 
569  setIcon( icon );
570 
571  // update and emit current definition
572  if ( newDef != oldDef )
573  {
574  mCurrentDefinition = newDef;
575  emit dataDefinedChanged( mCurrentDefinition );
576  }
577 
578  // build full description for tool tip and popup dialog
579  mFullDescription = tr( "<b><u>Data defined override</u></b><br>" );
580 
581  mFullDescription += tr( "<b>Active: </b>%1&nbsp;&nbsp;&nbsp;<i>(ctrl|right-click toggles)</i><br>" ).arg( isActive() ? tr( "yes" ) : tr( "no" ) );
582 
583  if ( !mUsageInfo.isEmpty() )
584  {
585  mFullDescription += tr( "<b>Usage:</b><br>%1<br>" ).arg( mUsageInfo );
586  }
587 
588  if ( !mInputDescription.isEmpty() )
589  {
590  mFullDescription += tr( "<b>Expected input:</b><br>%1<br>" ).arg( mInputDescription );
591  }
592 
593  if ( !mDataTypesString.isEmpty() )
594  {
595  mFullDescription += tr( "<b>Valid input types:</b><br>%1<br>" ).arg( mDataTypesString );
596  }
597 
598  QString deftype( "" );
599  if ( deftip != tr( "undefined" ) )
600  {
601  deftype = QString( " (%1)" ).arg( useExpression() ? tr( "expression" ) : tr( "field" ) );
602  }
603 
604  // truncate long expressions, or tool tip may be too wide for screen
605  if ( deftip.length() > 75 )
606  {
607  deftip.truncate( 75 );
608  deftip.append( "..." );
609  }
610 
611  mFullDescription += tr( "<b>Current definition %1:</b><br>%2" ).arg( deftype, deftip );
612 
613  setToolTip( mFullDescription );
614 
615 }
616 
618 {
619  if ( isActive() != active )
620  {
621  mProperty.insert( "active", active ? "1" : "0" );
622  emit dataDefinedActivated( active );
623  }
624 }
625 
627 {
628  for ( int i = 0; i < wdgts.size(); ++i )
629  {
630  registerEnabledWidget( wdgts.at( i ) );
631  }
632 }
633 
635 {
636  QPointer<QWidget> wdgtP( wdgt );
637  if ( !mEnabledWidgets.contains( wdgtP ) )
638  {
639  mEnabledWidgets.append( wdgtP );
640  }
641 }
642 
644 {
645  QList<QWidget*> wdgtList;
646  wdgtList.reserve( mEnabledWidgets.size() );
647  for ( int i = 0; i < mEnabledWidgets.size(); ++i )
648  {
649  wdgtList << mEnabledWidgets.at( i );
650  }
651  return wdgtList;
652 }
653 
655 {
656  for ( int i = 0; i < mEnabledWidgets.size(); ++i )
657  {
658  mEnabledWidgets.at( i )->setDisabled( disable );
659  }
660 }
661 
663 {
664  for ( int i = 0; i < wdgts.size(); ++i )
665  {
666  registerCheckedWidget( wdgts.at( i ) );
667  }
668 }
669 
671 {
672  QPointer<QWidget> wdgtP( wdgt );
673  if ( !mCheckedWidgets.contains( wdgtP ) )
674  {
675  mCheckedWidgets.append( wdgtP );
676  }
677 }
678 
680 {
681  QList<QWidget*> wdgtList;
682  wdgtList.reserve( mCheckedWidgets.size() );
683  for ( int i = 0; i < mCheckedWidgets.size(); ++i )
684  {
685  wdgtList << mCheckedWidgets.at( i );
686  }
687  return wdgtList;
688 }
689 
691 {
692  mExpressionContextCallback = fnGetExpressionContext;
693  mExpressionContextCallbackContext = context;
694 }
695 
697 {
698  mActionAssistant->setText( title.isEmpty() ? tr( "Assistant..." ) : title );
699  mAssistant.reset( assistant );
700  mAssistant.data()->setParent( this, Qt::Dialog );
701 }
702 
704 {
705  return mAssistant.data();
706 }
707 
709 {
710  // don't uncheck, only set to checked
711  if ( !check )
712  {
713  return;
714  }
715  for ( int i = 0; i < mCheckedWidgets.size(); ++i )
716  {
717  QAbstractButton *btn = qobject_cast< QAbstractButton * >( mCheckedWidgets.at( i ) );
718  if ( btn && btn->isCheckable() )
719  {
720  btn->setChecked( true );
721  continue;
722  }
723  QGroupBox *grpbx = qobject_cast< QGroupBox * >( mCheckedWidgets.at( i ) );
724  if ( grpbx && grpbx->isCheckable() )
725  {
726  grpbx->setChecked( true );
727  }
728  }
729 }
730 
732 {
733  // just something to reduce translation redundancy
734  return tr( "string " );
735 }
736 
738 {
739  return tr( "single character" );
740 }
741 
743 {
744  return tr( "bool [<b>1</b>=True|<b>0</b>=False]" );
745 }
746 
748 {
749  return tr( "string of variable length" );
750 }
751 
753 {
754  return tr( "int [&lt;= 0 =&gt;]" );
755 }
756 
758 {
759  return tr( "int [&gt;= 0]" );
760 }
761 
763 {
764  return tr( "int [&gt;= 1]" );
765 }
766 
768 {
769  return tr( "double [&lt;= 0.0 =&gt;]" );
770 }
771 
773 {
774  return tr( "double [&gt;= 0.0]" );
775 }
776 
778 {
779  return tr( "double [0.0-1.0]" );
780 }
781 
783 {
784  return tr( "double coord [<b>X,Y</b>] as &lt;= 0.0 =&gt;" );
785 }
786 
788 {
789  return tr( "double [-180.0 - 180.0]" );
790 }
791 
793 {
794  return tr( "int [0-100]" );
795 }
796 
798 {
799  return trString() + "[<b>MM</b>|<b>MapUnit</b>]";
800 }
801 
803 {
804  return trString() + "[<b>MM</b>|<b>MapUnit</b>|<b>Percent</b>]";
805 }
806 
808 {
809  return tr( "string [<b>r,g,b</b>] as int 0-255" );
810 }
811 
813 {
814  return tr( "string [<b>r,g,b,a</b>] as int 0-255" );
815 }
816 
818 {
819  return trString() + "[<b>Left</b>|<b>Center</b>|<b>Right</b>]";
820 }
821 
823 {
824  return trString() + "[<b>Bottom</b>|<b>Middle</b>|<b>Top</b>]";
825 }
826 
828 {
829  return trString() + "[<b>bevel</b>|<b>miter</b>|<b>round</b>]";
830 }
831 
833 {
834  return trString() + QLatin1String( "[<b>Normal</b>|<b>Lighten</b>|<b>Screen</b>|<b>Dodge</b>|<br>"
835  "<b>Addition</b>|<b>Darken</b>|<b>Multiply</b>|<b>Burn</b>|<b>Overlay</b>|<br>"
836  "<b>SoftLight</b>|<b>HardLight</b>|<b>Difference</b>|<b>Subtract</b>]" );
837 }
838 
840 {
841  return trString() + QLatin1String( "[<b>filepath</b>] as<br>"
842  "<b>''</b>=empty|absolute|search-paths-relative|<br>"
843  "project-relative|URL" );
844 }
845 
847 {
848  return tr( "string [<b>filepath</b>]" );
849 }
850 
852 {
853  return trString() + QLatin1String( "[<b>A5</b>|<b>A4</b>|<b>A3</b>|<b>A2</b>|<b>A1</b>|<b>A0</b>"
854  "<b>B5</b>|<b>B4</b>|<b>B3</b>|<b>B2</b>|<b>B1</b>|<b>B0</b>"
855  "<b>Legal</b>|<b>Ansi A</b>|<b>Ansi B</b>|<b>Ansi C</b>|<b>Ansi D</b>|<b>Ansi E</b>"
856  "<b>Arch A</b>|<b>Arch B</b>|<b>Arch C</b>|<b>Arch D</b>|<b>Arch E</b>|<b>Arch E1</b>]"
857  );
858 }
859 
861 {
862  return trString() + QLatin1String( "[<b>portrait</b>|<b>landscape</b>]" );
863 }
864 
866 {
867  return trString() + QLatin1String( "[<b>left</b>|<b>center</b>|<b>right</b>]" );
868 }
869 
871 {
872  return trString() + QLatin1String( "[<b>top</b>|<b>center</b>|<b>bottom</b>]" );
873 }
874 
876 {
877  return trString() + QLatin1String( "[<b>linear</b>|<b>radial</b>|<b>conical</b>]" );
878 }
879 
881 {
882  return trString() + QLatin1String( "[<b>feature</b>|<b>viewport</b>]" );
883 }
884 
886 {
887  return trString() + QLatin1String( "[<b>pad</b>|<b>repeat</b>|<b>reflect</b>]" );
888 }
889 
891 {
892  return trString() + QLatin1String( "[<b>no</b>|<b>solid</b>|<b>dash</b>|<b>dot</b>|<b>dash dot</b>|<b>dash dot dot</b>]" );
893 }
894 
896 {
897  return trString() + QLatin1String( "[<b>square</b>|<b>flat</b>|<b>round</b>]" );
898 }
899 
901 {
902  return trString() + QLatin1String( "[<b>solid</b>|<b>horizontal</b>|<b>vertical</b>|<b>cross</b>|<b>b_diagonal</b>|<b>f_diagonal"
903  "</b>|<b>diagonal_x</b>|<b>dense1</b>|<b>dense2</b>|<b>dense3</b>|<b>dense4</b>|<b>dense5"
904  "</b>|<b>dense6</b>|<b>dense7</b>|<b>no]" );
905 }
906 
908 {
909  return trString() + QLatin1String( "[<b>circle</b>|<b>rectangle</b>|<b>cross</b>|<b>triangle</b>]" );
910 }
911 
913 {
914  return tr( "[<b><dash>;<space></b>] e.g. '8;2;1;2'" );
915 }
void setText(const QString &text)
Class for parsing and evaluation of expressions (formerly called "search strings").
void clear()
void setActive(bool active)
void setStyleSheet(const QString &styleSheet)
static QString gradientSpreadDesc()
An assistant (wizard) dialog, accessible from a QgsDataDefinedButton.
void setField(const QString &field)
Set the current defined field.
QString & append(QChar ch)
void setMenu(QMenu *menu)
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
void truncate(int position)
A container class for data source field mapping or expression.
static QString doublePosDesc()
static QString colorNoAlphaDesc()
static QString textVertAlignDesc()
QString field() const
Get the field which this QgsDataDefined represents.
QList< QWidget * > registeredEnabledWidgets()
Return widget siblings that get disabled/enabled when data definition or expression is set/unset...
static QString paperOrientationDesc()
QgsFields fields() const
Returns the list of fields of this layer.
void setFocusPolicy(Qt::FocusPolicy policy)
void dataDefinedChanged(const QString &definition)
Emitted when data definition or expression is changed.
void reserve(int alloc)
void registerEnabledWidgets(const QList< QWidget * > &wdgts)
Register list of sibling widgets that get disabled/enabled when data definition or expression is set/...
void setChecked(bool)
QString & prepend(QChar ch)
QVariant data() const
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
const T & at(int i) const
void addAction(QAction *action)
bool contains(const QString &str, Qt::CaseSensitivity cs) const
static QString unitsMmMuDesc()
static QString anyStringDesc()
int exec()
Container of fields for a vector layer.
Definition: qgsfield.h:187
void disableEnabledWidgets(bool disable)
Set siblings&#39; enabled property when data definition or expression is set/unset.
void setMenu(QMenu *menu)
static QString lineStyleDesc()
QString expressionString() const
Returns the expression string of this QgsDataDefined.
void updateDataDefined(QgsDataDefined *dd) const
Updates a QgsDataDefined with the current settings from the button.
QString join(const QString &separator) const
static QString horizontalAnchorDesc()
void triggered(QAction *action)
QIcon icon() const
QString tr(const char *sourceText, const char *disambiguation, int n)
int size() const
void mouseReleaseEvent(QMouseEvent *event) override
void reset(T *other)
void clear()
void setBold(bool enable)
void setMessageAsHtml(const QString &msg)
void clear()
void setUseExpression(bool use)
Controls if the field or the expression part is active.
void setExpression(const QString &exp)
Set the current defined expression.
QStringList variableNames() const
Returns a list of variables names set by all scopes in the context.
QgsExpressionContext(* ExpressionContextCallback)(const void *context)
Callback function for retrieving the expression context for the button.
void setActive(bool active)
Set whether the current data definition or expression is to be used.
static QString unitsMmMuPercentDesc()
int count(const T &value) const
void registerEnabledWidget(QWidget *wdgt)
Register a sibling widget that gets disabled/enabled when data definition or expression is set/unset...
void append(const T &value)
static QString textHorzAlignDesc()
void registerCheckedWidgets(const QList< QWidget * > &wdgts)
Register list of sibling widgets that get checked when data definition or expression is active...
void setChecked(bool checked)
static QString penJoinStyleDesc()
virtual void mousePressEvent(QMouseEvent *e)
static QString double180RotDesc()
QClipboard * clipboard()
static QString gradientTypeDesc()
void setField(const QString &field)
Set the field name which this QgsDataDefined represents.
void setIconSize(const QSize &size)
QString name() const
Gets the name of the field.
Definition: qgsfield.cpp:84
static QString intTranspDesc()
bool isEmpty() const
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
bool isEmpty() const
QString trimmed() const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
bool isReadOnly(const QString &name) const
Returns whether a variable is read only, and should not be modifiable by users.
QString getExpression() const
The current defined expression.
virtual bool event(QEvent *event)
int count() const
Return number of items.
Definition: qgsfield.cpp:365
bool isCheckable() const
QAction * addSeparator()
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:44
QgsDataDefinedAssistant * assistant()
Returns the assistant used to defined the data defined object properties, if set. ...
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.cpp:385
bool useExpression() const
Returns if the field or the expression part is active.
Qt::KeyboardModifiers modifiers() const
T * data() const
void setData(const QVariant &userData)
void setFixedSize(const QSize &s)
QList< QWidget * > registeredCheckedWidgets()
Return widget siblings that get checked when data definition or expression is active.
void registerGetExpressionContextCallback(ExpressionContextCallback fnGetExpressionContext, const void *context)
Register callback function for retrieving the expression context for the button.
static QString markerStyleDesc()
bool contains(const T &value) const
void dataDefinedActivated(bool active)
Emitted when active state changed.
void setCheckable(bool)
void setItalic(bool enable)
static QString blendModesDesc()
static QString gradientCoordModeDesc()
void setChecked(bool)
QString text(Mode mode) const
static QString trString()
Common descriptions for expected input values.
void registerCheckedWidget(QWidget *wdgt)
Register a sibling widget that get checked when data definition or expression is active.
QString getField() const
The current defined field.
void setAssistant(const QString &title, QgsDataDefinedAssistant *assistant)
Sets an assistant used to define the data defined object properties.
void activateWindow()
bool isCheckable() const
bool isNull() const
static QString verticalAnchorDesc()
void setWindowTitle(const QString &)
void setPopupMode(ToolButtonPopupMode mode)
static QString fillStyleDesc()
static QString paperSizeDesc()
void setUseExpression(bool use)
Set whether the current expression is to be used instead of field mapping.
void checkCheckedWidgets(bool check)
Set siblings&#39; checked property when data definition or expression is active.
A generic message view for displaying QGIS messages.
int length() const
bool toBool() const
static QString intPosOneDesc()
iterator insert(const Key &key, const T &value)
void setText(const QString &text, Mode mode)
QAction * menuAction() const
bool isActive() const
Whether the current data definition or expression is to be used.
void setToolTip(const QString &)
bool useExpression() const
Whether the current expression is to be used instead of field mapping.
QgsDataDefined currentDataDefined() const
Returns a QgsDataDefined which reflects the current settings from the button.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void init(const QgsVectorLayer *vl, const QgsDataDefined *datadefined=nullptr, const QgsDataDefinedButton::DataTypes &datatypes=AnyType, const QString &description=QString())
Initialize a newly constructed data defined button (useful if button already included from form layou...
QList< QAction * > actions() const
static QString customDashDesc()
Represents a vector layer which manages a vector based data sets.
QgsDataDefinedButton(QWidget *parent=nullptr, const QgsVectorLayer *vl=nullptr, const QgsDataDefined *datadefined=nullptr, const QgsDataDefinedButton::DataTypes &datatypes=AnyType, const QString &description=QString())
Construct a new data defined button.
QString parserErrorString() const
Returns parser error.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
QString toString() const
void setExpressionString(const QString &expr)
Sets the expression for this QgsDataDefined.
bool isActive() const
A generic dialog for building expression strings.
void setEnabled(bool)
static QString double0to1Desc()
static QString colorAlphaDesc()
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.
Definition: qgsfield.cpp:89