|
Quantum GIS API Documentation
master-693a1fe
|
00001 /*************************************************************************** 00002 qgsvectorlayerundocommand.cpp 00003 --------------------- 00004 begin : June 2009 00005 copyright : (C) 2009 by Martin Dobias 00006 email : wonder dot sk at gmail dot com 00007 *************************************************************************** 00008 * * 00009 * This program is free software; you can redistribute it and/or modify * 00010 * it under the terms of the GNU General Public License as published by * 00011 * the Free Software Foundation; either version 2 of the License, or * 00012 * (at your option) any later version. * 00013 * * 00014 ***************************************************************************/ 00015 00016 #include "qgsvectorlayerundocommand.h" 00017 00018 #include "qgsgeometry.h" 00019 #include "qgsfeature.h" 00020 #include "qgsvectorlayer.h" 00021 #include "qgsgeometrycache.h" 00022 #include "qgsvectorlayereditbuffer.h" 00023 00024 #include "qgslogger.h" 00025 00026 00027 00028 00029 00030 QgsVectorLayerUndoCommandAddFeature::QgsVectorLayerUndoCommandAddFeature( QgsVectorLayerEditBuffer* buffer, QgsFeature& f ) 00031 : QgsVectorLayerUndoCommand( buffer ) 00032 { 00033 static int addedIdLowWaterMark = -1; 00034 00035 //assign a temporary id to the feature (use negative numbers) 00036 addedIdLowWaterMark--; 00037 00038 QgsDebugMsg( "Assigned feature id " + QString::number( addedIdLowWaterMark ) ); 00039 00040 // Force a feature ID (to keep other functions in QGIS happy, 00041 // providers will use their own new feature ID when we commit the new feature) 00042 // and add to the known added features. 00043 f.setFeatureId( addedIdLowWaterMark ); 00044 00045 mFeature = f; 00046 } 00047 00048 void QgsVectorLayerUndoCommandAddFeature::undo() 00049 { 00050 #ifdef QGISDEBUG 00051 QgsFeatureMap::const_iterator it = mBuffer->mAddedFeatures.find( mFeature.id() ); 00052 Q_ASSERT( it != mBuffer->mAddedFeatures.end() ); 00053 #endif 00054 mBuffer->mAddedFeatures.remove( mFeature.id() ); 00055 00056 if ( mFeature.geometry() ) 00057 cache()->removeGeometry( mFeature.id() ); 00058 00059 emit mBuffer->featureDeleted( mFeature.id() ); 00060 } 00061 00062 void QgsVectorLayerUndoCommandAddFeature::redo() 00063 { 00064 mBuffer->mAddedFeatures.insert( mFeature.id(), mFeature ); 00065 00066 if ( mFeature.geometry() ) 00067 cache()->cacheGeometry( mFeature.id(), *mFeature.geometry() ); 00068 00069 emit mBuffer->featureAdded( mFeature.id() ); 00070 } 00071 00072 00073 00074 QgsVectorLayerUndoCommandDeleteFeature::QgsVectorLayerUndoCommandDeleteFeature( QgsVectorLayerEditBuffer* buffer, QgsFeatureId fid ) 00075 : QgsVectorLayerUndoCommand( buffer ) 00076 { 00077 mFid = fid; 00078 00079 if ( FID_IS_NEW( mFid ) ) 00080 { 00081 QgsFeatureMap::const_iterator it = mBuffer->mAddedFeatures.find( mFid ); 00082 Q_ASSERT( it != mBuffer->mAddedFeatures.end() ); 00083 mOldAddedFeature = it.value(); 00084 } 00085 } 00086 00087 void QgsVectorLayerUndoCommandDeleteFeature::undo() 00088 { 00089 if ( FID_IS_NEW( mFid ) ) 00090 { 00091 mBuffer->mAddedFeatures.insert( mOldAddedFeature.id(), mOldAddedFeature ); 00092 } 00093 else 00094 { 00095 mBuffer->mDeletedFeatureIds.remove( mFid ); 00096 } 00097 00098 emit mBuffer->featureAdded( mFid ); 00099 } 00100 00101 void QgsVectorLayerUndoCommandDeleteFeature::redo() 00102 { 00103 if ( FID_IS_NEW( mFid ) ) 00104 { 00105 mBuffer->mAddedFeatures.remove( mFid ); 00106 } 00107 else 00108 { 00109 mBuffer->mDeletedFeatureIds.insert( mFid ); 00110 } 00111 00112 emit mBuffer->featureDeleted( mFid ); 00113 } 00114 00115 00116 00117 QgsVectorLayerUndoCommandChangeGeometry::QgsVectorLayerUndoCommandChangeGeometry( QgsVectorLayerEditBuffer* buffer, QgsFeatureId fid, QgsGeometry* newGeom ) 00118 : QgsVectorLayerUndoCommand( buffer ), 00119 mFid( fid ) 00120 { 00121 00122 if ( FID_IS_NEW( mFid ) ) 00123 { 00124 QgsFeatureMap::const_iterator it = mBuffer->mAddedFeatures.find( mFid ); 00125 Q_ASSERT( it != mBuffer->mAddedFeatures.end() ); 00126 mOldGeom = new QgsGeometry( *it.value().geometry() ); 00127 } 00128 else 00129 { 00130 bool changedAlready = mBuffer->mChangedGeometries.contains( mFid ); 00131 QgsGeometry geom; 00132 bool cachedGeom = cache()->geometry( mFid, geom ); 00133 mOldGeom = ( changedAlready && cachedGeom ) ? new QgsGeometry( geom ) : 0; 00134 } 00135 00136 mNewGeom = new QgsGeometry( *newGeom ); 00137 } 00138 00139 QgsVectorLayerUndoCommandChangeGeometry::~QgsVectorLayerUndoCommandChangeGeometry() 00140 { 00141 delete mOldGeom; 00142 delete mNewGeom; 00143 } 00144 00145 void QgsVectorLayerUndoCommandChangeGeometry::undo() 00146 { 00147 if ( FID_IS_NEW( mFid ) ) 00148 { 00149 // modify added features 00150 QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.find( mFid ); 00151 Q_ASSERT( it != mBuffer->mAddedFeatures.end() ); 00152 it.value().setGeometry( *mOldGeom ); 00153 00154 cache()->cacheGeometry( mFid, *mOldGeom ); 00155 emit mBuffer->geometryChanged( mFid, *mOldGeom ); 00156 } 00157 else 00158 { 00159 // existing feature 00160 00161 if ( !mOldGeom ) 00162 { 00163 mBuffer->mChangedGeometries.remove( mFid ); 00164 00165 QgsFeature f; 00166 if ( layer()->getFeatures( QgsFeatureRequest().setFilterFid( mFid ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) && f.geometry() ) 00167 { 00168 cache()->cacheGeometry( mFid, *f.geometry() ); 00169 emit mBuffer->geometryChanged( mFid, *f.geometry() ); 00170 } 00171 } 00172 else 00173 { 00174 mBuffer->mChangedGeometries[mFid] = *mOldGeom; 00175 cache()->cacheGeometry( mFid, *mOldGeom ); 00176 emit mBuffer->geometryChanged( mFid, *mOldGeom ); 00177 } 00178 } 00179 00180 } 00181 00182 void QgsVectorLayerUndoCommandChangeGeometry::redo() 00183 { 00184 if ( FID_IS_NEW( mFid ) ) 00185 { 00186 // modify added features 00187 QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.find( mFid ); 00188 Q_ASSERT( it != mBuffer->mAddedFeatures.end() ); 00189 it.value().setGeometry( *mNewGeom ); 00190 } 00191 else 00192 { 00193 mBuffer->mChangedGeometries[ mFid ] = *mNewGeom; 00194 } 00195 cache()->cacheGeometry( mFid, *mNewGeom ); 00196 emit mBuffer->geometryChanged( mFid, *mNewGeom ); 00197 } 00198 00199 00200 00201 00202 00203 QgsVectorLayerUndoCommandChangeAttribute::QgsVectorLayerUndoCommandChangeAttribute( QgsVectorLayerEditBuffer* buffer, QgsFeatureId fid, int fieldIndex, const QVariant& newValue ) 00204 : QgsVectorLayerUndoCommand( buffer ), 00205 mFid( fid ), 00206 mFieldIndex( fieldIndex ), 00207 mNewValue( newValue ), 00208 mFirstChange( true ) 00209 { 00210 00211 if ( FID_IS_NEW( mFid ) ) 00212 { 00213 // work with added feature 00214 QgsFeatureMap::const_iterator it = mBuffer->mAddedFeatures.find( mFid ); 00215 Q_ASSERT( it != mBuffer->mAddedFeatures.end() ); 00216 if ( it.value().attribute( mFieldIndex ).isValid() ) 00217 { 00218 mOldValue = it.value().attribute( mFieldIndex ); 00219 mFirstChange = false; 00220 } 00221 } 00222 else 00223 { 00224 if ( mBuffer->mChangedAttributeValues.contains( mFid ) && mBuffer->mChangedAttributeValues[mFid].contains( mFieldIndex ) ) 00225 { 00226 mOldValue = mBuffer->mChangedAttributeValues[mFid][mFieldIndex]; 00227 mFirstChange = false; 00228 } 00229 } 00230 00231 } 00232 00233 void QgsVectorLayerUndoCommandChangeAttribute::undo() 00234 { 00235 QVariant original = mOldValue; 00236 00237 if ( FID_IS_NEW( mFid ) ) 00238 { 00239 // added feature 00240 QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.find( mFid ); 00241 Q_ASSERT( it != mBuffer->mAddedFeatures.end() ); 00242 it.value().setAttribute( mFieldIndex, mOldValue ); 00243 } 00244 else 00245 { 00246 // existing feature 00247 if ( mFirstChange ) 00248 { 00249 mBuffer->mChangedAttributeValues[mFid].remove( mFieldIndex ); 00250 if ( mBuffer->mChangedAttributeValues[mFid].isEmpty() ) 00251 mBuffer->mChangedAttributeValues.remove( mFid ); 00252 00253 // get old value from provider 00254 QgsFeature tmp; 00255 QgsFeatureRequest request; 00256 request.setFilterFid( mFid ); 00257 request.setFlags( QgsFeatureRequest::NoGeometry ); 00258 request.setSubsetOfAttributes( QgsAttributeList() << mFieldIndex ); 00259 QgsFeatureIterator fi = layer()->getFeatures( request ); 00260 if ( fi.nextFeature( tmp ) ) 00261 original = tmp.attribute( mFieldIndex ); 00262 } 00263 else 00264 { 00265 mBuffer->mChangedAttributeValues[mFid][mFieldIndex] = mOldValue; 00266 } 00267 } 00268 00269 emit mBuffer->attributeValueChanged( mFid, mFieldIndex, original ); 00270 } 00271 00272 void QgsVectorLayerUndoCommandChangeAttribute::redo() 00273 { 00274 if ( FID_IS_NEW( mFid ) ) 00275 { 00276 // updated added feature 00277 QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.find( mFid ); 00278 Q_ASSERT( it != mBuffer->mAddedFeatures.end() ); 00279 it.value().setAttribute( mFieldIndex, mNewValue ); 00280 } 00281 else 00282 { 00283 // changed attribute of existing feature 00284 if ( !mBuffer->mChangedAttributeValues.contains( mFid ) ) 00285 { 00286 mBuffer->mChangedAttributeValues.insert( mFid, QgsAttributeMap() ); 00287 } 00288 00289 mBuffer->mChangedAttributeValues[mFid].insert( mFieldIndex, mNewValue ); 00290 } 00291 00292 emit mBuffer->attributeValueChanged( mFid, mFieldIndex, mNewValue ); 00293 } 00294 00295 00296 00297 00298 00299 00300 QgsVectorLayerUndoCommandAddAttribute::QgsVectorLayerUndoCommandAddAttribute( QgsVectorLayerEditBuffer* buffer, const QgsField& field ) 00301 : QgsVectorLayerUndoCommand( buffer ), 00302 mField( field ) 00303 { 00304 mFieldIndex = layer()->pendingFields().count(); 00305 } 00306 00307 void QgsVectorLayerUndoCommandAddAttribute::undo() 00308 { 00309 int index = layer()->pendingFields().fieldOriginIndex( mFieldIndex ); 00310 00311 mBuffer->mAddedAttributes.removeAt( index ); 00312 mBuffer->updateLayerFields(); 00313 mBuffer->handleAttributeDeleted( mFieldIndex ); 00314 00315 emit mBuffer->attributeDeleted( mFieldIndex ); 00316 } 00317 00318 void QgsVectorLayerUndoCommandAddAttribute::redo() 00319 { 00320 mBuffer->mAddedAttributes.append( mField ); 00321 mBuffer->updateLayerFields(); 00322 mBuffer->handleAttributeAdded( mFieldIndex ); 00323 00324 emit mBuffer->attributeAdded( mFieldIndex ); 00325 } 00326 00327 00328 00329 00330 00331 QgsVectorLayerUndoCommandDeleteAttribute::QgsVectorLayerUndoCommandDeleteAttribute( QgsVectorLayerEditBuffer* buffer, int fieldIndex ) 00332 : QgsVectorLayerUndoCommand( buffer ), 00333 mFieldIndex( fieldIndex ) 00334 { 00335 const QgsFields& fields = layer()->pendingFields(); 00336 QgsFields::FieldOrigin origin = fields.fieldOrigin( mFieldIndex ); 00337 mOriginIndex = fields.fieldOriginIndex( mFieldIndex ); 00338 mProviderField = ( origin == QgsFields::OriginProvider ); 00339 00340 if ( !mProviderField ) 00341 { 00342 // need to store the field definition 00343 mOldField = mBuffer->mAddedAttributes[mOriginIndex]; 00344 } 00345 00346 // save values of new features 00347 for ( QgsFeatureMap::const_iterator it = mBuffer->mAddedFeatures.begin(); it != mBuffer->mAddedFeatures.end(); ++it ) 00348 { 00349 const QgsFeature& f = it.value(); 00350 mDeletedValues.insert( f.id(), f.attribute( mFieldIndex ) ); 00351 } 00352 00353 // save changed values 00354 for ( QgsChangedAttributesMap::const_iterator it = mBuffer->mChangedAttributeValues.begin(); it != mBuffer->mChangedAttributeValues.end(); ++it ) 00355 { 00356 const QgsAttributeMap& attrs = it.value(); 00357 if ( attrs.contains( mFieldIndex ) ) 00358 mDeletedValues.insert( it.key(), attrs[mFieldIndex] ); 00359 } 00360 } 00361 00362 void QgsVectorLayerUndoCommandDeleteAttribute::undo() 00363 { 00364 if ( mProviderField ) 00365 { 00366 mBuffer->mDeletedAttributeIds.removeOne( mOriginIndex ); 00367 } 00368 else 00369 { 00370 // newly added attribute 00371 mBuffer->mAddedAttributes.insert( mOriginIndex, mOldField ); 00372 } 00373 00374 mBuffer->updateLayerFields(); 00375 mBuffer->handleAttributeAdded( mFieldIndex ); // update changed attributes + new features 00376 00377 // set previously used attributes of new features 00378 for ( QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.begin(); it != mBuffer->mAddedFeatures.end(); ++it ) 00379 { 00380 QgsFeature& f = it.value(); 00381 f.setAttribute( mFieldIndex, mDeletedValues.value( f.id() ) ); 00382 } 00383 // set previously used changed attributes 00384 for ( QMap<QgsFeatureId, QVariant>::const_iterator it = mDeletedValues.begin(); it != mDeletedValues.end(); ++it ) 00385 { 00386 if ( !FID_IS_NEW( it.key() ) ) 00387 { 00388 QgsAttributeMap& attrs = mBuffer->mChangedAttributeValues[it.key()]; // also adds record if nonexistant 00389 attrs.insert( mFieldIndex, it.value() ); 00390 } 00391 } 00392 00393 emit mBuffer->attributeAdded( mFieldIndex ); 00394 } 00395 00396 void QgsVectorLayerUndoCommandDeleteAttribute::redo() 00397 { 00398 if ( mProviderField ) 00399 { 00400 mBuffer->mDeletedAttributeIds.append( mOriginIndex ); 00401 qSort( mBuffer->mDeletedAttributeIds ); // keep it sorted 00402 } 00403 else 00404 { 00405 // newly added attribute 00406 mBuffer->mAddedAttributes.removeAt( mOriginIndex ); // removing temporary attribute 00407 } 00408 00409 mBuffer->updateLayerFields(); 00410 mBuffer->handleAttributeDeleted( mFieldIndex ); // update changed attributes + new features 00411 emit mBuffer->attributeDeleted( mFieldIndex ); 00412 }