Skip to content

Commit 7733abd

Browse files
author
jef
committedSep 25, 2010
allow attribute and alias names in actions
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@14283 c8812cc2-4d05-0410-92ff-de0c093fc19c

12 files changed

+303
-181
lines changed
 

‎python/core/qgsattributeaction.sip

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class QgsAttributeAction
3737
#include "qgsattributeaction.h"
3838
%End
3939
public:
40-
QgsAttributeAction();
40+
QgsAttributeAction( QgsVectorLayer * );
4141

4242
//! Destructor
4343
virtual ~QgsAttributeAction();
@@ -53,16 +53,17 @@ class QgsAttributeAction
5353
// index into values which indicates which value in the values vector
5454
// is to be used if the action has a default placeholder.
5555
// @note added to python API in 1.6 (without executePython parameter)
56-
void doAction( int index, const QList< QPair<QString, QString> > &values,
56+
void doAction( int index,
57+
const QMap<int, QVariant> &values,
5758
int defaultValueIndex = 0 );
5859

5960
//! Removes all actions
6061
void clearActions();
6162

62-
//! Expands the given action, replacing all %'s with the value as
63-
// given.
64-
static QString expandAction( QString action, const QList< QPair<QString, QString> > &values,
65-
uint defaultValueIndex );
63+
//! Expands the given action, replacing all %'s with the value as given.
64+
QString expandAction( QString action,
65+
const QMap<int, QVariant> &values,
66+
uint defaultValueIndex );
6667

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

‎src/app/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ SET(QGIS_APP_SRCS
2626
qgsgraduatedsymboldialog.cpp
2727
qgshelpviewer.cpp
2828
qgsidentifyresults.cpp
29+
qgsfeatureaction.cpp
2930
qgslabeldialog.cpp
3031
qgslabelengineconfigdialog.cpp
3132
qgslabelinggui.cpp
@@ -155,6 +156,7 @@ SET (QGIS_APP_MOC_HDRS
155156
qgsgraduatedsymboldialog.h
156157
qgshelpviewer.h
157158
qgsidentifyresults.h
159+
qgsfeatureaction.h
158160
qgslabeldialog.h
159161
qgsmanageconnectionsdialog.h
160162
qgsmaptoolidentify.h

‎src/app/attributetable/qgsattributetablemodel.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -499,14 +499,11 @@ void QgsAttributeTableModel::incomingChangeLayout()
499499

500500
void QgsAttributeTableModel::executeAction( int action, const QModelIndex &idx ) const
501501
{
502-
QList< QPair<QString, QString> > attributes;
502+
QgsAttributeMap attributes;
503503

504504
for ( int i = 0; i < mAttributes.size(); i++ )
505505
{
506-
attributes << QPair<QString, QString>(
507-
mLayer->pendingFields()[ mAttributes[i] ].name(),
508-
data( index( idx.row(), i ), Qt::EditRole ).toString()
509-
);
506+
attributes.insert( i, data( index( idx.row(), i ), Qt::EditRole ) );
510507
}
511508

512509
mLayer->actions()->doAction( action, attributes, fieldIdx( idx.column() ) );

‎src/app/qgsfeatureaction.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/***************************************************************************
2+
qgsfeatureaction.cpp - description
3+
-------------------
4+
begin : 2010-09-20
5+
copyright : (C) 2010 by Jürgen E. Fischer
6+
email : jef at norbit dot de
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
/* $Id$ */
18+
19+
#include "qgsfeatureaction.h"
20+
#include "qgsvectorlayer.h"
21+
#include "qgsidentifyresults.h"
22+
23+
QgsFeatureAction::QgsFeatureAction( const QString &name, QgsIdentifyResults *results, QgsVectorLayer *vl, int action, QTreeWidgetItem *featItem )
24+
: QAction( name, results )
25+
, mLayer( vl )
26+
, mAction( action )
27+
{
28+
results->retrieveAttributes( featItem, mAttributes, mIdx );
29+
}
30+
31+
QgsFeatureAction::QgsFeatureAction( const QString &name, QgsFeature &f, QgsVectorLayer *layer, int action, QObject *parent )
32+
: QAction( name, parent )
33+
, mLayer( layer )
34+
, mAction( action )
35+
{
36+
mAttributes = f.attributeMap();
37+
}
38+
39+
void QgsFeatureAction::execute()
40+
{
41+
mLayer->actions()->doAction( mAction, mAttributes, mIdx );
42+
}

‎src/app/qgsfeatureaction.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/***************************************************************************
2+
qgsfeatureaction.h - description
3+
------------------
4+
begin : 2010-09-20
5+
copyright : (C) 2010 by Jürgen E. Fischer
6+
email : jef at norbit dot de
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
/* $Id$ */
18+
#ifndef QGSFEATUREACTION_H
19+
#define QGSFEATUREACTION_H
20+
21+
#include "qgsfeature.h"
22+
23+
#include <QList>
24+
#include <QPair>
25+
#include <QAction>
26+
27+
class QgsIdentifyResults;
28+
class QgsVectorLayer;
29+
class QTreeWidgetItem;
30+
31+
class QgsFeatureAction : public QAction
32+
{
33+
Q_OBJECT
34+
35+
public:
36+
QgsFeatureAction( const QString &name, QgsFeature &f, QgsVectorLayer *vl, int action, QObject *parent );
37+
QgsFeatureAction( const QString &name, QgsIdentifyResults *results, QgsVectorLayer *vl, int action, QTreeWidgetItem *featItem );
38+
39+
public slots:
40+
void execute();
41+
42+
private:
43+
QgsVectorLayer *mLayer;
44+
int mAction;
45+
int mIdx;
46+
QgsAttributeMap mAttributes;
47+
};
48+
49+
#endif

‎src/app/qgsidentifyresults.cpp

Lines changed: 140 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "qgsattributedialog.h"
2929
#include "qgsmapcanvas.h"
3030
#include "qgsattributeaction.h"
31+
#include "qgsfeatureaction.h"
3132

3233
#include <QCloseEvent>
3334
#include <QLabel>
@@ -44,20 +45,6 @@
4445

4546
#include "qgslogger.h"
4647

47-
QgsFeatureAction::QgsFeatureAction( const QString &name, QgsIdentifyResults *results, QgsVectorLayer *vl, int action, QTreeWidgetItem *featItem )
48-
: QAction( name, results )
49-
, mLayer( vl )
50-
, mAction( action )
51-
{
52-
QList< QPair<QString, QString> > attributes;
53-
results->retrieveAttributes( featItem, mAttributes, mIdx );
54-
}
55-
56-
void QgsFeatureAction::execute()
57-
{
58-
mLayer->actions()->doAction( mAction, mAttributes, mIdx );
59-
}
60-
6148
class QgsIdentifyResultsDock : public QDockWidget
6249
{
6350
public:
@@ -82,9 +69,9 @@ class QgsIdentifyResultsDock : public QDockWidget
8269
// actions (if any) [userrole: "actions"]
8370
// edit [userrole: "edit"]
8471
// action [userrole: "action", idx]
85-
// name value
86-
// name value
87-
// name value
72+
// displayname [userroles: fieldIdx, original name] displayvalue [userrole: original value]
73+
// displayname [userroles: fieldIdx, original name] displayvalue [userrole: original value]
74+
// displayname [userroles: fieldIdx, original name] displayvalue [userrole: original value]
8875
// feature
8976
// derived attributes (if any)
9077
// name value
@@ -145,61 +132,74 @@ QTreeWidgetItem *QgsIdentifyResults::layerItem( QObject *layer )
145132
return 0;
146133
}
147134

148-
void QgsIdentifyResults::addFeature( QgsMapLayer *layer, int fid,
149-
QString displayField, QString displayValue,
150-
const QMap<QString, QString> &attributes,
135+
void QgsIdentifyResults::addFeature( QgsVectorLayer *vlayer, int fid,
136+
const QgsAttributeMap &attributes,
151137
const QMap<QString, QString> &derivedAttributes )
152138
{
153-
QTreeWidgetItem *layItem = layerItem( layer );
154-
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
155-
QgsRasterLayer *rlayer = qobject_cast<QgsRasterLayer *>( layer );
139+
QTreeWidgetItem *layItem = layerItem( vlayer );
156140

157141
if ( layItem == 0 )
158142
{
159-
layItem = new QTreeWidgetItem( QStringList() << QString::number( lstResults->topLevelItemCount() ) << layer->name() );
160-
layItem->setData( 0, Qt::UserRole, QVariant::fromValue( qobject_cast<QObject *>( layer ) ) );
143+
layItem = new QTreeWidgetItem( QStringList() << QString::number( lstResults->topLevelItemCount() ) << vlayer->name() );
144+
layItem->setData( 0, Qt::UserRole, QVariant::fromValue( qobject_cast<QObject *>( vlayer ) ) );
161145
lstResults->addTopLevelItem( layItem );
162146

163-
if ( vlayer )
164-
{
165-
connect( vlayer, SIGNAL( layerDeleted() ), this, SLOT( layerDestroyed() ) );
166-
connect( vlayer, SIGNAL( layerCrsChanged() ), this, SLOT( layerDestroyed() ) );
167-
connect( vlayer, SIGNAL( featureDeleted( int ) ), this, SLOT( featureDeleted( int ) ) );
168-
connect( vlayer, SIGNAL( attributeValueChanged( int, int, const QVariant & ) ), this, SLOT( attributeValueChanged( int, int, const QVariant & ) ) );
169-
connect( vlayer, SIGNAL( editingStarted() ), this, SLOT( editingToggled() ) );
170-
connect( vlayer, SIGNAL( editingStopped() ), this, SLOT( editingToggled() ) );
171-
}
172-
else
173-
{
174-
connect( layer, SIGNAL( destroyed() ), this, SLOT( layerDestroyed() ) );
175-
connect( layer, SIGNAL( layerCrsChanged() ), this, SLOT( layerDestroyed() ) );
176-
}
147+
connect( vlayer, SIGNAL( layerDeleted() ), this, SLOT( layerDestroyed() ) );
148+
connect( vlayer, SIGNAL( layerCrsChanged() ), this, SLOT( layerDestroyed() ) );
149+
connect( vlayer, SIGNAL( featureDeleted( int ) ), this, SLOT( featureDeleted( int ) ) );
150+
connect( vlayer, SIGNAL( attributeValueChanged( int, int, const QVariant & ) ), this, SLOT( attributeValueChanged( int, int, const QVariant & ) ) );
151+
connect( vlayer, SIGNAL( editingStarted() ), this, SLOT( editingToggled() ) );
152+
connect( vlayer, SIGNAL( editingStopped() ), this, SLOT( editingToggled() ) );
177153
}
178154

179-
QTreeWidgetItem *featItem = new QTreeWidgetItem( QStringList() << displayField << displayValue );
155+
QTreeWidgetItem *featItem = new QTreeWidgetItem;
180156
featItem->setData( 0, Qt::UserRole, fid );
181157
layItem->addChild( featItem );
182158

183-
if ( !rlayer || rlayer->providerKey() != "wms" )
159+
for ( QgsAttributeMap::const_iterator it = attributes.begin(); it != attributes.end(); it++ )
184160
{
185-
for ( QMap<QString, QString>::const_iterator it = attributes.begin(); it != attributes.end(); it++ )
161+
QTreeWidgetItem *attrItem = new QTreeWidgetItem( QStringList() << QString::number( it.key() ) << it.value().toString() );
162+
163+
const QgsFieldMap &fields = vlayer->pendingFields();
164+
165+
QgsFieldMap::const_iterator fit = fields.find( it.key() );
166+
if ( fit == fields.constEnd() )
186167
{
187-
QTreeWidgetItem *attrItem = new QTreeWidgetItem( QStringList() << it.key() << it.value() );
188-
if ( vlayer )
189-
{
190-
attrItem->setData( 0, Qt::UserRole, vlayer->fieldNameIndex( it.key() ) );
191-
}
192-
featItem->addChild( attrItem );
168+
delete attrItem;
169+
continue;
193170
}
194-
}
195-
else
196-
{
197-
QTreeWidgetItem *attrItem = new QTreeWidgetItem( QStringList() << attributes.begin().key() << "" );
198-
featItem->addChild( attrItem );
199171

200-
QTextBrowser *tb = new QTextBrowser( attrItem->treeWidget() );
201-
tb->setHtml( attributes.begin().value() );
202-
attrItem->treeWidget()->setItemWidget( attrItem, 1, tb );
172+
attrItem->setData( 0, Qt::DisplayRole, vlayer->attributeDisplayName( it.key() ) );
173+
attrItem->setData( 0, Qt::UserRole, fit->name() );
174+
attrItem->setData( 0, Qt::UserRole + 1, it.key() );
175+
176+
QVariant value = it.value();
177+
attrItem->setData( 1, Qt::UserRole, value );
178+
179+
switch ( vlayer->editType( it.key() ) )
180+
{
181+
case QgsVectorLayer::Hidden:
182+
// skip the item
183+
delete attrItem;
184+
continue;
185+
186+
case QgsVectorLayer::ValueMap:
187+
value = vlayer->valueMap( it.key() ).key( it->toString(), QString( "(%1)" ).arg( it->toString() ) );
188+
break;
189+
190+
default:
191+
break;
192+
}
193+
194+
attrItem->setData( 1, Qt::DisplayRole, value );
195+
196+
if ( fit->name() == vlayer->displayField() )
197+
{
198+
featItem->setText( 0, attrItem->text( 0 ) );
199+
featItem->setText( 1, attrItem->text( 1 ) );
200+
}
201+
202+
featItem->addChild( attrItem );
203203
}
204204

205205
if ( derivedAttributes.size() >= 0 )
@@ -214,33 +214,81 @@ void QgsIdentifyResults::addFeature( QgsMapLayer *layer, int fid,
214214
}
215215
}
216216

217-
if ( vlayer )
217+
QTreeWidgetItem *actionItem = new QTreeWidgetItem( QStringList() << tr( "(Actions)" ) );
218+
actionItem->setData( 0, Qt::UserRole, "actions" );
219+
featItem->addChild( actionItem );
220+
221+
QTreeWidgetItem *editItem = new QTreeWidgetItem( QStringList() << "" << ( vlayer->isEditable() ? tr( "Edit feature form" ) : tr( "View feature form" ) ) );
222+
editItem->setIcon( 0, QgisApp::getThemeIcon( vlayer->isEditable() ? "/mIconEditable.png" : "/mIconEditable.png" ) );
223+
editItem->setData( 0, Qt::UserRole, "edit" );
224+
actionItem->addChild( editItem );
225+
226+
for ( int i = 0; i < vlayer->actions()->size(); i++ )
218227
{
219-
QTreeWidgetItem *actionItem = new QTreeWidgetItem( QStringList() << tr( "(Actions)" ) );
220-
actionItem->setData( 0, Qt::UserRole, "actions" );
221-
featItem->addChild( actionItem );
228+
const QgsAction &action = vlayer->actions()->at( i );
222229

223-
QTreeWidgetItem *editItem = new QTreeWidgetItem( QStringList() << "" << ( vlayer->isEditable() ? tr( "Edit feature form" ) : tr( "View feature form" ) ) );
224-
editItem->setIcon( 0, QgisApp::getThemeIcon( vlayer->isEditable() ? "/mIconEditable.png" : "/mIconEditable.png" ) );
225-
editItem->setData( 0, Qt::UserRole, "edit" );
226-
actionItem->addChild( editItem );
230+
if ( !action.runable() )
231+
continue;
227232

228-
for ( int i = 0; i < vlayer->actions()->size(); i++ )
229-
{
230-
const QgsAction &action = vlayer->actions()->at( i );
233+
QTreeWidgetItem *twi = new QTreeWidgetItem( QStringList() << "" << action.name() );
234+
twi->setIcon( 0, QgisApp::getThemeIcon( "/mAction.png" ) );
235+
twi->setData( 0, Qt::UserRole, "action" );
236+
twi->setData( 0, Qt::UserRole + 1, QVariant::fromValue( i ) );
237+
actionItem->addChild( twi );
238+
}
231239

232-
if ( !action.runable() )
233-
continue;
240+
highlightFeature( featItem );
241+
}
242+
243+
void QgsIdentifyResults::addFeature( QgsRasterLayer *layer,
244+
QString label,
245+
const QMap<QString, QString> &attributes,
246+
const QMap<QString, QString> &derivedAttributes )
247+
{
248+
QTreeWidgetItem *layItem = layerItem( layer );
249+
250+
if ( layItem == 0 )
251+
{
252+
layItem = new QTreeWidgetItem( QStringList() << QString::number( lstResults->topLevelItemCount() ) << layer->name() );
253+
layItem->setData( 0, Qt::UserRole, QVariant::fromValue( qobject_cast<QObject *>( layer ) ) );
254+
lstResults->addTopLevelItem( layItem );
255+
256+
connect( layer, SIGNAL( destroyed() ), this, SLOT( layerDestroyed() ) );
257+
connect( layer, SIGNAL( layerCrsChanged() ), this, SLOT( layerDestroyed() ) );
258+
}
259+
260+
QTreeWidgetItem *featItem = new QTreeWidgetItem( QStringList() << label << "" );
261+
featItem->setData( 0, Qt::UserRole, -1 );
262+
layItem->addChild( featItem );
263+
264+
if ( layer && layer->providerKey() == "wms" )
265+
{
266+
QTreeWidgetItem *attrItem = new QTreeWidgetItem( QStringList() << attributes.begin().key() << "" );
267+
featItem->addChild( attrItem );
234268

235-
QTreeWidgetItem *twi = new QTreeWidgetItem( QStringList() << "" << action.name() );
236-
twi->setIcon( 0, QgisApp::getThemeIcon( "/mAction.png" ) );
237-
twi->setData( 0, Qt::UserRole, "action" );
238-
twi->setData( 0, Qt::UserRole + 1, QVariant::fromValue( i ) );
239-
actionItem->addChild( twi );
269+
QTextBrowser *tb = new QTextBrowser( attrItem->treeWidget() );
270+
tb->setHtml( attributes.begin().value() );
271+
attrItem->treeWidget()->setItemWidget( attrItem, 1, tb );
272+
}
273+
else
274+
{
275+
for ( QMap<QString, QString>::const_iterator it = attributes.begin(); it != attributes.end(); it++ )
276+
{
277+
featItem->addChild( new QTreeWidgetItem( QStringList() << it.key() << it.value() ) );
240278
}
241279
}
242280

243-
highlightFeature( featItem );
281+
if ( derivedAttributes.size() >= 0 )
282+
{
283+
QTreeWidgetItem *derivedItem = new QTreeWidgetItem( QStringList() << tr( "(Derived)" ) );
284+
derivedItem->setData( 0, Qt::UserRole, "derived" );
285+
featItem->addChild( derivedItem );
286+
287+
for ( QMap< QString, QString>::const_iterator it = derivedAttributes.begin(); it != derivedAttributes.end(); it++ )
288+
{
289+
derivedItem->addChild( new QTreeWidgetItem( QStringList() << it.key() << it.value() ) );
290+
}
291+
}
244292
}
245293

246294
void QgsIdentifyResults::editingToggled()
@@ -484,7 +532,7 @@ void QgsIdentifyResults::deactivate()
484532
void QgsIdentifyResults::doAction( QTreeWidgetItem *item, int action )
485533
{
486534
int idx;
487-
QList< QPair<QString, QString> > attributes;
535+
QgsAttributeMap attributes;
488536
QTreeWidgetItem *featItem = retrieveAttributes( item, attributes, idx );
489537
if ( !featItem )
490538
return;
@@ -570,7 +618,7 @@ QgsVectorLayer *QgsIdentifyResults::vectorLayer( QTreeWidgetItem *item )
570618
}
571619

572620

573-
QTreeWidgetItem *QgsIdentifyResults::retrieveAttributes( QTreeWidgetItem *item, QList< QPair<QString, QString> > &attributes, int &idx )
621+
QTreeWidgetItem *QgsIdentifyResults::retrieveAttributes( QTreeWidgetItem *item, QgsAttributeMap &attributes, int &idx )
574622
{
575623
QTreeWidgetItem *featItem = featureItem( item );
576624
if ( !featItem )
@@ -585,8 +633,8 @@ QTreeWidgetItem *QgsIdentifyResults::retrieveAttributes( QTreeWidgetItem *item,
585633
if ( item->childCount() > 0 )
586634
continue;
587635
if ( item == lstResults->currentItem() )
588-
idx = attributes.size();
589-
attributes << QPair<QString, QString>( item->data( 0, Qt::DisplayRole ).toString(), item->data( 1, Qt::DisplayRole ).toString() );
636+
idx = item->data( 0, Qt::UserRole + 1 ).toInt();
637+
attributes.insert( item->data( 0, Qt::UserRole + 1 ).toInt(), item->data( 1, Qt::DisplayRole ) );
590638
}
591639

592640
return featItem;
@@ -939,13 +987,23 @@ void QgsIdentifyResults::copyFeatureAttributes()
939987
QClipboard *clipboard = QApplication::clipboard();
940988
QString text;
941989

990+
QgsVectorLayer *vlayer = vectorLayer( lstResults->currentItem() );
991+
if ( !vlayer )
992+
return;
993+
942994
int idx;
943-
QList< QPair<QString, QString> > attributes;
995+
QgsAttributeMap attributes;
944996
retrieveAttributes( lstResults->currentItem(), attributes, idx );
945997

946-
for ( QList< QPair<QString, QString> >::iterator it = attributes.begin(); it != attributes.end(); it++ )
998+
const QgsFieldMap &fields = vlayer->pendingFields();
999+
1000+
for ( QgsAttributeMap::const_iterator it = attributes.begin(); it != attributes.end(); it++ )
9471001
{
948-
text += QString( "%1: %2\n" ).arg( it->first ).arg( it->second );
1002+
QgsFieldMap::const_iterator fit = fields.find( it.key() );
1003+
if ( fit == fields.constEnd() )
1004+
continue;
1005+
1006+
text += QString( "%1: %2\n" ).arg( fit->name() ).arg( it.value().toString() );
9491007
}
9501008

9511009
QgsDebugMsg( QString( "set clipboard: %1" ).arg( text ) );

‎src/app/qgsidentifyresults.h

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "ui_qgsidentifyresultsbase.h"
2323
#include "qgsattributeaction.h"
2424
#include "qgscontexthelp.h"
25+
#include "qgsfeature.h"
2526

2627
#include <QWidget>
2728
#include <QList>
@@ -31,8 +32,8 @@ class QTreeWidgetItem;
3132
class QAction;
3233
class QMenu;
3334

34-
class QgsMapLayer;
3535
class QgsVectorLayer;
36+
class QgsRasterLayer;
3637
class QgsRubberBand;
3738
class QgsMapCanvas;
3839
class QDockWidget;
@@ -53,9 +54,13 @@ class QgsIdentifyResults: public QDialog, private Ui::QgsIdentifyResultsBase
5354

5455
~QgsIdentifyResults();
5556

56-
/** Add add feature */
57-
void addFeature( QgsMapLayer *layer, int fid,
58-
QString displayField, QString displayValue,
57+
/** Add add feature from vector layer */
58+
void addFeature( QgsVectorLayer *layer, int fid,
59+
const QgsAttributeMap &attributes,
60+
const QMap< QString, QString > &derivedAttributes );
61+
62+
/** Add add feature from other layer */
63+
void addFeature( QgsRasterLayer *layer, QString label,
5964
const QMap< QString, QString > &attributes,
6065
const QMap< QString, QString > &derivedAttributes );
6166

@@ -104,7 +109,7 @@ class QgsIdentifyResults: public QDialog, private Ui::QgsIdentifyResultsBase
104109
/* Item in tree was clicked */
105110
void itemClicked( QTreeWidgetItem *lvi, int column );
106111

107-
QTreeWidgetItem *retrieveAttributes( QTreeWidgetItem *item, QList< QPair<QString, QString> > &attributes, int &currentIdx );
112+
QTreeWidgetItem *retrieveAttributes( QTreeWidgetItem *item, QgsAttributeMap &attributes, int &currentIdx );
108113

109114
void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); }
110115

@@ -132,21 +137,4 @@ class QgsIdentifyResults: public QDialog, private Ui::QgsIdentifyResultsBase
132137
QDockWidget *mDock;
133138
};
134139

135-
class QgsFeatureAction : public QAction
136-
{
137-
Q_OBJECT
138-
139-
public:
140-
QgsFeatureAction( const QString &name, QgsIdentifyResults *results, QgsVectorLayer *vl, int action, QTreeWidgetItem *featItem );
141-
142-
public slots:
143-
void execute();
144-
145-
private:
146-
QgsVectorLayer *mLayer;
147-
int mAction;
148-
int mIdx;
149-
QList< QPair<QString, QString> > mAttributes;
150-
};
151-
152140
#endif

‎src/app/qgsmaptoolidentify.cpp

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,6 @@ bool QgsMapToolIdentify::identifyVectorLayer( QgsVectorLayer *layer, int x, int
209209
identifyValue = QGis::DEFAULT_IDENTIFY_RADIUS;
210210

211211
int featureCount = 0;
212-
const QgsFieldMap& fields = layer->pendingFields();
213212

214213
// init distance/area calculator
215214
QgsDistanceArea calc;
@@ -254,37 +253,7 @@ bool QgsMapToolIdentify::identifyVectorLayer( QgsVectorLayer *layer, int x, int
254253
featureCount++;
255254

256255
int fid = f_it->id();
257-
QString displayField, displayValue;
258-
QMap<QString, QString> attributes, derivedAttributes;
259-
260-
const QgsAttributeMap& attr = f_it->attributeMap();
261-
262-
for ( QgsAttributeMap::const_iterator it = attr.begin(); it != attr.end(); ++it )
263-
{
264-
QString attributeName = layer->attributeDisplayName( it.key() );
265-
QString attributeValue = it->isNull() ? "NULL" : it->toString();
266-
267-
switch ( layer->editType( it.key() ) )
268-
{
269-
case QgsVectorLayer::Hidden:
270-
continue;
271-
272-
case QgsVectorLayer::ValueMap:
273-
attributeValue = layer->valueMap( it.key() ).key( it->toString(), QString( "(%1)" ).arg( it->toString() ) );
274-
break;
275-
276-
default:
277-
break;
278-
}
279-
280-
if ( fields[it.key()].name() == layer->displayField() )
281-
{
282-
displayField = attributeName;
283-
displayValue = attributeValue;
284-
}
285-
286-
attributes.insert( attributeName, attributeValue );
287-
}
256+
QMap<QString, QString> derivedAttributes;
288257

289258
// Calculate derived attributes and insert:
290259
// measure distance or area depending on geometry type
@@ -331,7 +300,7 @@ bool QgsMapToolIdentify::identifyVectorLayer( QgsVectorLayer *layer, int x, int
331300

332301
derivedAttributes.insert( tr( "feature id" ), fid < 0 ? tr( "new feature" ) : QString::number( fid ) );
333302

334-
results()->addFeature( layer, fid, displayField, displayValue, attributes, derivedAttributes );
303+
results()->addFeature( layer, fid, f_it->attributeMap(), derivedAttributes );
335304
}
336305

337306
QgsDebugMsg( "Feature count on identify: " + QString::number( featureCount ) );
@@ -392,7 +361,7 @@ bool QgsMapToolIdentify::identifyRasterLayer( QgsRasterLayer *layer, int x, int
392361
if ( res )
393362
{
394363
derivedAttributes.insert( tr( "(clicked coordinate)" ), idPoint.toString() );
395-
results()->addFeature( layer, -1, type, "", attributes, derivedAttributes );
364+
results()->addFeature( layer, type, attributes, derivedAttributes );
396365
}
397366

398367
return res;

‎src/core/qgsattributeaction.cpp

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#include "qgsattributeaction.h"
3232
#include "qgsrunprocess.h"
33+
#include "qgsvectorlayer.h"
3334

3435
static const char * const ident_ = "$Id$";
3536

@@ -38,7 +39,7 @@ void QgsAttributeAction::addAction( QgsAction::ActionType type, QString name, QS
3839
mActions << QgsAction( type, name, action, capture );
3940
}
4041

41-
void QgsAttributeAction::doAction( int index, const QList< QPair<QString, QString> > &values,
42+
void QgsAttributeAction::doAction( int index, const QgsAttributeMap &attributes,
4243
int defaultValueIndex, void ( *executePython )( const QString & ) )
4344
{
4445
if ( index < 0 || index >= size() )
@@ -61,7 +62,7 @@ void QgsAttributeAction::doAction( int index, const QList< QPair<QString, QStrin
6162

6263
// The QgsRunProcess instance created by this static function
6364
// deletes itself when no longer needed.
64-
QString expandedAction = expandAction( action.action(), values, defaultValueIndex );
65+
QString expandedAction = expandAction( action.action(), attributes, defaultValueIndex );
6566
if ( action.type() == QgsAction::GenericPython )
6667
{
6768
if ( executePython )
@@ -79,7 +80,7 @@ void QgsAttributeAction::doAction( int index, const QList< QPair<QString, QStrin
7980
}
8081
}
8182

82-
QString QgsAttributeAction::expandAction( QString action, const QList< QPair<QString, QString> > &values,
83+
QString QgsAttributeAction::expandAction( QString action, const QgsAttributeMap &attributes,
8384
uint clickedOnValue )
8485
{
8586
// This function currently replaces all %% characters in the action
@@ -98,19 +99,29 @@ QString QgsAttributeAction::expandAction( QString action, const QList< QPair<QSt
9899
// for the actual substitutions.
99100

100101
QString expanded_action;
101-
if ( clickedOnValue >= 0 && clickedOnValue < static_cast<unsigned int>( values.size() ) )
102-
expanded_action = action.replace( "%%", values[clickedOnValue].second );
102+
if ( clickedOnValue >= 0 && attributes.contains( clickedOnValue ) )
103+
expanded_action = action.replace( "%%", attributes[clickedOnValue].toString() );
103104
else
104105
expanded_action = action;
105106

106-
for ( int i = 0; i < values.size(); ++i )
107+
const QgsFieldMap &fields = mLayer->pendingFields();
108+
109+
for ( QgsAttributeMap::const_iterator it = attributes.begin(); it != attributes.end(); it++ )
107110
{
108-
// Check for a replace a quoted version and a non-quoted version.
109-
QString to_replace_1 = "[%" + values[i].first + "]";
110-
QString to_replace_2 = "%" + values[i].first;
111+
QgsFieldMap::const_iterator fit = fields.find( it.key() );
112+
if ( fit == fields.constEnd() )
113+
continue;
111114

112-
expanded_action = expanded_action.replace( to_replace_1, values[i].second );
113-
expanded_action = expanded_action.replace( to_replace_2, values[i].second );
115+
// Check for a replace a quoted version and a non-quoted version.
116+
QString to_replace_1 = "[%" + fit->name() + "]";
117+
QString to_replace_2 = "%" + fit->name() + "%";
118+
QString to_replace_3 = "%" + mLayer->attributeDisplayName( it.key() ) + "%";
119+
QString to_replace_4 = "[%" + mLayer->attributeDisplayName( it.key() ) + "%]";
120+
121+
expanded_action = expanded_action.replace( to_replace_1, it.value().toString() );
122+
expanded_action = expanded_action.replace( to_replace_2, it.value().toString() );
123+
expanded_action = expanded_action.replace( to_replace_3, it.value().toString() );
124+
expanded_action = expanded_action.replace( to_replace_4, it.value().toString() );
114125
}
115126

116127
return expanded_action;

‎src/core/qgsattributeaction.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,13 @@
2727

2828
#include <QString>
2929
#include <QObject>
30-
#include <QList>
31-
#include <QPair>
30+
31+
#include <qgsfeature.h>
3232

3333
class QDomNode;
3434
class QDomDocument;
3535
class QgsPythonUtils;
36+
class QgsVectorLayer;
3637

3738
/** \ingroup core
3839
* Utility class that encapsulates an action based on vector attributes.
@@ -95,7 +96,7 @@ class CORE_EXPORT QgsAttributeAction
9596
{
9697
public:
9798
//! Constructor
98-
QgsAttributeAction() {}
99+
QgsAttributeAction( QgsVectorLayer *layer ) : mLayer( layer ) {}
99100

100101
//! Destructor
101102
virtual ~QgsAttributeAction() {}
@@ -111,16 +112,19 @@ class CORE_EXPORT QgsAttributeAction
111112
// index into values which indicates which value in the values vector
112113
// is to be used if the action has a default placeholder.
113114
// @note parameter executePython deprecated (and missing in python binding)
114-
void doAction( int index, const QList< QPair<QString, QString> > &values,
115-
int defaultValueIndex = 0, void ( *executePython )( const QString & ) = 0 );
115+
void doAction( int index,
116+
const QgsAttributeMap &attributes,
117+
int defaultValueIndex = 0,
118+
void ( *executePython )( const QString & ) = 0 );
116119

117120
//! Removes all actions
118121
void clearActions() { mActions.clear(); }
119122

120123
//! Expands the given action, replacing all %'s with the value as
121124
// given.
122-
static QString expandAction( QString action, const QList< QPair<QString, QString> > &values,
123-
uint defaultValueIndex );
125+
QString expandAction( QString action,
126+
const QgsAttributeMap &attributes,
127+
uint defaultValueIndex );
124128

125129
//! Writes the actions out in XML format
126130
bool writeXML( QDomNode& layer_node, QDomDocument& doc ) const;
@@ -136,6 +140,7 @@ class CORE_EXPORT QgsAttributeAction
136140

137141
private:
138142
QList<QgsAction> mActions;
143+
QgsVectorLayer *mLayer;
139144
static void ( *smPythonExecute )( const QString & );
140145
};
141146

‎src/core/qgsfeature.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,24 +23,24 @@ email : sherman at mrcc.com
2323
*/
2424

2525
QgsFeature::QgsFeature( int id, QString typeName )
26-
: mFid( id ),
27-
mGeometry( 0 ),
28-
mOwnsGeometry( 0 ),
29-
mValid( false ),
30-
mDirty( 0 ),
31-
mTypeName( typeName )
26+
: mFid( id )
27+
, mGeometry( 0 )
28+
, mOwnsGeometry( 0 )
29+
, mValid( false )
30+
, mDirty( 0 )
31+
, mTypeName( typeName )
3232
{
3333
// NOOP
3434
}
3535

3636
QgsFeature::QgsFeature( QgsFeature const & rhs )
37-
: mFid( rhs.mFid ),
38-
mAttributes( rhs.mAttributes ),
39-
mGeometry( 0 ),
40-
mOwnsGeometry( false ),
41-
mValid( rhs.mValid ),
42-
mDirty( rhs.mDirty ),
43-
mTypeName( rhs.mTypeName )
37+
: mFid( rhs.mFid )
38+
, mAttributes( rhs.mAttributes )
39+
, mGeometry( 0 )
40+
, mOwnsGeometry( false )
41+
, mValid( rhs.mValid )
42+
, mDirty( rhs.mDirty )
43+
, mTypeName( rhs.mTypeName )
4444
{
4545

4646
// copy embedded geometry

‎src/core/qgsvectorlayer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ QgsVectorLayer::QgsVectorLayer( QString vectorLayerPath,
111111
mVertexMarkerOnlyForSelection( false ),
112112
mFetching( false )
113113
{
114-
mActions = new QgsAttributeAction;
114+
mActions = new QgsAttributeAction( this );
115115

116116
// if we're given a provider type, try to create and bind one to this layer
117117
if ( ! mProviderKey.isEmpty() )

0 commit comments

Comments
 (0)
Please sign in to comment.