Skip to content

Commit 5af78ab

Browse files
committedSep 22, 2015
[GRASS] vector attributes editing
1 parent a3b43b4 commit 5af78ab

8 files changed

+783
-432
lines changed
 

‎src/providers/grass/qgsgrassfeatureiterator.cpp

Lines changed: 18 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -654,46 +654,27 @@ void QgsGrassFeatureIterator::setFeatureAttributes( int cat, QgsFeature *feature
654654
void QgsGrassFeatureIterator::setFeatureAttributes( int cat, QgsFeature *feature, const QgsAttributeList& attlist, QgsGrassVectorMap::TopoSymbol symbol )
655655
{
656656
QgsDebugMsgLevel( QString( "setFeatureAttributes cat = %1 symbol = %2" ).arg( cat ).arg( symbol ), 3 );
657-
int nFields = mSource->mLayer->fields().size();
658-
int nAttributes = nFields;
659-
if ( mSource->mEditing )
660-
{
661-
//nAttributes += 1;
662-
}
663-
feature->initAttributes( nAttributes );
664-
if ( mSource->mLayer->hasTable() )
657+
feature->initAttributes( mSource->mLayer->fields().size() );
658+
659+
for ( QgsAttributeList::const_iterator iter = attlist.begin(); iter != attlist.end(); ++iter )
665660
{
666-
for ( QgsAttributeList::const_iterator iter = attlist.begin(); iter != attlist.end(); ++iter )
661+
if ( *iter == mSource->mSymbolAttributeIndex )
667662
{
668-
if ( !mSource->mLayer->attributes().contains( cat ) )
669-
{
670-
QgsDebugMsgLevel( QString( "cat %1 not found in attributes" ).arg( cat ), 3 );
671-
}
672-
QVariant value = mSource->mLayer->attributes().value( cat ).value( *iter );
673-
if ( value.type() == QVariant::ByteArray )
674-
{
675-
value = QVariant( mSource->mEncoding->toUnicode( value.toByteArray() ) );
676-
}
677-
QgsDebugMsgLevel( QString( "iter = %1 value = %2" ).arg( *iter ).arg( value.toString() ), 3 );
678-
feature->setAttribute( *iter, value );
663+
continue;
679664
}
665+
QVariant value = mSource->mLayer->attribute( cat, *iter );
666+
if ( value.type() == QVariant::ByteArray )
667+
{
668+
value = QVariant( mSource->mEncoding->toUnicode( value.toByteArray() ) );
669+
}
670+
QgsDebugMsgLevel( QString( "iter = %1 value = %2" ).arg( *iter ).arg( value.toString() ), 3 );
671+
feature->setAttribute( *iter, value );
680672
}
681-
else if ( attlist.contains( 0 ) ) // no table and first attribute requested -> add cat
682-
{
683-
QgsDebugMsgLevel( QString( "no table, set attribute 0 to cat %1" ).arg( cat ), 3 );
684-
feature->setAttribute( 0, QVariant( cat ) );
685-
}
686-
else
687-
{
688-
QgsDebugMsgLevel( "no table, cat not requested", 3 );
689-
}
690-
if ( mSource->mEditing )
673+
674+
if ( mSource->mEditing && attlist.contains( mSource->mSymbolAttributeIndex ) )
691675
{
692-
// append topo_symbol
693-
int idx = nAttributes - 1;
694-
QgsDebugMsgLevel( QString( "set attribute %1 to symbol %2" ).arg( idx ).arg( symbol ), 3 );
695-
//feature->setAttribute( 0, QVariant( symbol ) ); // debug
696-
feature->setAttribute( idx, QVariant( symbol ) );
676+
QgsDebugMsgLevel( QString( "set attribute %1 to symbol %2" ).arg( mSource->mSymbolAttributeIndex ).arg( symbol ), 3 );
677+
feature->setAttribute( mSource->mSymbolAttributeIndex, QVariant( symbol ) );
697678
}
698679
}
699680

@@ -709,15 +690,9 @@ QgsGrassFeatureSource::QgsGrassFeatureSource( const QgsGrassProvider* p )
709690
, mEncoding( p->mEncoding )
710691
, mEditing( p->mEditBuffer )
711692
{
712-
713693
Q_ASSERT( mLayer );
714-
#if 0
715-
if ( mEditing )
716-
{
717-
mFields.clear();
718-
mFields.append( QgsField( "topo_symbol", QVariant::Int, "int" ) );
719-
}
720-
#endif
694+
695+
mSymbolAttributeIndex = mFields.indexFromName( QgsGrassVectorMap::topoSymbolFieldName() );
721696
}
722697

723698
QgsGrassFeatureSource::~QgsGrassFeatureSource()

‎src/providers/grass/qgsgrassfeatureiterator.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ class QgsGrassFeatureSource : public QgsAbstractFeatureSource
6363
QTextCodec* mEncoding;
6464

6565
bool mEditing; // Standard QGIS editing mode
66+
67+
int mSymbolAttributeIndex;
68+
6669
friend class QgsGrassFeatureIterator;
6770
};
6871

