Skip to content

Commit

Permalink
Merge pull request #5660 from pblottiere/bugfix-clickxy-218
Browse files Browse the repository at this point in the history
[backport][bugfix] Fixes #16852 by adding click_x and click_y variables to resolve actions
  • Loading branch information
pblottiere committed Nov 22, 2017
2 parents dbd4f9e + 4fe0013 commit 10b34b9
Show file tree
Hide file tree
Showing 16 changed files with 208 additions and 12 deletions.
13 changes: 9 additions & 4 deletions python/core/qgsactionmanager.sip
Expand Up @@ -62,13 +62,18 @@ class QgsActionManager
//! Remove an action at given index
void removeAction( int index );

/** Does the given values. defaultValueIndex is the index of the
* field to be used if the action has a $currfield placeholder.
* @note available in python bindings as doActionFeature
/**
* Does the given action.
*
* @param index Index of the action
* @param feat Feature to run action for
* @param defaultValueIndex Index of the field to be used if the action has a $currfield placeholder.
* @param scope Expression context scope to add during expression evaluation
*/
void doAction( int index,
const QgsFeature &feat,
int defaultValueIndex = 0 ) /PyName=doActionFeature/;
int defaultValueIndex = 0,
const QgsExpressionContextScope &scope = QgsExpressionContextScope() ) /PyName=doActionFeature/;

/** Does the action using the expression engine to replace any embedded expressions
* in the action definition.
Expand Down
14 changes: 14 additions & 0 deletions python/gui/qgsactionmenu.sip
Expand Up @@ -62,6 +62,20 @@ class QgsActionMenu : QMenu
*/
void setFeature( QgsFeature* feature );

/**
* Sets an expression context scope used to resolve underlying actions.
*
* @note Added in QGIS 2.18
*/
void setExpressionContextScope( const QgsExpressionContextScope &scope );

/**
* Returns an expression context scope used to resolve underlying actions.
*
* @note Added in QGIS 2.18
*/
QgsExpressionContextScope expressionContextScope() const;

signals:
void reinit();

Expand Down
14 changes: 14 additions & 0 deletions python/gui/qgsidentifymenu.sip
Expand Up @@ -83,6 +83,20 @@ class QgsIdentifyMenu : QMenu
*/
QList<QgsMapToolIdentify::IdentifyResult> exec( const QList<QgsMapToolIdentify::IdentifyResult>& idResults, QPoint pos );

/**
* Sets an expression context scope used to resolve underlying actions.
*
* @note Added in QGIS 2.18
*/
void setExpressionContextScope( const QgsExpressionContextScope &scope );

/**
* Returns an expression context scope used to resolve underlying actions.
*
* @note Added in QGIS 2.18
*/
QgsExpressionContextScope expressionContextScope() const;

protected:
virtual void closeEvent( QCloseEvent *e );
};
2 changes: 2 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -1190,6 +1190,8 @@ QgisApp::QgisApp()
mLayerTreeView = new QgsLayerTreeView( this );
mUndoWidget = new QgsUndoWidget( nullptr, mMapCanvas );
mInfoBar = new QgsMessageBar( centralWidget() );
mPanelMenu = new QMenu( this );
mProgressBar = new QProgressBar( this );
// More tests may need more members to be initialized
}

Expand Down
12 changes: 11 additions & 1 deletion src/app/qgsidentifyresultsdialog.cpp
Expand Up @@ -1237,7 +1237,7 @@ void QgsIdentifyResultsDialog::doAction( QTreeWidgetItem *item, int action )
}

int featIdx = featItem->data( 0, Qt::UserRole + 1 ).toInt();
layer->actions()->doAction( action, mFeatures[ featIdx ], idx );
layer->actions()->doAction( action, mFeatures[ featIdx ], idx, mExpressionContextScope );
}

void QgsIdentifyResultsDialog::doMapLayerAction( QTreeWidgetItem *item, QgsMapLayerAction* action )
Expand Down Expand Up @@ -1951,6 +1951,16 @@ void QgsIdentifyResultsDialog::formatChanged( int index )
}
}

void QgsIdentifyResultsDialog::setExpressionContextScope( const QgsExpressionContextScope &scope )
{
mExpressionContextScope = scope;
}

QgsExpressionContextScope QgsIdentifyResultsDialog::expressionContextScope() const
{
return mExpressionContextScope;
}

/*
* QgsIdentifyResultsDialogMapLayerAction
*/
Expand Down
18 changes: 18 additions & 0 deletions src/app/qgsidentifyresultsdialog.h
Expand Up @@ -152,6 +152,22 @@ class APP_EXPORT QgsIdentifyResultsDialog: public QDialog, private Ui::QgsIdenti
/** Map tool was activated */
void activate();

