Transactions.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) Juergen Riegel         <juergen.riegel@web.de>          *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00024 #include "PreCompiled.h"
00025 
00026 #ifndef _PreComp_
00027 # include <cassert>
00028 #endif
00029 
00031 #include <Base/Writer.h>
00032 using Base::Writer;
00033 #include <Base/Reader.h>
00034 using Base::XMLReader;
00035 #include "Transactions.h"
00036 #include "Property.h"
00037 #include "Document.h"
00038 #include "DocumentObject.h"
00039 
00040 using namespace App;
00041 using namespace std;
00042 
00043 TYPESYSTEM_SOURCE(App::Transaction, Base::Persistence)
00044 
00045 //**************************************************************************
00046 // Construction/Destruction
00047 
00048 Transaction::Transaction()
00049   : iPos(0)
00050 {
00051 }
00052 
00053 Transaction::Transaction(int pos)
00054   : iPos(pos)
00055 {
00056 }
00057 
00062 Transaction::~Transaction()
00063 {
00064     std::map<const DocumentObject*,TransactionObject*>::iterator It;
00065     for (It= _Objects.begin();It!=_Objects.end();++It) {
00066         if (It->second->status == TransactionObject::New) {
00067             // If an object has been removed from the document the transaction
00068             // status is 'New'. The 'pcNameInDocument' member serves as criterion
00069             // to check whether the object is part of the document or not.
00070             // Note, it's possible that the transaction status is 'New' while the
00071             // object is (again) part of the document. This usually happens when
00072             // a previous removal is undone.
00073             // Thus, if the object has been removed, i.e. the status is 'New' and
00074             // is still not part of the document the object must be destroyed not
00075             // to cause a memory leak. This usually is the case when the removal
00076             // of an object is not undone or when an addition is undone.
00077             if (!It->first->pcNameInDocument) {
00078                 delete It->first;
00079             }
00080         }
00081         delete It->second;
00082     }
00083 }
00084 
00085 unsigned int Transaction::getMemSize (void) const
00086 {
00087     return 0;
00088 }
00089 
00090 void Transaction::Save (Base::Writer &/*writer*/) const
00091 {
00092     assert(0);
00093 }
00094 
00095 void Transaction::Restore(Base::XMLReader &/*reader*/)
00096 {
00097     assert(0);
00098 }
00099 
00100 int Transaction::getPos(void) const
00101 {
00102     return iPos;
00103 }
00104 
00105 
00106 //**************************************************************************
00107 // separator for other implemetation aspects
00108 
00109 
00110 void Transaction::apply(Document &Doc, bool forward)
00111 {
00112     std::map<const DocumentObject*,TransactionObject*>::iterator It;
00113     //for (It= _Objects.begin();It!=_Objects.end();++It)
00114     //    It->second->apply(Doc,const_cast<DocumentObject*>(It->first));
00115     for (It= _Objects.begin();It!=_Objects.end();++It)
00116         It->second->applyDel(Doc,const_cast<DocumentObject*>(It->first));
00117     for (It= _Objects.begin();It!=_Objects.end();++It)
00118         It->second->applyNew(Doc,const_cast<DocumentObject*>(It->first));
00119     for (It= _Objects.begin();It!=_Objects.end();++It)
00120         It->second->applyChn(Doc,const_cast<DocumentObject*>(It->first),forward);
00121 }
00122 
00123 void Transaction::addObjectNew(DocumentObject *Obj)
00124 {
00125     std::map<const DocumentObject*,TransactionObject*>::iterator pos = _Objects.find(Obj);
00126 
00127     if (pos != _Objects.end()) {
00128         if (pos->second->status == TransactionObject::Del) {
00129             delete pos->second;
00130             delete pos->first;
00131             _Objects.erase(pos);
00132         }
00133         else {
00134             pos->second->status = TransactionObject::New;
00135             pos->second->_NameInDocument = Obj->getNameInDocument();
00136             Obj->pcNameInDocument = 0;
00137         }
00138     }
00139     else {
00140         TransactionObject *To = new TransactionObject(Obj,Obj->getNameInDocument());
00141         _Objects[Obj] = To;
00142         // set name cache false
00143         Obj->pcNameInDocument = 0;
00144         To->status = TransactionObject::New;
00145     }
00146 }
00147 
00148 void Transaction::addObjectDel(const DocumentObject *Obj)
00149 {
00150     std::map<const DocumentObject*,TransactionObject*>::iterator pos = _Objects.find(Obj);
00151 
00152     // is it created in this transaction ?
00153     if (pos != _Objects.end() && pos->second->status == TransactionObject::New) {
00154         // remove completely from transaction
00155         delete pos->second;
00156         _Objects.erase(pos);
00157     }
00158     else if (pos != _Objects.end() && pos->second->status == TransactionObject::Chn) {
00159         pos->second->status = TransactionObject::Del;
00160     }
00161     else {
00162         TransactionObject *To = new TransactionObject(Obj);
00163         _Objects[Obj] = To;
00164         To->status = TransactionObject::Del;
00165     }
00166 }
00167 
00168 void Transaction::addObjectChange(const DocumentObject *Obj,const Property *Prop)
00169 {
00170     std::map<const DocumentObject*,TransactionObject*>::iterator pos = _Objects.find(Obj);
00171     TransactionObject *To;
00172 
00173     if (pos != _Objects.end()) {
00174         To = pos->second;
00175     }
00176     else {
00177         To = new TransactionObject(Obj);
00178         _Objects[Obj] = To;
00179         To->status = TransactionObject::Chn;
00180     }
00181 
00182     To->setProperty(Prop);
00183 }
00184 
00185 
00186 //**************************************************************************
00187 //**************************************************************************
00188 // TransactionObject
00189 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
00190 
00191 TYPESYSTEM_SOURCE_ABSTRACT(App::TransactionObject, Base::Persistence);
00192 
00193 //**************************************************************************
00194 // Construction/Destruction
00195 
00200 TransactionObject::TransactionObject(const DocumentObject * /*pcObj*/,const char *NameInDocument)
00201   : status(New)
00202 {
00203     if (NameInDocument)
00204         _NameInDocument=NameInDocument;
00205 }
00206 
00211 TransactionObject::~TransactionObject()
00212 {
00213     std::map<const Property*,Property*>::const_iterator It;
00214     for (It=_PropChangeMap.begin();It!=_PropChangeMap.end();++It)
00215         delete It->second;
00216 }
00217 
00218 void TransactionObject::applyDel(Document &Doc, DocumentObject *pcObj)
00219 {
00220     if (status == Del) {
00221         // simply filling in the saved object
00222         Doc._remObject(pcObj);
00223     }
00224 }
00225 
00226 void TransactionObject::applyNew(Document &Doc, DocumentObject *pcObj)
00227 {
00228     if (status == New) {
00229         Doc._addObject(pcObj,_NameInDocument.c_str());
00230     }
00231 }
00232 
00233 void TransactionObject::applyChn(Document & /*Doc*/, DocumentObject * /*pcObj*/,bool Forward)
00234 {
00235     if (status == New || status == Chn) {
00236         // apply changes if any
00237         if(!Forward){
00238             std::map<const Property*,Property*>::const_reverse_iterator It;
00239             for (It=_PropChangeMap.rbegin();It!=_PropChangeMap.rend();++It)
00240                 const_cast<Property*>(It->first)->Paste(*(It->second));
00241         }else{
00242             std::map<const Property*,Property*>::const_iterator It;
00243             for (It=_PropChangeMap.begin();It!=_PropChangeMap.end();++It)
00244                 const_cast<Property*>(It->first)->Paste(*(It->second));
00245         }
00246     }
00247 }
00248 
00249 void TransactionObject::setProperty(const Property* pcProp)
00250 {
00251     std::map<const Property*,Property*>::iterator pos = _PropChangeMap.find(pcProp);
00252     if (pos == _PropChangeMap.end())
00253         _PropChangeMap[pcProp] = pcProp->Copy();
00254 }
00255 
00256 unsigned int TransactionObject::getMemSize (void) const
00257 {
00258     return 0;
00259 }
00260 
00261 void TransactionObject::Save (Base::Writer &/*writer*/) const
00262 {
00263     assert(0);
00264 }
00265 
00266 void TransactionObject::Restore(Base::XMLReader &/*reader*/)
00267 {
00268     assert(0);
00269 }

Generated on Wed Nov 23 19:00:50 2011 for FreeCAD by  doxygen 1.6.1