‎src/providers/grass/qgsgrassprovider.cpp

Lines changed: 111 additions & 322 deletions
Large diffs are not rendered by default.

‎src/providers/grass/qgsgrassprovider.h

Lines changed: 8 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,9 @@ class GRASS_LIB_EXPORT QgsGrassProvider : public QgsVectorDataProvider
129129
// TODO: implement also these functions but disable during manual layer editing
130130
virtual bool addFeatures( QgsFeatureList & flist ) override { Q_UNUSED( flist ); return true; }
131131
virtual bool deleteFeatures( const QgsFeatureIds & id ) override { Q_UNUSED( id ); return true; }
132-
virtual bool addAttributes( const QList<QgsField> &attributes ) override { Q_UNUSED( attributes ); return true; }
133-
virtual bool deleteAttributes( const QgsAttributeIds &attributes ) override { Q_UNUSED( attributes ); return true; }
134-
virtual bool changeAttributeValues( const QgsChangedAttributesMap & attr_map ) override { Q_UNUSED( attr_map ); return true; }
132+
virtual bool addAttributes( const QList<QgsField> &attributes ) override;
133+
virtual bool deleteAttributes( const QgsAttributeIds &attributes ) override;
134+
virtual bool changeAttributeValues( const QgsChangedAttributesMap & attr_map ) override { Q_UNUSED( attr_map ); return true; }
135135
virtual bool changeGeometryValues( QgsGeometryMap & geometry_map ) override { Q_UNUSED( geometry_map ); return true; }
136136

137137

@@ -332,57 +332,6 @@ class GRASS_LIB_EXPORT QgsGrassProvider : public QgsVectorDataProvider
332332
*/
333333
int dbLinkField( int link );
334334

335-
/** Execute SQL statement
336-
* @param field
337-
* @param sql
338-
* @return empty string or error message
339-
*/
340-
QString executeSql( int field, const QString &sql );
341-
342-
/** Update attributes
343-
* @param field
344-
* @param cat
345-
* @param update comma separated update string, e.g.: col1 = 5, col2 = 'Val d''Aosta'
346-
* @return empty string or error messagemLayer
347-
*/
348-
QString updateAttributes( int field, int cat, const QString &values );
349-
350-
/** Insert new attributes to the table (it does not check if attributes already exists)
351-
* @param field
352-
* @param cat
353-
* @return empty string or error message
354-
*/
355-
QString insertAttributes( int field, int cat );
356-
357-
/** Delete attributes from the table
358-
* @param field
359-
* @param cat
360-
* @return empty string or error message
361-
*/
362-
QString deleteAttribute( int field, int cat );
363-
364-
/** Check if a database row exists and it is orphan (no more lines with
365-
* that category)
366-
* @param field
367-
* @param cat
368-
* @param orphan set to true if a record exits and it is orphan
369-
* @return empty string or error message
370-
*/
371-
QString isOrphan( int field, int cat, int &orphan );
372-
373-
/** Create table and link vector to this table
374-
* @param field
375-
* @param columns SQL definition for columns, e.g. cat integer, label varchar(10)
376-
* @return empty string or error message
377-
*/
378-
QString createTable( int field, const QString &key, const QString &columns );
379-
380-
/** Add column to table
381-
* @param field
382-
* @param column SQL definition for columns, e.g. label varchar(10)
383-
* @return empty string or error message
384-
*/
385-
QString addColumn( int field, const QString &column );
386335

387336
/* Following functions work only until first edit operation! (category index used) */
388337