/**
* Sets an expression context scope to consider for resolving underlying
* actions.
*
* @note Added in QGIS 2.18
*/
void setExpressionContextScope( const QgsExpressionContextScope &scope );

/**
* Returns an expression context scope used for resolving underlying
* actions.
*
* @note Added in QGIS 2.18
*/
QgsExpressionContextScope expressionContextScope() const;

signals:
void selectedFeatureChanged( QgsVectorLayer *, QgsFeatureId featureId );

Expand Down Expand Up @@ -263,6 +279,8 @@ class APP_EXPORT QgsIdentifyResultsDialog: public QDialog, private Ui::QgsIdenti
QgsDockWidget *mDock;

QVector<QgsIdentifyPlotCurve *> mPlotCurves;

QgsExpressionContextScope mExpressionContextScope;
};

class QgsIdentifyResultsDialogMapLayerAction : public QAction
Expand Down
14 changes: 14 additions & 0 deletions src/app/qgsmaptoolidentifyaction.cpp
Expand Up @@ -118,6 +118,8 @@ void QgsMapToolIdentifyAction::canvasReleaseEvent( QgsMapMouseEvent* e )
connect( this, SIGNAL( identifyProgress( int, int ) ), QgisApp::instance(), SLOT( showProgress( int, int ) ) );
connect( this, SIGNAL( identifyMessage( QString ) ), QgisApp::instance(), SLOT( showStatusMessage( QString ) ) );

setClickContextScope( toMapCoordinates( e->pos() ) );

identifyMenu()->setResultsIfExternalAction( false );

// enable the right click for extended menu so it behaves as a contextual menu
Expand Down Expand Up @@ -200,4 +202,16 @@ void QgsMapToolIdentifyAction::handleCopyToClipboard( QgsFeatureStore & featureS
emit copyToClipboard( featureStore );
}

void QgsMapToolIdentifyAction::setClickContextScope( const QgsPoint &point )
{
QgsExpressionContextScope clickScope;
clickScope.addVariable( QgsExpressionContextScope::StaticVariable( QString( "click_x" ), point.x(), true ) );
clickScope.addVariable( QgsExpressionContextScope::StaticVariable( QString( "click_y" ), point.y(), true ) );

resultsDialog()->setExpressionContextScope( clickScope );

if ( mIdentifyMenu )
{
mIdentifyMenu->setExpressionContextScope( clickScope );
}
}
2 changes: 2 additions & 0 deletions src/app/qgsmaptoolidentifyaction.h
Expand Up @@ -82,7 +82,9 @@ class APP_EXPORT QgsMapToolIdentifyAction : public QgsMapToolIdentify

virtual QGis::UnitType displayDistanceUnits() const override;
virtual QgsUnitTypes::AreaUnit displayAreaUnits() const override;
void setClickContextScope( const QgsPoint &point );

friend class TestQgsMapToolIdentifyAction;
};

#endif
4 changes: 2 additions & 2 deletions src/core/qgsactionmanager.cpp
Expand Up @@ -63,10 +63,10 @@ void QgsActionManager::removeAction( int index )
}
}

void QgsActionManager::doAction( int index, const QgsFeature& feat, int defaultValueIndex )
void QgsActionManager::doAction( int index, const QgsFeature& feat, int defaultValueIndex, const QgsExpressionContextScope &scope )
{
QgsExpressionContext context = createExpressionContext();
QgsExpressionContextScope* actionScope = new QgsExpressionContextScope();
QgsExpressionContextScope* actionScope = new QgsExpressionContextScope( scope );
actionScope->addVariable( QgsExpressionContextScope::StaticVariable( QString( "current_field" ), feat.attribute( defaultValueIndex ), true ) );
context << actionScope;
doAction( index, feat, context );
Expand Down
15 changes: 11 additions & 4 deletions src/core/qgsactionmanager.h
Expand Up @@ -78,13 +78,20 @@ class CORE_EXPORT QgsActionManager
//! Remove an action at given index
void removeAction( int index );

/** Does the given values. defaultValueIndex is the index of the
* field to be used if the action has a $currfield placeholder.
* @note available in python bindings as doActionFeature
/**
* Does the given action.
*
* @param index Index of the action
* @param feat Feature to run action for
* @param defaultValueIndex Index of the field to be used if the action has a $currfield placeholder.
* @param scope Expression context scope to add during expression evaluation
*
* @note available in python bindings as doActionFeature
*/
void doAction( int index,
const QgsFeature &feat,
int defaultValueIndex = 0 );
int defaultValueIndex = 0,
const QgsExpressionContextScope &scope = QgsExpressionContextScope() );

