summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Tools/idle/ClassBrowser.py205
-rw-r--r--Tools/idle/ScrolledList.py128
2 files changed, 205 insertions, 128 deletions
diff --git a/Tools/idle/ClassBrowser.py b/Tools/idle/ClassBrowser.py
index 8db037a..ffbf508 100644
--- a/Tools/idle/ClassBrowser.py
+++ b/Tools/idle/ClassBrowser.py
@@ -9,11 +9,15 @@ XXX TO DO:
"""
+import os
import string
import pyclbr
from Tkinter import *
import tkMessageBox
+from ScrolledList import ScrolledList
+
+
class ClassBrowser:
def __init__(self, flist, name):
@@ -32,44 +36,62 @@ class ClassBrowser:
self.root = root
self.top = top = Toplevel(root)
self.top.protocol("WM_DELETE_WINDOW", self.close)
+ top.wm_title("Class browser")
self.leftframe = leftframe = Frame(top)
self.leftframe.pack(side="left", fill="both", expand=1)
- top.wm_title("Class browser")
# Create help label
- self.helplabel = Label(leftframe,
- text="Classes in module %s" % name,
- borderwidth=2, relief="groove")
+ self.helplabel = Label(leftframe, text="Module %s" % name,
+ relief="groove", borderwidth=2)
self.helplabel.pack(fill="x")
# Create top frame, with scrollbar and listbox
- self.topframe = Frame(leftframe)
- self.topframe.pack(fill="both", expand=1)
- self.vbar = Scrollbar(self.topframe, name="vbar")
- self.vbar.pack(side="right", fill="y")
- self.listbox = Listbox(self.topframe, exportselection=0,
- takefocus=1, width=30)
- self.listbox.pack(expand=1, fill="both")
- # Tie listbox and scrollbar together
- self.vbar["command"] = self.listbox.yview
- self.listbox["yscrollcommand"] = self.vbar.set
- # Bind events to the list box
- self.listbox.bind("<ButtonRelease-1>", self.click_event)
- self.listbox.bind("<Double-ButtonRelease-1>", self.double_click_event)
- ##self.listbox.bind("<ButtonPress-3>", self.popup_event)
- self.listbox.bind("<Key-Up>", self.up_event)
- self.listbox.bind("<Key-Down>", self.down_event)
+ self.classviewer = ClassViewer(
+ self.leftframe, self.flist, self)
# Load the classes
- self.loadclasses(dict, name)
+ self.load_classes(dict, name)
def close(self):
+ self.classviewer = None
+ self.methodviewer = None
self.top.destroy()
- def loadclasses(self, dict, module):
+ def load_classes(self, dict, module):
+ self.classviewer.load_classes(dict, module)
+ if self.botframe:
+ self.botframe.destroy()
+ self.botframe = None
+ self.methodviewer = None
+
+ botframe = None
+ methodhelplabel = None
+ methodviewer = None
+
+ def show_methods(self, cl):
+ if not self.botframe:
+ self.botframe = Frame(self.top)
+ self.botframe.pack(side="right", expand=1, fill="both")
+ self.methodhelplabel = Label(self.botframe,
+ relief="groove", borderwidth=2)
+ self.methodhelplabel.pack(fill="x")
+ self.methodviewer = MethodViewer(self.botframe, self.flist)
+ self.methodhelplabel.config(text="Class %s" % cl.name)
+ self.methodviewer.load_methods(cl)
+
+
+class ClassViewer(ScrolledList):
+
+ def __init__(self, master, flist, browser):
+ ScrolledList.__init__(self, master)
+ self.flist = flist
+ self.browser = browser
+
+ def load_classes(self, dict, module):
+ self.clear()
+ self.dict = dict
items = []
for key, value in dict.items():
if value.module == module:
items.append((value.lineno, key, value))
items.sort()
- l = self.listbox
for lineno, key, value in items:
s = key
if value.super:
@@ -80,133 +102,60 @@ class ClassBrowser:
name = "%s.%s" % (sup.module, name)
super.append(name)
s = s + "(%s)" % string.join(super, ", ")
- l.insert("end", s)
- l.focus_set()
- l.selection_clear(0, "end")
- if self.botframe:
- self.botframe.destroy()
- self.botframe = None
- self.methodviewer = None
-
- def click_event(self, event):
- self.listbox.activate("@%d,%d" % (event.x, event.y))
- index = self.listbox.index("active")
- self.show_methods(index)
-
- def double_click_event(self, event):
- self.listbox.activate("@%d,%d" % (event.x, event.y))
- index = self.listbox.index("active")
- self.show_source(index)
-
- def up_event(self, event):
- index = self.listbox.index("active") - 1
- if index < 0:
- self.top.bell()
- return "break"
- self.show_methods(index)
- return "break"
+ self.append(s)
- def down_event(self, event):
- index = self.listbox.index("active") + 1
- if index >= self.listbox.index("end"):
- self.top.bell()
- return "break"
- self.show_methods(index)
- return "break"
-
- def show_source(self, index):
+ def getname(self, index):
name = self.listbox.get(index)
i = string.find(name, '(')
if i >= 0:
name = name[:i]
- cl = self.dict[name]
- edit = self.flist.open(cl.file)
- edit.gotoline(cl.lineno)
+ return name
- botframe = None
- methodviewer = None
+ def getclass(self, index):
+ return self.dict[self.getname(index)]
+
+ def on_select(self, index):
+ self.show_methods(index)
+
+ def on_double(self, index):
+ self.show_source(index)
def show_methods(self, index):
- self.listbox.selection_clear(0, "end")
- self.listbox.selection_set(index)
- self.listbox.activate(index)
- self.listbox.see(index)
- self.listbox.focus_set()
- name = self.listbox.get(index)
- i = string.find(name, '(')
- if i >= 0:
- name = name[:i]
- cl = self.dict[name]
- if not self.botframe:
- self.botframe = Frame(self.top)
- self.botframe.pack(expand=1, fill="both")
- if not self.methodviewer:
- self.methodviewer = MethodViewer(self.botframe, self.flist)
- self.methodviewer.loadmethods(cl)
+ cl = self.getclass(index)
+ self.browser.show_methods(cl)
-class MethodViewer:
-
- # XXX There's a pattern emerging here...
+ def show_source(self, index):
+ cl = self.getclass(index)
+ if os.path.isfile(cl.file):
+ edit = self.flist.open(cl.file)
+ edit.gotoline(cl.lineno)
+
+
+class MethodViewer(ScrolledList):
- def __init__(self, frame, flist):
- self.frame = frame
+ def __init__(self, master, flist):
+ ScrolledList.__init__(self, master)
self.flist = flist
- # Create help label
- self.helplabel = Label(frame,
- text="Methods", borderwidth=2, relief="groove")
- self.helplabel.pack(fill="x")
- # Create top frame, with scrollbar and listbox
- self.topframe = Frame(frame)
- self.topframe.pack(fill="both", expand=1)
- self.vbar = Scrollbar(self.topframe, name="vbar")
- self.vbar.pack(side="right", fill="y")
- self.listbox = Listbox(self.topframe, exportselection=0,
- takefocus=1, width=30)
- self.listbox.pack(expand=1, fill="both")
- # Tie listbox and scrollbar together
- self.vbar["command"] = self.listbox.yview
- self.listbox["yscrollcommand"] = self.vbar.set
- # Bind events to the list box
- self.listbox.bind("<ButtonRelease-1>", self.click_event)
- self.listbox.bind("<Double-ButtonRelease-1>", self.double_click_event)
- ##self.listbox.bind("<ButtonPress-3>", self.popup_event)
- self.listbox.bind("<Key-Up>", self.up_event)
- self.listbox.bind("<Key-Down>", self.down_event)
classinfo = None
- def loadmethods(self, cl):
+ def load_methods(self, cl):
self.classinfo = cl
- self.helplabel.config(text="Methods of class %s" % cl.name)
- l = self.listbox
- l.delete(0, "end")
- l.selection_clear(0, "end")
+ self.clear()
items = []
for name, lineno in cl.methods.items():
items.append((lineno, name))
items.sort()
for item, name in items:
- l.insert("end", name)
+ self.append(name)
def click_event(self, event):
pass
- def double_click_event(self, event):
- self.listbox.activate("@%d,%d" % (event.x, event.y))
- index = self.listbox.index("active")
- self.show_source(index)
-
- def up_event(self, event):
- pass
-
- def down_event(self, event):
- pass
+ def on_double(self, index):
+ self.show_source(self.get(index))
- def show_source(self, index):
- name = self.listbox.get(index)
- i = string.find(name, '(')
- if i >= 0:
- name = name[:i]
- edit = self.flist.open(self.classinfo.file)
- edit.gotoline(self.classinfo.methods[name])
-
+ def show_source(self, name):
+ if os.path.isfile(self.classinfo.file):
+ edit = self.flist.open(self.classinfo.file)
+ edit.gotoline(self.classinfo.methods[name])
diff --git a/Tools/idle/ScrolledList.py b/Tools/idle/ScrolledList.py
new file mode 100644
index 0000000..703cd0c
--- /dev/null
+++ b/Tools/idle/ScrolledList.py
@@ -0,0 +1,128 @@
+from Tkinter import *
+
+class ScrolledList:
+
+ def __init__(self, master, **options):
+ # Create top frame, with scrollbar and listbox
+ self.master = master
+ self.frame = frame = Frame(master)
+ self.frame.pack(fill="both", expand=1)
+ self.vbar = vbar = Scrollbar(frame, name="vbar")
+ self.vbar.pack(side="right", fill="y")
+ self.listbox = listbox = Listbox(frame, exportselection=0)
+ if options:
+ listbox.configure(options)
+ listbox.pack(expand=1, fill="both")
+ # Tie listbox and scrollbar together
+ vbar["command"] = listbox.yview
+ listbox["yscrollcommand"] = vbar.set
+ # Bind events to the list box
+ listbox.bind("<ButtonRelease-1>", self.click_event)
+ listbox.bind("<Double-ButtonRelease-1>", self.double_click_event)
+ listbox.bind("<ButtonPress-3>", self.popup_event)
+ listbox.bind("<Key-Up>", self.up_event)
+ listbox.bind("<Key-Down>", self.down_event)
+ # Set the focus
+ listbox.focus_set()
+
+ def clear(self):
+ self.listbox.delete(0, "end")
+
+ def append(self, item):
+ self.listbox.insert("end", str(item))
+
+ def get(self, index):
+ return self.listbox.get(index)
+
+ def click_event(self, event):
+ self.listbox.activate("@%d,%d" % (event.x, event.y))
+ index = self.listbox.index("active")
+ self.select(index)
+ self.on_select(index)
+ return "break"
+
+ def double_click_event(self, event):
+ index = self.listbox.index("active")
+ self.select(index)
+ self.on_double(index)
+ return "break"
+
+ menu = None
+
+ def popup_event(self, event):
+ if not self.menu:
+ self.make_menu()
+ menu = self.menu
+ self.listbox.activate("@%d,%d" % (event.x, event.y))
+ index = self.listbox.index("active")
+ self.select(index)
+ menu.tk_popup(event.x_root, event.y_root)
+
+ def make_menu(self):
+ menu = Menu(self.listbox, tearoff=0)
+ self.menu = menu
+ self.fill_menu()
+
+ def up_event(self, event):
+ index = self.listbox.index("active")
+ if self.listbox.selection_includes(index):
+ index = index - 1
+ else:
+ index = self.listbox.size() - 1
+ if index < 0:
+ self.listbox.bell()
+ else:
+ self.select(index)
+ self.on_select(index)
+ return "break"
+
+ def down_event(self, event):
+ index = self.listbox.index("active")
+ if self.listbox.selection_includes(index):
+ index = index + 1
+ else:
+ index = 0
+ if index >= self.listbox.size():
+ self.listbox.bell()
+ else:
+ self.select(index)
+ self.on_select(index)
+ return "break"
+
+ def select(self, index):
+ self.listbox.focus_set()
+ self.listbox.activate(index)
+ self.listbox.selection_clear(0, "end")
+ self.listbox.selection_set(index)
+ self.listbox.see(index)
+
+ # Methods to override for specific actions
+
+ def fill_menu(self):
+ pass
+
+ def on_select(self, index):
+ pass
+
+ def on_double(self, index):
+ pass
+
+
+def test():
+ root = Tk()
+ root.protocol("WM_DELETE_WINDOW", root.destroy)
+ class MyScrolledList(ScrolledList):
+ def fill_menu(self): self.menu.add_command(label="pass")
+ def on_select(self, index): print "select", self.get(index)
+ def on_double(self, index): print "double", self.get(index)
+ s = MyScrolledList(root)
+ for i in range(30):
+ s.append("item %02d" % i)
+ return root
+
+def main():
+ root = test()
+ root.mainloop()
+
+if __name__ == '__main__':
+ main()