1# PyDia Self Documentation Series - Part II : Object Types 2# Copyright (c) 2003, Hans Breuer <hans@breuer.org> 3# 4# generates a new diagram which contains all the currently 5# registered object types sorted by their containing package 6# 7 8# This program is free software; you can redistribute it and/or modify 9# it under the terms of the GNU General Public License as published by 10# the Free Software Foundation; either version 2 of the License, or 11# (at your option) any later version. 12# 13# This program is distributed in the hope that it will be useful, 14# but WITHOUT ANY WARRANTY; without even the implied warranty of 15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16# GNU General Public License for more details. 17# 18# You should have received a copy of the GNU General Public License 19# along with this program; if not, write to the Free Software 20# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 22import sys, dia, string 23 24def _log(s, append=1) : 25 pass 26 if append : 27 mode = "a" 28 else : 29 mode = "w" 30 f = open("c:\\temp\\otypes.log", mode) 31 f.write(s) 32 33def otypes_cb(data, flags) : 34 35 if data : 36 diagram = None # we may be running w/o GUI 37 else : 38 diagram = dia.new("Object Types.dia") 39 data = diagram.data 40 layer = data.active_layer 41 42 otypes = dia.registered_types() 43 keys = otypes.keys() 44 keys.sort() 45 46 # property keys w/o overlap 47 object_props = ["obj_pos", "obj_bb", "meta"] 48 element_props = ["elem_corner", "elem_width", "elem_height"] 49 orthconn_props = ["orth_points", "orth_orient", "orth_autoroute"] 50 shape_props = ["flip_horizontal", "flip_vertical"] 51 # the following are not exclusuve to any objects type 52 line_props = ["line_width", "line_style", "line_colour"] 53 fill_props = ["fill_colour", "show_background"] 54 text_props = ["text_colour", "text_font", "text_height", "text"] # "text_alignment", "text_pos" 55 56 packages = {} 57 for s in keys : 58 kt = string.split(s, " - ") 59 if len(kt) == 2 : 60 if len(kt[0]) == 0 : 61 sp = "<unnamed>" 62 else : 63 sp = kt[0] 64 st = kt[1] 65 else : 66 sp = "<broken>" 67 st = kt[0] 68 if packages.has_key(sp) : 69 packages[sp].append(st) 70 else : 71 packages[sp] = [st] 72 73 dtp = dia.get_object_type("UML - LargePackage") 74 dtc = dia.get_object_type("UML - Class") 75 cy = 0 76 maxy = 0 77 maxx = 0 78 79 for sp in packages.keys() : 80 pkg = packages[sp] 81 op, h1, h2 = dtp.create(0.0, cy + 1.0) 82 op.properties["name"] = sp 83 layer.add_object(op) 84 cx = 0 85 for st in pkg : 86 if st == "Group" : 87 continue # too special to handle 88 oc, h3, h4 = dtc.create(cx + 1.0, cy + 4.0) 89 oc.properties["name"] = st 90 attrs = [] 91 # we detect inheritance by common props 92 n_object = 0 93 n_element = 0 94 n_orthconn = 0 95 n_shape = 0 96 n_line = 0 97 n_fill = 0 98 n_text = 0 99 if otypes.has_key(st) : 100 o_real, h5, h6 = dia.get_object_type(st).create(0,0) 101 elif otypes.has_key(sp + " - " + st) : 102 o_real, h5, h6 = dia.get_object_type(sp + " - " + st).create(0,0) 103 else : 104 o_real = None 105 print "Failed to create object", sp, st 106 formal_params = [] 107 if not o_real is None : 108 for p in o_real.properties.keys() : 109 if p in object_props : n_object = n_object + 1 110 elif p in orthconn_props : n_orthconn = n_orthconn + 1 111 elif p in element_props : n_element = n_element + 1 112 elif p in shape_props : n_shape = n_shape + 1 113 elif p in line_props : n_line = n_line + 1 114 elif p in text_props : n_text = n_text + 1 115 elif p in fill_props : n_fill = n_fill + 1 116 else : # don't replicate common props 117 attrs.append((p, o_real.properties[p].type, '', '', 0, 0, 0)) 118 if n_line == len(line_props) : 119 formal_params.append(('Line', '')) 120 else : # need to add the incomplete set 121 for pp in line_props : 122 if o_real.properties.has_key(pp) : 123 attrs.append((pp, o_real.properties[pp].type, '', '', 0, 0, 0)) 124 if n_fill == len(fill_props) : 125 formal_params.append(('Fill', '')) 126 else : 127 for pp in fill_props : 128 if o_real.properties.has_key(pp) : 129 attrs.append((pp, o_real.properties[pp].type, '', '', 0, 0, 0)) 130 if n_text == len(text_props) : 131 formal_params.append(('Text', '')) 132 else : 133 for pp in text_props : 134 if o_real.properties.has_key(pp) : 135 attrs.append((pp, o_real.properties[pp].type, '', '', 0, 0, 0)) 136 if n_orthconn == len(orthconn_props) : 137 oc.properties["stereotype"] = "OrthConn" 138 oc.properties["fill_colour"] = "light blue" 139 elif n_shape == len(shape_props) : 140 oc.properties["stereotype"] = "Shape" 141 oc.properties["fill_colour"] = "light cyan" 142 elif n_element == len(element_props) : 143 oc.properties["stereotype"] = "Element" 144 oc.properties["fill_colour"] = "light yellow" 145 elif n_object == len(object_props) : 146 oc.properties["stereotype"] = "Object" 147 else : 148 print "Huh?", st 149 oc.properties["fill_colour"] = "red" 150 oc.properties["attributes"] = attrs 151 if len(formal_params) > 0 : 152 oc.properties["template"] = 1 153 oc.properties["templates"] = formal_params 154 layer.add_object(oc) 155 # XXX: there really should be a way to safely delete an object. This one will crash: 156 # - when the object got added somewhere 157 # - any object method gets called afterwards 158 if not o_real is None : 159 o_real.destroy() 160 del o_real 161 cx = oc.bounding_box.right 162 if maxy < oc.bounding_box.bottom : 163 maxy = oc.bounding_box.bottom 164 if maxx < cx : 165 maxx = cx 166 # wrapping too long lines 167 if cx > 300 : 168 cx = 0 169 cy = maxy 170 h = op.handles[7] 171 # adjust the package size to fit the objects 172 op.move_handle(h,(maxx + 1.0, maxy + 1.0), 0, 0) 173 cy = maxy + 2.0 174 maxx = 0 # every package a new size 175 data.update_extents() 176 if diagram : 177 diagram.display() 178 diagram.flush() 179 # make it work standalone 180 return data 181 182dia.register_action ("HelpOtypes", "Dia Object Types", 183 "/ToolboxMenu/Help/HelpExtensionStart", 184 otypes_cb) 185