Skip to content

Commit 43278d7

Browse files
author
jef
committed
handling vector data geometry and attribute updates refactored
QgsVectorLayer: - move attribute part of editing to vector layer class and unify with geometry handling: * remove commitAttributeChanges(), addedFeatures(), deletedFeatureIds(), changedAttributes() and replace with changeAttributeValue(), deleteFeature(), addAttribute() and deleteAttribute() * add pendingFields(), pendingAttributeList(), pendingFeatureCount() * emit signals on start editing and commit, change of attribute values, adding/deleting of attributes and layer or feature removal (currently used in the attribute table) - new commitErrors() method to query errors from commitChanges() - replaced featuresInRectangle with select/getNextFeature combo - edit types added to support more input widgets and input constraints QgsFeature: - remove update aware ctor - unify geometry handling in ctors QgsVectorDataProvider: - add QVariant::Type to supportNativeTypes() QgisApp: - add instance() method to query QgisApp object - replace code at various place to use it instead of passing the pointer arround or searching it in the widget tree. - move toggleEditing() code from the legend here QgsAttributeTable/QgsAttributeTableDisplay: - move attribute table creation legend here - make attribute table dockable (from Tim) - most editing logic moved to QgsVectorLayer - adding/deleting attributes moved to QgsVectorLayerProperties QgsIdentifyResults: - add support for attribute editing when it edit mode QgsVectorLayerProperties: add a new tab to show attribute list: * start/stop editing * add/delete attributes * assign edit type to attributes (unique values, value map, ranges) QgsAttributeDialog: add support for attribute edit types: * selection from unique value render classes (combobox) * selection from unique values of existing features (combobox or line edits with completion) * spinboxes for ranges QgsPostgresProvider: - use read-only connection for cursors and read-write connection for updates - updated native types QgsOgrProvider: - remove unused references to GEOS geometry factory - updated native types git-svn-id: http://svn.osgeo.org/qgis/trunk@9092 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 03ef707 commit 43278d7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+4003
-3728
lines changed

python/core/qgsfeature.sip

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,6 @@ class QgsFeature
1313
//! Constructor
1414
QgsFeature(int id = 0, QString typeName = "" );
1515

16-
/** create a copy of this feature in its uncommitted state.
17-
To do this, you also pass in a reference to the feature's
18-
layer's uncommitted attribute and geometry changes.
19-
The resulting feature will have those changes applied.
20-
21-
This is useful in the cut/copy routine, where you'd
22-
want a copy of the "current" feature, not the on-disk feature.
23-
*/
24-
QgsFeature( const QgsFeature & rhs,
25-
const QMap<int, QMap<int, QVariant> >& changedAttributes,
26-
const QMap<int, QgsGeometry> & changedGeometries );
27-
2816
/** copy ctor needed due to internal pointer */
2917
QgsFeature(const QgsFeature & rhs );
3018

python/core/qgsvectordataprovider.sip

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ class QgsVectorDataProvider : QgsDataProvider
8888
*/
8989
virtual QGis::WKBTYPE geometryType() const = 0;
9090

91-
9291
/**
9392
* Number of features in the layer
9493
* @return long containing number of features
@@ -230,7 +229,7 @@ class QgsVectorDataProvider : QgsDataProvider
230229
QList<int> allAttributesList();
231230

232231
/**Returns the names of the numerical types*/
233-
const QSet<QString>& supportedNativeTypes() const;
232+
const QMap<QString,QVariant::Type> &supportedNativeTypes() const;
234233

235234
/**
236235
* Set whether provider should return also features that don't have

python/core/qgsvectorlayer.sip

Lines changed: 110 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,27 @@
1-
2-
31
class QgsVectorLayer : QgsMapLayer
42
{
53
%TypeHeaderCode
6-
#include <qgsvectorlayer.h>
4+
#include "qgsvectorlayer.h"
75
%End
86

97
public:
8+
enum EditType {
9+
LineEdit,
10+
UniqueValues,
11+
UniqueValuesEditable,
12+
ValueMap,
13+
Classification,
14+
Range,
15+
};
16+
17+
struct RangeData {
18+
RangeData();
19+
RangeData(QVariant theMin, QVariant theMax, QVariant theStep);
20+
21+
QVariant mMin;
22+
QVariant mMax;
23+
QVariant mStep;
24+
};
1025

1126
/** Constructor */
1227
QgsVectorLayer(QString baseName = 0, QString path = 0, QString providerLib = 0);
@@ -66,10 +81,6 @@ public:
6681
/** Returns the bounding box of the selected features. If there is no selection, QgsRect(0,0,0,0) is returned */
6782
QgsRect boundingBoxOfSelected();
6883

