diff --git a/src/App/Application.cpp b/src/App/Application.cpp index b1e7791235..1808fb0985 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -1116,8 +1116,6 @@ void Application::initTypes(void) // Document classes App ::DocumentObject ::init(); App ::GeoFeature ::init(); - App ::GeoFeatureGroup ::init(); - App ::GeoFeatureGroupPython ::init(); App ::FeatureTest ::init(); App ::FeatureTestException ::init(); App ::FeaturePython ::init(); @@ -1125,6 +1123,8 @@ void Application::initTypes(void) App ::Document ::init(); App ::DocumentObjectGroup ::init(); App ::DocumentObjectGroupPython ::init(); + App ::GeoFeatureGroup ::init(); + App ::GeoFeatureGroupPython ::init(); App ::DocumentObjectFileIncluded::init(); App ::InventorObject ::init(); App ::VRMLObject ::init(); diff --git a/src/App/DocumentObjectGroup.cpp b/src/App/DocumentObjectGroup.cpp index cb9f8494c6..474a00276d 100644 --- a/src/App/DocumentObjectGroup.cpp +++ b/src/App/DocumentObjectGroup.cpp @@ -103,12 +103,18 @@ DocumentObject *DocumentObjectGroup::getObject(const char *Name) const return 0; } -bool DocumentObjectGroup::hasObject(const DocumentObject* obj) const +bool DocumentObjectGroup::hasObject(const DocumentObject* obj, bool recursive) const { const std::vector& grp = Group.getValues(); for (std::vector::const_iterator it = grp.begin(); it != grp.end(); ++it) { - if (*it == obj) + if (*it == obj) { return true; + } else if ( recursive && (*it)->isDerivedFrom (App::DocumentObjectGroup::getTypeId()) ) { + App::DocumentObjectGroup *subGroup = static_cast (*it); + if (subGroup->hasObject (obj, recursive)) { + return true; + } + } } return false; diff --git a/src/App/DocumentObjectGroup.h b/src/App/DocumentObjectGroup.h index e5d1208817..b0a549a29f 100644 --- a/src/App/DocumentObjectGroup.h +++ b/src/App/DocumentObjectGroup.h @@ -64,8 +64,10 @@ public: DocumentObject *getObject(const char* Name) const; /** * Checks whether the object \a obj is part of this group. + * @param obj the object to check for. + * @param recursive if true check also if the obj is child of some sub group (default is false). */ - bool hasObject(const DocumentObject* obj) const; + bool hasObject(const DocumentObject* obj, bool recursive=false) const; /** * Checks whether this group object is a child (or sub-child) * of the given group object. diff --git a/src/App/DocumentObjectGroupPy.xml b/src/App/DocumentObjectGroupPy.xml index 5acc0d5a1c..a39ee8c217 100644 --- a/src/App/DocumentObjectGroupPy.xml +++ b/src/App/DocumentObjectGroupPy.xml @@ -39,8 +39,12 @@ - - Checks if the group has a given object + + hasObject(obj, recursive=false) + Checks if the group has a given object + @param obj the object to check for. + @param recursive if true check also if the obj is child of some sub group (default is false). + diff --git a/src/App/DocumentObjectGroupPyImp.cpp b/src/App/DocumentObjectGroupPyImp.cpp index 222f598395..bb290ee443 100644 --- a/src/App/DocumentObjectGroupPyImp.cpp +++ b/src/App/DocumentObjectGroupPyImp.cpp @@ -48,7 +48,7 @@ PyObject* DocumentObjectGroupPy::newObject(PyObject *args) DocumentObject *object = getDocumentObjectGroupPtr()->addObject(sType, sName); if ( object ) { return object->getPyObject(); - } + } else { PyErr_Format(Base::BaseExceptionFreeCADError, "Cannot create object of type '%s'", sType); return NULL; @@ -58,8 +58,8 @@ PyObject* DocumentObjectGroupPy::newObject(PyObject *args) PyObject* DocumentObjectGroupPy::addObject(PyObject *args) { PyObject *object; - if (!PyArg_ParseTuple(args, "O!", &(DocumentObjectPy::Type), &object)) // convert args: Python->C - return NULL; // NULL triggers exception + if (!PyArg_ParseTuple(args, "O!", &(DocumentObjectPy::Type), &object)) // convert args: Python->C + return NULL; // NULL triggers exception DocumentObjectPy* docObj = static_cast(object); if (!docObj->getDocumentObjectPtr() || !docObj->getDocumentObjectPtr()->getNameInDocument()) { @@ -109,8 +109,8 @@ PyObject* DocumentObjectGroupPy::addObject(PyObject *args) PyObject* DocumentObjectGroupPy::removeObject(PyObject *args) { PyObject *object; - if (!PyArg_ParseTuple(args, "O!", &(DocumentObjectPy::Type), &object)) // convert args: Python->C - return NULL; // NULL triggers exception + if (!PyArg_ParseTuple(args, "O!", &(DocumentObjectPy::Type), &object)) // convert args: Python->C + return NULL; // NULL triggers exception DocumentObjectPy* docObj = static_cast(object); if (!docObj->getDocumentObjectPtr() || !docObj->getDocumentObjectPtr()->getNameInDocument()) { @@ -148,8 +148,8 @@ PyObject* DocumentObjectGroupPy::removeObject(PyObject *args) PyObject* DocumentObjectGroupPy::removeObjectsFromDocument(PyObject *args) { - if (!PyArg_ParseTuple(args, "")) // convert args: Python->C - return NULL; // NULL triggers exception + if (!PyArg_ParseTuple(args, "")) // convert args: Python->C + return NULL; // NULL triggers exception getDocumentObjectGroupPtr()->removeObjectsFromDocument(); Py_Return; @@ -158,8 +158,8 @@ PyObject* DocumentObjectGroupPy::removeObjectsFromDocument(PyObject *args) PyObject* DocumentObjectGroupPy::getObject(PyObject *args) { char* pcName; - if (!PyArg_ParseTuple(args, "s", &pcName)) // convert args: Python->C - return NULL; // NULL triggers exception + if (!PyArg_ParseTuple(args, "s", &pcName)) // convert args: Python->C + return NULL; // NULL triggers exception DocumentObject* obj = getDocumentObjectGroupPtr()->getObject(pcName); if ( obj ) { @@ -172,8 +172,10 @@ PyObject* DocumentObjectGroupPy::getObject(PyObject *args) PyObject* DocumentObjectGroupPy::hasObject(PyObject *args) { PyObject *object; - if (!PyArg_ParseTuple(args, "O!", &(DocumentObjectPy::Type), &object)) // convert args: Python->C - return NULL; // NULL triggers exception + PyObject *recursivePy = 0; + int recursive = 0; + if (!PyArg_ParseTuple(args, "O!|O", &(DocumentObjectPy::Type), &object, &recursivePy)) + return NULL; // NULL triggers exception DocumentObjectPy* docObj = static_cast(object); if (!docObj->getDocumentObjectPtr() || !docObj->getDocumentObjectPtr()->getNameInDocument()) { @@ -184,8 +186,16 @@ PyObject* DocumentObjectGroupPy::hasObject(PyObject *args) PyErr_SetString(Base::BaseExceptionFreeCADError, "Cannot check an object from another document with this group"); return NULL; } + if (recursivePy) { + recursive = PyObject_IsTrue(recursivePy); + if ( recursive == -1) { + // Note: shouldn't happen + PyErr_SetString(PyExc_ValueError, "The recursive parameter should be of boolean type"); + return 0; + } + } - bool v = getDocumentObjectGroupPtr()->hasObject(docObj->getDocumentObjectPtr()); + bool v = getDocumentObjectGroupPtr()->hasObject(docObj->getDocumentObjectPtr(), recursive); return PyBool_FromLong(v ? 1 : 0); } @@ -196,6 +206,6 @@ PyObject *DocumentObjectGroupPy::getCustomAttributes(const char* /*attr*/) const int DocumentObjectGroupPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) { - return 0; + return 0; } diff --git a/src/App/GeoFeatureGroup.cpp b/src/App/GeoFeatureGroup.cpp index 85375b9f23..f31218cac6 100644 --- a/src/App/GeoFeatureGroup.cpp +++ b/src/App/GeoFeatureGroup.cpp @@ -1,5 +1,6 @@ /*************************************************************************** * Copyright (c) Juergen Riegel (juergen.riegel@web.de) 2014 * + * Copyright (c) Alexander Golubev (Fat-Zer) 2015 * * * * This file is part of the FreeCAD CAx development system. * * * @@ -27,15 +28,15 @@ #endif #include + #include "GeoFeatureGroup.h" #include "GeoFeatureGroupPy.h" #include "FeaturePythonPyImp.h" - using namespace App; -PROPERTY_SOURCE(App::GeoFeatureGroup, App::GeoFeature) +PROPERTY_SOURCE(App::GeoFeatureGroup, App::DocumentObjectGroup) //=========================================================================== @@ -44,138 +45,41 @@ PROPERTY_SOURCE(App::GeoFeatureGroup, App::GeoFeature) GeoFeatureGroup::GeoFeatureGroup(void) { - ADD_PROPERTY(Items,(0)); + ADD_PROPERTY(Placement,(Base::Placement())); } GeoFeatureGroup::~GeoFeatureGroup(void) { } -DocumentObject* GeoFeatureGroup::addObject(const char* sType, const char* pObjectName) +void GeoFeatureGroup::transformPlacement(const Base::Placement &transform) { - DocumentObject* obj = getDocument()->addObject(sType, pObjectName); - if (obj) addObject(obj); - return obj; + // NOTE: Keep in sync with APP::GeoFeature + Base::Placement plm = this->Placement.getValue(); + plm = transform * plm; + this->Placement.setValue(plm); } -void GeoFeatureGroup::addObject(DocumentObject* obj) +GeoFeatureGroup* GeoFeatureGroup::getGroupOfObject(const DocumentObject* obj) { - if (!hasObject(obj)) { - std::vector grp = Items.getValues(); - grp.push_back(obj); - Items.setValues(grp); - } -} - -void GeoFeatureGroup::removeObject(DocumentObject* obj) -{ - std::vector grp = Items.getValues(); - for (std::vector::iterator it = grp.begin(); it != grp.end(); ++it) { - if (*it == obj) { - grp.erase(it); - Items.setValues(grp); - break; - } - } -} - -void GeoFeatureGroup::removeObjectsFromDocument() -{ - std::vector grp = Items.getValues(); - for (std::vector::iterator it = grp.begin(); it != grp.end(); ++it) { - removeObjectFromDocument(*it); - } -} - -void GeoFeatureGroup::removeObjectFromDocument(DocumentObject* obj) -{ - // remove all children - if (obj->getTypeId().isDerivedFrom(GeoFeatureGroup::getClassTypeId())) { - std::vector grp = static_cast(obj)->Items.getValues(); - for (std::vector::iterator it = grp.begin(); it != grp.end(); ++it) { - // recursive call to remove all subgroups - removeObjectFromDocument(*it); - } + const Document* doc = obj->getDocument(); + std::vector grps = doc->getObjectsOfType(GeoFeatureGroup::getClassTypeId()); + for (std::vector::const_iterator it = grps.begin(); it != grps.end(); ++it) { + GeoFeatureGroup* grp = (GeoFeatureGroup*)(*it); + if (grp->hasObject(obj)) + return grp; } - this->getDocument()->remObject(obj->getNameInDocument(), true); -} - -DocumentObject *GeoFeatureGroup::getObject(const char *Name) const -{ - DocumentObject* obj = getDocument()->getObject(Name); - if (obj && hasObject(obj)) - return obj; return 0; } -bool GeoFeatureGroup::hasObject(const DocumentObject* obj, bool recursive) const -{ - const std::vector& grp = Items.getValues(); - for (std::vector::const_iterator it = grp.begin(); it != grp.end(); ++it) { - if (*it == obj) - return true; - if (recursive && (*it)->getTypeId().isDerivedFrom(GeoFeatureGroup::getClassTypeId())) { - if (static_cast(*it)->hasObject(obj, recursive)) - return true; - } - } - - return false; -} - -bool GeoFeatureGroup::isChildOf(const GeoFeatureGroup* group) const -{ - const std::vector& grp = group->Items.getValues(); - for (std::vector::const_iterator it = grp.begin(); it != grp.end(); ++it) { - if (*it == this) - return true; - if ((*it)->getTypeId().isDerivedFrom(GeoFeatureGroup::getClassTypeId())) { - if (this->isChildOf(static_cast(*it))) - return true; - } - } - - return false; -} - -std::vector GeoFeatureGroup::getObjects() const -{ - return Items.getValues(); -} - -std::vector GeoFeatureGroup::getObjectsOfType(const Base::Type& typeId) const -{ - std::vector type; - const std::vector& grp = Items.getValues(); - for (std::vector::const_iterator it = grp.begin(); it != grp.end(); ++it) { - if ( (*it)->getTypeId().isDerivedFrom(typeId)) - type.push_back(*it); - } - - return type; -} - -int GeoFeatureGroup::countObjectsOfType(const Base::Type& typeId) const -{ - int type=0; - const std::vector& grp = Items.getValues(); - for (std::vector::const_iterator it = grp.begin(); it != grp.end(); ++it) { - if ( (*it)->getTypeId().isDerivedFrom(typeId)) - type++; - } - - return type; -} - - PyObject *GeoFeatureGroup::getPyObject() { if (PythonObject.is(Py::_None())){ // ref counter is set to 1 PythonObject = Py::Object(new GeoFeatureGroupPy(this),true); } - return Py::new_reference_to(PythonObject); + return Py::new_reference_to(PythonObject); } // Python feature --------------------------------------------------------- diff --git a/src/App/GeoFeatureGroup.h b/src/App/GeoFeatureGroup.h index 9b4edab084..c25f2717b0 100644 --- a/src/App/GeoFeatureGroup.h +++ b/src/App/GeoFeatureGroup.h @@ -1,5 +1,6 @@ /*************************************************************************** - * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2014 * + * Copyright (c) Juergen Riegel (juergen.riegel@web.de) 2014 * + * Copyright (c) Alexander Golubev (Fat-Zer) 2015 * * * * This file is part of the FreeCAD CAx development system. * * * @@ -24,76 +25,48 @@ #ifndef APP_GeoFeatureGroup_H #define APP_GeoFeatureGroup_H -#include "GeoFeature.h" -#include "PropertyLinks.h" #include +#include "DocumentObjectGroup.h" +#include "PropertyGeo.h" namespace App { - -/** Base class of all geometric document objects. +/** + * The base class for placeable group of DocumentObjects */ -class AppExport GeoFeatureGroup : public App::GeoFeature +class AppExport GeoFeatureGroup : public App::DocumentObjectGroup { PROPERTY_HEADER(App::GeoFeatureGroup); public: - PropertyLinkList Items; + PropertyPlacement Placement; + /** + * @brief transformPlacement applies transform to placement of this shape. + * Override this function to propagate the change of placement to base + * features, for example. By the time of writing this comment, the function + * was only called by alignment task (Edit->Alignment) + * @param transform (input). + */ + virtual void transformPlacement(const Base::Placement &transform); /// Constructor GeoFeatureGroup(void); virtual ~GeoFeatureGroup(); + /** Returns the geo feature group which contains this object. + * In case this object is not part of any geoFeatureGroup 0 is returned. + * Unlike DocumentObjectGroup::getGroupOfObject serches only for GeoFeatureGroups + */ + static GeoFeatureGroup* getGroupOfObject(const DocumentObject* obj); + /// returns the type name of the ViewProvider virtual const char* getViewProviderName(void) const { return "Gui::ViewProviderGeoFeatureGroup"; } - /** @name Object handling */ - //@{ - /** Adds an object of \a sType with \a pObjectName to the document this group belongs to and - * append it to this group as well. - */ - DocumentObject *addObject(const char* sType, const char* pObjectName); - /* Adds the object \a obj to this group. - */ - void addObject(DocumentObject* obj); - /** Removes an object from this group. - */ - void removeObject(DocumentObject* obj); - /** Removes all children objects from this group and the document. - */ - void removeObjectsFromDocument(); - /** Returns the object of this group with \a Name. If the group doesn't have such an object 0 is returned. - * @note This method might return 0 even if the document this group belongs to contains an object with this name. - */ - DocumentObject *getObject(const char* Name) const; - /** - * Checks whether the object \a obj is GeoFeatureGroup of this group. - */ - bool hasObject(const App::DocumentObject* obj, bool recursive = false) const; - /** - * Checks whether this group object is a child (or sub-child) - * of the given group object. - */ - bool isChildOf(const GeoFeatureGroup*) const; - /** Returns a list of all objects this group does have. - */ - std::vector getObjects() const; - /** Returns a list of all objects of \a typeId this group does have. - */ - std::vector getObjectsOfType(const Base::Type& typeId) const; - /** Returns the number of objects of \a typeId this group does have. - */ - int countObjectsOfType(const Base::Type& typeId) const; - //@} virtual PyObject *getPyObject(void); - -private: - void removeObjectFromDocument(DocumentObject*); - }; typedef App::FeaturePythonT GeoFeatureGroupPython; diff --git a/src/App/GeoFeatureGroupPy.xml b/src/App/GeoFeatureGroupPy.xml index dda25a074e..e26a767d94 100644 --- a/src/App/GeoFeatureGroupPy.xml +++ b/src/App/GeoFeatureGroupPy.xml @@ -1,48 +1,18 @@ - This class handles document objects in Part - - - Create and add an object with given type and name to the GeoFeatureGroup - - - - - Add an object to the GeoFeatureGroup - - - - - Remove an object from the GeoFeatureGroup - - - - - Remove all child objects from the GeoFeatureGroup and document - - - - - Return the object with the given name - - - - - Checks if the GeoFeatureGroup has a given object - - - + diff --git a/src/App/GeoFeatureGroupPyImp.cpp b/src/App/GeoFeatureGroupPyImp.cpp index d565576f35..7f222089dd 100644 --- a/src/App/GeoFeatureGroupPyImp.cpp +++ b/src/App/GeoFeatureGroupPyImp.cpp @@ -16,121 +16,6 @@ std::string GeoFeatureGroupPy::representation(void) const } - -PyObject* GeoFeatureGroupPy::newObject(PyObject *args) -{ - char *sType,*sName=0; - if (!PyArg_ParseTuple(args, "s|s", &sType,&sName)) // convert args: Python->C - return NULL; - - DocumentObject *object = getGeoFeatureGroupPtr()->addObject(sType, sName); - if ( object ) { - return object->getPyObject(); - } - else { - PyErr_Format(PyExc_Exception, "Cannot create object of type '%s'", sType); - return NULL; - } -} - -PyObject* GeoFeatureGroupPy::addObject(PyObject *args) -{ - PyObject *object; - if (!PyArg_ParseTuple(args, "O!", &(DocumentObjectPy::Type), &object)) // convert args: Python->C - return NULL; // NULL triggers exception - - DocumentObjectPy* docObj = static_cast(object); - if (!docObj->getDocumentObjectPtr() || !docObj->getDocumentObjectPtr()->getNameInDocument()) { - PyErr_SetString(PyExc_Exception, "Cannot add an invalid object"); - return NULL; - } - if (docObj->getDocumentObjectPtr()->getDocument() != getGeoFeatureGroupPtr()->getDocument()) { - PyErr_SetString(PyExc_Exception, "Cannot add an object from another document to this GeoFeatureGroup"); - return NULL; - } - if (docObj->getDocumentObjectPtr() == this->getGeoFeatureGroupPtr()) { - PyErr_SetString(PyExc_Exception, "Cannot add a GeoFeatureGroup to itself"); - return NULL; - } - - getGeoFeatureGroupPtr()->addObject(docObj->getDocumentObjectPtr()); - - Py_Return; -} - -PyObject* GeoFeatureGroupPy::removeObject(PyObject *args) -{ - PyObject *object; - if (!PyArg_ParseTuple(args, "O!", &(DocumentObjectPy::Type), &object)) // convert args: Python->C - return NULL; // NULL triggers exception - - DocumentObjectPy* docObj = static_cast(object); - if (!docObj->getDocumentObjectPtr() || !docObj->getDocumentObjectPtr()->getNameInDocument()) { - PyErr_SetString(PyExc_Exception, "Cannot remove an invalid object"); - return NULL; - } - if (docObj->getDocumentObjectPtr()->getDocument() != getGeoFeatureGroupPtr()->getDocument()) { - PyErr_SetString(PyExc_Exception, "Cannot remove an object from another document from this group"); - return NULL; - } - - getGeoFeatureGroupPtr()->removeObject(docObj->getDocumentObjectPtr()); - - Py_Return; -} - -PyObject* GeoFeatureGroupPy::removeObjectsFromDocument(PyObject *args) -{ - if (!PyArg_ParseTuple(args, "")) // convert args: Python->C - return NULL; // NULL triggers exception - - getGeoFeatureGroupPtr()->removeObjectsFromDocument(); - Py_Return; -} - -PyObject* GeoFeatureGroupPy::getObject(PyObject *args) -{ - char* pcName; - if (!PyArg_ParseTuple(args, "s", &pcName)) // convert args: Python->C - return NULL; // NULL triggers exception - - DocumentObject* obj = getGeoFeatureGroupPtr()->getObject(pcName); - if ( obj ) { - return obj->getPyObject(); - } else { - Py_Return; - } -} - -PyObject* GeoFeatureGroupPy::hasObject(PyObject *args) -{ - PyObject *object; - if (!PyArg_ParseTuple(args, "O!", &(DocumentObjectPy::Type), &object)) // convert args: Python->C - return NULL; // NULL triggers exception - - DocumentObjectPy* docObj = static_cast(object); - if (!docObj->getDocumentObjectPtr() || !docObj->getDocumentObjectPtr()->getNameInDocument()) { - PyErr_SetString(PyExc_Exception, "Cannot check an invalid object"); - return NULL; - } - if (docObj->getDocumentObjectPtr()->getDocument() != getGeoFeatureGroupPtr()->getDocument()) { - PyErr_SetString(PyExc_Exception, "Cannot check an object from another document with this group"); - return NULL; - } - - if (getGeoFeatureGroupPtr()->hasObject(docObj->getDocumentObjectPtr())) { - Py_INCREF(Py_True); - return Py_True; - } - else { - Py_INCREF(Py_False); - return Py_False; - } -} - - - - PyObject *GeoFeatureGroupPy::getCustomAttributes(const char* /*attr*/) const { return 0; @@ -138,7 +23,7 @@ PyObject *GeoFeatureGroupPy::getCustomAttributes(const char* /*attr*/) const int GeoFeatureGroupPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) { - return 0; + return 0; } diff --git a/src/App/Part.cpp b/src/App/Part.cpp index e3fdda41fb..82ab8da479 100644 --- a/src/App/Part.cpp +++ b/src/App/Part.cpp @@ -81,24 +81,6 @@ PyObject *Part::getPyObject() return Py::new_reference_to(PythonObject); } -void Part::onSettingDocument() { - - if(connection.connected()) - connection.disconnect(); - - getDocument()->signalDeletedObject.connect(boost::bind(&Part::onDelete, this, _1)); - App::DocumentObject::onSettingDocument(); -} - -void Part::onDelete(const App::DocumentObject& obj) { - - if(&obj == this) { - //delete all child objects if needed - this->removeObjectsFromDocument(); - } -} - - // Python feature --------------------------------------------------------- // Not quit sure yet makeing Part derivable in Python is good Idea! diff --git a/src/App/Part.h b/src/App/Part.h index 599cfe4d1e..244fcd8adc 100644 --- a/src/App/Part.h +++ b/src/App/Part.h @@ -57,7 +57,6 @@ public: /// Meta descriptons App::PropertyMap Meta; - /** License string * Holds the short license string for the Item, e.g. CC-BY * for the Creative Commons license suit. @@ -91,13 +90,6 @@ public: static const char* BaseplaneTypes[3]; static const char* BaselineTypes[3]; - -protected: - virtual void onSettingDocument(); - -private: - boost::signals::scoped_connection connection; - void onDelete(const App::DocumentObject& obj); }; //typedef App::FeaturePythonT PartPython; diff --git a/src/Gui/ViewProvider.h b/src/Gui/ViewProvider.h index 02e8f89c54..d852221c57 100644 --- a/src/Gui/ViewProvider.h +++ b/src/Gui/ViewProvider.h @@ -125,8 +125,13 @@ public: /// return the higlight lines for a given element or the whole shape virtual std::vector getSelectionShape(const char* Element) const { return std::vector(); } - /// get called if the object is about to get deleted. Here you can delete other objects to or switch visibility of others. - virtual bool onDelete(const std::vector &) + /** + * Get called if the object is about to get deleted. + * Here you can delete other objects, switch their visibility or prevent the deletion of the object. + * @param subNames list of selected subelements + * @return true if the deletion is approoved by the view provider. + */ + virtual bool onDelete(const std::vector &subNames) { return true;} //@} diff --git a/src/Gui/ViewProviderGeoFeatureGroup.cpp b/src/Gui/ViewProviderGeoFeatureGroup.cpp index 0a8af28c32..6fe2e73a4c 100644 --- a/src/Gui/ViewProviderGeoFeatureGroup.cpp +++ b/src/Gui/ViewProviderGeoFeatureGroup.cpp @@ -1,5 +1,6 @@ /*************************************************************************** * Copyright (c) 2011 Juergen Riegel * + * Copyright (c) 2015 Alexander Golubev (Fat-Zer) * * * * This file is part of the FreeCAD CAx development system. * * * @@ -24,36 +25,21 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include +# include #endif -#include -#include +#include -/// Here the FreeCAD includes sorted by Base,App,Gui...... #include "ViewProviderGeoFeatureGroup.h" -#include "Application.h" -#include "Command.h" -#include "BitmapFactory.h" -#include "Document.h" -#include "Tree.h" -#include "View3DInventor.h" -#include "View3DInventorViewer.h" using namespace Gui; -PROPERTY_SOURCE(Gui::ViewProviderGeoFeatureGroup, Gui::ViewProviderGeometryObject) +PROPERTY_SOURCE(Gui::ViewProviderGeoFeatureGroup, Gui::ViewProviderDocumentObjectGroup) - -/** - * Creates the view provider for an object group. - */ ViewProviderGeoFeatureGroup::ViewProviderGeoFeatureGroup() { - pcGroupChildren = new SoGroup(); pcGroupChildren->ref(); } @@ -64,66 +50,73 @@ ViewProviderGeoFeatureGroup::~ViewProviderGeoFeatureGroup() pcGroupChildren = 0; } +std::vector ViewProviderGeoFeatureGroup::claimChildren3D(void) const { + App::GeoFeatureGroup *geoGroup = static_cast(getObject()); + const auto & objs = geoGroup->Group.getValues(); + std::set rvSet; + // search recursively for all non-geoGroups and claim their children either + std::set curSearchSet (objs.begin(), objs.end()); -std::vector ViewProviderGeoFeatureGroup::claimChildren(void)const -{ - return std::vector(static_cast(getObject())->Items.getValues()); -} + for ( auto objIt = curSearchSet.begin(); !curSearchSet.empty(); + curSearchSet.erase (objIt), objIt = curSearchSet.begin() ) { + // Check if we havent already processed the element may happen in case of nontree structure + // Note: this case generally indicates malformed structure + if ( rvSet.find (*objIt) != rvSet.end() ) { + continue; + } -std::vector ViewProviderGeoFeatureGroup::claimChildren3D(void)const -{ - return std::vector(static_cast(getObject())->Items.getValues()); -} + rvSet.insert (*objIt); + if ( (*objIt)->isDerivedFrom ( App::DocumentObjectGroup::getClassTypeId () ) && + !(*objIt)->isDerivedFrom ( App::GeoFeatureGroup::getClassTypeId () ) ) { -bool ViewProviderGeoFeatureGroup::onDelete(const std::vector &) -{ - //Gui::Command::doCommand(Gui::Command::Doc,"App.getDocument(\"%s\").getObject(\"%s\").removeObjectsFromDocument()" - // ,getObject()->getDocument()->getName(), getObject()->getNameInDocument()); - return true; -} + // add the non-GeoGroup's content to search + App::DocumentObjectGroup *group = static_cast (*objIt); + const auto & objs = group->Group.getValues(); + curSearchSet.insert ( objs.begin(), objs.end() ); + } + } - -/** - * Returns the pixmap for the list item. - */ -QIcon ViewProviderGeoFeatureGroup::getIcon() const -{ - QIcon groupIcon; - groupIcon.addPixmap(QApplication::style()->standardPixmap(QStyle::SP_DirClosedIcon), - QIcon::Normal, QIcon::Off); - groupIcon.addPixmap(QApplication::style()->standardPixmap(QStyle::SP_DirOpenIcon), - QIcon::Normal, QIcon::On); - return groupIcon; + return std::vector ( rvSet.begin(), rvSet.end() ); } void ViewProviderGeoFeatureGroup::attach(App::DocumentObject* pcObject) { - addDisplayMaskMode(pcGroupChildren, "Part"); - Gui::ViewProviderGeometryObject::attach(pcObject); + addDisplayMaskMode(pcGroupChildren, "Group"); + Gui::ViewProviderDocumentObjectGroup::attach(pcObject); } void ViewProviderGeoFeatureGroup::setDisplayMode(const char* ModeName) { - if ( strcmp("Part",ModeName)==0 ) - setDisplayMaskMode("Part"); + if ( strcmp("Group",ModeName)==0 ) + setDisplayMaskMode("Group"); - ViewProviderGeometryObject::setDisplayMode( ModeName ); + ViewProviderDocumentObjectGroup::setDisplayMode( ModeName ); } std::vector ViewProviderGeoFeatureGroup::getDisplayModes(void) const { // get the modes of the father - std::vector StrList = ViewProviderGeometryObject::getDisplayModes(); + std::vector StrList = ViewProviderDocumentObjectGroup::getDisplayModes(); // add your own modes - StrList.push_back("Part"); + StrList.push_back("Group"); return StrList; } +void ViewProviderGeoFeatureGroup::updateData(const App::Property* prop) +{ + if (prop->isDerivedFrom(App::PropertyPlacement::getClassTypeId()) && + strcmp(prop->getName(), "Placement") == 0) { + setTransformation ( static_cast(prop)->getValue().toMatrix() ); + } else { + ViewProviderDocumentObjectGroup::updateData ( prop ); + } +} + // Python feature ----------------------------------------------------------------------- namespace Gui { diff --git a/src/Gui/ViewProviderGeoFeatureGroup.h b/src/Gui/ViewProviderGeoFeatureGroup.h index 393b564e54..f1058451d1 100644 --- a/src/Gui/ViewProviderGeoFeatureGroup.h +++ b/src/Gui/ViewProviderGeoFeatureGroup.h @@ -1,5 +1,6 @@ /*************************************************************************** * Copyright (c) 2011 Juergen Riegel * + * Copyright (c) 2015 Alexander Golubev (Fat-Zer) * * * * This file is part of the FreeCAD CAx development system. * * * @@ -25,12 +26,11 @@ #define GUI_VIEWPROVIDER_ViewProviderGeoFeatureGroup_H -#include "ViewProviderGeometryObject.h" -#include "ViewProviderPythonFeature.h" +#include "ViewProviderDocumentObjectGroup.h" namespace Gui { -class GuiExport ViewProviderGeoFeatureGroup : public ViewProviderGeometryObject +class GuiExport ViewProviderGeoFeatureGroup : public ViewProviderDocumentObjectGroup { PROPERTY_HEADER(Gui::ViewProviderGeoFeatureGroup); @@ -40,23 +40,15 @@ public: /// destructor. virtual ~ViewProviderGeoFeatureGroup(); - virtual std::vector claimChildren(void)const; virtual std::vector claimChildren3D(void)const; - virtual SoGroup* getChildRoot(void) const {return pcGroupChildren;}; + virtual SoGroup* getChildRoot(void) const {return pcGroupChildren;}; - QIcon getIcon(void) const; virtual void attach(App::DocumentObject* pcObject); virtual void setDisplayMode(const char* ModeName); virtual std::vector getDisplayModes(void) const; - virtual bool onDelete(const std::vector &); - - /// get called if the user hover over a object in the tree - //virtual bool allowDrop(const std::vector &objList,Qt::KeyboardModifiers keys,Qt::MouseButtons mouseBts,const QPoint &pos); - /// get called if the user drops some objects - //virtual void drop(const std::vector &objList,Qt::KeyboardModifiers keys,Qt::MouseButtons mouseBts,const QPoint &pos); - + virtual void updateData(const App::Property*); protected: SoGroup *pcGroupChildren; }; diff --git a/src/Gui/ViewProviderOrigin.cpp b/src/Gui/ViewProviderOrigin.cpp index 53d043ec86..3fc76585bf 100644 --- a/src/Gui/ViewProviderOrigin.cpp +++ b/src/Gui/ViewProviderOrigin.cpp @@ -53,7 +53,7 @@ using namespace Gui; -PROPERTY_SOURCE(Gui::ViewProviderOrigin, Gui::ViewProviderGeometryObject) +PROPERTY_SOURCE(Gui::ViewProviderOrigin, Gui::ViewProviderGeoFeatureGroup) /** @@ -70,6 +70,18 @@ ViewProviderOrigin::~ViewProviderOrigin() { } + +bool ViewProviderOrigin::canDragObjects() const +{ + return false; +} + +bool ViewProviderOrigin::canDropObjects() const +{ + return false; +} + + bool ViewProviderOrigin::setEdit(int ModNum) { return true; diff --git a/src/Gui/ViewProviderOrigin.h b/src/Gui/ViewProviderOrigin.h index 3ecc45a6d4..54aeb28a46 100644 --- a/src/Gui/ViewProviderOrigin.h +++ b/src/Gui/ViewProviderOrigin.h @@ -48,7 +48,10 @@ public: virtual bool setEdit(int ModNum); virtual void unsetEdit(int ModNum); - + + virtual bool canDragObjects() const; + virtual bool canDropObjects() const; + virtual QIcon getIcon(void) const; //temporary mode to override visibility of grouped objects diff --git a/src/Gui/ViewProviderPart.cpp b/src/Gui/ViewProviderPart.cpp index 41495a076c..73ea05c48f 100644 --- a/src/Gui/ViewProviderPart.cpp +++ b/src/Gui/ViewProviderPart.cpp @@ -54,7 +54,7 @@ using namespace Gui; -PROPERTY_SOURCE(Gui::ViewProviderPart, Gui::ViewProviderGeometryObject) +PROPERTY_SOURCE(Gui::ViewProviderPart, Gui::ViewProviderGeoFeatureGroup) /** @@ -93,10 +93,10 @@ void ViewProviderPart::updateData(const App::Property* prop) void ViewProviderPart::onObjectChanged(const App::DocumentObject& obj, const App::Property&) { App::Part* part = static_cast(pcObject); - if(static_cast(pcObject)->hasObject(&obj) && + if ( &obj == pcObject || ( obj.getTypeId() != App::Origin::getClassTypeId() && obj.getTypeId() != App::Plane::getClassTypeId() && - obj.getTypeId() != App::Line::getClassTypeId()) { + obj.getTypeId() != App::Line::getClassTypeId() ) ) { View3DInventorViewer* viewer = static_cast(this->getActiveView())->getViewer(); SoGetBoundingBoxAction bboxAction(viewer->getSoRenderManager()->getViewportRegion()); diff --git a/src/Gui/ViewProviderPart.h b/src/Gui/ViewProviderPart.h index 0e2fb65f5f..3b63383cbc 100644 --- a/src/Gui/ViewProviderPart.h +++ b/src/Gui/ViewProviderPart.h @@ -58,11 +58,6 @@ public: virtual bool onDelete(const std::vector &); - /// get called if the user hover over a object in the tree - //virtual bool allowDrop(const std::vector &objList,Qt::KeyboardModifiers keys,Qt::MouseButtons mouseBts,const QPoint &pos); - /// get called if the user drops some objects - //virtual void drop(const std::vector &objList,Qt::KeyboardModifiers keys,Qt::MouseButtons mouseBts,const QPoint &pos); - /// helper to set up the standard content of a Part Object static void setUpPart(const App::Part *part); protected: