blob: ffbf5089e4fbcf15def40411e87be92b2c29ee5f [file] [log] [blame]
Guido van Rossum7f5c9ef1998-10-13 16:31:03 +00001"""Primitive class browser.
2
3XXX TO DO:
4
5- generalize the scrolling listbox with some behavior into a base class
6- add popup menu with more options (e.g. doc strings, base classes, imports)
7- show function argument list (have to do pattern matching on source)
8- should the classes and methods lists also be in the module's menu bar?
9
10"""
11
Guido van Rossume6fae1c1998-10-15 23:27:08 +000012import os
Guido van Rossum439c4671998-10-13 03:59:57 +000013import string
14import pyclbr
Guido van Rossum7f5c9ef1998-10-13 16:31:03 +000015from Tkinter import *
16import tkMessageBox
Guido van Rossum439c4671998-10-13 03:59:57 +000017
Guido van Rossume6fae1c1998-10-15 23:27:08 +000018from ScrolledList import ScrolledList
19
20
Guido van Rossum439c4671998-10-13 03:59:57 +000021class ClassBrowser:
22
Guido van Rossum7f5c9ef1998-10-13 16:31:03 +000023 def __init__(self, flist, name):
24 root = flist.root
Guido van Rossum439c4671998-10-13 03:59:57 +000025 try:
26 dict = pyclbr.readmodule(name)
27 except ImportError, msg:
28 tkMessageBox.showerror("Import error", str(msg), parent=root)
29 return
30 if not dict:
31 tkMessageBox.showerror("Nothing to browse",
32 "Module %s defines no classes" % name, parent=root)
33 return
Guido van Rossum7f5c9ef1998-10-13 16:31:03 +000034 self.flist = flist
35 self.dict = dict
Guido van Rossum439c4671998-10-13 03:59:57 +000036 self.root = root
37 self.top = top = Toplevel(root)
Guido van Rossum7f5c9ef1998-10-13 16:31:03 +000038 self.top.protocol("WM_DELETE_WINDOW", self.close)
Guido van Rossume6fae1c1998-10-15 23:27:08 +000039 top.wm_title("Class browser")
Guido van Rossum7f5c9ef1998-10-13 16:31:03 +000040 self.leftframe = leftframe = Frame(top)
41 self.leftframe.pack(side="left", fill="both", expand=1)
Guido van Rossum439c4671998-10-13 03:59:57 +000042 # Create help label
Guido van Rossume6fae1c1998-10-15 23:27:08 +000043 self.helplabel = Label(leftframe, text="Module %s" % name,
44 relief="groove", borderwidth=2)
Guido van Rossum439c4671998-10-13 03:59:57 +000045 self.helplabel.pack(fill="x")
46 # Create top frame, with scrollbar and listbox
Guido van Rossume6fae1c1998-10-15 23:27:08 +000047 self.classviewer = ClassViewer(
48 self.leftframe, self.flist, self)
Guido van Rossum439c4671998-10-13 03:59:57 +000049 # Load the classes
Guido van Rossume6fae1c1998-10-15 23:27:08 +000050 self.load_classes(dict, name)
Guido van Rossum7f5c9ef1998-10-13 16:31:03 +000051
52 def close(self):
Guido van Rossume6fae1c1998-10-15 23:27:08 +000053 self.classviewer = None
54 self.methodviewer = None
Guido van Rossum7f5c9ef1998-10-13 16:31:03 +000055 self.top.destroy()
Guido van Rossum439c4671998-10-13 03:59:57 +000056
Guido van Rossume6fae1c1998-10-15 23:27:08 +000057 def load_classes(self, dict, module):
58 self.classviewer.load_classes(dict, module)
59 if self.botframe:
60 self.botframe.destroy()
61 self.botframe = None
62 self.methodviewer = None
63
64 botframe = None
65 methodhelplabel = None
66 methodviewer = None
67
68 def show_methods(self, cl):
69 if not self.botframe:
70 self.botframe = Frame(self.top)
71 self.botframe.pack(side="right", expand=1, fill="both")
72 self.methodhelplabel = Label(self.botframe,
73 relief="groove", borderwidth=2)
74 self.methodhelplabel.pack(fill="x")
75 self.methodviewer = MethodViewer(self.botframe, self.flist)
76 self.methodhelplabel.config(text="Class %s" % cl.name)
77 self.methodviewer.load_methods(cl)
78
79
80class ClassViewer(ScrolledList):
81
82 def __init__(self, master, flist, browser):
83 ScrolledList.__init__(self, master)
84 self.flist = flist
85 self.browser = browser
86
87 def load_classes(self, dict, module):
88 self.clear()
89 self.dict = dict
Guido van Rossum7f5c9ef1998-10-13 16:31:03 +000090 items = []
91 for key, value in dict.items():
92 if value.module == module:
93 items.append((value.lineno, key, value))
Guido van Rossum439c4671998-10-13 03:59:57 +000094 items.sort()
Guido van Rossum7f5c9ef1998-10-13 16:31:03 +000095 for lineno, key, value in items:
Guido van Rossum439c4671998-10-13 03:59:57 +000096 s = key
97 if value.super:
98 super = []
99 for sup in value.super:
100 name = sup.name
101 if sup.module != value.module:
102 name = "%s.%s" % (sup.module, name)
103 super.append(name)
104 s = s + "(%s)" % string.join(super, ", ")
Guido van Rossume6fae1c1998-10-15 23:27:08 +0000105 self.append(s)
106
107 def getname(self, index):
108 name = self.listbox.get(index)
109 i = string.find(name, '(')
110 if i >= 0:
111 name = name[:i]
112 return name
Guido van Rossum7f5c9ef1998-10-13 16:31:03 +0000113
Guido van Rossume6fae1c1998-10-15 23:27:08 +0000114 def getclass(self, index):
115 return self.dict[self.getname(index)]
116
117 def on_select(self, index):
Guido van Rossum7f5c9ef1998-10-13 16:31:03 +0000118 self.show_methods(index)
119
Guido van Rossume6fae1c1998-10-15 23:27:08 +0000120 def on_double(self, index):
Guido van Rossum7f5c9ef1998-10-13 16:31:03 +0000121 self.show_source(index)
122
Guido van Rossum7f5c9ef1998-10-13 16:31:03 +0000123 def show_methods(self, index):
Guido van Rossume6fae1c1998-10-15 23:27:08 +0000124 cl = self.getclass(index)
125 self.browser.show_methods(cl)
Guido van Rossum7f5c9ef1998-10-13 16:31:03 +0000126
Guido van Rossume6fae1c1998-10-15 23:27:08 +0000127 def show_source(self, index):
128 cl = self.getclass(index)
129 if os.path.isfile(cl.file):
130 edit = self.flist.open(cl.file)
131 edit.gotoline(cl.lineno)
132
133
134class MethodViewer(ScrolledList):
Guido van Rossum7f5c9ef1998-10-13 16:31:03 +0000135
Guido van Rossume6fae1c1998-10-15 23:27:08 +0000136 def __init__(self, master, flist):
137 ScrolledList.__init__(self, master)
Guido van Rossum7f5c9ef1998-10-13 16:31:03 +0000138 self.flist = flist
Guido van Rossum7f5c9ef1998-10-13 16:31:03 +0000139
140 classinfo = None
141
Guido van Rossume6fae1c1998-10-15 23:27:08 +0000142 def load_methods(self, cl):
Guido van Rossum7f5c9ef1998-10-13 16:31:03 +0000143 self.classinfo = cl
Guido van Rossume6fae1c1998-10-15 23:27:08 +0000144 self.clear()
Guido van Rossum7f5c9ef1998-10-13 16:31:03 +0000145 items = []
146 for name, lineno in cl.methods.items():
147 items.append((lineno, name))
148 items.sort()
149 for item, name in items:
Guido van Rossume6fae1c1998-10-15 23:27:08 +0000150 self.append(name)
Guido van Rossum439c4671998-10-13 03:59:57 +0000151
152 def click_event(self, event):
153 pass
154
Guido van Rossume6fae1c1998-10-15 23:27:08 +0000155 def on_double(self, index):
156 self.show_source(self.get(index))
Guido van Rossum439c4671998-10-13 03:59:57 +0000157
Guido van Rossume6fae1c1998-10-15 23:27:08 +0000158 def show_source(self, name):
159 if os.path.isfile(self.classinfo.file):
160 edit = self.flist.open(self.classinfo.file)
161 edit.gotoline(self.classinfo.methods[name])