69-
70-
/** Insert a copy of the given features into the layer */
71-
bool addFeatures(QList<QgsFeature> features, bool makeSelected = TRUE);
72-
7384
/** Copies the symbology settings from another layer. Returns true in case of success */
7485
bool copySymbologySettings(const QgsMapLayer& other);
7586

@@ -92,12 +103,12 @@ public:
92103
QString providerType() const;
93104

94105
/** reads vector layer specific state from project file DOM node.
95-
* @note Called by QgsMapLayer::readXML().
106+
* @note Called by QgsMapLayer::readXml().
96107
*/
97108
virtual bool readXml( QDomNode & layer_node );
98109

99110
/** write vector layer specific state to project file DOM node.
100-
* @note Called by QgsMapLayer::writeXML().
111+
* @note Called by QgsMapLayer::writeXml().
101112
*/
102113
virtual bool writeXml( QDomNode & layer_node, QDomDocument & doc );
103114

@@ -130,17 +141,20 @@ public:
130141
*/
131142
virtual QString subsetString();
132143

133-
/**Returns the features contained in the rectangle. Considers the changed, added, deleted and permanent features
134-
@return 0 in case of success*/
135-
int featuresInRectangle(const QgsRect& searchRect, QList<QgsFeature>& features /Out/, bool fetchGeometries = true, bool fetchAttributes = true);
144+
void select(QList<int> fetchAttributes = QList<int>(),
145+
QgsRect rect = QgsRect(),
146+
bool fetchGeometry = true);
147+
148+
bool getNextFeature(QgsFeature& feature);
149+
136150

137-
/**Gets the feature at the given feature id. Considers the changed, added, deleted and permanent features
151+
/**Gets the feature at the given feature id. Considers the changed, added, deleted and permanent features
138152
@return 0 in case of success*/
139-
int getFeatureAtId(int featureId, QgsFeature& f, bool fetchGeometries = true, bool fetchAttributes = true);
153+
int getFeatureAtId(int featureId, QgsFeature& f, bool fetchGeometries = true, bool fetchAttributes = true);
140154

141155
/** Adds a feature
142-
@param lastFeatureInBatch If True, will also go to the effort of e.g. updating the extents.
143-
@return Irue in case of success and False in case of error
156+
@param alsoUpdateExtent If True, will also go to the effort of e.g. updating the extents.
157+
@return True in case of success and False in case of error
144158
*/
145159
bool addFeature(QgsFeature& f, bool alsoUpdateExtent = TRUE);
146160

@@ -168,49 +182,60 @@ public:
168182
bool deleteSelectedFeatures();
169183

170184
/**Adds a ring to polygon/multipolygon features
171-
@return 0 in case of success, 1 problem with feature type, 2 ring not closed, 3 ring not valid, 4 ring crosses \
172-
existing rings, 5 no feature found where ring can be inserted*/
185+
@return
186+
0 in case of success,
187+
1 problem with feature type,
188+
2 ring not closed,
189+
3 ring not valid,
190+
4 ring crosses existing rings,
191+
5 no feature found where ring can be inserted*/
173192
int addRing(const QList<QgsPoint>& ring);
174193

175194
/**Adds a new island polygon to a multipolygon feature
176-
@return 0 in case of success, 1 if selected feature is not multipolygon, 2 if ring is not a valid geometry, \
177-
3 if new polygon ring not disjoint with existing rings, 4 if no feature was selected, 5 if several features are selected, \
178-
6 if selected geometry not found*/
195+
@return
196+
0 in case of success,
197+
1 if selected feature is not multipolygon,
198+
2 if ring is not a valid geometry,
199+
3 if new polygon ring not disjoint with existing rings,
200+
4 if no feature was selected,
201+
5 if several features are selected,
202+
6 if selected geometry not found*/
179203
int addIsland(const QList<QgsPoint>& ring);
180204

181-
/**Translates feature by dx, dy
205+
/**Translates feature by dx, dy
182206
@param featureId id of the feature to translate
183207
@param dx translation of x-coordinate
184208
@param dy translation of y-coordinate
185209
@return 0 in case of success*/
186210
int translateFeature(int featureId, double dx, double dy);
187211

