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