Groups: Handle add and remove object correctly
This commit is contained in:
@@ -133,6 +133,22 @@ void GeoFeatureGroupExtension::addObject(App::DocumentObject* object) {
|
||||
|
||||
Group.setValues(grp);
|
||||
}
|
||||
|
||||
|
||||
void GeoFeatureGroupExtension::removeObject(App::DocumentObject* object) {
|
||||
|
||||
//cross CoordinateSystem links are not allowed, so we need to remove the whole link group
|
||||
auto links = getCSRelevantLinks(object);
|
||||
links.push_back(object);
|
||||
|
||||
//remove all links out of group
|
||||
std::vector<DocumentObject*> grp = Group.getValues();
|
||||
for(auto link : links)
|
||||
grp.erase(std::remove(grp.begin(), grp.end(), link), grp.end());
|
||||
|
||||
Group.setValues(grp);
|
||||
}
|
||||
|
||||
std::vector< DocumentObject* > GeoFeatureGroupExtension::getObjectsFromLinks(DocumentObject* obj) {
|
||||
|
||||
//we get all linked objects. We can't use outList() as this includes the links from expressions
|
||||
|
||||
@@ -97,6 +97,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void addObject(DocumentObject* obj);
|
||||
virtual void removeObject(DocumentObject* obj);
|
||||
|
||||
/// returns GeoFeatureGroup relevant objects that are linked from the given one. That meas all linked objects
|
||||
/// including their linkes (recursively) except GeoFeatureGroups, where the recursion stops. Expressions
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "GroupExtensionPy.h"
|
||||
#include "Document.h"
|
||||
#include "FeaturePythonPyImp.h"
|
||||
#include "GeoFeatureGroupExtension.h"
|
||||
|
||||
using namespace App;
|
||||
|
||||
@@ -63,17 +64,23 @@ void GroupExtension::addObject(DocumentObject* obj)
|
||||
if(!allowObject(obj))
|
||||
return;
|
||||
|
||||
if (hasObject(obj))
|
||||
return;
|
||||
|
||||
//only one group per object. Note that it is allowed to be in a group and geofeaturegroup. However,
|
||||
//getGroupOfObject() returns only normal groups, no GeoFeatureGroups. Hence this works.
|
||||
auto *group = App::GroupExtension::getGroupOfObject(obj);
|
||||
if(group && group != getExtendedObject())
|
||||
group->getExtensionByType<App::GroupExtension>()->removeObject(obj);
|
||||
|
||||
if (!hasObject(obj)) {
|
||||
std::vector<DocumentObject*> grp = Group.getValues();
|
||||
grp.push_back(obj);
|
||||
Group.setValues(grp);
|
||||
}
|
||||
//if we are on a geofeaturegroup we need to ensure the object is too
|
||||
auto geogrp = GeoFeatureGroupExtension::getGroupOfObject(getExtendedObject());
|
||||
if( geogrp && (geogrp != GeoFeatureGroupExtension::getGroupOfObject(obj)) )
|
||||
geogrp->getExtensionByType<GeoFeatureGroupExtension>()->addObject(obj);
|
||||
|
||||
std::vector<DocumentObject*> grp = Group.getValues();
|
||||
grp.push_back(obj);
|
||||
Group.setValues(grp);
|
||||
}
|
||||
|
||||
void GroupExtension::addObjects(const std::vector<App::DocumentObject*>& objs)
|
||||
|
||||
@@ -120,102 +120,6 @@ void ViewProviderGeoFeatureGroupExtension::extensionUpdateData(const App::Proper
|
||||
}
|
||||
}
|
||||
|
||||
std::vector< App::DocumentObject* > ViewProviderGeoFeatureGroupExtension::getLinkedObjects(App::DocumentObject* obj) {
|
||||
|
||||
if(!obj)
|
||||
return std::vector< App::DocumentObject* >();
|
||||
|
||||
//if the object is a geofeaturegroup than all dependencies belong to that CS, we are not allowed
|
||||
//to grap them
|
||||
if(obj->hasExtension(App::GeoFeatureGroupExtension::getExtensionClassTypeId()))
|
||||
return std::vector< App::DocumentObject* >();
|
||||
|
||||
//we get all linked objects
|
||||
std::vector< App::DocumentObject* > result;
|
||||
std::vector<App::Property*> list;
|
||||
obj->getPropertyList(list);
|
||||
for(App::Property* prop : list) {
|
||||
if(prop->getTypeId().isDerivedFrom(App::PropertyLink::getClassTypeId()))
|
||||
result.push_back(static_cast<App::PropertyLink*>(prop)->getValue());
|
||||
else if(prop->getTypeId().isDerivedFrom(App::PropertyLinkList::getClassTypeId())) {
|
||||
auto vec = static_cast<App::PropertyLinkList*>(prop)->getValues();
|
||||
result.insert(result.end(), vec.begin(), vec.end());
|
||||
}
|
||||
else if(prop->getTypeId().isDerivedFrom(App::PropertyLinkSub::getClassTypeId()))
|
||||
result.push_back(static_cast<App::PropertyLinkSub*>(prop)->getValue());
|
||||
else if(prop->getTypeId().isDerivedFrom(App::PropertyLinkSubList::getClassTypeId())) {
|
||||
auto vec = static_cast<App::PropertyLinkList*>(prop)->getValues();
|
||||
result.insert(result.end(), vec.begin(), vec.end());
|
||||
}
|
||||
}
|
||||
|
||||
//clear all null objects
|
||||
result.erase(std::remove(result.begin(), result.end(), nullptr), result.end());
|
||||
|
||||
//collect all dependencies of those objects
|
||||
std::vector< App::DocumentObject* > links;
|
||||
for(App::DocumentObject *obj : result) {
|
||||
auto vec = getLinkedObjects(obj);
|
||||
links.insert(links.end(), vec.begin(), vec.end());
|
||||
}
|
||||
|
||||
if (!links.empty()) {
|
||||
result.insert(result.end(), links.begin(), links.end());
|
||||
std::sort(result.begin(), result.end());
|
||||
result.erase(std::unique(result.begin(), result.end()), result.end());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void ViewProviderGeoFeatureGroupExtension::extensionDropObject(App::DocumentObject* obj) {
|
||||
|
||||
// Open command
|
||||
App::DocumentObject* grp = static_cast<App::DocumentObject*>(getExtendedViewProvider()->getObject());
|
||||
App::Document* doc = grp->getDocument();
|
||||
Gui::Document* gui = Gui::Application::Instance->getDocument(doc);
|
||||
gui->openCommand("Move object");
|
||||
|
||||
//links between different CS are not allowed, hence we need to ensure if all dependencies are in
|
||||
//the same geofeaturegroup
|
||||
auto vec = getLinkedObjects(obj);
|
||||
|
||||
//remove all objects already in the correct group
|
||||
vec.erase(std::remove_if(vec.begin(), vec.end(), [this](App::DocumentObject* o){
|
||||
return App::GroupExtension::getGroupOfObject(o) == this->getExtendedViewProvider()->getObject();
|
||||
}), vec.end());
|
||||
|
||||
vec.push_back(obj);
|
||||
|
||||
for(App::DocumentObject* o : vec) {
|
||||
// build Python command for execution
|
||||
QString cmd;
|
||||
cmd = QString::fromLatin1("App.getDocument(\"%1\").getObject(\"%2\").addObject("
|
||||
"App.getDocument(\"%1\").getObject(\"%3\"))")
|
||||
.arg(QString::fromLatin1(doc->getName()))
|
||||
.arg(QString::fromLatin1(grp->getNameInDocument()))
|
||||
.arg(QString::fromLatin1(o->getNameInDocument()));
|
||||
|
||||
Gui::Command::doCommand(Gui::Command::App, cmd.toUtf8());
|
||||
}
|
||||
gui->commitCommand();
|
||||
}
|
||||
|
||||
|
||||
void ViewProviderGeoFeatureGroupExtension::extensionDragObject(App::DocumentObject* obj) {
|
||||
//links between different coordinate systems are not allowed, hence draging one object also needs
|
||||
//to drag out all dependend objects
|
||||
auto vec = getLinkedObjects(obj);
|
||||
|
||||
//add this object
|
||||
vec.push_back(obj);
|
||||
|
||||
for(App::DocumentObject* obj : vec)
|
||||
ViewProviderGroupExtension::extensionDragObject(obj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
namespace Gui {
|
||||
EXTENSION_PROPERTY_SOURCE_TEMPLATE(Gui::ViewProviderGeoFeatureGroupExtensionPython, Gui::ViewProviderGeoFeatureGroupExtension)
|
||||
|
||||
|
||||
@@ -58,14 +58,9 @@ public:
|
||||
}
|
||||
|
||||
virtual void extensionUpdateData(const App::Property*) override;
|
||||
|
||||
virtual void extensionDropObject(App::DocumentObject*) override;
|
||||
virtual void extensionDragObject(App::DocumentObject*) override;
|
||||
|
||||
|
||||
protected:
|
||||
SoGroup *pcGroupChildren;
|
||||
|
||||
std::vector<App::DocumentObject*> getLinkedObjects(App::DocumentObject* obj);
|
||||
};
|
||||
|
||||
typedef ViewProviderExtensionPythonT<Gui::ViewProviderGeoFeatureGroupExtension> ViewProviderGeoFeatureGroupExtensionPython;
|
||||
|
||||
@@ -86,13 +86,6 @@ bool ViewProviderGroupExtension::extensionCanDropObject(App::DocumentObject* obj
|
||||
if (group->hasObject(obj))
|
||||
return false;
|
||||
|
||||
//group into group?
|
||||
if (obj->hasExtension(App::GroupExtension::getExtensionClassTypeId())) {
|
||||
if (group->isChildOf(obj->getExtensionByType<App::GroupExtension>()))
|
||||
return false;
|
||||
}
|
||||
|
||||
//We need to find the correct App extension to ask if this is a supported type, there should only be one
|
||||
if (group->allowObject(obj))
|
||||
return true;
|
||||
|
||||
@@ -107,18 +100,6 @@ void ViewProviderGroupExtension::extensionDropObject(App::DocumentObject* obj) {
|
||||
Gui::Document* gui = Gui::Application::Instance->getDocument(doc);
|
||||
gui->openCommand("Move object");
|
||||
|
||||
const App::DocumentObject* par = App::GroupExtension::getGroupOfObject(obj);
|
||||
if (par) {
|
||||
// allow an object to be in one group only
|
||||
QString cmd;
|
||||
cmd = QString::fromLatin1("App.getDocument(\"%1\").getObject(\"%2\").removeObject("
|
||||
"App.getDocument(\"%1\").getObject(\"%3\"))")
|
||||
.arg(QString::fromLatin1(doc->getName()))
|
||||
.arg(QString::fromLatin1(par->getNameInDocument()))
|
||||
.arg(QString::fromLatin1(obj->getNameInDocument()));
|
||||
Gui::Command::doCommand(Gui::Command::App, cmd.toUtf8());
|
||||
}
|
||||
|
||||
// build Python command for execution
|
||||
QString cmd;
|
||||
cmd = QString::fromLatin1("App.getDocument(\"%1\").getObject(\"%2\").addObject("
|
||||
|
||||
@@ -69,6 +69,8 @@ public:
|
||||
/// Reset the visibility
|
||||
void resetTemporaryVisibility ();
|
||||
///@}
|
||||
|
||||
virtual bool canDragObjects() const {return false;};
|
||||
|
||||
/// Returns default size. Use this if it is not possible to determine appropriate size by other means
|
||||
static double defaultSize() {return 10.;}
|
||||
|
||||
@@ -199,64 +199,6 @@ void ViewProviderOriginGroupExtension::updateOriginSize () {
|
||||
vpOrigin->Size.setValue ( size * 1.3 );
|
||||
}
|
||||
|
||||
void ViewProviderOriginGroupExtension::extensionDragObject(App::DocumentObject* obj) {
|
||||
|
||||
//links between different coordinate systems are not allowed, hence draging one object also needs
|
||||
//to drag out all dependend objects
|
||||
auto vec = getLinkedObjects(obj);
|
||||
|
||||
//remove all origin objects
|
||||
vec.erase(std::remove_if(vec.begin(), vec.end(), [this](App::DocumentObject* o) {
|
||||
return o->isDerivedFrom(App::OriginFeature::getClassTypeId());}), vec.end());
|
||||
|
||||
//add the original object
|
||||
vec.push_back(obj);
|
||||
|
||||
for(App::DocumentObject* obj : vec)
|
||||
ViewProviderGroupExtension::extensionDragObject(obj);
|
||||
}
|
||||
|
||||
void ViewProviderOriginGroupExtension::extensionDropObject(App::DocumentObject* obj) {
|
||||
|
||||
// Open command
|
||||
App::DocumentObject* grp = static_cast<App::DocumentObject*>(getExtendedViewProvider()->getObject());
|
||||
App::Document* doc = grp->getDocument();
|
||||
Gui::Document* gui = Gui::Application::Instance->getDocument(doc);
|
||||
gui->openCommand("Move object");
|
||||
|
||||
//links between different CS are not allowed, hence we need to enure if all dependencies are in
|
||||
//the same geofeaturegroup
|
||||
auto vec = getLinkedObjects(obj);
|
||||
|
||||
//remove all origin objects
|
||||
vec.erase(std::remove_if(vec.begin(), vec.end(), [](App::DocumentObject* o) {
|
||||
return o->isDerivedFrom(App::OriginFeature::getClassTypeId());}), vec.end());
|
||||
|
||||
//remove all objects already in the correct group
|
||||
vec.erase(std::remove_if(vec.begin(), vec.end(), [this](App::DocumentObject* o){
|
||||
return App::GroupExtension::getGroupOfObject(o) == this->getExtendedViewProvider()->getObject();
|
||||
}), vec.end());
|
||||
|
||||
//add the original object
|
||||
vec.push_back(obj);
|
||||
|
||||
for(App::DocumentObject* o : vec) {
|
||||
|
||||
// build Python command for execution
|
||||
QString cmd;
|
||||
cmd = QString::fromLatin1("App.getDocument(\"%1\").getObject(\"%2\").addObject("
|
||||
"App.getDocument(\"%1\").getObject(\"%3\"))")
|
||||
.arg(QString::fromLatin1(doc->getName()))
|
||||
.arg(QString::fromLatin1(grp->getNameInDocument()))
|
||||
.arg(QString::fromLatin1(o->getNameInDocument()));
|
||||
|
||||
Gui::Command::doCommand(Gui::Command::App, cmd.toUtf8());
|
||||
}
|
||||
gui->commitCommand();
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace Gui {
|
||||
EXTENSION_PROPERTY_SOURCE_TEMPLATE(Gui::ViewProviderOriginGroupExtensionPython, Gui::ViewProviderOriginGroupExtension)
|
||||
|
||||
|
||||
@@ -45,9 +45,6 @@ public:
|
||||
|
||||
virtual void extensionAttach(App::DocumentObject *pcObject) override;
|
||||
virtual void extensionUpdateData(const App::Property* prop) override;
|
||||
|
||||
virtual void extensionDragObject(App::DocumentObject*) override;
|
||||
virtual void extensionDropObject(App::DocumentObject*) override;
|
||||
|
||||
void updateOriginSize();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user