allow attribute and alias names in actions

git-svn-id: http://svn.osgeo.org/qgis/trunk@14283 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
jef 2010-09-25 20:09:20 +00:00
parent ff198a85d1
commit c8c01721e0
12 changed files with 308 additions and 186 deletions

View File

@ -37,7 +37,7 @@ class QgsAttributeAction
#include "qgsattributeaction.h"
%End
public:
QgsAttributeAction();
QgsAttributeAction( QgsVectorLayer * );
//! Destructor
virtual ~QgsAttributeAction();
@ -53,16 +53,17 @@ class QgsAttributeAction
// index into values which indicates which value in the values vector
// is to be used if the action has a default placeholder.
// @note added to python API in 1.6 (without executePython parameter)
void doAction( int index, const QList< QPair<QString, QString> > &values,
void doAction( int index,
const QMap<int, QVariant> &values,
int defaultValueIndex = 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 );
//! Expands the given action, replacing all %'s with the value as given.
QString expandAction( QString action,
const QMap<int, QVariant> &values,
uint defaultValueIndex );
//! Writes the actions out in XML format
bool writeXML( QDomNode& layer_node, QDomDocument& doc ) const;

View File

@ -26,6 +26,7 @@ SET(QGIS_APP_SRCS
qgsgraduatedsymboldialog.cpp
qgshelpviewer.cpp
qgsidentifyresults.cpp
qgsfeatureaction.cpp
qgslabeldialog.cpp
qgslabelengineconfigdialog.cpp
qgslabelinggui.cpp
@ -155,6 +156,7 @@ SET (QGIS_APP_MOC_HDRS
qgsgraduatedsymboldialog.h
qgshelpviewer.h
qgsidentifyresults.h
qgsfeatureaction.h
qgslabeldialog.h
qgsmanageconnectionsdialog.h
qgsmaptoolidentify.h

View File

@ -499,14 +499,11 @@ void QgsAttributeTableModel::incomingChangeLayout()
void QgsAttributeTableModel::executeAction( int action, const QModelIndex &idx ) const
{
QList< QPair<QString, QString> > attributes;
QgsAttributeMap attributes;
for ( int i = 0; i < mAttributes.size(); i++ )
{
attributes << QPair<QString, QString>(
mLayer->pendingFields()[ mAttributes[i] ].name(),
data( index( idx.row(), i ), Qt::EditRole ).toString()
);
attributes.insert( i, data( index( idx.row(), i ), Qt::EditRole ) );
}
mLayer->actions()->doAction( action, attributes, fieldIdx( idx.column() ) );

View File

@ -0,0 +1,42 @@
/***************************************************************************
qgsfeatureaction.cpp - description
-------------------
begin : 2010-09-20
copyright : (C) 2010 by Jürgen E. Fischer
email : jef at norbit dot de
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/* $Id$ */
#include "qgsfeatureaction.h"
#include "qgsvectorlayer.h"
#include "qgsidentifyresults.h"
QgsFeatureAction::QgsFeatureAction( const QString &name, QgsIdentifyResults *results, QgsVectorLayer *vl, int action, QTreeWidgetItem *featItem )
: QAction( name, results )
, mLayer( vl )
, mAction( action )
{
results->retrieveAttributes( featItem, mAttributes, mIdx );
}
QgsFeatureAction::QgsFeatureAction( const QString &name, QgsFeature &f, QgsVectorLayer *layer, int action, QObject *parent )
: QAction( name, parent )
, mLayer( layer )
, mAction( action )
{
mAttributes = f.attributeMap();
}
void QgsFeatureAction::execute()
{
mLayer->actions()->doAction( mAction, mAttributes, mIdx );
}

View File

@ -0,0 +1,49 @@
/***************************************************************************
qgsfeatureaction.h - description
------------------
begin : 2010-09-20
copyright : (C) 2010 by Jürgen E. Fischer
email : jef at norbit dot de
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/* $Id$ */
#ifndef QGSFEATUREACTION_H
#define QGSFEATUREACTION_H
#include "qgsfeature.h"
#include <QList>
#include <QPair>
#include <QAction>
class QgsIdentifyResults;
class QgsVectorLayer;
class QTreeWidgetItem;
class QgsFeatureAction : public QAction
{
Q_OBJECT
public:
QgsFeatureAction( const QString &name, QgsFeature &f, QgsVectorLayer *vl, int action, QObject *parent );
QgsFeatureAction( const QString &name, QgsIdentifyResults *results, QgsVectorLayer *vl, int action, QTreeWidgetItem *featItem );
public slots:
void execute();
private:
QgsVectorLayer *mLayer;
int mAction;
int mIdx;
QgsAttributeMap mAttributes;
};
#endif

View File

@ -28,6 +28,7 @@
#include "qgsattributedialog.h"
#include "qgsmapcanvas.h"
#include "qgsattributeaction.h"
#include "qgsfeatureaction.h"
#include <QCloseEvent>
#include <QLabel>
@ -44,20 +45,6 @@
#include "qgslogger.h"
QgsFeatureAction::QgsFeatureAction( const QString &name, QgsIdentifyResults *results, QgsVectorLayer *vl, int action, QTreeWidgetItem *featItem )
: QAction( name, results )
, mLayer( vl )
, mAction( action )
{
QList< QPair<QString, QString> > attributes;
results->retrieveAttributes( featItem, mAttributes, mIdx );
}
void QgsFeatureAction::execute()
{
mLayer->actions()->doAction( mAction, mAttributes, mIdx );
}
class QgsIdentifyResultsDock : public QDockWidget
{
public:
@ -82,9 +69,9 @@ class QgsIdentifyResultsDock : public QDockWidget
// actions (if any) [userrole: "actions"]
// edit [userrole: "edit"]
// action [userrole: "action", idx]
// name value
// name value
// name value
// displayname [userroles: fieldIdx, original name] displayvalue [userrole: original value]
// displayname [userroles: fieldIdx, original name] displayvalue [userrole: original value]
// displayname [userroles: fieldIdx, original name] displayvalue [userrole: original value]
// feature
// derived attributes (if any)
// name value
@ -145,61 +132,74 @@ QTreeWidgetItem *QgsIdentifyResults::layerItem( QObject *layer )
return 0;
}
void QgsIdentifyResults::addFeature( QgsMapLayer *layer, int fid,
QString displayField, QString displayValue,
const QMap<QString, QString> &attributes,
void QgsIdentifyResults::addFeature( QgsVectorLayer *vlayer, int fid,
const QgsAttributeMap &attributes,
const QMap<QString, QString> &derivedAttributes )
{
QTreeWidgetItem *layItem = layerItem( layer );
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
QgsRasterLayer *rlayer = qobject_cast<QgsRasterLayer *>( layer );
QTreeWidgetItem *layItem = layerItem( vlayer );
if ( layItem == 0 )
{
layItem = new QTreeWidgetItem( QStringList() << QString::number( lstResults->topLevelItemCount() ) << layer->name() );
layItem->setData( 0, Qt::UserRole, QVariant::fromValue( qobject_cast<QObject *>( layer ) ) );
layItem = new QTreeWidgetItem( QStringList() << QString::number( lstResults->topLevelItemCount() ) << vlayer->name() );
layItem->setData( 0, Qt::UserRole, QVariant::fromValue( qobject_cast<QObject *>( vlayer ) ) );
lstResults->addTopLevelItem( layItem );
if ( vlayer )
{
connect( vlayer, SIGNAL( layerDeleted() ), this, SLOT( layerDestroyed() ) );
connect( vlayer, SIGNAL( layerCrsChanged() ), this, SLOT( layerDestroyed() ) );
connect( vlayer, SIGNAL( featureDeleted( int ) ), this, SLOT( featureDeleted( int ) ) );
connect( vlayer, SIGNAL( attributeValueChanged( int, int, const QVariant & ) ), this, SLOT( attributeValueChanged( int, int, const QVariant & ) ) );
connect( vlayer, SIGNAL( editingStarted() ), this, SLOT( editingToggled() ) );
connect( vlayer, SIGNAL( editingStopped() ), this, SLOT( editingToggled() ) );
}
else
{
connect( layer, SIGNAL( destroyed() ), this, SLOT( layerDestroyed() ) );
connect( layer, SIGNAL( layerCrsChanged() ), this, SLOT( layerDestroyed() ) );
}
connect( vlayer, SIGNAL( layerDeleted() ), this, SLOT( layerDestroyed() ) );
connect( vlayer, SIGNAL( layerCrsChanged() ), this, SLOT( layerDestroyed() ) );
connect( vlayer, SIGNAL( featureDeleted( int ) ), this, SLOT( featureDeleted( int ) ) );
connect( vlayer, SIGNAL( attributeValueChanged( int, int, const QVariant & ) ), this, SLOT( attributeValueChanged( int, int, const QVariant & ) ) );
connect( vlayer, SIGNAL( editingStarted() ), this, SLOT( editingToggled() ) );
connect( vlayer, SIGNAL( editingStopped() ), this, SLOT( editingToggled() ) );
}
QTreeWidgetItem *featItem = new QTreeWidgetItem( QStringList() << displayField << displayValue );
QTreeWidgetItem *featItem = new QTreeWidgetItem;
featItem->setData( 0, Qt::UserRole, fid );
layItem->addChild( featItem );
if ( !rlayer || rlayer->providerKey() != "wms" )
for ( QgsAttributeMap::const_iterator it = attributes.begin(); it != attributes.end(); it++ )
{
for ( QMap<QString, QString>::const_iterator it = attributes.begin(); it != attributes.end(); it++ )
{
QTreeWidgetItem *attrItem = new QTreeWidgetItem( QStringList() << it.key() << it.value() );
if ( vlayer )
{
attrItem->setData( 0, Qt::UserRole, vlayer->fieldNameIndex( it.key() ) );
}
featItem->addChild( attrItem );
}
}
else
{
QTreeWidgetItem *attrItem = new QTreeWidgetItem( QStringList() << attributes.begin().key() << "" );
featItem->addChild( attrItem );
QTreeWidgetItem *attrItem = new QTreeWidgetItem( QStringList() << QString::number( it.key() ) << it.value().toString() );
QTextBrowser *tb = new QTextBrowser( attrItem->treeWidget() );
tb->setHtml( attributes.begin().value() );
attrItem->treeWidget()->setItemWidget( attrItem, 1, tb );
const QgsFieldMap &fields = vlayer->pendingFields();
QgsFieldMap::const_iterator fit = fields.find( it.key() );
if ( fit == fields.constEnd() )
{
delete attrItem;
continue;
}
attrItem->setData( 0, Qt::DisplayRole, vlayer->attributeDisplayName( it.key() ) );
attrItem->setData( 0, Qt::UserRole, fit->name() );
attrItem->setData( 0, Qt::UserRole + 1, it.key() );
QVariant value = it.value();
attrItem->setData( 1, Qt::UserRole, value );
switch ( vlayer->editType( it.key() ) )
{
case QgsVectorLayer::Hidden:
// skip the item
delete attrItem;
continue;
case QgsVectorLayer::ValueMap:
value = vlayer->valueMap( it.key() ).key( it->toString(), QString( "(%1)" ).arg( it->toString() ) );
break;
default:
break;
}
attrItem->setData( 1, Qt::DisplayRole, value );
if ( fit->name() == vlayer->displayField() )
{
featItem->setText( 0, attrItem->text( 0 ) );
featItem->setText( 1, attrItem->text( 1 ) );
}
featItem->addChild( attrItem );
}
if ( derivedAttributes.size() >= 0 )
@ -214,35 +214,83 @@ void QgsIdentifyResults::addFeature( QgsMapLayer *layer, int fid,
}
}
if ( vlayer )
QTreeWidgetItem *actionItem = new QTreeWidgetItem( QStringList() << tr( "(Actions)" ) );
actionItem->setData( 0, Qt::UserRole, "actions" );
featItem->addChild( actionItem );
QTreeWidgetItem *editItem = new QTreeWidgetItem( QStringList() << "" << ( vlayer->isEditable() ? tr( "Edit feature form" ) : tr( "View feature form" ) ) );
editItem->setIcon( 0, QgisApp::getThemeIcon( vlayer->isEditable() ? "/mIconEditable.png" : "/mIconEditable.png" ) );
editItem->setData( 0, Qt::UserRole, "edit" );
actionItem->addChild( editItem );
for ( int i = 0; i < vlayer->actions()->size(); i++ )
{
QTreeWidgetItem *actionItem = new QTreeWidgetItem( QStringList() << tr( "(Actions)" ) );
actionItem->setData( 0, Qt::UserRole, "actions" );
featItem->addChild( actionItem );
const QgsAction &action = vlayer->actions()->at( i );
QTreeWidgetItem *editItem = new QTreeWidgetItem( QStringList() << "" << ( vlayer->isEditable() ? tr( "Edit feature form" ) : tr( "View feature form" ) ) );
editItem->setIcon( 0, QgisApp::getThemeIcon( vlayer->isEditable() ? "/mIconEditable.png" : "/mIconEditable.png" ) );
editItem->setData( 0, Qt::UserRole, "edit" );
actionItem->addChild( editItem );
if ( !action.runable() )
continue;
for ( int i = 0; i < vlayer->actions()->size(); i++ )
{
const QgsAction &action = vlayer->actions()->at( i );
if ( !action.runable() )
continue;
QTreeWidgetItem *twi = new QTreeWidgetItem( QStringList() << "" << action.name() );
twi->setIcon( 0, QgisApp::getThemeIcon( "/mAction.png" ) );
twi->setData( 0, Qt::UserRole, "action" );
twi->setData( 0, Qt::UserRole + 1, QVariant::fromValue( i ) );
actionItem->addChild( twi );
}
QTreeWidgetItem *twi = new QTreeWidgetItem( QStringList() << "" << action.name() );
twi->setIcon( 0, QgisApp::getThemeIcon( "/mAction.png" ) );
twi->setData( 0, Qt::UserRole, "action" );
twi->setData( 0, Qt::UserRole + 1, QVariant::fromValue( i ) );
actionItem->addChild( twi );
}
highlightFeature( featItem );
}
void QgsIdentifyResults::addFeature( QgsRasterLayer *layer,
QString label,
const QMap<QString, QString> &attributes,
const QMap<QString, QString> &derivedAttributes )
{
QTreeWidgetItem *layItem = layerItem( layer );
if ( layItem == 0 )
{
layItem = new QTreeWidgetItem( QStringList() << QString::number( lstResults->topLevelItemCount() ) << layer->name() );
layItem->setData( 0, Qt::UserRole, QVariant::fromValue( qobject_cast<QObject *>( layer ) ) );
lstResults->addTopLevelItem( layItem );
connect( layer, SIGNAL( destroyed() ), this, SLOT( layerDestroyed() ) );
connect( layer, SIGNAL( layerCrsChanged() ), this, SLOT( layerDestroyed() ) );
}
QTreeWidgetItem *featItem = new QTreeWidgetItem( QStringList() << label << "" );
featItem->setData( 0, Qt::UserRole, -1 );
layItem->addChild( featItem );
if ( layer && layer->providerKey() == "wms" )
{
QTreeWidgetItem *attrItem = new QTreeWidgetItem( QStringList() << attributes.begin().key() << "" );
featItem->addChild( attrItem );
QTextBrowser *tb = new QTextBrowser( attrItem->treeWidget() );
tb->setHtml( attributes.begin().value() );
attrItem->treeWidget()->setItemWidget( attrItem, 1, tb );
}
else
{
for ( QMap<QString, QString>::const_iterator it = attributes.begin(); it != attributes.end(); it++ )
{
featItem->addChild( new QTreeWidgetItem( QStringList() << it.key() << it.value() ) );
}
}
if ( derivedAttributes.size() >= 0 )
{
QTreeWidgetItem *derivedItem = new QTreeWidgetItem( QStringList() << tr( "(Derived)" ) );
derivedItem->setData( 0, Qt::UserRole, "derived" );
featItem->addChild( derivedItem );
for ( QMap< QString, QString>::const_iterator it = derivedAttributes.begin(); it != derivedAttributes.end(); it++ )
{
derivedItem->addChild( new QTreeWidgetItem( QStringList() << it.key() << it.value() ) );
}
}
}
void QgsIdentifyResults::editingToggled()
{
QTreeWidgetItem *layItem = layerItem( sender() );
@ -484,7 +532,7 @@ void QgsIdentifyResults::deactivate()
void QgsIdentifyResults::doAction( QTreeWidgetItem *item, int action )
{
int idx;
QList< QPair<QString, QString> > attributes;
QgsAttributeMap attributes;
QTreeWidgetItem *featItem = retrieveAttributes( item, attributes, idx );
if ( !featItem )
return;
@ -570,7 +618,7 @@ QgsVectorLayer *QgsIdentifyResults::vectorLayer( QTreeWidgetItem *item )
}
QTreeWidgetItem *QgsIdentifyResults::retrieveAttributes( QTreeWidgetItem *item, QList< QPair<QString, QString> > &attributes, int &idx )
QTreeWidgetItem *QgsIdentifyResults::retrieveAttributes( QTreeWidgetItem *item, QgsAttributeMap &attributes, int &idx )
{
QTreeWidgetItem *featItem = featureItem( item );
if ( !featItem )
@ -585,8 +633,8 @@ QTreeWidgetItem *QgsIdentifyResults::retrieveAttributes( QTreeWidgetItem *item,
if ( item->childCount() > 0 )
continue;
if ( item == lstResults->currentItem() )
idx = attributes.size();
attributes << QPair<QString, QString>( item->data( 0, Qt::DisplayRole ).toString(), item->data( 1, Qt::DisplayRole ).toString() );
idx = item->data( 0, Qt::UserRole + 1 ).toInt();
attributes.insert( item->data( 0, Qt::UserRole + 1 ).toInt(), item->data( 1, Qt::DisplayRole ) );
}
return featItem;
@ -939,13 +987,23 @@ void QgsIdentifyResults::copyFeatureAttributes()
QClipboard *clipboard = QApplication::clipboard();
QString text;
QgsVectorLayer *vlayer = vectorLayer( lstResults->currentItem() );
if ( !vlayer )
return;
int idx;
QList< QPair<QString, QString> > attributes;
QgsAttributeMap attributes;
retrieveAttributes( lstResults->currentItem(), attributes, idx );
for ( QList< QPair<QString, QString> >::iterator it = attributes.begin(); it != attributes.end(); it++ )
const QgsFieldMap &fields = vlayer->pendingFields();
for ( QgsAttributeMap::const_iterator it = attributes.begin(); it != attributes.end(); it++ )
{
text += QString( "%1: %2\n" ).arg( it->first ).arg( it->second );
QgsFieldMap::const_iterator fit = fields.find( it.key() );
if ( fit == fields.constEnd() )
continue;
text += QString( "%1: %2\n" ).arg( fit->name() ).arg( it.value().toString() );
}
QgsDebugMsg( QString( "set clipboard: %1" ).arg( text ) );

View File

@ -22,6 +22,7 @@
#include "ui_qgsidentifyresultsbase.h"
#include "qgsattributeaction.h"
#include "qgscontexthelp.h"
#include "qgsfeature.h"
#include <QWidget>
#include <QList>
@ -31,8 +32,8 @@ class QTreeWidgetItem;
class QAction;
class QMenu;
class QgsMapLayer;
class QgsVectorLayer;
class QgsRasterLayer;
class QgsRubberBand;
class QgsMapCanvas;
class QDockWidget;
@ -53,9 +54,13 @@ class QgsIdentifyResults: public QDialog, private Ui::QgsIdentifyResultsBase
~QgsIdentifyResults();
/** Add add feature */
void addFeature( QgsMapLayer *layer, int fid,
QString displayField, QString displayValue,
/** Add add feature from vector layer */
void addFeature( QgsVectorLayer *layer, int fid,
const QgsAttributeMap &attributes,
const QMap< QString, QString > &derivedAttributes );
/** Add add feature from other layer */
void addFeature( QgsRasterLayer *layer, QString label,
const QMap< QString, QString > &attributes,
const QMap< QString, QString > &derivedAttributes );
@ -104,7 +109,7 @@ class QgsIdentifyResults: public QDialog, private Ui::QgsIdentifyResultsBase
/* Item in tree was clicked */
void itemClicked( QTreeWidgetItem *lvi, int column );
QTreeWidgetItem *retrieveAttributes( QTreeWidgetItem *item, QList< QPair<QString, QString> > &attributes, int &currentIdx );
QTreeWidgetItem *retrieveAttributes( QTreeWidgetItem *item, QgsAttributeMap &attributes, int &currentIdx );
void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); }
@ -132,21 +137,4 @@ class QgsIdentifyResults: public QDialog, private Ui::QgsIdentifyResultsBase
QDockWidget *mDock;
};
class QgsFeatureAction : public QAction
{
Q_OBJECT
public:
QgsFeatureAction( const QString &name, QgsIdentifyResults *results, QgsVectorLayer *vl, int action, QTreeWidgetItem *featItem );
public slots:
void execute();
private:
QgsVectorLayer *mLayer;
int mAction;
int mIdx;
QList< QPair<QString, QString> > mAttributes;
};
#endif

View File

@ -209,7 +209,6 @@ bool QgsMapToolIdentify::identifyVectorLayer( QgsVectorLayer *layer, int x, int
identifyValue = QGis::DEFAULT_IDENTIFY_RADIUS;
int featureCount = 0;
const QgsFieldMap& fields = layer->pendingFields();
// init distance/area calculator
QgsDistanceArea calc;
@ -254,37 +253,7 @@ bool QgsMapToolIdentify::identifyVectorLayer( QgsVectorLayer *layer, int x, int
featureCount++;
int fid = f_it->id();
QString displayField, displayValue;
QMap<QString, QString> attributes, derivedAttributes;
const QgsAttributeMap& attr = f_it->attributeMap();
for ( QgsAttributeMap::const_iterator it = attr.begin(); it != attr.end(); ++it )
{
QString attributeName = layer->attributeDisplayName( it.key() );
QString attributeValue = it->isNull() ? "NULL" : it->toString();
switch ( layer->editType( it.key() ) )
{
case QgsVectorLayer::Hidden:
continue;
case QgsVectorLayer::ValueMap:
attributeValue = layer->valueMap( it.key() ).key( it->toString(), QString( "(%1)" ).arg( it->toString() ) );
break;
default:
break;
}
if ( fields[it.key()].name() == layer->displayField() )
{
displayField = attributeName;
displayValue = attributeValue;
}
attributes.insert( attributeName, attributeValue );
}
QMap<QString, QString> derivedAttributes;
// Calculate derived attributes and insert:
// measure distance or area depending on geometry type
@ -331,7 +300,7 @@ bool QgsMapToolIdentify::identifyVectorLayer( QgsVectorLayer *layer, int x, int
derivedAttributes.insert( tr( "feature id" ), fid < 0 ? tr( "new feature" ) : QString::number( fid ) );
results()->addFeature( layer, fid, displayField, displayValue, attributes, derivedAttributes );
results()->addFeature( layer, fid, f_it->attributeMap(), derivedAttributes );
}
QgsDebugMsg( "Feature count on identify: " + QString::number( featureCount ) );
@ -392,7 +361,7 @@ bool QgsMapToolIdentify::identifyRasterLayer( QgsRasterLayer *layer, int x, int
if ( res )
{
derivedAttributes.insert( tr( "(clicked coordinate)" ), idPoint.toString() );
results()->addFeature( layer, -1, type, "", attributes, derivedAttributes );
results()->addFeature( layer, type, attributes, derivedAttributes );
}
return res;

View File

@ -30,6 +30,7 @@
#include "qgsattributeaction.h"
#include "qgsrunprocess.h"
#include "qgsvectorlayer.h"
static const char * const ident_ = "$Id$";
@ -38,7 +39,7 @@ void QgsAttributeAction::addAction( QgsAction::ActionType type, QString name, QS
mActions << QgsAction( type, name, action, capture );
}
void QgsAttributeAction::doAction( int index, const QList< QPair<QString, QString> > &values,
void QgsAttributeAction::doAction( int index, const QgsAttributeMap &attributes,
int defaultValueIndex, void ( *executePython )( const QString & ) )
{
if ( index < 0 || index >= size() )
@ -61,7 +62,7 @@ void QgsAttributeAction::doAction( int index, const QList< QPair<QString, QStrin
// The QgsRunProcess instance created by this static function
// deletes itself when no longer needed.
QString expandedAction = expandAction( action.action(), values, defaultValueIndex );
QString expandedAction = expandAction( action.action(), attributes, defaultValueIndex );
if ( action.type() == QgsAction::GenericPython )
{
if ( executePython )
@ -79,7 +80,7 @@ void QgsAttributeAction::doAction( int index, const QList< QPair<QString, QStrin
}
}
QString QgsAttributeAction::expandAction( QString action, const QList< QPair<QString, QString> > &values,
QString QgsAttributeAction::expandAction( QString action, const QgsAttributeMap &attributes,
uint clickedOnValue )
{
// This function currently replaces all %% characters in the action
@ -98,19 +99,29 @@ QString QgsAttributeAction::expandAction( QString action, const QList< QPair<QSt
// for the actual substitutions.
QString expanded_action;
if ( clickedOnValue >= 0 && clickedOnValue < static_cast<unsigned int>( values.size() ) )
expanded_action = action.replace( "%%", values[clickedOnValue].second );
if ( clickedOnValue >= 0 && attributes.contains( clickedOnValue ) )
expanded_action = action.replace( "%%", attributes[clickedOnValue].toString() );
else
expanded_action = action;
for ( int i = 0; i < values.size(); ++i )
{
// Check for a replace a quoted version and a non-quoted version.
QString to_replace_1 = "[%" + values[i].first + "]";
QString to_replace_2 = "%" + values[i].first;
const QgsFieldMap &fields = mLayer->pendingFields();
expanded_action = expanded_action.replace( to_replace_1, values[i].second );
expanded_action = expanded_action.replace( to_replace_2, values[i].second );
for ( QgsAttributeMap::const_iterator it = attributes.begin(); it != attributes.end(); it++ )
{
QgsFieldMap::const_iterator fit = fields.find( it.key() );
if ( fit == fields.constEnd() )
continue;
// Check for a replace a quoted version and a non-quoted version.
QString to_replace_1 = "[%" + fit->name() + "]";
QString to_replace_2 = "%" + fit->name() + "%";
QString to_replace_3 = "%" + mLayer->attributeDisplayName( it.key() ) + "%";
QString to_replace_4 = "[%" + mLayer->attributeDisplayName( it.key() ) + "%]";
expanded_action = expanded_action.replace( to_replace_1, it.value().toString() );
expanded_action = expanded_action.replace( to_replace_2, it.value().toString() );
expanded_action = expanded_action.replace( to_replace_3, it.value().toString() );
expanded_action = expanded_action.replace( to_replace_4, it.value().toString() );
}
return expanded_action;

View File

@ -27,12 +27,13 @@
#include <QString>
#include <QObject>
#include <QList>
#include <QPair>
#include <qgsfeature.h>
class QDomNode;
class QDomDocument;
class QgsPythonUtils;
class QgsVectorLayer;
/** \ingroup core
* Utility class that encapsulates an action based on vector attributes.
@ -95,7 +96,7 @@ class CORE_EXPORT QgsAttributeAction
{
public:
//! Constructor
QgsAttributeAction() {}
QgsAttributeAction( QgsVectorLayer *layer ) : mLayer( layer ) {}
//! Destructor
virtual ~QgsAttributeAction() {}
@ -111,16 +112,19 @@ class CORE_EXPORT QgsAttributeAction
// index into values which indicates which value in the values vector
// is to be used if the action has a default placeholder.
// @note parameter executePython deprecated (and missing in python binding)
void doAction( int index, const QList< QPair<QString, QString> > &values,
int defaultValueIndex = 0, void ( *executePython )( const QString & ) = 0 );
void doAction( int index,
const QgsAttributeMap &attributes,
int defaultValueIndex = 0,
void ( *executePython )( const QString & ) = 0 );
//! Removes all actions
void clearActions() { mActions.clear(); }
//! 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 );
QString expandAction( QString action,
const QgsAttributeMap &attributes,
uint defaultValueIndex );
//! Writes the actions out in XML format
bool writeXML( QDomNode& layer_node, QDomDocument& doc ) const;
@ -136,6 +140,7 @@ class CORE_EXPORT QgsAttributeAction
private:
QList<QgsAction> mActions;
QgsVectorLayer *mLayer;
static void ( *smPythonExecute )( const QString & );
};

View File

@ -23,24 +23,24 @@ email : sherman at mrcc.com
*/
QgsFeature::QgsFeature( int id, QString typeName )
: mFid( id ),
mGeometry( 0 ),
mOwnsGeometry( 0 ),
mValid( false ),
mDirty( 0 ),
mTypeName( typeName )
: mFid( id )
, mGeometry( 0 )
, mOwnsGeometry( 0 )
, mValid( false )
, mDirty( 0 )
, mTypeName( typeName )
{
// NOOP
}
QgsFeature::QgsFeature( QgsFeature const & rhs )
: mFid( rhs.mFid ),
mAttributes( rhs.mAttributes ),
mGeometry( 0 ),
mOwnsGeometry( false ),
mValid( rhs.mValid ),
mDirty( rhs.mDirty ),
mTypeName( rhs.mTypeName )
: mFid( rhs.mFid )
, mAttributes( rhs.mAttributes )
, mGeometry( 0 )
, mOwnsGeometry( false )
, mValid( rhs.mValid )
, mDirty( rhs.mDirty )
, mTypeName( rhs.mTypeName )
{
// copy embedded geometry

View File

@ -111,7 +111,7 @@ QgsVectorLayer::QgsVectorLayer( QString vectorLayerPath,
mVertexMarkerOnlyForSelection( false ),
mFetching( false )
{
mActions = new QgsAttributeAction;
mActions = new QgsAttributeAction( this );
// if we're given a provider type, try to create and bind one to this layer
if ( ! mProviderKey.isEmpty() )