Branch data Line data Source code
1 : : /***************************************************************************
2 : : qgsvectorlayerundocommand.cpp
3 : : ---------------------
4 : : begin : June 2009
5 : : copyright : (C) 2009 by Martin Dobias
6 : : email : wonder dot sk at gmail dot com
7 : : ***************************************************************************
8 : : * *
9 : : * This program is free software; you can redistribute it and/or modify *
10 : : * it under the terms of the GNU General Public License as published by *
11 : : * the Free Software Foundation; either version 2 of the License, or *
12 : : * (at your option) any later version. *
13 : : * *
14 : : ***************************************************************************/
15 : :
16 : : #include "qgsvectorlayerundocommand.h"
17 : :
18 : : #include "qgsfeatureiterator.h"
19 : : #include "qgsgeometry.h"
20 : : #include "qgsfeature.h"
21 : : #include "qgsvectorlayer.h"
22 : : #include "qgsvectorlayereditbuffer.h"
23 : :
24 : : #include "qgslogger.h"
25 : :
26 : :
27 : 1 : QgsVectorLayerUndoCommandAddFeature::QgsVectorLayerUndoCommandAddFeature( QgsVectorLayerEditBuffer *buffer, QgsFeature &f )
28 : 1 : : QgsVectorLayerUndoCommand( buffer )
29 : 2 : {
30 : : static int sAddedIdLowWaterMark = -1;
31 : :
32 : : //assign a temporary id to the feature (use negative numbers)
33 : 1 : sAddedIdLowWaterMark--;
34 : :
35 : 1 : QgsDebugMsgLevel( "Assigned feature id " + QString::number( sAddedIdLowWaterMark ), 4 );
36 : :
37 : : // Force a feature ID (to keep other functions in QGIS happy,
38 : : // providers will use their own new feature ID when we commit the new feature)
39 : : // and add to the known added features.
40 : 1 : f.setId( sAddedIdLowWaterMark );
41 : :
42 : 1 : mFeature = f;
43 : 1 : }
44 : :
45 : 0 : void QgsVectorLayerUndoCommandAddFeature::undo()
46 : : {
47 : : #ifndef QT_NO_DEBUG
48 : : QgsFeatureMap::const_iterator it = mBuffer->mAddedFeatures.constFind( mFeature.id() );
49 : : Q_ASSERT( it != mBuffer->mAddedFeatures.constEnd() );
50 : : #endif
51 : 0 : mBuffer->mAddedFeatures.remove( mFeature.id() );
52 : :
53 : 0 : emit mBuffer->featureDeleted( mFeature.id() );
54 : 0 : }
55 : :
56 : 1 : void QgsVectorLayerUndoCommandAddFeature::redo()
57 : : {
58 : 1 : mBuffer->mAddedFeatures.insert( mFeature.id(), mFeature );
59 : :
60 : 1 : emit mBuffer->featureAdded( mFeature.id() );
61 : 1 : }
62 : :
63 : :
64 : :
65 : 0 : QgsVectorLayerUndoCommandDeleteFeature::QgsVectorLayerUndoCommandDeleteFeature( QgsVectorLayerEditBuffer *buffer, QgsFeatureId fid )
66 : 0 : : QgsVectorLayerUndoCommand( buffer )
67 : 0 : {
68 : 0 : mFid = fid;
69 : :
70 : 0 : if ( FID_IS_NEW( mFid ) )
71 : : {
72 : 0 : QgsFeatureMap::const_iterator it = mBuffer->mAddedFeatures.constFind( mFid );
73 : : Q_ASSERT( it != mBuffer->mAddedFeatures.constEnd() );
74 : 0 : mOldAddedFeature = it.value();
75 : 0 : }
76 : 0 : }
77 : :
78 : 0 : void QgsVectorLayerUndoCommandDeleteFeature::undo()
79 : : {
80 : 0 : if ( FID_IS_NEW( mFid ) )
81 : : {
82 : 0 : mBuffer->mAddedFeatures.insert( mOldAddedFeature.id(), mOldAddedFeature );
83 : 0 : }
84 : : else
85 : : {
86 : 0 : mBuffer->mDeletedFeatureIds.remove( mFid );
87 : : }
88 : :
89 : 0 : emit mBuffer->featureAdded( mFid );
90 : 0 : }
91 : :
92 : 0 : void QgsVectorLayerUndoCommandDeleteFeature::redo()
93 : : {
94 : 0 : if ( FID_IS_NEW( mFid ) )
95 : : {
96 : 0 : mBuffer->mAddedFeatures.remove( mFid );
97 : 0 : }
98 : : else
99 : : {
100 : 0 : mBuffer->mDeletedFeatureIds.insert( mFid );
101 : : }
102 : :
103 : 0 : emit mBuffer->featureDeleted( mFid );
104 : 0 : }
105 : :
106 : :
107 : :
108 : 1 : QgsVectorLayerUndoCommandChangeGeometry::QgsVectorLayerUndoCommandChangeGeometry( QgsVectorLayerEditBuffer *buffer, QgsFeatureId fid, const QgsGeometry &newGeom )
109 : 1 : : QgsVectorLayerUndoCommand( buffer )
110 : 1 : , mFid( fid )
111 : 1 : , mNewGeom( newGeom )
112 : 2 : {
113 : 1 : if ( FID_IS_NEW( mFid ) )
114 : : {
115 : 1 : QgsFeatureMap::const_iterator it = mBuffer->mAddedFeatures.constFind( mFid );
116 : : Q_ASSERT( it != mBuffer->mAddedFeatures.constEnd() );
117 : 1 : mOldGeom = ( it.value().geometry() );
118 : 1 : }
119 : : else
120 : : {
121 : 0 : mOldGeom = mBuffer->mChangedGeometries.value( mFid, QgsGeometry() );
122 : : }
123 : 1 : }
124 : :
125 : :
126 : :
127 : 0 : bool QgsVectorLayerUndoCommandChangeGeometry::mergeWith( const QUndoCommand *other )
128 : : {
129 : 0 : if ( other->id() != id() )
130 : 0 : return false;
131 : :
132 : 0 : const QgsVectorLayerUndoCommandChangeGeometry *merge = dynamic_cast<const QgsVectorLayerUndoCommandChangeGeometry *>( other );
133 : 0 : if ( !merge )
134 : 0 : return false;
135 : :
136 : 0 : if ( merge->mFid != mFid )
137 : 0 : return false;
138 : :
139 : 0 : mNewGeom = merge->mNewGeom;
140 : 0 : merge->mNewGeom = QgsGeometry();
141 : :
142 : 0 : return true;
143 : 0 : }
144 : :
145 : 0 : void QgsVectorLayerUndoCommandChangeGeometry::undo()
146 : : {
147 : 0 : if ( FID_IS_NEW( mFid ) )
148 : : {
149 : : // modify added features
150 : 0 : QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.find( mFid );
151 : : Q_ASSERT( it != mBuffer->mAddedFeatures.end() );
152 : 0 : it.value().setGeometry( mOldGeom );
153 : :
154 : 0 : emit mBuffer->geometryChanged( mFid, mOldGeom );
155 : 0 : }
156 : : else
157 : : {
158 : : // existing feature
159 : :
160 : 0 : if ( mOldGeom.isNull() )
161 : : {
162 : 0 : mBuffer->mChangedGeometries.remove( mFid );
163 : :
164 : 0 : QgsFeature f;
165 : 0 : if ( layer()->getFeatures( QgsFeatureRequest().setFilterFid( mFid ).setNoAttributes() ).nextFeature( f ) && f.hasGeometry() )
166 : : {
167 : 0 : emit mBuffer->geometryChanged( mFid, f.geometry() );
168 : 0 : }
169 : 0 : }
170 : : else
171 : : {
172 : 0 : mBuffer->mChangedGeometries[mFid] = mOldGeom;
173 : 0 : emit mBuffer->geometryChanged( mFid, mOldGeom );
174 : : }
175 : : }
176 : :
177 : 0 : }
178 : :
179 : 1 : void QgsVectorLayerUndoCommandChangeGeometry::redo()
180 : : {
181 : 1 : if ( FID_IS_NEW( mFid ) )
182 : : {
183 : : // modify added features
184 : 1 : QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.find( mFid );
185 : : Q_ASSERT( it != mBuffer->mAddedFeatures.end() );
186 : 1 : it.value().setGeometry( mNewGeom );
187 : 1 : }
188 : : else
189 : : {
190 : 0 : mBuffer->mChangedGeometries[ mFid ] = mNewGeom;
191 : : }
192 : 1 : emit mBuffer->geometryChanged( mFid, mNewGeom );
193 : 1 : }
194 : :
195 : :
196 : 0 : QgsVectorLayerUndoCommandChangeAttribute::QgsVectorLayerUndoCommandChangeAttribute( QgsVectorLayerEditBuffer *buffer, QgsFeatureId fid, int fieldIndex, const QVariant &newValue, const QVariant &oldValue )
197 : 0 : : QgsVectorLayerUndoCommand( buffer )
198 : 0 : , mFid( fid )
199 : 0 : , mFieldIndex( fieldIndex )
200 : 0 : , mOldValue( oldValue )
201 : 0 : , mNewValue( newValue )
202 : 0 : , mFirstChange( true )
203 : 0 : {
204 : 0 : if ( FID_IS_NEW( mFid ) )
205 : : {
206 : : // work with added feature
207 : 0 : QgsFeatureMap::const_iterator it = mBuffer->mAddedFeatures.constFind( mFid );
208 : : Q_ASSERT( it != mBuffer->mAddedFeatures.constEnd() );
209 : 0 : if ( it.value().attribute( mFieldIndex ).isValid() )
210 : : {
211 : 0 : mOldValue = it.value().attribute( mFieldIndex );
212 : 0 : mFirstChange = false;
213 : 0 : }
214 : 0 : }
215 : 0 : else if ( mBuffer->mChangedAttributeValues.contains( mFid ) && mBuffer->mChangedAttributeValues[mFid].contains( mFieldIndex ) )
216 : : {
217 : 0 : mOldValue = mBuffer->mChangedAttributeValues[mFid][mFieldIndex];
218 : 0 : mFirstChange = false;
219 : 0 : }
220 : :
221 : 0 : }
222 : :
223 : 0 : void QgsVectorLayerUndoCommandChangeAttribute::undo()
224 : : {
225 : 0 : QVariant original = mOldValue;
226 : :
227 : 0 : if ( FID_IS_NEW( mFid ) )
228 : : {
229 : : // added feature
230 : 0 : QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.find( mFid );
231 : : Q_ASSERT( it != mBuffer->mAddedFeatures.end() );
232 : 0 : it.value().setAttribute( mFieldIndex, mOldValue );
233 : 0 : }
234 : 0 : else if ( mFirstChange )
235 : : {
236 : : // existing feature
237 : 0 : mBuffer->mChangedAttributeValues[mFid].remove( mFieldIndex );
238 : 0 : if ( mBuffer->mChangedAttributeValues[mFid].isEmpty() )
239 : 0 : mBuffer->mChangedAttributeValues.remove( mFid );
240 : :
241 : 0 : if ( !mOldValue.isValid() )
242 : : {
243 : : // get old value from provider
244 : 0 : QgsFeature tmp;
245 : 0 : QgsFeatureRequest request;
246 : 0 : request.setFilterFid( mFid );
247 : 0 : request.setFlags( QgsFeatureRequest::NoGeometry );
248 : 0 : request.setSubsetOfAttributes( QgsAttributeList() << mFieldIndex );
249 : 0 : QgsFeatureIterator fi = layer()->getFeatures( request );
250 : 0 : if ( fi.nextFeature( tmp ) )
251 : 0 : original = tmp.attribute( mFieldIndex );
252 : 0 : }
253 : 0 : }
254 : : else
255 : : {
256 : 0 : mBuffer->mChangedAttributeValues[mFid][mFieldIndex] = mOldValue;
257 : : }
258 : :
259 : 0 : emit mBuffer->attributeValueChanged( mFid, mFieldIndex, original );
260 : 0 : }
261 : :
262 : 0 : void QgsVectorLayerUndoCommandChangeAttribute::redo()
263 : : {
264 : 0 : if ( FID_IS_NEW( mFid ) )
265 : : {
266 : : // updated added feature
267 : 0 : QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.find( mFid );
268 : : Q_ASSERT( it != mBuffer->mAddedFeatures.end() );
269 : 0 : it.value().setAttribute( mFieldIndex, mNewValue );
270 : 0 : }
271 : : else
272 : : {
273 : : // changed attribute of existing feature
274 : 0 : if ( !mBuffer->mChangedAttributeValues.contains( mFid ) )
275 : : {
276 : 0 : mBuffer->mChangedAttributeValues.insert( mFid, QgsAttributeMap() );
277 : 0 : }
278 : :
279 : 0 : mBuffer->mChangedAttributeValues[mFid].insert( mFieldIndex, mNewValue );
280 : : }
281 : :
282 : 0 : emit mBuffer->attributeValueChanged( mFid, mFieldIndex, mNewValue );
283 : 0 : }
284 : :
285 : :
286 : 0 : QgsVectorLayerUndoCommandAddAttribute::QgsVectorLayerUndoCommandAddAttribute( QgsVectorLayerEditBuffer *buffer, const QgsField &field )
287 : 0 : : QgsVectorLayerUndoCommand( buffer )
288 : 0 : , mField( field )
289 : 0 : {
290 : 0 : const QgsFields &fields = layer()->fields();
291 : : int i;
292 : 0 : for ( i = 0; i < fields.count() && fields.fieldOrigin( i ) != QgsFields::OriginJoin; i++ )
293 : : ;
294 : 0 : mFieldIndex = i;
295 : 0 : }
296 : :
297 : 0 : void QgsVectorLayerUndoCommandAddAttribute::undo()
298 : : {
299 : 0 : int index = layer()->fields().fieldOriginIndex( mFieldIndex );
300 : :
301 : 0 : mBuffer->mAddedAttributes.removeAt( index );
302 : 0 : mBuffer->handleAttributeDeleted( mFieldIndex );
303 : 0 : mBuffer->updateLayerFields();
304 : :
305 : 0 : emit mBuffer->attributeDeleted( mFieldIndex );
306 : 0 : }
307 : :
308 : 0 : void QgsVectorLayerUndoCommandAddAttribute::redo()
309 : : {
310 : 0 : mBuffer->mAddedAttributes.append( mField );
311 : 0 : mBuffer->handleAttributeAdded( mFieldIndex );
312 : 0 : mBuffer->updateLayerFields();
313 : :
314 : 0 : emit mBuffer->attributeAdded( mFieldIndex );
315 : 0 : }
316 : :
317 : :
318 : 0 : QgsVectorLayerUndoCommandDeleteAttribute::QgsVectorLayerUndoCommandDeleteAttribute( QgsVectorLayerEditBuffer *buffer, int fieldIndex )
319 : 0 : : QgsVectorLayerUndoCommand( buffer )
320 : 0 : , mFieldIndex( fieldIndex )
321 : 0 : {
322 : 0 : const QgsFields &fields = layer()->fields();
323 : 0 : QgsFields::FieldOrigin origin = fields.fieldOrigin( mFieldIndex );
324 : 0 : mOriginIndex = fields.fieldOriginIndex( mFieldIndex );
325 : 0 : mProviderField = ( origin == QgsFields::OriginProvider );
326 : 0 : mFieldName = fields.field( mFieldIndex ).name();
327 : :
328 : 0 : if ( !mProviderField )
329 : : {
330 : : // need to store the field definition
331 : 0 : mOldField = mBuffer->mAddedAttributes[mOriginIndex];
332 : 0 : }
333 : :
334 : 0 : if ( mBuffer->mRenamedAttributes.contains( fieldIndex ) )
335 : : {
336 : 0 : mOldName = mBuffer->mRenamedAttributes.value( fieldIndex );
337 : 0 : }
338 : :
339 : : // save values of new features
340 : 0 : for ( QgsFeatureMap::const_iterator it = mBuffer->mAddedFeatures.constBegin(); it != mBuffer->mAddedFeatures.constEnd(); ++it )
341 : : {
342 : 0 : const QgsFeature &f = it.value();
343 : 0 : mDeletedValues.insert( f.id(), f.attribute( mFieldIndex ) );
344 : 0 : }
345 : :
346 : : // save changed values
347 : 0 : for ( QgsChangedAttributesMap::const_iterator it = mBuffer->mChangedAttributeValues.constBegin(); it != mBuffer->mChangedAttributeValues.constEnd(); ++it )
348 : : {
349 : 0 : const QgsAttributeMap &attrs = it.value();
350 : 0 : if ( attrs.contains( mFieldIndex ) )
351 : 0 : mDeletedValues.insert( it.key(), attrs[mFieldIndex] );
352 : 0 : }
353 : 0 : }
354 : :
355 : 0 : void QgsVectorLayerUndoCommandDeleteAttribute::undo()
356 : : {
357 : 0 : if ( mProviderField )
358 : : {
359 : 0 : mBuffer->mDeletedAttributeIds.removeOne( mOriginIndex );
360 : 0 : }
361 : : else
362 : : {
363 : : // newly added attribute
364 : 0 : mBuffer->mAddedAttributes.insert( mOriginIndex, mOldField );
365 : : }
366 : :
367 : 0 : mBuffer->updateLayerFields();
368 : 0 : mBuffer->handleAttributeAdded( mFieldIndex ); // update changed attributes + new features
369 : :
370 : 0 : if ( !mOldName.isEmpty() )
371 : : {
372 : 0 : mBuffer->mRenamedAttributes[ mFieldIndex ] = mOldName;
373 : 0 : mBuffer->updateLayerFields();
374 : 0 : }
375 : :
376 : : // set previously used attributes of new features
377 : 0 : for ( QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.begin(); it != mBuffer->mAddedFeatures.end(); ++it )
378 : : {
379 : 0 : QgsFeature &f = it.value();
380 : 0 : f.setAttribute( mFieldIndex, mDeletedValues.value( f.id() ) );
381 : 0 : }
382 : : // set previously used changed attributes
383 : 0 : for ( QMap<QgsFeatureId, QVariant>::const_iterator it = mDeletedValues.constBegin(); it != mDeletedValues.constEnd(); ++it )
384 : : {
385 : 0 : if ( !FID_IS_NEW( it.key() ) )
386 : : {
387 : 0 : QgsAttributeMap &attrs = mBuffer->mChangedAttributeValues[it.key()]; // also adds record if nonexistent
388 : 0 : attrs.insert( mFieldIndex, it.value() );
389 : 0 : }
390 : 0 : }
391 : :
392 : 0 : QgsEditFormConfig formConfig = mBuffer->L->editFormConfig();
393 : 0 : mBuffer->L->setEditFormConfig( formConfig );
394 : :
395 : 0 : emit mBuffer->attributeAdded( mFieldIndex );
396 : 0 : }
397 : :
398 : 0 : void QgsVectorLayerUndoCommandDeleteAttribute::redo()
399 : : {
400 : 0 : if ( mProviderField )
401 : : {
402 : 0 : mBuffer->mDeletedAttributeIds.append( mOriginIndex );
403 : 0 : std::sort( mBuffer->mDeletedAttributeIds.begin(), mBuffer->mDeletedAttributeIds.end() ); // keep it sorted
404 : 0 : }
405 : : else
406 : : {
407 : : // newly added attribute
408 : 0 : mBuffer->mAddedAttributes.removeAt( mOriginIndex ); // removing temporary attribute
409 : : }
410 : :
411 : 0 : mBuffer->handleAttributeDeleted( mFieldIndex ); // update changed attributes + new features
412 : 0 : mBuffer->updateLayerFields();
413 : 0 : emit mBuffer->attributeDeleted( mFieldIndex );
414 : 0 : }
415 : :
416 : :
417 : 0 : QgsVectorLayerUndoCommandRenameAttribute::QgsVectorLayerUndoCommandRenameAttribute( QgsVectorLayerEditBuffer *buffer, int fieldIndex, const QString &newName )
418 : 0 : : QgsVectorLayerUndoCommand( buffer )
419 : 0 : , mFieldIndex( fieldIndex )
420 : 0 : , mOldName( layer()->fields().at( fieldIndex ).name() )
421 : 0 : , mNewName( newName )
422 : 0 : {
423 : 0 : const QgsFields &fields = layer()->fields();
424 : 0 : QgsFields::FieldOrigin origin = fields.fieldOrigin( mFieldIndex );
425 : 0 : mOriginIndex = fields.fieldOriginIndex( mFieldIndex );
426 : 0 : mProviderField = ( origin == QgsFields::OriginProvider );
427 : 0 : }
428 : :
429 : 0 : void QgsVectorLayerUndoCommandRenameAttribute::undo()
430 : : {
431 : 0 : if ( mProviderField )
432 : : {
433 : 0 : mBuffer->mRenamedAttributes[ mFieldIndex ] = mOldName;
434 : 0 : }
435 : : else
436 : : {
437 : : // newly added attribute
438 : 0 : mBuffer->mAddedAttributes[mOriginIndex].setName( mOldName );
439 : : }
440 : 0 : mBuffer->updateLayerFields();
441 : 0 : emit mBuffer->attributeRenamed( mFieldIndex, mOldName );
442 : 0 : }
443 : :
444 : 0 : void QgsVectorLayerUndoCommandRenameAttribute::redo()
445 : : {
446 : 0 : if ( mProviderField )
447 : : {
448 : 0 : mBuffer->mRenamedAttributes[ mFieldIndex ] = mNewName;
449 : 0 : }
450 : : else
451 : : {
452 : : // newly added attribute
453 : 0 : mBuffer->mAddedAttributes[mOriginIndex].setName( mNewName );
454 : : }
455 : 0 : mBuffer->updateLayerFields();
456 : 0 : emit mBuffer->attributeRenamed( mFieldIndex, mNewName );
457 : 0 : }
|