added Choose2() support

This commit is contained in:
elias.bachaalany 2009-09-24 14:20:29 +00:00
parent 56f6dc02be
commit d278419064
5 changed files with 869 additions and 5 deletions

View File

@ -72,6 +72,8 @@ BINDIST_MANIFEST = [
"examples/structure.py",
"examples/ex_gdl_qflow_chart.py",
"examples/ex_strings.py",
"examples/ex_func_chooser.py",
"examples/ex_choose2.py",
"examples/ex_debug_names.py"
]

84
examples/ex_choose2.py Normal file
View File

@ -0,0 +1,84 @@
import idaapi
from idaapi import Choose2
class MyChoose2(Choose2):
def __init__(self, title, nb = 5):
Choose2.__init__(self, title, [ ["Address", 10], ["Name", 30] ])
self.n = 0
self.items = [ self.make_item() for x in xrange(0, nb+1) ]
self.icon = 5
self.selcount = 0
self.popup_names = ["Inzert", "Del leet", "Ehdeet", "Ree frech"]
print "created", str(self)
def OnClose(self):
print "closed", str(self)
def OnEditLine(self, n):
self.items[n][1] = self.items[n][1] + "*"
print "editing", str(n)
def OnInsertLine(self):
self.items.append(self.make_item())
print "insert line"
def OnSelectLine(self, n):
self.selcount += 1
Warning("[%02d] selectline '%s'" % (self.selcount, n))
def OnGetLine(self, n):
print "getline", str(n)
return self.items[n]
def OnGetSize(self):
print "getsize"
return len(self.items)
def OnDeleteLine(self, n):
print "del ",str(n)
del self.items[n]
return n
def OnRefresh(self, n):
print "refresh", n
return n
def OnCommand(self, n, cmd_id):
if cmd_id == self.cmd_a:
print "command A selected @", n
elif cmd_id == self.cmd_b:
print "command B selected @", n
else:
print "Unknown command:", cmd_id, "@", n
return 1
def OnGetIcon(self, n):
r = self.items[n]
t = self.icon + r[1].count("*")
print "geticon", n, t
return t
def show(self):
t = self.Show()
if t < 0:
return False
self.cmd_a = self.AddCommand("command A")
self.cmd_b = self.AddCommand("command B")
return True
def make_item(self):
r = [str(self.n), "func_%04d" % self.n]
self.n += 1
return r
def OnGetLineAttr(self, n):
print "getlineattr", n
if n == 1:
return [0xFF0000, 0]
for i in xrange(1, 5+1):
c = MyChoose2("choose2 - sample %d" % i, i*2)
r = c.show()
print r

View File

@ -0,0 +1,38 @@
import idaapi
import idautils
import idc
class MyChoose2(Choose2):
def __init__(self, title):
Choose2.__init__(self, title, [ ["Address", 10 | Choose2.CHCOL_HEX], ["Name", 30 | Choose2.CHCOL_PLAIN] ])
self.n = 0
self.icon = 41
self.PopulateItems()
def PopulateItems(self):
self.items = [ [hex(x), GetFunctionName(x), x] for x in idautils.Functions() ]
def OnClose(self):
print "closed ", self.title
def OnSelectLine(self, n):
idc.Jump(self.items[n][2])
def OnGetLine(self, n):
return self.items[n]
def OnGetSize(self):
return len(self.items)
def OnDeleteLine(self, n):
ea = self.items[n][2]
idc.DelFunction(ea)
return n
def OnRefresh(self, n):
self.PopulateItems()
return n
c = MyChoose2("My functions list")
c.Show()

View File

