#ifndef __PY_KERNWIN_ASKFORM__ #define __PY_KERNWIN_ASKFORM__ // // //--------------------------------------------------------------------------- // #define DECLARE_FORM_ACTIONS form_actions_t *fa = (form_actions_t *)p_fa; #ifdef TESTABLE_BUILD idaman void ida_export add_test_feature(const char *name); #endif //--------------------------------------------------------------------------- static bool textctrl_info_t_assign(PyObject *self, PyObject *other) { textctrl_info_t *lhs = textctrl_info_t_get_clink(self); textctrl_info_t *rhs = textctrl_info_t_get_clink(other); if ( lhs == nullptr || rhs == nullptr ) return false; *lhs = *rhs; return true; } //------------------------------------------------------------------------- static bool textctrl_info_t_set_text(PyObject *self, const char *s) { textctrl_info_t *ti = (textctrl_info_t *)pyobj_get_clink(self); if ( ti == nullptr ) return false; ti->text = s; return true; } //------------------------------------------------------------------------- static const char *textctrl_info_t_get_text(PyObject *self) { textctrl_info_t *ti = (textctrl_info_t *)pyobj_get_clink(self); return ti == nullptr ? "" : ti->text.c_str(); } //------------------------------------------------------------------------- static bool textctrl_info_t_set_flags(PyObject *self, unsigned int flags) { textctrl_info_t *ti = (textctrl_info_t *)pyobj_get_clink(self); if ( ti == nullptr ) return false; ti->flags = flags; return true; } //------------------------------------------------------------------------- static unsigned int textctrl_info_t_get_flags(PyObject *self) { textctrl_info_t *ti = (textctrl_info_t *)pyobj_get_clink(self); return ti == nullptr ? 0 : ti->flags; } //------------------------------------------------------------------------- static bool textctrl_info_t_set_tabsize(PyObject *self, unsigned int tabsize) { textctrl_info_t *ti = (textctrl_info_t *)pyobj_get_clink(self); if ( ti == nullptr ) return false; ti->tabsize = tabsize; return true; } //------------------------------------------------------------------------- static unsigned int textctrl_info_t_get_tabsize(PyObject *self) { textctrl_info_t *ti = (textctrl_info_t *)pyobj_get_clink(self); return ti == nullptr ? 0 : ti->tabsize; } //--------------------------------------------------------------------------- static bool formchgcbfa_enable_field(size_t p_fa, int fid, bool enable) { DECLARE_FORM_ACTIONS; return fa->enable_field(fid, enable); } //--------------------------------------------------------------------------- static bool formchgcbfa_show_field(size_t p_fa, int fid, bool show) { DECLARE_FORM_ACTIONS; return fa->show_field(fid, show); } //--------------------------------------------------------------------------- static bool formchgcbfa_move_field( size_t p_fa, int fid, int x, int y, int w, int h) { DECLARE_FORM_ACTIONS; return fa->move_field(fid, x, y, w, h); } //--------------------------------------------------------------------------- static int formchgcbfa_get_focused_field(size_t p_fa) { DECLARE_FORM_ACTIONS; return fa->get_focused_field(); } //--------------------------------------------------------------------------- static bool formchgcbfa_set_focused_field(size_t p_fa, int fid) { DECLARE_FORM_ACTIONS; return fa->set_focused_field(fid); } //--------------------------------------------------------------------------- static void formchgcbfa_refresh_field(size_t p_fa, int fid) { DECLARE_FORM_ACTIONS; return fa->refresh_field(fid); } //--------------------------------------------------------------------------- static void formchgcbfa_close(size_t p_fa, int close_normally) { DECLARE_FORM_ACTIONS; fa->close(close_normally); } //--------------------------------------------------------------------------- static PyObject *formchgcbfa_get_field_value( size_t p_fa, int fid, int ft, size_t sz) { DECLARE_FORM_ACTIONS; PYW_GIL_CHECK_LOCKED_SCOPE(); switch ( ft ) { // dropdown list case 8: // Readonly? Then return the selected index if ( sz == 1 ) { int sel_idx; if ( fa->get_combobox_value(fid, &sel_idx) ) return PyLong_FromLong(sel_idx); } // Not readonly? Then return the qstring else { qstring val; if ( fa->get_combobox_value(fid, &val) ) return PyUnicode_FromString(val.c_str()); } break; // multilinetext - tuple representing textctrl_info_t case 7: { textctrl_info_t ti; if ( fa->get_text_value(fid, &ti) ) return Py_BuildValue("(sII)", ti.text.c_str(), ti.flags, ti.tabsize); break; } // button - uint32 case 4: { uval_t val; if ( fa->get_unsigned_value(fid, &val) ) return PyLong_FromUnsignedLong(val & 0xFFFFFFFF); break; } // ushort case 2: { ushort val; if ( fa->_get_field_value(fid, &val) ) return PyLong_FromUnsignedLong(val); break; } // string label case 1: { char val[MAXSTR]; if ( fa->get_string_value(fid, val, sizeof(val)) ) return PyUnicode_FromString(val); break; } // string input case 3: { qstring val; val.resize(sz + 1); if ( fa->get_string_value(fid, val.begin(), val.size()) ) return PyUnicode_FromString(val.begin()); break; } case 5: { sizevec_t selection; if ( fa->get_chooser_value(fid, &selection) ) { ref_t l(PyW_SizeVecToPyList(selection)); l.incref(); return l.o; } break; } // Numeric control case 6: { union { sel_t sel; sval_t sval; uval_t uval; uint64 ull; } u; switch ( sz ) { case 'S': // sel_t if ( fa->get_segment_value(fid, &u.sel) ) return Py_BuildValue(PY_BV_SEL, bvsel_t(u.sel)); break; // sval_t case 'n': case 'D': case 'O': case 'Y': case 'H': if ( fa->get_signed_value(fid, &u.sval) ) return Py_BuildValue(PY_BV_SVAL, bvsval_t(u.sval)); break; case 'L': // uint64 case 'l': // int64 if ( fa->_get_field_value(fid, &u.ull) ) return Py_BuildValue("K", u.ull); break; case 'N': case 'M': // uval_t if ( fa->get_unsigned_value(fid, &u.uval) ) return Py_BuildValue(PY_BV_UVAL, bvuval_t(u.uval)); break; case '$': // ea_t if ( fa->get_ea_value(fid, &u.uval) ) return Py_BuildValue(PY_BV_UVAL, bvuval_t(u.uval)); break; } break; } } Py_RETURN_NONE; } //--------------------------------------------------------------------------- static bool formchgcbfa_set_field_value( size_t p_fa, int fid, int ft, PyObject *py_val) { DECLARE_FORM_ACTIONS; PYW_GIL_CHECK_LOCKED_SCOPE(); switch ( ft ) { // dropdown list case 8: // Editable dropdown list if ( PyUnicode_Check(py_val) ) { qstring val; PyUnicode_as_qstring(&val, py_val); return fa->set_combobox_value(fid, &val); } // Readonly dropdown list else { int sel_idx = PyLong_AsLong(py_val); return fa->set_combobox_value(fid, &sel_idx); } break; // multilinetext - textctrl_info_t case 7: { textctrl_info_t *ti = (textctrl_info_t *)pyobj_get_clink(py_val); return ti != nullptr && fa->set_text_value(fid, ti); } // button - uint32 case 4: { uval_t val = PyLong_AsUnsignedLong(py_val); return fa->set_unsigned_value(fid, &val); } // ushort case 2: { ushort val = PyLong_AsUnsignedLong(py_val) & 0xffff; return fa->_set_field_value(fid, &val); } // strings case 3: case 1: { qstring val; PyUnicode_as_qstring(&val, py_val); return fa->set_string_value(fid, val.c_str()); } // intvec_t case 5: { sizevec_t selection; if ( !PySequence_Check(py_val) || PyW_PySeqToSizeVec(&selection, py_val) < 0 ) { break; } return fa->set_chooser_value(fid, &selection); } // Numeric case 6: { uint64 num; if ( PyW_GetNumber(py_val, &num) ) return fa->_set_field_value(fid, &num); } } return false; } #undef DECLARE_FORM_ACTIONS static size_t py_get_ask_form() { // Return a pointer to the function. Note that, although // the C implementation of vask_form will do some // Qt/txt widgets generation, the Python's ctypes // implementation through which the call will go will first // unblock other threads. No need to do it ourselves. return (size_t)ask_form; } static size_t py_get_open_form() { // See comments above. return (size_t)open_form; } static void py_register_compiled_form(PyObject *py_form) { #ifdef TESTABLE_BUILD add_test_feature("idapy:askform"); #endif PyW_register_compiled_form(py_form); } static void py_unregister_compiled_form(PyObject *py_form) { PyW_unregister_compiled_form(py_form); } // #endif // __PY_KERNWIN_ASKFORM__