@@ -438,9 +387,12 @@ class GRASS_LIB_EXPORT QgsGrassProvider : public QgsVectorDataProvider
438387
void onAttributeAdded( int idx );
439388
void onAttributeDeleted( int idx );
440389
void onBeforeCommitChanges();
390+
void onBeforeRollBack();
441391
void onEditingStopped();
442392
void onUndoIndexChanged( int index );
443393

394+
void onDataChanged();
395+
444396
protected:
445397
// used by QgsGrassFeatureSource
446398
QgsGrassVectorMapLayer *openLayer() const;
@@ -497,9 +449,10 @@ class GRASS_LIB_EXPORT QgsGrassProvider : public QgsVectorDataProvider
497449
/** Fields used for topo layers */
498450
QgsFields mTopoFields;
499451

500-
QgsFields mEditFields;
452+
//QgsFields mEditFields;
501453

502454
QgsVectorLayerEditBuffer* mEditBuffer;
455+
QgsVectorLayer* mEditLayer;
503456

504457
friend class QgsGrassFeatureSource;
505458
friend class QgsGrassFeatureIterator;

‎src/providers/grass/qgsgrassvectormap.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,9 +282,16 @@ bool QgsGrassVectorMap::startEdit()
282282
QgsDebugMsg( QString( "Vector successfully reopened for update mOldNumLines = %1" ).arg( mOldNumLines ) );
283283

284284
mIsEdited = true;
285+
286+
Q_FOREACH ( QgsGrassVectorMapLayer *l, mLayers )
287+
{
288+
l->startEdit();
289+
}
290+
285291
mValid = true;
286292
QgsGrass::unlock();
287293
unlockOpenClose();
294+
emit dataChanged();
288295
return true;
289296
}
290297

@@ -303,6 +310,11 @@ bool QgsGrassVectorMap::closeEdit( bool newMap )
303310
closeAllIterators(); // blocking
304311

305312
QgsGrass::lock();
313+
Q_FOREACH ( QgsGrassVectorMapLayer *l, mLayers )
314+
{
315+
l->closeEdit();
316+
}
317+
306318
mOldLids.clear();
307319
mNewLids.clear();
308320
mOldGeometries.clear();
@@ -345,6 +357,7 @@ bool QgsGrassVectorMap::closeEdit( bool newMap )
345357
mVersion++;
346358
unlockOpenClose();
347359

360+
emit dataChanged();
348361
QgsDebugMsg( "edit closed" );
349362
return mValid;
350363
}
@@ -459,6 +472,7 @@ void QgsGrassVectorMap::update()
459472
openMap();
460473
reloadLayers();
461474
unlockOpenClose();
475+
emit dataChanged();
462476
}
463477

464478
bool QgsGrassVectorMap::mapOutdated()

‎src/providers/grass/qgsgrassvectormap.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ class GRASS_LIB_EXPORT QgsGrassVectorMap : public QObject
135135
* @param type geometry type */
136136
TopoSymbol topoSymbol( int lid );
137137

138+
static QString topoSymbolFieldName() { return "topo_symbol" ; }
139+
138140
signals:
139141
/** Ask all iterators to cancel iteration when possible. Connected to iterators with
140142
* Qt::DirectConnection (non blocking) */
@@ -143,6 +145,9 @@ class GRASS_LIB_EXPORT QgsGrassVectorMap : public QObject
143145
/** Close all iterators. Connected to iterators in different threads with Qt::BlockingQueuedConnection */
144146
void closeIterators();
145147

148+
/** Emited when data were reloaded */
149+
void dataChanged();
150+
146151
private:
147152
/** Close iterators, blocking */
148153
void closeAllIterators();

‎src/providers/grass/qgsgrassvectormaplayer.cpp

Lines changed: 530 additions & 11 deletions
Large diffs are not rendered by default.

‎src/providers/grass/qgsgrassvectormaplayer.h

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,20 @@
2424

2525
#include "qgsfield.h"
2626

27+
extern "C"
28+
{
29+
#include <grass/version.h>
30+
#include <grass/gprojects.h>
31+
#include <grass/gis.h>
32+
#include <grass/dbmi.h>
33+
#if GRASS_VERSION_MAJOR < 7
34+
#include <grass/Vect.h>
35+
#else
36+
#include <grass/vector.h>
37+
#define BOUND_BOX bound_box
38+
#endif
39+
}
40+
2741
class QgsGrassVectorMap;
2842

