QGIS API Documentation  3.22.4-Białowieża (ce8e65e95e)
qgsattributeactionpropertiesdialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsattributeactionpropertiesdialog.cpp - QgsAttributeActionPropertiesDialog
3 
4  ---------------------
5  begin : 18.4.2016
6  copyright : (C) 2016 by Matthias Kuhn
7  email : [email protected]
8  ***************************************************************************
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU General Public License as published by *
12  * the Free Software Foundation; either version 2 of the License, or *
13  * (at your option) any later version. *
14  * *
15  ***************************************************************************/
16 
19 #include "qgsmapcanvas.h"
20 #include "qgsproject.h"
21 #include "qgsvectorlayer.h"
22 #include "qgsapplication.h"
23 #include "qgsactionscoperegistry.h"
24 #include "qgsactionscope.h"
26 
27 #include <QComboBox>
28 #include <QLineEdit>
29 #include <QPlainTextEdit>
30 #include <QCheckBox>
31 #include <QFileDialog>
32 #include <QImageWriter>
33 
34 QgsAttributeActionPropertiesDialog::QgsAttributeActionPropertiesDialog( QgsAction::ActionType type, const QString &description, const QString &shortTitle, const QString &iconPath, const QString &actionText, bool capture, const QSet<QString> &actionScopes, const QString &notificationMessage, bool isEnabledOnlyWhenEditable, QgsVectorLayer *layer, QWidget *parent )
35  : QDialog( parent )
36  , mLayer( layer )
37 {
38  setupUi( this );
39 
40  mActionType->setCurrentIndex( type );
41  mActionName->setText( description );
42  mShortTitle->setText( shortTitle );
43  mActionIcon->setText( iconPath );
44  mIconPreview->setPixmap( QPixmap( iconPath ) );
45  mActionText->setText( actionText );
46  mCaptureOutput->setChecked( capture );
47  mNotificationMessage->setText( notificationMessage );
48  mIsEnabledOnlyWhenEditable->setChecked( isEnabledOnlyWhenEditable );
49 
50  init( actionScopes );
51 }
52 
54  : QDialog( parent )
55  , mLayer( layer )
56 {
57  setupUi( this );
58 
59  QSet<QString> defaultActionScopes;
60  defaultActionScopes << QStringLiteral( "Canvas" )
61  << QStringLiteral( "FieldSpecific" )
62  << QStringLiteral( "Feature" )
63  << QStringLiteral( "FeatureForm" );
64 
65  init( defaultActionScopes );
66 }
67 
69 {
70  return static_cast<QgsAction::ActionType>( mActionType->currentIndex() );
71 }
72 
74 {
75  return mActionName->text();
76 }
77 
79 {
80  return mShortTitle->text();
81 }
82 
84 {
85  return mActionIcon->text();
86 }
87 
89 {
90  return mActionText->text();
91 }
92 
94 {
95  QSet<QString> actionScopes;
96 
97  const auto constMActionScopeCheckBoxes = mActionScopeCheckBoxes;
98  for ( QCheckBox *cb : constMActionScopeCheckBoxes )
99  {
100  if ( cb->isChecked() )
101  actionScopes.insert( cb->property( "ActionScopeName" ).toString() );
102  }
103 
104  return actionScopes;
105 }
106 
108 {
109  return mNotificationMessage->text();
110 }
111 
113 {
114  return mIsEnabledOnlyWhenEditable->isChecked();
115 }
116 
118 {
119  return mCaptureOutput->isChecked();
120 }
121 
123 {
124  QgsExpressionContext context = mLayer->createExpressionContext();
125 
126  const auto constMActionScopeCheckBoxes = mActionScopeCheckBoxes;
127  for ( QCheckBox *cb : constMActionScopeCheckBoxes )
128  {
129  if ( cb->isChecked() )
130  {
131  const QgsActionScope actionScope = QgsApplication::actionScopeRegistry()->actionScope( cb->property( "ActionScopeName" ).toString() );
132  context.appendScope( new QgsExpressionContextScope( actionScope.expressionContextScope() ) );
133  }
134  }
135 
137 
138  return context;
139 }
140 
141 void QgsAttributeActionPropertiesDialog::browse()
142 {
143  // Popup a file browser and place the results into the action widget
144  const QString action = QFileDialog::getOpenFileName(
145  this, tr( "Select an action", "File dialog window title" ), QDir::homePath() );
146 
147  if ( !action.isNull() )
148  mActionText->insertText( action );
149 }
150 
151 void QgsAttributeActionPropertiesDialog::insertExpressionOrField()
152 {
153  QString selText = mActionText->selectedText();
154 
155  // edit the selected expression if there's one
156  if ( selText.startsWith( QLatin1String( "[%" ) ) && selText.endsWith( QLatin1String( "%]" ) ) )
157  selText = selText.mid( 2, selText.size() - 4 );
158 
159  mActionText->insertText( "[%" + mFieldExpression->currentField() + "%]" );
160 }
161 
162 void QgsAttributeActionPropertiesDialog::chooseIcon()
163 {
164  const QList<QByteArray> list = QImageWriter::supportedImageFormats();
165  QStringList formatList;
166  const auto constList = list;
167  for ( const QByteArray &format : constList )
168  formatList << QStringLiteral( "*.%1" ).arg( QString( format ) );
169 
170  const QString filter = tr( "Images( %1 ); All( *.* )" ).arg( formatList.join( QLatin1Char( ' ' ) ) );
171  const QString icon = QFileDialog::getOpenFileName( this, tr( "Choose Icon…" ), mActionIcon->text(), filter );
172 
173  if ( !icon.isNull() )
174  {
175  mActionIcon->setText( icon );
176  mIconPreview->setPixmap( QPixmap( icon ) );
177  }
178 }
179 
180 void QgsAttributeActionPropertiesDialog::updateButtons()
181 {
182  if ( mActionName->text().isEmpty() || mActionText->text().isEmpty() )
183  {
184  mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( false );
185  }
186  else
187  {
188  mButtonBox->button( QDialogButtonBox::Ok )->setEnabled( true );
189  }
190 }
191 
192 void QgsAttributeActionPropertiesDialog::init( const QSet<QString> &actionScopes )
193 {
194  const QSet<QgsActionScope> availableActionScopes = QgsApplication::actionScopeRegistry()->actionScopes();
195 
196  const auto constAvailableActionScopes = availableActionScopes;
197  for ( const QgsActionScope &scope : constAvailableActionScopes )
198  {
199  QCheckBox *actionScopeCheckBox = new QCheckBox( scope.title() );
200  if ( actionScopes.contains( scope.id() ) )
201  actionScopeCheckBox->setChecked( true );
202  const QStringList variables = scope.expressionContextScope().variableNames();
203 
204  QString tooltip = scope.description();
205  if ( !variables.empty() )
206  {
207  tooltip += QLatin1String( "<br><br>" );
208  tooltip += tr( "Additional variables" );
209  tooltip += QLatin1String( "<ul><li>" );
210  tooltip += variables.join( QLatin1String( "</li><li>" ) );
211  tooltip += QLatin1String( "</ul></li>" );
212  }
213  actionScopeCheckBox->setToolTip( tooltip );
214  actionScopeCheckBox->setProperty( "ActionScopeName", scope.id() );
215  mActionScopeCheckBoxes.append( actionScopeCheckBox );
216  mActionScopesGroupBox->layout()->addWidget( actionScopeCheckBox );
217  }
218 
219  QgsDistanceArea myDa;
220  myDa.setSourceCrs( mLayer->crs(), QgsProject::instance()->transformContext() );
221  myDa.setEllipsoid( QgsProject::instance()->ellipsoid() );
222 
223  mFieldExpression->setLayer( mLayer );
224  mFieldExpression->setGeomCalculator( myDa );
225  mFieldExpression->registerExpressionContextGenerator( this );
226 
227  connect( mBrowseButton, &QAbstractButton::clicked, this, &QgsAttributeActionPropertiesDialog::browse );
228  connect( mInsertFieldOrExpression, &QAbstractButton::clicked, this, &QgsAttributeActionPropertiesDialog::insertExpressionOrField );
229  connect( mActionName, &QLineEdit::textChanged, this, &QgsAttributeActionPropertiesDialog::updateButtons );
230  connect( mActionText, &QsciScintilla::textChanged, this, &QgsAttributeActionPropertiesDialog::updateButtons );
231  connect( mChooseIconButton, &QAbstractButton::clicked, this, &QgsAttributeActionPropertiesDialog::chooseIcon );
232 
233  connect( mButtonBox, &QDialogButtonBox::helpRequested, this, &QgsAttributeActionPropertiesDialog::showHelp );
234 
235  updateButtons();
236 }
237 
238 void QgsAttributeActionPropertiesDialog::showHelp()
239 {
240  QgsHelp::openHelp( QStringLiteral( "working_with_vector/vector_properties.html#actions-properties" ) );
241 }
QgsActionScope actionScope(const QString &id)
Gets an action scope by its id.
QSet< QgsActionScope > actionScopes
An action scope defines a "place" for an action to be shown and may add additional expression variabl...
QgsExpressionContextScope expressionContextScope() const
An expression scope may offer additional variables for an action scope.
static QgsActionScopeRegistry * actionScopeRegistry()
Returns the action scope registry.
QgsAttributeActionPropertiesDialog(QgsAction::ActionType type, const QString &description, const QString &shortTitle, const QString &iconPath, const QString &actionText, bool capture, const QSet< QString > &actionScopes, const QString &notificationMessage, bool isEnabledOnlyWhenEditable, QgsVectorLayer *layer, QWidget *parent=nullptr)
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
Single scope for storing variables and functions for use within a QgsExpressionContext.
static QgsExpressionContextScope * notificationScope(const QString &message=QString())
Creates a new scope which contains variables and functions relating to provider notifications.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:36
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:79
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:467
QgsCoordinateTransformContext transformContext
Definition: qgsproject.h:107
Represents a vector layer which manages a vector based data sets.
QgsExpressionContext createExpressionContext() const FINAL
This method needs to be reimplemented in all classes which implement this interface and return an exp...