QGIS API Documentation  2.18.21-Las Palmas (9fba24a)
qgsidentifymenu.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsidentifymenu.cpp - menu to be used in identify map tool
3  ---------------------
4  begin : August 2014
5  copyright : (C) 2014 by Denis Rouzaud
6  email : [email protected]
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 <QMouseEvent>
17 
18 #include "qgsidentifymenu.h"
19 
20 #include "qgsapplication.h"
21 #include "qgsactionmanager.h"
22 #include "qgshighlight.h"
23 
24 
26 CustomActionRegistry::CustomActionRegistry( QObject* parent )
27  : QgsMapLayerActionRegistry( parent )
28 {
29 }
31 
33  : QMenu( canvas )
34  , mCanvas( canvas )
35  , mAllowMultipleReturn( true )
36  , mExecWithSingleResult( false )
37  , mShowFeatureActions( false )
38  , mResultsIfExternalAction( false )
39  , mMaxLayerDisplay( 10 )
40  , mMaxFeatureDisplay( 10 )
41  , mDefaultActionName( tr( "Identify" ) )
42  , mCustomActionRegistry( CustomActionRegistry::instance() )
43 {
44 }
45 
47 {
48  deleteRubberBands();
49 }
50 
51 
53 {
54  if ( maxLayerDisplay < 0 )
55  {
56  QgsDebugMsg( "invalid value for number of layers displayed." );
57  }
58  mMaxLayerDisplay = maxLayerDisplay;
59 }
60 
61 
63 {
64  if ( maxFeatureDisplay < 0 )
65  {
66  QgsDebugMsg( "invalid value for number of layers displayed." );
67  }
68  mMaxFeatureDisplay = maxFeatureDisplay;
69 }
70 
71 
73 {
74  clear();
75  mLayerIdResults.clear();
76 
78 
79  if ( idResults.isEmpty() )
80  {
81  return returnResults;
82  }
83  if ( idResults.count() == 1 && !mExecWithSingleResult )
84  {
85  returnResults << idResults[0];
86  return returnResults;
87  }
88 
89  // sort results by layer
90  Q_FOREACH ( const QgsMapToolIdentify::IdentifyResult& result, idResults )
91  {
92  QgsMapLayer *layer = result.mLayer;
93  if ( mLayerIdResults.contains( layer ) )
94  {
95  mLayerIdResults[layer].append( result );
96  }
97  else
98  {
99  mLayerIdResults.insert( layer, QList<QgsMapToolIdentify::IdentifyResult>() << result );
100  }
101  }
102 
103  // add results to the menu
104  bool singleLayer = mLayerIdResults.count() == 1;
105  int count = 0;
107  while ( it.hasNext() )
108  {
109  if ( mMaxLayerDisplay != 0 && count > mMaxLayerDisplay )
110  break;
111  ++count;
112  it.next();
113  QgsMapLayer* layer = it.key();
114  if ( layer->type() == QgsMapLayer::RasterLayer )
115  {
116  addRasterLayer( layer );
117  }
118  else if ( layer->type() == QgsMapLayer::VectorLayer )
119  {
120  QgsVectorLayer* vl = qobject_cast<QgsVectorLayer*>( layer );
121  if ( !vl )
122  continue;
123  addVectorLayer( vl, it.value(), singleLayer );
124  }
125  }
126 
127  // add an "identify all" action on the top level
128  if ( !singleLayer && mAllowMultipleReturn && idResults.count() > 1 )
129  {
130  addSeparator();
131  QAction* allAction = new QAction( QgsApplication::getThemeIcon( "/mActionIdentify.svg" ), tr( "%1 all (%2)" ).arg( mDefaultActionName ).arg( idResults.count() ), this );
132  allAction->setData( QVariant::fromValue<ActionData>( ActionData( nullptr ) ) );
133  connect( allAction, SIGNAL( hovered() ), this, SLOT( handleMenuHover() ) );
134  addAction( allAction );
135  }
136 
137  // exec
138  QAction* selectedAction = QMenu::exec( pos );
139  bool externalAction;
140  returnResults = results( selectedAction, externalAction );
141 
142  // delete actions
143  clear();
144  // also remove the QgsActionMenu
145  qDeleteAll( findChildren<QgsActionMenu*>() );
146 
147  if ( externalAction && !mResultsIfExternalAction )
148  {
150  }
151  else
152  {
153  return returnResults;
154  }
155 }
156 
158 {
159  deleteRubberBands();
160  QMenu::closeEvent( e );
161 }
162 
163 void QgsIdentifyMenu::addRasterLayer( QgsMapLayer* layer )
164 {
165  QAction* layerAction;
166  QMenu* layerMenu = nullptr;
167 
169  QList<QgsMapLayerAction*> layerActions = mCustomActionRegistry.mapLayerActions( layer, QgsMapLayerAction::Layer );
170  int nCustomActions = layerActions.count();
171  if ( nCustomActions )
172  {
173  separators.append( layerActions[0] );
174  }
175  if ( mShowFeatureActions )
176  {
177  layerActions.append( QgsMapLayerActionRegistry::instance()->mapLayerActions( layer, QgsMapLayerAction::Layer ) );
178  if ( layerActions.count() > nCustomActions )
179  {
180  separators.append( layerActions[nCustomActions] );
181  }
182  }
183 
184  // use a menu only if actions will be listed
185  if ( layerActions.isEmpty() )
186  {
187  layerAction = new QAction( layer->name(), this );
188  }
189  else
190  {
191  layerMenu = new QMenu( layer->name(), this );
192  layerAction = layerMenu->menuAction();
193  }
194 
195  // add layer action to the top menu
196  layerAction->setIcon( QgsApplication::getThemeIcon( "/mIconRasterLayer.svg" ) );
197  layerAction->setData( QVariant::fromValue<ActionData>( ActionData( layer ) ) );
198  connect( layerAction, SIGNAL( hovered() ), this, SLOT( handleMenuHover() ) );
199  addAction( layerAction );
200 
201  // no need to go further if there is no menu
202  if ( !layerMenu )
203  return;
204 
205  // add default identify action
206  QAction* identifyFeatureAction = new QAction( mDefaultActionName, layerMenu );
207  connect( identifyFeatureAction, SIGNAL( hovered() ), this, SLOT( handleMenuHover() ) );
208  identifyFeatureAction->setData( QVariant::fromValue<ActionData>( ActionData( layer ) ) );
209  layerMenu->addAction( identifyFeatureAction );
210 
211  // add custom/layer actions
212  Q_FOREACH ( QgsMapLayerAction* mapLayerAction, layerActions )
213  {
214  QAction* action = new QAction( mapLayerAction->icon(), mapLayerAction->text(), layerMenu );
215  action->setData( QVariant::fromValue<ActionData>( ActionData( layer, true ) ) );
216  connect( action, SIGNAL( hovered() ), this, SLOT( handleMenuHover() ) );
217  connect( action, SIGNAL( triggered() ), this, SLOT( triggerMapLayerAction() ) );
218  layerMenu->addAction( action );
219  if ( separators.contains( mapLayerAction ) )
220  {
221  layerMenu->insertSeparator( action );
222  }
223  }
224 }
225 
226 void QgsIdentifyMenu::addVectorLayer( QgsVectorLayer* layer, const QList<QgsMapToolIdentify::IdentifyResult>& results, bool singleLayer )
227 {
228  QAction* layerAction = nullptr;
229  QMenu* layerMenu = nullptr;
230 
231  // do not add actions with MultipleFeatures as target if only 1 feature is found for this layer
232  // targets defines which actions will be shown
233  QgsMapLayerAction::Targets targets = results.count() > 1 ? QgsMapLayerAction::Layer | QgsMapLayerAction::MultipleFeatures : QgsMapLayerAction::Layer;
234 
236  QList<QgsMapLayerAction*> layerActions = mCustomActionRegistry.mapLayerActions( layer, targets );
237  int nCustomActions = layerActions.count();
238  if ( nCustomActions )
239  {
240  separators << layerActions[0];
241  }
242  if ( mShowFeatureActions )
243  {
244  layerActions << QgsMapLayerActionRegistry::instance()->mapLayerActions( layer, targets );
245 
246  if ( layerActions.count() > nCustomActions )
247  {
248  separators << layerActions[nCustomActions];
249  }
250  }
251 
252  // determines if a menu should be created or not. Following cases:
253  // 1. only one result and no feature action to be shown => just create an action
254  // 2. several features (2a) or display feature actions (2b) => create a menu
255  // 3. case 2 but only one layer (singeLayer) => do not create a menu, but give the top menu instead
256 
257  bool createMenu = results.count() > 1 || !layerActions.isEmpty();
258 
259  // case 2b: still create a menu for layer, if there is a sub-level for features
260  // i.e custom actions or map layer actions at feature level
261  if ( !createMenu )
262  {
263  createMenu = !mCustomActionRegistry.mapLayerActions( layer, QgsMapLayerAction::SingleFeature ).isEmpty();
264  if ( !createMenu && mShowFeatureActions )
265  {
266  QgsActionMenu* featureActionMenu = new QgsActionMenu( layer, &( results[0].mFeature ), this );
267  createMenu = !featureActionMenu->actions().isEmpty();
268  delete featureActionMenu;
269  }
270  }
271 
272  // use a menu only if actions will be listed
273  if ( !createMenu )
274  {
275  // case 1
276  QString featureTitle = results[0].mFeature.attribute( layer->displayField() ).toString();
277  if ( featureTitle.isEmpty() )
278  featureTitle = QString( "%1" ).arg( results[0].mFeature.id() );
279  layerAction = new QAction( QString( "%1 (%2)" ).arg( layer->name(), featureTitle ), this );
280  }
281  else
282  {
283  if ( singleLayer )
284  {
285  // case 3
286  layerMenu = this;
287  }
288  else
289  {
290  // case 2a
291  if ( results.count() > 1 )
292  {
293  layerMenu = new QMenu( layer->name(), this );
294  }
295  // case 2b
296  else
297  {
298  QString featureTitle = results[0].mFeature.attribute( layer->displayField() ).toString();
299  if ( featureTitle.isEmpty() )
300  featureTitle = QString( "%1" ).arg( results[0].mFeature.id() );
301  layerMenu = new QMenu( QString( "%1 (%2)" ).arg( layer->name(), featureTitle ), this );
302  }
303  layerAction = layerMenu->menuAction();
304  }
305  }
306 
307  // case 1 or 2
308  if ( layerAction )
309  {
310  // icons
311  switch ( layer->geometryType() )
312  {
313  case QGis::Point:
314  layerAction->setIcon( QgsApplication::getThemeIcon( "/mIconPointLayer.svg" ) );
315  break;
316  case QGis::Line:
317  layerAction->setIcon( QgsApplication::getThemeIcon( "/mIconLineLayer.svg" ) );
318  break;
319  case QGis::Polygon:
320  layerAction->setIcon( QgsApplication::getThemeIcon( "/mIconPolygonLayer.svg" ) );
321  break;
322  default:
323  break;
324  }
325 
326  // add layer action to the top menu
327  layerAction->setData( QVariant::fromValue<ActionData>( ActionData( layer ) ) );
328  connect( layerAction, SIGNAL( hovered() ), this, SLOT( handleMenuHover() ) );
329  addAction( layerAction );
330  }
331 
332  // case 1. no need to go further
333  if ( !layerMenu )
334  return;
335 
336  // add results to the menu
337  int count = 0;
338  Q_FOREACH ( const QgsMapToolIdentify::IdentifyResult& result, results )
339  {
340  if ( mMaxFeatureDisplay != 0 && count > mMaxFeatureDisplay )
341  break;
342  ++count;
343 
344  QAction* featureAction = nullptr;
345  QMenu* featureMenu = nullptr;
346  QgsActionMenu* featureActionMenu = nullptr;
347 
348  QList<QgsMapLayerAction*> customFeatureActions = mCustomActionRegistry.mapLayerActions( layer, QgsMapLayerAction::SingleFeature );
349  if ( mShowFeatureActions )
350  {
351  featureActionMenu = new QgsActionMenu( layer, result.mFeature.id(), layerMenu );
352  featureActionMenu->setExpressionContextScope( mExpressionContextScope );
353  }
354 
355  // feature title
356  QString featureTitle = result.mFeature.attribute( layer->displayField() ).toString();
357  if ( featureTitle.isEmpty() )
358  featureTitle = QString( "%1" ).arg( result.mFeature.id() );
359 
360  if ( customFeatureActions.isEmpty() && ( !featureActionMenu || featureActionMenu->actions().isEmpty() ) )
361  {
362  featureAction = new QAction( featureTitle, layerMenu );
363  // add the feature action (or menu) to the layer menu
364  featureAction->setData( QVariant::fromValue<ActionData>( ActionData( layer, result.mFeature.id() ) ) );
365  connect( featureAction, SIGNAL( hovered() ), this, SLOT( handleMenuHover() ) );
366  layerMenu->addAction( featureAction );
367  }
368  else if ( results.count() == 1 )
369  {
370  // if we are here with only one results, this means there is a sub-feature level (for actions)
371  // => skip the feature level since there would be only a single entry
372  // => give the layer menu as pointer instead of a new feature menu
373  featureMenu = layerMenu;
374  }
375  else
376  {
377  featureMenu = new QMenu( featureTitle, layerMenu );
378 
379  // get the action from the menu
380  featureAction = featureMenu->menuAction();
381  // add the feature action (or menu) to the layer menu
382  featureAction->setData( QVariant::fromValue<ActionData>( ActionData( layer, result.mFeature.id() ) ) );
383  connect( featureAction, SIGNAL( hovered() ), this, SLOT( handleMenuHover() ) );
384  layerMenu->addAction( featureAction );
385  }
386 
387  // if no feature menu, no need to go further
388  if ( !featureMenu )
389  continue;
390 
391  // add default identify action
392  QAction* identifyFeatureAction = new QAction( QgsApplication::getThemeIcon( "/mActionIdentify.svg" ), mDefaultActionName, featureMenu );
393  connect( identifyFeatureAction, SIGNAL( hovered() ), this, SLOT( handleMenuHover() ) );
394  identifyFeatureAction->setData( QVariant::fromValue<ActionData>( ActionData( layer, result.mFeature.id() ) ) );
395  featureMenu->addAction( identifyFeatureAction );
396  featureMenu->addSeparator();
397 
398  // custom action at feature level
399  Q_FOREACH ( QgsMapLayerAction* mapLayerAction, customFeatureActions )
400  {
401  QAction* action = new QAction( mapLayerAction->icon(), mapLayerAction->text(), featureMenu );
402  action->setData( QVariant::fromValue<ActionData>( ActionData( layer, result.mFeature.id(), mapLayerAction ) ) );
403  connect( action, SIGNAL( hovered() ), this, SLOT( handleMenuHover() ) );
404  connect( action, SIGNAL( triggered() ), this, SLOT( triggerMapLayerAction() ) );
405  featureMenu->addAction( action );
406  }
407  // use QgsActionMenu for feature actions
408  if ( featureActionMenu )
409  {
410  Q_FOREACH ( QAction* action, featureActionMenu->actions() )
411  {
412  connect( action, SIGNAL( hovered() ), this, SLOT( handleMenuHover() ) );
413  featureMenu->addAction( action );
414  }
415  }
416  }
417 
418  // back to layer level
419 
420  // identify all action
421  if ( mAllowMultipleReturn && results.count() > 1 )
422  {
423  layerMenu->addSeparator();
424  QAction* allAction = new QAction( QgsApplication::getThemeIcon( "/mActionIdentify.svg" ), tr( "%1 all (%2)" ).arg( mDefaultActionName ).arg( results.count() ), layerMenu );
425  allAction->setData( QVariant::fromValue<ActionData>( ActionData( layer ) ) );
426  connect( allAction, SIGNAL( hovered() ), this, SLOT( handleMenuHover() ) );
427  layerMenu->addAction( allAction );
428  }
429 
430  // add custom/layer actions
431  Q_FOREACH ( QgsMapLayerAction* mapLayerAction, layerActions )
432  {
433  QString title = mapLayerAction->text();
434  if ( mapLayerAction->targets().testFlag( QgsMapLayerAction::MultipleFeatures ) )
435  title.append( QString( " (%1)" ).arg( results.count() ) );
436  QAction* action = new QAction( mapLayerAction->icon(), title, layerMenu );
437  action->setData( QVariant::fromValue<ActionData>( ActionData( layer, mapLayerAction ) ) );
438  connect( action, SIGNAL( hovered() ), this, SLOT( handleMenuHover() ) );
439  connect( action, SIGNAL( triggered() ), this, SLOT( triggerMapLayerAction() ) );
440  layerMenu->addAction( action );
441  if ( separators.contains( mapLayerAction ) )
442  {
443  layerMenu->insertSeparator( action );
444  }
445  }
446 }
447 
448 void QgsIdentifyMenu::triggerMapLayerAction()
449 {
450  QAction* action = qobject_cast<QAction*>( sender() );
451  if ( !action )
452  return;
453  QVariant varData = action->data();
454  if ( !varData.isValid() || !varData.canConvert<ActionData>() )
455  return;
456 
457  ActionData actData = action->data().value<ActionData>();
458 
459  if ( actData.mIsValid && actData.mMapLayerAction )
460  {
461  // layer
462  if ( actData.mMapLayerAction->targets().testFlag( QgsMapLayerAction::Layer ) )
463  {
464  actData.mMapLayerAction->triggerForLayer( actData.mLayer );
465  }
466 
467  // multiples features
468  if ( actData.mMapLayerAction->targets().testFlag( QgsMapLayerAction::MultipleFeatures ) )
469  {
470  QList<QgsFeature> featureList;
471  Q_FOREACH ( const QgsMapToolIdentify::IdentifyResult& result, mLayerIdResults[actData.mLayer] )
472  {
473  featureList << result.mFeature;
474  }
475  actData.mMapLayerAction->triggerForFeatures( actData.mLayer, featureList );
476  }
477 
478  // single feature
479  if ( actData.mMapLayerAction->targets().testFlag( QgsMapLayerAction::SingleFeature ) )
480  {
481  Q_FOREACH ( const QgsMapToolIdentify::IdentifyResult& result, mLayerIdResults[actData.mLayer] )
482  {
483  if ( result.mFeature.id() == actData.mFeatureId )
484  {
485  actData.mMapLayerAction->triggerForFeature( actData.mLayer, new QgsFeature( result.mFeature ) );
486  return;
487  }
488  }
489  QgsDebugMsg( QString( "Identify menu: could not retrieve feature for action %1" ).arg( action->text() ) );
490  }
491  }
492 }
493 
494 
495 QList<QgsMapToolIdentify::IdentifyResult> QgsIdentifyMenu::results( QAction* action, bool &externalAction )
496 {
498 
499  externalAction = false;
500 
501  ActionData actData;
502  bool hasData = false;
503 
504  if ( !action )
505  return idResults;
506 
507  QVariant varData = action->data();
508  if ( !varData.isValid() )
509  {
510  QgsDebugMsg( "Identify menu: could not retrieve results from menu entry (invalid data)" );
511  return idResults;
512  }
513 
514  if ( varData.canConvert<ActionData>() )
515  {
516  actData = action->data().value<ActionData>();
517  if ( actData.mIsValid )
518  {
519  externalAction = actData.mIsExternalAction;
520  hasData = true;
521  }
522  }
523 
524  if ( !hasData && varData.canConvert<QgsActionMenu::ActionData>() )
525  {
527  if ( dataSrc.actionType != QgsActionMenu::Invalid )
528  {
529  externalAction = true;
530  actData = ActionData( dataSrc.mapLayer, dataSrc.featureId );
531  hasData = true;
532  }
533  }
534 
535  if ( !hasData )
536  {
537  QgsDebugMsg( "Identify menu: could not retrieve results from menu entry (no data found)" );
538  return idResults;
539  }
540 
541  // return all results
542  if ( actData.mAllResults )
543  {
544  // this means "All" action was triggered
546  while ( it.hasNext() )
547  {
548  it.next();
549  idResults << it.value();
550  }
551  return idResults;
552  }
553 
554  if ( !mLayerIdResults.contains( actData.mLayer ) )
555  {
556  QgsDebugMsg( "Identify menu: could not retrieve results from menu entry (layer not found)" );
557  return idResults;
558  }
559 
560  if ( actData.mLevel == LayerLevel )
561  {
562  return mLayerIdResults[actData.mLayer];
563  }
564 
565  if ( actData.mLevel == FeatureLevel )
566  {
567  Q_FOREACH ( const QgsMapToolIdentify::IdentifyResult& res, mLayerIdResults[actData.mLayer] )
568  {
569  if ( res.mFeature.id() == actData.mFeatureId )
570  {
571  idResults << res;
572  return idResults;
573  }
574  }
575  }
576 
577  QgsDebugMsg( "Identify menu: could not retrieve results from menu entry (don't know what happened')" );
578  return idResults;
579 }
580 
581 void QgsIdentifyMenu::handleMenuHover()
582 {
583  if ( !mCanvas )
584  return;
585 
586  deleteRubberBands();
587 
588  QAction* senderAction = qobject_cast<QAction*>( sender() );
589  if ( !senderAction )
590  return;
591 
592  bool externalAction;
593  QList<QgsMapToolIdentify::IdentifyResult> idResults = results( senderAction, externalAction );
594 
595  Q_FOREACH ( const QgsMapToolIdentify::IdentifyResult& result, idResults )
596  {
597  QgsVectorLayer* vl = qobject_cast<QgsVectorLayer*>( result.mLayer );
598  if ( !vl )
599  continue;
600 
601  QgsHighlight *hl = new QgsHighlight( mCanvas, result.mFeature.constGeometry(), vl );
602  QSettings settings;
603  QColor color = QColor( settings.value( "/Map/highlight/color", QGis::DEFAULT_HIGHLIGHT_COLOR.name() ).toString() );
604  int alpha = settings.value( "/Map/highlight/colorAlpha", QGis::DEFAULT_HIGHLIGHT_COLOR.alpha() ).toInt();
605  double buffer = settings.value( "/Map/highlight/buffer", QGis::DEFAULT_HIGHLIGHT_BUFFER_MM ).toDouble();
606  double minWidth = settings.value( "/Map/highlight/minWidth", QGis::DEFAULT_HIGHLIGHT_MIN_WIDTH_MM ).toDouble();
607  hl->setColor( color ); // sets also fill with default alpha
608  color.setAlpha( alpha );
609  hl->setFillColor( color ); // sets fill with alpha
610  hl->setBuffer( buffer );
611  hl->setMinWidth( minWidth );
612  mRubberBands.append( hl );
613  connect( vl, SIGNAL( destroyed() ), this, SLOT( layerDestroyed() ) );
614  }
615 }
616 
617 void QgsIdentifyMenu::deleteRubberBands()
618 {
620  for ( ; it != mRubberBands.constEnd(); ++it )
621  delete *it;
622  mRubberBands.clear();
623 }
624 
625 void QgsIdentifyMenu::layerDestroyed()
626 {
627  QList<QgsHighlight*>::iterator it = mRubberBands.begin();
628  while ( it != mRubberBands.end() )
629  {
630  if (( *it )->layer() == sender() )
631  {
632  delete *it;
633  it = mRubberBands.erase( it );
634  }
635  else
636  {
637  ++it;
638  }
639  }
640 }
641 
643 {
644  mCustomActionRegistry.clear();
645 
646 }
647 
649 {
650  mExpressionContextScope = scope;
651 }
652 
654 {
655  return mExpressionContextScope;
656 }
void hovered(QAction *action)
bool canConvert(Type t) const
void clear()
QAction * insertSeparator(QAction *before)
static double DEFAULT_HIGHLIGHT_BUFFER_MM
Default highlight buffer in mm.
Definition: qgis.h:247
Base class for all map layer types.
Definition: qgsmaplayer.h:49
static const QColor DEFAULT_HIGHLIGHT_COLOR
Default highlight color.
Definition: qgis.h:243
QString & append(QChar ch)
bool contains(const Key &key) const
QString name() const
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
QObject * sender() const
int value() const
QVariant data() const
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
void setIcon(const QIcon &icon)
void addAction(QAction *action)
void setFillColor(const QColor &fillColor)
Set polygons fill color.
void triggered(QAction *action)
T value() const
void setAlpha(int alpha)
iterator erase(iterator pos)
uint count() const
const QgsGeometry * constGeometry() const
Gets a const pointer to the geometry object associated with this feature.
Definition: qgsfeature.cpp:82
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:187
void clear()
QgsMapLayer::LayerType type() const
Get the type of the layer.
Definition: qgsmaplayer.cpp:99
QString tr(const char *sourceText, const char *disambiguation, int n)
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:109
void setBuffer(double buffer)
Set line / outline buffer in millimeters.
Definition: qgshighlight.h:64
void clear()
int count(const T &value) const
void append(const T &value)
QgsMapLayerAction * mMapLayerAction
This class is a menu that is populated automatically with the actions defined for a given layer...
Definition: qgsactionmenu.h:30
bool isEmpty() const
QgsIdentifyMenu(QgsMapCanvas *canvas)
QgsIdentifyMenu is a menu to be used to choose within a list of QgsMapTool::IdentifyReults.
bool isEmpty() const
A class for highlight features on the map.
Definition: qgshighlight.h:37
QPoint pos() const
QString title() const
QGis::GeometryType geometryType() const
Returns point, line or polygon.
QAction * addSeparator()
const Key & key() const
Single scope for storing variables and functions for use within a QgsExpressionContext.
This class tracks map layer actions.
const T & value() const
QMenu(QWidget *parent)
QAction * exec()
const Targets & targets() const
Return availibity of action.
void setMaxFeatureDisplay(int maxFeatureDisplay)
Defines the maximimum number of features displayed in the menu for vector layers (default is 10)...
QString displayField() const
Returns the primary display field name used in the identify results dialog.
void setData(const QVariant &userData)
iterator end()
QgsFeatureId id() const
Get the feature ID for this feature.
Definition: qgsfeature.cpp:65
void triggerForFeatures(QgsMapLayer *layer, const QList< QgsFeature > &featureList)
Triggers the action with the specified layer and list of feature.
virtual void closeEvent(QCloseEvent *e) override
bool contains(const T &value) const
void setExpressionContextScope(const QgsExpressionContextScope &scope)
Sets an expression context scope used to resolve underlying actions.
static QgsMapLayerActionRegistry * instance()
Returns the instance pointer, creating the object on the first call.
void setColor(const QColor &color)
Set line/outline to color, polygon fill to color with alpha = 63.
QList< QgsMapLayerAction * > mapLayerActions(QgsMapLayer *layer, const QgsMapLayerAction::Targets &targets=QgsMapLayerAction::AllActions)
Returns the map layer actions which can run on the specified layer.
bool isValid() const
QString name
Read property of QString layerName.
Definition: qgsmaplayer.h:53
iterator insert(const Key &key, const T &value)
QAction * menuAction() const
virtual void closeEvent(QCloseEvent *event)
QgsExpressionContextScope expressionContextScope() const
Returns an expression context scope used to resolve underlying actions.
const_iterator constEnd() const
const_iterator constBegin() const
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)
QList< QAction * > actions() const
void removeCustomActions()
remove all custom actions from the menu to be built
Represents a vector layer which manages a vector based data sets.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:271
void setMaxLayerDisplay(int maxLayerDisplay)
Defines the maximimum number of layers displayed in the menu (default is 10).
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
void triggerForLayer(QgsMapLayer *layer)
Triggers the action with the specified layer.
void triggerForFeature(QgsMapLayer *layer, const QgsFeature *feature)
Triggers the action with the specified layer and feature.
static double DEFAULT_HIGHLIGHT_MIN_WIDTH_MM
Default highlight line/outline minimum width in mm.
Definition: qgis.h:251
int count(const Key &key) const
iterator begin()
An action which can run on map layers.
void destroyed(QObject *obj)
bool hasNext() const
void setMinWidth(double width)
Set minimum line / outline width in millimeters.
Definition: qgshighlight.h:68