some fixes in Active object handling on Viewer

This commit is contained in:
jriegel 2015-01-05 15:00:10 +01:00 committed by Stefan Tröger
parent 842604a2f8
commit 775744c1ac
5 changed files with 106 additions and 65 deletions

View File

@ -47,7 +47,12 @@ namespace Gui
{
public:
template<class T> T* getObject(const char*);
template<typename _T>
inline _T getObject(const char* name)
{
std::map<std::string, App::DocumentObject*>::const_iterator pos = _ObjectMap.find(name);
return pos == _ObjectMap.end() ? 0 : dynamic_cast<_T>(pos->second);
}
void setObject(App::DocumentObject*, const char*);
bool hasObject(const char*);
protected:
@ -56,15 +61,6 @@ namespace Gui
};
template<class T>
T* Gui::ActiveObjectList::getObject(const char* name)
{
auto pos = _ObjectMap.find(name);
if (pos == _ObjectMap.end())
return 0;
else
return dynamic_cast<T*>(pos->second);
}
} //namespace Gui

View File

@ -38,6 +38,7 @@
#include "Document.h"
#include "Application.h"
#include "MainWindow.h"
#include "ActiveObjectList.h"
using namespace Gui;
@ -48,6 +49,7 @@ MDIView::MDIView(Gui::Document* pcDocument,QWidget* parent, Qt::WindowFlags wfla
: QMainWindow(parent, wflags), BaseView(pcDocument),currentMode(Child), wstate(Qt::WindowNoState)
{
setAttribute(Qt::WA_DeleteOnClose);
pcActiveObjects = new ActiveObjectList();
}
MDIView::~MDIView()
@ -70,6 +72,8 @@ MDIView::~MDIView()
}
}
}
delete pcActiveObjects;
}
void MDIView::deleteSelf()

View File

