27 #include <QMouseEvent> 32 QIcon QgsDataDefinedButton::mIconDataDefine;
33 QIcon QgsDataDefinedButton::mIconDataDefineOn;
34 QIcon QgsDataDefinedButton::mIconDataDefineError;
35 QIcon QgsDataDefinedButton::mIconDataDefineExpression;
36 QIcon QgsDataDefinedButton::mIconDataDefineExpressionOn;
37 QIcon QgsDataDefinedButton::mIconDataDefineExpressionError;
42 const DataTypes& datatypes,
45 , mExpressionContextCallback( nullptr )
46 , mExpressionContextCallbackContext( nullptr )
49 if ( mIconDataDefine.
isNull() )
63 setStyleSheet(
QString(
"QToolButton{ background: none; border: 1px solid rgba(0, 0, 0, 0%);} QToolButton:focus { border: 1px solid palette(highlight); }" ) );
67 mDefineMenu =
new QMenu(
this );
68 connect( mDefineMenu, SIGNAL( aboutToShow() ),
this, SLOT( aboutToShowMenu() ) );
72 mFieldsMenu =
new QMenu(
this );
73 mActionDataTypes =
new QAction(
this );
75 mActionDataTypes->
setMenu( mFieldsMenu );
77 mActionVariables =
new QAction(
tr(
"Variable" ),
this );
78 mVariablesMenu =
new QMenu(
this );
79 mActionVariables->
setMenu( mVariablesMenu );
81 mActionActive =
new QAction(
this );
86 mActionDescription =
new QAction(
tr(
"Description..." ),
this );
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();
96 mActionAssistant->
setFont( assistantFont );
97 mDefineMenu->
addAction( mActionAssistant );
103 init( vl, datadefined, datatypes, description );
108 mEnabledWidgets.
clear();
109 mCheckedWidgets.
clear();
114 const DataTypes& datatypes,
121 mProperty.
insert(
"active",
"0" );
122 mProperty.
insert(
"useexpr",
"0" );
128 mProperty.
insert(
"active", datadefined->
isActive() ?
"1" :
"0" );
134 mDataTypes = datatypes;
135 mFieldNameList.
clear();
136 mFieldTypeList.
clear();
138 mInputDescription = description;
139 mFullDescription.
clear();
141 mCurrentDefinition.
clear();
144 mDataTypesString.
clear();
147 if ( mDataTypes.testFlag(
String ) )
149 ts <<
tr(
"string" );
151 if ( mDataTypes.testFlag(
Int ) )
155 if ( mDataTypes.testFlag(
Double ) )
157 ts <<
tr(
"double" );
162 mDataTypesString = ts.
join(
", " );
163 mActionDataTypes->
setText(
tr(
"Field type: " ) + mDataTypesString );
170 for (
int i = 0; i < fields.
count(); ++i )
173 bool fieldMatch =
false;
178 case QVariant::String:
179 fieldMatch = mDataTypes.testFlag(
String );
180 fieldType =
tr(
"string" );
183 fieldMatch = mDataTypes.testFlag(
Int ) || mDataTypes.testFlag(
Double );
184 fieldType =
tr(
"integer" );
186 case QVariant::Double:
187 fieldMatch = mDataTypes.testFlag(
Double );
188 fieldType =
tr(
"double" );
190 case QVariant::Invalid:
193 fieldType =
tr(
"unknown type" );
195 if ( fieldMatch || mDataTypes.testFlag(
AnyType ) )
197 mFieldNameList << f.
name();
198 mFieldTypeList << fieldType;
227 if (( event->
modifiers() & ( Qt::ControlModifier ) )
228 ||
event->button() == Qt::RightButton )
240 void QgsDataDefinedButton::aboutToShowMenu()
242 mDefineMenu->
clear();
246 QString ddTitle =
tr(
"Data defined override" );
251 ddTitleAct->
setFont( titlefont );
254 bool addActiveAction =
false;
267 if ( addActiveAction )
275 if ( !mFullDescription.
isEmpty() )
277 mDefineMenu->
addAction( mActionDescription );
282 bool fieldActive =
false;
283 if ( !mDataTypesString.
isEmpty() )
286 fieldTitleAct->
setFont( titlefont );
289 mDefineMenu->
addAction( mActionDataTypes );
291 mFieldsMenu->
clear();
293 if ( !mFieldNameList.
isEmpty() )
296 for (
int j = 0; j < mFieldNameList.
count(); ++j )
298 QString fldname = mFieldNameList.
at( j );
299 QAction* act = mFieldsMenu->
addAction( fldname +
" (" + mFieldTypeList.
at( j ) +
')' );
322 exprTitleAct->
setFont( titlefont );
325 mVariablesMenu->
clear();
326 bool variableActive =
false;
327 if ( mExpressionContextCallback )
331 Q_FOREACH (
const QString& variable, variables )
345 variableActive =
true;
350 if ( mVariablesMenu->
actions().isEmpty() )
356 mDefineMenu->
addAction( mActionVariables );
363 if ( expString.
length() > 35 )
366 expString.
append(
"..." );
371 if ( !mActionExpression )
373 mActionExpression =
new QAction( expString,
this );
378 mActionExpression->
setText( expString );
380 mDefineMenu->
addAction( mActionExpression );
383 mDefineMenu->
addAction( mActionExpDialog );
384 mDefineMenu->
addAction( mActionCopyExpr );
385 mDefineMenu->
addAction( mActionPasteExpr );
386 mDefineMenu->
addAction( mActionClearExpr );
390 mDefineMenu->
addAction( mActionExpDialog );
391 mDefineMenu->
addAction( mActionPasteExpr );
394 if ( mAssistant.
data() )
397 mDefineMenu->
addAction( mActionAssistant );
401 void QgsDataDefinedButton::menuActionTriggered(
QAction* action )
403 if ( action == mActionActive )
408 else if ( action == mActionDescription )
410 showDescriptionDialog();
412 else if ( action == mActionExpDialog )
414 showExpressionDialog();
416 else if ( action == mActionExpression )
422 else if ( action == mActionCopyExpr )
426 else if ( action == mActionPasteExpr )
437 else if ( action == mActionClearExpr )
448 else if ( action == mActionAssistant )
452 else if ( mFieldsMenu->
actions().contains( action ) )
465 else if ( mVariablesMenu->
actions().contains( action ) )
477 void QgsDataDefinedButton::showDescriptionDialog()
485 void QgsDataDefinedButton::showAssistant()
487 if ( !mAssistant.
data() )
490 if ( mAssistant->exec() == QDialog::Accepted )
504 void QgsDataDefinedButton::showExpressionDialog()
509 if ( d.
exec() == QDialog::Accepted )
513 bool hasExp = !newExp.
isEmpty();
522 void QgsDataDefinedButton::updateGui()
524 QString oldDef = mCurrentDefinition;
543 icon =
isActive() ? mIconDataDefineExpressionOn : mIconDataDefineExpression;
550 icon = mIconDataDefineExpressionError;
557 icon =
isActive() ? mIconDataDefineOn : mIconDataDefine;
563 icon = mIconDataDefineError;
572 if ( newDef != oldDef )
574 mCurrentDefinition = newDef;
579 mFullDescription =
tr(
"<b><u>Data defined override</u></b><br>" );
581 mFullDescription +=
tr(
"<b>Active: </b>%1 <i>(ctrl|right-click toggles)</i><br>" ).
arg(
isActive() ?
tr(
"yes" ) :
tr(
"no" ) );
585 mFullDescription +=
tr(
"<b>Usage:</b><br>%1<br>" ).
arg( mUsageInfo );
588 if ( !mInputDescription.
isEmpty() )
590 mFullDescription +=
tr(
"<b>Expected input:</b><br>%1<br>" ).
arg( mInputDescription );
593 if ( !mDataTypesString.
isEmpty() )
595 mFullDescription +=
tr(
"<b>Valid input types:</b><br>%1<br>" ).
arg( mDataTypesString );
599 if ( deftip !=
tr(
"undefined" ) )
605 if ( deftip.
length() > 75 )
611 mFullDescription +=
tr(
"<b>Current definition %1:</b><br>%2" ).
arg( deftype, deftip );
621 mProperty.
insert(
"active", active ?
"1" :
"0" );
628 for (
int i = 0; i < wdgts.
size(); ++i )
637 if ( !mEnabledWidgets.
contains( wdgtP ) )
639 mEnabledWidgets.
append( wdgtP );
647 for (
int i = 0; i < mEnabledWidgets.
size(); ++i )
649 wdgtList << mEnabledWidgets.
at( i );
656 for (
int i = 0; i < mEnabledWidgets.
size(); ++i )
658 mEnabledWidgets.
at( i )->setDisabled( disable );
664 for (
int i = 0; i < wdgts.
size(); ++i )
673 if ( !mCheckedWidgets.
contains( wdgtP ) )
675 mCheckedWidgets.
append( wdgtP );
683 for (
int i = 0; i < mCheckedWidgets.
size(); ++i )
685 wdgtList << mCheckedWidgets.
at( i );
692 mExpressionContextCallback = fnGetExpressionContext;
693 mExpressionContextCallbackContext = context;
698 mActionAssistant->
setText( title.
isEmpty() ?
tr(
"Assistant..." ) : title );
699 mAssistant.
reset( assistant );
700 mAssistant.
data()->setParent(
this, Qt::Dialog );
705 return mAssistant.
data();
715 for (
int i = 0; i < mCheckedWidgets.
size(); ++i )
734 return tr(
"string " );
739 return tr(
"single character" );
744 return tr(
"bool [<b>1</b>=True|<b>0</b>=False]" );
749 return tr(
"string of variable length" );
754 return tr(
"int [<= 0 =>]" );
759 return tr(
"int [>= 0]" );
764 return tr(
"int [>= 1]" );
769 return tr(
"double [<= 0.0 =>]" );
774 return tr(
"double [>= 0.0]" );
779 return tr(
"double [0.0-1.0]" );
784 return tr(
"double coord [<b>X,Y</b>] as <= 0.0 =>" );
789 return tr(
"double [-180.0 - 180.0]" );
794 return tr(
"int [0-100]" );
799 return trString() +
"[<b>MM</b>|<b>MapUnit</b>]";
804 return trString() +
"[<b>MM</b>|<b>MapUnit</b>|<b>Percent</b>]";
809 return tr(
"string [<b>r,g,b</b>] as int 0-255" );
814 return tr(
"string [<b>r,g,b,a</b>] as int 0-255" );
819 return trString() +
"[<b>Left</b>|<b>Center</b>|<b>Right</b>]";
824 return trString() +
"[<b>Bottom</b>|<b>Middle</b>|<b>Top</b>]";
829 return trString() +
"[<b>bevel</b>|<b>miter</b>|<b>round</b>]";
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>]" );
842 "<b>''</b>=empty|absolute|search-paths-relative|<br>" 843 "project-relative|URL" );
848 return tr(
"string [<b>filepath</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>]" 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>]" );
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]" );
909 return trString() +
QLatin1String(
"[<b>circle</b>|<b>rectangle</b>|<b>cross</b>|<b>triangle</b>]" );
914 return tr(
"[<b><dash>;<space></b>] e.g. '8;2;1;2'" );
void setText(const QString &text)
Class for parsing and evaluation of expressions (formerly called "search strings").
void setActive(bool active)
An assistant (wizard) dialog, accessible from a QgsDataDefinedButton.
QString & append(QChar ch)
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.
QString field() const
Get the field which this QgsDataDefined represents.
QgsFields fields() const
Returns the list of fields of this layer.
QString & prepend(QChar ch)
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
const T & at(int i) const
bool contains(const QString &str, Qt::CaseSensitivity cs) const
Container of fields for a vector layer.
QString expressionString() const
Returns the expression string of this QgsDataDefined.
QString join(const QString &separator) const
QString tr(const char *sourceText, const char *disambiguation, int n)
void setBold(bool enable)
void setMessageAsHtml(const QString &msg)
void setUseExpression(bool use)
Controls if the field or the expression part is active.
QStringList variableNames() const
Returns a list of variables names set by all scopes in the context.
int count(const T &value) const
void append(const T &value)
void setChecked(bool checked)
void setField(const QString &field)
Set the field name which this QgsDataDefined represents.
QString name() const
Gets the name of the field.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
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.
int count() const
Return number of items.
Encapsulate a field in an attribute table or data source.
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
bool useExpression() const
Returns if the field or the expression part is active.
void setData(const QVariant &userData)
bool contains(const T &value) const
void setItalic(bool enable)
QString text(Mode mode) const
A generic message view for displaying QGIS messages.
iterator insert(const Key &key, const T &value)
void setText(const QString &text, Mode mode)
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 parserErrorString() const
Returns parser error.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
void setExpressionString(const QString &expr)
Sets the expression for this QgsDataDefined.
A generic dialog for building expression strings.
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.