PyXR

c:\python24\lib \ idlelib \ ClassBrowser.py



0001 """Class browser.
0002 
0003 XXX TO DO:
0004 
0005 - reparse when source changed (maybe just a button would be OK?)
0006     (or recheck on window popup)
0007 - add popup menu with more options (e.g. doc strings, base classes, imports)
0008 - show function argument list? (have to do pattern matching on source)
0009 - should the classes and methods lists also be in the module's menu bar?
0010 - add base classes to class browser tree
0011 """
0012 
0013 import os
0014 import sys
0015 import pyclbr
0016 
0017 import PyShell
0018 from WindowList import ListedToplevel
0019 from TreeWidget import TreeNode, TreeItem, ScrolledCanvas
0020 from configHandler import idleConf
0021 
0022 class ClassBrowser:
0023 
0024     def __init__(self, flist, name, path):
0025         # XXX This API should change, if the file doesn't end in ".py"
0026         # XXX the code here is bogus!
0027         self.name = name
0028         self.file = os.path.join(path[0], self.name + ".py")
0029         self.init(flist)
0030 
0031     def close(self, event=None):
0032         self.top.destroy()
0033         self.node.destroy()
0034 
0035     def init(self, flist):
0036         self.flist = flist
0037         # reset pyclbr
0038         pyclbr._modules.clear()
0039         # create top
0040         self.top = top = ListedToplevel(flist.root)
0041         top.protocol("WM_DELETE_WINDOW", self.close)
0042         top.bind("<Escape>", self.close)
0043         self.settitle()
0044         top.focus_set()
0045         # create scrolled canvas
0046         theme = idleConf.GetOption('main','Theme','name')
0047         background = idleConf.GetHighlight(theme, 'normal')['background']
0048         sc = ScrolledCanvas(top, bg=background, highlightthickness=0, takefocus=1)
0049         sc.frame.pack(expand=1, fill="both")
0050         item = self.rootnode()
0051         self.node = node = TreeNode(sc.canvas, None, item)
0052         node.update()
0053         node.expand()
0054 
0055     def settitle(self):
0056         self.top.wm_title("Class Browser - " + self.name)
0057         self.top.wm_iconname("Class Browser")
0058 
0059     def rootnode(self):
0060         return ModuleBrowserTreeItem(self.file)
0061 
0062 class ModuleBrowserTreeItem(TreeItem):
0063 
0064     def __init__(self, file):
0065         self.file = file
0066 
0067     def GetText(self):
0068         return os.path.basename(self.file)
0069 
0070     def GetIconName(self):
0071         return "python"
0072 
0073     def GetSubList(self):
0074         sublist = []
0075         for name in self.listclasses():
0076             item = ClassBrowserTreeItem(name, self.classes, self.file)
0077             sublist.append(item)
0078         return sublist
0079 
0080     def OnDoubleClick(self):
0081         if os.path.normcase(self.file[-3:]) != ".py":
0082             return
0083         if not os.path.exists(self.file):
0084             return
0085         PyShell.flist.open(self.file)
0086 
0087     def IsExpandable(self):
0088         return os.path.normcase(self.file[-3:]) == ".py"
0089 
0090     def listclasses(self):
0091         dir, file = os.path.split(self.file)
0092         name, ext = os.path.splitext(file)
0093         if os.path.normcase(ext) != ".py":
0094             return []
0095         try:
0096             dict = pyclbr.readmodule_ex(name, [dir] + sys.path)
0097         except ImportError, msg:
0098             return []
0099         items = []
0100         self.classes = {}
0101         for key, cl in dict.items():
0102             if cl.module == name:
0103                 s = key
0104                 if hasattr(cl, 'super') and cl.super:
0105                     supers = []
0106                     for sup in cl.super:
0107                         if type(sup) is type(''):
0108                             sname = sup
0109                         else:
0110                             sname = sup.name
0111                             if sup.module != cl.module:
0112                                 sname = "%s.%s" % (sup.module, sname)
0113                         supers.append(sname)
0114                     s = s + "(%s)" % ", ".join(supers)
0115                 items.append((cl.lineno, s))
0116                 self.classes[s] = cl
0117         items.sort()
0118         list = []
0119         for item, s in items:
0120             list.append(s)
0121         return list
0122 
0123 class ClassBrowserTreeItem(TreeItem):
0124 
0125     def __init__(self, name, classes, file):
0126         self.name = name
0127         self.classes = classes
0128         self.file = file
0129         try:
0130             self.cl = self.classes[self.name]
0131         except (IndexError, KeyError):
0132             self.cl = None
0133         self.isfunction = isinstance(self.cl, pyclbr.Function)
0134 
0135     def GetText(self):
0136         if self.isfunction:
0137             return "def " + self.name + "(...)"
0138         else:
0139             return "class " + self.name
0140 
0141     def GetIconName(self):
0142         if self.isfunction:
0143             return "python"
0144         else:
0145             return "folder"
0146 
0147     def IsExpandable(self):
0148         if self.cl:
0149             try:
0150                 return not not self.cl.methods
0151             except AttributeError:
0152                 return False
0153 
0154     def GetSubList(self):
0155         if not self.cl:
0156             return []
0157         sublist = []
0158         for name in self.listmethods():
0159             item = MethodBrowserTreeItem(name, self.cl, self.file)
0160             sublist.append(item)
0161         return sublist
0162 
0163     def OnDoubleClick(self):
0164         if not os.path.exists(self.file):
0165             return
0166         edit = PyShell.flist.open(self.file)
0167         if hasattr(self.cl, 'lineno'):
0168             lineno = self.cl.lineno
0169             edit.gotoline(lineno)
0170 
0171     def listmethods(self):
0172         if not self.cl:
0173             return []
0174         items = []
0175         for name, lineno in self.cl.methods.items():
0176             items.append((lineno, name))
0177         items.sort()
0178         list = []
0179         for item, name in items:
0180             list.append(name)
0181         return list
0182 
0183 class MethodBrowserTreeItem(TreeItem):
0184 
0185     def __init__(self, name, cl, file):
0186         self.name = name
0187         self.cl = cl
0188         self.file = file
0189 
0190     def GetText(self):
0191         return "def " + self.name + "(...)"
0192 
0193     def GetIconName(self):
0194         return "python" # XXX
0195 
0196     def IsExpandable(self):
0197         return 0
0198 
0199     def OnDoubleClick(self):
0200         if not os.path.exists(self.file):
0201             return
0202         edit = PyShell.flist.open(self.file)
0203         edit.gotoline(self.cl.methods[self.name])
0204 
0205 def main():
0206     try:
0207         file = __file__
0208     except NameError:
0209         file = sys.argv[0]
0210         if sys.argv[1:]:
0211             file = sys.argv[1]
0212         else:
0213             file = sys.argv[0]
0214     dir, file = os.path.split(file)
0215     name = os.path.splitext(file)[0]
0216     ClassBrowser(PyShell.flist, name, [dir])
0217     if sys.stdin is sys.__stdin__:
0218         mainloop()
0219 
0220 if __name__ == "__main__":
0221     main()
0222 

Generated by PyXR 0.9.4
SourceForge.net Logo