Skip to content

Commit

Permalink
[FEATHRE] attribute action improvements
Browse files Browse the repository at this point in the history
- add python bindings for attribute actions
- support actions as context menu in feature form (ui)
- add action types:
  * generic: commands that should work on all platforms
  * windows, mac, unix: commands that should work and are only shown on one platform respectively
    (eg. vim on unix, notepad on windows and textmate on Mac)
  * python: python strings to be executed instead of a command
    (eg. qgis.utils.plugins['apluginname'].amethod('[%someattribute%]'))

[BUGFIXES]
- ogr support for relative filenames fixed
- relative filename support also for feature form uis


git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@12113 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
jef committed Nov 15, 2009
1 parent 3126e7b commit 81366dd
Show file tree
Hide file tree
Showing 15 changed files with 407 additions and 254 deletions.
1 change: 1 addition & 0 deletions python/core/core.sip
Expand Up @@ -68,6 +68,7 @@
%Include qgssymbologyutils.sip
%Include qgstolerance.sip
%Include qgsuniquevaluerenderer.sip
%Include qgsattributeaction.sip
%Include qgsvectordataprovider.sip
%Include qgsvectorfilewriter.sip
%Include qgsvectorlayer.sip
Expand Down
77 changes: 77 additions & 0 deletions python/core/qgsattributeaction.sip
@@ -0,0 +1,77 @@
class QgsAction
{
%TypeHeaderCode
#include "qgsattributeaction.h"
%End

public:
enum ActionType
{
Generic,
GenericPython,
Mac,
Windows,
Unix,
};

QgsAction( ActionType type, QString name, QString action, bool capture );

//! The name of the action
QString name() const;

//! The action
QString action() const;

//! The action type
ActionType type() const;

//! Whether to capture output for display when this action is run
bool capture() const;

bool runable() const;
};

class QgsAttributeAction
{
%TypeHeaderCode
#include "qgsattributeaction.h"
%End
public:
QgsAttributeAction();

//! Destructor
virtual ~QgsAttributeAction();

//! Add an action with the given name and action details.
// Will happily have duplicate names and actions. If
// capture is true, when running the action using doAction(),
// any stdout from the process will be captured and displayed in a
// dialog box.
void addAction( QgsAction::ActionType type, QString name, QString action, bool capture = false );

/*
//! Does the action using the given values. defaultValueIndex is an
// index into values which indicates which value in the values vector
// is to be used if the action has a default placeholder.
void doAction( int index, const QList< QPair<QString, QString> > &values,
int defaultValueIndex = 0, void *executePython = 0 );
*/

//! Removes all actions
void clearActions();

//! Expands the given action, replacing all %'s with the value as
// given.
static QString expandAction( QString action, const QList< QPair<QString, QString> > &values,
uint defaultValueIndex );

//! Writes the actions out in XML format
bool writeXML( QDomNode& layer_node, QDomDocument& doc ) const;

//! Reads the actions in in XML format
bool readXML( const QDomNode& layer_node );

//! interface to inherited methods from QList<QgsAction>
const QgsAction &at( int idx );
const int size();
};
2 changes: 1 addition & 1 deletion python/core/qgsvectorlayer.sip
Expand Up @@ -63,7 +63,7 @@ public:

QgsLabel *label();

// TODO: wrap QgsAttributeAction* actions();
QgsAttributeAction *actions();

/** The number of features that are selected in this layer */
int selectedFeatureCount();
Expand Down
8 changes: 8 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -6397,3 +6397,11 @@ void QgisApp::updateUndoActions()
mActionUndo->setEnabled( canUndo );
mActionRedo->setEnabled( canRedo );
}

void QgisApp::runPythonString( const QString &expr )
{
if ( mPythonUtils )
{
mPythonUtils->runStringUnsafe( expr );
}
}
3 changes: 3 additions & 0 deletions src/app/qgisapp.h
Expand Up @@ -340,6 +340,9 @@ class QgisApp : public QMainWindow
QToolBar *pluginToolBar() { return mPluginToolBar; }
QToolBar *helpToolBar() { return mHelpToolBar; }

//! run python
void runPythonString( const QString &expr );

public slots:
//! Zoom to full extent
void zoomFull();
Expand Down
46 changes: 25 additions & 21 deletions src/app/qgsattributeactiondialog.cpp
Expand Up @@ -68,24 +68,26 @@ void QgsAttributeActionDialog::init()
attributeActionTable->setRowCount( 0 );

// Populate with our actions.
QgsAttributeAction::AttributeActions::const_iterator
iter = mActions->begin();
int i = 0;
for ( ; iter != mActions->end(); ++iter, ++i )
for ( int i = 0; i < mActions->size(); i++ )
{
insertRow( i, iter->name(), iter->action(), iter->capture() );
const QgsAction action = ( *mActions )[i];
insertRow( i, action.type(), action.name(), action.action(), action.capture() );
}
}