2943
class GRASS_LIB_EXPORT QgsGrassVectorMapLayer : public QObject
@@ -35,8 +49,20 @@ class GRASS_LIB_EXPORT QgsGrassVectorMapLayer : public QObject
3549
int field() const { return mField; }
3650
bool isValid() const { return mValid; }
3751
QgsGrassVectorMap *map() { return mMap; }
52+
53+
/** Original fields before editing started + topo field if edited.
54+
* Does not reflect add/delete column.
55+
* Original fields must be returned by provider fields() */
3856
QgsFields & fields() { return mFields; }
57+
58+
static QStringList fieldNames( QgsFields & fields );
59+
3960
QMap<int, QList<QVariant> > & attributes() { return mAttributes; }
61+
62+
/** Get attribute for index corresponding to current fields(),
63+
* if there is no table, returns cat */
64+
QVariant attribute( int cat, int index );
65+
4066
bool hasTable() { return mHasTable; }
4167
int keyColumn() { return mKeyColumn; }
4268
QList< QPair<double, double> > minMax() { return mMinMax; }
@@ -53,18 +79,85 @@ class GRASS_LIB_EXPORT QgsGrassVectorMapLayer : public QObject
5379
/** Decrease number of users and clear if no more users */
5480
void close();
5581

56-
private:
82+
void startEdit();
83+
void closeEdit();
84+
85+
//------------------------------- Database utils ---------------------------------
86+
void setMapset();
87+
88+
/** Execute SQL statement
89+
* @param sql */
90+
void executeSql( const QString &sql, QString &error );
91+
92+
/** Update attributes
93+
* @param cat
94+
* @param index ields index */
95+
void changeAttributeValue( int cat, QgsField field, QVariant value, QString &error );
96+
97+
/** Insert new attributes to the table (it does not check if attributes already exists)
98+
* @param cat */
99+
void insertAttributes( int cat, QString &error );
100+
101+
/** Delete attributes from the table
102+
* @param cat
103+
*/
104+
void deleteAttribute( int cat, QString &error );
57105

106+
/** Check if a database row exists and it is orphan (no more lines with
107+
* that category)
108+
* @param cat
109+
* @param orphan set to true if a record exits and it is orphan
110+
* @return empty string or error message
111+
*/
112+
void isOrphan( int cat, int &orphan, QString &error );
113+
114+
/** Create table and link vector to this table
115+
* @param columns SQL definition for columns, e.g. cat integer, label varchar(10)
116+
* @return empty string or error message
117+
*/
118+
void createTable( const QString &key, const QString &columns, QString &error );
119+
120+
/** Add column to table
121+
* @param field
122+
*/
123+
void addColumn( const QgsField &field, QString &error );
124+
125+
void deleteColumn( const QgsField &field, QString &error );
126+
127+
// update fields to real state
128+
void updateFields();
129+
130+
private:
131+
QString quotedValue( QVariant value );
132+
dbDriver * openDriver( QString &error );
133+
void addTopoField( QgsFields &fields );
58134
int mField;
59135
bool mValid;
60136
QgsGrassVectorMap *mMap;
61137
struct field_info *mFieldInfo;
138+
dbDriver *mDriver;
139+
62140
bool mHasTable;
63141
// index of key column
64142
int mKeyColumn;
143+
144+
// table fields, updated if a field is added/deleted, if there is no table, it contains
145+
// cat field
146+
QgsFields mTableFields;
147+
148+
// original fields + topo symbol when editing, does not reflect add/column
65149
QgsFields mFields;
150+
151+
// list of fields in mAttributes, these fields may only grow when a field is added,
152+
// but do not shrink until editing is closed
153+
QgsFields mAttributeFields;
154+
66155
// Map of attributes with cat as key
67156
QMap<int, QList<QVariant> > mAttributes;
157+
158+
// Map of current original fields() indexes to mAttributes, skipping topo symbol
159+
//QMap<int, int> mAttributeIndexes;
160+
68161
// minimum and maximum values of attributes
69162
QList<QPair<double, double> > mMinMax;
70163
// timestamp when attributes were loaded

0 commit comments

Comments
 (0)
Please sign in to comment.