+ extend Python API of selection gate

This commit is contained in:
wmayer 2014-04-03 13:57:57 +02:00
parent 982a555dcb
commit a1e049bc8a
4 changed files with 148 additions and 47 deletions

View File

@ -907,7 +907,6 @@ SelectionSingleton::~SelectionSingleton()
{
}
SelectionSingleton* SelectionSingleton::_pcSingleton = NULL;
SelectionSingleton& SelectionSingleton::instance(void)
@ -923,21 +922,6 @@ void SelectionSingleton::destruct (void)
delete _pcSingleton;
_pcSingleton = 0;
}
/*
void SelectionSingleton::addObject(App::DocumentObject *f)
{
_ObjectSet.insert(f);
}
void SelectionSingleton::removeObject(App::DocumentObject *f)
{
_ObjectSet.erase(f);
}
*/
//**************************************************************************
// Python stuff
@ -977,13 +961,25 @@ PyMethodDef SelectionSingleton::Methods[] = {
{"removeObserver", (PyCFunction) SelectionSingleton::sRemSelObserver, 1,
"removeObserver(Object) -- Uninstall an observer\n"},
{"addSelectionGate", (PyCFunction) SelectionSingleton::sAddSelectionGate, 1,
"addSelectionGate(String) -- activate the selection gate.\n"
"The selection gate will prohibit all selections which do not match\n"
"the given selection filter string. Examples strings are:\n"
"'SELECT Part::Feature SUBELEMENT Edge',\n"
"'SELECT Robot::RobotObject'\n"},
"addSelectionGate(String|Filter|Gate) -- activate the selection gate.\n"
"The selection gate will prohibit all selections which do not match\n"
"the given selection filter string.\n"
" Examples strings are:\n"
"'SELECT Part::Feature SUBELEMENT Edge',\n"
"'SELECT Robot::RobotObject'\n"
"\n"
"You can also set an instance of SelectionFilter:\n"
"filter = Gui.Selection.Filter('SELECT Part::Feature SUBELEMENT Edge')\n"
"Gui.Selection.addSelectionGate(filter)\n"
"\n"
"And the most flexible approach is to write your own selection gate class\n"
"that implements the method 'allow'\n"
"class Gate:\n"
" def allow(self,doc,obj,sub):\n"
" return (sub[0:4] == 'Face')\n"
"Gui.Selection.addSelectionGate(Gate())"},
{"removeSelectionGate", (PyCFunction) SelectionSingleton::sRemoveSelectionGate, 1,
"removeSelectionGate() -- remove the active slection gate\n"},
"removeSelectionGate() -- remove the active selection gate\n"},
{NULL, NULL, 0, NULL} /* Sentinel */
};
@ -1167,14 +1163,33 @@ PyObject *SelectionSingleton::sRemSelObserver(PyObject * /*self*/, PyObject *arg
PyObject *SelectionSingleton::sAddSelectionGate(PyObject * /*self*/, PyObject *args, PyObject * /*kwd*/)
{
char* filter;
if (!PyArg_ParseTuple(args, "s",&filter))
return NULL; // NULL triggers exception
if (PyArg_ParseTuple(args, "s",&filter)) {
PY_TRY {
Selection().addSelectionGate(new SelectionFilterGate(filter));
Py_Return;
} PY_CATCH;
}
PY_TRY {
Selection().addSelectionGate(new SelectionFilterGate(filter));
} PY_CATCH;
PyErr_Clear();
PyObject* filterPy;
if (PyArg_ParseTuple(args, "O!",SelectionFilterPy::type_object(),&filterPy)) {
PY_TRY {
Selection().addSelectionGate(new SelectionFilterGatePython(static_cast<SelectionFilterPy*>(filterPy)));
Py_Return;
} PY_CATCH;
}
Py_Return;
PyErr_Clear();
PyObject* gate;
if (PyArg_ParseTuple(args, "O",&gate)) {
PY_TRY {
Selection().addSelectionGate(new SelectionGatePython(Py::Object(gate, false)));
Py_Return;
} PY_CATCH;
}
PyErr_SetString(PyExc_ValueError, "Argument is neither string nor SelectionFiler nor SelectionGate");
return 0;
}
PyObject *SelectionSingleton::sRemoveSelectionGate(PyObject * /*self*/, PyObject *args, PyObject * /*kwd*/)

View File

@ -33,6 +33,7 @@
#include <App/DocumentObjectPy.h>
#include <App/DocumentObject.h>
#include <Base/Interpreter.h>
#include <CXX/Objects.hxx>
#include "Selection.h"
#include "SelectionFilter.h"
@ -73,6 +74,63 @@ bool SelectionFilterGate::allow(App::Document*pDoc,App::DocumentObject*pObj, con
// ----------------------------------------------------------------------------
SelectionGatePython::SelectionGatePython(const Py::Object& obj)
: gate(obj)
{
}
SelectionGatePython::~SelectionGatePython()
{
}
bool SelectionGatePython::allow(App::Document* doc, App::DocumentObject* obj, const char* sub)
{
Base::PyGILStateLocker lock;
try {
if (this->gate.hasAttr(std::string("allow"))) {
Py::Callable method(this->gate.getAttr(std::string("allow")));
Py::Object pyDoc = Py::asObject(doc->getPyObject());
Py::Object pyObj = Py::asObject(obj->getPyObject());
Py::String pySub;
if (sub)
pySub = std::string(sub);
Py::Tuple args(3);
args.setItem(0, pyDoc);
args.setItem(1, pyObj);
args.setItem(2, pySub);
Py::Boolean ok(method.apply(args));
return (bool)ok;
}
}
catch (Py::Exception&) {
Base::PyException e; // extract the Python error text
e.ReportException();
}
return true;
}
// ----------------------------------------------------------------------------
SelectionFilterGatePython::SelectionFilterGatePython(SelectionFilterPy* obj) : filter(obj)
{
Base::PyGILStateLocker lock;
Py_INCREF(filter);
}
SelectionFilterGatePython::~SelectionFilterGatePython()
{
Base::PyGILStateLocker lock;
Py_DECREF(filter);
}
bool SelectionFilterGatePython::allow(App::Document*, App::DocumentObject* obj, const char* sub)
{
return filter->filter.test(obj, sub);
}
// ----------------------------------------------------------------------------
SelectionFilter::SelectionFilter(const char* filter)
: Ast(0)
{
@ -185,6 +243,7 @@ void SelectionFilterPy::init_type()
add_varargs_method("match",&SelectionFilterPy::match,"match()");
add_varargs_method("result",&SelectionFilterPy::result,"result()");
add_varargs_method("test",&SelectionFilterPy::test,"test()");
add_varargs_method("setFilter",&SelectionFilterPy::setFilter,"setFilter()");
}
PyObject *SelectionFilterPy::PyMake(struct _typeobject *, PyObject *args, PyObject *)
@ -219,7 +278,7 @@ Py::Object SelectionFilterPy::match(const Py::Tuple& args)
Py::Object SelectionFilterPy::test(const Py::Tuple& args)
{
PyObject * pcObj ;
PyObject * pcObj;
char* text=0;
if (!PyArg_ParseTuple(args.ptr(), "O!|s",&(App::DocumentObjectPy::Type),&pcObj,&text))
throw Py::Exception();
@ -238,14 +297,21 @@ Py::Object SelectionFilterPy::result(const Py::Tuple&)
Py::Tuple tuple(it->size());
int index=0;
for (jt = it->begin(); jt != it->end(); ++jt) {
tuple[index++] = Py::asObject(jt->getObject()->getPyObject());
tuple[index++] = Py::asObject(jt->getPyObject());
}
list.append(tuple);
}
return list;
}
Py::Object SelectionFilterPy::setFilter(const Py::Tuple& args)
{
char* text=0;
if (!PyArg_ParseTuple(args.ptr(), "s",&text))
throw Py::Exception();
filter.setFilter(text);
return Py::None();
}
// === Parser & Scanner stuff ===============================================

View File

@ -109,6 +109,23 @@ protected:
SelectionFilter *Filter;
};
/**
* A wrapper around a Python class that implements the SelectionGate interface
* @author Werner Mayer
*/
class SelectionGatePython : public SelectionGate
{
public:
/// Constructor
SelectionGatePython(const Py::Object& obj);
virtual ~SelectionGatePython();
bool allow(App::Document*, App::DocumentObject*, const char*);
private:
Py::Object gate;
};
/**
* Python binding for SelectionFilter class.
* @see SelectionFilter
@ -116,7 +133,7 @@ protected:
*/
class SelectionFilterPy : public Py::PythonExtension<SelectionFilterPy>
{
private:
public:
SelectionFilter filter;
public:
@ -129,11 +146,29 @@ public:
Py::Object match(const Py::Tuple&);
Py::Object result(const Py::Tuple&);
Py::Object test(const Py::Tuple&);
Py::Object setFilter(const Py::Tuple&);
private:
static PyObject *PyMake(struct _typeobject *, PyObject *, PyObject *);
};
/**
* A Python wrapper around SelectionFilterPy to implement the SelectionGate interface
* @author Werner Mayer
*/
class SelectionFilterGatePython : public SelectionGate
{
public:
/// Constructor
SelectionFilterGatePython(SelectionFilterPy* obj);
virtual ~SelectionFilterGatePython();
bool allow(App::Document*, App::DocumentObject*, const char*);
private:
SelectionFilterPy* filter;
};
// === Abstract syntax tree (AST) ===========================================
struct Node_Slice

View File

@ -43,21 +43,6 @@ SelectionObject::SelectionObject()
{
}
//SelectionObject::SelectionObject( const Gui::SelectionSingleton::SelObj &Obj )
//{
// // moving the information over
// // no pointer is copied, cause is to dangerous to keep pointers to
// // the document outside....
// DocName = Obj.DocName;
// FeatName = Obj.FeatName;
// SubName = Obj.SubName;
// TypeName = Obj.TypeName;
// x = Obj.x;
// y = Obj.y;
// z = Obj.z;
//
//}
SelectionObject::~SelectionObject()
{
}