Download src/Mod/Sandbox/App/DocumentProtector.cpp from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 8.65 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/Sandbox/App/DocumentProtector.cpp
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/src/Mod/Sandbox/App/DocumentProtector.cpp
-
curl -L -o DocumentProtector.cpp https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/Sandbox/App/DocumentProtector.cpp
8.65 kB
| // SPDX-License-Identifier: LGPL-2.1-or-later | |
| /*************************************************************************** | |
| * Copyright (c) 2009 Werner Mayer <wmayer@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 * | |
| * * | |
| ***************************************************************************/ | |
| using namespace Sandbox; | |
| namespace Sandbox { | |
| static const int QT_CUSTOM_EVENT_PROTECTOR = 10000; | |
| class AbstractCustomProtectorEvent : public QEvent | |
| { | |
| public: | |
| AbstractCustomProtectorEvent() | |
| : QEvent(QEvent::Type(QT_CUSTOM_EVENT_PROTECTOR)), semaphore(0) | |
| { | |
| } | |
| ~AbstractCustomProtectorEvent() | |
| { | |
| if (semaphore) | |
| semaphore->release(); | |
| } | |
| virtual void execute() = 0; | |
| QSemaphore* semaphore; | |
| }; | |
| class CustomAddObjectEvent : public AbstractCustomProtectorEvent | |
| { | |
| public: | |
| CustomAddObjectEvent(App::DocumentObject** o, App::Document* d, const std::string& type, const std::string& name) | |
| : obj(o), doc(d), type(type), name(name) | |
| { | |
| } | |
| ~CustomAddObjectEvent() | |
| { | |
| } | |
| void execute() | |
| { | |
| *obj = doc->addObject(this->type.c_str(), this->name.c_str()); | |
| } | |
| protected: | |
| App::DocumentObject** obj; | |
| App::Document* doc; | |
| std::string type, name; | |
| }; | |
| class CustomRemoveObjectEvent : public AbstractCustomProtectorEvent | |
| { | |
| public: | |
| CustomRemoveObjectEvent(App::Document* d, const std::string& n) : doc(d), name(n) | |
| { | |
| } | |
| ~CustomRemoveObjectEvent() | |
| { | |
| } | |
| void execute() | |
| { | |
| doc->removeObject(this->name.c_str()); | |
| } | |
| protected: | |
| App::Document* doc; | |
| std::string name; | |
| }; | |
| class CustomRecomputeEvent : public AbstractCustomProtectorEvent | |
| { | |
| public: | |
| CustomRecomputeEvent(App::Document* d) : doc(d) | |
| { | |
| } | |
| ~CustomRecomputeEvent() | |
| { | |
| } | |
| void execute() | |
| { | |
| doc->recompute(); | |
| } | |
| protected: | |
| App::Document* doc; | |
| }; | |
| class CustomPropertyEvent : public AbstractCustomProtectorEvent | |
| { | |
| public: | |
| CustomPropertyEvent(App::Property& p, const App::Property& v) | |
| : property(p), value(v) | |
| { | |
| } | |
| ~CustomPropertyEvent() | |
| { | |
| } | |
| void execute() | |
| { | |
| property.Paste(value); | |
| } | |
| protected: | |
| App::Property& property; | |
| const App::Property& value; | |
| }; | |
| class CustomCallableEvent : public AbstractCustomProtectorEvent | |
| { | |
| public: | |
| CustomCallableEvent(const AbstractCallable& call) | |
| : callable(call) | |
| { | |
| } | |
| ~CustomCallableEvent() | |
| { | |
| } | |
| void execute() | |
| { | |
| callable(); | |
| } | |
| protected: | |
| const AbstractCallable& callable; | |
| }; | |
| class CustomPurgeEvent : public AbstractCustomProtectorEvent | |
| { | |
| public: | |
| CustomPurgeEvent(App::DocumentObject* o) | |
| : obj(o) | |
| { | |
| } | |
| ~CustomPurgeEvent() | |
| { | |
| } | |
| void execute() | |
| { | |
| obj->purgeTouched(); | |
| } | |
| protected: | |
| App::DocumentObject* obj; | |
| }; | |
| class DocumentReceiver : public QObject | |
| { | |
| public: | |
| DocumentReceiver(QObject *parent = 0) : QObject(parent) | |
| { | |
| } | |
| ~DocumentReceiver() | |
| { | |
| } | |
| static DocumentReceiver *globalInstance(); | |
| protected: | |
| void customEvent(QEvent*); | |
| void postEventAndWait(QEvent*); | |
| // friends | |
| friend class DocumentProtector; | |
| friend class DocumentObjectProtector; | |
| }; | |
| Q_GLOBAL_STATIC(DocumentReceiver, theInstance) | |
| DocumentReceiver *DocumentReceiver::globalInstance() | |
| { | |
| return theInstance(); | |
| } | |
| // Posts an event and waits for it to finish processing | |
| void DocumentReceiver::postEventAndWait(QEvent* e) | |
| { | |
| QThread *currentThread = QThread::currentThread(); | |
| QThread *thr = this->thread(); // this is the main thread | |
| if (currentThread == thr) { | |
| // we're in the main thread | |
| QCoreApplication::sendEvent(this, e); | |
| delete e; | |
| } | |
| else { | |
| // NOTE: We send an event to this instance that's why it is important | |
| // that this object is part of the main thread | |
| QSemaphore semaphore; | |
| static_cast<AbstractCustomProtectorEvent*>(e)->semaphore = &semaphore; | |
| QCoreApplication::postEvent(this, e); | |
| // wait until the event has been processed | |
| semaphore.acquire(); | |
| } | |
| } | |
| void DocumentReceiver::customEvent(QEvent* e) | |
| { | |
| if ((int)e->type() == QT_CUSTOM_EVENT_PROTECTOR) { | |
| static_cast<AbstractCustomProtectorEvent*>(e)->execute(); | |
| } | |
| } | |
| } | |
| DocumentProtector::DocumentProtector(App::Document* doc) | |
| : App::DocumentObserver(doc) | |
| { | |
| } | |
| DocumentProtector::~DocumentProtector() | |
| { | |
| } | |
| void DocumentProtector::init() | |
| { | |
| // this method must be called somewhere from the main thread | |
| DocumentReceiver::globalInstance()-> | |
| moveToThread(QCoreApplication::instance()->thread()); | |
| } | |
| void DocumentProtector::slotDeletedDocument(const App::Document& Doc) | |
| { | |
| if (&Doc == getDocument()) { | |
| this->detachDocument(); | |
| } | |
| } | |
| void DocumentProtector::validate() | |
| { | |
| if (!this->getDocument()) | |
| throw Base::ValueError("Handled document is null"); | |
| } | |
| App::DocumentObject *DocumentProtector::addObject(const std::string& type, const std::string& name) | |
| { | |
| validate(); | |
| App::DocumentObject* obj; | |
| DocumentReceiver::globalInstance()->postEventAndWait | |
| (new CustomAddObjectEvent(&obj, this->getDocument(), type, name)); | |
| return obj; | |
| } | |
| void DocumentProtector::removeObject(const std::string& name) | |
| { | |
| validate(); | |
| DocumentReceiver::globalInstance()->postEventAndWait | |
| (new CustomRemoveObjectEvent(this->getDocument(), name)); | |
| } | |
| void DocumentProtector::recompute() | |
| { | |
| validate(); | |
| DocumentReceiver::globalInstance()->postEventAndWait | |
| (new CustomRecomputeEvent(this->getDocument())); | |
| } | |
| // ------------------------------------------ | |
| DocumentObjectProtector::DocumentObjectProtector(App::DocumentObject* o) : obj(o) | |
| { | |
| } | |
| DocumentObjectProtector::~DocumentObjectProtector() | |
| { | |
| } | |
| void DocumentObjectProtector::validate() | |
| { | |
| if (!obj) | |
| throw Base::ValueError("Handled document object is null"); | |
| } | |
| App::DocumentObject* DocumentObjectProtector::getObject() const | |
| { | |
| return this->obj; | |
| } | |
| bool DocumentObjectProtector::setProperty(const std::string& name, const App::Property& value) | |
| { | |
| validate(); | |
| App::Property* prop = obj->getPropertyByName(name.c_str()); | |
| if (!prop) | |
| return false; | |
| DocumentReceiver::globalInstance()->postEventAndWait(new CustomPropertyEvent(*prop, value)); | |
| return true; | |
| } | |
| void DocumentObjectProtector::execute(const AbstractCallable& call) | |
| { | |
| validate(); | |
| DocumentReceiver::globalInstance()->postEventAndWait(new CustomCallableEvent(call)); | |
| } | |
| void DocumentObjectProtector::purgeTouched() | |
| { | |
| validate(); | |
| DocumentReceiver::globalInstance()->postEventAndWait(new CustomPurgeEvent(obj)); | |
| } | |