QGIS API Documentation  2.0.1-Dufour
 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() )
55 
56  emit mBuffer->featureDeleted( mFeature.id() );
57 }
58 
60 {
62 
63  if ( 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  {
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 
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  {
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  {
214  }
217 }
218 
219 
221  : QgsVectorLayerUndoCommand( buffer )
222  , mFid( fid )
223  , mFieldIndex( fieldIndex )
224  , mNewValue( newValue )
225  , mFirstChange( true )
226 {
227  if ( FID_IS_NEW( mFid ) )
228  {
229  // work with added feature
230  QgsFeatureMap::const_iterator it = mBuffer->mAddedFeatures.find( mFid );
231  Q_ASSERT( it != mBuffer->mAddedFeatures.end() );
232  if ( it.value().attribute( mFieldIndex ).isValid() )
233  {
234  mOldValue = it.value().attribute( mFieldIndex );
235  mFirstChange = false;
236  }
237  }
238  else
239  {
241  {
243  mFirstChange = false;
244  }
245  }
246 
247 }
248 
250 {
251  QVariant original = mOldValue;
252 
253  if ( FID_IS_NEW( mFid ) )
254  {
255  // added feature
256  QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.find( mFid );
257  Q_ASSERT( it != mBuffer->mAddedFeatures.end() );
258  it.value().setAttribute( mFieldIndex, mOldValue );
259  }
260  else
261  {
262  // existing feature
263  if ( mFirstChange )
264  {
266  if ( mBuffer->mChangedAttributeValues[mFid].isEmpty() )
268 
269  // get old value from provider
270  QgsFeature tmp;
271  QgsFeatureRequest request;
272  request.setFilterFid( mFid );
275  QgsFeatureIterator fi = layer()->getFeatures( request );
276  if ( fi.nextFeature( tmp ) )
277  original = tmp.attribute( mFieldIndex );
278  }
279  else
280  {
282  }
283  }
284 
285  emit mBuffer->attributeValueChanged( mFid, mFieldIndex, original );
286 }
287 
289 {
290  if ( FID_IS_NEW( mFid ) )
291  {
292  // updated added feature
293  QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.find( mFid );
294  Q_ASSERT( it != mBuffer->mAddedFeatures.end() );
295  it.value().setAttribute( mFieldIndex, mNewValue );
296  }
297  else
298  {
299  // changed attribute of existing feature
300  if ( !mBuffer->mChangedAttributeValues.contains( mFid ) )
301  {
303  }
304 
306  }
307 
309 }
310 
311 
313  : QgsVectorLayerUndoCommand( buffer )
314  , mField( field )
315 {
317 }
318 
320 {
321  int index = layer()->pendingFields().fieldOriginIndex( mFieldIndex );
322 
323  mBuffer->mAddedAttributes.removeAt( index );
326 
328 }
329 
331 {
332  mBuffer->mAddedAttributes.append( mField );
335 
337 }
338 
339 
341  : QgsVectorLayerUndoCommand( buffer )
342  , mFieldIndex( fieldIndex )
343 {
344  const QgsFields& fields = layer()->pendingFields();
348 
349  if ( !mProviderField )
350  {
351  // need to store the field definition
353  }
354 
355  // save values of new features
356  for ( QgsFeatureMap::const_iterator it = mBuffer->mAddedFeatures.begin(); it != mBuffer->mAddedFeatures.end(); ++it )
357  {
358  const QgsFeature& f = it.value();
359  mDeletedValues.insert( f.id(), f.attribute( mFieldIndex ) );
360  }
361 
362  // save changed values
363  for ( QgsChangedAttributesMap::const_iterator it = mBuffer->mChangedAttributeValues.begin(); it != mBuffer->mChangedAttributeValues.end(); ++it )
364  {
365  const QgsAttributeMap& attrs = it.value();
366  if ( attrs.contains( mFieldIndex ) )
367  mDeletedValues.insert( it.key(), attrs[mFieldIndex] );
368  }
369 }
370 
372 {
373  if ( mProviderField )
374  {
376  }
377  else
378  {
379  // newly added attribute
381  }
382 
384  mBuffer->handleAttributeAdded( mFieldIndex ); // update changed attributes + new features
385 
386  // set previously used attributes of new features
387  for ( QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.begin(); it != mBuffer->mAddedFeatures.end(); ++it )
388  {
389  QgsFeature& f = it.value();
390  f.setAttribute( mFieldIndex, mDeletedValues.value( f.id() ) );
391  }
392  // set previously used changed attributes
393  for ( QMap<QgsFeatureId, QVariant>::const_iterator it = mDeletedValues.begin(); it != mDeletedValues.end(); ++it )
394  {
395  if ( !FID_IS_NEW( it.key() ) )
396  {
397  QgsAttributeMap& attrs = mBuffer->mChangedAttributeValues[it.key()]; // also adds record if nonexistant
398  attrs.insert( mFieldIndex, it.value() );
399  }
400  }
401 
403 }
404 
406 {
407  if ( mProviderField )
408  {
410  qSort( mBuffer->mDeletedAttributeIds ); // keep it sorted
411  }
412  else
413  {
414  // newly added attribute
415  mBuffer->mAddedAttributes.removeAt( mOriginIndex ); // removing temporary attribute
416  }
417 
419  mBuffer->handleAttributeDeleted( mFieldIndex ); // update changed attributes + new features
421 }