ok anoter compile fix
This commit is contained in:
@@ -95,7 +95,14 @@ extern "C" {
|
||||
int BPY_menu_do_python( short menutype, int event );
|
||||
int BPY_menu_do_shortcut( short menutype, unsigned short key, unsigned short modifiers );
|
||||
int BPY_menu_invoke( struct BPyMenu *pym, short menutype );
|
||||
void BPY_run_python_script( struct bContext *C, const char *filename );
|
||||
|
||||
/* 2.5 UI Scripts */
|
||||
int BPY_run_python_script( struct bContext *C, const char *filename, struct Text *text ); // 2.5 working
|
||||
int BPY_run_script_space_draw(struct bContext *C, struct SpaceScript * sc); // 2.5 working
|
||||
// int BPY_run_script_space_listener(struct bContext *C, struct SpaceScript * sc, struct ARegion *ar, struct wmNotifier *wmn); // 2.5 working
|
||||
|
||||
|
||||
|
||||
int BPY_run_script(struct Script *script);
|
||||
void BPY_free_compiled_text( struct Text *text );
|
||||
|
||||
|
||||
@@ -121,7 +121,14 @@ def rna2epy(target_path):
|
||||
try: return rna_struct.base.identifier
|
||||
except: return '' # invalid id
|
||||
|
||||
structs = [(base_id(rna_struct), rna_struct.identifier, rna_struct) for rna_struct in bpydoc.structs.values()]
|
||||
#structs = [(base_id(rna_struct), rna_struct.identifier, rna_struct) for rna_struct in bpydoc.structs.values()]
|
||||
|
||||
structs = []
|
||||
for rna_struct in bpydoc.structs.values():
|
||||
structs.append( (base_id(rna_struct), rna_struct.identifier, rna_struct) )
|
||||
|
||||
|
||||
|
||||
structs.sort() # not needed but speeds up sort below, setting items without an inheritance first
|
||||
|
||||
# Arrange so classes are always defined in the correct order
|
||||
@@ -173,12 +180,13 @@ def op2epy(target_path):
|
||||
operators = dir(bpyoperator)
|
||||
operators.remove('add')
|
||||
operators.remove('remove')
|
||||
operators.remove('__dir__')
|
||||
operators.sort()
|
||||
|
||||
|
||||
for op in operators:
|
||||
|
||||
if op.startswith('__'):
|
||||
continue
|
||||
|
||||
# Keyword attributes
|
||||
kw_args = [] # "foo = 1", "bar=0.5", "spam='ENUM'"
|
||||
|
||||
@@ -80,5 +80,8 @@
|
||||
PyObject *Py_CmpToRich(int op, int cmp);
|
||||
#endif
|
||||
|
||||
#ifndef Py_CmpToRich
|
||||
PyObject *Py_CmpToRich(int op, int cmp); /* bpy_util.c */
|
||||
#endif
|
||||
|
||||
#endif /* BPY_COMPAT_H__ */
|
||||
|
||||
@@ -12,7 +12,21 @@
|
||||
|
||||
#include "bpy_rna.h"
|
||||
#include "bpy_operator.h"
|
||||
#include "bpy_ui.h"
|
||||
|
||||
#include "DNA_space_types.h"
|
||||
|
||||
#include "BKE_text.h"
|
||||
#include "DNA_text_types.h"
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
void BPY_free_compiled_text( struct Text *text )
|
||||
{
|
||||
if( text->compiled ) {
|
||||
Py_DECREF( ( PyObject * ) text->compiled );
|
||||
text->compiled = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Description: This function creates a new Python dictionary object.
|
||||
@@ -81,29 +95,182 @@ void BPY_end_python( void )
|
||||
return;
|
||||
}
|
||||
|
||||
void BPY_run_python_script( bContext *C, const char *fn )
|
||||
/* Can run a file or text block */
|
||||
int BPY_run_python_script( bContext *C, const char *fn, struct Text *text )
|
||||
{
|
||||
PyObject *py_dict, *py_result;
|
||||
char pystring[512];
|
||||
PyGILState_STATE gilstate;
|
||||
|
||||
/* TODO - look into a better way to run a file */
|
||||
sprintf(pystring, "exec(open(r'%s').read())", fn);
|
||||
|
||||
if (fn==NULL && text==NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//BPY_start_python();
|
||||
|
||||
gilstate = PyGILState_Ensure();
|
||||
|
||||
py_dict = CreateGlobalDictionary(C);
|
||||
|
||||
if (text) {
|
||||
|
||||
if( !text->compiled ) { /* if it wasn't already compiled, do it now */
|
||||
char *buf = txt_to_buf( text );
|
||||
|
||||
text->compiled =
|
||||
Py_CompileString( buf, text->id.name+2, Py_file_input );
|
||||
|
||||
MEM_freeN( buf );
|
||||
|
||||
if( PyErr_Occurred( ) ) {
|
||||
BPY_free_compiled_text( text );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
py_result = PyEval_EvalCode( text->compiled, py_dict, py_dict );
|
||||
|
||||
} else {
|
||||
char pystring[512];
|
||||
/* TODO - look into a better way to run a file */
|
||||
sprintf(pystring, "exec(open(r'%s').read())", fn);
|
||||
py_result = PyRun_String( pystring, Py_file_input, py_dict, py_dict );
|
||||
}
|
||||
|
||||
if (!py_result) {
|
||||
PyErr_Print();
|
||||
} else {
|
||||
Py_DECREF( py_result );
|
||||
}
|
||||
PyGILState_Release(gilstate);
|
||||
|
||||
//BPY_end_python();
|
||||
return py_result ? 1:0;
|
||||
}
|
||||
|
||||
|
||||
/* TODO - move into bpy_space.c ? */
|
||||
/* GUI interface routines */
|
||||
|
||||
/* Copied from Draw.c */
|
||||
static void exit_pydraw( SpaceScript * sc, short err )
|
||||
{
|
||||
Script *script = NULL;
|
||||
|
||||
if( !sc || !sc->script )
|
||||
return;
|
||||
|
||||
script = sc->script;
|
||||
|
||||
if( err ) {
|
||||
PyErr_Print( );
|
||||
script->flags = 0; /* mark script struct for deletion */
|
||||
SCRIPT_SET_NULL(script);
|
||||
script->scriptname[0] = '\0';
|
||||
script->scriptarg[0] = '\0';
|
||||
// XXX 2.5 error_pyscript();
|
||||
// XXX 2.5 scrarea_queue_redraw( sc->area );
|
||||
}
|
||||
|
||||
#if 0 // XXX 2.5
|
||||
BPy_Set_DrawButtonsList(sc->but_refs);
|
||||
BPy_Free_DrawButtonsList(); /*clear all temp button references*/
|
||||
#endif
|
||||
|
||||
sc->but_refs = NULL;
|
||||
|
||||
Py_XDECREF( ( PyObject * ) script->py_draw );
|
||||
Py_XDECREF( ( PyObject * ) script->py_event );
|
||||
Py_XDECREF( ( PyObject * ) script->py_button );
|
||||
|
||||
script->py_draw = script->py_event = script->py_button = NULL;
|
||||
}
|
||||
|
||||
static int bpy_run_script_init(bContext *C, SpaceScript * sc)
|
||||
{
|
||||
if (sc->script==NULL)
|
||||
return 0;
|
||||
|
||||
if (sc->script->py_draw==NULL && sc->script->scriptname[0] != '\0')
|
||||
BPY_run_python_script(C, sc->script->scriptname, NULL);
|
||||
|
||||
if (sc->script->py_draw==NULL)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int BPY_run_script_space_draw(bContext *C, SpaceScript * sc)
|
||||
{
|
||||
if (bpy_run_script_init(C, sc)) {
|
||||
PyGILState_STATE gilstate = PyGILState_Ensure();
|
||||
PyObject *result = PyObject_CallObject( sc->script->py_draw, NULL );
|
||||
|
||||
if (result==NULL)
|
||||
exit_pydraw(sc, 1);
|
||||
|
||||
PyGILState_Release(gilstate);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// XXX - not used yet, listeners dont get a context
|
||||
int BPY_run_script_space_listener(bContext *C, SpaceScript * sc)
|
||||
{
|
||||
if (bpy_run_script_init(C, sc)) {
|
||||
PyGILState_STATE gilstate = PyGILState_Ensure();
|
||||
|
||||
PyObject *result = PyObject_CallObject( sc->script->py_draw, NULL );
|
||||
|
||||
if (result==NULL)
|
||||
exit_pydraw(sc, 1);
|
||||
|
||||
PyGILState_Release(gilstate);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* called from the the scripts window, assume context is ok */
|
||||
int BPY_run_python_script_space(const char *modulename, const char *func)
|
||||
{
|
||||
PyObject *py_dict, *py_result= NULL;
|
||||
char pystring[512];
|
||||
PyGILState_STATE gilstate;
|
||||
|
||||
/* for calling the module function */
|
||||
PyObject *py_func,
|
||||
|
||||
gilstate = PyGILState_Ensure();
|
||||
|
||||
py_dict = CreateGlobalDictionary(C);
|
||||
|
||||
py_result = PyRun_String( pystring, Py_file_input, py_dict, py_dict );
|
||||
PyObject *module = PyImport_ImportModule(scpt->script.filename);
|
||||
if (module==NULL) {
|
||||
PyErr_SetFormat(PyExc_SystemError, "could not import '%s'", scpt->script.filename);
|
||||
}
|
||||
else {
|
||||
py_func = PyObject_GetAttrString(modulename, func);
|
||||
if (py_func==NULL) {
|
||||
PyErr_SetFormat(PyExc_SystemError, "module has no function '%s.%s'\n", scpt->script.filename, func);
|
||||
}
|
||||
else {
|
||||
if (!PyCallable_Check(py_func)) {
|
||||
PyErr_SetFormat(PyExc_SystemError, "module item is not callable '%s.%s'\n", scpt->script.filename, func);
|
||||
}
|
||||
else {
|
||||
py_result= PyObject_CallObject(py_func, NULL); // XXX will need args eventually
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!py_result)
|
||||
PyErr_Print();
|
||||
else
|
||||
Py_DECREF( py_result );
|
||||
|
||||
PyGILState_Release(gilstate);
|
||||
Py_XDECREF(module);
|
||||
|
||||
//BPY_end_python();
|
||||
|
||||
PyGILState_Release(gilstate);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -115,6 +115,18 @@ static int pyop_func_compare( BPy_OperatorFunc * a, BPy_OperatorFunc * b )
|
||||
return (strcmp(a->name, b->name)==0) ? 0 : -1;
|
||||
}
|
||||
|
||||
/* For some reason python3 needs these :/ */
|
||||
static PyObject *pyop_func_richcmp(BPy_OperatorFunc * a, BPy_OperatorFunc * b, int op)
|
||||
{
|
||||
int cmp_result= -1; /* assume false */
|
||||
if (BPy_OperatorFunc_Check(a) && BPy_OperatorFunc_Check(b)) {
|
||||
cmp_result= pyop_func_compare(a, b);
|
||||
}
|
||||
|
||||
return Py_CmpToRich(op, cmp_result);
|
||||
}
|
||||
|
||||
|
||||
/*----------------------repr--------------------------------------------*/
|
||||
static PyObject *pyop_base_repr( BPy_OperatorBase * self )
|
||||
{
|
||||
@@ -126,6 +138,11 @@ static PyObject *pyop_func_repr( BPy_OperatorFunc * self )
|
||||
return PyUnicode_FromFormat( "[BPy_OperatorFunc \"%s\"]", self->name);
|
||||
}
|
||||
|
||||
static struct PyMethodDef pyop_base_methods[] = {
|
||||
{"add", (PyCFunction)PYOP_wrap_add, METH_VARARGS, ""},
|
||||
{"remove", (PyCFunction)PYOP_wrap_remove, METH_VARARGS, ""},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
//---------------getattr--------------------------------------------
|
||||
static PyObject *pyop_base_getattro( BPy_OperatorBase * self, PyObject *pyname )
|
||||
@@ -133,10 +150,22 @@ static PyObject *pyop_base_getattro( BPy_OperatorBase * self, PyObject *pyname )
|
||||
char *name = _PyUnicode_AsString(pyname);
|
||||
PyObject *ret;
|
||||
wmOperatorType *ot;
|
||||
|
||||
PyMethodDef *meth;
|
||||
|
||||
if ((ot = WM_operatortype_find(name))) {
|
||||
ret= pyop_func_CreatePyObject(self->C, name);
|
||||
}
|
||||
else if (strcmp(name, "__dict__")==0) {
|
||||
ret = PyDict_New();
|
||||
|
||||
for(ot= WM_operatortype_first(); ot; ot= ot->next) {
|
||||
PyDict_SetItemString(ret, ot->idname, Py_None);
|
||||
}
|
||||
|
||||
for(meth=pyop_base_methods; meth->ml_name; meth++) {
|
||||
PyDict_SetItemString(ret, meth->ml_name, Py_None);
|
||||
}
|
||||
}
|
||||
else if ((ret = PyObject_GenericGetAttr((PyObject *)self, pyname))) {
|
||||
/* do nothing, this accounts for methoddef's add and remove */
|
||||
}
|
||||
@@ -144,7 +173,7 @@ static PyObject *pyop_base_getattro( BPy_OperatorBase * self, PyObject *pyname )
|
||||
PyErr_Format( PyExc_AttributeError, "Operator \"%s\" not found", name);
|
||||
ret= NULL;
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -244,37 +273,6 @@ static PyObject * pyop_func_call(BPy_OperatorFunc * self, PyObject *args, PyObje
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
PyObject *pyop_base_dir(PyObject *self);
|
||||
|
||||
static struct PyMethodDef pyop_base_methods[] = {
|
||||
{"add", (PyCFunction)PYOP_wrap_add, METH_VARARGS, ""},
|
||||
{"remove", (PyCFunction)PYOP_wrap_remove, METH_VARARGS, ""},
|
||||
{"__dir__", (PyCFunction)pyop_base_dir, METH_NOARGS, ""},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
PyObject *pyop_base_dir(PyObject *self)
|
||||
{
|
||||
PyObject *ret = PyList_New(0);
|
||||
PyObject *item;
|
||||
wmOperatorType *ot;
|
||||
PyMethodDef *meth;
|
||||
|
||||
for(ot= WM_operatortype_first(); ot; ot= ot->next) {
|
||||
item = PyUnicode_FromString( ot->idname );
|
||||
PyList_Append(ret, item);
|
||||
Py_DECREF(item);
|
||||
}
|
||||
|
||||
for(meth=pyop_base_methods; meth->ml_name; meth++) {
|
||||
item = PyUnicode_FromString( meth->ml_name );
|
||||
PyList_Append(ret, item);
|
||||
Py_DECREF(item);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*-----------------------BPy_OperatorBase method def------------------------------*/
|
||||
PyTypeObject pyop_base_Type = {
|
||||
#if (PY_VERSION_HEX >= 0x02060000)
|
||||
@@ -379,7 +377,7 @@ PyTypeObject pyop_func_Type = {
|
||||
NULL, /* printfunc tp_print; */
|
||||
NULL, /* getattrfunc tp_getattr; */
|
||||
NULL, /* setattrfunc tp_setattr; */
|
||||
( cmpfunc ) pyop_func_compare, /* tp_compare */
|
||||
NULL, /* tp_compare */ /* DEPRECATED in python 3.0! */
|
||||
( reprfunc ) pyop_func_repr, /* tp_repr */
|
||||
|
||||
/* Method suites for standard classes */
|
||||
@@ -412,7 +410,7 @@ PyTypeObject pyop_func_Type = {
|
||||
|
||||
/*** Assigned meaning in release 2.1 ***/
|
||||
/*** rich comparisons ***/
|
||||
NULL, /* richcmpfunc tp_richcompare; */
|
||||
(richcmpfunc)pyop_func_richcmp, /* richcmpfunc tp_richcompare; */
|
||||
|
||||
/*** weak reference enabler ***/
|
||||
0, /* long tp_weaklistoffset; */
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
extern PyTypeObject pyop_base_Type;
|
||||
extern PyTypeObject pyop_func_Type;
|
||||
|
||||
#define BPy_OperatorBase_Check(v) (PyObject_TypeCheck(v, &pyop_base_Type))
|
||||
#define BPy_OperatorFunc_Check(v) (PyObject_TypeCheck(v, &pyop_func_Type))
|
||||
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD /* required python macro */
|
||||
bContext *C;
|
||||
|
||||
@@ -120,8 +120,7 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
|
||||
PyObject *ret;
|
||||
int type = RNA_property_type(ptr, prop);
|
||||
int len = RNA_property_array_length(ptr, prop);
|
||||
/* resolve path */
|
||||
|
||||
|
||||
if (len > 0) {
|
||||
/* resolve the array from a new pytype */
|
||||
return pyrna_prop_CreatePyObject(ptr, prop);
|
||||
@@ -154,7 +153,7 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
|
||||
if (RNA_property_enum_identifier(ptr, prop, val, &identifier)) {
|
||||
ret = PyUnicode_FromString( identifier );
|
||||
} else {
|
||||
PyErr_Format(PyExc_AttributeError, "enum \"%d\" not found", val);
|
||||
PyErr_Format(PyExc_AttributeError, "RNA Error: Current value \"%d\" matches no enum", val);
|
||||
ret = NULL;
|
||||
}
|
||||
|
||||
@@ -176,7 +175,7 @@ PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
|
||||
ret = pyrna_prop_CreatePyObject(ptr, prop);
|
||||
break;
|
||||
default:
|
||||
PyErr_SetString(PyExc_AttributeError, "unknown type (pyrna_prop_to_py)");
|
||||
PyErr_Format(PyExc_AttributeError, "RNA Error: unknown type \"%d\" (pyrna_prop_to_py)", type);
|
||||
ret = NULL;
|
||||
break;
|
||||
}
|
||||
@@ -189,7 +188,6 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, PyObject *value)
|
||||
{
|
||||
int type = RNA_property_type(ptr, prop);
|
||||
int len = RNA_property_array_length(ptr, prop);
|
||||
/* resolve path */
|
||||
|
||||
if (len > 0) {
|
||||
PyObject *item;
|
||||
@@ -374,8 +372,6 @@ static PyObject * pyrna_prop_to_py_index(PointerRNA *ptr, PropertyRNA *prop, int
|
||||
PyObject *ret;
|
||||
int type = RNA_property_type(ptr, prop);
|
||||
|
||||
/* resolve path */
|
||||
|
||||
/* see if we can coorce into a python type - PropertyType */
|
||||
switch (type) {
|
||||
case PROP_BOOLEAN:
|
||||
@@ -401,8 +397,6 @@ static int pyrna_py_to_prop_index(PointerRNA *ptr, PropertyRNA *prop, int index,
|
||||
int ret = 0;
|
||||
int type = RNA_property_type(ptr, prop);
|
||||
|
||||
/* resolve path */
|
||||
|
||||
/* see if we can coorce into a python type - PropertyType */
|
||||
switch (type) {
|
||||
case PROP_BOOLEAN:
|
||||
@@ -555,7 +549,7 @@ static int pyrna_prop_assign_subscript( BPy_PropertyRNA * self, PyObject *key, P
|
||||
if (keynum >= len){
|
||||
PyErr_SetString(PyExc_AttributeError, "index out of range");
|
||||
ret = -1;
|
||||
} else { /* not an array*/
|
||||
} else {
|
||||
ret = pyrna_py_to_prop_index(&self->ptr, self->prop, keynum, value);
|
||||
}
|
||||
}
|
||||
@@ -571,138 +565,6 @@ static PyMappingMethods pyrna_prop_as_mapping = {
|
||||
( objobjargproc ) pyrna_prop_assign_subscript, /* mp_ass_subscript */
|
||||
};
|
||||
|
||||
|
||||
PyObject *pyrna_struct_to_docstring(BPy_StructRNA *self)
|
||||
{
|
||||
PyObject *ret;
|
||||
PropertyRNA *prop;
|
||||
|
||||
DynStr *dynstr;
|
||||
const char *identifier;
|
||||
const char *desc;
|
||||
char *readonly;
|
||||
char *result;
|
||||
int len;
|
||||
int i; /* general iter */
|
||||
|
||||
dynstr= BLI_dynstr_new();
|
||||
BLI_dynstr_appendf(dynstr, "RNA %s: %s\n", RNA_struct_identifier(&self->ptr), RNA_struct_ui_name(&self->ptr));
|
||||
|
||||
/* Add EPI ===='s */
|
||||
i = BLI_dynstr_get_len(dynstr);
|
||||
while (--i)
|
||||
BLI_dynstr_append(dynstr, "=");
|
||||
|
||||
BLI_dynstr_append(dynstr, "\n");
|
||||
/* done */
|
||||
|
||||
{
|
||||
PropertyRNA *iterprop;
|
||||
CollectionPropertyIterator iter;
|
||||
|
||||
iterprop= RNA_struct_iterator_property(&self->ptr);
|
||||
RNA_property_collection_begin(&self->ptr, iterprop, &iter);
|
||||
|
||||
for(; iter.valid; RNA_property_collection_next(&iter)) {
|
||||
prop = iter.ptr.data;
|
||||
identifier = RNA_property_identifier(&iter.ptr, prop);
|
||||
desc = RNA_property_ui_description(&iter.ptr, prop);
|
||||
|
||||
readonly = (RNA_property_editable(&self->ptr, prop)) ? "" : " *readonly*";
|
||||
len = RNA_property_array_length(&iter.ptr, prop);
|
||||
|
||||
switch(RNA_property_type(&iter.ptr, prop)) {
|
||||
case PROP_BOOLEAN:
|
||||
{
|
||||
BLI_dynstr_appendf(dynstr, "@ivar %s: %s%s\n", identifier, desc, readonly);
|
||||
|
||||
if (len==0) BLI_dynstr_appendf(dynstr, "@type %s: bool\n", identifier);
|
||||
else BLI_dynstr_appendf(dynstr, "@type %s: bool[%d]\n", identifier, len);
|
||||
break;
|
||||
}
|
||||
case PROP_INT:
|
||||
{
|
||||
int hardmin, hardmax;
|
||||
RNA_property_int_range(&iter.ptr, prop, &hardmin, &hardmax);
|
||||
|
||||
BLI_dynstr_appendf(dynstr, "@ivar %s: %s in (%d, %d)%s\n", identifier, desc, hardmin, hardmax, readonly);
|
||||
|
||||
if (len==0) BLI_dynstr_appendf(dynstr, "@type %s: int\n", identifier);
|
||||
else BLI_dynstr_appendf(dynstr, "@type %s: int[%d]\n", identifier, len);
|
||||
break;
|
||||
}
|
||||
case PROP_FLOAT:
|
||||
{
|
||||
float hardmin, hardmax;
|
||||
RNA_property_float_range(&iter.ptr, prop, &hardmin, &hardmax);
|
||||
|
||||
BLI_dynstr_appendf(dynstr, "@ivar %s: %s in (", identifier, desc);
|
||||
|
||||
if (hardmin < -MAXFLOAT_DOC)BLI_dynstr_append(dynstr, "-inf, ");
|
||||
else BLI_dynstr_appendf(dynstr, "%.3f, ", hardmin);
|
||||
|
||||
if (hardmax > MAXFLOAT_DOC)BLI_dynstr_append(dynstr, "inf");
|
||||
else BLI_dynstr_appendf(dynstr, "%.3f", hardmax);
|
||||
|
||||
BLI_dynstr_appendf(dynstr, ")%s\n", readonly);
|
||||
|
||||
|
||||
if (len==0) BLI_dynstr_appendf(dynstr, "@type %s: float\n", identifier);
|
||||
else BLI_dynstr_appendf(dynstr, "@type %s: float[%d]\n", identifier, len);
|
||||
break;
|
||||
}
|
||||
case PROP_STRING:
|
||||
{
|
||||
int maxlen = RNA_property_string_maxlength(&iter.ptr, prop);
|
||||
|
||||
BLI_dynstr_appendf(dynstr, "@ivar %s: %s (%d maximum length)%s\n", identifier, desc, maxlen, readonly);
|
||||
BLI_dynstr_appendf(dynstr, "@type %s: string\n", identifier);
|
||||
break;
|
||||
}
|
||||
case PROP_ENUM:
|
||||
{
|
||||
char *enum_str= pyrna_enum_as_string(&iter.ptr, prop);
|
||||
BLI_dynstr_appendf(dynstr, "@ivar %s: %s%s\n", identifier, desc, readonly);
|
||||
BLI_dynstr_appendf(dynstr, "@type %s: enum in [%s]\n", identifier, enum_str);
|
||||
MEM_freeN(enum_str);
|
||||
break;
|
||||
}
|
||||
case PROP_POINTER:
|
||||
{
|
||||
BLI_dynstr_appendf(dynstr, "@ivar %s: %s%s\n", identifier, desc, readonly);
|
||||
|
||||
// TODO - why does this crash sometimes
|
||||
// PointerRNA newptr;
|
||||
// newptr= RNA_property_pointer_get(&iter.ptr, prop);
|
||||
|
||||
// Use this instead, its not that useful
|
||||
BLI_dynstr_appendf(dynstr, "@type %s: PyRNA %s\n", identifier, RNA_struct_identifier(&iter.ptr));
|
||||
break;
|
||||
}
|
||||
case PROP_COLLECTION:
|
||||
BLI_dynstr_appendf(dynstr, "@ivar %s: %s%s\n", identifier, desc, readonly);
|
||||
BLI_dynstr_appendf(dynstr, "@type %s: PyRNA Collection\n", identifier);
|
||||
break;
|
||||
default:
|
||||
BLI_dynstr_appendf(dynstr, "@ivar %s: %s%s\n", identifier, desc, readonly);
|
||||
BLI_dynstr_appendf(dynstr, "@type %s: <unknown>\n", identifier);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RNA_property_collection_end(&iter);
|
||||
}
|
||||
|
||||
result= BLI_dynstr_get_cstring(dynstr);
|
||||
BLI_dynstr_free(dynstr);
|
||||
|
||||
ret = PyUnicode_FromString(result);
|
||||
MEM_freeN(result);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//---------------getattr--------------------------------------------
|
||||
static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname )
|
||||
{
|
||||
@@ -717,18 +579,36 @@ static PyObject *pyrna_struct_getattro( BPy_StructRNA * self, PyObject *pyname )
|
||||
if (ret) return ret;
|
||||
else PyErr_Clear();
|
||||
/* done with subtypes */
|
||||
|
||||
prop = RNA_struct_find_property(&self->ptr, name);
|
||||
|
||||
if ( strcmp( name, "__doc__" ) == 0 ) {
|
||||
ret = pyrna_struct_to_docstring(self);
|
||||
} else {
|
||||
prop = RNA_struct_find_property(&self->ptr, name);
|
||||
|
||||
if (prop==NULL) {
|
||||
PyErr_Format( PyExc_AttributeError, "Attribute \"%s\" not found", name);
|
||||
ret = NULL;
|
||||
} else {
|
||||
ret = pyrna_prop_to_py(&self->ptr, prop);
|
||||
if (prop) {
|
||||
ret = pyrna_prop_to_py(&self->ptr, prop);
|
||||
}
|
||||
else if (strcmp(name, "__dict__")==0) { /* Not quite correct, adding this so dir() gives good feedback */
|
||||
PropertyRNA *iterprop, *nameprop;
|
||||
CollectionPropertyIterator iter;
|
||||
char name[256], *nameptr;
|
||||
|
||||
iterprop= RNA_struct_iterator_property(&self->ptr);
|
||||
RNA_property_collection_begin(&self->ptr, iterprop, &iter);
|
||||
|
||||
ret = PyDict_New();
|
||||
for(; iter.valid; RNA_property_collection_next(&iter)) {
|
||||
if(iter.ptr.data && (nameprop = RNA_struct_name_property(&iter.ptr))) {
|
||||
nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name));
|
||||
PyDict_SetItemString(ret, nameptr, Py_None);
|
||||
|
||||
if ((char *)&name != nameptr)
|
||||
MEM_freeN(nameptr);
|
||||
}
|
||||
}
|
||||
|
||||
RNA_property_collection_end(&iter);
|
||||
}
|
||||
else {
|
||||
PyErr_Format( PyExc_AttributeError, "Attribute \"%s\" not found", name);
|
||||
ret = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -754,32 +634,6 @@ static int pyrna_struct_setattro( BPy_StructRNA * self, PyObject *pyname, PyObje
|
||||
return pyrna_py_to_prop(&self->ptr, prop, value);
|
||||
}
|
||||
|
||||
static PyObject *pyrna_struct_dir( BPy_StructRNA * self )
|
||||
{
|
||||
PyObject *ret = PyList_New(0);
|
||||
PyObject *item;
|
||||
PropertyRNA *prop;
|
||||
PropertyRNA *iterprop;
|
||||
CollectionPropertyIterator iter;
|
||||
|
||||
iterprop= RNA_struct_iterator_property(&self->ptr);
|
||||
RNA_property_collection_begin(&self->ptr, iterprop, &iter);
|
||||
|
||||
|
||||
for(; iter.valid; RNA_property_collection_next(&iter)) {
|
||||
prop = iter.ptr.data;
|
||||
item = PyUnicode_FromString( RNA_property_identifier(&iter.ptr, prop) );
|
||||
PyList_Append(ret, item);
|
||||
Py_DECREF(item);
|
||||
}
|
||||
|
||||
RNA_property_collection_end(&iter);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PyObject *pyrna_prop_keys(BPy_PropertyRNA *self)
|
||||
{
|
||||
PyObject *ret;
|
||||
@@ -796,8 +650,7 @@ PyObject *pyrna_prop_keys(BPy_PropertyRNA *self)
|
||||
|
||||
RNA_property_collection_begin(&self->ptr, self->prop, &iter);
|
||||
for(; iter.valid; RNA_property_collection_next(&iter)) {
|
||||
nameprop= RNA_struct_name_property(&iter.ptr);
|
||||
if(iter.ptr.data && nameprop) {
|
||||
if(iter.ptr.data && (nameprop = RNA_struct_name_property(&iter.ptr))) {
|
||||
nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name));
|
||||
|
||||
/* add to python list */
|
||||
@@ -832,8 +685,7 @@ PyObject *pyrna_prop_items(BPy_PropertyRNA *self)
|
||||
|
||||
RNA_property_collection_begin(&self->ptr, self->prop, &iter);
|
||||
for(; iter.valid; RNA_property_collection_next(&iter)) {
|
||||
nameprop= RNA_struct_name_property(&iter.ptr);
|
||||
if(iter.ptr.data && nameprop) {
|
||||
if(iter.ptr.data && (nameprop = RNA_struct_name_property(&iter.ptr))) {
|
||||
nameptr= RNA_property_string_get_alloc(&iter.ptr, nameprop, name, sizeof(name));
|
||||
|
||||
/* add to python list */
|
||||
@@ -868,15 +720,10 @@ PyObject *pyrna_prop_values(BPy_PropertyRNA *self)
|
||||
|
||||
RNA_property_collection_begin(&self->ptr, self->prop, &iter);
|
||||
for(; iter.valid; RNA_property_collection_next(&iter)) {
|
||||
nameprop= RNA_struct_name_property(&iter.ptr);
|
||||
if(iter.ptr.data && nameprop) {
|
||||
|
||||
/* add to python list */
|
||||
if(iter.ptr.data && (nameprop = RNA_struct_name_property(&iter.ptr))) {
|
||||
item = pyrna_struct_CreatePyObject(&iter.ptr);
|
||||
PyList_Append(ret, item);
|
||||
Py_DECREF(item);
|
||||
/* done */
|
||||
|
||||
}
|
||||
}
|
||||
RNA_property_collection_end(&iter);
|
||||
@@ -918,10 +765,10 @@ PyObject *pyrna_prop_iter(BPy_PropertyRNA *self)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct PyMethodDef pyrna_struct_methods[] = {
|
||||
/*static struct PyMethodDef pyrna_struct_methods[] = {
|
||||
{"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, ""},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
};*/
|
||||
|
||||
static struct PyMethodDef pyrna_prop_methods[] = {
|
||||
{"keys", (PyCFunction)pyrna_prop_keys, METH_NOARGS, ""},
|
||||
@@ -984,7 +831,7 @@ PyTypeObject pyrna_struct_Type = {
|
||||
NULL, /* printfunc tp_print; */
|
||||
NULL, /* getattrfunc tp_getattr; */
|
||||
NULL, /* setattrfunc tp_setattr; */
|
||||
( cmpfunc ) pyrna_struct_compare, /* tp_compare */
|
||||
NULL, /* tp_compare */ /* DEPRECATED in python 3.0! */
|
||||
( reprfunc ) pyrna_struct_repr, /* tp_repr */
|
||||
|
||||
/* Method suites for standard classes */
|
||||
@@ -1028,7 +875,7 @@ PyTypeObject pyrna_struct_Type = {
|
||||
NULL, /* iternextfunc tp_iternext; */
|
||||
|
||||
/*** Attribute descriptor and subclassing stuff ***/
|
||||
pyrna_struct_methods, /* struct PyMethodDef *tp_methods; */
|
||||
NULL, /* struct PyMethodDef *tp_methods; */
|
||||
NULL, /* struct PyMemberDef *tp_members; */
|
||||
NULL, /* struct PyGetSetDef *tp_getset; */
|
||||
NULL, /* struct _typeobject *tp_base; */
|
||||
@@ -1070,7 +917,7 @@ PyTypeObject pyrna_prop_Type = {
|
||||
NULL, /* printfunc tp_print; */
|
||||
NULL, /* getattrfunc tp_getattr; */
|
||||
NULL, /* setattrfunc tp_setattr; */
|
||||
( cmpfunc ) pyrna_prop_compare, /* tp_compare */
|
||||
NULL, /* tp_compare */ /* DEPRECATED in python 3.0! */
|
||||
( reprfunc ) pyrna_prop_repr, /* tp_repr */
|
||||
|
||||
/* Method suites for standard classes */
|
||||
@@ -1142,6 +989,10 @@ PyTypeObject pyrna_prop_Type = {
|
||||
PyObject *pyrna_struct_CreatePyObject( PointerRNA *ptr )
|
||||
{
|
||||
BPy_StructRNA *pyrna;
|
||||
|
||||
if (ptr->data==NULL) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
pyrna = ( BPy_StructRNA * ) PyObject_NEW( BPy_StructRNA, &pyrna_struct_Type );
|
||||
|
||||
@@ -1169,8 +1020,6 @@ PyObject *pyrna_prop_CreatePyObject( PointerRNA *ptr, PropertyRNA *prop )
|
||||
|
||||
pyrna->ptr = *ptr;
|
||||
pyrna->prop = prop;
|
||||
|
||||
/* TODO - iterator? */
|
||||
|
||||
return ( PyObject * ) pyrna;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,11 @@
|
||||
*/
|
||||
|
||||
#include "bpy_ui.h"
|
||||
#include "bpy_util.h"
|
||||
#include "bpy_rna.h" /* for rna buttons */
|
||||
#include "bpy_operator.h" /* for setting button operator properties */
|
||||
#include "bpy_compat.h"
|
||||
#include "WM_types.h" /* for WM_OP_INVOKE_DEFAULT & friends */
|
||||
|
||||
#include "BLI_dynstr.h"
|
||||
|
||||
@@ -32,6 +36,7 @@
|
||||
#include "BKE_context.h"
|
||||
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_space_types.h" /* only for SpaceLink */
|
||||
#include "UI_interface.h"
|
||||
#include "WM_api.h"
|
||||
|
||||
@@ -73,16 +78,48 @@ static PyObject *Method_menuItemO( PyObject * self, PyObject * args )
|
||||
|
||||
static PyObject *Method_defButO( PyObject * self, PyObject * args )
|
||||
{
|
||||
PyObject *py_block;
|
||||
uiBut *but;
|
||||
PyObject *py_block, *py_keywords= NULL;
|
||||
char *opname, *butname, *tip;
|
||||
int exec, xco, yco, width, height;
|
||||
|
||||
if( !PyArg_ParseTuple( args, "O!sisiiiis:defButO", &PyCObject_Type, &py_block, &opname, &exec, &butname, &xco, &yco, &width, &height, &tip))
|
||||
if( !PyArg_ParseTuple( args, "O!sisiiiis|O!:defButO", &PyCObject_Type, &py_block, &opname, &exec, &butname, &xco, &yco, &width, &height, &tip, &PyDict_Type, &py_keywords))
|
||||
return NULL;
|
||||
|
||||
return PyCObject_FromVoidPtr(uiDefButO(PyCObject_AsVoidPtr(py_block), BUT, opname, exec, butname, xco, yco, width, height, tip), NULL );
|
||||
but= uiDefButO(PyCObject_AsVoidPtr(py_block), BUT, opname, exec, butname, xco, yco, width, height, tip);
|
||||
|
||||
/* Optional python doctionary used to set python properties, just like how keyword args are used */
|
||||
if (py_keywords && PyDict_Size(py_keywords)) {
|
||||
if (PYOP_props_from_dict(uiButGetOperatorPtrRNA(but), py_keywords) == -1)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return PyCObject_FromVoidPtr(but, NULL);
|
||||
}
|
||||
|
||||
static PyObject *Method_defAutoButR( PyObject * self, PyObject * args )
|
||||
{
|
||||
PyObject *py_block;
|
||||
BPy_StructRNA *py_rna;
|
||||
char *propname, *butname;
|
||||
int index, xco, yco, width, height;
|
||||
PropertyRNA *prop;
|
||||
|
||||
if( !PyArg_ParseTuple( args, "O!O!sisiiii:defAutoButR", &PyCObject_Type, &py_block, &pyrna_struct_Type, &py_rna, &propname, &index, &butname, &xco, &yco, &width, &height))
|
||||
return NULL;
|
||||
|
||||
// XXX This isnt that nice api, but we dont always have the rna property from python since its converted immediately into a PyObject
|
||||
prop = RNA_struct_find_property(&py_rna->ptr, propname);
|
||||
if (prop==NULL) {
|
||||
PyErr_SetString(PyExc_ValueError, "rna property not found");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return PyCObject_FromVoidPtr( uiDefAutoButR(PyCObject_AsVoidPtr(py_block), &py_rna->ptr, prop, index, butname, xco, yco, width, height), NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static uiBlock *py_internal_uiBlockCreateFunc(struct bContext *C, struct ARegion *ar, void *arg1)
|
||||
{
|
||||
PyObject *ret, *args;
|
||||
@@ -141,6 +178,40 @@ static PyObject *Method_endBlock( PyObject * self, PyObject * args )
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *Method_drawBlock( PyObject * self, PyObject * args )
|
||||
{
|
||||
PyObject *py_context, *py_block;
|
||||
|
||||
if( !PyArg_ParseTuple( args, "O!O!:drawBlock", &PyCObject_Type, &py_context, &PyCObject_Type, &py_block) )
|
||||
return NULL;
|
||||
|
||||
uiDrawBlock(PyCObject_AsVoidPtr(py_context), PyCObject_AsVoidPtr(py_block));
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *Method_drawPanels( PyObject * self, PyObject * args )
|
||||
{
|
||||
PyObject *py_context;
|
||||
int align;
|
||||
|
||||
if( !PyArg_ParseTuple( args, "O!i:drawPanels", &PyCObject_Type, &py_context, &align) )
|
||||
return NULL;
|
||||
|
||||
uiDrawPanels(PyCObject_AsVoidPtr(py_context), align);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *Method_matchPanelsView2d( PyObject * self, PyObject * args )
|
||||
{
|
||||
PyObject *py_ar;
|
||||
|
||||
if( !PyArg_ParseTuple( args, "O!:matchPanelsView2d", &PyCObject_Type, &py_ar) )
|
||||
return NULL;
|
||||
|
||||
uiMatchPanelsView2d(PyCObject_AsVoidPtr(py_ar));
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *Method_popupBoundsBlock( PyObject * self, PyObject * args )
|
||||
{
|
||||
PyObject *py_block;
|
||||
@@ -175,6 +246,18 @@ static PyObject *Method_blockEndAlign( PyObject * self, PyObject * args )
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *Method_blockSetFlag( PyObject * self, PyObject * args )
|
||||
{
|
||||
PyObject *py_block;
|
||||
int flag; /* Note new py api should not use flags, but for this low level UI api its ok. */
|
||||
|
||||
if( !PyArg_ParseTuple( args, "O!i:blockSetFlag", &PyCObject_Type, &py_block, &flag))
|
||||
return NULL;
|
||||
|
||||
uiBlockSetFlag(PyCObject_AsVoidPtr(py_block), flag);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *Method_newPanel( PyObject * self, PyObject * args )
|
||||
{
|
||||
PyObject *py_context, *py_area, *py_block;
|
||||
@@ -187,6 +270,84 @@ static PyObject *Method_newPanel( PyObject * self, PyObject * args )
|
||||
return PyLong_FromSize_t(uiNewPanel(PyCObject_AsVoidPtr(py_context), PyCObject_AsVoidPtr(py_area), PyCObject_AsVoidPtr(py_block), panelname, tabname, ofsx, ofsy, sizex, sizey));
|
||||
}
|
||||
|
||||
/* similar to Draw.c */
|
||||
static PyObject *Method_register( PyObject * self, PyObject * args )
|
||||
{
|
||||
PyObject *py_sl, *py_draw_func;
|
||||
SpaceLink *sl;
|
||||
if( !PyArg_ParseTuple( args, "O!O:register", &PyCObject_Type, &py_sl, &py_draw_func) )
|
||||
return NULL;
|
||||
|
||||
sl = PyCObject_AsVoidPtr(py_sl);
|
||||
|
||||
if(sl->spacetype!=SPACE_SCRIPT) { // XXX todo - add a script space when needed
|
||||
PyErr_SetString(PyExc_ValueError, "can only register in a script space");
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
SpaceScript *scpt= (SpaceScript *)sl;
|
||||
char *filename = NULL;
|
||||
|
||||
if (scpt->script==NULL) {
|
||||
scpt->script = MEM_callocN(sizeof(Script), "ScriptRegister");
|
||||
}
|
||||
|
||||
BPY_getFileAndNum(&filename, NULL);
|
||||
|
||||
if (filename) {
|
||||
strncpy(scpt->script->scriptname, filename, sizeof(scpt->script->scriptname));
|
||||
#if 0
|
||||
char *dot;
|
||||
dot = strchr(scpt->script->scriptname, '.'); /* remove extension */
|
||||
if (dot)
|
||||
*dot= '\0';
|
||||
#endif
|
||||
Py_XINCREF( py_draw_func );
|
||||
scpt->script->py_draw= (void *)py_draw_func;
|
||||
}
|
||||
else {
|
||||
return NULL; /* BPY_getFileAndNum sets the error */
|
||||
}
|
||||
|
||||
if (filename==NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *Method_registerKey( PyObject * self, PyObject * args )
|
||||
{
|
||||
PyObject *py_context;
|
||||
PyObject *py_keywords= NULL;
|
||||
char *keymap_name, *operator_name;
|
||||
int spaceid, regionid;
|
||||
int keyval, evtval, q1, q2;
|
||||
|
||||
wmWindowManager *wm;
|
||||
ListBase *keymap;
|
||||
wmKeymapItem *km;
|
||||
|
||||
if( !PyArg_ParseTuple( args, "O!iissiiii|O!:registerKey", &PyCObject_Type, &py_context, &spaceid, ®ionid, &keymap_name, &operator_name, &keyval, &evtval, &q1, &q2, &PyDict_Type, &py_keywords) )
|
||||
return NULL;
|
||||
|
||||
wm= CTX_wm_manager(PyCObject_AsVoidPtr(py_context));
|
||||
|
||||
/* keymap= WM_keymap_listbase(wm, "Image Generic", SPACE_IMAGE, 0); */
|
||||
keymap= WM_keymap_listbase(wm, keymap_name, spaceid, regionid);
|
||||
|
||||
km= WM_keymap_add_item(keymap, operator_name, keyval, evtval, q1, q2);
|
||||
|
||||
/* Optional python doctionary used to set python properties, just like how keyword args are used */
|
||||
if (py_keywords && PyDict_Size(py_keywords)) {
|
||||
if (PYOP_props_from_dict(km->ptr, py_keywords) == -1)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
/* internal use only */
|
||||
static bContext *get_py_context__internal(void)
|
||||
{
|
||||
@@ -219,6 +380,14 @@ static PyObject *Method_getScreenPtr( PyObject * self )
|
||||
return PyCObject_FromVoidPtr(screen, NULL);
|
||||
}
|
||||
|
||||
static PyObject *Method_getSpacePtr( PyObject * self )
|
||||
{
|
||||
bContext *C= get_py_context__internal();
|
||||
|
||||
SpaceLink *sl= CTX_wm_space_data(C);
|
||||
return PyCObject_FromVoidPtr(sl, NULL);
|
||||
}
|
||||
|
||||
static PyObject *Method_getWindowPtr( PyObject * self )
|
||||
{
|
||||
bContext *C= get_py_context__internal();
|
||||
@@ -232,24 +401,225 @@ static struct PyMethodDef ui_methods[] = {
|
||||
{"pupMenuEnd", (PyCFunction)Method_pupMenuEnd, METH_VARARGS, ""},
|
||||
{"menuItemO", (PyCFunction)Method_menuItemO, METH_VARARGS, ""},
|
||||
{"defButO", (PyCFunction)Method_defButO, METH_VARARGS, ""},
|
||||
{"defAutoButR", (PyCFunction)Method_defAutoButR, METH_VARARGS, ""},
|
||||
{"pupBlock", (PyCFunction)Method_pupBlock, METH_VARARGS, ""},
|
||||
{"beginBlock", (PyCFunction)Method_beginBlock, METH_VARARGS, ""},
|
||||
{"endBlock", (PyCFunction)Method_endBlock, METH_VARARGS, ""},
|
||||
{"drawBlock", (PyCFunction)Method_drawBlock, METH_VARARGS, ""},
|
||||
{"popupBoundsBlock", (PyCFunction)Method_popupBoundsBlock, METH_VARARGS, ""},
|
||||
{"blockBeginAlign", (PyCFunction)Method_blockBeginAlign, METH_VARARGS, ""},
|
||||
{"blockEndAlign", (PyCFunction)Method_blockEndAlign, METH_VARARGS, ""},
|
||||
{"blockSetFlag", (PyCFunction)Method_blockSetFlag, METH_VARARGS, ""},
|
||||
{"newPanel", (PyCFunction)Method_newPanel, METH_VARARGS, ""},
|
||||
{"drawPanels", (PyCFunction)Method_drawPanels, METH_VARARGS, ""},
|
||||
{"matchPanelsView2d", (PyCFunction)Method_matchPanelsView2d, METH_VARARGS, ""},
|
||||
|
||||
{"register", (PyCFunction)Method_register, METH_VARARGS, ""}, // XXX not sure about this - registers current script with the ScriptSpace, like Draw.Register()
|
||||
{"registerKey", (PyCFunction)Method_registerKey, METH_VARARGS, ""}, // XXX could have this in another place too
|
||||
|
||||
|
||||
|
||||
{"getRegonPtr", (PyCFunction)Method_getRegonPtr, METH_NOARGS, ""}, // XXX Nasty, we really need to improve dealing with context!
|
||||
{"getAreaPtr", (PyCFunction)Method_getAreaPtr, METH_NOARGS, ""},
|
||||
{"getScreenPtr", (PyCFunction)Method_getScreenPtr, METH_NOARGS, ""},
|
||||
{"getSpacePtr", (PyCFunction)Method_getSpacePtr, METH_NOARGS, ""},
|
||||
{"getWindowPtr", (PyCFunction)Method_getWindowPtr, METH_NOARGS, ""},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
static struct PyModuleDef ui_module = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"bpyui",
|
||||
"",
|
||||
-1,/* multiple "initialization" just copies the module dict. */
|
||||
ui_methods,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
PyObject *BPY_ui_module( void )
|
||||
{
|
||||
PyObject *submodule;
|
||||
submodule = Py_InitModule3( "bpyui", ui_methods, "" );
|
||||
PyObject *submodule, *mod;
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
submodule= PyModule_Create(&ui_module);
|
||||
#else /* Py2.x */
|
||||
submodule= Py_InitModule3( "bpyui", ui_methods, "" );
|
||||
#endif
|
||||
|
||||
/* uiBlock->flag (controls) */
|
||||
mod = PyModule_New("ui");
|
||||
PyModule_AddObject( submodule, "ui", mod );
|
||||
PyModule_AddObject( mod, "BLOCK_LOOP", PyLong_FromSize_t(UI_BLOCK_LOOP) );
|
||||
PyModule_AddObject( mod, "BLOCK_RET_1", PyLong_FromSize_t(UI_BLOCK_RET_1) );
|
||||
PyModule_AddObject( mod, "BLOCK_NUMSELECT", PyLong_FromSize_t(UI_BLOCK_NUMSELECT) );
|
||||
PyModule_AddObject( mod, "BLOCK_ENTER_OK", PyLong_FromSize_t(UI_BLOCK_ENTER_OK) );
|
||||
PyModule_AddObject( mod, "BLOCK_NOSHADOW", PyLong_FromSize_t(UI_BLOCK_NOSHADOW) );
|
||||
PyModule_AddObject( mod, "BLOCK_NO_HILITE", PyLong_FromSize_t(UI_BLOCK_NO_HILITE) );
|
||||
PyModule_AddObject( mod, "BLOCK_MOVEMOUSE_QUIT", PyLong_FromSize_t(UI_BLOCK_MOVEMOUSE_QUIT) );
|
||||
PyModule_AddObject( mod, "BLOCK_KEEP_OPEN", PyLong_FromSize_t(UI_BLOCK_KEEP_OPEN) );
|
||||
PyModule_AddObject( mod, "BLOCK_POPUP", PyLong_FromSize_t(UI_BLOCK_POPUP) );
|
||||
|
||||
/* for executing operators (XXX move elsewhere) */
|
||||
mod = PyModule_New("wmTypes");
|
||||
PyModule_AddObject( submodule, "wmTypes", mod );
|
||||
PyModule_AddObject( mod, "OP_INVOKE_DEFAULT", PyLong_FromSize_t(WM_OP_INVOKE_DEFAULT) );
|
||||
PyModule_AddObject( mod, "OP_INVOKE_REGION_WIN", PyLong_FromSize_t(WM_OP_INVOKE_REGION_WIN) );
|
||||
PyModule_AddObject( mod, "OP_INVOKE_AREA", PyLong_FromSize_t(WM_OP_INVOKE_AREA) );
|
||||
PyModule_AddObject( mod, "OP_INVOKE_SCREEN", PyLong_FromSize_t(WM_OP_INVOKE_SCREEN) );
|
||||
PyModule_AddObject( mod, "OP_EXEC_DEFAULT", PyLong_FromSize_t(WM_OP_EXEC_DEFAULT) );
|
||||
PyModule_AddObject( mod, "OP_EXEC_REGION_WIN", PyLong_FromSize_t(WM_OP_EXEC_REGION_WIN) );
|
||||
PyModule_AddObject( mod, "OP_EXEC_AREA", PyLong_FromSize_t(WM_OP_EXEC_AREA) );
|
||||
PyModule_AddObject( mod, "OP_EXEC_SCREEN", PyLong_FromSize_t(WM_OP_EXEC_SCREEN) );
|
||||
|
||||
mod = PyModule_New("keyValTypes");
|
||||
PyModule_AddObject( submodule, "keyValTypes", mod );
|
||||
PyModule_AddObject( mod, "ANY", PyLong_FromSize_t(KM_ANY) );
|
||||
PyModule_AddObject( mod, "NOTHING", PyLong_FromSize_t(KM_NOTHING) );
|
||||
PyModule_AddObject( mod, "PRESS", PyLong_FromSize_t(KM_PRESS) );
|
||||
PyModule_AddObject( mod, "RELEASE", PyLong_FromSize_t(KM_RELEASE) );
|
||||
|
||||
mod = PyModule_New("keyModTypes");
|
||||
PyModule_AddObject( submodule, "keyModTypes", mod );
|
||||
PyModule_AddObject( mod, "SHIFT", PyLong_FromSize_t(KM_SHIFT) );
|
||||
PyModule_AddObject( mod, "CTRL", PyLong_FromSize_t(KM_CTRL) );
|
||||
PyModule_AddObject( mod, "ALT", PyLong_FromSize_t(KM_ALT) );
|
||||
PyModule_AddObject( mod, "OSKEY", PyLong_FromSize_t(KM_OSKEY) );
|
||||
|
||||
PyModule_AddObject( mod, "SHIFT2", PyLong_FromSize_t(KM_SHIFT2) );
|
||||
PyModule_AddObject( mod, "CTRL2", PyLong_FromSize_t(KM_CTRL2) );
|
||||
PyModule_AddObject( mod, "ALT2", PyLong_FromSize_t(KM_ALT2) );
|
||||
PyModule_AddObject( mod, "OSKEY2", PyLong_FromSize_t(KM_OSKEY2) );
|
||||
|
||||
mod = PyModule_New("keyTypes");
|
||||
PyModule_AddObject( submodule, "keyTypes", mod );
|
||||
PyModule_AddObject( mod, "A", PyLong_FromSize_t(AKEY) );
|
||||
PyModule_AddObject( mod, "B", PyLong_FromSize_t(BKEY) );
|
||||
PyModule_AddObject( mod, "C", PyLong_FromSize_t(CKEY) );
|
||||
PyModule_AddObject( mod, "D", PyLong_FromSize_t(DKEY) );
|
||||
PyModule_AddObject( mod, "E", PyLong_FromSize_t(EKEY) );
|
||||
PyModule_AddObject( mod, "F", PyLong_FromSize_t(FKEY) );
|
||||
PyModule_AddObject( mod, "G", PyLong_FromSize_t(GKEY) );
|
||||
PyModule_AddObject( mod, "H", PyLong_FromSize_t(HKEY) );
|
||||
PyModule_AddObject( mod, "I", PyLong_FromSize_t(IKEY) );
|
||||
PyModule_AddObject( mod, "J", PyLong_FromSize_t(JKEY) );
|
||||
PyModule_AddObject( mod, "K", PyLong_FromSize_t(KKEY) );
|
||||
PyModule_AddObject( mod, "L", PyLong_FromSize_t(LKEY) );
|
||||
PyModule_AddObject( mod, "M", PyLong_FromSize_t(MKEY) );
|
||||
PyModule_AddObject( mod, "N", PyLong_FromSize_t(NKEY) );
|
||||
PyModule_AddObject( mod, "O", PyLong_FromSize_t(OKEY) );
|
||||
PyModule_AddObject( mod, "P", PyLong_FromSize_t(PKEY) );
|
||||
PyModule_AddObject( mod, "Q", PyLong_FromSize_t(QKEY) );
|
||||
PyModule_AddObject( mod, "R", PyLong_FromSize_t(RKEY) );
|
||||
PyModule_AddObject( mod, "S", PyLong_FromSize_t(SKEY) );
|
||||
PyModule_AddObject( mod, "T", PyLong_FromSize_t(TKEY) );
|
||||
PyModule_AddObject( mod, "U", PyLong_FromSize_t(UKEY) );
|
||||
PyModule_AddObject( mod, "V", PyLong_FromSize_t(VKEY) );
|
||||
PyModule_AddObject( mod, "W", PyLong_FromSize_t(WKEY) );
|
||||
PyModule_AddObject( mod, "X", PyLong_FromSize_t(XKEY) );
|
||||
PyModule_AddObject( mod, "Y", PyLong_FromSize_t(YKEY) );
|
||||
PyModule_AddObject( mod, "Z", PyLong_FromSize_t(ZKEY) );
|
||||
PyModule_AddObject( mod, "ZERO", PyLong_FromSize_t(ZEROKEY) );
|
||||
PyModule_AddObject( mod, "ONE", PyLong_FromSize_t(ONEKEY) );
|
||||
PyModule_AddObject( mod, "TWO", PyLong_FromSize_t(TWOKEY) );
|
||||
PyModule_AddObject( mod, "THREE", PyLong_FromSize_t(THREEKEY) );
|
||||
PyModule_AddObject( mod, "FOUR", PyLong_FromSize_t(FOURKEY) );
|
||||
PyModule_AddObject( mod, "FIVE", PyLong_FromSize_t(FIVEKEY) );
|
||||
PyModule_AddObject( mod, "SIX", PyLong_FromSize_t(SIXKEY) );
|
||||
PyModule_AddObject( mod, "SEVEN", PyLong_FromSize_t(SEVENKEY) );
|
||||
PyModule_AddObject( mod, "EIGHT", PyLong_FromSize_t(EIGHTKEY) );
|
||||
PyModule_AddObject( mod, "NINE", PyLong_FromSize_t(NINEKEY) );
|
||||
PyModule_AddObject( mod, "CAPSLOCK", PyLong_FromSize_t(CAPSLOCKKEY) );
|
||||
PyModule_AddObject( mod, "LEFTCTRL", PyLong_FromSize_t(LEFTCTRLKEY) );
|
||||
PyModule_AddObject( mod, "LEFTALT", PyLong_FromSize_t(LEFTALTKEY) );
|
||||
PyModule_AddObject( mod, "RIGHTALT", PyLong_FromSize_t(RIGHTALTKEY) );
|
||||
PyModule_AddObject( mod, "RIGHTCTRL", PyLong_FromSize_t(RIGHTCTRLKEY) );
|
||||
PyModule_AddObject( mod, "RIGHTSHIFT", PyLong_FromSize_t(RIGHTSHIFTKEY) );
|
||||
PyModule_AddObject( mod, "LEFTSHIFT", PyLong_FromSize_t(LEFTSHIFTKEY) );
|
||||
PyModule_AddObject( mod, "ESC", PyLong_FromSize_t(ESCKEY) );
|
||||
PyModule_AddObject( mod, "TAB", PyLong_FromSize_t(TABKEY) );
|
||||
PyModule_AddObject( mod, "RET", PyLong_FromSize_t(RETKEY) );
|
||||
PyModule_AddObject( mod, "SPACE", PyLong_FromSize_t(SPACEKEY) );
|
||||
PyModule_AddObject( mod, "LINEFEED", PyLong_FromSize_t(LINEFEEDKEY) );
|
||||
PyModule_AddObject( mod, "BACKSPACE", PyLong_FromSize_t(BACKSPACEKEY) );
|
||||
PyModule_AddObject( mod, "DEL", PyLong_FromSize_t(DELKEY) );
|
||||
PyModule_AddObject( mod, "SEMICOLON", PyLong_FromSize_t(SEMICOLONKEY) );
|
||||
PyModule_AddObject( mod, "PERIOD", PyLong_FromSize_t(PERIODKEY) );
|
||||
PyModule_AddObject( mod, "COMMA", PyLong_FromSize_t(COMMAKEY) );
|
||||
PyModule_AddObject( mod, "QUOTE", PyLong_FromSize_t(QUOTEKEY) );
|
||||
PyModule_AddObject( mod, "ACCENTGRAVE", PyLong_FromSize_t(ACCENTGRAVEKEY) );
|
||||
PyModule_AddObject( mod, "MINUS", PyLong_FromSize_t(MINUSKEY) );
|
||||
PyModule_AddObject( mod, "SLASH", PyLong_FromSize_t(SLASHKEY) );
|
||||
PyModule_AddObject( mod, "BACKSLASH", PyLong_FromSize_t(BACKSLASHKEY) );
|
||||
PyModule_AddObject( mod, "EQUAL", PyLong_FromSize_t(EQUALKEY) );
|
||||
PyModule_AddObject( mod, "LEFTBRACKET", PyLong_FromSize_t(LEFTBRACKETKEY) );
|
||||
PyModule_AddObject( mod, "RIGHTBRACKET", PyLong_FromSize_t(RIGHTBRACKETKEY) );
|
||||
PyModule_AddObject( mod, "LEFTARROW", PyLong_FromSize_t(LEFTARROWKEY) );
|
||||
PyModule_AddObject( mod, "DOWNARROW", PyLong_FromSize_t(DOWNARROWKEY) );
|
||||
PyModule_AddObject( mod, "RIGHTARROW", PyLong_FromSize_t(RIGHTARROWKEY) );
|
||||
PyModule_AddObject( mod, "UPARROW", PyLong_FromSize_t(UPARROWKEY) );
|
||||
PyModule_AddObject( mod, "PAD0", PyLong_FromSize_t(PAD0) );
|
||||
PyModule_AddObject( mod, "PAD1", PyLong_FromSize_t(PAD1) );
|
||||
PyModule_AddObject( mod, "PAD2", PyLong_FromSize_t(PAD2) );
|
||||
PyModule_AddObject( mod, "PAD3", PyLong_FromSize_t(PAD3) );
|
||||
PyModule_AddObject( mod, "PAD4", PyLong_FromSize_t(PAD4) );
|
||||
PyModule_AddObject( mod, "PAD5", PyLong_FromSize_t(PAD5) );
|
||||
PyModule_AddObject( mod, "PAD6", PyLong_FromSize_t(PAD6) );
|
||||
PyModule_AddObject( mod, "PAD7", PyLong_FromSize_t(PAD7) );
|
||||
PyModule_AddObject( mod, "PAD8", PyLong_FromSize_t(PAD8) );
|
||||
PyModule_AddObject( mod, "PAD9", PyLong_FromSize_t(PAD9) );
|
||||
PyModule_AddObject( mod, "PADPERIOD", PyLong_FromSize_t(PADPERIOD) );
|
||||
PyModule_AddObject( mod, "PADSLASH", PyLong_FromSize_t(PADSLASHKEY) );
|
||||
PyModule_AddObject( mod, "PADASTER", PyLong_FromSize_t(PADASTERKEY) );
|
||||
PyModule_AddObject( mod, "PADMINUS", PyLong_FromSize_t(PADMINUS) );
|
||||
PyModule_AddObject( mod, "PADENTER", PyLong_FromSize_t(PADENTER) );
|
||||
PyModule_AddObject( mod, "PADPLUS", PyLong_FromSize_t(PADPLUSKEY) );
|
||||
PyModule_AddObject( mod, "F1", PyLong_FromSize_t(F1KEY) );
|
||||
PyModule_AddObject( mod, "F2", PyLong_FromSize_t(F2KEY) );
|
||||
PyModule_AddObject( mod, "F3", PyLong_FromSize_t(F3KEY) );
|
||||
PyModule_AddObject( mod, "F4", PyLong_FromSize_t(F4KEY) );
|
||||
PyModule_AddObject( mod, "F5", PyLong_FromSize_t(F5KEY) );
|
||||
PyModule_AddObject( mod, "F6", PyLong_FromSize_t(F6KEY) );
|
||||
PyModule_AddObject( mod, "F7", PyLong_FromSize_t(F7KEY) );
|
||||
PyModule_AddObject( mod, "F8", PyLong_FromSize_t(F8KEY) );
|
||||
PyModule_AddObject( mod, "F9", PyLong_FromSize_t(F9KEY) );
|
||||
PyModule_AddObject( mod, "F10", PyLong_FromSize_t(F10KEY) );
|
||||
PyModule_AddObject( mod, "F11", PyLong_FromSize_t(F11KEY) );
|
||||
PyModule_AddObject( mod, "F12", PyLong_FromSize_t(F12KEY) );
|
||||
PyModule_AddObject( mod, "PAUSE", PyLong_FromSize_t(PAUSEKEY) );
|
||||
PyModule_AddObject( mod, "INSERT", PyLong_FromSize_t(INSERTKEY) );
|
||||
PyModule_AddObject( mod, "HOME", PyLong_FromSize_t(HOMEKEY) );
|
||||
PyModule_AddObject( mod, "PAGEUP", PyLong_FromSize_t(PAGEUPKEY) );
|
||||
PyModule_AddObject( mod, "PAGEDOWN", PyLong_FromSize_t(PAGEDOWNKEY) );
|
||||
PyModule_AddObject( mod, "END", PyLong_FromSize_t(ENDKEY) );
|
||||
PyModule_AddObject( mod, "UNKNOWN", PyLong_FromSize_t(UNKNOWNKEY) );
|
||||
PyModule_AddObject( mod, "COMMAND", PyLong_FromSize_t(COMMANDKEY) );
|
||||
PyModule_AddObject( mod, "GRLESS", PyLong_FromSize_t(GRLESSKEY) );
|
||||
|
||||
mod = PyModule_New("spaceTypes");
|
||||
PyModule_AddObject( submodule, "spaceTypes", mod );
|
||||
PyModule_AddObject( mod, "EMPTY", PyLong_FromSize_t(SPACE_EMPTY) );
|
||||
PyModule_AddObject( mod, "VIEW3D", PyLong_FromSize_t(SPACE_VIEW3D) );
|
||||
PyModule_AddObject( mod, "IPO", PyLong_FromSize_t(SPACE_IPO) );
|
||||
PyModule_AddObject( mod, "OOPS", PyLong_FromSize_t(SPACE_OOPS) );
|
||||
PyModule_AddObject( mod, "BUTS", PyLong_FromSize_t(SPACE_BUTS) );
|
||||
PyModule_AddObject( mod, "FILE", PyLong_FromSize_t(SPACE_FILE) );
|
||||
PyModule_AddObject( mod, "IMAGE", PyLong_FromSize_t(SPACE_IMAGE) );
|
||||
PyModule_AddObject( mod, "INFO", PyLong_FromSize_t(SPACE_INFO) );
|
||||
PyModule_AddObject( mod, "SEQ", PyLong_FromSize_t(SPACE_SEQ) );
|
||||
PyModule_AddObject( mod, "TEXT", PyLong_FromSize_t(SPACE_TEXT) );
|
||||
PyModule_AddObject( mod, "IMASEL", PyLong_FromSize_t(SPACE_IMASEL) );
|
||||
PyModule_AddObject( mod, "SOUND", PyLong_FromSize_t(SPACE_SOUND) );
|
||||
PyModule_AddObject( mod, "ACTION", PyLong_FromSize_t(SPACE_ACTION) );
|
||||
PyModule_AddObject( mod, "NLA", PyLong_FromSize_t(SPACE_NLA) );
|
||||
PyModule_AddObject( mod, "SCRIPT", PyLong_FromSize_t(SPACE_SCRIPT) );
|
||||
PyModule_AddObject( mod, "TIME", PyLong_FromSize_t(SPACE_TIME) );
|
||||
PyModule_AddObject( mod, "NODE", PyLong_FromSize_t(SPACE_NODE) );
|
||||
|
||||
|
||||
|
||||
|
||||
return submodule;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ int BPY_flag_from_seq(BPY_flag_def *flagdef, PyObject *seq, int *flag)
|
||||
|
||||
|
||||
/* Copied from pythons 3's Object.c */
|
||||
#if PY_VERSION_HEX < 0x03000000
|
||||
#ifndef Py_CmpToRich
|
||||
PyObject *
|
||||
Py_CmpToRich(int op, int cmp)
|
||||
{
|
||||
@@ -161,3 +161,53 @@ void PyObSpit(char *name, PyObject *var) {
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
void PyLineSpit(void) {
|
||||
char filename[512];
|
||||
int lineno;
|
||||
|
||||
PyErr_Clear();
|
||||
BPY_getFileAndNum(&filename, &lineno);
|
||||
|
||||
fprintf(stderr, "%s:%d\n", filename, lineno);
|
||||
}
|
||||
|
||||
void BPY_getFileAndNum(char **filename, int *lineno)
|
||||
{
|
||||
PyObject *getframe, *frame;
|
||||
PyObject *f_lineno, *f_code, *co_filename;
|
||||
|
||||
if (filename) *filename= NULL;
|
||||
if (lineno) *lineno = -1;
|
||||
|
||||
getframe = PySys_GetObject("_getframe"); // borrowed
|
||||
if (getframe) {
|
||||
frame = PyObject_CallObject(getframe, NULL);
|
||||
if (frame) {
|
||||
f_lineno= PyObject_GetAttrString(frame, "f_lineno");
|
||||
f_code= PyObject_GetAttrString(frame, "f_code");
|
||||
if (f_lineno && f_code) {
|
||||
co_filename= PyObject_GetAttrString(f_code, "co_filename");
|
||||
if (co_filename) {
|
||||
|
||||
if (filename) *filename = _PyUnicode_AsString(co_filename);
|
||||
if (lineno) *lineno = (int)PyLong_AsSsize_t(f_lineno);
|
||||
|
||||
Py_DECREF(f_lineno);
|
||||
Py_DECREF(f_code);
|
||||
Py_DECREF(co_filename);
|
||||
Py_DECREF(frame);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Py_XDECREF(co_filename);
|
||||
Py_XDECREF(f_lineno);
|
||||
Py_XDECREF(f_code);
|
||||
Py_XDECREF(frame);
|
||||
|
||||
PyErr_SetString(PyExc_SystemError, "Could not access sys._getframe().f_code.co_filename");
|
||||
}
|
||||
|
||||
@@ -35,4 +35,5 @@ PyObject *BPY_flag_to_list(BPY_flag_def *flagdef, int flag);
|
||||
int BPY_flag_from_seq(BPY_flag_def *flagdef, PyObject *seq, int *flag);
|
||||
|
||||
void PyObSpit(char *name, PyObject *var);
|
||||
|
||||
void PyLineSpit(void);
|
||||
void BPY_getFileAndNum(char **filename, int *lineno);
|
||||
|
||||
@@ -36,7 +36,7 @@ void BPY_do_pyscript() {}
|
||||
void BPY_pydriver_eval() {}
|
||||
void BPY_pydriver_get_objects() {}
|
||||
void BPY_clear_script() {}
|
||||
void BPY_free_compiled_text() {}
|
||||
//void BPY_free_compiled_text() {}
|
||||
void BPY_pyconstraint_eval() {}
|
||||
void BPY_pyconstraint_target() {}
|
||||
int BPY_is_pyconstraint() {return 0;}
|
||||
|
||||
Reference in New Issue
Block a user