1 /***************************************************************************
2   qgsaction.h - QgsAction
3 
4  ---------------------
5  begin                : 18.4.2016
6  copyright            : (C) 2016 by Matthias Kuhn
7  email                : matthias@opengis.ch
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 #ifndef QGSACTION_H
17 #define QGSACTION_H
18 
19 #include "qgis_core.h"
20 #include <QSet>
21 #include <QString>
22 #include <QIcon>
23 #include <QUuid>
24 
25 #include "qgsexpressioncontext.h"
26 #include <memory>
27 
28 class QgsExpressionContextScope;
29 
30 /**
31  * \ingroup core
32  * \brief Utility class that encapsulates an action based on vector attributes.
33  */
34 class CORE_EXPORT QgsAction
35 {
36   public:
37     enum ActionType
38     {
39       Generic,
40       GenericPython,
41       Mac,
42       Windows,
43       Unix,
44       OpenUrl,
45     };
46 
47     /**
48      * Default constructor
49      */
50     QgsAction() = default;
51 
52     /**
53      * Create a new QgsAction
54      *
55      * \param type          The type of this action
56      * \param description   A human readable description string
57      * \param command       The action text. Its interpretation depends on the type
58      * \param capture       If this is set to TRUE, the output will be captured when an action is run
59      * \param enabledOnlyWhenEditable if TRUE then action is only enable in editmode. Not available in Python bindings.
60      */
61     QgsAction( ActionType type, const QString &description, const QString &command, bool capture = false, bool enabledOnlyWhenEditable SIP_PYARGREMOVE = false )
mType(type)62       : mType( type )
63       , mDescription( description )
64       , mCommand( command )
65       , mCaptureOutput( capture )
66       , mId( QUuid::createUuid() )
67       , mIsEnabledOnlyWhenEditable( enabledOnlyWhenEditable )
68     {}
69 
70     /**
71      * Create a new QgsAction
72      *
73      * \param type                 The type of this action
74      * \param description          A human readable description string
75      * \param action               The action text. Its interpretation depends on the type
76      * \param icon                 Path to an icon for this action
77      * \param capture              If this is set to TRUE, the output will be captured when an action is run
78      * \param shortTitle           A short string used to label user interface elements like buttons
79      * \param actionScopes         A set of scopes in which this action will be available
80      * \param notificationMessage  A particular message which reception will trigger the action
81      * \param enabledOnlyWhenEditable if TRUE then action is only enable in editmode. Not available in Python bindings.
82      */
83     QgsAction( ActionType type, const QString &description, const QString &action, const QString &icon, bool capture, const QString &shortTitle = QString(), const QSet<QString> &actionScopes = QSet<QString>(), const QString &notificationMessage = QString(), bool enabledOnlyWhenEditable SIP_PYARGREMOVE = false )
mType(type)84       : mType( type )
85       , mDescription( description )
86       , mShortTitle( shortTitle )
87       , mIcon( icon )
88       , mCommand( action )
89       , mCaptureOutput( capture )
90       , mActionScopes( actionScopes )
91       , mNotificationMessage( notificationMessage )
92       , mId( QUuid::createUuid() )
93       , mIsEnabledOnlyWhenEditable( enabledOnlyWhenEditable )
94     {}
95 
96     /**
97      * Create a new QgsAction
98      *
99      * \param id                   The unique identifier of this action
100      * \param type                 The type of this action
101      * \param description          A human readable description string
102      * \param action               The action text. Its interpretation depends on the type
103      * \param icon                 Path to an icon for this action
104      * \param capture              If this is set to TRUE, the output will be captured when an action is run
105      * \param shortTitle           A short string used to label user interface elements like buttons
106      * \param actionScopes         A set of scopes in which this action will be available
107      * \param notificationMessage  A particular message which reception will trigger the action
108      * \param enabledOnlyWhenEditable if TRUE then action is only enable in editmode. Not available in Python bindings.
109      */
110     QgsAction( const QUuid &id, ActionType type, const QString &description, const QString &action, const QString &icon, bool capture, const QString &shortTitle = QString(), const QSet<QString> &actionScopes = QSet<QString>(), const QString &notificationMessage = QString(), bool enabledOnlyWhenEditable SIP_PYARGREMOVE = false )
mType(type)111       : mType( type )
112       , mDescription( description )
113       , mShortTitle( shortTitle )
114       , mIcon( icon )
115       , mCommand( action )
116       , mCaptureOutput( capture )
117       , mActionScopes( actionScopes )
118       , mNotificationMessage( notificationMessage )
119       , mId( id )
120       , mIsEnabledOnlyWhenEditable( enabledOnlyWhenEditable )
121     {}
122 
123 
124     //! The name of the action. This may be a longer description.
name()125     QString name() const { return mDescription; }
126 
127     //! The short title is used to label user interface elements like buttons
shortTitle()128     QString shortTitle() const { return mShortTitle; }
129 
130     /**
131      * Returns a unique id for this action.
132      *
133      * \since QGIS 3.0
134      */
id()135     QUuid id() const { return mId; }
136 
137     /**
138      * Returns TRUE if this action was a default constructed one.
139      *
140      * \since QGIS 3.0
141      */
isValid()142     bool isValid() const { return !mId.isNull(); }
143 
144     //! The path to the icon
iconPath()145     QString iconPath() const { return mIcon; }
146 
147     //! The icon
icon()148     QIcon icon() const { return QIcon( mIcon ); }
149 
150     /**
151      * Returns the command that is executed by this action.
152      * How the content is interpreted depends on the type() and
153      * the actionScope().
154      *
155      * \since QGIS 3.0
156      */
command()157     QString command() const { return mCommand; }
158 
159     /**
160      * Returns the notification message that triggers the action
161      *
162      * \since QGIS 3.0
163      */
notificationMessage()164     QString notificationMessage() const { return mNotificationMessage; }
165 
166     //! The action type
type()167     ActionType type() const { return mType; }
168 
169     //! Whether to capture output for display when this action is run
capture()170     bool capture() const { return mCaptureOutput; }
171 
172 
173     //! Returns whether only enabled in editable mode
isEnabledOnlyWhenEditable()174     bool isEnabledOnlyWhenEditable() const { return mIsEnabledOnlyWhenEditable; }
175 
176     /**
177      * Set whether the action is only enabled in editable mode
178      *
179      * \since QGIS 3.16
180      */
setEnabledOnlyWhenEditable(bool enable)181     void setEnabledOnlyWhenEditable( bool enable ) { mIsEnabledOnlyWhenEditable = enable; };
182 
183 
184     //! Checks if the action is runable on the current platform
185     bool runable() const;
186 
187     /**
188      * Run this action.
189      *
190      * \since QGIS 3.0
191      */
192     void run( QgsVectorLayer *layer, const QgsFeature &feature, const QgsExpressionContext &expressionContext ) const;
193 
194     /**
195      * Run this action.
196      *
197      * \since QGIS 3.0
198      */
199     void run( const QgsExpressionContext &expressionContext ) const;
200 
201     /**
202      * The action scopes define where an action will be available.
203      * Action scopes may offer additional variables like the clicked
204      * coordinate.
205      *
206      * \see QgsActionScope
207      * \since QGIS 3.0
208      */
209     QSet<QString> actionScopes() const;
210 
211     /**
212      * The action scopes define where an action will be available.
213      * Action scopes may offer additional variables like the clicked
214      * coordinate.
215      *
216      * \since QGIS 3.0
217      */
218     void setActionScopes( const QSet<QString> &actionScopes );
219 
220     /**
221      * Reads an XML definition from actionNode
222      * into this object.
223      *
224      * \since QGIS 3.0
225      */
226     void readXml( const QDomNode &actionNode );
227 
228     /**
229      * Appends an XML definition for this action as a new
230      * child node to actionsNode.
231      *
232      * \since QGIS 3.0
233      */
234     void writeXml( QDomNode &actionsNode ) const;
235 
236     /**
237      * Sets an expression context scope to use for running the action.
238      *
239      * \since QGIS 3.0
240      */
241     void setExpressionContextScope( const QgsExpressionContextScope &scope );
242 
243     /**
244      * Returns an expression context scope used for running the action.
245      *
246      * \since QGIS 3.0
247      */
248     QgsExpressionContextScope expressionContextScope() const;
249 
250     /**
251      * Returns an HTML table with the basic information about this action.
252      *
253      * \since QGIS 3.24
254      */
255     QString html( ) const;
256 
257   private:
258     ActionType mType = Generic;
259     QString mDescription;
260     QString mShortTitle;
261     QString mIcon;
262     QString mCommand;
263     bool mCaptureOutput = false;
264     QSet<QString> mActionScopes;
265     QString mNotificationMessage;
266     QUuid mId;
267     QgsExpressionContextScope mExpressionContextScope;
268     bool mIsEnabledOnlyWhenEditable = false;
269 };
270 
271 Q_DECLARE_METATYPE( QgsAction )
272 
273 #endif // QGSACTION_H
274