188-
/**Splits features cut by the given line
212+
/**Splits features cut by the given line
189213
@param splitLine line that splits the layer features
190214
@param topologicalEditing true if topological editing is enabled
191-
@return 0 in case of success, 1 if several intersections but only 1 split done, \
192-
2 if intersection too complex to be handled, else other error*/
215+
@return
216+
0 in case of success,
217+
1 if several intersections but only 1 split done,
218+
2 if intersection too complex to be handled, else other error*/
193219
int splitFeatures(const QList<QgsPoint>& splitLine, bool topologicalEditing = false);
194220

195-
/**Changes the specified geometry such that it has no intersections with other \
221+
/**Changes the specified geometry such that it has no intersections with other \
196222
polygon (or multipolygon) geometries in this vector layer
197-
@param geom geometry to modify
198-
@return 0 in case of success*/
223+
@param geom geometry to modify
224+
@return 0 in case of success*/
199225
int removePolygonIntersections(QgsGeometry* geom);
200226

201-
/**Adds topological points for every vertex of the
202-
geometry
203-
@param geom the geometry where each vertex is added to segments of other features
204-
Note: geom is not going to be modified by the function
205-
@return 0 in case of success*/
227+
/**Adds topological points for every vertex of the geometry
228+
@param geom the geometry where each vertex is added to segments of other features
229+
Note: geom is not going to be modified by the function
230+
@return 0 in case of success*/
206231
int addTopologicalPoints(QgsGeometry* geom);
207232

208-
/**Adds a vertex to segments which intersect point p but don't
209-
already have a vertex there. If a feature already has a vertex at position p,
210-
no additional vertex is inserted. This method is usefull for topological
211-
editing.
212-
@param p position of the vertex
213-
@return 0 in case of success*/
233+
/**Adds a vertex to segments which intersect point p but don't
234+
already have a vertex there. If a feature already has a vertex at position p,
235+
no additional vertex is inserted. This method is usefull for topological
236+
editing.
237+
@param p position of the vertex
238+
@return 0 in case of success*/
214239
int addTopologicalPoints(const QgsPoint& p);
215240

216241
/**Inserts vertices to the snapped segments.
@@ -246,29 +271,7 @@ existing rings, 5 no feature found where ring can be inserted*/
246271
@return 0 in case of success
247272
*/
248273
int snapWithContext(const QgsPoint& startPoint, double snappingTolerance, QMultiMap<double, QgsSnappingResult>& snappingResults /Out/,
249-
QgsSnapper::SNAP_TO snap_to);
250-
251-
/**
252-
Commits edited attributes. Depending on the feature id,
253-
the changes are written to not commited features or redirected to
254-
the data provider
255-
256-
The commits (in this version) occur in three distinct stages,
257-
(delete attributes, add attributes, change attribute values)
258-
so if a stage fails, it's difficult to roll back cleanly.
259-
260-
\todo Need to indicate at which stage the failed commit occurred,
261-
for better cleanup and recovery from the error.
262-
263-
\param deleted Set of attribute indices (i.e. columns) to delete
264-
\param added Map (name, type) of attribute names (i.e. columns) to add
265-
\param changed Map (feature ID, Map (attribute name, new value) )
266-
of attribute values to change
267-
268-
*/
269-
bool commitAttributeChanges(const QSet<int>& deleted,
270-
const QMap<QString, QString>& added,
271-
const QMap<int, QMap<int, QVariant> >& changed);
274+
QgsSnapper::SNAP_TO snap_to);
272275

273276
/** Draws the layer using coordinate transformation
274277
* @return FALSE if an error occurred during drawing
@@ -283,20 +286,36 @@ existing rings, 5 no feature found where ring can be inserted*/
283286
*/
284287
void drawLabels(QPainter * p, const QgsRect& viewExtent, const QgsMapToPixel* cXf, const QgsCoordinateTransform* ct, double scale);
285288

286-
/** returns array of added features */
287-
QList<QgsFeature>& addedFeatures();
289+
/** returns list of attributes */
290+
QList<int> pendingAllAttributesList();
288291

289-
/** returns array of deleted feature IDs */
290-
QSet<int>& deletedFeatureIds();
291-
292-
/** returns array of features with changed attributes */
293-
QMap<int, QMap<int, QVariant> >& changedAttributes();
292+
/** returns fields list which are not commited */
293+
const QMap<int, QgsField> &pendingFields();
294294

295+
/** returns feature count after commit */
296+
int pendingFeatureCount();
297+
295298
/** Sets whether some features are modified or not */
296299
void setModified(bool modified = TRUE, bool onlyGeometryWasModified = FALSE);
297300

