Quantum GIS API Documentation  master-693a1fe
src/core/qgsvectorlayerundocommand.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines