root/gaphor/tags/gaphor-0.7.0/utils/gbrowseUML.py

Revision 165, 5.5 kB (checked in by arjanmol, 6 years ago)

*** empty log message ***

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
Line 
1 #!/usr/bin/env python
2 '''This application shows a nice tree view of the UML meta model.
3
4 Somehow, this peace of code seems to crash by X server. I thinnk it's a bug in
5 GTK+. ... but how do I isolate the bug?
6 '''
7
8 import sys
9 sys.path.append("..")
10
11 from gaphor.UML import *
12 import gtk
13 import gobject
14 import types
15
16
17 # to create a new GtkTreeModel from python, you must derive from
18 # GenericTreeModel.
19 class TreeModel(gtk.GenericTreeModel):
20     ''' The node is defined by a "name" tuple. '''
21
22     def __init__(self, klass):
23         '''constructor for the model.  Make sure you call
24         PyTreeModel.__init__'''
25         self.iter = None # Value used to keep track of iterations.
26         self.klass = klass;
27        
28         gtk.GenericTreeModel.__init__(self)
29
30     def class_from_node(self, node):
31         klass = self.klass
32         for n in node:
33             attrdef = klass._attrdef[n]
34             klass = attrdef[1]
35         return klass
36
37     # the implementations for TreeModel methods are prefixed with on_
38     def on_get_flags(self):
39         '''returns the GtkTreeModelFlags for this particular type of model'''
40         return 0
41
42     def on_get_n_columns(self):
43         '''returns the number of columns in the model'''
44         return 1
45
46     def on_get_column_type(self, index):
47         '''returns the type of a column in the model'''
48         return gobject.TYPE_STRING
49
50     def on_get_path(self, node):
51         '''returns the tree path (a tuple of indices at the various
52         levels) for a particular node.'''
53         print "on_get_path", node
54         return node
55
56     def on_get_iter(self, path):
57         '''returns the node corresponding to the given path. The patch is a
58            tuple of values, like (0 1 1). We have to figure out a path that is
59            easy to use by on_get_value() and can also be easely extended by
60            on_iter_children() and chopped by on_iter_parent()'''
61         def get_iter(klass, path):
62             item = klass._attrdef.items()[path[0]]
63             if len(path) == 1:
64                 return (item[0],)
65             else:
66                 subklass = klass._attrdef.items()[path[0]][1][1]
67                 return (item[0],) + get_iter(subklass, path[1:])
68        
69         node = get_iter(self.klass, path)
70        
71         #print "on_get_iter", path, node
72         return node
73
74     def on_get_value(self, node, column):
75         '''returns the value stored in a particular column for the node'''
76         assert column == 0
77         attr = node[-1]
78         parent = self.class_from_node(node[:-1])
79         attrdef = parent._attrdef[attr]
80         #print "on_get_value", node, attrdef
81         closing = ")"
82         if attrdef[0] == Sequence:
83             closing = "*)"
84            
85         if len(attrdef) == 3:
86             return attr + " (" + attrdef[1].__name__ + "::" + attrdef[2] + closing
87         else:
88             return attr + " (" + attrdef[1].__name__ + closing
89
90     def on_iter_next(self, node):
91         '''returns the next node at this level of the tree'''
92         attr = node[-1]
93         parent = self.class_from_node(node[:-1])
94         attrdef = parent._attrdef[attr]
95         items = parent._attrdef.items()
96         sentinel = 0
97         for i in items:
98             if sentinel:
99                 node = node[:-1] + (i[0],)
100                 #print "on_iter_next", node
101                 return node
102             elif i[0] == attr:
103                 sentinel = 1 # Use next item
104         #print "on_iter_next (None)"
105         return None
106
107     def on_iter_children(self, node):
108         '''returns the first child of this node'''
109         klass = self.class_from_node(node)
110         if klass.__dict__.has_key("_attrdef"):
111             item = klass._attrdef.items()[0][0]
112             #print "on_iter_children", node, item
113             return node + (item,)
114         else:
115             #print "on_iter_children (None)"
116             return None
117
118     def on_iter_has_child(self, node):
119         '''returns true if this node has children'''
120         #return 0
121         klass = self.class_from_node(node)
122         #print "on_iter_has_child", node
123         return klass.__dict__.has_key("_attrdef") and len(klass._attrdef) > 0
124
125     def on_iter_n_children(self, node):
126         '''returns the number of children of this node'''
127         klass = self.class_from_node(node)
128         if klass.__dict__.has_key("_attrdef"):
129             items = klass._attrdef.items()
130             #print "on_iter_n_children", len(items)
131             return len(items) - 1
132         else:
133             #print "on_iter_n_children (None)"
134             return 0
135
136     def on_iter_nth_child(self, node, n):
137         '''returns the nth child of this node'''
138         #print "on_iter_nth_child"
139         if node == None:
140             #print 'result =', n, self.klass._attrdef.items()[0][0]
141             return (self.klass._attrdef.items()[0][0],)
142         klass = self.class_from_node(node)
143         if klass.__dict__.has_key("_attrdef") and len(node) >= n:
144             item = klass._attrdef.items()[n][0]
145             #print "on_iter_nth_child", node, klass.__name__, item
146             #print 'result =', n, node, item
147             return node + (item,)
148         else:
149             #print 'result =', n, None
150             return None
151
152     def on_iter_parent(self, node):
153         '''returns the parent of this node'''
154         #print "on_iter_parent", node
155         return node[:-1]
156
157 def main():
158     args = sys.argv[1:]
159    
160     base_class = None
161     try:
162         base_class = eval(args[0])
163     except NameError:
164         print "Invalid class name (" + args[0] + ")"
165         sys.exit(1)
166     except IndexError:
167         print "Use gbrowseUML.py <class>, now using class ModelElement"
168         base_class = ModelElement
169
170     window = gtk.Window()
171     window.connect('destroy', lambda win: gtk.main_quit())
172     window.set_title('gbrowseUML -- ' + base_class.__name__)
173     window.set_default_size(250, 400)
174
175     scrolled_window = gtk.ScrolledWindow()
176     scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
177     window.add(scrolled_window)
178
179     model = TreeModel(base_class)
180     tree_view = gtk.TreeView(model)
181     cell = gtk.CellRendererText()
182     # the text in the column comes from column 0
183     column = gtk.TreeViewColumn(base_class.__name__, cell, text=0)
184     tree_view.append_column(column)
185
186     scrolled_window.add(tree_view)
187     window.show_all()
188
189     gtk.main()
190
191 if __name__ == '__main__':
192     main()
193 else:
194     del main
Note: See TracBrowser for help on using the browser.