QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
qgsactionmenu.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsactionmenu.cpp
3  --------------------------------------
4  Date : 11.8.2014
5  Copyright : (C) 2014 Matthias Kuhn
6  Email : matthias at opengis dot ch
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 "qgsactionmenu.h"
17 #include "qgsvectorlayer.h"
18 
20  : QMenu( parent )
21  , mLayer( layer )
22  , mActions( nullptr )
23  , mFeature( feature )
24  , mFeatureId( feature->id() )
25  , mOwnsFeature( false )
26 {
27  init();
28 }
29 
31  : QMenu( parent )
32  , mLayer( layer )
33  , mActions( nullptr )
34  , mFeature( nullptr )
35  , mFeatureId( fid )
36  , mOwnsFeature( false )
37 {
38  init();
39 }
40 
41 void QgsActionMenu::init()
42 {
43  setTitle( tr( "&Actions" ) );
44 
45  connect( QgsMapLayerActionRegistry::instance(), SIGNAL( changed() ), this, SLOT( reloadActions() ) );
46 
47  reloadActions();
48 }
49 
50 const QgsFeature* QgsActionMenu::feature()
51 {
52  if ( !mFeature || !mFeature->isValid() )
53  {
54  QgsFeature* feat = new QgsFeature();
55  if ( mActions->layer()->getFeatures( QgsFeatureRequest( mFeatureId ) ).nextFeature( *feat ) )
56  {
57  mFeature = feat;
58  mOwnsFeature = true;
59  }
60  else
61  {
62  delete feat;
63  }
64  }
65 
66  return mFeature;
67 }
68 
70 {
71  delete mActions;
72 
73  if ( mOwnsFeature )
74  delete mFeature;
75 }
76 
78 {
79  if ( mOwnsFeature )
80  delete mFeature;
81  mOwnsFeature = false;
82  mFeature = feature;
83 }
84 
85 void QgsActionMenu::triggerAction()
86 {
87  if ( !feature() )
88  return;
89 
90  QAction* action = qobject_cast<QAction*>( sender() );
91  if ( !action )
92  return;
93 
94  if ( !action->data().isValid() || !action->data().canConvert<ActionData>() )
95  return;
96 
97  ActionData data = action->data().value<ActionData>();
98 
99  if ( data.actionType == Invalid )
100  return;
101 
102  if ( data.actionType == MapLayerAction )
103  {
104  QgsMapLayerAction* mapLayerAction = data.actionId.action;
105  mapLayerAction->triggerForFeature( data.mapLayer, feature() );
106  }
107  else if ( data.actionType == AttributeAction )
108  {
109  mActions->doAction( data.actionId.id, *feature(), 0, mExpressionContextScope );
110  }
111 }
112 
113 void QgsActionMenu::reloadActions()
114 {
115  clear();
116 
117  delete mActions;
118  mActions = new QgsActionManager( *mLayer->actions() );
119 
120  for ( int idx = 0; idx < mActions->size(); ++idx )
121  {
122  const QgsAction& qaction( mActions->at( idx ) );
123 
124  QAction* action = new QAction( qaction.icon(), qaction.name(), this );
125  action->setData( QVariant::fromValue<ActionData>( ActionData( idx, mFeatureId, mLayer ) ) );
126  action->setIcon( qaction.icon() );
127 
128  // Only enable items on supported platforms
129  if ( !qaction.runable() )
130  {
131  action->setEnabled( false );
132  action->setToolTip( tr( "Not supported on your platform" ) );
133  }
134  else
135  {
136  action->setToolTip( qaction.action() );
137  }
138  connect( action, SIGNAL( triggered() ), this, SLOT( triggerAction() ) );
139  addAction( action );
140  }
141 
143 
144  if ( !mapLayerActions.isEmpty() )
145  {
146  //add a separator between user defined and standard actions
147  addSeparator();
148 
149  for ( int i = 0; i < mapLayerActions.size(); ++i )
150  {
151  QgsMapLayerAction* qaction = mapLayerActions.at( i );
152  QAction* action = new QAction( qaction->icon(), qaction->text(), this );
153  action->setData( QVariant::fromValue<ActionData>( ActionData( qaction, mFeatureId, mLayer ) ) );
154  addAction( action );
155  connect( action, SIGNAL( triggered() ), this, SLOT( triggerAction() ) );
156  }
157  }
158 
159  emit reinit();
160 }
161 
163 {
164  mExpressionContextScope = scope;
165 }
166 
168 {
169  return mExpressionContextScope;
170 }
bool isValid() const
Returns the validity of this feature.
Definition: qgsfeature.cpp:199
bool canConvert(Type t) const
QgsActionManager * actions()
Get all layer actions defined on this layer.
QgsVectorLayer * layer() const
Return the layer.
QgsActionMenu(QgsVectorLayer *layer, const QgsFeature *feature, QWidget *parent=nullptr)
Constructs a new QgsActionMenu.
QObject * sender() const
QgsExpressionContextScope expressionContextScope() const
Returns an expression context scope used to resolve underlying actions.
QVariant data() const
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
const T & at(int i) const
void addAction(QAction *action)
~QgsActionMenu()
Destructor.
void triggered(QAction *action)
T value() const
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:187
QString tr(const char *sourceText, const char *disambiguation, int n)
Standard actions (defined by core or plugins)
Definition: qgsactionmenu.h:38
const QgsAction & at(int idx) const
Get the action at the specified index.
union QgsActionMenu::ActionData::aid actionId
int size() const
void clear()
Utility class that encapsulates an action based on vector attributes.
Definition: qgsaction.h:25
bool isEmpty() const
This class wraps a request for features to a vector layer (or directly its vector data provider)...
Storage and management of actions associated with a layer.
void setTitle(const QString &title)
QAction * addSeparator()
Single scope for storing variables and functions for use within a QgsExpressionContext.
QgsMapLayerAction * action
Definition: qgsactionmenu.h:72
void setData(const QVariant &userData)
void setFeature(QgsFeature *feature)
Change the feature on which actions are performed.
static QgsMapLayerActionRegistry * instance()
Returns the instance pointer, creating the object on the first call.
Custom actions (manually defined in layer properties)
Definition: qgsactionmenu.h:39
QList< QgsMapLayerAction * > mapLayerActions(QgsMapLayer *layer, const QgsMapLayerAction::Targets &targets=QgsMapLayerAction::AllActions)
Returns the map layer actions which can run on the specified layer.
qint64 QgsFeatureId
Definition: qgsfeature.h:31
bool isValid() const
bool nextFeature(QgsFeature &f)
void setExpressionContextScope(const QgsExpressionContextScope &scope)
Sets an expression context scope used to resolve underlying actions.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const
Represents a vector layer which manages a vector based data sets.
int size() const
Get the number of actions managed by this.
void doAction(int index, const QgsFeature &feat, int defaultValueIndex=0, const QgsExpressionContextScope &scope=QgsExpressionContextScope())
Does the given action.
void triggerForFeature(QgsMapLayer *layer, const QgsFeature *feature)
Triggers the action with the specified layer and feature.
An action which can run on map layers.