• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /macosx-10.10/pyobjc-45/2.6/pyobjc/pyobjc-framework-Cocoa/Examples/AppKit/ClassBrowser/
1"""ClassBrowser.py -- A simple class browser, demonstrating the use of an NSBrowser.
2
3To build the demo program, run this line in Terminal.app:
4
5    $ python setup.py py2app -A
6
7This creates a directory "dist" containing ClassBrowser.app. (The
8-A option causes the files to be symlinked to the .app bundle instead
9of copied. This means you don't have to rebuild the app if you edit the
10sources or nibs.)
11
12See also the iClass demo.
13"""
14
15from PyObjCTools import AppHelper
16from objc import getClassList, objc_object
17from Foundation import *
18
19
20try:
21    import AddressBook
22except ImportError:
23    pass
24
25try:
26    import PreferencePanes
27except ImportError:
28    pass
29
30try:
31    import InterfaceBuilder
32except ImportError:
33    pass
34
35def _sortClasses(classList):
36    classes = [(cls.__name__, cls) for cls in classList]
37    classes.sort()
38    return [cls for name, cls in classes]
39
40
41class ClassBrowserDelegate (NSObject):
42    browser = objc.IBOutlet()
43    pathLabel = objc.IBOutlet()
44    table = objc.IBOutlet()
45
46    selectedClassMethods = None
47
48    def awakeFromNib(self):
49        classes = getClassList()
50        rootClasses = []
51        for cls in classes:
52            if cls.__base__ == objc_object:
53                rootClasses.append(cls)
54        rootClasses = _sortClasses(rootClasses)
55        self.columns = [rootClasses]
56        self.browser.setMaxVisibleColumns_(7)
57        self.browser.setMinColumnWidth_(150)
58        self.selectedClass = None
59        self.selectedClassMethods = None
60
61    def browser_willDisplayCell_atRow_column_(self, browser, cell, row, col):
62        cell.setLeaf_(not self.columns[col][row].__subclasses__())
63        cell.setStringValue_(self.columns[col][row].__name__)
64
65    def browser_numberOfRowsInColumn_(self, browser, col):
66        if col == 0:
67            return len(self.columns[0])
68        del self.columns[col:]
69        cls = self.columns[col - 1][browser.selectedRowInColumn_(col - 1)]
70        subclasses = _sortClasses(cls.__subclasses__())
71        self.columns.append(subclasses)
72        return len(subclasses)
73
74    @objc.IBAction
75    def browserAction_(self, browser):
76        self.pathLabel.setStringValue_(browser.path())
77
78        self.selectedClass = None
79        self.selectedClassMethods = None
80        col = len(self.columns)
81        row = -1
82        while row == -1:
83            col -= 1
84            if col < 0:
85                break
86            row = self.browser.selectedRowInColumn_(col)
87        if row >= 0:
88            self.selectedClass = self.columns[col][row]
89            # Classes get initialized lazily, upon the first attribute access,
90            # only after that cls.__dict__ actually contains the methods.
91            # Do a dummy hasattr() to make sure the class is initialized.
92            hasattr(self.selectedClass, "alloc")
93            self.selectedClassMethods = [
94                '-' + obj.selector for obj in self.selectedClass.pyobjc_instanceMethods.__dict__.values()
95                 if hasattr(obj, "selector")
96            ]
97            self.selectedClassMethods += [
98                '+' + obj.selector for obj in self.selectedClass.pyobjc_classMethods.__dict__.values()
99                if hasattr(obj, "selector")
100            ]
101            self.selectedClassMethods.sort()
102
103        self.table.reloadData()
104
105    # table view delegate methods
106    def numberOfRowsInTableView_(self, tableView):
107        if self.selectedClassMethods is None:
108            return 0
109        return len(self.selectedClassMethods)
110
111    def tableView_objectValueForTableColumn_row_(self, tableView, col, row):
112        return str(self.selectedClassMethods[row])
113
114    def tableView_shouldEditTableColumn_row_(self, tableView, col, row):
115        return 0
116
117if __name__ == "__main__":
118    AppHelper.runEventLoop()
119