@ -26,7 +26,6 @@
#include "View.h"
#include <QMainWindow>
#include "ActiveObjectList.h"
QT_BEGIN_NAMESPACE
class QPrinter;
@ -35,6 +34,7 @@ QT_END_NAMESPACE
namespace Gui
{
class Document;
class ActiveObjectList;
/** Base class of all windows belonging to a document.
* There are two ways of belonging to a document:
@ -109,7 +109,7 @@ public:
virtual void setCurrentViewMode(ViewMode mode);
ViewMode currentViewMode() const { return currentMode; }
ActiveObjectList ActiveObjects;
ActiveObjectList *pcActiveObjects;
public Q_SLOTS:
virtual void setOverrideCursor(const QCursor&);

View File

@ -52,6 +52,8 @@
#include "View3DInventor.h"
#include "View3DInventorViewer.h"
#include "View3DViewerPy.h"
#include "ActiveObjectList.h"
#include <Base/Console.h>
#include <Base/Exception.h>
@ -174,6 +176,7 @@ void View3DInventorPy::init_type()
"Remove the DraggerCalback function from the coin node\n"
"Possibles types :\n"
"'addFinishCallback','addStartCallback','addMotionCallback','addValueChangedCallback'\n");
add_varargs_method("setActiveObject", &View3DInventorPy::setActiveObject, "setActiveObject(name,object)\nadd or set a new active object");
}
View3DInventorPy::View3DInventorPy(View3DInventor *vi)
@ -225,10 +228,12 @@ Py::Object View3DInventorPy::getattr(const char * attr)
throw Py::RuntimeError(s_out.str());
}
else {
App::DocumentObject *docObj = _view->ActiveObjects.getObject<App::DocumentObject>(attr);
// see if a active object has the same name
App::DocumentObject *docObj = _view->pcActiveObjects->getObject<App::DocumentObject*>(attr);
if (docObj){
return Py::Object(docObj->getPyObject());
return Py::Object(docObj->getPyObject(),true);
}else{
// else looking for a methode with the name and call it
Py::Object obj = Py::PythonExtension<View3DInventorPy>::getattr(attr);
if (PyCFunction_Check(obj.ptr())) {
PyCFunctionObject* op = reinterpret_cast<PyCFunctionObject*>(obj.ptr());
@ -2169,12 +2174,14 @@ Py::Object View3DInventorPy::removeDraggerCallback(const Py::Tuple& args)
Py::Object View3DInventorPy::setActiveObject(const Py::Tuple& args)
{
App::DocumentObjectPy* docObject = 0;
PyObject* docObject = 0;
char* name;
if (!PyArg_ParseTuple(args.ptr(), "sO!", &name, &App::DocumentObjectPy::Type, &docObject))
throw Py::Exception();
if (docObject){
_view->ActiveObjects.setObject(docObject->getDocumentObjectPtr(), name);
App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(docObject)->getDocumentObjectPtr();
_view->pcActiveObjects->setObject(obj, name);
}
return Py::None();
}

View File

@ -47,6 +47,8 @@
#include <Gui/Control.h>
#include <Gui/DlgCheckableMessageBox.h>
#include <Gui/ViewProviderPart.h>
#include <Gui/ActiveObjectList.h>
#include <Mod/Sketcher/Gui/Workbench.h>
#include <Mod/Part/App/Part2DObject.h>
@ -101,7 +103,21 @@ Workbench::~Workbench()
PartDesign::Body *Workbench::setUpPart(const App::Part *part)
{
// first do the general Part setup
Gui::ViewProviderPart::setUpPart(part);
// check for Bodies
std::vector<App::DocumentObject*> bodies = part->getObjectsOfType(PartDesign::Body::getClassTypeId());
assert(bodies.size() == 0);
std::string PartName = part->getNameInDocument();
std::string BodyName = part->getDocument()->getUniqueObjectName("MainBody");
Gui::Command::addModule(Gui::Command::Doc, "PartDesign");
Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().addObject('PartDesign::Body','%s')", BodyName.c_str());
Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().%s.addObject(App.activeDocument().ActiveObject)", part->getNameInDocument());
Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeView().setActiveObject('Body',App.activeDocument().%s)", BodyName.c_str());
return NULL;
}
@ -322,72 +338,90 @@ void Workbench::_switchToDocument(const App::Document* doc)
if (doc == NULL) return;
PartDesign::Body* activeBody = NULL;
App::Part* activePart = NULL;
std::vector<App::DocumentObject*> bodies = doc->getObjectsOfType(PartDesign::Body::getClassTypeId());
// Is there a body feature in this document?
if (bodies.empty())
// No tip, so build up structure or migrate
if (!doc->Tip.getValue())
{
_doMigration(doc);
if (doc->countObjects() == 0){
std::string PartName = doc->getUniqueObjectName("Part");
//// create a PartDesign Part for now, can be later any kind of Part or an empty one
Gui::Command::addModule(Gui::Command::Doc, "PartDesignGui");
Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().Tip = App.activeDocument().addObject('App::Part','%s')", PartName.c_str());
Gui::Command::doCommand(Gui::Command::Doc, "PartDesignGui.setUpPart(App.activeDocument().%s)", PartName.c_str());
Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeView().setActiveObject('Part',App.activeDocument().%s)", PartName.c_str());
activeBody = Gui::Application::Instance->activeDocument()->getActiveView()->pcActiveObjects->getObject<PartDesign::Body*>("Body");
// body have to be created
assert(activeBody);
} else
// empty document with no tip, so do migration
_doMigration(doc);
}
else
{
// Find active body
for (std::vector<App::DocumentObject*>::const_iterator b = bodies.begin(); b != bodies.end(); b++) {
PartDesign::Body* body = static_cast<PartDesign::Body*>(*b);
if (body->IsActive.getValue()) {
activeBody = body;
break;
}
}
activeBody = Gui::Application::Instance->activeDocument()->getActiveView()->pcActiveObjects->getObject<PartDesign::Body*>("Body");
activePart = Gui::Application::Instance->activeDocument()->getActiveView()->pcActiveObjects->getObject<App::Part*>("Part");
// Do the base planes exist in this document?
bool found = false;
std::vector<App::DocumentObject*> planes = doc->getObjectsOfType(App::Plane::getClassTypeId());
for (std::vector<App::DocumentObject*>::const_iterator p = planes.begin(); p != planes.end(); p++) {
for (unsigned i = 0; i < 3; i++) {
if (strcmp(PartDesignGui::BaseplaneNames[i], (*p)->getNameInDocument()) == 0) {
found = true;
break;
}
}
if (found) break;
}
//// Find active body
//for (std::vector<App::DocumentObject*>::const_iterator b = bodies.begin(); b != bodies.end(); b++) {
// PartDesign::Body* body = static_cast<PartDesign::Body*>(*b);
// if (body->IsActive.getValue()) {
// activeBody = body;
// break;
// }
//}
if (!found) {
// Add the planes ...
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject('App::Plane','%s')", PartDesignGui::BaseplaneNames[0]);
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().ActiveObject.Label = '%s'", QObject::tr("XY-Plane").toStdString().c_str());
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject('App::Plane','%s')", PartDesignGui::BaseplaneNames[1]);
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().ActiveObject.Placement = App.Placement(App.Vector(),App.Rotation(App.Vector(1,0,0),90))");
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().ActiveObject.Label = '%s'", QObject::tr("XZ-Plane").toStdString().c_str());
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject('App::Plane','%s')", PartDesignGui::BaseplaneNames[2]);
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().ActiveObject.Placement = App.Placement(App.Vector(),App.Rotation(App.Vector(0,1,0),90))");
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().ActiveObject.Label = '%s'", QObject::tr("YZ-Plane").toStdString().c_str());
// ... and put them in the 'Origin' group
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject('App::DocumentObjectGroup','%s')", QObject::tr("Origin").toStdString().c_str());
for (unsigned i = 0; i < 3; i++)
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().Origin.addObject(App.activeDocument().getObject('%s'))", PartDesignGui::BaseplaneNames[i]);
// TODO: Fold the group (is that possible through the Python interface?)
}
//// Do the base planes exist in this document?
//bool found = false;
//std::vector<App::DocumentObject*> planes = doc->getObjectsOfType(App::Plane::getClassTypeId());
//for (std::vector<App::DocumentObject*>::const_iterator p = planes.begin(); p != planes.end(); p++) {
// for (unsigned i = 0; i < 3; i++) {
// if (strcmp(PartDesignGui::BaseplaneNames[i], (*p)->getNameInDocument()) == 0) {
// found = true;
// break;
// }
// }
// if (found) break;
//}
//if (!found) {
// // Add the planes ...
// Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject('App::Plane','%s')", PartDesignGui::BaseplaneNames[0]);
// Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().ActiveObject.Label = '%s'", QObject::tr("XY-Plane").toStdString().c_str());
// Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject('App::Plane','%s')", PartDesignGui::BaseplaneNames[1]);
// Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().ActiveObject.Placement = App.Placement(App.Vector(),App.Rotation(App.Vector(1,0,0),90))");
// Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().ActiveObject.Label = '%s'", QObject::tr("XZ-Plane").toStdString().c_str());
// Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject('App::Plane','%s')", PartDesignGui::BaseplaneNames[2]);
// Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().ActiveObject.Placement = App.Placement(App.Vector(),App.Rotation(App.Vector(0,1,0),90))");
// Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().ActiveObject.Label = '%s'", QObject::tr("YZ-Plane").toStdString().c_str());
// // ... and put them in the 'Origin' group
// Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject('App::DocumentObjectGroup','%s')", QObject::tr("Origin").toStdString().c_str());
// for (unsigned i = 0; i < 3; i++)
// Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().Origin.addObject(App.activeDocument().getObject('%s'))", PartDesignGui::BaseplaneNames[i]);
// // TODO: Fold the group (is that possible through the Python interface?)
//}
}
// If there is only one body, make it active
if ((activeBody == NULL) && (bodies.size() == 1))
activeBody = static_cast<PartDesign::Body*>(bodies.front());
//// If there is only one body, make it active
//if ((activeBody == NULL) && (bodies.size() == 1))
// activeBody = static_cast<PartDesign::Body*>(bodies.front());
// add the non PartDesign feature group to the Part
if( groupCreated && doc->Tip.getValue() != NULL)
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().Tip.addObject(App.activeDocument().NonBodyFeatures)");
//// add the non PartDesign feature group to the Part
//if( groupCreated && doc->Tip.getValue() != NULL)
// Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().Tip.addObject(App.activeDocument().NonBodyFeatures)");
if (activeBody != NULL) {
Gui::Command::doCommand(Gui::Command::Doc,"import PartDesignGui");
Gui::Command::doCommand(Gui::Command::Gui,"PartDesignGui.setActiveBody(App.activeDocument().%s)", activeBody->getNameInDocument());
} else {
if (activeBody == NULL) {
QMessageBox::critical(Gui::getMainWindow(), QObject::tr("Could not create body"),
QObject::tr("No body was found in this document, and none could be created. Please report this bug."
"We recommend you do not use this document with the PartDesign workbench until the bug has been fixed."
));
}
std::string bodyName = activeBody->getNameInDocument();
}
void Workbench::slotActiveDocument(const Gui::Document& Doc)