/** Does the action using the expression engine to replace any embedded expressions
* in the action definition.
Expand Down
11 changes: 10 additions & 1 deletion src/gui/qgsactionmenu.cpp
Expand Up @@ -106,7 +106,7 @@ void QgsActionMenu::triggerAction()
}
else if ( data.actionType == AttributeAction )
{
mActions->doAction( data.actionId.id, *feature() );
mActions->doAction( data.actionId.id, *feature(), 0, mExpressionContextScope );
}
}

Expand Down Expand Up @@ -159,3 +159,12 @@ void QgsActionMenu::reloadActions()
emit reinit();
}

void QgsActionMenu::setExpressionContextScope( const QgsExpressionContextScope &scope )
{
mExpressionContextScope = scope;
}

QgsExpressionContextScope QgsActionMenu::expressionContextScope() const
{
return mExpressionContextScope;
}
15 changes: 15 additions & 0 deletions src/gui/qgsactionmenu.h
Expand Up @@ -108,6 +108,20 @@ class GUI_EXPORT QgsActionMenu : public QMenu
*/
void setFeature( QgsFeature* feature );

/**
* Sets an expression context scope used to resolve underlying actions.
*
* @note Added in QGIS 2.18
*/
void setExpressionContextScope( const QgsExpressionContextScope &scope );

/**
* Returns an expression context scope used to resolve underlying actions.
*
* @note Added in QGIS 2.18
*/
QgsExpressionContextScope expressionContextScope() const;

private slots:
void triggerAction();
void reloadActions();
Expand All @@ -124,6 +138,7 @@ class GUI_EXPORT QgsActionMenu : public QMenu
const QgsFeature* mFeature;
QgsFeatureId mFeatureId;
bool mOwnsFeature;
QgsExpressionContextScope mExpressionContextScope;
};

Q_DECLARE_METATYPE( QgsActionMenu::ActionData )
Expand Down
11 changes: 11 additions & 0 deletions src/gui/qgsidentifymenu.cpp
Expand Up @@ -349,6 +349,7 @@ void QgsIdentifyMenu::addVectorLayer( QgsVectorLayer* layer, const QList<QgsMapT
if ( mShowFeatureActions )
{
featureActionMenu = new QgsActionMenu( layer, result.mFeature.id(), layerMenu );
featureActionMenu->setExpressionContextScope( mExpressionContextScope );
}

// feature title
Expand Down Expand Up @@ -643,3 +644,13 @@ void QgsIdentifyMenu::removeCustomActions()
mCustomActionRegistry.clear();

}

void QgsIdentifyMenu::setExpressionContextScope( const QgsExpressionContextScope &scope )
{
mExpressionContextScope = scope;
}

QgsExpressionContextScope QgsIdentifyMenu::expressionContextScope() const
{
return mExpressionContextScope;
}
16 changes: 16 additions & 0 deletions src/gui/qgsidentifymenu.h
Expand Up @@ -148,6 +148,20 @@ class GUI_EXPORT QgsIdentifyMenu : public QMenu
*/
QList<QgsMapToolIdentify::IdentifyResult> exec( const QList<QgsMapToolIdentify::IdentifyResult>& idResults, QPoint pos );

/**
* Sets an expression context scope used to resolve underlying actions.
*
* @note Added in QGIS 2.18
*/
void setExpressionContextScope( const QgsExpressionContextScope &scope );

/**
* Returns an expression context scope used to resolve underlying actions.
*
* @note Added in QGIS 2.18
*/
QgsExpressionContextScope expressionContextScope() const;

protected:
virtual void closeEvent( QCloseEvent *e ) override;

Expand Down Expand Up @@ -178,6 +192,8 @@ class GUI_EXPORT QgsIdentifyMenu : public QMenu
int mMaxLayerDisplay;
int mMaxFeatureDisplay;

QgsExpressionContextScope mExpressionContextScope;

// name of the action to be displayed for feature default action, if other actions are shown
QString mDefaultActionName;

Expand Down
1 change: 1 addition & 0 deletions tests/src/app/CMakeLists.txt
Expand Up @@ -23,6 +23,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}
)
INCLUDE_DIRECTORIES(SYSTEM
${QT_INCLUDE_DIR}
${QWT_INCLUDE_DIR}
${GDAL_INCLUDE_DIR}
${PROJ_INCLUDE_DIR}
${GEOS_INCLUDE_DIR}
Expand Down

0 comments on commit 10b34b9

Please sign in to comment.