diff --git a/examples/ex_custview.py b/examples/ex_custview.py
index 2e9ea58..9b373a8 100644
--- a/examples/ex_custview.py
+++ b/examples/ex_custview.py
@@ -4,22 +4,26 @@
#
import idaapi
import idc
-from idaapi import simplecustview_t
-#
+from idaapi import simplecustviewer_t
+#
# -----------------------------------------------------------------------
-class mycv_t(simplecustview_t):
+class mycv_t(simplecustviewer_t):
def Create(self, sn=None):
# Form the title
title = "Simple custom view test"
if sn:
title += " %d" % sn
+
# Create the customview
- if not simplecustview_t.Create(self, title):
+ if not simplecustviewer_t.Create(self, title):
return False
- id = self.AddPopupMenu("Hello")
+ self.menu_hello = self.AddPopupMenu("Hello")
+ self.menu_world = self.AddPopupMenu("World")
+
for i in xrange(0, 100):
self.AddLine("Line %d" % i)
+
return True
def OnClick(self, shift):
@@ -37,7 +41,9 @@ class mycv_t(simplecustview_t):
@param shift: Shift flag
@return Boolean. True if you handled the event
"""
- print "OnDblClick, shift=%d" % shift
+ word = self.GetCurrentWord()
+ if not word: word = ""
+ print "OnDblClick, shift=%d, current word=%s" % (shift, word)
return True
def OnCursorPosChanged(self):
@@ -67,14 +73,17 @@ class mycv_t(simplecustview_t):
self.Close()
elif vkey == 46:
n = self.GetLineNo()
- self.DelLine(n)
- self.Refresh()
- print "Deleted line %d" % n
+ if n is not None:
+ self.DelLine(n)
+ self.Refresh()
+ print "Deleted line %d" % n
# Goto?
elif vkey == ord('G'):
- v = idc.AskLong(self.GetLineNo(), "Where to go?")
- if v:
- self.Jump(v, 0, 5)
+ n = self.GetLineNo()
+ if n is not None:
+ v = idc.AskLong(self.GetLineNo(), "Where to go?")
+ if v:
+ self.Jump(v, 0, 5)
elif vkey == ord('R'):
print "refreshing...."
self.Refresh()
@@ -128,10 +137,17 @@ class mycv_t(simplecustview_t):
def OnPopupMenu(self, menu_id):
"""
A context (or popup) menu item was executed.
- @param menu_id: ID previously registered with add_popup_menu()
+ @param menu_id: ID previously registered with AddPopupMenu()
@return: Boolean
"""
print "OnPopupMenu, menu_id=%d" % menu_id
+ if menu_id == self.menu_hello:
+ print "Hello"
+ elif menu_id == self.menu_world:
+ print "World"
+ else:
+ # Unhandled
+ return False
return True
# -----------------------------------------------------------------------
@@ -156,11 +172,13 @@ if not mycv:
del mycv
def make_many(n):
+ L = []
for i in xrange(1, n+1):
- t = mycv_t()
- if not t.Create(i):
+ v = mycv_t()
+ if not v.Create(i):
break
- t.Show()
- return i
+ v.Show()
+ L.append(v)
+ return L
-#
\ No newline at end of file
+#
\ No newline at end of file
diff --git a/swig/kernwin.i b/swig/kernwin.i
index 902afd5..98458ce 100644
--- a/swig/kernwin.i
+++ b/swig/kernwin.i
@@ -75,11 +75,11 @@ def askseg(defval, format):
%{
-//
+//
//---------------------------------------------------------------------------
-// Base class for all custview place_t providers
-class custview_data_t
+// Base class for all custviewer place_t providers
+class custviewer_data_t
{
public:
virtual void *get_ud() = 0;
@@ -88,7 +88,7 @@ public:
};
//---------------------------------------------------------------------------
-class cvdata_simpleline_t: public custview_data_t
+class cvdata_simpleline_t: public custviewer_data_t
{
private:
strvec_t lines;
@@ -192,13 +192,13 @@ public:
};
//---------------------------------------------------------------------------
-class customview_t
+class customviewer_t
{
protected:
qstring _title;
TForm *_form;
TCustomControl *_cv;
- custview_data_t *_data;
+ custviewer_data_t *_data;
int _features;
enum
{
@@ -214,9 +214,9 @@ private:
struct pyw_popupctx_t
{
size_t menu_id;
- customview_t *cv;
+ customviewer_t *cv;
pyw_popupctx_t(): menu_id(0), cv(NULL) { }
- pyw_popupctx_t(size_t mid, customview_t *v): menu_id(mid), cv(v) { }
+ pyw_popupctx_t(size_t mid, customviewer_t *v): menu_id(mid), cv(v) { }
};
typedef std::map pyw_popupmap_t;
static pyw_popupmap_t _global_popup_map;
@@ -226,7 +226,7 @@ private:
static bool idaapi s_popup_cb(void *ud)
{
- customview_t *_this = (customview_t *)ud;
+ customviewer_t *_this = (customviewer_t *)ud;
return _this->on_popup();
}
@@ -241,38 +241,38 @@ private:
static bool idaapi s_cv_keydown(TCustomControl * /*cv*/, int vk_key, int shift, void *ud)
{
- customview_t *_this = (customview_t *)ud;
+ customviewer_t *_this = (customviewer_t *)ud;
return _this->on_keydown(vk_key, shift);
}
// The popup menu is being constructed
static void idaapi s_cv_popup(TCustomControl * /*cv*/, void *ud)
{
- customview_t *_this = (customview_t *)ud;
+ customviewer_t *_this = (customviewer_t *)ud;
_this->on_popup();
}
// The user clicked
static bool idaapi s_cv_click(TCustomControl *cv, int shift, void *ud)
{
- customview_t *_this = (customview_t *)ud;
+ customviewer_t *_this = (customviewer_t *)ud;
return _this->on_click(shift);
}
// The user double clicked
static bool idaapi s_cv_dblclick(TCustomControl * /*cv*/, int shift, void *ud)
{
- customview_t *_this = (customview_t *)ud;
+ customviewer_t *_this = (customviewer_t *)ud;
return _this->on_dblclick(shift);
}
// Cursor position has been changed
static void idaapi s_cv_curpos(TCustomControl * /*cv*/, void *ud)
{
- customview_t *_this = (customview_t *)ud;
+ customviewer_t *_this = (customviewer_t *)ud;
_this->on_curpos_changed();
}
//--------------------------------------------------------------------------
static int idaapi s_ui_cb(void *ud, int code, va_list va)
{
- customview_t *_this = (customview_t *)ud;
+ customviewer_t *_this = (customviewer_t *)ud;
switch ( code )
{
case ui_get_custom_viewer_hint:
@@ -331,12 +331,12 @@ public:
_form = NULL;
}
- customview_t()
+ customviewer_t()
{
init_vars();
}
- ~customview_t()
+ ~customviewer_t()
{
}
@@ -386,6 +386,38 @@ public:
return jumpto(pl, x, y);
}
+ //--------------------------------------------------------------------------
+ bool get_current_word(bool mouse, qstring &word)
+ {
+ // query the cursor position
+ int x, y;
+ if ( get_place(mouse, &x, &y) == NULL )
+ return false;
+
+ // query the line at the cursor
+ const char *line = get_current_line(mouse, true);
+ if ( line == NULL )
+ return false;
+
+ if ( x >= (int)strlen(line) )
+ return false;
+
+ // find the beginning of the word
+ const char *ptr = line + x;
+ while ( ptr > line && !isspace(ptr[-1]) )
+ ptr--;
+
+ // find the end of the word
+ const char *begin = ptr;
+ ptr = line + x;
+ while ( !isspace(*ptr) && *ptr != '\0' )
+ ptr++;
+
+ word.qclear();
+ word.append(begin, ptr-begin);
+ return true;
+ }
+
//--------------------------------------------------------------------------
const char *get_current_line(bool mouse, bool notags)
{
@@ -434,7 +466,7 @@ public:
{
size_t menu_id = _global_popup_id + 1;
// Overlap / already exists?
- if (_cv == NULL || // No custview?
+ if (_cv == NULL || // No custviewer?
menu_id == 0 || // Overlap?
_global_popup_map.find(menu_id) != _global_popup_map.end()) // Already exists?
{
@@ -452,7 +484,7 @@ public:
}
//--------------------------------------------------------------------------
- bool create(const char *title, int features, custview_data_t *data)
+ bool create(const char *title, int features, custviewer_data_t *data)
{
// Already created? (in the instance)
if ( _form != NULL )
@@ -516,10 +548,10 @@ public:
}
};
-customview_t::pyw_popupmap_t customview_t::_global_popup_map;
-size_t customview_t::_global_popup_id = 0;
+customviewer_t::pyw_popupmap_t customviewer_t::_global_popup_map;
+size_t customviewer_t::_global_popup_id = 0;
//---------------------------------------------------------------------------
-class py_simplecustview_t: public customview_t
+class py_simplecustview_t: public customviewer_t
{
private:
cvdata_simpleline_t data;
@@ -735,7 +767,7 @@ public:
bool jumpto(size_t ln, int x, int y)
{
- return customview_t::jumpto(&simpleline_place_t(ln), x, y);
+ return customviewer_t::jumpto(&simpleline_place_t(ln), x, y);
}
// Initializes and links the Python object to this class
@@ -788,7 +820,7 @@ public:
if ( !init(py_last_link, _title.c_str()) )
return false;
}
- return customview_t::show();
+ return customviewer_t::show();
}
bool get_selection(size_t *x1, size_t *y1, size_t *x2, size_t *y2)
@@ -828,7 +860,7 @@ public:
return py_this;
}
};
-//
+//
bool idaapi py_menu_item_callback(void *userdata)
{
@@ -862,10 +894,10 @@ bool idaapi py_menu_item_callback(void *userdata)
%rename (add_menu_item) wrap_add_menu_item;
%inline %{
-//
+//
//
-// Pywraps Simple Custom View functions
+// Pywraps Simple Custom Viewer functions
//
PyObject *pyscv_init(PyObject *py_link, const char *title)
{
@@ -1022,6 +1054,18 @@ PyObject *pyscv_get_selection(PyObject *py_this)
return _this->py_get_selection();
}
+PyObject *pyscv_get_current_word(PyObject *py_this, bool mouse)
+{
+ DECL_THIS;
+ if ( _this != NULL )
+ {
+ qstring word;
+ if ( _this->get_current_word(mouse, word) )
+ return PyString_FromString(word.c_str());
+ }
+ Py_RETURN_NONE;
+}
+
// Edits an existing line
bool pyscv_edit_line(PyObject *py_this, size_t nline, PyObject *py_sl)
{
@@ -1029,7 +1073,7 @@ bool pyscv_edit_line(PyObject *py_this, size_t nline, PyObject *py_sl)
return _this == NULL ? false : _this->edit_line(nline, py_sl);
}
#undef DECL_THIS
-//
+//
//
#ifdef CH_ATTRS
@@ -1798,8 +1842,8 @@ class Choose:
"""
return _idaapi.choose_choose(self, self.flags, self.x0, self.y0, self.x1, self.y1, self.width)
-#
-class simplecustview_t(object):
+#
+class simplecustviewer_t(object):
def __init__(self):
self.this = None
@@ -1875,11 +1919,17 @@ class simplecustview_t(object):
return _idaapi.pyscv_add_line(self.this, self.make_sl_arg(line, fgcolor, bgcolor))
def InsertLine(self, lineno, line, fgcolor=None, bgcolor=None):
- """Inserts a line in the given position"""
+ """
+ Inserts a line in the given position
+ @return Boolean
+ """
return _idaapi.pyscv_insert_line(self.this, lineno, self.make_sl_arg(line, fgcolor, bgcolor))
def EditLine(self, lineno, line, fgcolor=None, bgcolor=None):
- """Edits an existing line"""
+ """
+ Edits an existing line.
+ @return Boolean
+ """
return _idaapi.pyscv_edit_line(self.this, lineno, self.make_sl_arg(line, fgcolor, bgcolor))
def PatchLine(self, lineno, offs, value):
@@ -1887,11 +1937,29 @@ class simplecustview_t(object):
return _idaapi.pyscv_patch_line(self.this, lineno, offs, value)
def DelLine(self, lineno):
+ """
+ Deletes an existing line
+ @return Boolean
+ """
return _idaapi.pyscv_del_line(self.this, lineno)
def GetLine(self, lineno):
+ """
+ Returns a line
+ @param lineno: The line number
+ @return:
+ Returns a tuple (colored_line, fgcolor, bgcolor) or None
+ """
return _idaapi.pyscv_get_line(self.this, lineno)
+ def GetCurrentWord(self, mouse = 0):
+ """
+ Returns the current word
+ @param mouse: Use mouse position or cursor position
+ @return: None if failed or a String containing the current word at mouse or cursor
+ """
+ return _idaapi.pyscv_get_current_word(self.this, mouse)
+
def GetCurrentLine(self, mouse = 0, notags = 0):
"""
Returns the current line.
@@ -2008,7 +2076,7 @@ class simplecustview_t(object):
# print "OnPopupMenu, menu_id=" % menu_id
# return True
-#
+#
#
class Choose2: