Gui: make AbstractSplitViewPy acting as sub-class of MDIViewPy
This commit is contained in:
@@ -38,6 +38,7 @@
|
||||
#include "Application.h"
|
||||
#include "NavigationStyle.h"
|
||||
#include "View3DPy.h"
|
||||
#include <Base/Interpreter.h>
|
||||
|
||||
|
||||
using namespace Gui;
|
||||
@@ -47,7 +48,7 @@ TYPESYSTEM_SOURCE_ABSTRACT(Gui::AbstractSplitView,Gui::MDIView)
|
||||
AbstractSplitView::AbstractSplitView(Gui::Document* pcDocument, QWidget* parent, Qt::WindowFlags wflags)
|
||||
: MDIView(pcDocument,parent, wflags)
|
||||
{
|
||||
_viewerPy = 0;
|
||||
_viewerPy = nullptr;
|
||||
// important for highlighting
|
||||
setMouseTracking(true);
|
||||
}
|
||||
@@ -59,7 +60,7 @@ AbstractSplitView::~AbstractSplitView()
|
||||
delete *it;
|
||||
}
|
||||
if (_viewerPy) {
|
||||
static_cast<AbstractSplitViewPy*>(_viewerPy)->_view = 0;
|
||||
Base::PyGILStateLocker lock;
|
||||
Py_DECREF(_viewerPy);
|
||||
}
|
||||
}
|
||||
@@ -72,6 +73,12 @@ void AbstractSplitView::deleteSelf()
|
||||
MDIView::deleteSelf();
|
||||
}
|
||||
|
||||
void AbstractSplitView::viewAll()
|
||||
{
|
||||
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
|
||||
(*it)->viewAll();
|
||||
}
|
||||
|
||||
bool AbstractSplitView::containsViewProvider(const ViewProvider* vp) const
|
||||
{
|
||||
for (auto it = _viewer.begin(); it != _viewer.end(); ++it) {
|
||||
@@ -307,8 +314,7 @@ const char *AbstractSplitView::getName(void) const
|
||||
bool AbstractSplitView::onMsg(const char* pMsg, const char**)
|
||||
{
|
||||
if (strcmp("ViewFit",pMsg) == 0 ) {
|
||||
for (std::vector<View3DInventorViewer*>::iterator it = _viewer.begin(); it != _viewer.end(); ++it)
|
||||
(*it)->viewAll();
|
||||
viewAll();
|
||||
return true;
|
||||
}
|
||||
else if (strcmp("ViewBottom",pMsg) == 0) {
|
||||
@@ -439,6 +445,8 @@ void AbstractSplitViewPy::init_type()
|
||||
behaviors().doc("Python binding class for the Inventor viewer class");
|
||||
// you must have overwritten the virtual functions
|
||||
behaviors().supportRepr();
|
||||
behaviors().supportGetattr();
|
||||
behaviors().supportSetattr();
|
||||
behaviors().supportSequenceType();
|
||||
|
||||
add_varargs_method("fitAll",&AbstractSplitViewPy::fitAll,"fitAll()");
|
||||
@@ -452,10 +460,12 @@ void AbstractSplitViewPy::init_type()
|
||||
add_varargs_method("viewIsometric",&AbstractSplitViewPy::viewIsometric,"viewIsometric()");
|
||||
add_varargs_method("getViewer",&AbstractSplitViewPy::getViewer,"getViewer(index)");
|
||||
add_varargs_method("close",&AbstractSplitViewPy::close,"close()");
|
||||
add_varargs_method("cast_to_base", &AbstractSplitViewPy::cast_to_base, "cast_to_base() cast to MDIView class");
|
||||
behaviors().readyType();
|
||||
}
|
||||
|
||||
AbstractSplitViewPy::AbstractSplitViewPy(AbstractSplitView *vi)
|
||||
: _view(vi)
|
||||
: base(vi)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -463,30 +473,61 @@ AbstractSplitViewPy::~AbstractSplitViewPy()
|
||||
{
|
||||
}
|
||||
|
||||
void AbstractSplitViewPy::testExistence()
|
||||
Py::Object AbstractSplitViewPy::cast_to_base(const Py::Tuple&)
|
||||
{
|
||||
if (!(_view && _view->getViewer(0)))
|
||||
throw Py::RuntimeError("Object already deleted");
|
||||
return Gui::MDIViewPy::create(base.getMDIViewPtr());
|
||||
}
|
||||
|
||||
Py::Object AbstractSplitViewPy::repr()
|
||||
{
|
||||
std::string s;
|
||||
std::ostringstream s_out;
|
||||
if (!_view)
|
||||
if (!getSplitViewPtr())
|
||||
throw Py::RuntimeError("Cannot print representation of deleted object");
|
||||
s_out << "AbstractSplitView";
|
||||
return Py::String(s_out.str());
|
||||
}
|
||||
|
||||
// Since with PyCXX it's not possible to make a sub-class of MDIViewPy
|
||||
// a trick is to use MDIViewPy as class member and override getattr() to
|
||||
// join the attributes of both classes. This way all methods of MDIViewPy
|
||||
// appear for SheetViewPy, too.
|
||||
Py::Object AbstractSplitViewPy::getattr(const char * attr)
|
||||
{
|
||||
getSplitViewPtr();
|
||||
std::string name( attr );
|
||||
if (name == "__dict__" || name == "__class__") {
|
||||
Py::Dict dict_self(BaseType::getattr("__dict__"));
|
||||
Py::Dict dict_base(base.getattr("__dict__"));
|
||||
for (auto it : dict_base) {
|
||||
dict_self.setItem(it.first, it.second);
|
||||
}
|
||||
return dict_self;
|
||||
}
|
||||
|
||||
try {
|
||||
return BaseType::getattr(attr);
|
||||
}
|
||||
catch (Py::AttributeError& e) {
|
||||
e.clear();
|
||||
return base.getattr(attr);
|
||||
}
|
||||
}
|
||||
|
||||
AbstractSplitView* AbstractSplitViewPy::getSplitViewPtr()
|
||||
{
|
||||
AbstractSplitView* view = qobject_cast<AbstractSplitView*>(base.getMDIViewPtr());
|
||||
if (!(view && view->getViewer(0)))
|
||||
throw Py::RuntimeError("Object already deleted");
|
||||
return view;
|
||||
}
|
||||
|
||||
Py::Object AbstractSplitViewPy::fitAll(const Py::Tuple& args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args.ptr(), ""))
|
||||
throw Py::Exception();
|
||||
testExistence();
|
||||
|
||||
try {
|
||||
_view->onMsg("ViewFit", 0);
|
||||
getSplitViewPtr()->onMsg("ViewFit", 0);
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
throw Py::RuntimeError(e.what());
|
||||
@@ -504,10 +545,9 @@ Py::Object AbstractSplitViewPy::viewBottom(const Py::Tuple& args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args.ptr(), ""))
|
||||
throw Py::Exception();
|
||||
testExistence();
|
||||
|
||||
try {
|
||||
_view->onMsg("ViewBottom", 0);
|
||||
getSplitViewPtr()->onMsg("ViewBottom", 0);
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
throw Py::RuntimeError(e.what());
|
||||
@@ -526,10 +566,9 @@ Py::Object AbstractSplitViewPy::viewFront(const Py::Tuple& args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args.ptr(), ""))
|
||||
throw Py::Exception();
|
||||
testExistence();
|
||||
|
||||
try {
|
||||
_view->onMsg("ViewFront", 0);
|
||||
getSplitViewPtr()->onMsg("ViewFront", 0);
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
throw Py::RuntimeError(e.what());
|
||||
@@ -548,10 +587,9 @@ Py::Object AbstractSplitViewPy::viewLeft(const Py::Tuple& args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args.ptr(), ""))
|
||||
throw Py::Exception();
|
||||
testExistence();
|
||||
|
||||
try {
|
||||
_view->onMsg("ViewLeft", 0);
|
||||
getSplitViewPtr()->onMsg("ViewLeft", 0);
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
throw Py::RuntimeError(e.what());
|
||||
@@ -570,10 +608,9 @@ Py::Object AbstractSplitViewPy::viewRear(const Py::Tuple& args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args.ptr(), ""))
|
||||
throw Py::Exception();
|
||||
testExistence();
|
||||
|
||||
try {
|
||||
_view->onMsg("ViewRear", 0);
|
||||
getSplitViewPtr()->onMsg("ViewRear", 0);
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
throw Py::RuntimeError(e.what());
|
||||
@@ -592,10 +629,9 @@ Py::Object AbstractSplitViewPy::viewRight(const Py::Tuple& args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args.ptr(), ""))
|
||||
throw Py::Exception();
|
||||
testExistence();
|
||||
|
||||
try {
|
||||
_view->onMsg("ViewRight", 0);
|
||||
getSplitViewPtr()->onMsg("ViewRight", 0);
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
throw Py::RuntimeError(e.what());
|
||||
@@ -614,10 +650,9 @@ Py::Object AbstractSplitViewPy::viewTop(const Py::Tuple& args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args.ptr(), ""))
|
||||
throw Py::Exception();
|
||||
testExistence();
|
||||
|
||||
try {
|
||||
_view->onMsg("ViewTop", 0);
|
||||
getSplitViewPtr()->onMsg("ViewTop", 0);
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
throw Py::RuntimeError(e.what());
|
||||
@@ -636,10 +671,9 @@ Py::Object AbstractSplitViewPy::viewIsometric(const Py::Tuple& args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args.ptr(), ""))
|
||||
throw Py::Exception();
|
||||
testExistence();
|
||||
|
||||
try {
|
||||
_view->onMsg("ViewAxo", 0);
|
||||
getSplitViewPtr()->onMsg("ViewAxo", 0);
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
throw Py::RuntimeError(e.what());
|
||||
@@ -659,10 +693,9 @@ Py::Object AbstractSplitViewPy::getViewer(const Py::Tuple& args)
|
||||
int viewIndex;
|
||||
if (!PyArg_ParseTuple(args.ptr(), "i", &viewIndex))
|
||||
throw Py::Exception();
|
||||
testExistence();
|
||||
|
||||
try {
|
||||
Gui::View3DInventorViewer* view = _view->getViewer(viewIndex);
|
||||
Gui::View3DInventorViewer* view = getSplitViewPtr()->getViewer(viewIndex);
|
||||
if (!view)
|
||||
throw Py::IndexError("Index out of range");
|
||||
return Py::asObject(view->getPyObject());
|
||||
@@ -673,6 +706,10 @@ Py::Object AbstractSplitViewPy::getViewer(const Py::Tuple& args)
|
||||
catch (const std::exception& e) {
|
||||
throw Py::RuntimeError(e.what());
|
||||
}
|
||||
catch (const Py::Exception&) {
|
||||
// re-throw
|
||||
throw;
|
||||
}
|
||||
catch(...) {
|
||||
throw Py::RuntimeError("Unknown C++ exception");
|
||||
}
|
||||
@@ -680,29 +717,28 @@ Py::Object AbstractSplitViewPy::getViewer(const Py::Tuple& args)
|
||||
|
||||
Py::Object AbstractSplitViewPy::sequence_item(ssize_t viewIndex)
|
||||
{
|
||||
testExistence();
|
||||
if (viewIndex >= _view->getSize() || viewIndex < 0)
|
||||
AbstractSplitView* view = getSplitViewPtr();
|
||||
if (viewIndex >= view->getSize() || viewIndex < 0)
|
||||
throw Py::IndexError("Index out of range");
|
||||
PyObject* viewer = _view->getViewer(viewIndex)->getPyObject();
|
||||
PyObject* viewer = view->getViewer(viewIndex)->getPyObject();
|
||||
return Py::asObject(viewer);
|
||||
}
|
||||
|
||||
int AbstractSplitViewPy::sequence_length()
|
||||
{
|
||||
testExistence();
|
||||
return _view->getSize();
|
||||
AbstractSplitView* view = getSplitViewPtr();
|
||||
return view->getSize();
|
||||
}
|
||||
|
||||
Py::Object AbstractSplitViewPy::close(const Py::Tuple& args)
|
||||
{
|
||||
if (!PyArg_ParseTuple(args.ptr(), ""))
|
||||
throw Py::Exception();
|
||||
testExistence();
|
||||
|
||||
_view->close();
|
||||
if (_view->parentWidget())
|
||||
_view->parentWidget()->deleteLater();
|
||||
_view = 0;
|
||||
AbstractSplitView* view = getSplitViewPtr();
|
||||
view->close();
|
||||
if (view->parentWidget())
|
||||
view->parentWidget()->deleteLater();
|
||||
|
||||
return Py::None();
|
||||
}
|
||||
@@ -791,3 +827,5 @@ SplitView3DInventor::SplitView3DInventor(int views, Gui::Document* pcDocument, Q
|
||||
SplitView3DInventor::~SplitView3DInventor()
|
||||
{
|
||||
}
|
||||
|
||||
#include "moc_SplitView3DInventor.cpp"
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#define GUI_SPLITVIEW3DINVENTOR_H
|
||||
|
||||
#include "MDIView.h"
|
||||
#include "MDIViewPy.h"
|
||||
|
||||
#include <Base/Parameter.h>
|
||||
#include <CXX/Extensions.hxx>
|
||||
@@ -39,6 +40,8 @@ class AbstractSplitViewPy;
|
||||
*/
|
||||
class GuiExport AbstractSplitView : public MDIView, public ParameterGrp::ObserverType
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
TYPESYSTEM_HEADER();
|
||||
|
||||
public:
|
||||
@@ -53,6 +56,7 @@ public:
|
||||
virtual void OnChange(ParameterGrp::SubjectType &rCaller,ParameterGrp::MessageType Reason);
|
||||
virtual void onUpdate(void);
|
||||
virtual void deleteSelf();
|
||||
virtual void viewAll();
|
||||
|
||||
View3DInventorViewer *getViewer(unsigned int) const;
|
||||
void setOverrideCursor(const QCursor&);
|
||||
@@ -75,12 +79,16 @@ protected:
|
||||
class AbstractSplitViewPy : public Py::PythonExtension<AbstractSplitViewPy>
|
||||
{
|
||||
public:
|
||||
static void init_type(void); // announce properties and methods
|
||||
using BaseType = Py::PythonExtension<AbstractSplitViewPy>;
|
||||
static void init_type(); // announce properties and methods
|
||||
|
||||
AbstractSplitViewPy(AbstractSplitView *vi);
|
||||
~AbstractSplitViewPy();
|
||||
AbstractSplitView* getSplitViewPtr();
|
||||
|
||||
Py::Object repr();
|
||||
Py::Object getattr(const char *);
|
||||
Py::Object cast_to_base(const Py::Tuple&);
|
||||
|
||||
Py::Object fitAll(const Py::Tuple&);
|
||||
Py::Object viewBottom(const Py::Tuple&);
|
||||
@@ -96,9 +104,7 @@ public:
|
||||
int sequence_length();
|
||||
|
||||
private:
|
||||
AbstractSplitView* _view;
|
||||
friend class AbstractSplitView;
|
||||
void testExistence();
|
||||
Gui::MDIViewPy base;
|
||||
};
|
||||
|
||||
/** The SplitView3DInventor class allows to create a window with two or more Inventor views.
|
||||
|
||||
Reference in New Issue
Block a user