Changeset 101
- Timestamp:
- 07/02/02 02:15:32 (6 years ago)
- Files:
-
- trunk/gaphor/ChangeLog (modified) (1 diff)
- trunk/gaphor/doc/gaphor.dtd (modified) (1 diff)
- trunk/gaphor/doc/model.txt (modified) (1 diff)
- trunk/gaphor/gaphor/Makefile.am (modified) (1 diff)
- trunk/gaphor/gaphor/UML/Makefile.am (modified) (1 diff)
- trunk/gaphor/gaphor/UML/diagram.py (modified) (1 diff)
- trunk/gaphor/gaphor/UML/element.py (modified) (12 diffs)
- trunk/gaphor/gaphor/UML/elementfactory.py (modified) (4 diffs)
- trunk/gaphor/gaphor/UML/sequence.py (modified) (6 diffs)
- trunk/gaphor/gaphor/diagram/__init__.py (modified) (1 diff)
- trunk/gaphor/gaphor/diagram/actor.py (modified) (1 diff)
- trunk/gaphor/gaphor/diagram/comment.py (modified) (1 diff)
- trunk/gaphor/gaphor/diagram/commentline.py (modified) (1 diff)
- trunk/gaphor/gaphor/diagram/dependency.py (added)
- trunk/gaphor/gaphor/diagram/diagramitem.py (added)
- trunk/gaphor/gaphor/diagram/diagramitemfactory.py (modified) (1 diff)
- trunk/gaphor/gaphor/diagram/modelelement.py (modified) (6 diffs)
- trunk/gaphor/gaphor/diagram/relationship.py (added)
- trunk/gaphor/gaphor/diagram/usecase.py (modified) (3 diffs)
- trunk/gaphor/gaphor/misc/Makefile.am (modified) (1 diff)
- trunk/gaphor/gaphor/misc/__init__.py (modified) (1 diff)
- trunk/gaphor/gaphor/misc/gaphorerror.py (added)
- trunk/gaphor/gaphor/misc/signal.py (modified) (3 diffs)
- trunk/gaphor/gaphor/misc/storage.py (modified) (1 diff)
- trunk/gaphor/gaphor/misc/storage_libxml2.py (added)
- trunk/gaphor/gaphor/misc/storage_minidom.py (added)
- trunk/gaphor/gaphor/test-diagram.py (modified) (1 diff)
- trunk/gaphor/gaphor/tree/namespace.py (modified) (3 diffs)
- trunk/gaphor/gaphor/ui/Makefile.am (modified) (1 diff)
- trunk/gaphor/gaphor/ui/diagramview.py (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/gaphor/ChangeLog
r96 r101 1 2002-07-02 Arjan Molenaar <arjanmolenaar@hetnet.nl> 2 3 * doc/gaphor.dtd: Allow text data in Value tag. 4 * gaphor/UML/element.py: Restructured get/set attr stuff. Now it is 5 more readable and better usable for e.g. tree models. 6 * gaphor/UML/element.py: Changed signal protocol. Now old and new 7 values are also parameters. 8 * gaphor/diagram/(relationship.py|diagramitem.py|dependency.py): 9 new files. 10 * gaphor/misc/signal.py: Added signal queueing options (queue(), 11 flush()) 12 * gaphor/misc: Added parsers using both libxml2 or xml.dom.minidom. 13 (work in progress). 14 15 2002-03-28 Arjan Molenaar <arjanmolenaar@hetnet.nl> 16 17 * gaphor/misc/storage.py: Now use the standard Python XML stuff 18 (with expat). 19 * Various feature improvements and other nifty things... 20 1 21 2002-03-25 Arjan Molenaar <arjanmolenaar@hetnet.nl> 2 22 trunk/gaphor/doc/gaphor.dtd
r91 r101 14 14 refid IDREF #REQUIRED > 15 15 16 <!ELEMENT Value EMPTY>16 <!ELEMENT Value (#PCDATA) > 17 17 <!ATTLIST Value 18 18 name CDATA #REQUIRED 19 value CDATA # REQUIRED >19 value CDATA #IMPLIED > 20 20 21 21 <!ELEMENT Canvas (Value | CanvasItem)* > trunk/gaphor/doc/model.txt
r6 r101 15 15 but we should check the object that is added to the list for its type. 16 16 17 18 Signals 19 ~~~~~~~ 20 UML elements should emit signals if their state changes. This can be done 21 by means of the misc.signal.Signal class. All what's left is to define a 22 protocol (the arguments that the UML element supplies). 23 24 The following cases can occur: 25 1. Unidirectional relationships or attributes: 26 a. Set data 27 b. Set data and overwrite old data 28 c. Remove the attribute 29 2. Bidirectional relationships 30 a. multiplicity of '1' 31 b. multiplicity of '*' 32 33 For non-sequence attributes we can do something like this 34 35 def signal_handler(attribute_name, old_value, new_value, *custom_args): 36 pass 37 38 where old_value and new_value is None (or the default value) in case no value 39 was set before. 40 41 For sequences we can only add and remove values. We can do this with the 42 same amount of attributes, only old_value will be one of 'add' or 'remove' and 43 new_value will contain the value that is added or removed. 44 45 46 trunk/gaphor/gaphor/Makefile.am
r57 r101 1 2 SUBDIRS = UML diagram tree ui misc3 1 4 2 gaphordir = $(pythondir)/$(subdir) 5 3 6 gaphor_PYTHON = gaphor.py 4 gaphor_PYTHON = gaphor.py test-diagram.py 7 5 8 EXTRA_DIST = test-diagram.py test-load.py9 trunk/gaphor/gaphor/UML/Makefile.am
r57 r101 11 11 element.py \ 12 12 elementfactory.py \ 13 modelelements.py 13 modelelements.py \ 14 diagram.py 14 15 15 16 all-local: modelelements.py trunk/gaphor/gaphor/UML/diagram.py
r100 r101 87 87 canvas_store = store.canvas() 88 88 for name, value in canvas_store.values().items(): 89 print 'Diagram: loading attribute', name 89 90 if name == 'root_affine': 90 91 self.canvas.root.set_property('affine', eval(value)) 91 92 else: 92 self.canvas.set_property (name, eval(value)) 93 print 'value = "%s"' % value 94 v = eval(value) 95 self.canvas.set_property (name, v) 93 96 94 97 item_dict = canvas_store.canvas_items() trunk/gaphor/gaphor/UML/element.py
r93 r101 30 30 import types, copy 31 31 from enumeration import Enumeration_ 32 from sequence import Sequence 32 from sequence import Sequence, SequenceError 33 33 #from misc import Signal 34 34 from misc.signal import Signal … … 80 80 # del elements[self.__dict__['__id']] 81 81 #print 'Element.__unlink()', self 82 self.__emit("__unlink__" )82 self.__emit("__unlink__", None, None) 83 83 for key in self.__dict__.keys(): 84 84 # In case of a cyclic reference, we should check if the element … … 103 103 def unlink(self): 104 104 '''Remove all references to the object.''' 105 print 'Element.unlink():', self105 #print 'Element.unlink():', self 106 106 # Notify other objects that we want to unlink() 107 107 self.__unlink () … … 119 119 self.__dict__.has_key('__undodata'): 120 120 self.__load_undo_data() 121 self.__emit('__relink__' )121 self.__emit('__relink__', None, None) 122 122 123 123 def remove_presentation (self, presentation): … … 191 191 return self.__dict__[key] 192 192 193 def get(self, key): 194 if self.__dict__.has_key(key): 195 # Key is already in the object 196 return self.__dict__[key] 197 else: 198 info = self.__get_attr_info (key, self.__class__) 199 if info[0] is Sequence: 200 # We do not have a sequence here... create it and return it. 201 self.__dict__[key] = Sequence(self, info[1]) 202 return self.__dict__[key] 203 else: 204 # Otherwise, return the default value 205 return copy.copy(info[0]) 206 207 def __set(self, key, obj): 208 old_value = None 209 if self.__dict__.has_key(key): 210 old_value = self.__dict__[key] 211 self.__dict__[key] = obj 212 self.__queue(key, old_value, obj) 213 214 def __del(self, key, dummy=None): 215 '''Remove an attribute.''' 216 old_value = None 217 if self.__dict__.has_key(key): 218 old_value = self.__dict__[key] 219 del self.__dict__[key] 220 self.__emit(key, old_value, None) 221 222 def __sequence_add(self, key, obj): 223 if not self.__dict__.has_key(key): 224 info = self.__get_attr_info(key, self.__class__) 225 self.__dict__[key] = Sequence(self, info[1]) 226 seq = self.__dict__[key] 227 self.__real_sequence_add(key, seq, obj) 228 229 def __real_sequence_add(self, key, seq, obj): 230 list = seq.list 231 if list.count(obj) == 0: 232 list.append(obj) 233 list.sort() 234 self.__queue(key, 'add', seq.index(obj)) 235 236 def __sequence_remove(self, key, obj): 237 self.__emit(key, 'remove', obj) 238 self.__dict__[key].list.remove(obj) 239 193 240 def __getattr__(self, key): 194 241 if key == 'id': 195 242 return self.__dict__['__id'] 196 elif self.__dict__.has_key(key):197 # Key is already in the object198 return self.__dict__[key]199 243 else: 200 #if key[0] != '_': 201 #print 'Unknown attr: Element.__getattr__(' + key + ')' 202 rec = self.__get_attr_info (key, self.__class__) 203 if rec[0] is Sequence: 204 # We do not have a sequence here... create it and return it. 205 return self.__ensure_seq (key, rec[1]) 206 else: 207 # Otherwise, return the default value 208 return copy.copy(rec[0]) 244 return self.get(key) 209 245 210 246 def __setattr__(self, key, value): … … 217 253 b. Set up a new relationship between self-value and value-self.''' 218 254 219 rec= self.__get_attr_info (key, self.__class__)255 info = self.__get_attr_info (key, self.__class__) 220 256 #print 'Element:__setattr__(' + key + ')' + str(rec) 221 if len(rec) == 2: # Attribute or one-way relation 222 if rec[0] is Sequence: 223 #print '__setattr__', key, value 224 self.__ensure_seq (key, rec[1]).append(value) 225 else: 226 self.__dict__[key] = value 227 self.__emit (key) 257 if len(info) == 2: # Attribute or one-way relation 258 if info[0] is Sequence: 259 self.__sequence_add(key, value) 260 else: 261 self.__set(key, value) 228 262 else: 229 xrec = value.__get_attr_info (rec[2], value.__class__) 263 xkey = info[2] 264 xinfo = value.__get_attr_info (xkey, value.__class__) 265 230 266 #print '__setattr__x', xrec 231 if len(xrec) > 2: 232 assert xrec[2] == key 233 if self.__dict__.has_key(key): 234 #print 'del old...' 267 if len(xinfo) > 2: 268 assert xinfo[2] == key 269 270 # We have to remove our reference from the current 'other side' 271 if self.__dict__.has_key(key) and info[0] is not Sequence: 235 272 xself = self.__dict__[key] 236 # Keep the relationship if we have a n:m relationship 237 if rec[0] is not Sequence or xrec[0] is not Sequence: 238 if rec[0] is Sequence: 239 #print 'del-seq-item rec' 240 #self.__del_seq_item(self.__dict__[key], xself) 241 if xself in self.__dict__[key].list: 242 self.__dict__[key].list.remove(xself) 243 elif self.__dict__.has_key(key): 244 #print 'del-item rec' 245 del self.__dict__[key] 246 if xrec[0] is Sequence: 247 #print 'del-seq-item xrec' 248 #xself.__del_seq_item(xself.__dict__[rec[2]], self) 249 xself.__dict__[rec[2]].list.remove (self) 250 elif xself.__dict__.has_key(rec[2]): 251 #print 'del-item xrec' 252 del xself.__dict__[rec[2]] 273 if xinfo[0] is Sequence: 274 xself.__sequence_remove(xkey, self) 275 else: 276 xself.__del(xkey) 277 253 278 # Establish the relationship 254 if rec[0] is Sequence:279 if info[0] is Sequence: 255 280 #print 'add to seq' 256 self.__ ensure_seq(key, rec[1]).append (value)281 self.__sequence_add(key, value) 257 282 else: 258 283 #print 'add to item' 259 self.__dict__[key] = value 260 if xrec[0] is Sequence: 284 self.__set(key, value) 285 286 if xinfo[0] is Sequence: 261 287 #print 'add to xseq' 262 value.__ ensure_seq(rec[2], xrec[1]).append (self)288 value.__sequence_add(xkey, self) 263 289 else: 264 290 #print 'add to xitem' 265 value.__dict__[rec[2]] = self 266 self.__emit (key) 267 value.__emit (rec[2]) 268 291 value.__set(xkey, self) 292 self.__flush() 293 269 294 def __delattr__(self, key): 270 rec= self.__get_attr_info (key, self.__class__)271 if rec[0] is Sequence:295 info = self.__get_attr_info (key, self.__class__) 296 if info[0] is Sequence: 272 297 raise AttributeError, 'Element: you can not remove a sequence' 273 298 if not self.__dict__.has_key(key): 274 299 return 275 xval = self.__dict__[key] 276 if len(rec) > 2: # Bi-directional relationship 277 xrec = xval.__get_attr_info (rec[2], rec[1]) 278 if xrec[0] is Sequence: 279 #xval.__del_seq_item(xval.__dict__[rec[2]], self) 280 #xval.__dict__[rec[2]].list.remove (self) 281 # Handle it via sequence_remove() 282 del xval.__dict__[rec[2]][self] 283 else: 284 del xval.__dict__[rec[2]] 285 del self.__dict__[key] 286 self.__emit (key) 287 xval.__emit(rec[2]) 288 else: 289 del self.__dict__[key] 290 self.__emit (key) 300 301 if len(info) > 2: 302 xself = self.__dict__[key] 303 xkey = info[2] 304 xinfo = xself.__get_attr_info (xkey, info[1]) 305 if xinfo[0] is Sequence: 306 xself.__sequence_remove(xkey, self) 307 else: 308 xself.__del(xkey) 309 self.__del(key) 310 self.__flush() 311 312 def sequence_add(self, seq, obj): 313 '''Add an entry. Should only be called by Sequence instances. 314 This function adds an object to the sequence.''' 315 for key in self.__dict__.keys(): 316 if self.__dict__[key] is seq: 317 break 318 self.__real_sequence_add(key, seq, obj) 319 self.__flush() 291 320 292 321 def sequence_remove(self, seq, obj): … … 299 328 #print 'Element.sequence_remove', key 300 329 #seq_len = len (seq) 301 rec= self.__get_attr_info (key, self.__class__)302 if rec[0] is not Sequence:330 info = self.__get_attr_info (key, self.__class__) 331 if info[0] is not Sequence: 303 332 raise AttributeError, 'Element: This should be called from Sequence' 304 333 seq.list.remove(obj) 305 if len( rec) > 2: # Bi-directional relationship306 x rec = obj.__get_attr_info (rec[2], obj.__class__) #rec[1])307 if xrec[0] is Sequence:308 obj.__dict__[rec[2]].list.remove (self)309 else:310 del obj.__dict__[rec[2]]311 obj.__emit (rec[2])312 self.__emit (key)313 #assert len (seq) == seq_len - 1334 if len(info) > 2: 335 xself = obj 336 xkey = info[2] 337 xinfo = xself.__get_attr_info (xkey, info[1]) 338 if xinfo[0] is Sequence: 339 xself.__sequence_remove(xkey, self) 340 else: 341 xself.__del(xkey) 342 self.__flush() 314 343 315 344 # Functions used by the signal functions … … 320 349 self.__dict__['__signal'].disconnect (signal_func) 321 350 322 def __emit (self, key): 323 self.__dict__['__signal'].emit (key) 351 def __queue (self, key, old_value_or_action, new_value): 352 self.__dict__['__signal'].queue (key, old_value_or_action, new_value) 353 354 def __flush (self): 355 self.__dict__['__signal'].flush () 356 357 def __emit (self, key, old_value_or_action, new_value): 358 self.__dict__['__signal'].emit (key, old_value_or_action, new_value) 324 359 325 360 def save(self, store): … … 345 380 if value and value != '': 346 381 self.__dict__[name] = value 347 self.__emit (name )382 self.__emit (name, None, value) 348 383 349 384 for name, reflist in store.references().items(): … … 356 391 if refelem not in self.__dict__[name]: 357 392 self.__dict__[name].list.append (refelem) 358 self.__emit (name )393 self.__emit (name, 'add', refelem) 359 394 else: 360 395 self.__dict__[name] = refelem 361 self.__emit (name )396 self.__emit (name, None, refelem) 362 397 363 398 def postload (self, store): … … 549 584 550 585 del b.seq[a] 551 assert a.ref is None 586 assert a.ref is None, 'a.ref = ' + str(a.ref) 552 587 assert a.seq.list == [ ] 553 588 assert b.ref is b … … 668 703 a.rel = b 669 704 assert z.cb_data[0] == 'rel' 670 assert z.cb_data[1] == 'one' 671 assert z.cb_data[2] == 'two' 705 assert z.cb_data[1] == None # old_value 706 assert z.cb_data[2] == b # new_value 707 assert z.cb_data[3] == 'one' 708 assert z.cb_data[4] == 'two' 672 709 assert y.cb_data[0] == 'rel' 673 assert y.cb_data[1] == 'three' 710 assert y.cb_data[1] == None 711 assert y.cb_data[2] == b 712 assert y.cb_data[3] == 'three' 674 713 675 714 a.disconnect (z.callback) trunk/gaphor/gaphor/UML/elementfactory.py
r93 r101 14 14 class ElementFactory(Singleton): 15 15 16 def __element_signal (self, key, o bj):16 def __element_signal (self, key, old_value, new_value, obj): 17 17 if key == '__unlink__' and self.__elements.has_key(obj.id): 18 18 print 'Unlinking element', obj … … 35 35 obj.connect (self.__element_signal, obj) 36 36 self.__emit_create (obj) 37 print 'ElementFactory:', str(self.__index), 'elements in the factory'37 #print 'ElementFactory:', str(self.__index), 'elements in the factory' 38 38 return obj 39 39 … … 48 48 if old_index > self.__index: 49 49 self.__index = old_index 50 51 50 52 51 def lookup (self, id): … … 65 64 '''Flush all elements in the UML.elements table.''' 66 65 for key, value in self.__elements.items(): 66 print 'ElementFactory: unlinking', value 67 67 value.unlink() 68 assert len(self.__elements) == 0 69 return None70 while 1:71 try:72 (key, value) = self.__elements.popitem()73 except KeyError:74 break;75 value.unlink()76 assert len(self.__elements) == 068 assert len(self.__elements) == 0, 'Still items in the factory: %s' % str(self.__elements.values()) 69 self.__index = 1 70 #while 1: 71 # try: 72 # (key, value) = self.__elements.popitem() 73 # except KeyError: 74 # break; 75 # value.unlink() 76 # assert len(self.__elements) == 0 77 77 78 78 def connect (self, signal_func, *data): trunk/gaphor/gaphor/UML/sequence.py
r84 r101 1 # vim:sw=4 1 2 3 import misc 4 5 class SequenceError(misc.GaphorError): 6 pass 7 2 8 class Sequence: 3 9 '''A Sequence class has the following properties: … … 5 11 - Only accepts object of a certain type (or descendants). 6 12 - Only keep one reference to the object. 7 - A Sequence might have an owner. In that care the owners13 - A Sequence has an owner. The owners 8 14 sequence_{add|remove}() functions are called to allow 9 bi-directional relations to be added and deleted.''' 15 bi-directional relations to be added and deleted. 16 Note that the Sequence itself does not add items to its list, it 17 only invokes the owning object if something needs to be done.''' 18 10 19 def __init__(self, owner, type): 11 20 self.owner = owner 12 self.requ ested_type = type21 self.required_type = type 13 22 self.list = [] 14 23 … … 17 26 18 27 def __setitem__(self, key, value): 19 raise Exception, 'Sequence:items should not be overwritten.'28 raise SequenceError, 'items should not be overwritten.' 20 29 21 30 def __delitem__(self, key): 22 if self.owner: 23 self.owner.sequence_remove(self, key) 24 else: 25 self.list.__delitem__(key) 31 self.remove(key) 26 32 27 33 def __getitem__(self, key): … … 32 38 33 39 def __setslice__(self, i, j, s): 34 raise IndexError, 'Sequence:items should not be overwritten.'40 raise SequenceError, 'items should not be overwritten.' 35 41 36 42 def __delslice__(self, i, j): 37 raise IndexError, 'Sequence:items should not be deleted this way.'43 raise SequenceError, 'items should not be deleted this way.' 38 44 39 45 def __contains__(self, obj): … … 41 47 42 48 def append(self, obj): 43 if isinstance (obj, self.requested_type): 44 if self.list.count (obj) == 0: 45 self.list.append (obj) 46 self.list.sort () 49 if isinstance(obj, self.required_type): 50 self.owner.sequence_add(self, obj) 51 #if self.list.count(obj) == 0: 52 #self.list.append(obj) 53 #self.list.sort() 47 54 else: 48 raise ValueError, 'Sequence._add(obj): Object is not of type ' + \49 str (self.requ ested_type)55 raise SequenceError, 'append(): Object is not of type ' + \ 56 str (self.required_type) 50 57 51 58 def remove(self, key): 52 self. __delitem__(key)59 self.owner.sequence_remove(self, key) 53 60 54 61 def index(self, key): … … 56 63 if self.list[i] is key: 57 64 return i 58 raise ValueError, 'sequence.index(key): key not in list'65 raise SequenceError, 'index(): key %s not in list' % str(key) 59 66 trunk/gaphor/gaphor/diagram/__init__.py
r96 r101 4 4 from commentline import * 5 5 from usecase import * 6 from relationship import * 7 from dependency import * 6 8 7 9 from diagramitemfactory import * trunk/gaphor/gaphor/diagram/actor.py
r100 r101 174 174 return -1 175 175 176 def on_subject_update(self, name ):176 def on_subject_update(self, name, old_value, new_value): 177 177 if name == 'name': 178 178 self.__name.set(text=self.subject.name) 179 179 self.__name_update() 180 180 else: 181 ModelElementItem.on_subject_update(self, name) 182 181 ModelElementItem.on_subject_update(self, name, old_value, new_value) 183 182 def on_text_changed(self, text): 184 183 if text != self.subject.name: trunk/gaphor/gaphor/diagram/comment.py
r100 r101 113 113 return -1 114 114 115 def on_subject_update(self, name ):115 def on_subject_update(self, name, old_value, new_value): 116 116 if name == 'body': 117 117 self.__body.set(text=self.subject.body) 118 118 self.__body_update() 119 119 else: 120 ModelElementItem.on_subject_update(self, name )120 ModelElementItem.on_subject_update(self, name, old_value, new_value) 121 121 122 122 def on_text_changed(self, text): trunk/gaphor/gaphor/diagram/commentline.py
r100 r101 71 71 raise AttributeError, 'Unknown property %s' % pspec.name 72 72 73 def on_glue(self, handle, wx, wy): 74 "No connections are allowed on a CommentLine." 75 return None 76 73 77 def on_connect_handle(self, handle): 74 """No connections are allows to the CommentLine. 75 """ 76 #ret = diacanvas.CanvasLine.on_connect_handle(handle) 78 "No connections are allows to the CommentLine." 77 79 return 0 78 80 79 81 def on_disconnect_handle(self, handle): 80 """No connections are allows to the CommentLine. 81 """ 82 #ret = diacanvas.CanvasLine.on_disconnect_handle(handle) 82 "No connections are allows to the CommentLine." 83 83 return 0 84 84 trunk/gaphor/gaphor/diagram/diagramitemfactory.py
r96 r101 30 30 return obj 31 31 32 def set_next_id(self, id): 33 """ 34 set_next_id() sets the id to use for the next canvas item that will 35 be created. 36 """ 37 if id > self.__index: 38 self.__index = id 39 40 def flush(self): 41 self.__index = 1 42 32 43 def register(self, item_class, uml_class): 33 44 gobject.type_register(item_class) trunk/gaphor/gaphor/diagram/modelelement.py
r99 r101 6 6 ''' 7 7 8 if __name__ == '__main__':9 import sys10 sys.path.append('..')11 del sys12 13 8 import gobject 14 9 import diacanvas 10 from diagramitem import DiagramItem 15 11 16 12 __revision__ = '$revision$' … … 19 15 20 16 21 class ModelElementItem (diacanvas.CanvasElement, diacanvas.CanvasAbstractGroup ):17 class ModelElementItem (diacanvas.CanvasElement, diacanvas.CanvasAbstractGroup, DiagramItem): 22 18 __gproperties__ = { 23 19 'id': (gobject.TYPE_PYOBJECT, 'id', … … 34 30 def __init__(self): 35 31 self.__gobject_init__() 32 DiagramItem.__init__(self) 36 33 self.subject = None 37 34 self.auto_resize = 0 38 35 self.__id = -1 39 self.connect ('notify::parent', ModelElementItem.on_parent_notify)40 36 41 37 def save (self, store): … … 53 49 def postload(self, store): 54 50 pass 51 55 52 def do_set_property (self, pspec, value): 56 53 if pspec.name == 'id': … … 59 56 elif pspec.name == 'subject': 60 57 print 'Setting subject:', value 61 self.preserve_property('subject') 62 if value != self.subject: 63 if self.subject: 64 self.subject.remove_presentation(self) 65 self.subject.disconnect(self.on_subject_update) 66 self.subject = value 67 if value: 68 value.connect(self.on_subject_update) 69 value.add_presentation(self) 70 58 self._set_subject(value) 71 59 elif pspec.name == 'auto-resize': 72 60 self.auto_resize = value … … 86 74 # DiaCanvasItem callbacks 87 75 def on_glue(self, handle, wx, wy): 88 if handle.owner.allow_connect_handle (handle, self): 89 return diacanvas.CanvasElement.on_glue (self, handle, wx, wy) 90 # Dummy value with large distance value 91 return None 76 return self._on_glue(handle, wx, wy, diacanvas.CanvasElement) 92 77 93 78 def on_connect_handle (self, handle): 94 if handle.owner.allow_connect_handle (handle, self): 95 ret = diacanvas.CanvasElement.on_connect_handle (self, handle) 96 if ret != 0: 97 handle.owner.confirm_connect_handle(handle) 98 return ret 99 return 0 79 return self._on_connect_handle(handle, diacanvas.CanvasElement) 100 80 101 81 def on_disconnect_handle (self, handle): 102 if handle.owner.allow_disconnect_handle (handle): 103 ret = diacanvas.CanvasElement.on_disconnect_handle (self, handle) 104 if ret != 0: 105 handle.owner.confirm_disconnect_handle(handle, self) 106 return ret 107 return 0 82 return self._on_disconnect_handle(handle, diacanvas.CanvasElement) 108 83 109 def on_parent_notify (self, parent):110 print self111 if self.subject:112 if self.parent:113 print 'Have Parent', self, parent114 self.subject.add_presentation (self)115 else:116 print 'No parent...', self, parent117 self.subject.remove_presentation (self)118 119 def on_subject_update (self, name):120 if name == '__unlink__':121 #self.set_property('subject', None)122 if self.parent:123 self.parent.remove(self)124 else:125 print 'ModelElementItem: unhandled signal "%s"' % str(name)126 84 127 85 gobject.type_register(ModelElementItem) trunk/gaphor/gaphor/diagram/usecase.py
r100 r101 53 53 self.__name.update_now() 54 54 55 def on_handle_motion (self, handle, wx, wy, mask): 56 retval = ModelElementItem.on_handle_motion(self, handle, wx, wy, mask) 57 self.__name_update() 58 return retval 59 55 60 def on_get_shape_iter(self): 56 61 return self.__border … … 61 66 def on_shape_value(self, iter): 62 67 return iter 63 64 # def on_move(self, x, y):65 # self.__name.request_update()66 # ModelElementItem.on_move(self, x, y)67 68 # def on_handle_motion (self, handle, wx, wy, mask):69 # retval = ModelElementItem.on_handle_motion(self, handle, wx, wy, mask)70 # self.__name_update()71 # return retval72 68 73 69 # Groupable … … 105 101 return -1 106 102 107 def on_subject_update(self, name ):103 def on_subject_update(self, name, old_value, new_value): 108 104 if name == 'name': 109 105 self.__name.set(text=self.subject.name) 110 106 self.__name_update() 111 107 else: 112 ModelElementItem.on_subject_update(self, name )108 ModelElementItem.on_subject_update(self, name, old_value, new_value) 113 109 114 110 def on_text_changed(self, text): trunk/gaphor/gaphor/misc/Makefile.am
r57 r101 5 5 __init__.py \ 6 6 singleton.py \ 7 command.py 7 command.py \ 8 gaphorerror.py \ 9 signal.py \ 10 storage-libxml2.py \ 11 storage-minidom.py \ 12 storage.py 8 13 9 14 CLEANFILES = *.pyc *.pyo trunk/gaphor/gaphor/misc/__init__.py
r92 r101 1 1 2 2 __all__ = [ 'singleton', 'command', 'signal', 'storage' ] 3 #from singleton import * 4 #from command import * 5 #from signal import * 6 #from storage import * 3 4 from gaphorerror import GaphorError 5 trunk/gaphor/gaphor/misc/signal.py
r99 r101 19 19 # Signals are stored in a list as [ (signal_func, (data)), <next sig> ] 20 20 self.__signals = [ ] 21 self.__queue = [ ] 21 22 22 23 def connect (self, signal_handler, *data): … … 35 36 self.__signals) 36 37 38 def queue (self, *keys): 39 """ 40 Queue signals for emision. This is handy in case several parameters 41 have to be set before an object is in a consistent state. Queued signals 42 will be emited as soon as flush() is called. 43 """ 44 self.__queue.append(keys) 45 46 def flush (self): 47 """ 48 Flush the signal queue. 49 """ 50 queue = self.__queue 51 self.__queue = [ ] 52 53 for keys in queue: 54 self.emit(*keys) 55 37 56 def emit (self, *keys): 38 57 """ … … 40 59 passed to the signal handler. Those parameters will be set before 41 60 the parameters provided through the connect() method. 61 In case there are queued emisions, this function will queue the 62 signal emision too. 42 63 43 64 Note that you should define how many parameters are provided by the 44 65 owner of the signal. 45 66 """ 46 #print 'Signal.emit():', self.__signals 47 for signal in self.__signals: 48 signal_handler = signal[0] 49 data = keys + signal[1:] 50 #print 'signal:', signal_handler, data 51 signal_handler (*data) 67 #print 'Signal.emit():', keys 68 if len(self.__queue) > 0: 69 self.queue(*keys) 70 else: 71 for signal in self.__signals: 72 signal_handler = signal[0] 73 data = keys + signal[1:] 74 #print 'signal:', signal_
