Changing active object handling in PartDesign

This commit is contained in:
jriegel 2015-01-06 22:45:01 +01:00 committed by Stefan Tröger
parent 775744c1ac
commit 45f7c99c1c
24 changed files with 255 additions and 169 deletions

View File

@ -29,18 +29,28 @@
#endif
#include "ActiveObjectList.h"
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/ViewProviderDocumentObject.h>
using namespace Gui;
void Gui::ActiveObjectList::setObject(App::DocumentObject* obj, const char* name)
void Gui::ActiveObjectList::setObject(App::DocumentObject* obj, const char* name, const Gui::HighlightMode& mode)
{
_ObjectMap[name] = obj;
if (obj){
if (hasObject(name)){
Gui::Application::Instance->activeDocument()->signalHighlightObject(*dynamic_cast<Gui::ViewProviderDocumentObject*>(Gui::Application::Instance->activeDocument()->getViewProvider(getObject<App::DocumentObject*>(name))), mode, false);
}
_ObjectMap[name] = obj;
Gui::Application::Instance->activeDocument()->signalHighlightObject(*dynamic_cast<Gui::ViewProviderDocumentObject*>(Gui::Application::Instance->activeDocument()->getViewProvider(obj)), mode, true);
}
}
bool Gui::ActiveObjectList::hasObject(const char*name)
bool Gui::ActiveObjectList::hasObject(const char*name)const
{
return _ObjectMap.find(name) != _ObjectMap.end();
}

View File

@ -27,6 +27,7 @@
#define GUI_ActiveObjectList_H
#include <map>
#include "Tree.h"
namespace App {
class DocumentObject;
}
@ -48,13 +49,13 @@ namespace Gui
public:
template<typename _T>
inline _T getObject(const char* name)
inline _T getObject(const char* name) const
{
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*);
void setObject(App::DocumentObject*, const char*, const Gui::HighlightMode& m = Gui::LightBlue);
bool hasObject(const char*)const;
protected:
std::map<std::string, App::DocumentObject*> _ObjectMap;

View File

@ -321,6 +321,15 @@ struct PyMethodDef FreeCADGui_methods[] = {
{NULL, NULL} /* sentinel */
};
Gui::MDIView* Application::activeView(void) const
{
if (activeDocument())
return activeDocument()->getActiveView();
else
return NULL;
}
} // namespace Gui
Application::Application(bool GUIenabled)

View File

@ -147,7 +147,9 @@ public:
* If no such document exists 0 is returned.
*/
Gui::Document* getDocument(const App::Document* pDoc) const;
/// Shows the associated view provider of the given object
/// Getter for the active view of the active document or null
Gui::MDIView* activeView(void) const;
/// Shows the associated view provider of the given object
void showViewProvider(const App::DocumentObject*);
/// Hides the associated view provider of the given object
void hideViewProvider(const App::DocumentObject*);

View File

@ -38,7 +38,6 @@
#include "Document.h"
#include "Application.h"
#include "MainWindow.h"
#include "ActiveObjectList.h"
using namespace Gui;
@ -49,7 +48,6 @@ 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()
@ -73,7 +71,6 @@ MDIView::~MDIView()
}
}
delete pcActiveObjects;
}
void MDIView::deleteSelf()

View File

@ -26,6 +26,7 @@
#include "View.h"
#include <QMainWindow>
#include "ActiveObjectList.h"
QT_BEGIN_NAMESPACE
class QPrinter;
@ -34,7 +35,6 @@ 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,21 @@ public:
virtual void setCurrentViewMode(ViewMode mode);
ViewMode currentViewMode() const { return currentMode; }
ActiveObjectList *pcActiveObjects;
/// access getter for the active object list
template<typename _T>
inline _T getActiveObject(const char* name) const
{
return ActiveObjects.getObject<_T>(name);
};
void setActiveObject(App::DocumentObject*o, const char*n)
{
ActiveObjects.setObject(o, n);
};
bool hasActiveObject(const char*n) const
{
return ActiveObjects.hasObject(n);
};
public Q_SLOTS:
virtual void setOverrideCursor(const QCursor&);
@ -133,6 +147,8 @@ protected:
private:
ViewMode currentMode;
Qt::WindowStates wstate;
// list of active objects of this view
ActiveObjectList ActiveObjects;
};
} // namespace Gui

View File

