QGIS API Documentation  2.8.2-Wien
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgsvectorlayerundocommand.cpp
Go to the documentation of this file.
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 
17 
18 #include "qgsgeometry.h"
19 #include "qgsfeature.h"
20 #include "qgsvectorlayer.h"
21 #include "qgsgeometrycache.h"
23 
24 #include "qgslogger.h"
25 
26 
28  : QgsVectorLayerUndoCommand( buffer )
29 {
30  static int addedIdLowWaterMark = -1;
31 
32  //assign a temporary id to the feature (use negative numbers)
33  addedIdLowWaterMark--;
34 
35  QgsDebugMsg( "Assigned feature id " + QString::number( addedIdLowWaterMark ) );
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  f.setFeatureId( addedIdLowWaterMark );
41 
42  mFeature = f;
43 }
44 
46 {
47 #ifdef QGISDEBUG
48  QgsFeatureMap::const_iterator it = mBuffer->mAddedFeatures.find( mFeature.id() );
49  Q_ASSERT( it != mBuffer->mAddedFeatures.end() );
50 #endif
51  mBuffer->mAddedFeatures.remove( mFeature.id() );
52 
53  if ( mFeature.geometry() )
54  cache()->removeGeometry( mFeature.id() );
55 
56  emit mBuffer->featureDeleted( mFeature.id() );
57 }
58 
60 {
61  mBuffer->mAddedFeatures.insert( mFeature.id(), mFeature );
62 
63  if ( mFeature.geometry() )
64  cache()->cacheGeometry( mFeature.id(), *mFeature.geometry() );
65 
66  emit mBuffer->featureAdded( mFeature.id() );
67 }
68 
69 
70 
72  : QgsVectorLayerUndoCommand( buffer )
73 {
74  mFid = fid;
75 
76  if ( FID_IS_NEW( mFid ) )
77  {
78  QgsFeatureMap::const_iterator it = mBuffer->mAddedFeatures.find( mFid );
79  Q_ASSERT( it != mBuffer->mAddedFeatures.end() );
80  mOldAddedFeature = it.value();
81  }
82 }
83 
85 {
86  if ( FID_IS_NEW( mFid ) )
87  {
88  mBuffer->mAddedFeatures.insert( mOldAddedFeature.id(), mOldAddedFeature );
89  }
90  else
91  {
92  mBuffer->mDeletedFeatureIds.remove( mFid );
93  }
94 
95  emit mBuffer->featureAdded( mFid );
96 }
97 
99 {
100  if ( FID_IS_NEW( mFid ) )
101  {
102  mBuffer->mAddedFeatures.remove( mFid );
103  }
104  else
105  {
106  mBuffer->mDeletedFeatureIds.insert( mFid );
107  }
108 
109  emit mBuffer->featureDeleted( mFid );
110 }
111 
112 
113 
115  : QgsVectorLayerUndoCommand( buffer )
116  , mFid( fid )
117 {
118  if ( FID_IS_NEW( mFid ) )
119  {
120  QgsFeatureMap::const_iterator it = mBuffer->mAddedFeatures.find( mFid );
121  Q_ASSERT( it != mBuffer->mAddedFeatures.end() );
122  mOldGeom = new QgsGeometry( *it.value().geometry() );
123  }
124  else
125  {
126  bool changedAlready = mBuffer->mChangedGeometries.contains( mFid );
127  QgsGeometry geom;
128  bool cachedGeom = cache()->geometry( mFid, geom );
129  mOldGeom = ( changedAlready && cachedGeom ) ? new QgsGeometry( geom ) : 0;
130  }
131 
132  mNewGeom = new QgsGeometry( *newGeom );
133 }
134 
136 {
137  return 1;
138 }
139 
140 bool QgsVectorLayerUndoCommandChangeGeometry::mergeWith( const QUndoCommand *other )
141 {
142  if ( other->id() != id() )
143  return false;
144 
145  const QgsVectorLayerUndoCommandChangeGeometry *merge = dynamic_cast<const QgsVectorLayerUndoCommandChangeGeometry *>( other );
146  if ( !merge )
147  return false;
148 
149  if ( merge->mFid != mFid )
150  return false;
151 
152  delete mNewGeom;
153  mNewGeom = merge->mNewGeom;
154  merge->mNewGeom = 0;
155 
156  return true;
157 }
158 
160 {
161  delete mOldGeom;
162  delete mNewGeom;
163 }
164 
166 {
167  if ( FID_IS_NEW( mFid ) )
168  {
169  // modify added features
170  QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.find( mFid );
171  Q_ASSERT( it != mBuffer->mAddedFeatures.end() );
172  it.value().setGeometry( *mOldGeom );
173 
174  cache()->cacheGeometry( mFid, *mOldGeom );
175  emit mBuffer->geometryChanged( mFid, *mOldGeom );
176  }
177  else
178  {
179  // existing feature
180 
181  if ( !mOldGeom )
182  {
183  mBuffer->mChangedGeometries.remove( mFid );
184 
185  QgsFeature f;
186  if ( layer()->getFeatures( QgsFeatureRequest().setFilterFid( mFid ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) && f.geometry() )
187  {
188  cache()->cacheGeometry( mFid, *f.geometry() );
189  emit mBuffer->geometryChanged( mFid, *f.geometry() );
190  }
191  }
192  else
193  {
194  mBuffer->mChangedGeometries[mFid] = *mOldGeom;
195  cache()->cacheGeometry( mFid, *mOldGeom );
196  emit mBuffer->geometryChanged( mFid, *mOldGeom );
197  }
198  }
199 
200 }
201 
203 {
204  if ( FID_IS_NEW( mFid ) )
205  {
206  // modify added features
207  QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.find( mFid );
208  Q_ASSERT( it != mBuffer->mAddedFeatures.end() );
209  it.value().setGeometry( *mNewGeom );
210  }
211  else
212  {
213  mBuffer->mChangedGeometries[ mFid ] = *mNewGeom;
214  }
215  cache()->cacheGeometry( mFid, *mNewGeom );
216  emit mBuffer->geometryChanged( mFid, *mNewGeom );
217 }
218 
219 
220 QgsVectorLayerUndoCommandChangeAttribute::QgsVectorLayerUndoCommandChangeAttribute( QgsVectorLayerEditBuffer* buffer, QgsFeatureId fid, int fieldIndex, const QVariant &newValue, const QVariant &oldValue )
221  : QgsVectorLayerUndoCommand( buffer )
222  , mFid( fid )
223  , mFieldIndex( fieldIndex )
224  , mOldValue( oldValue )
225  , mNewValue( newValue )
226  , mFirstChange( true )
227 {
228  if ( FID_IS_NEW( mFid ) )
229  {
230  // work with added feature
231  QgsFeatureMap::const_iterator it = mBuffer->mAddedFeatures.find( mFid );
232  Q_ASSERT( it != mBuffer->mAddedFeatures.end() );
233  if ( it.value().attribute( mFieldIndex ).isValid() )
234  {
235  mOldValue = it.value().attribute( mFieldIndex );
236  mFirstChange = false;
237  }
238  }
239  else if ( mBuffer->mChangedAttributeValues.contains( mFid ) && mBuffer->mChangedAttributeValues[mFid].contains( mFieldIndex ) )
240  {
241  mOldValue = mBuffer->mChangedAttributeValues[mFid][mFieldIndex];
242  mFirstChange = false;
243  }
244 
245 }
246 
248 {
249  QVariant original = mOldValue;
250 
251  if ( FID_IS_NEW( mFid ) )
252  {
253  // added feature
254  QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.find( mFid );
255  Q_ASSERT( it != mBuffer->mAddedFeatures.end() );
256  it.value().setAttribute( mFieldIndex, mOldValue );
257  }
258  else if ( mFirstChange )
259  {
260  // existing feature
261  mBuffer->mChangedAttributeValues[mFid].remove( mFieldIndex );
262  if ( mBuffer->mChangedAttributeValues[mFid].isEmpty() )
263  mBuffer->mChangedAttributeValues.remove( mFid );
264 
265  if ( !mOldValue.isValid() )
266  {
267  // get old value from provider
268  QgsFeature tmp;
269  QgsFeatureRequest request;
270  request.setFilterFid( mFid );
272  request.setSubsetOfAttributes( QgsAttributeList() << mFieldIndex );
273  QgsFeatureIterator fi = layer()->getFeatures( request );
274  if ( fi.nextFeature( tmp ) )
275  original = tmp.attribute( mFieldIndex );
276  }
277  }
278  else
279  {
280  mBuffer->mChangedAttributeValues[mFid][mFieldIndex] = mOldValue;
281  }
282 
283  emit mBuffer->attributeValueChanged( mFid, mFieldIndex, original );
284 }
285 
287 {
288  if ( FID_IS_NEW( mFid ) )
289  {
290  // updated added feature
291  QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.find( mFid );
292  Q_ASSERT( it != mBuffer->mAddedFeatures.end() );
293  it.value().setAttribute( mFieldIndex, mNewValue );
294  }
295  else
296  {
297  // changed attribute of existing feature
298  if ( !mBuffer->mChangedAttributeValues.contains( mFid ) )
299  {
301  }
302 
303  mBuffer->mChangedAttributeValues[mFid].insert( mFieldIndex, mNewValue );
304  }
305 
306  emit mBuffer->attributeValueChanged( mFid, mFieldIndex, mNewValue );
307 }
308 
309 
311  : QgsVectorLayerUndoCommand( buffer )
312  , mField( field )
313 {
314  const QgsFields &fields = layer()->pendingFields();
315  int i;
316  for ( i = 0; i < fields.count() && fields.fieldOrigin( i ) != QgsFields::OriginJoin; i++ )
317  ;
318  mFieldIndex = i;
319 }
320 
322 {
323  int index = layer()->pendingFields().fieldOriginIndex( mFieldIndex );
324 
325  mBuffer->mAddedAttributes.removeAt( index );
327  mBuffer->handleAttributeDeleted( mFieldIndex );
328 
329  emit mBuffer->attributeDeleted( mFieldIndex );
330 }
331 
333 {
334  mBuffer->mAddedAttributes.append( mField );
336  mBuffer->handleAttributeAdded( mFieldIndex );
337 
338  emit mBuffer->attributeAdded( mFieldIndex );
339 }
340 
341 
343  : QgsVectorLayerUndoCommand( buffer )
344  , mFieldIndex( fieldIndex )
345 {
346  const QgsFields& fields = layer()->pendingFields();
347  QgsFields::FieldOrigin origin = fields.fieldOrigin( mFieldIndex );
348  mOriginIndex = fields.fieldOriginIndex( mFieldIndex );
349  mProviderField = ( origin == QgsFields::OriginProvider );
350 
351  if ( !mProviderField )
352  {
353  // need to store the field definition
354  mOldField = mBuffer->mAddedAttributes[mOriginIndex];
355  }
356 
357  // save values of new features
358  for ( QgsFeatureMap::const_iterator it = mBuffer->mAddedFeatures.begin(); it != mBuffer->mAddedFeatures.end(); ++it )
359  {
360  const QgsFeature& f = it.value();
361  mDeletedValues.insert( f.id(), f.attribute( mFieldIndex ) );
362  }
363 
364  // save changed values
365  for ( QgsChangedAttributesMap::const_iterator it = mBuffer->mChangedAttributeValues.begin(); it != mBuffer->mChangedAttributeValues.end(); ++it )
366  {
367  const QgsAttributeMap& attrs = it.value();
368  if ( attrs.contains( mFieldIndex ) )
369  mDeletedValues.insert( it.key(), attrs[mFieldIndex] );
370  }
371 }
372 
374 {
375  if ( mProviderField )
376  {
377  mBuffer->mDeletedAttributeIds.removeOne( mOriginIndex );
378  }
379  else
380  {
381  // newly added attribute
382  mBuffer->mAddedAttributes.insert( mOriginIndex, mOldField );
383  }
384 
386  mBuffer->handleAttributeAdded( mFieldIndex ); // update changed attributes + new features
387 
388  // set previously used attributes of new features
389  for ( QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.begin(); it != mBuffer->mAddedFeatures.end(); ++it )
390  {
391  QgsFeature& f = it.value();
392  f.setAttribute( mFieldIndex, mDeletedValues.value( f.id() ) );
393  }
394  // set previously used changed attributes
395  for ( QMap<QgsFeatureId, QVariant>::const_iterator it = mDeletedValues.begin(); it != mDeletedValues.end(); ++it )
396  {
397  if ( !FID_IS_NEW( it.key() ) )
398  {
399  QgsAttributeMap& attrs = mBuffer->mChangedAttributeValues[it.key()]; // also adds record if nonexistant
400  attrs.insert( mFieldIndex, it.value() );
401  }
402  }
403 
404  emit mBuffer->attributeAdded( mFieldIndex );
405 }
406 
408 {
409  if ( mProviderField )
410  {
411  mBuffer->mDeletedAttributeIds.append( mOriginIndex );
412  qSort( mBuffer->mDeletedAttributeIds ); // keep it sorted
413  }
414  else
415  {
416  // newly added attribute
417  mBuffer->mAddedAttributes.removeAt( mOriginIndex ); // removing temporary attribute
418  }
419 
421  mBuffer->handleAttributeDeleted( mFieldIndex ); // update changed attributes + new features
422  emit mBuffer->attributeDeleted( mFieldIndex );
423 }