@ -2,7 +2,7 @@
#------------------------------------------------------------
# IDAPython - Python plugin for Interactive Disassembler Pro
#
# Copyright (c) 2004-2009 Gergely Erdelyi <dyce@d-dome.net>
# Copyright (c) 2004-2009 Gergely Erdelyi <dyce@d-dome.net>
#
# All rights reserved.
#
@ -37,7 +37,7 @@ def addscriptpath(script):
if pathitem == scriptpath:
pathfound = 1
break
if pathfound == 0:
sys.path.append(scriptpath)
@ -124,7 +124,7 @@ print_banner()
#-----------------------------------------------------------
# Import all the required modules
#-----------------------------------------------------------
from idaapi import Choose, get_user_idadir, cvar
from idaapi import Choose, get_user_idadir, cvar, Choose2
from idc import *
from idautils import *
import idaapi
@ -147,7 +147,7 @@ class ScriptBox(Choose):
return None
n = self.choose()
if n > 0:
return self.list[n-1]
else:
@ -166,7 +166,7 @@ scriptbox = ScriptBox()
# watchdog.activate(10) # Use 10-second timeout
#
# Note: The watchdog only works for code running inside
# functions, not in global/module namespace.
# functions, not in global/module namespace.
#-------------------------------------------------------------
class WatchDog():
"""

View File

@ -141,7 +141,635 @@ uint32 choose_choose(PyObject *self,
int x1,int y1,
int width);
PyObject *choose2_find(const char *title);
int choose2_add_command(PyObject *self, const char *caption, int flags=0, int menu_index=-1, int icon=-1);
void choose2_refresh(PyObject *self);
void choose2_close(PyObject *self);
int choose2_show(PyObject *self);
void choose2_activate(PyObject *self);
%{
//-------------------------------------------------------------------------
// Chooser2 wrapper class
//-------------------------------------------------------------------------
#include <map>
//------------------------------------------------------------------------
static PyObject *PyObject_TryGetAttrString(PyObject *object, const char *attr)
{
if (!PyObject_HasAttrString(object, attr))
return NULL;
return PyObject_GetAttrString(object, attr);
}
//------------------------------------------------------------------------
// Some defines
#define POPUP_NAMES_COUNT 4
#define MAX_CHOOSER_MENU_COMMANDS 10
#define thisobj ((py_choose2_t *) obj)
#define thisdecl py_choose2_t *_this = thisobj
#define MENU_COMMAND_CB(id) static uint32 idaapi s_menu_command_##id(void *obj, uint32 n) { return thisobj->on_command(id, int(n)); }
#define DECL_MENU_COMMAND_CB(id) s_menu_command_##id
#define S_ON_EDIT_LINE "OnEditLine"
#define S_ON_INSERT_LINE "OnInsertLine"
#define S_ON_GET_LINE "OnGetLine"
#define S_ON_DELETE_LINE "OnDeleteLine"
#define S_ON_REFRESH "OnRefresh"
#define S_ON_SELECT_LINE "OnSelectLine"
#define S_ON_COMMAND "OnCommand"
#define S_ON_GET_ICON "OnGetIcon"
#ifdef CH_ATTRS
#define S_ON_GET_LINE_ATTR "OnGetLineAttr"
#endif
#define S_ON_GET_SIZE "OnGetSize"
#define S_ON_CLOSE "OnClose"
#define CHOOSE2_HAVE_DEL 0x0001
#define CHOOSE2_HAVE_INS 0x0002
#define CHOOSE2_HAVE_UPDATE 0x0004
#define CHOOSE2_HAVE_EDIT 0x0008
#define CHOOSE2_HAVE_ENTER 0x0010
#define CHOOSE2_HAVE_GETICON 0x0020
#define CHOOSE2_HAVE_GETATTR 0x0040
#define CHOOSE2_HAVE_COMMAND 0x0080
#define CHOOSE2_HAVE_ONCLOSE 0x0100
//------------------------------------------------------------------------
// Helper functions
class py_choose2_t;
typedef std::map<PyObject *, py_choose2_t *> pychoose2_to_choose2_map_t;
static pychoose2_to_choose2_map_t choosers;
py_choose2_t *choose2_find_instance(PyObject *self)
{
pychoose2_to_choose2_map_t::iterator it = choosers.find(self);
if (it == choosers.end())
return NULL;
return it->second;
}
void choose2_add_instance(PyObject *self, py_choose2_t *c2)
{
choosers[self] = c2;
}
void choose2_del_instance(PyObject *self)
{
pychoose2_to_choose2_map_t::iterator it = choosers.find(self);
if (it != choosers.end())
choosers.erase(it);
}
//------------------------------------------------------------------------
class py_choose2_t
{
private:
int flags;
int cb_flags;
qstring title;
PyObject *self;
qstrvec_t cols;
// the number of declarations should follow the MAX_CHOOSER_MENU_COMMANDS value
MENU_COMMAND_CB(0) MENU_COMMAND_CB(1)
MENU_COMMAND_CB(2) MENU_COMMAND_CB(3)
MENU_COMMAND_CB(4) MENU_COMMAND_CB(5)
MENU_COMMAND_CB(6) MENU_COMMAND_CB(7)
MENU_COMMAND_CB(8) MENU_COMMAND_CB(9)
static chooser_cb_t *menu_cbs[MAX_CHOOSER_MENU_COMMANDS];
int menu_cb_idx;
//------------------------------------------------------------------------
// Static methods to dispatch to member functions
//------------------------------------------------------------------------
#ifdef CH_ATTRS
static int idaapi ui_cb(void *obj, int notification_code, va_list va)
{
if ( notification_code != ui_get_chooser_item_attrs )
return 0;
va_arg(va, void *);
int n = int(va_arg(va, uint32));
chooser_item_attrs_t *attr = va_arg(va, chooser_item_attrs_t *);
thisobj->on_get_line_attr(n, attr);
return 1;
}
#endif
static uint32 idaapi s_sizer(void *obj)
{
return (uint32)thisobj->on_get_size();
}
static void idaapi s_getl(void *obj, uint32 n, char * const *arrptr)
{
thisobj->on_get_line(int(n), arrptr);
}
static uint32 idaapi s_del(void *obj, uint32 n)
{
return uint32(thisobj->on_delete_line(int(n)));
}
static void idaapi s_ins(void *obj)
{
thisobj->on_insert_line();
}
static uint32 idaapi s_update(void *obj, uint32 n)
{
return uint32(thisobj->on_refresh(int(n)));
}
static void idaapi s_edit(void *obj, uint32 n)
{
thisobj->on_edit_line(int(n));
}
static void idaapi s_enter(void * obj, uint32 n)
{
thisobj->on_select_line(int(n));
}
static int idaapi s_get_icon(void *obj, uint32 n)
{
return thisobj->on_get_icon(int(n));
}
static void idaapi s_destroy(void *obj)
{
thisobj->on_close();
}
private:
//------------------------------------------------------------------------
// Member functions corresponding to each chooser2() callback
//------------------------------------------------------------------------
void on_get_line(int lineno, char * const *line_arr)
{
if (lineno == 0)
{
for (size_t i=0;i<cols.size();i++)
qstrncpy(line_arr[i], cols[i].c_str(), MAXSTR);
return;
}
// Clear buffer
int ncols = int(cols.size());
for (int i=ncols-1;i>=0;i--)
line_arr[i][0] = '\0';
// Call Python
PyObject *list = PyObject_CallMethod(self, S_ON_GET_LINE, "l", lineno - 1);
if (list == NULL)
return;
for (int i=ncols-1;i>=0;i--)
{
PyObject *item = PyList_GetItem(list, Py_ssize_t(i));
if (item == NULL)
continue;
const char *str = PyString_AsString(item);
if (str != NULL)
qstrncpy(line_arr[i], str, MAXSTR);
}
Py_DECREF(list);
}
size_t on_get_size()
{
PyObject *pyres = PyObject_CallMethod(self, S_ON_GET_SIZE, NULL);
if (pyres == NULL)
return 0;
size_t res = PyInt_AsLong(pyres);
Py_DECREF(pyres);
return res;
}
void on_close()
{
#ifdef CH_ATTRS
if ( (flags & CH_ATTRS) != 0 )
unhook_from_notification_point(HT_UI, ui_cb, this);
#endif
// Call Python
PyObject *pyres = PyObject_CallMethod(self, S_ON_CLOSE, NULL);
Py_XDECREF(pyres);
Py_XDECREF(self);
// Remove from list
choose2_del_instance(self);
// delete this instance if none modal
if ( (flags & CH_MODAL) == 0 )
delete this;
}
int on_delete_line(int lineno)
{
PyObject *pyres = PyObject_CallMethod(self, S_ON_DELETE_LINE, "l", lineno - 1);
if (pyres == NULL)
return lineno;
size_t res = PyInt_AsLong(pyres);
Py_DECREF(pyres);
return res + 1;
}
int on_refresh(int lineno)
{
PyObject *pyres = PyObject_CallMethod(self, S_ON_REFRESH, "l", lineno - 1);
if (pyres == NULL)
return lineno;
size_t res = PyInt_AsLong(pyres);
Py_DECREF(pyres);
return res + 1;
}
void on_insert_line()
{
PyObject *pyres = PyObject_CallMethod(self, S_ON_INSERT_LINE, NULL);
Py_XDECREF(pyres);
}
void on_select_line(int lineno)
{
PyObject *pyres = PyObject_CallMethod(self, S_ON_SELECT_LINE, "l", lineno - 1);
Py_XDECREF(pyres);
}
void on_edit_line(int lineno)
{
PyObject *pyres = PyObject_CallMethod(self, S_ON_EDIT_LINE, "l", lineno - 1);
Py_XDECREF(pyres);
}
int on_command(int cmd_id, int lineno)
{
PyObject *pyres = PyObject_CallMethod(self, S_ON_COMMAND, "ll", lineno - 1, cmd_id);
if (pyres==NULL)
return lineno;
size_t res = PyInt_AsLong(pyres);
Py_XDECREF(pyres);
return res;
}
int on_get_icon(int lineno)
{
PyObject *pyres = PyObject_CallMethod(self, S_ON_GET_ICON, "l", lineno - 1);
size_t res = PyInt_AsLong(pyres);
Py_XDECREF(pyres);
return res;
}
#ifdef CH_ATTRS
void on_get_line_attr(int lineno, chooser_item_attrs_t *attr)
{
PyObject *pyres = PyObject_CallMethod(self, S_ON_GET_LINE_ATTR, "l", lineno - 1);
if (pyres == NULL)
return;
if (PyList_Check(pyres))
{
PyObject *item;
if ((item = PyList_GetItem(pyres, 0)) != NULL)
attr->color = PyInt_AsLong(item);
if ((item = PyList_GetItem(pyres, 1)) != NULL)
attr->flags = PyInt_AsLong(item);
}
Py_XDECREF(pyres);
}
#endif
public:
//------------------------------------------------------------------------
// Public methods
//------------------------------------------------------------------------
py_choose2_t()
{
flags = 0;
cb_flags = 0;
menu_cb_idx = 0;
self = NULL;
}
static py_choose2_t *find_chooser(const char *title)
{
return (py_choose2_t *) get_chooser_obj(title);
}
void close()
{
close_chooser(title.c_str());
}
bool activate()
{
TForm *frm = find_tform(title.c_str());
if (frm == NULL)
return false;
switchto_tform(frm, true);
return true;
}
int choose2(
int fl,
int ncols,
const int *widths,
const char *title,
int deflt = -1,
// An array of 4 strings: ("Insert", "Delete", "Edit", "Refresh"
const char * const *popup_names = NULL,
int icon = -1,
int x1 = -1, int y1 = -1, int x2 = -1, int y2 = -1)
{
flags = fl;
#ifdef CH_ATTRS
if ( (flags & CH_ATTRS) != 0 )
{
if ( !hook_to_notification_point(HT_UI, ui_cb, this) )
flags &= ~CH_ATTRS;
}
#endif
this->title = title;
return ::choose2(
flags,
x1, y1, x2, y2,
this,
ncols, widths,
s_sizer,
s_getl,
title,
icon,
deflt,
cb_flags & CHOOSE2_HAVE_DEL ? s_del : NULL,
cb_flags & CHOOSE2_HAVE_INS ? s_ins : NULL,
cb_flags & CHOOSE2_HAVE_UPDATE ? s_update : NULL,
cb_flags & CHOOSE2_HAVE_EDIT ? s_edit : NULL,
cb_flags & CHOOSE2_HAVE_ENTER ? s_enter : NULL,
s_destroy,
popup_names,
cb_flags & CHOOSE2_HAVE_GETICON ? s_get_icon : NULL);
}
int add_command(const char *caption, int flags=0, int menu_index=-1, int icon=-1)
{
if (menu_cb_idx >= MAX_CHOOSER_MENU_COMMANDS)
return -1;
bool ret = add_chooser_command(title.c_str(), caption, menu_cbs[menu_cb_idx], menu_index, icon, flags);
if (!ret)
return -1;
return menu_cb_idx++;
}
int show(PyObject *self)
{
PyObject *attr;
// get title
if ( (attr = PyObject_TryGetAttrString(self, "title")) == NULL )
return -1;
qstring title = PyString_AsString(attr);
Py_DECREF(attr);
// get flags
if ( (attr = PyObject_TryGetAttrString(self, "flags")) == NULL )
return -1;
int flags = PyInt_AsLong(attr);
Py_DECREF(attr);
// get columns
if ( (attr = PyObject_TryGetAttrString(self, "cols")) == NULL )
return -1;
// get col count
int ncols = PyList_Size(attr);
// get cols caption and widthes
intvec_t widths;
cols.qclear();
for (int i=0;i<ncols;i++)
{
// get list item: [name, width]
PyObject *list = PyList_GetItem(attr, i);
PyObject *v = PyList_GetItem(list, 0);
// Extract string
const char *str;
if (v != NULL)
str = PyString_AsString(v);
else
str = "";
cols.push_back(str);
// Extract width
int width;
v = PyList_GetItem(list, 1);
if (v == NULL)
width = strlen(str);
else
width = PyInt_AsLong(v);
widths.push_back(width);
}
Py_DECREF(attr);
// get *deflt
int deflt = -1;
if ( (attr = PyObject_TryGetAttrString(self, "deflt")) != NULL )
{
deflt = PyInt_AsLong(attr);
Py_DECREF(attr);
}
// get *icon
int icon = -1;
if ( (attr = PyObject_TryGetAttrString(self, "icon")) != NULL )
{
icon = PyInt_AsLong(attr);
Py_DECREF(attr);
}
// get *x1,y1,x2,y2
int pts[4];
static const char *pt_attrs[qnumber(pts)] = {"x1", "y1", "x2", "y2"};
for (int i=0;i<qnumber(pts);i++)
{
if ((attr = PyObject_TryGetAttrString(self, pt_attrs[i])) == NULL)
{
pts[i] = -1;
}
else
{
pts[i] = PyInt_AsLong(attr);
Py_DECREF(attr);
}
}
// check what callbacks we have
static const struct
{
const char *name;
int have;
} callbacks[] =
{
{S_ON_GET_SIZE, 0}, // 0 = mandatory callback
{S_ON_GET_LINE, 0},
{S_ON_CLOSE, 0},
{S_ON_EDIT_LINE, CHOOSE2_HAVE_EDIT},
{S_ON_INSERT_LINE, CHOOSE2_HAVE_INS},
{S_ON_DELETE_LINE, CHOOSE2_HAVE_DEL},
{S_ON_REFRESH, CHOOSE2_HAVE_UPDATE},
{S_ON_SELECT_LINE, CHOOSE2_HAVE_ENTER},
{S_ON_COMMAND, CHOOSE2_HAVE_COMMAND},
#ifdef CH_ATTRS
{S_ON_GET_LINE_ATTR, CHOOSE2_HAVE_GETATTR},
#endif
{S_ON_GET_ICON, CHOOSE2_HAVE_GETICON}
};
cb_flags = 0;
for (int i=0;i<qnumber(callbacks);i++)
{
if ((attr = PyObject_TryGetAttrString(self, callbacks[i].name)) == NULL ||
PyCallable_Check(attr) == 0)
{
Py_XDECREF(attr);
// Mandatory field?
if (callbacks[i].have == 0)
return -1;
}
else
{
cb_flags |= callbacks[i].have;
}
}
// get *popup names
const char **popup_names = NULL;
if ( ((attr = PyObject_TryGetAttrString(self, "popup_names")) != NULL)
&& PyList_Check(attr)
&& PyList_Size(attr) == POPUP_NAMES_COUNT )
{
popup_names = new const char *[POPUP_NAMES_COUNT];
for (int i=0;i<POPUP_NAMES_COUNT;i++)
{
const char *str = PyString_AsString(PyList_GetItem(attr, i));
popup_names[i] = qstrdup(str);
}
}
Py_XDECREF(attr);
#ifdef CH_ATTRS
// Adjust flags (if needed)
if ( (cb_flags & CHOOSE2_HAVE_GETATTR) != 0 )
flags |= CH_ATTRS;
#endif
// Increase object reference
Py_INCREF(self);
this->self = self;
// Create chooser
int r = this->choose2(flags, ncols, &widths[0], title.c_str(), deflt, popup_names, icon, pts[0], pts[1], pts[2], pts[3]);
// Clear temporary popup_names
if (popup_names != NULL)
{
for (int i=0;i<POPUP_NAMES_COUNT;i++)
qfree((void *)popup_names[i]);
delete [] popup_names;
}
// Modal chooser return the index of the selected item
if ( (flags & CH_MODAL) != 0 )
r--;
return r;
}
PyObject *get_self() { return self; }
void refresh()
{
refresh_chooser(title.c_str());
}
};
//------------------------------------------------------------------------
// Initialize the callback pointers
chooser_cb_t *py_choose2_t::menu_cbs[MAX_CHOOSER_MENU_COMMANDS] =
{
DECL_MENU_COMMAND_CB(0), DECL_MENU_COMMAND_CB(1),
DECL_MENU_COMMAND_CB(2), DECL_MENU_COMMAND_CB(3),
DECL_MENU_COMMAND_CB(4), DECL_MENU_COMMAND_CB(5),
DECL_MENU_COMMAND_CB(6), DECL_MENU_COMMAND_CB(7),
DECL_MENU_COMMAND_CB(8), DECL_MENU_COMMAND_CB(9)
};
#undef POPUP_NAMES_COUNT
#undef MAX_CHOOSER_MENU_COMMANDS
#undef thisobj
#undef thisdecl
#undef MENU_COMMAND_CB
#undef DECL_MENU_COMMAND_CB
#undef S_ON_EDIT_LINE
#undef S_ON_INSERT_LINE
#undef S_ON_GET_LINE
#undef S_ON_DELETE_LINE
#undef S_ON_REFRESH
#undef S_ON_SELECT_LINE
#undef S_ON_COMMAND
#undef S_ON_GET_ICON
#undef S_ON_GET_LINE_ATTR
#undef S_ON_GET_SIZE
#undef S_ON_CLOSE
#undef CHOOSE2_HAVE_DEL
#undef CHOOSE2_HAVE_INS
#undef CHOOSE2_HAVE_UPDATE
#undef CHOOSE2_HAVE_EDIT
#undef CHOOSE2_HAVE_ENTER
#undef CHOOSE2_HAVE_GETICON
#undef CHOOSE2_HAVE_GETATTR
#undef CHOOSE2_HAVE_COMMAND
#undef CHOOSE2_HAVE_ONCLOSE
//------------------------------------------------------------------------
int choose2_show(PyObject *self)
{
py_choose2_t *c2 = choose2_find_instance(self);
if (c2 != NULL)
{
c2->activate();
return 1;
}
c2 = new py_choose2_t();
choose2_add_instance(self, c2);
return c2->show(self);
}
//------------------------------------------------------------------------
void choose2_close(PyObject *self)
{
py_choose2_t *c2 = choose2_find_instance(self);
if (c2 != NULL)
c2->close();
}
//------------------------------------------------------------------------
void choose2_refresh(PyObject *self)
{
py_choose2_t *c2 = choose2_find_instance(self);
if (c2 != NULL)
c2->refresh();
}
//------------------------------------------------------------------------
void choose2_activate(PyObject *self)
{
py_choose2_t *c2 = choose2_find_instance(self);
if (c2 != NULL)
c2->activate();
}
//------------------------------------------------------------------------
int choose2_add_command(PyObject *self, const char *caption, int flags=0, int menu_index=-1, int icon=-1)
{
py_choose2_t *c2 = choose2_find_instance(self);
if (c2 != NULL)
return c2->add_command(caption, flags, menu_index, icon);
else
return -2;
}
//------------------------------------------------------------------------
PyObject *choose2_find(const char *title)
{
py_choose2_t *c2 = py_choose2_t::find_chooser(title);
if (c2 == NULL)
return NULL;
return c2->get_self();
}
//-------------------------------------------------------------------------
// End of Chooser2 wrapper class
//-------------------------------------------------------------------------
uint32 idaapi choose_sizer(void *self)
{
PyObject *pyres;
@ -232,6 +860,7 @@ uint32 choose_choose(void *self,
%}
%pythoncode %{
class Choose:
"""
Choose - class for choose() with callbacks
@ -294,4 +923,115 @@ class Choose:
choose - Display the choose dialogue
"""
return _idaapi.choose_choose(self, self.flags, self.x0, self.y0, self.x1, self.y1, self.width)
class Choose2:
"""Choose2 wrapper class"""
# refer to kernwin.hpp for more information on how to use these constants
CH_MODAL = 0x01
CH_MULTI = 0x02
CH_MULTI_EDIT = 0x04
CH_NOBTNS = 0x08
CH_ATTRS = 0x10
CH_BUILTIN_MASK = 0xF80000
# column flags (are specified in the widths array)
CHCOL_PLAIN = 0x00000000
CHCOL_PATH = 0x00010000
CHCOL_HEX = 0x00020000
CHCOL_DEC = 0x00030000
CHCOL_FORMAT = 0x00070000
def __init__(self, title, cols, flags=0, popup_names=None, icon=-1, x1=-1, y1=-1, x2=-1, y2=-1):
self.title = title
self.flags = flags
# a list of colums; each list item is a list of two items
# example: [ ["Address", 10 | Choose2.CHCOL_HEX], ["Name", 30 | CHCOL_PLAIN] ]
self.cols = cols
self.deflt = -1
# list of new captions to replace this list ["Insert", "Delete", "Edit", "Refresh"]
self.popup_names = popup_names
self.icon = icon
self.x1 = x1
self.y1 = y1
self.x2 = x2
self.y2 = y2
def Show(self, modal=False):
"""Activates or creates a chooser window"""
if modal:
self.flags |= Choose2.CH_MODAL
else:
self.flags &= ~Choose2.CH_MODAL
return _idaapi.choose2_show(self)
def Activate():
"""Activates a visible chooser"""
return _idaapi.choose2_activate(self)
def Refresh():
"""Causes the refresh callback to trigger"""
return _idaapi.choose2_refresh(self)
def Close():
"""Closes the chooser"""
return _idaapi.choose2_close(self)
def AddCommand(self, caption, flags = _idaapi.CHOOSER_POPUP_MENU, menu_index=-1,icon = -1):
"""Adds a new chooser command
Save the returned value and later use it in the OnCommand handler
@return: Returns a negative value on failure or the command index
"""
return _idaapi.choose2_add_command(self, caption, flags, menu_index, icon)
#
# Implement these methods in the subclass:
#
# def OnClose(self):
# # return nothing
# pass
# def OnEditLine(self, n):
# # return nothing (mandatory callback)
# pass
# def OnInsertLine(self):
# # return nothing
# pass
# def OnSelectLine(self, n):
# # return nothing
# pass
# def OnGetLine(self, n):
# # return a list [col1, col2, col3, ...] describing the n-th line
# return ["col1", "col2", ...]
# def OnGetSize(self):
# # return the size (mandatory callback)
# return len(self.the_list)
# def OnDeleteLine(self, n):
# # return new line number
# return self.n
# def OnRefresh(self, n):
# # return new line number
# return self.n
# def OnCommand(self, n, cmd_id):
# # return int ; check add_chooser_command()
# return 0
# def OnGetIcon(self, n):
# # return icon number (or -1)
# return -1
# def OnGetLineAttr(self, n):
# # return list [color, flags] or None; check chooser_item_attrs_t
# pass
%}