/*
*
* Copyright (C) 2010 MeVis Medical Solutions AG All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* Further, this software is distributed without any warranty that it is
* free of the rightful claim of any third person regarding infringement
* or the like. Any license provided herein, whether implied or
* otherwise, applies only to this software file. Patent licenses, if
* any, provided herein do not apply to combinations of this program with
* other software, or any other product whatsoever.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Contact information: MeVis Medical Solutions AG, Universitaetsallee 29,
* 28359 Bremen, Germany or:
*
* http://www.mevis.de
*
*/
#include "PythonQtProperty.h"
#include "PythonQtSignal.h"
#include "PythonQtConversion.h"
int PythonQtProperty_init(PyObject *object, PyObject *args, PyObject *kw)
{
PythonQtProperty* self = (PythonQtProperty*)object;
self->data = new PythonQtPropertyData();
PythonQtPropertyData* data = self->data;
PyObject* type = 0;
static const char *kwlist[] =
{
"type",
"fget", "fset", "freset", "fdel",
"doc",
"designable", "scriptable", "stored", "user", "constant", "final",
"notify",
0
};
if (!PyArg_ParseTupleAndKeywords(args, kw,
"O|OOOOObbbbbbO!:QtCore.QProperty", (char**)kwlist,
&type,
&(data->fget), &(data->fset), &(data->freset), &(data->fdel),
&(data->doc),
&(data->designable), &(data->scriptable), &(data->stored), &(data->user), &(data->constant), &(data->final),
&PythonQtSignalFunction_Type, &(data->notify)))
{
return 0;
}
data->cppType = PythonQtConv::getCPPTypeName(type);
if (data->cppType.isEmpty()) {
PyErr_Format(PyExc_TypeError, "Unknown Property type: %s", type->ob_type->tp_name);
return -1;
}
if (data->fget == Py_None) {
data->fget = NULL;
}
if (data->fset == Py_None) {
data->fset = NULL;
}
if (data->freset == Py_None) {
data->freset = NULL;
}
if (data->fdel == Py_None) {
data->fdel = NULL;
}
if (data->doc == Py_None) {
data->doc = NULL;
}
if (data->fdel) {
std::cerr << "Property: fdel is not yet supported!" << std::endl;
}
Py_XINCREF(data->fget);
Py_XINCREF(data->fset);
Py_XINCREF(data->freset);
Py_XINCREF(data->fdel);
Py_XINCREF(data->notify);
Py_XINCREF(data->doc);
return 1;
}
void PythonQtProperty_dealloc(PyObject* object)
{
PythonQtProperty* self = (PythonQtProperty*)object;
Py_CLEAR(self->data->fget);
Py_CLEAR(self->data->fset);
Py_CLEAR(self->data->freset);
Py_CLEAR(self->data->fdel);
Py_CLEAR(self->data->notify);
Py_CLEAR(self->data->doc);
delete self->data;
self->data = NULL;
Py_TYPE(object)->tp_free(object);
}
PyObject* PythonQtProperty_setter(PyObject* object, PyObject* func)
{
PythonQtProperty* self = (PythonQtProperty*)object;
if (PyFunction_Check(func)) {
if (self->data->fset) {
Py_DECREF(self->data->fset);
}
Py_INCREF(func);
self->data->fset = func;
// return ourselves, so that setter can be used as a decorator
Py_INCREF(object);
return object;
} else {
PyErr_SetString(PyExc_TypeError, "Property needs a callable as fset.");
return 0;
}
}
PyObject* PythonQtProperty_getter(PyObject* object, PyObject* func)
{
PythonQtProperty* self = (PythonQtProperty*)object;
if (PyFunction_Check(func)) {
if (self->data->fget) {
Py_DECREF(self->data->fget);
}
Py_INCREF(func);
self->data->fget = func;
// return ourselves, so that setter can be used as a decorator
Py_INCREF(object);
return object;
} else {
PyErr_SetString(PyExc_TypeError, "Property needs a callable as fget.");
return 0;
}
}
PyObject* PythonQtProperty_call(PyObject* object, PyObject* args, PyObject* kw)
{
if (PyTuple_Size(args) == 1) {
PyObject *func = PyTuple_GetItem(args, 0);
return PythonQtProperty_getter(object, func);
} else {
PyErr_SetString(PyExc_TypeError, "Property expects a single callable.");
return 0;
}
}
static PyMethodDef PythonQtProperty_methods[] = {
{ "setter", (PyCFunction)PythonQtProperty_setter, METH_O, "Sets the fset function." },
{ "getter", (PyCFunction)PythonQtProperty_getter, METH_O, "Sets the fget function." },
{ "write", (PyCFunction)PythonQtProperty_setter, METH_O, "Sets the fset function." },
{ "read", (PyCFunction)PythonQtProperty_getter, METH_O, "Sets the fget function." },
{ NULL, NULL, 0, NULL } /* Sentinel */
};
static PyObject *PythonQtProperty_get_doc(PythonQtProperty* self, void * /*closure*/)
{
if (self->data->doc) {
Py_INCREF(self->data->doc);
return self->data->doc;
} else {
//TODO: we could get the doc string from the fget method if no doc string is given...
Py_INCREF(Py_None);
return Py_None;
}
}
static PyGetSetDef PythonQtProperty_getsets[] = {
{ const_cast