298301
/** Make layer editable */
299302
bool startEditing();
303+
304+
/** changed an attribute value (but does not commit it */
305+
bool changeAttributeValue(int fid, int field, QVariant value, bool emitSignal = true);
306+
307+
/** add an attribute field (but does not commit it)
308+
returns the field index or -1 in case of failure */
309+
bool addAttribute(QString name, QString type);
310+
311+
/** delete an attribute field (but does not commit it) */
312+
bool deleteAttribute(int attr);
313+
314+
/** Insert a copy of the given features into the layer (but does not commit it) */
315+
bool addFeatures(QList<QgsFeature> features, bool makeSelected = TRUE);
316+
317+
/** delete a feature from the layer (but does not commit it) */
318+
bool deleteFeature(int fid);
300319

301320
/**
302321
Attempts to commit any changes to disk. Returns the result of the attempt.
@@ -314,10 +333,23 @@ existing rings, 5 no feature found where ring can be inserted*/
314333

315334
*/
316335
bool commitChanges();
336+
const QStringList &commitErrors();
317337

318338
/** Stop editing and discard the edits */
319339
bool rollBack();
320340

341+
/**get edit type*/
342+
EditType editType(int idx);
343+
344+
/**set edit type*/
345+
void setEditType(int idx, EditType edit);
346+
347+
/**access value map*/
348+
QMap<QString, QVariant> &valueMap(int idx);
349+
350+
/**access range */
351+
RangeData &range(int idx);
352+
321353
public slots:
322354

323355
/** Select feature by its ID, optionally emit signal selectionChanged() */
@@ -341,6 +373,15 @@ signals:
341373
/** This signal is emitted when modifications has been done on layer */
342374
void wasModified(bool onlyGeometry);
343375

376+
void editingStarted();
377+
void editingStopped();
378+
void attributeAdded(int idx);
379+
void attributeDeleted(int idx);
380+
void featureDeleted(int fid);
381+
void layerDeleted();
382+
383+
void attributeValueChanged(int fid, int idx, const QVariant &);
384+
344385
private: // Private methods
345386

346387
/** vector layers are not copyable */

src/app/legend/qgslegend.cpp

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,8 @@
3636
#include "qgsproject.h"
3737
#include "qgsrasterlayer.h"
3838
#include "qgsrasterlayerproperties.h"
39-
#include "qgsvectorlayer.h"
4039
#include "qgsvectorlayerproperties.h"
41-
#include "qgsvectordataprovider.h"
40+
#include "qgsattributetabledisplay.h"
4241

4342
#include <cfloat>
4443
#include <iostream>
@@ -1811,29 +1810,39 @@ void QgsLegend::legendLayerZoomNative()
18111810
void QgsLegend::legendLayerAttributeTable()
18121811
{
18131812
if(!mMapCanvas || mMapCanvas->isDrawing())
1814-
{
1815-
return;
1816-
}
1813+
{
1814+
return;
1815+
}
1816+
1817+
QgsVectorLayer *vlayer = 0;
18171818

18181819
// try whether it's a legend layer
18191820
QgsLegendLayer* ll = dynamic_cast<QgsLegendLayer*>(currentItem());
18201821
if (ll)
18211822
{
1822-
ll->table();
1823-
return;
1823+
vlayer = dynamic_cast<QgsVectorLayer*>(ll->firstMapLayer());
18241824
}
18251825

1826-
// try whether it's a legend layer file
1827-
QgsLegendLayerFile* llf = dynamic_cast<QgsLegendLayerFile*>(currentItem());
1828-
if (llf)
1829-
{
1830-
llf->table();
1831-
return;
1826+
if(!vlayer) {
1827+
// try whether it's a legend layer file
1828+
QgsLegendLayerFile* llf = dynamic_cast<QgsLegendLayerFile*>(currentItem());
1829+
if (llf)
1830+
{
1831+
vlayer = dynamic_cast<QgsVectorLayer*>(llf->layer());
1832+
}
18321833
}
18331834

1834-
// nothing selected
1835-
QMessageBox::information(this, tr("No Layer Selected"),
1836-
tr("To open an attribute table, you must select a vector layer in the legend"));
1835+
if(vlayer)
1836+
{
1837+
QgsAttributeTableDisplay::attributeTable( vlayer );
1838+
}
1839+
else
1840+
{
1841+
// nothing selected
1842+
QMessageBox::information(this,
1843+
tr("No Layer Selected"),
1844+
tr("To open an attribute table, you must select a vector layer in the legend"));
1845+
}
18371846
}
18381847

18391848
void QgsLegend::readProject(const QDomDocument & doc)

0 commit comments

Comments
 (0)