Skip to content

Commit f59d6d7

Browse files
author
Hugo Mercier
authored
Merge pull request #4776 from pblottiere/bugfix_attributetable
[bugfix] attribute table
2 parents 9f5e33a + b354986 commit f59d6d7

15 files changed

+553
-1
lines changed

src/core/qgsvectorlayerjoinbuffer.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ void QgsVectorLayerJoinBuffer::resolveReferences( QgsProject *project )
348348
if ( QgsVectorLayer *joinedLayer = qobject_cast<QgsVectorLayer *>( project->mapLayer( it->joinLayerId() ) ) )
349349
{
350350
it->setJoinLayer( joinedLayer );
351+
connectJoinedLayer( joinedLayer );
351352
resolved = true;
352353
}
353354
}

src/gui/attributetable/qgsattributetablemodel.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,8 @@ void QgsAttributeTableModel::attributeValueChanged( QgsFeatureId fid, int idx, c
303303
// No filter request: skip all possibly heavy checks
304304
if ( mFeatureRequest.filterType() == QgsFeatureRequest::FilterNone )
305305
{
306-
setData( index( idToRow( fid ), fieldCol( idx ) ), value, Qt::EditRole );
306+
if ( loadFeatureAtId( fid ) )
307+
setData( index( idToRow( fid ), fieldCol( idx ) ), value, Qt::EditRole );
307308
}
308309
else
309310
{

tests/src/python/test_qgsattributetablemodel.py

+29
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,35 @@ def testRemoveColumns(self):
9191

9292
self.assertEqual(self.am.columnCount(), 1)
9393

94+
def testEdit(self):
95+
fid = 2
96+
field_idx = 1
97+
new_value = 333
98+
99+
# get the same feature from model and layer
100+
feature = self.layer.getFeature(fid)
101+
model_index = self.am.idToIndex(fid)
102+
feature_model = self.am.feature(model_index)
103+
104+
# check that feature from layer and model are sync
105+
self.assertEqual(feature.attribute(field_idx), feature_model.attribute(field_idx))
106+
107+
# change attribute value for a feature and commit
108+
self.layer.startEditing()
109+
self.layer.changeAttributeValue(fid, field_idx, new_value)
110+
self.layer.commitChanges()
111+
112+
# check the feature in layer is good
113+
feature = self.layer.getFeature(fid)
114+
self.assertEqual(feature.attribute(field_idx), new_value)
115+
116+
# get the same feature from model and layer
117+
model_index = self.am.idToIndex(fid)
118+
feature_model = self.am.feature(model_index)
119+
120+
# check that index from layer and model are sync
121+
self.assertEqual(feature.attribute(field_idx), feature_model.attribute(field_idx))
122+
94123

95124
if __name__ == '__main__':
96125
unittest.main()

tests/src/python/test_qgsvectorlayer.py

+64
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
QgsSymbol,
3737
QgsSingleSymbolRenderer,
3838
QgsCoordinateReferenceSystem,
39+
QgsVectorLayerCache,
3940
QgsReadWriteContext,
4041
QgsProject,
4142
QgsUnitTypes,
@@ -54,6 +55,9 @@
5455
QgsTextFormat,
5556
QgsVectorLayerSelectedFeatureSource,
5657
NULL)
58+
from qgis.gui import (QgsAttributeTableModel,
59+
QgsGui
60+
)
5761
from qgis.testing import start_app, unittest
5862
from featuresourcetestbase import FeatureSourceTestCase
5963
from utilities import unitTestDataPath
@@ -209,6 +213,7 @@ def getSource(cls):
209213
@classmethod
210214
def setUpClass(cls):
211215
"""Run before all tests"""
216+
QgsGui.editorWidgetRegistry().initEditors()
212217
# Create test layer for FeatureSourceTestCase
213218
cls.source = cls.getSource()
214219

@@ -1321,6 +1326,65 @@ def test_JoinStats(self):
13211326
self.assertEqual(layer.maximumValue(3), 321)
13221327
self.assertEqual(set(layer.uniqueValues(3)), set([111, 321]))
13231328

1329+
def test_valid_join_when_opening_project(self):
1330+
join_field = "id"
1331+
fid = 4
1332+
attr_idx = 4
1333+
join_attr_idx = 1
1334+
new_value = 33.0
1335+
1336+
# read project and get layers
1337+
myPath = os.path.join(unitTestDataPath(), 'joins.qgs')
1338+
rc = QgsProject.instance().read(myPath)
1339+
1340+
layer = QgsProject.instance().mapLayersByName("polys_with_id")[0]
1341+
join_layer = QgsProject.instance().mapLayersByName("polys_overlapping_with_id")[0]
1342+
1343+
# create an attribute table for the main_layer and the
1344+
# joined layer
1345+
cache = QgsVectorLayerCache(layer, 100)
1346+
am = QgsAttributeTableModel(cache)
1347+
am.loadLayer()
1348+
1349+
join_cache = QgsVectorLayerCache(join_layer, 100)
1350+
join_am = QgsAttributeTableModel(join_cache)
1351+
join_am.loadLayer()
1352+
1353+
# check feature value of a joined field from the attribute model
1354+
model_index = am.idToIndex(fid)
1355+
feature_model = am.feature(model_index)
1356+
1357+
join_model_index = join_am.idToIndex(fid)
1358+
join_feature_model = join_am.feature(join_model_index)
1359+
1360+
self.assertEqual(feature_model.attribute(attr_idx), join_feature_model.attribute(join_attr_idx))
1361+
1362+
# change attribute value for a feature of the joined layer
1363+
join_layer.startEditing()
1364+
join_layer.changeAttributeValue(fid, join_attr_idx, new_value)
1365+
join_layer.commitChanges()
1366+
1367+
# check the feature previously modified
1368+
join_model_index = join_am.idToIndex(fid)
1369+
join_feature_model = join_am.feature(join_model_index)
1370+
self.assertEqual(join_feature_model.attribute(join_attr_idx), new_value)
1371+
1372+
# recreate a new cache and model to simulate the opening of
1373+
# a new attribute table
1374+
cache = QgsVectorLayerCache(layer, 100)
1375+
am = QgsAttributeTableModel(cache)
1376+
am.loadLayer()
1377+
1378+
# test that the model is up to date with the joined layer
1379+
model_index = am.idToIndex(fid)
1380+
feature_model = am.feature(model_index)
1381+
self.assertEqual(feature_model.attribute(attr_idx), new_value)
1382+
1383+
# restore value
1384+
join_layer.startEditing()
1385+
join_layer.changeAttributeValue(fid, join_attr_idx, 7.0)
1386+
join_layer.commitChanges()
1387+
13241388
def testUniqueValue(self):
13251389
""" test retrieving unique values """
13261390
layer = createLayerWithFivePoints()

0 commit comments

Comments
 (0)