From f0e00311cdcbd6d5d71105c0a37261ba7d321197 Mon Sep 17 00:00:00 2001 From: wmayer Date: Sat, 18 Jun 2016 21:03:13 +0200 Subject: [PATCH] prepare view provider for undo/redo --- src/App/Application.cpp | 5 + src/App/CMakeLists.txt | 2 + src/App/Document.cpp | 10 +- src/App/Document.h | 6 +- src/App/DocumentObject.cpp | 18 ++- src/App/DocumentObject.h | 6 +- src/App/TransactionalObject.cpp | 50 +++++++++ src/App/TransactionalObject.h | 55 ++++++++++ src/App/Transactions.cpp | 146 +++++++++++++++++++------ src/App/Transactions.h | 130 +++++++++++++++------- src/Gui/Application.cpp | 5 + src/Gui/CMakeLists.txt | 2 + src/Gui/TransactionObject.cpp | 49 +++++++++ src/Gui/TransactionObject.h | 46 ++++++++ src/Gui/ViewProvider.cpp | 2 +- src/Gui/ViewProvider.h | 19 +++- src/Gui/ViewProviderDocumentObject.cpp | 40 +++++-- src/Gui/ViewProviderDocumentObject.h | 9 ++ 18 files changed, 498 insertions(+), 102 deletions(-) create mode 100644 src/App/TransactionalObject.cpp create mode 100644 src/App/TransactionalObject.h create mode 100644 src/Gui/TransactionObject.cpp create mode 100644 src/Gui/TransactionObject.h diff --git a/src/App/Application.cpp b/src/App/Application.cpp index 45a209a20..7828e658b 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -106,6 +106,7 @@ #include "MaterialObject.h" #include "MaterialPy.h" #include "Expression.h" +#include "Transactions.h" // If you stumble here, run the target "BuildExtractRevision" on Windows systems // or the Python script "SubWCRev.py" on Linux based systems which builds @@ -1133,6 +1134,7 @@ void Application::initTypes(void) App ::PropertyExpressionEngine ::init(); // Document classes + App ::TransactionalObject ::init(); App ::DocumentObject ::init(); App ::GeoFeature ::init(); App ::FeatureTest ::init(); @@ -1173,6 +1175,9 @@ void Application::initTypes(void) App ::BooleanExpression ::init(); App ::RangeExpression ::init(); + // register transaction type + new App::TransactionProducer + (DocumentObject::getClassTypeId()); } void Application::initConfig(int argc, char ** argv) diff --git a/src/App/CMakeLists.txt b/src/App/CMakeLists.txt index da7bfa4a5..d9f3129c3 100644 --- a/src/App/CMakeLists.txt +++ b/src/App/CMakeLists.txt @@ -111,6 +111,7 @@ SET(Document_CPP_SRCS OriginFeature.cpp Range.cpp Transactions.cpp + TransactionalObject.cpp VRMLObject.cpp MaterialObject.cpp MergeDocuments.cpp @@ -143,6 +144,7 @@ SET(Document_HPP_SRCS OriginFeature.h Range.h Transactions.h + TransactionalObject.h VRMLObject.h MaterialObject.h MergeDocuments.h diff --git a/src/App/Document.cpp b/src/App/Document.cpp index 81fa1885f..2c58447b9 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -820,7 +820,7 @@ void Document::onChanged(const Property* prop) } } -void Document::onBeforeChangeProperty(const DocumentObject *Who, const Property *What) +void Document::onBeforeChangeProperty(const TransactionalObject *Who, const Property *What) { if (d->activeUndoTransaction && !d->rollback) d->activeUndoTransaction->addObjectChange(Who,What); @@ -2050,8 +2050,6 @@ void Document::remObject(const char* sName) if (d->activeUndoTransaction) { // in this case transaction delete or save the object d->activeUndoTransaction->addObjectNew(pos->second); - // set name cache false - //pos->second->pcNameInDocument = 0; } else // if not saved in undo -> delete object @@ -2092,21 +2090,19 @@ void Document::_remObject(DocumentObject* pcObject) pcObject->StatusBits.reset (ObjectStatus::Delete); // Unset the bit to be on the safe side //remove the tip if needed - if(Tip.getValue() == pcObject) { + if (Tip.getValue() == pcObject) { Tip.setValue(nullptr); TipName.setValue(""); } // do no transactions if we do a rollback! - if(!d->rollback){ + if (!d->rollback) { // Undo stuff if (d->activeUndoTransaction) d->activeUndoTransaction->addObjectNew(pcObject); } // remove from map d->objectMap.erase(pos); - //// set name cache false - //pcObject->pcNameInDocument = 0; for (std::vector::iterator it = d->objectArray.begin(); it != d->objectArray.end(); ++it) { if (*it == pcObject) { diff --git a/src/App/Document.h b/src/App/Document.h index c74948eb0..fdaeb2cb4 100644 --- a/src/App/Document.h +++ b/src/App/Document.h @@ -46,6 +46,7 @@ namespace Base { namespace App { + class TransactionalObject; class DocumentObject; class DocumentObjectExecReturn; class Document; @@ -308,9 +309,10 @@ public: friend class Application; /// because of transaction handling + friend class TransactionalObject; friend class DocumentObject; friend class Transaction; - friend class TransactionObject; + friend class TransactionDocumentObject; /// Destruction virtual ~Document(); @@ -329,7 +331,7 @@ protected: void onChanged(const Property* prop); /// callback from the Document objects before property will be changed - void onBeforeChangeProperty(const DocumentObject *Who, const Property *What); + void onBeforeChangeProperty(const TransactionalObject *Who, const Property *What); /// callback from the Document objects after property was changed void onChangedProperty(const DocumentObject *Who, const Property *What); /// helper which Recompute only this feature diff --git a/src/App/DocumentObject.cpp b/src/App/DocumentObject.cpp index f4447ea06..bc003b4d4 100644 --- a/src/App/DocumentObject.cpp +++ b/src/App/DocumentObject.cpp @@ -30,17 +30,17 @@ #include "Document.h" #include "DocumentObject.h" -#include "DocumentObjectPy.h" #include "DocumentObjectGroup.h" #include "PropertyLinks.h" #include "PropertyExpressionEngine.h" +#include #include #include using namespace App; -PROPERTY_SOURCE(App::DocumentObject, App::PropertyContainer) +PROPERTY_SOURCE(App::DocumentObject, App::TransactionalObject) DocumentObjectExecReturn *DocumentObject::StdReturn = 0; @@ -123,6 +123,18 @@ const char *DocumentObject::getNameInDocument(void) const return pcNameInDocument->c_str(); } +bool DocumentObject::isAttachedToDocument() const +{ + return (pcNameInDocument != 0); +} + +const char* DocumentObject::detachFromDocument() +{ + const std::string* name = pcNameInDocument; + pcNameInDocument = 0; + return name ? name->c_str() : 0; +} + std::vector DocumentObject::getOutList(void) const { std::vector List; @@ -231,7 +243,7 @@ void DocumentObject::onBeforeChange(const Property* prop) oldLabel = Label.getStrValue(); if (_pDoc) - _pDoc->onBeforeChangeProperty(this,prop); + onBeforeChangeProperty(_pDoc, prop); } /// get called by the container when a Property was changed diff --git a/src/App/DocumentObject.h b/src/App/DocumentObject.h index 437b0dafd..3eb57bdd8 100644 --- a/src/App/DocumentObject.h +++ b/src/App/DocumentObject.h @@ -24,7 +24,7 @@ #ifndef APP_DOCUMENTOBJECT_H #define APP_DOCUMENTOBJECT_H -#include +#include #include #include #include @@ -76,7 +76,7 @@ public: /** Base class of all Classes handled in the Document */ -class AppExport DocumentObject: public App::PropertyContainer +class AppExport DocumentObject: public App::TransactionalObject { PROPERTY_HEADER(App::DocumentObject); @@ -95,6 +95,8 @@ public: /// returns the name which is set in the document for this object (not the name property!) const char *getNameInDocument(void) const; + virtual bool isAttachedToDocument() const; + virtual const char* detachFromDocument(); /// gets the document in which this Object is handled App::Document *getDocument(void) const; diff --git a/src/App/TransactionalObject.cpp b/src/App/TransactionalObject.cpp new file mode 100644 index 000000000..e118ccd59 --- /dev/null +++ b/src/App/TransactionalObject.cpp @@ -0,0 +1,50 @@ +/*************************************************************************** + * Copyright (c) 2016 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +#endif + +#include + +#include "Document.h" +#include "TransactionalObject.h" + +using namespace App; + + +PROPERTY_SOURCE_ABSTRACT(App::TransactionalObject, App::PropertyContainer) + +TransactionalObject::TransactionalObject(void) +{ +} + +TransactionalObject::~TransactionalObject(void) +{ +} + +void TransactionalObject::onBeforeChangeProperty(Document *doc, const Property *prop) +{ + doc->onBeforeChangeProperty(this, prop); +} diff --git a/src/App/TransactionalObject.h b/src/App/TransactionalObject.h new file mode 100644 index 000000000..6b84164d3 --- /dev/null +++ b/src/App/TransactionalObject.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (c) 2016 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef APP_TRANSACTIONALOBJECT_H +#define APP_TRANSACTIONALOBJECT_H + +#include + +namespace App +{ + +class Document; +class TransactionObject; + +/** Base class of transactional objects + */ +class AppExport TransactionalObject : public App::PropertyContainer +{ + PROPERTY_HEADER(App::TransactionalObject); + +public: + /// Constructor + TransactionalObject(void); + virtual ~TransactionalObject(); + virtual bool isAttachedToDocument() const = 0; + virtual const char* detachFromDocument() = 0; + +protected: + void onBeforeChangeProperty(Document *doc, const Property *prop); +}; + +} //namespace App + + +#endif // APP_TRANSACTIONALOBJECT_H diff --git a/src/App/Transactions.cpp b/src/App/Transactions.cpp index d52376370..e6eb63c34 100644 --- a/src/App/Transactions.cpp +++ b/src/App/Transactions.cpp @@ -61,7 +61,7 @@ Transaction::Transaction(int pos) */ Transaction::~Transaction() { - std::map::iterator It; + std::map::iterator It; for (It= _Objects.begin();It!=_Objects.end();++It) { if (It->second->status == TransactionObject::New) { // If an object has been removed from the document the transaction @@ -74,7 +74,8 @@ Transaction::~Transaction() // is still not part of the document the object must be destroyed not // to cause a memory leak. This usually is the case when the removal // of an object is not undone or when an addition is undone. - if (!It->first->pcNameInDocument) { + + if (!It->first->isAttachedToDocument()) { delete It->first; } } @@ -102,9 +103,9 @@ int Transaction::getPos(void) const return iPos; } -bool Transaction::hasObject(DocumentObject *Obj) const +bool Transaction::hasObject(const TransactionalObject *Obj) const { - std::map::const_iterator it; + std::map::const_iterator it; it = _Objects.find(Obj); return (it != _Objects.end()); } @@ -115,20 +116,20 @@ bool Transaction::hasObject(DocumentObject *Obj) const void Transaction::apply(Document &Doc, bool forward) { - std::map::iterator It; + std::map::iterator It; //for (It= _Objects.begin();It!=_Objects.end();++It) // It->second->apply(Doc,const_cast(It->first)); for (It= _Objects.begin();It!=_Objects.end();++It) - It->second->applyDel(Doc,const_cast(It->first)); + It->second->applyDel(Doc, const_cast(It->first)); for (It= _Objects.begin();It!=_Objects.end();++It) - It->second->applyNew(Doc,const_cast(It->first)); + It->second->applyNew(Doc, const_cast(It->first)); for (It= _Objects.begin();It!=_Objects.end();++It) - It->second->applyChn(Doc,const_cast(It->first),forward); + It->second->applyChn(Doc, const_cast(It->first), forward); } -void Transaction::addObjectNew(DocumentObject *Obj) +void Transaction::addObjectNew(TransactionalObject *Obj) { - std::map::iterator pos = _Objects.find(Obj); + std::map::iterator pos = _Objects.find(Obj); if (pos != _Objects.end()) { if (pos->second->status == TransactionObject::Del) { @@ -138,22 +139,20 @@ void Transaction::addObjectNew(DocumentObject *Obj) } else { pos->second->status = TransactionObject::New; - pos->second->_NameInDocument = Obj->getNameInDocument(); - Obj->pcNameInDocument = 0; + pos->second->_NameInDocument = Obj->detachFromDocument(); } } else { - TransactionObject *To = new TransactionObject(Obj,Obj->getNameInDocument()); - _Objects[Obj] = To; - // set name cache false - Obj->pcNameInDocument = 0; + TransactionObject *To = TransactionFactory::instance().createTransaction(Obj->getTypeId()); To->status = TransactionObject::New; + To->_NameInDocument = Obj->detachFromDocument(); + _Objects[Obj] = To; } } -void Transaction::addObjectDel(const DocumentObject *Obj) +void Transaction::addObjectDel(const TransactionalObject *Obj) { - std::map::iterator pos = _Objects.find(Obj); + std::map::iterator pos = _Objects.find(Obj); // is it created in this transaction ? if (pos != _Objects.end() && pos->second->status == TransactionObject::New) { @@ -165,22 +164,22 @@ void Transaction::addObjectDel(const DocumentObject *Obj) pos->second->status = TransactionObject::Del; } else { - TransactionObject *To = new TransactionObject(Obj); + TransactionObject *To = TransactionFactory::instance().createTransaction(Obj->getTypeId()); _Objects[Obj] = To; To->status = TransactionObject::Del; } } -void Transaction::addObjectChange(const DocumentObject *Obj,const Property *Prop) +void Transaction::addObjectChange(const TransactionalObject *Obj, const Property *Prop) { - std::map::iterator pos = _Objects.find(Obj); + std::map::iterator pos = _Objects.find(Obj); TransactionObject *To; if (pos != _Objects.end()) { To = pos->second; } else { - To = new TransactionObject(Obj); + To = TransactionFactory::instance().createTransaction(Obj->getTypeId()); _Objects[Obj] = To; To->status = TransactionObject::Chn; } @@ -203,11 +202,9 @@ TYPESYSTEM_SOURCE_ABSTRACT(App::TransactionObject, Base::Persistence); * A constructor. * A more elaborate description of the constructor. */ -TransactionObject::TransactionObject(const DocumentObject * /*pcObj*/,const char *NameInDocument) +TransactionObject::TransactionObject() : status(New) { - if (NameInDocument) - _NameInDocument=NameInDocument; } /** @@ -221,22 +218,15 @@ TransactionObject::~TransactionObject() delete It->second; } -void TransactionObject::applyDel(Document &Doc, DocumentObject *pcObj) +void TransactionObject::applyDel(Document &Doc, TransactionalObject *pcObj) { - if (status == Del) { - // simply filling in the saved object - Doc._remObject(pcObj); - } } -void TransactionObject::applyNew(Document &Doc, DocumentObject *pcObj) +void TransactionObject::applyNew(Document &Doc, TransactionalObject *pcObj) { - if (status == New) { - Doc._addObject(pcObj,_NameInDocument.c_str()); - } } -void TransactionObject::applyChn(Document & /*Doc*/, DocumentObject * /*pcObj*/,bool Forward) +void TransactionObject::applyChn(Document & /*Doc*/, TransactionalObject * /*pcObj*/, bool Forward) { if (status == New || status == Chn) { // apply changes if any @@ -257,7 +247,7 @@ void TransactionObject::applyChn(Document & /*Doc*/, DocumentObject * /*pcObj*/, void TransactionObject::setProperty(const Property* pcProp) { - std::map::iterator pos = _PropChangeMap.find(pcProp); + std::map::iterator pos = _PropChangeMap.find(pcProp); if (pos == _PropChangeMap.end()) _PropChangeMap[pcProp] = pcProp->Copy(); } @@ -276,3 +266,87 @@ void TransactionObject::Restore(Base::XMLReader &/*reader*/) { assert(0); } + +//************************************************************************** +//************************************************************************** +// TransactionDocumentObject +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TYPESYSTEM_SOURCE_ABSTRACT(App::TransactionDocumentObject, App::TransactionObject); + +//************************************************************************** +// Construction/Destruction + +/** + * A constructor. + * A more elaborate description of the constructor. + */ +TransactionDocumentObject::TransactionDocumentObject() +{ +} + +/** + * A destructor. + * A more elaborate description of the destructor. + */ +TransactionDocumentObject::~TransactionDocumentObject() +{ +} + +void TransactionDocumentObject::applyDel(Document &Doc, TransactionalObject *pcObj) +{ + if (status == Del) { + // simply filling in the saved object + DocumentObject* obj = static_cast(pcObj); + Doc._remObject(obj); + } +} + +void TransactionDocumentObject::applyNew(Document &Doc, TransactionalObject *pcObj) +{ + if (status == New) { + DocumentObject* obj = static_cast(pcObj); + Doc._addObject(obj, _NameInDocument.c_str()); + } +} + +//************************************************************************** +//************************************************************************** +// TransactionFactory +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +App::TransactionFactory* App::TransactionFactory::self = nullptr; + +TransactionFactory& TransactionFactory::instance() +{ + if (self == nullptr) + self = new TransactionFactory; + return *self; +} + +void TransactionFactory::destruct() +{ + delete self; + self = nullptr; +} + +void TransactionFactory::addProducer (const Base::Type& type, Base::AbstractProducer *producer) +{ + producers[type] = producer; +} + +/** + * Creates a transaction object for the given type id. + */ +TransactionObject* TransactionFactory::createTransaction (const Base::Type& type) const +{ + std::map::const_iterator it; + for (it = producers.begin(); it != producers.end(); ++it) { + if (type.isDerivedFrom(it->first)) { + return static_cast(it->second->Produce()); + } + } + + assert(0); + return nullptr; +} diff --git a/src/App/Transactions.h b/src/App/Transactions.h index 5c66fa6f2..8e70f9cf9 100644 --- a/src/App/Transactions.h +++ b/src/App/Transactions.h @@ -24,48 +24,19 @@ #ifndef APP_TRANSACTION_H #define APP_TRANSACTION_H +#include #include namespace App { class Document; -class DocumentObject; class Property; class Transaction; +class TransactionObject; +class TransactionalObject; -/** Represents an entry for an object in a Transaction - */ -class AppExport TransactionObject: public Base::Persistence -{ - TYPESYSTEM_HEADER(); - -public: - /// Construction - TransactionObject(const DocumentObject *pcObj,const char *NameInDocument=0); - /// Destruction - virtual ~TransactionObject(); - - void applyNew(Document &Doc, DocumentObject *pcObj); - void applyDel(Document &Doc, DocumentObject *pcObj); - void applyChn(Document &Doc, DocumentObject *pcObj,bool Forward); - - void setProperty(const Property* pcProp); - - virtual unsigned int getMemSize (void) const; - virtual void Save (Base::Writer &writer) const; - /// This method is used to restore properties from an XML document. - virtual void Restore(Base::XMLReader &reader); - - friend class Transaction; - -protected: - enum Status {New,Del,Chn} status; - std::map _PropChangeMap; - std::string _NameInDocument; -}; - /** Represents a atomic transaction of the document */ class AppExport Transaction : public Base::Persistence @@ -84,7 +55,7 @@ public: void apply(Document &Doc,bool forward); // the utf-8 name of the transaction - std::string Name; + std::string Name; virtual unsigned int getMemSize (void) const; virtual void Save (Base::Writer &writer) const; @@ -94,20 +65,103 @@ public: /// get the position in the transaction history int getPos(void) const; /// check if this object is used in a transaction - bool hasObject(DocumentObject *Obj) const; + bool hasObject(const TransactionalObject *Obj) const; friend class Document; protected: - void addObjectNew(DocumentObject *Obj); - void addObjectDel(const DocumentObject *Obj); - void addObjectChange(const DocumentObject *Obj,const Property *Prop); + void addObjectNew(TransactionalObject *Obj); + void addObjectDel(const TransactionalObject *Obj); + void addObjectChange(const TransactionalObject *Obj, const Property *Prop); private: int iPos; - std::map _Objects; + std::map _Objects; }; +/** Represents an entry for an object in a Transaction + */ +class AppExport TransactionObject : public Base::Persistence +{ + TYPESYSTEM_HEADER(); + +public: + /// Construction + TransactionObject(); + /// Destruction + virtual ~TransactionObject(); + + virtual void applyNew(Document &Doc, TransactionalObject *pcObj); + virtual void applyDel(Document &Doc, TransactionalObject *pcObj); + virtual void applyChn(Document &Doc, TransactionalObject *pcObj, bool Forward); + + void setProperty(const Property* pcProp); + + virtual unsigned int getMemSize (void) const; + virtual void Save (Base::Writer &writer) const; + /// This method is used to restore properties from an XML document. + virtual void Restore(Base::XMLReader &reader); + + friend class Transaction; + +protected: + enum Status {New,Del,Chn} status; + std::map _PropChangeMap; + std::string _NameInDocument; +}; + +/** Represents an entry for a document object in a transaction + */ +class AppExport TransactionDocumentObject : public TransactionObject +{ + TYPESYSTEM_HEADER(); + +public: + /// Construction + TransactionDocumentObject(); + /// Destruction + virtual ~TransactionDocumentObject(); + + void applyNew(Document &Doc, TransactionalObject *pcObj); + void applyDel(Document &Doc, TransactionalObject *pcObj); +}; + +class AppExport TransactionFactory +{ +public: + static TransactionFactory& instance(); + static void destruct (); + + TransactionObject* createTransaction (const Base::Type& type) const; + void addProducer (const Base::Type& type, Base::AbstractProducer *producer); + +private: + static TransactionFactory* self; + std::map producers; + + TransactionFactory(){} + ~TransactionFactory(){} +}; + +template +class TransactionProducer : public Base::AbstractProducer +{ +public: + TransactionProducer (const Base::Type& type) + { + TransactionFactory::instance().addProducer(type, this); + } + + virtual ~TransactionProducer (){} + + /** + * Creates an instance of the specified transaction object. + */ + virtual void* Produce () const + { + return (void*)(new CLASS); + } +}; } //namespace App diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp index ae6133b10..324eab072 100644 --- a/src/Gui/Application.cpp +++ b/src/Gui/Application.cpp @@ -88,6 +88,7 @@ #include "SpaceballEvent.h" #include "Control.h" #include "DocumentRecovery.h" +#include "TransactionObject.h" #include "TaskView/TaskView.h" #include "SplitView3DInventor.h" @@ -1563,6 +1564,10 @@ void Application::initTypes(void) Gui::PythonBaseWorkbench ::init(); Gui::PythonBlankWorkbench ::init(); Gui::PythonWorkbench ::init(); + + // register transaction type + new App::TransactionProducer + (ViewProviderDocumentObject::getClassTypeId()); } void Application::runApplication(void) diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index 49bea4d1a..f81b10891 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -1033,6 +1033,7 @@ SET(FreeCADGui_CPP_SRCS Utilities.cpp WaitCursor.cpp ManualAlignment.cpp + TransactionObject.cpp WinNativeGestureRecognizers.cpp ) SET(FreeCADGui_SRCS @@ -1060,6 +1061,7 @@ SET(FreeCADGui_SRCS Utilities.h WaitCursor.h ManualAlignment.h + TransactionObject.h WinNativeGestureRecognizers.h ) diff --git a/src/Gui/TransactionObject.cpp b/src/Gui/TransactionObject.cpp new file mode 100644 index 000000000..5f9c68bb9 --- /dev/null +++ b/src/Gui/TransactionObject.cpp @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (c) 2016 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +#endif +#include "TransactionObject.h" + +using namespace Gui; + + +TYPESYSTEM_SOURCE_ABSTRACT(Gui::TransactionViewProvider, App::TransactionObject) + +TransactionViewProvider::TransactionViewProvider() +{ +} + +TransactionViewProvider::~TransactionViewProvider() +{ +} + +void TransactionViewProvider::applyNew(App::Document& /*Doc*/, App::TransactionalObject* /*pcObj*/) +{ +} + +void TransactionViewProvider::applyDel(App::Document& /*Doc*/, App::TransactionalObject* /*pcObj*/) +{ +} diff --git a/src/Gui/TransactionObject.h b/src/Gui/TransactionObject.h new file mode 100644 index 000000000..155ec36dc --- /dev/null +++ b/src/Gui/TransactionObject.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (c) 2016 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef GUI_TRANSACTIONOBJECT_H +#define GUI_TRANSACTIONOBJECT_H + +#include + +namespace Gui +{ +class TransactionViewProvider : public App::TransactionObject +{ + TYPESYSTEM_HEADER(); + +public: + TransactionViewProvider(); + virtual ~TransactionViewProvider(); + + void applyNew(App::Document& Doc, App::TransactionalObject* pcObj); + void applyDel(App::Document& Doc, App::TransactionalObject* pcObj); +}; + +} //namespace Gui + + +#endif // GUI_TRANSACTIONOBJECT_H diff --git a/src/Gui/ViewProvider.cpp b/src/Gui/ViewProvider.cpp index 4e6627690..72e01ef5e 100644 --- a/src/Gui/ViewProvider.cpp +++ b/src/Gui/ViewProvider.cpp @@ -60,7 +60,7 @@ using namespace Gui; // ViewProvider //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -PROPERTY_SOURCE_ABSTRACT(Gui::ViewProvider, App::PropertyContainer) +PROPERTY_SOURCE_ABSTRACT(Gui::ViewProvider, App::TransactionalObject) ViewProvider::ViewProvider() : pcAnnotation(0) diff --git a/src/Gui/ViewProvider.h b/src/Gui/ViewProvider.h index 2bab337eb..4c93ce247 100644 --- a/src/Gui/ViewProvider.h +++ b/src/Gui/ViewProvider.h @@ -30,6 +30,9 @@ #include #include +#include +#include + class SbVec2s; class SbVec3f; class SoNode; @@ -56,9 +59,6 @@ namespace App { class SoGroup; -#include -#include - namespace Gui { namespace TaskView { @@ -77,7 +77,7 @@ class ObjectItem; * have to be implemented for any object type in order to * show them in the 3DView and TreeView. */ -class GuiExport ViewProvider : public App::PropertyContainer +class GuiExport ViewProvider : public App::TransactionalObject { PROPERTY_HEADER(Gui::ViewProvider); @@ -213,6 +213,17 @@ public: std::string toString() const; PyObject* getPyObject(); + /** @name Transaction handling + */ + //@{ + virtual bool isAttachedToDocument() const { + return false; + } + virtual const char* detachFromDocument() { + return 0; + } + //@} + /** @name Display mode methods */ //@{ diff --git a/src/Gui/ViewProviderDocumentObject.cpp b/src/Gui/ViewProviderDocumentObject.cpp index 62c33bb63..ca98a1442 100644 --- a/src/Gui/ViewProviderDocumentObject.cpp +++ b/src/Gui/ViewProviderDocumentObject.cpp @@ -42,7 +42,7 @@ #include "MDIView.h" #include "TaskView/TaskAppearance.h" #include "ViewProviderDocumentObject.h" -#include "ViewProviderDocumentObjectPy.h" +#include using namespace Gui; @@ -79,6 +79,28 @@ void ViewProviderDocumentObject::finishRestoring() { } +bool ViewProviderDocumentObject::isAttachedToDocument() const +{ + App::DocumentObject* obj = getObject(); + bool ok = obj ? obj->isAttachedToDocument() : false; + return ok; +} + +const char* ViewProviderDocumentObject::detachFromDocument() +{ + App::DocumentObject* obj = getObject(); + return obj ? obj->getNameInDocument() : 0; +} + +void ViewProviderDocumentObject::onBeforeChange(const App::Property* prop) +{ + App::DocumentObject* obj = getObject(); + App::Document* doc = obj ? obj->getDocument() : 0; + if (doc) { + onBeforeChangeProperty(doc, prop); + } +} + void ViewProviderDocumentObject::onChanged(const App::Property* prop) { if (prop == &DisplayMode) { @@ -156,25 +178,25 @@ void ViewProviderDocumentObject::attach(App::DocumentObject *pcObj) if (defmode) DisplayMode.setValue(defmode); } - -Gui::MDIView* ViewProviderDocumentObject::getActiveView() const -{ + +Gui::MDIView* ViewProviderDocumentObject::getActiveView() const +{ App::Document* pAppDoc = pcObject->getDocument(); - Gui::Document* pGuiDoc = Gui::Application::Instance->getDocument(pAppDoc); - return pGuiDoc->getActiveView(); -} + Gui::Document* pGuiDoc = Gui::Application::Instance->getDocument(pAppDoc); + return pGuiDoc->getActiveView(); +} Gui::MDIView* ViewProviderDocumentObject::getEditingView() const { App::Document* pAppDoc = pcObject->getDocument(); - Gui::Document* pGuiDoc = Gui::Application::Instance->getDocument(pAppDoc); + Gui::Document* pGuiDoc = Gui::Application::Instance->getDocument(pAppDoc); return pGuiDoc->getEditingViewOfViewProvider(const_cast(this)); } Gui::MDIView* ViewProviderDocumentObject::getInventorView() const { App::Document* pAppDoc = pcObject->getDocument(); - Gui::Document* pGuiDoc = Gui::Application::Instance->getDocument(pAppDoc); + Gui::Document* pGuiDoc = Gui::Application::Instance->getDocument(pAppDoc); Gui::MDIView* mdi = pGuiDoc->getEditingViewOfViewProvider(const_cast(this)); if (!mdi) { diff --git a/src/Gui/ViewProviderDocumentObject.h b/src/Gui/ViewProviderDocumentObject.h index 3b567a540..5be67bc14 100644 --- a/src/Gui/ViewProviderDocumentObject.h +++ b/src/Gui/ViewProviderDocumentObject.h @@ -117,6 +117,8 @@ protected: If a value different to 0 is returned it is guaranteed to be a 3d view. */ Gui::MDIView* getInventorView() const; + /// get called before the value is changed + virtual void onBeforeChange(const App::Property* prop); /// Gets called by the container whenever a property has been changed virtual void onChanged(const App::Property* prop); /** Searches in all view providers that are attached to an object that @@ -128,6 +130,13 @@ protected: */ SoNode* findFrontRootOfType(const SoType& type) const; + /** @name Transaction handling + */ + //@{ + virtual bool isAttachedToDocument() const; + virtual const char* detachFromDocument(); + //@} + protected: App::DocumentObject *pcObject;