@ -229,7 +229,7 @@ Py::Object View3DInventorPy::getattr(const char * attr)
}
else {
// see if a active object has the same name
App::DocumentObject *docObj = _view->pcActiveObjects->getObject<App::DocumentObject*>(attr);
App::DocumentObject *docObj = _view->getActiveObject<App::DocumentObject*>(attr);
if (docObj){
return Py::Object(docObj->getPyObject(),true);
}else{
@ -2181,7 +2181,7 @@ Py::Object View3DInventorPy::setActiveObject(const Py::Tuple& args)
if (docObject){
App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(docObject)->getDocumentObjectPtr();
_view->pcActiveObjects->setObject(obj, name);
_view->setActiveObject(obj, name);
}
return Py::None();
}

View File

@ -43,53 +43,48 @@
namespace PartDesignGui {
// pointer to the active assembly object
PartDesign::Body *ActivePartObject =0;
Gui::Document *ActiveGuiDoc =0;
App::Document *ActiveAppDoc =0;
Gui::ViewProviderDocumentObject *ActiveVp =0;
// The names of the base planes. Note: The user-visible label is different from this
const char* BaseplaneNames[3] = {"BaseplaneXY", "BaseplaneXZ", "BaseplaneYZ"};
}
static PyObject * setActiveBody(PyObject *self, PyObject *args)
{
PyObject *object=0;
if (PyArg_ParseTuple(args,"|O!",&(PartDesign::BodyPy::Type), &object)&& object) {
PartDesign::Body* Item = static_cast<PartDesign::BodyPy*>(object)->getBodyPtr();
// Should be set!
assert(Item);
// Set old body inactive if we are activating another body in the same document
if ((PartDesignGui::ActivePartObject != NULL) &&
(PartDesignGui::ActivePartObject->getDocument() == Item->getDocument()))
PartDesignGui::ActivePartObject->IsActive.setValue(false);
PartDesignGui::ActivePartObject = Item;
PartDesignGui::ActiveAppDoc = Item->getDocument();
PartDesignGui::ActiveGuiDoc = Gui::Application::Instance->getDocument(PartDesignGui::ActiveAppDoc);
PartDesignGui::ActiveVp = dynamic_cast<Gui::ViewProviderDocumentObject*> (PartDesignGui::ActiveGuiDoc->getViewProvider(Item));
PartDesignGui::ActiveVp->show();
Item->IsActive.setValue(true);
} else {
// This handles the case of deactivating the workbench
PartDesignGui::ActivePartObject=0;
PartDesignGui::ActiveGuiDoc =0;
PartDesignGui::ActiveAppDoc =0;
PartDesignGui::ActiveVp =0;
}
Py_Return;
}
static PyObject * getActiveBody(PyObject *, PyObject *)
{
if (PartDesignGui::ActivePartObject == NULL) {
return Py::_None();
}
return PartDesignGui::ActivePartObject->getPyObject();
}
//static PyObject * setActiveBody(PyObject *self, PyObject *args)
//{
// PyObject *object=0;
// if (PyArg_ParseTuple(args,"|O!",&(PartDesign::BodyPy::Type), &object)&& object) {
// PartDesign::Body* Item = static_cast<PartDesign::BodyPy*>(object)->getBodyPtr();
// // Should be set!
// assert(Item);
//
// // Set old body inactive if we are activating another body in the same document
// if ((PartDesignGui::ActivePartObject != NULL) &&
// (PartDesignGui::ActivePartObject->getDocument() == Item->getDocument()))
// PartDesignGui::ActivePartObject->IsActive.setValue(false);
// PartDesignGui::ActivePartObject = Item;
// PartDesignGui::ActiveAppDoc = Item->getDocument();
// PartDesignGui::ActiveGuiDoc = Gui::Application::Instance->getDocument(PartDesignGui::ActiveAppDoc);
// PartDesignGui::ActiveVp = dynamic_cast<Gui::ViewProviderDocumentObject*> (PartDesignGui::ActiveGuiDoc->getViewProvider(Item));
// PartDesignGui::ActiveVp->show();
// Item->IsActive.setValue(true);
// } else {
// // This handles the case of deactivating the workbench
// PartDesignGui::ActivePartObject=0;
// PartDesignGui::ActiveGuiDoc =0;
// PartDesignGui::ActiveAppDoc =0;
// PartDesignGui::ActiveVp =0;
// }
//
// Py_Return;
//}
//
//static PyObject * getActiveBody(PyObject *, PyObject *)
//{
// if (PartDesignGui::ActivePartObject == NULL) {
// return Py::_None();
// }
//
// return PartDesignGui::ActivePartObject->getPyObject();
//}
void setUpPart(App::Part *part);
@ -112,11 +107,11 @@ static PyObject * setUpPart(PyObject *self, PyObject *args)
/* registration table */
struct PyMethodDef Assembly_methods[] = {
{"setActiveBody" ,setActiveBody ,METH_VARARGS,
"setActiveBody(BodyObject) -- Set the PartBody object in work."},
//{"setActiveBody" ,setActiveBody ,METH_VARARGS,
// "setActiveBody(BodyObject) -- Set the PartBody object in work."},
{"getActiveBody" ,getActiveBody ,METH_NOARGS,
"getActiveBody() -- Get the PartBody object in work."},
//{"getActiveBody" ,getActiveBody ,METH_NOARGS,
// "getActiveBody() -- Get the PartBody object in work."},
{"setUpPart" ,setUpPart ,METH_VARARGS,
"setUpPart(Part) -- Sets a empty part object up for usage in PartDesign."},

View File

@ -43,17 +43,12 @@
namespace PartDesignGui {
// pointer to the active assembly object
PartDesign::Body *ActivePartObject =0;
Gui::Document *ActiveGuiDoc =0;
App::Document *ActiveAppDoc =0;
Gui::ViewProviderDocumentObject *ActiveVp =0;
// The names of the base planes. Note: The user-visible label is different from this
const char* BaseplaneNames[3] = {"BaseplaneXY", "BaseplaneXZ", "BaseplaneYZ"};
}
<<<<<<< 4db2e50e38d4a9c01764fa8dedb78231fc64faee:src/Mod/Assembly/App/AppAssemblyPy.cpp
static PyObject * setActiveBody(PyObject *self, PyObject *args)
{
PyObject *object=0;
@ -82,12 +77,7 @@ static PyObject * setActiveBody(PyObject *self, PyObject *args)
Py_Return;
}
<<<<<<< 394f4c51924312cf9cfcce09be5c3ba696a82cf4:src/Mod/Assembly/App/AppAssemblyPy.cpp
static PyObject * getActivePart(PyObject *, PyObject *)
=======
static PyObject * getActiveBody(PyObject *, PyObject *)
>>>>>>> Assembly: Rename to setActiveBody and make link indeipendant Part initialization:src/Mod/PartDesign/Gui/AppPartDesignGuiPy.cpp
{
if (PartDesignGui::ActivePartObject == NULL) {
return Py::_None();
@ -95,6 +85,45 @@ static PyObject * getActiveBody(PyObject *, PyObject *)
return PartDesignGui::ActivePartObject->getPyObject();
}
=======
//static PyObject * setActiveBody(PyObject *self, PyObject *args)
//{
// PyObject *object=0;
// if (PyArg_ParseTuple(args,"|O!",&(PartDesign::BodyPy::Type), &object)&& object) {
// PartDesign::Body* Item = static_cast<PartDesign::BodyPy*>(object)->getBodyPtr();
// // Should be set!
// assert(Item);
//
// // Set old body inactive if we are activating another body in the same document
// if ((PartDesignGui::ActivePartObject != NULL) &&
// (PartDesignGui::ActivePartObject->getDocument() == Item->getDocument()))
// PartDesignGui::ActivePartObject->IsActive.setValue(false);
// PartDesignGui::ActivePartObject = Item;
// PartDesignGui::ActiveAppDoc = Item->getDocument();
// PartDesignGui::ActiveGuiDoc = Gui::Application::Instance->getDocument(PartDesignGui::ActiveAppDoc);
// PartDesignGui::ActiveVp = dynamic_cast<Gui::ViewProviderDocumentObject*> (PartDesignGui::ActiveGuiDoc->getViewProvider(Item));
// PartDesignGui::ActiveVp->show();
// Item->IsActive.setValue(true);
// } else {
// // This handles the case of deactivating the workbench
// PartDesignGui::ActivePartObject=0;
// PartDesignGui::ActiveGuiDoc =0;
// PartDesignGui::ActiveAppDoc =0;
// PartDesignGui::ActiveVp =0;
// }
//
// Py_Return;
//}
//
//static PyObject * getActiveBody(PyObject *, PyObject *)
//{
// if (PartDesignGui::ActivePartObject == NULL) {
// return Py::_None();
// }
//
// return PartDesignGui::ActivePartObject->getPyObject();
//}
>>>>>>> Changing active object handling in PartDesign:src/Mod/PartDesign/Gui/AppPartDesignGuiPy.cpp
void setUpPart(App::Part *part);
@ -116,18 +145,18 @@ static PyObject * setUpPart(PyObject *self, PyObject *args)
/* registration table */
<<<<<<< 394f4c51924312cf9cfcce09be5c3ba696a82cf4:src/Mod/Assembly/App/AppAssemblyPy.cpp
<<<<<<< 4db2e50e38d4a9c01764fa8dedb78231fc64faee:src/Mod/Assembly/App/AppAssemblyPy.cpp
struct PyMethodDef Assembly_methods[] = {
{"setActivePart" ,setActivePart ,METH_VARARGS,
"setActivePart(BodyObject) -- Set the PartBody object in work."},
=======
struct PyMethodDef PartDesignGui_Import_methods[] = {
{"setActiveBody" ,setActiveBody ,METH_VARARGS,
"setActiveBody(BodyObject) -- Set the PartBody object in work."},
=======
struct PyMethodDef PartDesignGui_Import_methods[] = {
//{"setActiveBody" ,setActiveBody ,METH_VARARGS,
// "setActiveBody(BodyObject) -- Set the PartBody object in work."},
>>>>>>> Changing active object handling in PartDesign:src/Mod/PartDesign/Gui/AppPartDesignGuiPy.cpp
{"setActiveBody" ,getActiveBody ,METH_NOARGS,
"setActiveBody() -- Get the PartBody object in work."},
>>>>>>> Assembly: Rename to setActiveBody and make link indeipendant Part initialization:src/Mod/PartDesign/Gui/AppPartDesignGuiPy.cpp
//{"getActiveBody" ,getActiveBody ,METH_NOARGS,
// "getActiveBody() -- Get the PartBody object in work."},
{"setUpPart" ,setUpPart ,METH_VARARGS,
"setUpPart(Part) -- Sets a empty part object up for usage in PartDesign."},

View File

@ -53,7 +53,7 @@ PROPERTY_SOURCE(PartDesign::Body, Part::BodyBase)
Body::Body()
{
ADD_PROPERTY(IsActive,(0));
//ADD_PROPERTY(IsActive,(0));
}
/*

View File

@ -40,7 +40,7 @@ class PartDesignExport Body : public Part::BodyBase
public:
/// True if this body feature is active or was active when the document was last closed
App::PropertyBool IsActive;
//App::PropertyBool IsActive;
Body();

View File

@ -250,13 +250,13 @@ void CmdPartDesignDuplicateSelection::activated(int iMsg)
return;
}
std::vector<App::DocumentObject*> beforeFeatures = PartDesignGui::ActiveAppDoc->getObjects();
std::vector<App::DocumentObject*> beforeFeatures = getDocument()->getObjects();
openCommand("Duplicate a PartDesign object");
doCommand(Doc,"FreeCADGui.runCommand('Std_DuplicateSelection')");
// Find the features that were added
std::vector<App::DocumentObject*> afterFeatures = PartDesignGui::ActiveAppDoc->getObjects();
std::vector<App::DocumentObject*> afterFeatures = getDocument()->getObjects();
std::vector<App::DocumentObject*> newFeatures;
std::set_difference(afterFeatures.begin(), afterFeatures.end(), beforeFeatures.begin(), beforeFeatures.end(),
std::back_inserter(newFeatures));
@ -1868,8 +1868,9 @@ void CmdPartDesignBoolean::activated(int iMsg)
openCommand("Create Boolean");
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>("Body");
// Make sure we are working on the selected body
if (body != PartDesignGui::ActivePartObject) {
if (body != activeBody) {
Gui::Selection().clearSelection();
Gui::Selection().addSelection(body->getDocument()->getName(), body->Tip.getValue()->getNameInDocument());
Gui::Command::doCommand(Gui::Command::Gui,"FreeCADGui.runCommand('PartDesign_MoveTip')");

View File

@ -31,6 +31,9 @@
#endif
#include <App/Plane.h>
#include <App/Part.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Mod/Part/App/TopoShape.h>
#include <Mod/Part/App/PartFeature.h>
#include <Mod/PartDesign/App/Feature.h>
@ -48,6 +51,9 @@ using namespace Gui;
bool ReferenceSelection::allow(App::Document* pDoc, App::DocumentObject* pObj, const char* sSubName)
{
PartDesign::Body* ActivePartObject = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>("Body");
App::Part* activePart = Gui::Application::Instance->activeView()->getActiveObject<App::Part*>("Part");
// Don't allow selection in other document
if ((support != NULL) && (pDoc != support->getDocument()))
return false;

View File

@ -435,7 +435,8 @@ void TaskDatumParameters::onCheckFlip(bool on)
void TaskDatumParameters::onButtonRef(const bool pressed, const int idx)
{
// Note: Even if there is no solid, App::Plane and Part::Datum can still be selected
App::DocumentObject* solid = PartDesignGui::ActivePartObject->getPrevSolidFeature();
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>("Body");
App::DocumentObject* solid = activeBody->getPrevSolidFeature();
if (pressed) {
Gui::Selection().clearSelection();
@ -506,12 +507,13 @@ void TaskDatumParameters::onRefName(const QString& text, const int idx)
if (obj == NULL) return;
std::string subElement;
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>("Body");
if (obj->getTypeId().isDerivedFrom(App::Plane::getClassTypeId())) {
// everything is OK (we assume a Part can only have exactly 3 App::Plane objects located at the base of the feature tree)
subElement = "";
} else if (obj->getTypeId().isDerivedFrom(Part::Datum::getClassTypeId())) {
if (!PartDesignGui::ActivePartObject->hasFeature(obj))
if (!activeBody->hasFeature(obj))
return;
subElement = "";
} else {
@ -713,7 +715,8 @@ bool TaskDlgDatumParameters::accept()
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Angle = %f",name.c_str(),parameter->getAngle());
//Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Checked = %i",name.c_str(),parameter->getCheckBox1()?1:0);
App::DocumentObject* solid = PartDesignGui::ActivePartObject->getPrevSolidFeature();
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>("Body");
App::DocumentObject* solid = activeBody->getPrevSolidFeature();
if (solid != NULL) {
QString buf = QString::fromAscii("[");
for (int r = 0; r < 3; r++) {
@ -746,11 +749,12 @@ bool TaskDlgDatumParameters::reject()
Gui::Command::abortCommand();
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>("Body");
// Body housekeeping
if (ActivePartObject != NULL) {
if (activeBody != NULL) {
// Make the new Tip and the previous solid feature visible again
App::DocumentObject* tip = ActivePartObject->Tip.getValue();
App::DocumentObject* prev = ActivePartObject->getPrevSolidFeature();
App::DocumentObject* tip = activeBody->Tip.getValue();
App::DocumentObject* prev = activeBody->getPrevSolidFeature();
if (tip != NULL) {
Gui::Application::Instance->getViewProvider(tip)->show();
if ((tip != prev) && (prev != NULL))

View File

@ -240,10 +240,11 @@ bool TaskDlgDressUpParameters::reject()
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
// Body housekeeping
if (ActivePartObject != NULL) {
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>("Body");
if (activeBody != NULL) {
// Make the new Tip and the previous solid feature visible again
App::DocumentObject* tip = ActivePartObject->Tip.getValue();
App::DocumentObject* prev = ActivePartObject->getPrevSolidFeature();
App::DocumentObject* tip = activeBody->Tip.getValue();
App::DocumentObject* prev = activeBody->getPrevSolidFeature();
if (tip != NULL) {
Gui::Application::Instance->getViewProvider(tip)->show();
if ((tip != prev) && (prev != NULL))

View File

@ -408,21 +408,20 @@ bool TaskDlgGrooveParameters::reject()
Gui::Application::Instance->getViewProvider(pcSketch)->show();
}
// Body housekeeping
if (ActivePartObject != NULL) {
// Make the new Tip and the previous solid feature visible again
App::DocumentObject* tip = ActivePartObject->Tip.getValue();
App::DocumentObject* prev = ActivePartObject->getPrevSolidFeature();
if (tip != NULL) {
Gui::Application::Instance->getViewProvider(tip)->show();
if ((tip != prev) && (prev != NULL))
Gui::Application::Instance->getViewProvider(prev)->show();
}
}
// // Body housekeeping
// if (ActivePartObject != NULL) {
// // Make the new Tip and the previous solid feature visible again
// App::DocumentObject* tip = ActivePartObject->Tip.getValue();
// App::DocumentObject* prev = ActivePartObject->getPrevSolidFeature();
// if (tip != NULL) {
// Gui::Application::Instance->getViewProvider(tip)->show();
// if ((tip != prev) && (prev != NULL))
// Gui::Application::Instance->getViewProvider(prev)->show();
// }
// }
return true;
}
#include "moc_TaskGrooveParameters.cpp"

View File

@ -91,8 +91,9 @@ const QString TaskSketchBasedParameters::onAddSelection(const Gui::SelectionChan
void TaskSketchBasedParameters::onSelectReference(const bool pressed, const bool edge, const bool face, const bool planar) {
// Note: Even if there is no solid, App::Plane and Part::Datum can still be selected
App::DocumentObject* prevSolid = PartDesignGui::ActivePartObject->getPrevSolidFeature(vp->getObject(), false);
App::DocumentObject* curSolid = PartDesignGui::ActivePartObject->getPrevSolidFeature();
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>("Body");
App::DocumentObject* prevSolid = activeBody->getPrevSolidFeature(vp->getObject(), false);
App::DocumentObject* curSolid = activeBody->getPrevSolidFeature();
if (pressed) {
Gui::Document* doc = Gui::Application::Instance->activeDocument();
@ -135,11 +136,12 @@ const QByteArray TaskSketchBasedParameters::onFaceName(const QString& text)
if (obj == NULL)
return QByteArray();
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>("Body");
if (obj->getTypeId().isDerivedFrom(App::Plane::getClassTypeId())) {
// everything is OK (we assume a Part can only have exactly 3 App::Plane objects located at the base of the feature tree)
return QByteArray();
} else if (obj->getTypeId().isDerivedFrom(Part::Datum::getClassTypeId())) {
if (!PartDesignGui::ActivePartObject->hasFeature(obj))
if (!activeBody->hasFeature(obj))
return QByteArray();
return QByteArray();
} else {
@ -243,10 +245,11 @@ bool TaskDlgSketchBasedParameters::reject()
}
// Body housekeeping
if (ActivePartObject != NULL) {
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>("Body");
if (activeBody != NULL) {
// Make the new Tip and the previous solid feature visible again
App::DocumentObject* tip = ActivePartObject->Tip.getValue();
App::DocumentObject* prev = ActivePartObject->getPrevSolidFeature();
App::DocumentObject* tip = activeBody->Tip.getValue();
App::DocumentObject* prev = activeBody->getPrevSolidFeature();
if (tip != NULL) {
Gui::Application::Instance->getViewProvider(tip)->show();
if ((tip != prev) && (prev != NULL))

View File

@ -340,10 +340,11 @@ bool TaskDlgTransformedParameters::reject()
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
// Body housekeeping
if (ActivePartObject != NULL) {
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>("Body");
if (activeBody != NULL) {
// Make the new Tip and the previous solid feature visible again
App::DocumentObject* tip = ActivePartObject->Tip.getValue();
App::DocumentObject* prev = ActivePartObject->getPrevSolidFeature();
App::DocumentObject* tip = activeBody->Tip.getValue();
App::DocumentObject* prev = activeBody->getPrevSolidFeature();
if (tip != NULL) {
Gui::Application::Instance->getViewProvider(tip)->show();
if ((tip != prev) && (prev != NULL))

View File

@ -31,6 +31,7 @@
#include <Mod/PartDesign/App/Body.h>
#include <Mod/Part/App/PropertyTopoShape.h>
#include <Gui/Command.h>
#include <Gui/MDIView.h>
#include <Gui/Control.h>
#include <Gui/Application.h>
#include <Base/Exception.h>
@ -51,10 +52,11 @@ ViewProvider::~ViewProvider()
bool ViewProvider::doubleClicked(void)
{
if (PartDesignGui::ActivePartObject != NULL) {
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>("Body");
if (activeBody != NULL) {
// Drop into insert mode so that the user doesn't see all the geometry that comes later in the tree
// Also, this way the user won't be tempted to use future geometry as external references for the sketch
oldTip = ActivePartObject->Tip.getValue();
oldTip = activeBody->Tip.getValue();
if (oldTip != this->pcObject)
Gui::Command::doCommand(Gui::Command::Gui,"FreeCADGui.runCommand('PartDesign_MoveTip')");
else
@ -83,8 +85,9 @@ void ViewProvider::unsetEdit(int ModNum)
if (ModNum == ViewProvider::Default) {
// when pressing ESC make sure to close the dialog
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>("Body");
Gui::Control().closeDialog();
if ((PartDesignGui::ActivePartObject != NULL) && (oldTip != NULL)) {
if ((activeBody != NULL) && (oldTip != NULL)) {
Gui::Selection().clearSelection();
Gui::Selection().addSelection(oldTip->getDocument()->getName(), oldTip->getNameInDocument());
Gui::Command::doCommand(Gui::Command::Gui,"FreeCADGui.runCommand('PartDesign_MoveTip')");

View File

@ -104,8 +104,9 @@ bool ViewProviderBody::doubleClicked(void)
{
// assure the PartDesign workbench
Gui::Command::assureWorkbench("PartDesignWorkbench");
Gui::Command::addModule(Gui::Command::Gui,"PartDesignGui");
Gui::Command::doCommand(Gui::Command::Gui,"PartDesignGui.setActiveBody(App.activeDocument().%s)",this->getObject()->getNameInDocument());
//Gui::Command::doCommand(Gui::Command::Gui,"PartDesignGui.setActiveBody(App.activeDocument().%s)",this->getObject()->getNameInDocument());
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeView.setActiveBody(App.activeDocument().%s)",this->getObject()->getNameInDocument());
return true;
}
@ -148,40 +149,40 @@ std::vector<App::DocumentObject*> ViewProviderBody::claimChildren3D(void)const
}
void ViewProviderBody::updateTree()
{
if (ActiveGuiDoc == NULL) return;
// Highlight active body and all its features
//Base::Console().Error("ViewProviderBody::updateTree()\n");
PartDesign::Body* body = static_cast<PartDesign::Body*>(getObject());
bool active = body->IsActive.getValue();
//Base::Console().Error("Body is %s\n", active ? "active" : "inactive");
ActiveGuiDoc->signalHighlightObject(*this, Gui::Blue, active);
std::vector<App::DocumentObject*> features = body->Model.getValues();
bool highlight = true;
App::DocumentObject* tip = body->Tip.getValue();
for (std::vector<App::DocumentObject*>::const_iterator f = features.begin(); f != features.end(); f++) {
//Base::Console().Error("Highlighting %s: %s\n", (*f)->getNameInDocument(), highlight ? "true" : "false");
Gui::ViewProviderDocumentObject* vp = dynamic_cast<Gui::ViewProviderDocumentObject*>(Gui::Application::Instance->getViewProvider(*f));
if (vp != NULL)
ActiveGuiDoc->signalHighlightObject(*vp, Gui::LightBlue, active ? highlight : false);
if (highlight && (tip == *f))
highlight = false;
}
}
//void ViewProviderBody::updateTree()
//{
// if (ActiveGuiDoc == NULL) return;
//
// // Highlight active body and all its features
// //Base::Console().Error("ViewProviderBody::updateTree()\n");
// PartDesign::Body* body = static_cast<PartDesign::Body*>(getObject());
// bool active = body->IsActive.getValue();
// //Base::Console().Error("Body is %s\n", active ? "active" : "inactive");
// ActiveGuiDoc->signalHighlightObject(*this, Gui::Blue, active);
// std::vector<App::DocumentObject*> features = body->Model.getValues();
// bool highlight = true;
// App::DocumentObject* tip = body->Tip.getValue();
// for (std::vector<App::DocumentObject*>::const_iterator f = features.begin(); f != features.end(); f++) {
// //Base::Console().Error("Highlighting %s: %s\n", (*f)->getNameInDocument(), highlight ? "true" : "false");
// Gui::ViewProviderDocumentObject* vp = dynamic_cast<Gui::ViewProviderDocumentObject*>(Gui::Application::Instance->getViewProvider(*f));
// if (vp != NULL)
// ActiveGuiDoc->signalHighlightObject(*vp, Gui::LightBlue, active ? highlight : false);
// if (highlight && (tip == *f))
// highlight = false;
// }
//}
void ViewProviderBody::updateData(const App::Property* prop)
{
//Base::Console().Error("ViewProviderBody::updateData for %s\n", getObject()->getNameInDocument());
if (ActiveGuiDoc == NULL)
// PartDesign workbench not active
return PartGui::ViewProviderPart::updateData(prop);
//if (ActiveGuiDoc == NULL)
// // PartDesign workbench not active
// return PartGui::ViewProviderPart::updateData(prop);
if ((prop->getTypeId() == App::PropertyBool::getClassTypeId() && strcmp(prop->getName(),"IsActive") == 0) ||
(prop->getTypeId() == App::PropertyLink::getClassTypeId() && strcmp(prop->getName(),"Tip") == 0) ||
(prop->getTypeId() == App::PropertyLinkList::getClassTypeId() && strcmp(prop->getName(),"Model") == 0))
updateTree();
//if ((/*prop->getTypeId() == App::PropertyBool::getClassTypeId() && strcmp(prop->getName(),"IsActive") == 0) ||*/
// (prop->getTypeId() == App::PropertyLink::getClassTypeId() && strcmp(prop->getName(),"Tip") == 0) ||
// (prop->getTypeId() == App::PropertyLinkList::getClassTypeId() && strcmp(prop->getName(),"Model") == 0))
// // updateTree();
// Update the visual size of datum lines and planes
PartDesign::Body* body = static_cast<PartDesign::Body*>(getObject());

View File

@ -67,7 +67,7 @@ private:
SoGroup *pcBodyTip;
/// Update the children's highlighting
void updateTree();
//void updateTree();
};

View File

@ -60,6 +60,7 @@
#include <Gui/Control.h>
#include <Gui/Command.h>
#include <Gui/Application.h>
#include <Gui/MDIView.h>
#include <Mod/PartDesign/App/Body.h>
using namespace PartDesignGui;
@ -275,10 +276,11 @@ bool ViewProviderDatum::doubleClicked(void)
std::string Msg("Edit ");
Msg += this->pcObject->Label.getValue();
Gui::Command::openCommand(Msg.c_str());
if (PartDesignGui::ActivePartObject != NULL) {
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>("Body");
if (activeBody != NULL) {
// Drop into insert mode so that the user doesn't see all the geometry that comes later in the tree
// Also, this way the user won't be tempted to use future geometry as external references for the sketch
oldTip = ActivePartObject->Tip.getValue();
oldTip = activeBody->Tip.getValue();
if (oldTip != this->pcObject)
Gui::Command::doCommand(Gui::Command::Gui,"FreeCADGui.runCommand('PartDesign_MoveTip')");
else
@ -299,8 +301,9 @@ void ViewProviderDatum::unsetEdit(int ModNum)
if (ModNum == ViewProvider::Default) {
// when pressing ESC make sure to close the dialog
Gui::Control().closeDialog();
PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>("Body");
if ((PartDesignGui::ActivePartObject != NULL) && (oldTip != NULL)) {
if ((activeBody != NULL) && (oldTip != NULL)) {
Gui::Selection().clearSelection();
Gui::Selection().addSelection(oldTip->getDocument()->getName(), oldTip->getNameInDocument());
Gui::Command::doCommand(Gui::Command::Gui,"FreeCADGui.runCommand('PartDesign_MoveTip')");

View File

@ -75,15 +75,17 @@ namespace PartDesignGui {
PartDesign::Body *getBody(void)
{
if(!PartDesignGui::ActivePartObject){
PartDesign::Body * activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>("Body");
if (activeBody){
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No active Body"),
QObject::tr("In order to use PartDesign you need an active Body object in the document. "
"Please make one active or create one. If you have a legacy document "
"Please make one active (double click) or create one. If you have a legacy document "
"with PartDesign objects without Body, use the transfer function in "
"PartDesign to put them into a Body."
));
}
return PartDesignGui::ActivePartObject;
return activeBody;
}
@ -182,14 +184,14 @@ void Workbench::_doMigration(const App::Document* doc)
// Always create at least the first body, even if the document is empty
// This adds both the base planes and the body
Gui::Command::runCommand(Gui::Command::Doc, "FreeCADGui.runCommand('PartDesign_Body')");
PartDesign::Body *activeBody = PartDesignGui::ActivePartObject;
PartDesign::Body *activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>("Body");
// Create one Body for every root and put the appropriate features into it
for (std::vector<App::DocumentObject*>::iterator r = roots.begin(); r != roots.end(); r++) {
if (r != roots.begin()) {
Gui::Command::runCommand(Gui::Command::Doc, "FreeCADGui.runCommand('PartDesign_Body')");
activeBody = PartDesignGui::ActivePartObject;
activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>("Body");
}
std::set<App::DocumentObject*> inList;
@ -352,7 +354,7 @@ void Workbench::_switchToDocument(const App::Document* doc)
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");
activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>("Body");
// body have to be created
assert(activeBody);
@ -363,8 +365,11 @@ void Workbench::_switchToDocument(const App::Document* doc)
}
else
{
activeBody = Gui::Application::Instance->activeDocument()->getActiveView()->pcActiveObjects->getObject<PartDesign::Body*>("Body");
activePart = Gui::Application::Instance->activeDocument()->getActiveView()->pcActiveObjects->getObject<App::Part*>("Part");
activeBody = Gui::Application::Instance->activeView()->getActiveObject<PartDesign::Body*>("Body");
activePart = Gui::Application::Instance->activeView()->getActiveObject<App::Part*>("Part");
// document change not implemented yet
assert(activePart->getDocument() == doc);
//// Find active body
//for (std::vector<App::DocumentObject*>::const_iterator b = bodies.begin(); b != bodies.end(); b++) {
@ -441,10 +446,10 @@ void Workbench::slotFinishRestoreDocument(const App::Document& Doc)
void Workbench::slotDeleteDocument(const App::Document&)
{
ActivePartObject = 0;
ActiveGuiDoc = 0;
ActiveAppDoc = 0;
ActiveVp = 0;
//ActivePartObject = 0;
//ActiveGuiDoc = 0;
//ActiveAppDoc = 0;
//ActiveVp = 0;
}
/*
This does not work for Std_DuplicateSelection:
@ -650,7 +655,7 @@ void Workbench::activated()
));
// make the previously used active Body active again
PartDesignGui::ActivePartObject = NULL;
//PartDesignGui::ActivePartObject = NULL;
_switchToDocument(App::GetApplication().getActiveDocument());
addTaskWatcher(Watcher);

View File

@ -45,10 +45,10 @@ namespace App {
namespace PartDesignGui {
// pointer to the active assembly object
extern PartDesign::Body *ActivePartObject;
extern Gui::Document *ActiveGuiDoc;
extern App::Document *ActiveAppDoc;
extern Gui::ViewProviderDocumentObject *ActiveVp;
//extern PartDesign::Body *ActivePartObject;
//extern Gui::Document *ActiveGuiDoc;
//extern App::Document *ActiveAppDoc;
//extern Gui::ViewProviderDocumentObject *ActiveVp;
// The names of the base planes
extern const char* BaseplaneNames[3];