#ifndef __PY_PLGFORM__ #define __PY_PLGFORM__ // //--------------------------------------------------------------------------- class plgform_t { private: PyObject *py_obj; TForm *form; static int idaapi s_callback(void *ud, int notification_code, va_list va) { 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 PYW_GIL_ENSURE; PyObject *py_result = PyObject_CallMethod( _this->py_obj, (char *)S_ON_CREATE, "O", PyCObject_FromVoidPtr(form, NULL)); PYW_GIL_RELEASE; PyW_ShowCbErr(S_ON_CREATE); Py_XDECREF(py_result); } } else if ( notification_code == ui_tform_invisible ) { TForm *form = va_arg(va, TForm *); if ( form == _this->form ) { PYW_GIL_ENSURE; PyObject *py_result = PyObject_CallMethod( _this->py_obj, (char *)S_ON_CLOSE, "O", PyCObject_FromVoidPtr(form, NULL)); PYW_GIL_RELEASE; PyW_ShowCbErr(S_ON_CLOSE); Py_XDECREF(py_result); _this->unhook(); } } return 0; } void unhook() { unhook_from_notification_point(HT_UI, s_callback, this); form = NULL; // Call DECREF at last, since it may trigger __del__ Py_XDECREF(py_obj); } public: plgform_t(): py_obj(NULL), form(NULL) { } bool show( PyObject *obj, const char *caption, 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; if ( !hook_to_notification_point(HT_UI, s_callback, this) ) { form = NULL; return false; } py_obj = obj; Py_INCREF(obj); 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() { return PyCObject_FromVoidPtr(new plgform_t(), destroy); } static void destroy(void *obj) { delete (plgform_t *)obj; } }; // // //--------------------------------------------------------------------------- #define DECL_PLGFORM plgform_t *plgform = (plgform_t *) PyCObject_AsVoidPtr(py_link); static PyObject *plgform_new() { return plgform_t::create(); } static bool plgform_show( PyObject *py_link, PyObject *py_obj, const char *caption, int options = FORM_TAB|FORM_MENU|FORM_RESTORE) { 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 // #endif // __PY_PLGFORM__