App/GeoFeatureGroup: derive from DocumentObjectGroup

Refactor GeoFeatureGroup and derive it from DocumentObjectGroup rather
than GeoFeatureObject to unify code of those two classes.
This commit is contained in:
Alexander Golubev
2015-08-28 00:09:41 +03:00
committed by Stefan Tröger
parent 76b4685b5f
commit dbb5786ffd
18 changed files with 167 additions and 439 deletions

View File

@@ -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();

View File

@@ -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<DocumentObject*>& grp = Group.getValues();
for (std::vector<DocumentObject*>::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<App::DocumentObjectGroup *> (*it);
if (subGroup->hasObject (obj, recursive)) {
return true;
}
}
}
return false;

View File

@@ -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.

View File

@@ -39,8 +39,12 @@
</Documentation>
</Methode>
<Methode Name="hasObject">
<Documentation>
<UserDocu>Checks if the group has a given object</UserDocu>
<Documentation>
<UserDocu>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).
</UserDocu>
</Documentation>
</Methode>
<CustomAttributes />

View File

@@ -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<DocumentObjectPy*>(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<DocumentObjectPy*>(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<DocumentObjectPy*>(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;
}

View File

@@ -1,5 +1,6 @@
/***************************************************************************
* Copyright (c) Juergen Riegel (juergen.riegel@web.de) 2014 *
* Copyright (c) Alexander Golubev (Fat-Zer) <fatzer2@gmail.com> 2015 *
* *
* This file is part of the FreeCAD CAx development system. *
* *
@@ -27,15 +28,15 @@
#endif
#include <App/Document.h>
#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<DocumentObject*> grp = Items.getValues();
grp.push_back(obj);
Items.setValues(grp);
}
}
void GeoFeatureGroup::removeObject(DocumentObject* obj)
{
std::vector<DocumentObject*> grp = Items.getValues();
for (std::vector<DocumentObject*>::iterator it = grp.begin(); it != grp.end(); ++it) {
if (*it == obj) {
grp.erase(it);
Items.setValues(grp);
break;
}
}
}
void GeoFeatureGroup::removeObjectsFromDocument()
{
std::vector<DocumentObject*> grp = Items.getValues();
for (std::vector<DocumentObject*>::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<DocumentObject*> grp = static_cast<GeoFeatureGroup*>(obj)->Items.getValues();
for (std::vector<DocumentObject*>::iterator it = grp.begin(); it != grp.end(); ++it) {
// recursive call to remove all subgroups
removeObjectFromDocument(*it);
}
const Document* doc = obj->getDocument();
std::vector<DocumentObject*> grps = doc->getObjectsOfType(GeoFeatureGroup::getClassTypeId());
for (std::vector<DocumentObject*>::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<DocumentObject*>& grp = Items.getValues();
for (std::vector<DocumentObject*>::const_iterator it = grp.begin(); it != grp.end(); ++it) {
if (*it == obj)
return true;
if (recursive && (*it)->getTypeId().isDerivedFrom(GeoFeatureGroup::getClassTypeId())) {
if (static_cast<GeoFeatureGroup*>(*it)->hasObject(obj, recursive))
return true;
}
}
return false;
}
bool GeoFeatureGroup::isChildOf(const GeoFeatureGroup* group) const
{
const std::vector<DocumentObject*>& grp = group->Items.getValues();
for (std::vector<DocumentObject*>::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<GeoFeatureGroup*>(*it)))
return true;
}
}
return false;
}
std::vector<DocumentObject*> GeoFeatureGroup::getObjects() const
{
return Items.getValues();
}
std::vector<DocumentObject*> GeoFeatureGroup::getObjectsOfType(const Base::Type& typeId) const
{
std::vector<DocumentObject*> type;
const std::vector<DocumentObject*>& grp = Items.getValues();
for (std::vector<DocumentObject*>::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<DocumentObject*>& grp = Items.getValues();
for (std::vector<DocumentObject*>::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 ---------------------------------------------------------

View File

@@ -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) <fatzer2@gmail.com> 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 <App/FeaturePython.h>
#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<DocumentObject*> getObjects() const;
/** Returns a list of all objects of \a typeId this group does have.
*/
std::vector<DocumentObject*> 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<GeoFeatureGroup> GeoFeatureGroupPython;

View File

@@ -1,48 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="GeoFeaturePy"
Name="GeoFeatureGroupPy"
Twin="GeoFeatureGroup"
TwinPointer="GeoFeatureGroup"
Include="App/GeoFeatureGroup.h"
Namespace="App"
FatherInclude="App/GeoFeaturePy.h"
<PythonExport
Father="DocumentObjectGroupPy"
Name="GeoFeatureGroupPy"
Twin="GeoFeatureGroup"
TwinPointer="GeoFeatureGroup"
Include="App/GeoFeatureGroup.h"
Namespace="App"
FatherInclude="App/DocumentObjectGroupPy.h"
FatherNamespace="App">
<Documentation>
<Author Licence="LGPL" Name="Werner Mayer" EMail="wmayer@users.sourceforge.net" />
<UserDocu>This class handles document objects in Part</UserDocu>
</Documentation>
<Methode Name="newObject">
<Documentation>
<UserDocu>Create and add an object with given type and name to the GeoFeatureGroup</UserDocu>
</Documentation>
</Methode>
<Methode Name="addObject">
<Documentation>
<UserDocu>Add an object to the GeoFeatureGroup</UserDocu>
</Documentation>
</Methode>
<Methode Name="removeObject">
<Documentation>
<UserDocu>Remove an object from the GeoFeatureGroup</UserDocu>
</Documentation>
</Methode>
<Methode Name="removeObjectsFromDocument">
<Documentation>
<UserDocu>Remove all child objects from the GeoFeatureGroup and document</UserDocu>
</Documentation>
</Methode>
<Methode Name="getObject">
<Documentation>
<UserDocu>Return the object with the given name</UserDocu>
</Documentation>
</Methode>
<Methode Name="hasObject">
<Documentation>
<UserDocu>Checks if the GeoFeatureGroup has a given object</UserDocu>
</Documentation>
</Methode>
<CustomAttributes />
</PythonExport>
</GenerateModel>

View File

@@ -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<DocumentObjectPy*>(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<DocumentObjectPy*>(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<DocumentObjectPy*>(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;
}

View File

@@ -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!

View File

@@ -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<Part> PartPython;

View File

@@ -125,8 +125,13 @@ public:
/// return the higlight lines for a given element or the whole shape
virtual std::vector<Base::Vector3d> getSelectionShape(const char* Element) const
{ return std::vector<Base::Vector3d>(); }
/// 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<std::string> &)
/**
* 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<std::string> &subNames)
{ return true;}
//@}

View File

@@ -1,5 +1,6 @@
/***************************************************************************
* Copyright (c) 2011 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* Copyright (c) 2015 Alexander Golubev (Fat-Zer) <fatzer2@gmail.com> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
@@ -24,36 +25,21 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QApplication>
# include <QPixmap>
# include <Inventor/nodes/SoGroup.h>
#endif
#include <App/Part.h>
#include <App/Document.h>
#include <App/GeoFeatureGroup.h>
/// 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<App::DocumentObject*> ViewProviderGeoFeatureGroup::claimChildren3D(void) const {
App::GeoFeatureGroup *geoGroup = static_cast<App::GeoFeatureGroup *>(getObject());
const auto & objs = geoGroup->Group.getValues();
std::set<App::DocumentObject*> rvSet;
// search recursively for all non-geoGroups and claim their children either
std::set<App::DocumentObject*> curSearchSet (objs.begin(), objs.end());
std::vector<App::DocumentObject*> ViewProviderGeoFeatureGroup::claimChildren(void)const
{
return std::vector<App::DocumentObject*>(static_cast<App::Part*>(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<App::DocumentObject*> ViewProviderGeoFeatureGroup::claimChildren3D(void)const
{
return std::vector<App::DocumentObject*>(static_cast<App::Part*>(getObject())->Items.getValues());
}
rvSet.insert (*objIt);
if ( (*objIt)->isDerivedFrom ( App::DocumentObjectGroup::getClassTypeId () ) &&
!(*objIt)->isDerivedFrom ( App::GeoFeatureGroup::getClassTypeId () ) ) {
bool ViewProviderGeoFeatureGroup::onDelete(const std::vector<std::string> &)
{
//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<App::DocumentObjectGroup *> (*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<App::DocumentObject*> ( 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<std::string> ViewProviderGeoFeatureGroup::getDisplayModes(void) const
{
// get the modes of the father
std::vector<std::string> StrList = ViewProviderGeometryObject::getDisplayModes();
std::vector<std::string> 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<const App::PropertyPlacement*>(prop)->getValue().toMatrix() );
} else {
ViewProviderDocumentObjectGroup::updateData ( prop );
}
}
// Python feature -----------------------------------------------------------------------
namespace Gui {

View File

@@ -1,5 +1,6 @@
/***************************************************************************
* Copyright (c) 2011 Juergen Riegel <FreeCAD@juergen-riegel.net> *
* Copyright (c) 2015 Alexander Golubev (Fat-Zer) <fatzer2@gmail.com> *
* *
* 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<App::DocumentObject*> claimChildren(void)const;
virtual std::vector<App::DocumentObject*> 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<std::string> getDisplayModes(void) const;
virtual bool onDelete(const std::vector<std::string> &);
/// get called if the user hover over a object in the tree
//virtual bool allowDrop(const std::vector<const App::DocumentObject*> &objList,Qt::KeyboardModifiers keys,Qt::MouseButtons mouseBts,const QPoint &pos);
/// get called if the user drops some objects
//virtual void drop(const std::vector<const App::DocumentObject*> &objList,Qt::KeyboardModifiers keys,Qt::MouseButtons mouseBts,const QPoint &pos);
virtual void updateData(const App::Property*);
protected:
SoGroup *pcGroupChildren;
};

View File

@@ -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;

View File

@@ -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

View File

@@ -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<App::Part*>(pcObject);
if(static_cast<App::Part*>(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<View3DInventor*>(this->getActiveView())->getViewer();
SoGetBoundingBoxAction bboxAction(viewer->getSoRenderManager()->getViewportRegion());

View File

@@ -58,11 +58,6 @@ public:
virtual bool onDelete(const std::vector<std::string> &);
/// get called if the user hover over a object in the tree
//virtual bool allowDrop(const std::vector<const App::DocumentObject*> &objList,Qt::KeyboardModifiers keys,Qt::MouseButtons mouseBts,const QPoint &pos);
/// get called if the user drops some objects
//virtual void drop(const std::vector<const App::DocumentObject*> &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: