2011-12-02 16:40:11 +01:00
|
|
|
#ifndef __PY_PLGFORM__
|
|
|
|
#define __PY_PLGFORM__
|
|
|
|
|
|
|
|
//<code(py_plgform)>
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
class plgform_t
|
|
|
|
{
|
|
|
|
private:
|
2013-12-30 02:34:23 +01:00
|
|
|
ref_t py_obj;
|
2011-12-02 16:40:11 +01:00
|
|
|
TForm *form;
|
|
|
|
|
|
|
|
static int idaapi s_callback(void *ud, int notification_code, va_list va)
|
|
|
|
{
|
2013-12-30 02:34:23 +01:00
|
|
|
// This hook gets called from the kernel. Ensure we hold the GIL.
|
|
|
|
PYW_GIL_GET;
|
|
|
|
|
2011-12-02 16:40:11 +01:00
|
|
|
plgform_t *_this = (plgform_t *)ud;
|
|
|
|
if ( notification_code == ui_tform_visible )
|
|
|
|
{
|
|
|
|
TForm *form = va_arg(va, TForm *);
|
|
|
|
if ( form == _this->form )
|
|
|
|
{
|
|
|
|
// Qt: QWidget*
|
|
|
|
// G: HWND
|
|
|
|
// We wrap and pass as a CObject in the hope that a Python UI framework
|
|
|
|
// can unwrap a CObject and get the hwnd/widget back
|
2013-12-30 02:34:23 +01:00
|
|
|
newref_t py_result(
|
|
|
|
PyObject_CallMethod(
|
|
|
|
_this->py_obj.o,
|
|
|
|
(char *)S_ON_CREATE, "O",
|
|
|
|
PyCObject_FromVoidPtr(form, NULL)));
|
2011-12-02 16:40:11 +01:00
|
|
|
PyW_ShowCbErr(S_ON_CREATE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( notification_code == ui_tform_invisible )
|
|
|
|
{
|
|
|
|
TForm *form = va_arg(va, TForm *);
|
|
|
|
if ( form == _this->form )
|
|
|
|
{
|
2013-12-30 02:34:23 +01:00
|
|
|
{
|
|
|
|
newref_t py_result(
|
|
|
|
PyObject_CallMethod(
|
|
|
|
_this->py_obj.o,
|
|
|
|
(char *)S_ON_CLOSE, "O",
|
|
|
|
PyCObject_FromVoidPtr(form, NULL)));
|
|
|
|
PyW_ShowCbErr(S_ON_CLOSE);
|
|
|
|
}
|
2011-12-02 16:40:11 +01:00
|
|
|
_this->unhook();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void unhook()
|
|
|
|
{
|
|
|
|
unhook_from_notification_point(HT_UI, s_callback, this);
|
|
|
|
form = NULL;
|
2012-06-24 22:49:11 +02:00
|
|
|
|
2011-12-02 16:40:11 +01:00
|
|
|
// Call DECREF at last, since it may trigger __del__
|
2013-12-30 02:34:23 +01:00
|
|
|
PYW_GIL_CHECK_LOCKED_SCOPE();
|
|
|
|
py_obj = ref_t();
|
2011-12-02 16:40:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
2013-12-30 02:34:23 +01:00
|
|
|
plgform_t(): form(NULL)
|
2011-12-02 16:40:11 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool show(
|
|
|
|
PyObject *obj,
|
2012-06-24 22:49:11 +02:00
|
|
|
const char *caption,
|
2011-12-02 16:40:11 +01:00
|
|
|
int options)
|
|
|
|
{
|
|
|
|
// Already displayed?
|
|
|
|
TForm *f = find_tform(caption);
|
|
|
|
if ( f != NULL )
|
|
|
|
{
|
|
|
|
// Our form?
|
|
|
|
if ( f == form )
|
|
|
|
{
|
|
|
|
// Switch to it
|
|
|
|
switchto_tform(form, true);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
// Fail to create
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create a form
|
|
|
|
form = create_tform(caption, NULL);
|
|
|
|
if ( form == NULL )
|
|
|
|
return false;
|
2012-06-24 22:49:11 +02:00
|
|
|
|
2011-12-02 16:40:11 +01:00
|
|
|
if ( !hook_to_notification_point(HT_UI, s_callback, this) )
|
|
|
|
{
|
|
|
|
form = NULL;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-12-30 02:34:23 +01:00
|
|
|
py_obj = borref_t(obj);
|
2011-12-02 16:40:11 +01:00
|
|
|
|
|
|
|
if ( is_idaq() )
|
|
|
|
options |= FORM_QWIDGET;
|
|
|
|
|
|
|
|
this->form = form;
|
|
|
|
open_tform(form, options);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void close(int options = 0)
|
|
|
|
{
|
|
|
|
if ( form != NULL )
|
|
|
|
close_tform(form, options);
|
|
|
|
}
|
|
|
|
|
|
|
|
static PyObject *create()
|
|
|
|
{
|
2013-12-30 02:34:23 +01:00
|
|
|
PYW_GIL_CHECK_LOCKED_SCOPE();
|
2011-12-02 16:40:11 +01:00
|
|
|
return PyCObject_FromVoidPtr(new plgform_t(), destroy);
|
|
|
|
}
|
2012-06-24 22:49:11 +02:00
|
|
|
|
2011-12-02 16:40:11 +01:00
|
|
|
static void destroy(void *obj)
|
|
|
|
{
|
|
|
|
delete (plgform_t *)obj;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
//</code(py_plgform)>
|
|
|
|
|
|
|
|
//<inline(py_plgform)>
|
|
|
|
//---------------------------------------------------------------------------
|
2013-12-30 02:34:23 +01:00
|
|
|
#define DECL_PLGFORM PYW_GIL_CHECK_LOCKED_SCOPE(); plgform_t *plgform = (plgform_t *) PyCObject_AsVoidPtr(py_link);
|
2011-12-02 16:40:11 +01:00
|
|
|
static PyObject *plgform_new()
|
|
|
|
{
|
|
|
|
return plgform_t::create();
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool plgform_show(
|
|
|
|
PyObject *py_link,
|
2012-06-24 22:49:11 +02:00
|
|
|
PyObject *py_obj,
|
|
|
|
const char *caption,
|
|
|
|
int options = FORM_TAB|FORM_MENU|FORM_RESTORE)
|
2011-12-02 16:40:11 +01:00
|
|
|
{
|
|
|
|
DECL_PLGFORM;
|
|
|
|
return plgform->show(py_obj, caption, options);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void plgform_close(
|
|
|
|
PyObject *py_link,
|
|
|
|
int options)
|
|
|
|
{
|
|
|
|
DECL_PLGFORM;
|
|
|
|
plgform->close(options);
|
|
|
|
}
|
|
|
|
#undef DECL_PLGFORM
|
|
|
|
//</inline(py_plgform)>
|
|
|
|
|
2013-12-30 02:34:23 +01:00
|
|
|
#endif // __PY_PLGFORM__
|