Index: src/app/attributetable/qgsattributetableview.cpp =================================================================== --- src/app/attributetable/qgsattributetableview.cpp (revision 12627) +++ src/app/attributetable/qgsattributetableview.cpp (working copy) @@ -16,6 +16,7 @@ #include #include #include +#include #include "qgsattributetableview.h" #include "qgsattributetablemodel.h" @@ -25,10 +26,10 @@ #include "qgsvectorlayer.h" #include "qgsvectordataprovider.h" +#include "qgsattributeaction.h" - QgsAttributeTableView::QgsAttributeTableView( QWidget* parent ) - : QTableView( parent ) + : QTableView( parent ), mActionPopup( 0 ) { QSettings settings; restoreGeometry( settings.value( "/BetterTable/geometry" ).toByteArray() ); @@ -41,7 +42,6 @@ setSelectionBehavior( QAbstractItemView::SelectRows ); setSelectionMode( QAbstractItemView::NoSelection ); setSortingEnabled( true ); - } void QgsAttributeTableView::setLayer( QgsVectorLayer* layer ) @@ -64,6 +64,7 @@ { delete mModel; delete mFilterModel; + delete mActionPopup; } void QgsAttributeTableView::closeEvent( QCloseEvent *event ) @@ -71,3 +72,47 @@ QSettings settings; settings.setValue( "/BetterAttributeTable/geometry", QVariant( saveGeometry() ) ); } + +void QgsAttributeTableView::contextMenuEvent( QContextMenuEvent *event ) +{ + if ( mActionPopup ) + { + delete mActionPopup; + mActionPopup = 0; + } + + QModelIndex idx = indexAt( event->pos() ); + if ( !idx.isValid() ) + { + return; + } + + QgsVectorLayer *vlayer = mModel->layer(); + if ( !vlayer || vlayer->actions()->size() == 0 ) + { + return; + } + + mActionPopup = new QMenu(); + + QAction *a = mActionPopup->addAction( tr( "Run action" ) ); + a->setEnabled( false ); + + for ( int i = 0; i < vlayer->actions()->size(); i++ ) + { + const QgsAction &action = vlayer->actions()->at( i ); + + if ( !action.runable() ) + continue; + + QgsAttributeTableAction *a = new QgsAttributeTableAction( action.name(), this, mModel, i, idx ); + mActionPopup->addAction( action.name(), a, SLOT( execute() ) ); + } + + mActionPopup->popup( event->globalPos() ); +} + +void QgsAttributeTableAction::execute() +{ + mModel->executeAction( mAction, mFieldIdx ); +} Index: src/app/attributetable/qgsattributetableview.h =================================================================== --- src/app/attributetable/qgsattributetableview.h (revision 12627) +++ src/app/attributetable/qgsattributetableview.h (working copy) @@ -17,11 +17,13 @@ #define QGSATTRIBUTETABLEVIEW_H #include +#include class QgsAttributeTableModel; class QgsAttributeTableFilterModel; class QgsVectorLayer; +class QMenu; class QgsAttributeTableView: public QTableView @@ -42,9 +44,31 @@ */ void closeEvent( QCloseEvent *event ); + void contextMenuEvent( QContextMenuEvent* ); + private: QgsAttributeTableModel* mModel; QgsAttributeTableFilterModel* mFilterModel; + QMenu *mActionPopup; }; +class QgsAttributeTableAction : public QAction +{ + Q_OBJECT + + public: + QgsAttributeTableAction( const QString &name, QgsAttributeTableView *view, QgsAttributeTableModel *model, int action, const QModelIndex &fieldIdx ) : + QAction( name, view ), mModel( model ), mAction( action ), mFieldIdx( fieldIdx ) + {} + + public slots: + void execute(); + + private: + QgsAttributeTableModel *mModel; + int mAction; + QModelIndex mFieldIdx; +}; + + #endif Index: src/app/attributetable/qgsattributetablemodel.cpp =================================================================== --- src/app/attributetable/qgsattributetablemodel.cpp (revision 12627) +++ src/app/attributetable/qgsattributetablemodel.cpp (working copy) @@ -19,6 +19,8 @@ #include "qgsfield.h" #include "qgsvectorlayer.h" #include "qgslogger.h" +#include "qgisapp.h" +#include "qgsattributeaction.h" #include #include @@ -317,7 +319,10 @@ return QVariant( attributeName ); } } - else return QVariant(); + else + { + return QVariant(); + } } void QgsAttributeTableModel::sort( int column, Qt::SortOrder order ) @@ -487,3 +492,22 @@ emit layoutAboutToBeChanged(); } +static void _runPythonString( const QString &expr ) +{ + QgisApp::instance()->runPythonString( expr ); +} + +void QgsAttributeTableModel::executeAction( int action, const QModelIndex &idx ) const +{ + QList< QPair > attributes; + + for ( int i = 0; i < mAttributes.size(); i++ ) + { + attributes << QPair( + mLayer->pendingFields()[ mAttributes[i] ].name(), + data( index( idx.row(), i ), Qt::EditRole ).toString() + ); + } + + mLayer->actions()->doAction( action, attributes, fieldIdx( idx.column() ), _runPythonString ); +} Index: src/app/attributetable/qgsattributetablemodel.h =================================================================== --- src/app/attributetable/qgsattributetablemodel.h (revision 12627) +++ src/app/attributetable/qgsattributetablemodel.h (working copy) @@ -125,6 +125,9 @@ */ QgsVectorLayer* layer() const { return mLayer; } + /** Execute an action */ + void executeAction( int action, const QModelIndex &idx ) const; + signals: /** * Model has been changed Index: src/app/CMakeLists.txt =================================================================== --- src/app/CMakeLists.txt (revision 12627) +++ src/app/CMakeLists.txt (working copy) @@ -192,6 +192,7 @@ ogr/qgsopenvectorlayerdialog.h ogr/qgsnewogrconnection.h + attributetable/qgsattributetableview.h attributetable/qgsattributetablemodel.h attributetable/qgsattributetablememorymodel.h attributetable/qgsattributetabledialog.h