prepare view provider for undo/redo
This commit is contained in:
parent
62a8828dc8
commit
f0e00311cd
|
@ -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<TransactionDocumentObject>
|
||||
(DocumentObject::getClassTypeId());
|
||||
}
|
||||
|
||||
void Application::initConfig(int argc, char ** argv)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<DocumentObject*>::iterator it = d->objectArray.begin(); it != d->objectArray.end(); ++it) {
|
||||
if (*it == pcObject) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -30,17 +30,17 @@
|
|||
|
||||
#include "Document.h"
|
||||
#include "DocumentObject.h"
|
||||
#include "DocumentObjectPy.h"
|
||||
#include "DocumentObjectGroup.h"
|
||||
#include "PropertyLinks.h"
|
||||
#include "PropertyExpressionEngine.h"
|
||||
#include <App/DocumentObjectPy.h>
|
||||
#include <boost/signals/connection.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
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*> DocumentObject::getOutList(void) const
|
||||
{
|
||||
std::vector<Property*> 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
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#ifndef APP_DOCUMENTOBJECT_H
|
||||
#define APP_DOCUMENTOBJECT_H
|
||||
|
||||
#include <App/PropertyContainer.h>
|
||||
#include <App/TransactionalObject.h>
|
||||
#include <App/PropertyStandard.h>
|
||||
#include <App/PropertyLinks.h>
|
||||
#include <App/PropertyExpressionEngine.h>
|
||||
|
@ -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;
|
||||
|
||||
|
|
50
src/App/TransactionalObject.cpp
Normal file
50
src/App/TransactionalObject.cpp
Normal file
|
@ -0,0 +1,50 @@
|
|||
/***************************************************************************
|
||||
* Copyright (c) 2016 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* 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 <Base/Writer.h>
|
||||
|
||||
#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);
|
||||
}
|
55
src/App/TransactionalObject.h
Normal file
55
src/App/TransactionalObject.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
/***************************************************************************
|
||||
* Copyright (c) 2016 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* 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 <App/PropertyContainer.h>
|
||||
|
||||
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
|
|
@ -61,7 +61,7 @@ Transaction::Transaction(int pos)
|
|||
*/
|
||||
Transaction::~Transaction()
|
||||
{
|
||||
std::map<const DocumentObject*,TransactionObject*>::iterator It;
|
||||
std::map<const TransactionalObject*, TransactionObject*>::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 DocumentObject*,TransactionObject*>::const_iterator it;
|
||||
std::map<const TransactionalObject*, TransactionObject*>::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<const DocumentObject*,TransactionObject*>::iterator It;
|
||||
std::map<const TransactionalObject*, TransactionObject*>::iterator It;
|
||||
//for (It= _Objects.begin();It!=_Objects.end();++It)
|
||||
// It->second->apply(Doc,const_cast<DocumentObject*>(It->first));
|
||||
for (It= _Objects.begin();It!=_Objects.end();++It)
|
||||
It->second->applyDel(Doc,const_cast<DocumentObject*>(It->first));
|
||||
It->second->applyDel(Doc, const_cast<TransactionalObject*>(It->first));
|
||||
for (It= _Objects.begin();It!=_Objects.end();++It)
|
||||
It->second->applyNew(Doc,const_cast<DocumentObject*>(It->first));
|
||||
It->second->applyNew(Doc, const_cast<TransactionalObject*>(It->first));
|
||||
for (It= _Objects.begin();It!=_Objects.end();++It)
|
||||
It->second->applyChn(Doc,const_cast<DocumentObject*>(It->first),forward);
|
||||
It->second->applyChn(Doc, const_cast<TransactionalObject*>(It->first), forward);
|
||||
}
|
||||
|
||||
void Transaction::addObjectNew(DocumentObject *Obj)
|
||||
void Transaction::addObjectNew(TransactionalObject *Obj)
|
||||
{
|
||||
std::map<const DocumentObject*,TransactionObject*>::iterator pos = _Objects.find(Obj);
|
||||
std::map<const TransactionalObject*, TransactionObject*>::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<const DocumentObject*,TransactionObject*>::iterator pos = _Objects.find(Obj);
|
||||
std::map<const TransactionalObject*, TransactionObject*>::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<const DocumentObject*,TransactionObject*>::iterator pos = _Objects.find(Obj);
|
||||
std::map<const TransactionalObject*, TransactionObject*>::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<const Property*,Property*>::iterator pos = _PropChangeMap.find(pcProp);
|
||||
std::map<const Property*, Property*>::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<DocumentObject*>(pcObj);
|
||||
Doc._remObject(obj);
|
||||
}
|
||||
}
|
||||
|
||||
void TransactionDocumentObject::applyNew(Document &Doc, TransactionalObject *pcObj)
|
||||
{
|
||||
if (status == New) {
|
||||
DocumentObject* obj = static_cast<DocumentObject*>(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<Base::Type, Base::AbstractProducer*>::const_iterator it;
|
||||
for (it = producers.begin(); it != producers.end(); ++it) {
|
||||
if (type.isDerivedFrom(it->first)) {
|
||||
return static_cast<TransactionObject*>(it->second->Produce());
|
||||
}
|
||||
}
|
||||
|
||||
assert(0);
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -24,48 +24,19 @@
|
|||
#ifndef APP_TRANSACTION_H
|
||||
#define APP_TRANSACTION_H
|
||||
|
||||
#include <Base/Factory.h>
|
||||
#include <Base/Persistence.h>
|
||||
|
||||
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<const Property*,Property*> _PropChangeMap;
|
||||
std::string _NameInDocument;
|
||||
};
|
||||
|
||||
/** Represents a atomic transaction of the document
|
||||
*/
|
||||
class AppExport Transaction : public Base::Persistence
|
||||
|
@ -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<const DocumentObject*,TransactionObject*> _Objects;
|
||||
std::map<const TransactionalObject*, TransactionObject*> _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<const Property*,Property*> _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<Base::Type, Base::AbstractProducer*> producers;
|
||||
|
||||
TransactionFactory(){}
|
||||
~TransactionFactory(){}
|
||||
};
|
||||
|
||||
template <class CLASS>
|
||||
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
|
||||
|
||||
|
|
|
@ -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<TransactionViewProvider>
|
||||
(ViewProviderDocumentObject::getClassTypeId());
|
||||
}
|
||||
|
||||
void Application::runApplication(void)
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
||||
|
|
49
src/Gui/TransactionObject.cpp
Normal file
49
src/Gui/TransactionObject.cpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
/***************************************************************************
|
||||
* Copyright (c) 2016 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* 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*/)
|
||||
{
|
||||
}
|
46
src/Gui/TransactionObject.h
Normal file
46
src/Gui/TransactionObject.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/***************************************************************************
|
||||
* Copyright (c) 2016 Werner Mayer <wmayer[at]users.sourceforge.net> *
|
||||
* *
|
||||
* 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 <App/Transactions.h>
|
||||
|
||||
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
|
|
@ -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)
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
#include <QIcon>
|
||||
#include <boost/signals.hpp>
|
||||
|
||||
#include <App/TransactionalObject.h>
|
||||
#include <Base/Vector3D.h>
|
||||
|
||||
class SbVec2s;
|
||||
class SbVec3f;
|
||||
class SoNode;
|
||||
|
@ -56,9 +59,6 @@ namespace App {
|
|||
|
||||
class SoGroup;
|
||||
|
||||
#include <App/PropertyContainer.h>
|
||||
#include <Base/Vector3D.h>
|
||||
|
||||
|
||||
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
|
||||
*/
|
||||
//@{
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#include "MDIView.h"
|
||||
#include "TaskView/TaskAppearance.h"
|
||||
#include "ViewProviderDocumentObject.h"
|
||||
#include "ViewProviderDocumentObjectPy.h"
|
||||
#include <Gui/ViewProviderDocumentObjectPy.h>
|
||||
|
||||
|
||||
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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user