@@ -86,6 +86,8 @@ QgsGrassProvider::QgsGrassProvider( QString uri )
8686 , mEditBuffer( 0 )
8787 , mEditLayer( 0 )
8888 , mNewFeatureType( 0 )
89+ , mPoints( 0 )
90+ , mCats( 0 )
8991{
9092 QgsDebugMsg ( " uri = " + uri );
9193
@@ -99,6 +101,9 @@ QgsGrassProvider::QgsGrassProvider( QString uri )
99101 QTime time;
100102 time.start ();
101103
104+ mPoints = Vect_new_line_struct ();
105+ mCats = Vect_new_cats_struct ();
106+
102107 // Parse URI
103108 QDir dir ( uri ); // it is not a directory in fact
104109 QString myURI = dir.path (); // no dupl '/'
@@ -232,6 +237,23 @@ QgsGrassProvider::QgsGrassProvider( QString uri )
232237 QgsDebugMsg ( QString ( " New GRASS layer opened, time (ms): %1" ).arg ( time.elapsed () ) );
233238}
234239
240+ QgsGrassProvider::~QgsGrassProvider ()
241+ {
242+ QgsDebugMsg ( " entered" );
243+ if ( mLayer )
244+ {
245+ mLayer ->close ();
246+ }
247+ if ( mPoints )
248+ {
249+ Vect_destroy_line_struct ( mPoints );
250+ }
251+ if ( mCats )
252+ {
253+ Vect_destroy_cats_struct ( mCats );
254+ }
255+ }
256+
235257int QgsGrassProvider::capabilities () const
236258{
237259 // for now, only one map may be edited at time
@@ -333,16 +355,6 @@ void QgsGrassProvider::update()
333355 mValid = true ;
334356}
335357
336- QgsGrassProvider::~QgsGrassProvider ()
337- {
338- QgsDebugMsg ( " entered" );
339- if ( mLayer )
340- {
341- mLayer ->close ();
342- }
343- }
344-
345-
346358QgsAbstractFeatureSource* QgsGrassProvider::featureSource () const
347359{
348360 const_cast <QgsGrassProvider*>( this )->ensureUpdated ();
@@ -640,15 +652,35 @@ int QgsGrassProvider::readLine( struct line_pnts *Points, struct line_cats *Cats
640652 QgsDebugMsgLevel ( " entered" , 3 );
641653
642654 if ( Points )
655+ {
643656 Vect_reset_line ( Points );
657+ }
644658
645659 if ( Cats )
660+ {
646661 Vect_reset_cats ( Cats );
662+ }
663+
664+ if ( !map () )
665+ {
666+ return -1 ;
667+ }
647668
648669 if ( !Vect_line_alive ( map (), line ) )
670+ {
649671 return -1 ;
672+ }
650673
651- return ( Vect_read_line ( map (), Points, Cats, line ) );
674+ int type = -1 ;
675+ G_TRY
676+ {
677+ type = Vect_read_line ( map (), mPoints , mCats , line );
678+ }
679+ G_CATCH ( QgsGrass::Exception &e )
680+ {
681+ QgsDebugMsg ( QString ( " Cannot read line : %1" ).arg ( e.what () ) );
682+ }
683+ return type;
652684}
653685
654686bool QgsGrassProvider::nodeCoor ( int node, double *x, double *y )
@@ -697,14 +729,38 @@ int QgsGrassProvider::writeLine( int type, struct line_pnts *Points, struct line
697729 return (( int ) Vect_write_line ( map (), type, Points, Cats ) );
698730}
699731
700- int QgsGrassProvider::rewriteLine ( int line , int type, struct line_pnts *Points, struct line_cats *Cats )
732+ int QgsGrassProvider::rewriteLine ( int oldLid , int type, struct line_pnts *Points, struct line_cats *Cats )
701733{
702734 QgsDebugMsg ( QString ( " n_points = %1 n_cats = %2" ).arg ( Points->n_points ).arg ( Cats->n_cats ) );
703735
704- if ( !isEdited () )
736+ if ( !map () || !isEdited () )
737+ {
705738 return -1 ;
739+ }
740+
741+ int newLid = -1 ;
742+ G_TRY
743+ {
744+ newLid = Vect_rewrite_line ( map (), oldLid, type, Points, Cats );
745+
746+ // oldLids are maping to the very first, original version (used by undo)
747+ int oldestLid = oldLid;
748+ if ( mLayer ->map ()->oldLids ().contains ( oldLid ) ) // if it was changed already
749+ {
750+ oldestLid = mLayer ->map ()->oldLids ().value ( oldLid );
751+ }
706752
707- return ( Vect_rewrite_line ( map (), line, type, Points, Cats ) );
753+ QgsDebugMsg ( QString ( " oldLid = %1 oldestLid = %2 newLine = %3" ).arg ( oldLid ).arg ( oldestLid ).arg ( newLid ) );
754+ QgsDebugMsg ( QString ( " oldLids : %1 -> %2" ).arg ( newLid ).arg ( oldestLid ) );
755+ mLayer ->map ()->oldLids ()[newLid] = oldestLid;
756+ QgsDebugMsg ( QString ( " newLids : %1 -> %2" ).arg ( oldestLid ).arg ( newLid ) );
757+ mLayer ->map ()->newLids ()[oldestLid] = newLid;
758+ }
759+ G_CATCH ( QgsGrass::Exception &e )
760+ {
761+ QgsDebugMsg ( QString ( " Cannot write line : %1" ).arg ( e.what () ) );
762+ }
763+ return newLid;
708764}
709765
710766
@@ -1030,6 +1086,11 @@ void QgsGrassProvider::startEditing( QgsVectorLayer *vectorLayer )
10301086 // let qgis know (attribute table etc.) that we added topo symbol field
10311087 vectorLayer->updateFields ();
10321088
1089+ // TODO: enable cats editing once all consequences are implemented
1090+ // disable cat and topo symbol editing
1091+ vectorLayer->setFieldEditable ( mLayer ->keyColumn (), false );
1092+ vectorLayer->setFieldEditable ( mLayer ->fields ().size () - 1 , false );
1093+
10331094 QgsDebugMsg ( " edit started" );
10341095}
10351096
@@ -1139,11 +1200,9 @@ void QgsGrassProvider::onFeatureAdded( QgsFeatureId fid )
11391200 }
11401201 else
11411202 {
1142- struct line_pnts *points = Vect_new_line_struct ();
1143- struct line_cats *cats = Vect_new_cats_struct ();
11441203 int newCat = 0 ;
11451204
1146- setPoints ( points , geometry );
1205+ setPoints ( mPoints , geometry );
11471206 // TODO: get also old type if it is feature previously deleted
11481207 int type = mNewFeatureType == GV_AREA ? GV_BOUNDARY : mNewFeatureType ;
11491208
@@ -1182,7 +1241,8 @@ void QgsGrassProvider::onFeatureAdded( QgsFeatureId fid )
11821241 }
11831242 }
11841243 QgsDebugMsg ( QString ( " newCat = %1" ).arg ( newCat ) );
1185- Vect_cat_set ( cats, mLayerField , newCat );
1244+ Vect_reset_cats ( mCats );
1245+ Vect_cat_set ( mCats , mLayerField , newCat );
11861246 QString error;
11871247
11881248 // if the cat is user defined, the record may alredy exist
@@ -1265,14 +1325,15 @@ void QgsGrassProvider::onFeatureAdded( QgsFeatureId fid )
12651325 {
12661326 // TODO: orig field, maybe different
12671327 int field = mLayerField ;
1268- Vect_cat_set ( cats, field, cat );
1328+ Vect_reset_cats ( mCats );
1329+ Vect_cat_set ( mCats , field, cat );
12691330 }
12701331 }
12711332
1272- if ( type > 0 && points ->n_points > 0 )
1333+ if ( type > 0 && mPoints ->n_points > 0 )
12731334 {
12741335 mLayer ->map ()->lockReadWrite ();
1275- int newLid = Vect_write_line ( map (), type, points, cats );
1336+ int newLid = Vect_write_line ( map (), type, mPoints , mCats );
12761337 mLayer ->map ()->unlockReadWrite ();
12771338
12781339 QgsDebugMsg ( QString ( " newLine = %1" ).arg ( newLid ) );
@@ -1334,14 +1395,11 @@ void QgsGrassProvider::onFeatureAdded( QgsFeatureId fid )
13341395 }
13351396 }
13361397
1337- if ( type == GV_BOUNDARY )
1398+ if ( type == GV_BOUNDARY || type == GV_CENTROID )
13381399 {
13391400 setAddedFeaturesSymbol ();
13401401 }
13411402 }
1342-
1343- Vect_destroy_line_struct ( points );
1344- Vect_destroy_cats_struct ( cats );
13451403 }
13461404}
13471405
@@ -1395,7 +1453,7 @@ void QgsGrassProvider::onFeatureDeleted( QgsFeatureId fid )
13951453 }
13961454 mLayer ->map ()->unlockReadWrite ();
13971455
1398- if ( type == GV_BOUNDARY )
1456+ if ( type == GV_BOUNDARY || type == GV_CENTROID )
13991457 {
14001458 setAddedFeaturesSymbol ();
14011459 }
@@ -1411,22 +1469,12 @@ void QgsGrassProvider::onGeometryChanged( QgsFeatureId fid, QgsGeometry &geom )
14111469 }
14121470 QgsDebugMsg ( QString ( " fid = %1 oldLid = %2 realLine = %3" ).arg ( fid ).arg ( oldLid ).arg ( realLine ) );
14131471
1414- struct line_pnts *points = Vect_new_line_struct ();
1415- struct line_cats *cats = Vect_new_cats_struct ();
1416-
1417- int type = 0 ;
1418- G_TRY
1419- {
1420- type = Vect_read_line ( map (), points, cats, realLine );
1421- }
1422- G_CATCH ( QgsGrass::Exception &e )
1472+ int type = readLine ( mPoints , mCats , realLine );
1473+ QgsDebugMsg ( QString ( " type = %1 n_points = %2" ).arg ( type ).arg ( mPoints ->n_points ) );
1474+ if ( type < 1 ) // error
14231475 {
1424- QgsDebugMsg ( QString ( " Cannot read line : %1" ).arg ( e.what () ) );
1425- Vect_destroy_line_struct ( points );
1426- Vect_destroy_cats_struct ( cats );
14271476 return ;
14281477 }
1429- QgsDebugMsg ( QString ( " type = %1 n_points = %2" ).arg ( type ).arg ( points->n_points ) );
14301478
14311479 // store only the first original geometry if it is not new feature, changed geometries are stored in the buffer
14321480 if ( oldLid > 0 && !mLayer ->map ()->oldGeometries ().contains ( oldLid ) )
@@ -1443,37 +1491,16 @@ void QgsGrassProvider::onGeometryChanged( QgsFeatureId fid, QgsGeometry &geom )
14431491 }
14441492 }
14451493
1446- setPoints ( points , geom.geometry () );
1494+ setPoints ( mPoints , geom.geometry () );
14471495
14481496 mLayer ->map ()->lockReadWrite ();
14491497 // Vect_rewrite_line may delete/write the line with a new id
1450- int newLid = Vect_rewrite_line ( map (), realLine, type, points, cats );
1451- G_TRY
1452- {
1453- newLid = Vect_rewrite_line ( map (), realLine, type, points, cats );
1498+ int newLid = rewriteLine ( realLine, type, mPoints , mCats );
1499+ Q_UNUSED ( newLid )
14541500
1455- // oldLids are maping to the very first, original version (used by undo)
1456- int oldestLid = oldLid;
1457- if ( mLayer ->map ()->oldLids ().contains ( oldLid ) )
1458- {
1459- oldestLid = mLayer ->map ()->oldLids ().value ( oldLid );
1460- }
1461- QgsDebugMsg ( QString ( " oldLid = %1 oldestLid = %2 newLine = %3" ).arg ( oldLid ).arg ( oldestLid ).arg ( newLid ) );
1462- QgsDebugMsg ( QString ( " oldLids : %1 -> %2" ).arg ( newLid ).arg ( oldestLid ) );
1463- mLayer ->map ()->oldLids ()[newLid] = oldestLid;
1464- QgsDebugMsg ( QString ( " newLids : %1 -> %2" ).arg ( oldestLid ).arg ( newLid ) );
1465- mLayer ->map ()->newLids ()[oldestLid] = newLid;
1466- }
1467- G_CATCH ( QgsGrass::Exception &e )
1468- {
1469- QgsDebugMsg ( QString ( " Cannot write line : %1" ).arg ( e.what () ) );
1470- }
14711501 mLayer ->map ()->unlockReadWrite ();
14721502
1473- Vect_destroy_line_struct ( points );
1474- Vect_destroy_cats_struct ( cats );
1475-
1476- if ( type == GV_BOUNDARY )
1503+ if ( type == GV_BOUNDARY || type == GV_CENTROID )
14771504 {
14781505 setAddedFeaturesSymbol ();
14791506 }
@@ -1506,19 +1533,65 @@ void QgsGrassProvider::onAttributeValueChanged( QgsFeatureId fid, int idx, const
15061533 }
15071534 QgsField field = mEditLayer ->fields ()[idx];
15081535
1509- if ( realCat > 0 )
1536+ QgsDebugMsg ( " field.name() = " + field.name () + " keyColumnName() = " + mLayer ->keyColumnName () );
1537+ // TODO: Changing existing category is currently disabled (read only widget set on layer)
1538+ // bacause it makes it all too complicated
1539+ if ( field.name () == mLayer ->keyColumnName () )
15101540 {
1511- QString error;
1512- mLayer ->changeAttributeValue ( realCat, field, value, error );
1513- if ( !error.isEmpty () )
1541+ // user changed category -> rewrite line
1542+ QgsDebugMsg ( " cat changed -> rewrite line" );
1543+ int type = readLine ( mPoints , mCats , realLine );
1544+ if ( type <= 0 )
15141545 {
1515- QgsGrass::warning ( error );
1546+ QgsDebugMsg ( " cannot read line" );
1547+ }
1548+ else
1549+ {
1550+ if ( Vect_field_cat_del ( mCats , mLayerField , realCat ) == 0 )
1551+ {
1552+ // should not happen
1553+ QgsDebugMsg ( " the line does not have old category" );
1554+ }
1555+
1556+ int newCat = value.toInt ();
1557+ QgsDebugMsg ( QString ( " realCat = %1 newCat = %2" ).arg ( realCat ).arg ( newCat ) );
1558+ if ( newCat == 0 )
1559+ {
1560+ QgsDebugMsg ( " new category is 0" );
1561+ // TODO: remove category from line?
1562+ }
1563+ else
1564+ {
1565+ Vect_cat_set ( mCats , mLayerField , newCat );
1566+ mLayer ->map ()->lockReadWrite ();
1567+ int newLid = rewriteLine ( realLine, type, mPoints , mCats );
1568+ Q_UNUSED ( newLid )
1569+
1570+ // TODO: - store the new cat somewhere for cats mapping
1571+ // - insert record if does not exist
1572+ // - update feature attributes by existing record?
1573+
1574+ mLayer ->map ()->unlockReadWrite ();
1575+ }
15161576 }
15171577 }
15181578 else
15191579 {
1520- QgsDebugMsg ( " no cat -> add new cat to line" );
1521- // TODO
1580+
1581+ if ( realCat > 0 )
1582+ {
1583+ QString error;
1584+ mLayer ->changeAttributeValue ( realCat, field, value, error );
1585+ if ( !error.isEmpty () )
1586+ {
1587+ QgsGrass::warning ( error );
1588+ }
1589+ }
1590+ else
1591+ {
1592+ QgsDebugMsg ( " no cat -> add new cat to line" );
1593+ // TODO
1594+ }
15221595 }
15231596}
15241597
@@ -1574,8 +1647,7 @@ void QgsGrassProvider::setAddedFeaturesSymbol()
15741647 Q_FOREACH ( QgsFeatureId fid, features.keys () )
15751648 {
15761649 QgsFeature feature = features[fid];
1577- if ( !feature.geometry () || !feature.geometry ()->geometry () ||
1578- feature.geometry ()->geometry ()->wkbType () != QgsWKBTypes::LineString )
1650+ if ( !feature.geometry () || !feature.geometry ()->geometry () )
15791651 {
15801652 continue ;
15811653 }
0 commit comments