2 changes: 2 additions & 0 deletions src/app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ SET(QGIS_APP_SRCS
qgsmaptooldeletepart.cpp
qgsmaptooldeletevertex.cpp
qgsmaptooledit.cpp
qgsmaptoolfeatureaction.cpp
qgsmaptoolformannotation.cpp
qgsmaptoolidentify.cpp
qgsmaptoollabel.cpp
Expand Down Expand Up @@ -189,6 +190,7 @@ SET (QGIS_APP_MOC_HDRS
qgsmaptooldeletepart.h
qgsmaptooldeletering.h
qgsmaptooldeletevertex.h
qgsmaptoolfeatureaction.h
qgsmaptoolidentify.h
qgsmaptoolmeasureangle.h
qgsmaptoolmovefeature.h
Expand Down
65 changes: 64 additions & 1 deletion src/app/qgisapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@
#include "qgsmaptooldeletering.h"
#include "qgsmaptooldeletepart.h"
#include "qgsmaptooldeletevertex.h"
#include "qgsmaptoolfeatureaction.h"
#include "qgsmaptoolformannotation.h"
#include "qgsmaptoolidentify.h"
#include "qgsmaptoolmeasureangle.h"
Expand Down Expand Up @@ -640,6 +641,7 @@ QgisApp::~QgisApp()
delete mMapTools.mZoomOut;
delete mMapTools.mPan;
delete mMapTools.mIdentify;
delete mMapTools.mFeatureAction;
delete mMapTools.mMeasureDist;
delete mMapTools.mMeasureArea;
delete mMapTools.mMeasureAngle;
Expand Down Expand Up @@ -814,6 +816,7 @@ void QgisApp::createActions()
connect( mActionSelectRadius, SIGNAL( triggered() ), this, SLOT( selectByRadius() ) );
connect( mActionDeselectAll, SIGNAL( triggered() ), this, SLOT( deselectAll() ) );
connect( mActionIdentify, SIGNAL( triggered() ), this, SLOT( identify() ) );
connect( mActionFeatureAction, SIGNAL( triggered() ), this, SLOT( doFeatureAction() ) );
connect( mActionMeasure, SIGNAL( triggered() ), this, SLOT( measure() ) );
connect( mActionMeasureArea, SIGNAL( triggered() ), this, SLOT( measureArea() ) );
connect( mActionMeasureAngle, SIGNAL( triggered() ), this, SLOT( measureAngle() ) );
Expand Down Expand Up @@ -989,6 +992,7 @@ void QgisApp::createActionGroups()
mMapToolGroup->addAction( mActionZoomIn );
mMapToolGroup->addAction( mActionZoomOut );
mMapToolGroup->addAction( mActionIdentify );
mMapToolGroup->addAction( mActionFeatureAction );
mMapToolGroup->addAction( mActionSelect );
mMapToolGroup->addAction( mActionSelectRectangle );
mMapToolGroup->addAction( mActionSelectPolygon );
Expand Down Expand Up @@ -1172,6 +1176,18 @@ void QgisApp::createToolBars()
selectAction->setObjectName( "ActionSelect" );
connect( bt, SIGNAL( triggered( QAction * ) ), this, SLOT( toolButtonActionTriggered( QAction * ) ) );

// feature action tool button

bt = new QToolButton( mAttributesToolBar );
bt->setPopupMode( QToolButton::MenuButtonPopup );
bt->setDefaultAction( mActionFeatureAction );
mFeatureActionMenu = new QMenu( bt );
connect( mFeatureActionMenu, SIGNAL( triggered( QAction * ) ), this, SLOT( updateDefaultFeatureAction( QAction * ) ) );
connect( mFeatureActionMenu, SIGNAL( aboutToShow() ), this, SLOT( refreshFeatureActions() ) );
bt->setMenu( mFeatureActionMenu );
QAction* featureActionAction = mAttributesToolBar->insertWidget( selectAction, bt );
featureActionAction->setObjectName( "ActionFeatureAction" );

// measure tool button

bt = new QToolButton( mAttributesToolBar );
Expand Down Expand Up @@ -1478,6 +1494,7 @@ void QgisApp::setTheme( QString theThemeName )
mActionZoomToLayer->setIcon( getThemeIcon( "/mActionZoomToLayer.png" ) );
mActionZoomActualSize->setIcon( getThemeIcon( "/mActionZoomActual.png" ) );
mActionIdentify->setIcon( getThemeIcon( "/mActionIdentify.png" ) );
mActionFeatureAction->setIcon( getThemeIcon( "/mAction.png" ) );
mActionSelect->setIcon( getThemeIcon( "/mActionSelect.png" ) );
mActionSelectRectangle->setIcon( getThemeIcon( "/mActionSelectRectangle.png" ) );
mActionSelectPolygon->setIcon( getThemeIcon( "/mActionSelectPolygon.png" ) );
Expand Down Expand Up @@ -1604,6 +1621,8 @@ void QgisApp::createCanvasTools()
mMapTools.mPan->setAction( mActionPan );
mMapTools.mIdentify = new QgsMapToolIdentify( mMapCanvas );
mMapTools.mIdentify->setAction( mActionIdentify );
mMapTools.mFeatureAction = new QgsMapToolFeatureAction( mMapCanvas );
mMapTools.mFeatureAction->setAction( mActionFeatureAction );
mMapTools.mMeasureDist = new QgsMeasureTool( mMapCanvas, false /* area */ );
mMapTools.mMeasureDist->setAction( mActionMeasure );
mMapTools.mMeasureArea = new QgsMeasureTool( mMapCanvas, true /* area */ );
Expand Down Expand Up @@ -3274,6 +3293,48 @@ void QgisApp::identify()
mMapCanvas->setMapTool( mMapTools.mIdentify );
}

void QgisApp::doFeatureAction()
{
mMapCanvas->setMapTool( mMapTools.mFeatureAction );
}

void QgisApp::updateDefaultFeatureAction( QAction *action )
{
foreach( QAction *a, mFeatureActionMenu->actions() )
{
a->setChecked( a == action );
}

QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( activeLayer() );
if ( !vlayer )
return;

int index = mFeatureActionMenu->actions().indexOf( action );
vlayer->actions()->setDefaultAction( index );

doFeatureAction();
}

void QgisApp::refreshFeatureActions()
{
mFeatureActionMenu->clear();

QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( activeLayer() );
if ( !vlayer )
return;

QgsAttributeAction *actions = vlayer->actions();
for ( int i = 0; i < actions->size(); i++ )
{
QAction *action = mFeatureActionMenu->addAction( actions->at( i ).name() );
action->setCheckable( true );
if ( i == actions->defaultAction() )
{
action->setChecked( true );
}
}
}

void QgisApp::measure()
{
mMapCanvas->setMapTool( mMapTools.mMeasureDist );
Expand Down Expand Up @@ -6019,7 +6080,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
mActionLayerProperties->setEnabled( false );
mActionLayerSubsetString->setEnabled( false );
mActionAddToOverview->setEnabled( false );

mActionFeatureAction->setEnabled( false );
mActionAddFeature->setEnabled( false );
mActionMoveFeature->setEnabled( false );
mActionNodeTool->setEnabled( false );
Expand Down Expand Up @@ -6077,6 +6138,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
mActionLayerSaveAs->setEnabled( true );
mActionLayerSelectionSaveAs->setEnabled( true );
mActionCopyFeatures->setEnabled( layerHasSelection );
mActionFeatureAction->setEnabled( vlayer->actions()->size() > 0 );

if ( !vlayer->isEditable() && mMapCanvas->mapTool() && mMapCanvas->mapTool()->isEditTool() )
{
Expand Down Expand Up @@ -6244,6 +6306,7 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
mActionFullHistogramStretch->setEnabled( false );
}
mActionLayerSubsetString->setEnabled( false );
mActionFeatureAction->setEnabled( false );
mActionSelect->setEnabled( false );
mActionSelectRectangle->setEnabled( false );
mActionSelectPolygon->setEnabled( false );
Expand Down
11 changes: 11 additions & 0 deletions src/app/qgisapp.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
QAction *actionSelectFreehand() { return mActionSelectFreehand; }
QAction *actionSelectRadius() { return mActionSelectRadius; }
QAction *actionIdentify() { return mActionIdentify; }
QAction *actionFeatureAction() { return mActionFeatureAction; }
QAction *actionMeasure() { return mActionMeasure; }
QAction *actionMeasureArea() { return mActionMeasureArea; }
QAction *actionZoomFullExtent() { return mActionZoomFullExtent; }
Expand Down Expand Up @@ -757,6 +758,13 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
//! Measure angle
void measureAngle();

//! Run the default feature action on the current layer
void doFeatureAction();
//! Set the default feature action for the current layer
void updateDefaultFeatureAction( QAction *action );
//! Refresh the list of feature actions of the current layer
void refreshFeatureActions();

//annotations
void addFormAnnotation();
void addTextAnnotation();
Expand Down Expand Up @@ -969,6 +977,7 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
QgsMapTool* mZoomOut;
QgsMapTool* mPan;
QgsMapTool* mIdentify;
QgsMapTool* mFeatureAction;
QgsMapTool* mMeasureDist;
QgsMapTool* mMeasureArea;
QgsMapTool* mMeasureAngle;
Expand Down Expand Up @@ -1025,6 +1034,8 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
QLabel * mOnTheFlyProjectionStatusLabel;
//! Widget in status bar used to show status of on the fly projection
QToolButton * mOnTheFlyProjectionStatusButton;
//! Menu that contains the list of actions of the selected vector layer
QMenu *mFeatureActionMenu;
//! Popup menu
QMenu * mPopupMenu;
//! Top level database menu
Expand Down
1 change: 1 addition & 0 deletions src/app/qgisappinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ QAction *QgisAppInterface::actionSelectPolygon() { return qgis->actionSelectPoly
QAction *QgisAppInterface::actionSelectFreehand() { return qgis->actionSelectFreehand(); }
QAction *QgisAppInterface::actionSelectRadius() { return qgis->actionSelectRadius(); }
QAction *QgisAppInterface::actionIdentify() { return qgis->actionIdentify(); }
QAction *QgisAppInterface::actionFeatureAction() { return qgis->actionFeatureAction(); }
QAction *QgisAppInterface::actionMeasure() { return qgis->actionMeasure(); }
QAction *QgisAppInterface::actionMeasureArea() { return qgis->actionMeasureArea(); }
QAction *QgisAppInterface::actionViewSeparator1() { return 0; }
Expand Down
1 change: 1 addition & 0 deletions src/app/qgisappinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ class QgisAppInterface : public QgisInterface
virtual QAction *actionSelectFreehand();
virtual QAction *actionSelectRadius();
virtual QAction *actionIdentify();
virtual QAction *actionFeatureAction();
virtual QAction *actionMeasure();
virtual QAction *actionMeasureArea();
virtual QAction *actionViewSeparator1();
Expand Down
39 changes: 31 additions & 8 deletions src/app/qgsattributeactiondialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ back to QgsVectorLayer.

#include "qgsattributeactiondialog.h"
#include "qgsattributeaction.h"
#include "qgsexpressionbuilderdialog.h"

#include <QFileDialog>
#include <QHeaderView>
#include <QMessageBox>

#include <QSettings>

QgsAttributeActionDialog::QgsAttributeActionDialog( QgsAttributeAction* actions,
const QgsFieldMap& fields,
Expand All @@ -50,6 +51,7 @@ QgsAttributeActionDialog::QgsAttributeActionDialog( QgsAttributeAction* actions,
connect( insertButton, SIGNAL( clicked() ), this, SLOT( insert() ) );
connect( updateButton, SIGNAL( clicked() ), this, SLOT( update() ) );
connect( insertFieldButton, SIGNAL( clicked() ), this, SLOT( insertField() ) );
connect( insertExpressionButton, SIGNAL( clicked() ), this, SLOT( insertExpression() ) );

init();
// Populate the combo box with the field names. Will the field names
Expand Down Expand Up @@ -143,16 +145,36 @@ void QgsAttributeActionDialog::swapRows( int row1, int row2 )

void QgsAttributeActionDialog::browse()
{
// Popup a file browser and place the results into the actionName
// widget

// Popup a file browser and place the results into the action widget
QString action = QFileDialog::getOpenFileName(
this, tr( "Select an action", "File dialog window title" ) );

if ( !action.isNull() )
actionAction->insert( action );
}

void QgsAttributeActionDialog::insertExpression()
{
QString selText = actionAction->selectedText();

// edit the selected expression if there's one
if ( selText.startsWith( "[%" ) && selText.endsWith( "%]" ) )
selText = selText.mid( 2, selText.size() - 3 );

// display the expression builder
QgsExpressionBuilderDialog dlg( mActions->layer(), selText, this );
dlg.setWindowTitle( tr( "Insert expression" ) );
if ( dlg.exec() == QDialog::Accepted )
{
QString expression = dlg.expressionBuilder()->getExpressionString();
//Only add the expression if the user has entered some text.
if ( !expression.isEmpty() )
{
actionAction->insert( "[%" + expression + "%]" );
}
}
}

void QgsAttributeActionDialog::remove()
{
QList<QTableWidgetItem *> selection = attributeActionTable->selectedItems();
Expand Down Expand Up @@ -234,13 +256,14 @@ void QgsAttributeActionDialog::update()

void QgsAttributeActionDialog::insertField()
{
// Take the selected field, preprend a % and insert into the action
// field at the cursor position
// Convert the selected field to an expression and
// insert it into the action at the cursor position

if ( !fieldComboBox->currentText().isNull() )
{
QString field( "%" );
QString field = "[% \"";
field += fieldComboBox->currentText();
field += "\" %]";
actionAction->insert( field );
}
}
Expand Down Expand Up @@ -285,7 +308,7 @@ void QgsAttributeActionDialog::rowSelected( int row )
actionType->setCurrentIndex( actionType->findText( attributeActionTable->item( row, 0 )->text() ) );
actionName->setText( attributeActionTable->item( row, 1 )->text() );
actionAction->setText( attributeActionTable->item( row, 2 )->text() );
captureCB->setChecked( item->checkState() == Qt::Checked );
captureCB->setChecked( attributeActionTable->item( row, 3 )->checkState() == Qt::Checked );
}
}

Expand Down
1 change: 1 addition & 0 deletions src/app/qgsattributeactiondialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class QgsAttributeActionDialog: public QWidget, private Ui::QgsAttributeActionDi
void remove();
void insert();
void insertField();
void insertExpression();
void apply();
void update();
void itemSelectionChanged();
Expand Down
2 changes: 1 addition & 1 deletion src/app/qgsfeatureaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ QgsFeatureAction::QgsFeatureAction( const QString &name, QgsFeature &f, QgsVecto

void QgsFeatureAction::execute()
{
mLayer->actions()->doAction( mAction, mFeature.attributeMap(), mIdx );
mLayer->actions()->doAction( mAction, mFeature, mIdx );
}

QgsAttributeDialog *QgsFeatureAction::newDialog( bool cloneFeature )
Expand Down
11 changes: 5 additions & 6 deletions src/app/qgsidentifyresults.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ void QgsIdentifyResults::contextMenuEvent( QContextMenuEvent* event )

mActionPopup = new QMenu();

int idx = 0;
int idx = -1;
QTreeWidgetItem *featItem = featureItem( item );
if ( featItem )
{
Expand Down Expand Up @@ -549,17 +549,15 @@ void QgsIdentifyResults::deactivate()

void QgsIdentifyResults::doAction( QTreeWidgetItem *item, int action )
{
int idx;
QgsAttributeMap attributes;
QTreeWidgetItem *featItem = retrieveAttributes( item, attributes, idx );
QTreeWidgetItem *featItem = featureItem( item );
if ( !featItem )
return;

QgsVectorLayer *layer = qobject_cast<QgsVectorLayer *>( featItem->parent()->data( 0, Qt::UserRole ).value<QObject *>() );
if ( !layer )
return;

idx = -1;
int idx = -1;
if ( item->parent() == featItem )
{
QString fieldName = item->data( 0, Qt::DisplayRole ).toString();
Expand All @@ -574,7 +572,8 @@ void QgsIdentifyResults::doAction( QTreeWidgetItem *item, int action )
}
}

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

QTreeWidgetItem *QgsIdentifyResults::featureItem( QTreeWidgetItem *item )
Expand Down
Loading