void QgsAttributeActionDialog::insertRow( int row, const QString &name, const QString &action, bool capture )
void QgsAttributeActionDialog::insertRow( int row, QgsAction::ActionType type, const QString &name, const QString &action, bool capture )
{
QTableWidgetItem* item;
attributeActionTable->insertRow( row );
attributeActionTable->setItem( row, 0, new QTableWidgetItem( name ) );
attributeActionTable->setItem( row, 1, new QTableWidgetItem( action ) );
QTableWidgetItem* item = new QTableWidgetItem();
item = new QTableWidgetItem( actionType->itemText( type ) );
item->setFlags( item->flags() & ~Qt::ItemIsEditable );
attributeActionTable->setItem( row, 0, item );
attributeActionTable->setItem( row, 1, new QTableWidgetItem( name ) );
attributeActionTable->setItem( row, 2, new QTableWidgetItem( action ) );
item = new QTableWidgetItem();
item->setFlags( item->flags() & ~( Qt::ItemIsEditable | Qt::ItemIsUserCheckable ) );
item->setCheckState( capture ? Qt::Checked : Qt::Unchecked );
attributeActionTable->setItem( row, 2, item );
attributeActionTable->setItem( row, 3, item );
}

void QgsAttributeActionDialog::moveUp()
Expand Down Expand Up @@ -208,15 +210,15 @@ void QgsAttributeActionDialog::insert( int pos )
if ( pos >= numRows )
{
// Expand the table to have a row with index pos
insertRow( pos, name, actionAction->text(), captureCB->isChecked() );
insertRow( pos, ( QgsAction::ActionType ) actionType->currentIndex(), name, actionAction->text(), captureCB->isChecked() );
}
else
{
// Update existing row
attributeActionTable->item( pos, 0 )->setText( name );
attributeActionTable->item( pos, 1 )->setText( actionAction->text() );
attributeActionTable->item( pos, 2 )->setCheckState(
captureCB->isChecked() ? Qt::Checked : Qt::Unchecked );
attributeActionTable->item( pos, 0 )->setText( actionType->currentText() );
attributeActionTable->item( pos, 1 )->setText( name );
attributeActionTable->item( pos, 2 )->setText( actionAction->text() );
attributeActionTable->item( pos, 3 )->setCheckState( captureCB->isChecked() ? Qt::Checked : Qt::Unchecked );
}
}
}
Expand Down Expand Up @@ -253,12 +255,13 @@ void QgsAttributeActionDialog::apply()
mActions->clearActions();
for ( int i = 0; i < attributeActionTable->rowCount(); ++i )
{
const QString &name = attributeActionTable->item( i, 0 )->text();
const QString &action = attributeActionTable->item( i, 1 )->text();
const QgsAction::ActionType type = ( QgsAction::ActionType ) actionType->findText( attributeActionTable->item( i, 0 )->text() );
const QString &name = attributeActionTable->item( i, 1 )->text();
const QString &action = attributeActionTable->item( i, 2 )->text();
if ( !name.isEmpty() && !action.isEmpty() )
{
QTableWidgetItem *item = attributeActionTable->item( i, 2 );
mActions->addAction( name, action, item->checkState() == Qt::Checked );
QTableWidgetItem *item = attributeActionTable->item( i, 3 );
mActions->addAction( type, name, action, item->checkState() == Qt::Checked );
}
}
}
Expand Down Expand Up @@ -292,8 +295,9 @@ void QgsAttributeActionDialog::rowSelected( int row )
if ( item )
{
// Only if a populated row was selected
actionName->setText( attributeActionTable->item( row, 0 )->text() );
actionAction->setText( attributeActionTable->item( row, 1 )->text() );
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 );
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/app/qgsattributeactiondialog.h
Expand Up @@ -25,6 +25,7 @@ back to QgsVectorLayer.
#define QGSATTRIBUTEACTIONDIALOG_H

#include "ui_qgsattributeactiondialogbase.h"
#include "qgsattributeaction.h"
#include "qgsfield.h"
#include <QMap>

Expand Down Expand Up @@ -56,7 +57,7 @@ class QgsAttributeActionDialog: public QWidget, private Ui::QgsAttributeActionDi

private:

void insertRow( int row, const QString &name, const QString &action, bool capture );
void insertRow( int row, QgsAction::ActionType type, const QString &name, const QString &action, bool capture );
void swapRows( int row1, int row2 );

void insert( int pos );
Expand All @@ -66,7 +67,7 @@ class QgsAttributeActionDialog: public QWidget, private Ui::QgsAttributeActionDi
QString uniqueName( QString name );

// Pointer to the QgsAttributeAction in the class that created us.
QgsAttributeAction* mActions;
QgsAttributeAction *mActions;
};

#endif
2 changes: 2 additions & 0 deletions src/app/qgsattributedialog.h
Expand Up @@ -45,6 +45,8 @@ class QgsAttributeDialog : public QObject
*/
void restoreGeometry();

QDialog *dialog() { return mDialog; }

public slots:
/** Overloaded accept method which will write the feature field
* values, then delegate to QDialog::accept()
Expand Down

0 comments on commit 81366dd

Please sign in to comment.