Changeset 101

Show
Ignore:
Timestamp:
07/02/02 02:15:32 (6 years ago)
Author:
arjanmol
Message:

*** empty log message ***

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/gaphor/ChangeLog

    r96 r101  
     12002-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 
     152002-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 
    1212002-03-25  Arjan Molenaar  <arjanmolenaar@hetnet.nl> 
    222 
  • trunk/gaphor/doc/gaphor.dtd

    r91 r101  
    1414    refid       IDREF   #REQUIRED > 
    1515 
    16 <!ELEMENT Value EMPTY
     16<!ELEMENT Value (#PCDATA)
    1717<!ATTLIST Value 
    1818    name        CDATA   #REQUIRED 
    19     value       CDATA   #REQUIRED > 
     19    value       CDATA   #IMPLIED > 
    2020 
    2121<!ELEMENT Canvas (Value | CanvasItem)* > 
  • trunk/gaphor/doc/model.txt

    r6 r101  
    1515but we should check the object that is added to the list for its type.  
    1616 
     17 
     18Signals 
     19~~~~~~~ 
     20UML elements should emit signals if their state changes. This can be done 
     21by means of the misc.signal.Signal class. All what's left is to define a 
     22protocol (the arguments that the UML element supplies). 
     23 
     24The following cases can occur: 
     251. Unidirectional relationships or attributes: 
     26   a. Set data 
     27   b. Set data and overwrite old data 
     28   c. Remove the attribute 
     292. Bidirectional relationships 
     30   a. multiplicity of '1' 
     31   b. multiplicity of '*' 
     32 
     33For 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 
     38where old_value and new_value is None (or the default value) in case no value 
     39was set before. 
     40 
     41For sequences we can only add and remove values. We can do this with the 
     42same amount of attributes, only old_value will be one of 'add' or 'remove' and 
     43new_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 misc 
    31 
    42gaphordir = $(pythondir)/$(subdir) 
    53 
    6 gaphor_PYTHON = gaphor.py 
     4gaphor_PYTHON = gaphor.py test-diagram.py 
    75 
    8 EXTRA_DIST = test-diagram.py test-load.py 
    9  
  • trunk/gaphor/gaphor/UML/Makefile.am

    r57 r101  
    1111        element.py      \ 
    1212        elementfactory.py \ 
    13         modelelements.py 
     13        modelelements.py \ 
     14        diagram.py 
    1415 
    1516all-local: modelelements.py 
  • trunk/gaphor/gaphor/UML/diagram.py

    r100 r101  
    8787        canvas_store = store.canvas() 
    8888        for name, value in canvas_store.values().items(): 
     89            print 'Diagram: loading attribute', name 
    8990            if name == 'root_affine': 
    9091                self.canvas.root.set_property('affine', eval(value)) 
    9192            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) 
    9396 
    9497        item_dict = canvas_store.canvas_items() 
  • trunk/gaphor/gaphor/UML/element.py

    r93 r101  
    3030import types, copy 
    3131from enumeration import Enumeration_ 
    32 from sequence import Sequence 
     32from sequence import Sequence, SequenceError 
    3333#from misc import Signal 
    3434from misc.signal import Signal 
     
    8080        #    del elements[self.__dict__['__id']] 
    8181        #print 'Element.__unlink()', self 
    82         self.__emit("__unlink__"
     82        self.__emit("__unlink__", None, None
    8383        for key in self.__dict__.keys(): 
    8484            # In case of a cyclic reference, we should check if the element 
     
    103103    def unlink(self): 
    104104        '''Remove all references to the object.''' 
    105         print 'Element.unlink():', self 
     105        #print 'Element.unlink():', self 
    106106        # Notify other objects that we want to unlink() 
    107107        self.__unlink () 
     
    119119                        self.__dict__.has_key('__undodata'): 
    120120                self.__load_undo_data() 
    121                 self.__emit('__relink__'
     121                self.__emit('__relink__', None, None
    122122 
    123123    def remove_presentation (self, presentation): 
     
    191191        return self.__dict__[key] 
    192192 
     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 
    193240    def __getattr__(self, key): 
    194241        if key == 'id': 
    195242            return self.__dict__['__id'] 
    196         elif self.__dict__.has_key(key): 
    197             # Key is already in the object 
    198             return self.__dict__[key] 
    199243        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) 
    209245 
    210246    def __setattr__(self, key, value): 
     
    217253           b. Set up a new relationship between self-value and value-self.''' 
    218254 
    219         rec = self.__get_attr_info (key, self.__class__) 
     255        info = self.__get_attr_info (key, self.__class__) 
    220256        #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) 
    228262        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 
    230266            #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: 
    235272                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 
    253278            # Establish the relationship 
    254             if rec[0] is Sequence: 
     279            if info[0] is Sequence: 
    255280                #print 'add to seq' 
    256                 self.__ensure_seq(key, rec[1]).append (value) 
     281                self.__sequence_add(key, value) 
    257282            else: 
    258283                #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: 
    261287                #print 'add to xseq' 
    262                 value.__ensure_seq(rec[2], xrec[1]).append (self) 
     288                value.__sequence_add(xkey, self) 
    263289            else: 
    264290                #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 
    269294    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: 
    272297            raise AttributeError, 'Element: you can not remove a sequence' 
    273298        if not self.__dict__.has_key(key): 
    274299            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() 
    291320 
    292321    def sequence_remove(self, seq, obj): 
     
    299328        #print 'Element.sequence_remove', key 
    300329        #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: 
    303332            raise AttributeError, 'Element: This should be called from Sequence' 
    304333        seq.list.remove(obj) 
    305         if len(rec) > 2: # Bi-directional relationship 
    306             xrec = 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 - 1 
     334        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() 
    314343 
    315344    # Functions used by the signal functions 
     
    320349        self.__dict__['__signal'].disconnect (signal_func) 
    321350 
    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) 
    324359 
    325360    def save(self, store): 
     
    345380                if value and value != '': 
    346381                    self.__dict__[name] = value 
    347             self.__emit (name
     382            self.__emit (name, None, value
    348383         
    349384        for name, reflist in store.references().items(): 
     
    356391                    if refelem not in self.__dict__[name]: 
    357392                        self.__dict__[name].list.append (refelem) 
    358                         self.__emit (name
     393                        self.__emit (name, 'add', refelem
    359394                else: 
    360395                    self.__dict__[name] = refelem 
    361                     self.__emit (name
     396                    self.__emit (name, None, refelem
    362397 
    363398    def postload (self, store): 
     
    549584 
    550585    del b.seq[a] 
    551     assert a.ref is None 
     586    assert a.ref is None, 'a.ref = ' + str(a.ref) 
    552587    assert a.seq.list == [ ] 
    553588    assert b.ref is b 
     
    668703    a.rel = b 
    669704    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' 
    672709    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' 
    674713     
    675714    a.disconnect (z.callback) 
  • trunk/gaphor/gaphor/UML/elementfactory.py

    r93 r101  
    1414class ElementFactory(Singleton): 
    1515 
    16     def __element_signal (self, key, obj): 
     16    def __element_signal (self, key, old_value, new_value, obj): 
    1717        if key == '__unlink__' and self.__elements.has_key(obj.id): 
    1818            print 'Unlinking element', obj 
     
    3535        obj.connect (self.__element_signal, obj) 
    3636        self.__emit_create (obj) 
    37         print 'ElementFactory:', str(self.__index), 'elements in the factory' 
     37        #print 'ElementFactory:', str(self.__index), 'elements in the factory' 
    3838        return obj 
    3939 
     
    4848        if old_index > self.__index: 
    4949            self.__index = old_index 
    50  
    5150 
    5251    def lookup (self, id): 
     
    6564        '''Flush all elements in the UML.elements table.''' 
    6665        for key, value in self.__elements.items(): 
     66            print 'ElementFactory: unlinking', value 
    6767            value.unlink() 
    68         assert len(self.__elements) == 0 
    69         return None 
    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 
     68        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 
    7777 
    7878    def connect (self, signal_func, *data): 
  • trunk/gaphor/gaphor/UML/sequence.py

    r84 r101  
     1# vim:sw=4 
    12 
     3import misc 
     4 
     5class SequenceError(misc.GaphorError): 
     6    pass 
     7         
    28class Sequence: 
    39    '''A Sequence class has the following properties: 
     
    511    - Only accepts object of a certain type (or descendants). 
    612    - Only keep one reference to the object. 
    7     - A Sequence might have an owner. In that care the owners 
     13    - A Sequence has an owner. The owners 
    814      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 
    1019    def __init__(self, owner, type): 
    1120        self.owner = owner 
    12         self.requested_type = type 
     21        self.required_type = type 
    1322        self.list = [] 
    1423 
     
    1726 
    1827    def __setitem__(self, key, value): 
    19         raise Exception, 'Sequence: items should not be overwritten.' 
     28        raise SequenceError, 'items should not be overwritten.' 
    2029 
    2130    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) 
    2632 
    2733    def __getitem__(self, key): 
     
    3238 
    3339    def __setslice__(self, i, j, s): 
    34         raise IndexError, 'Sequence: items should not be overwritten.' 
     40        raise SequenceError, 'items should not be overwritten.' 
    3541 
    3642    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.' 
    3844 
    3945    def __contains__(self, obj): 
     
    4147 
    4248    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() 
    4754        else: 
    48             raise ValueError, 'Sequence._add(obj): Object is not of type ' + \ 
    49                                 str (self.requested_type) 
     55            raise SequenceError, 'append(): Object is not of type ' + \ 
     56                                str (self.required_type) 
    5057 
    5158    def remove(self, key): 
    52         self.__delitem__(key) 
     59        self.owner.sequence_remove(self, key) 
    5360 
    5461    def index(self, key): 
     
    5663            if self.list[i] is key: 
    5764                return i 
    58         raise ValueError, 'sequence.index(key): key not in list' 
     65        raise SequenceError, 'index(): key %s not in list' % str(key) 
    5966     
  • trunk/gaphor/gaphor/diagram/__init__.py

    r96 r101  
    44from commentline import * 
    55from usecase import * 
     6from relationship import * 
     7from dependency import * 
    68 
    79from diagramitemfactory import * 
  • trunk/gaphor/gaphor/diagram/actor.py

    r100 r101  
    174174            return -1 
    175175 
    176     def on_subject_update(self, name): 
     176    def on_subject_update(self, name, old_value, new_value): 
    177177        if name == 'name': 
    178178            self.__name.set(text=self.subject.name) 
    179179            self.__name_update() 
    180180        else: 
    181             ModelElementItem.on_subject_update(self, name) 
    182  
     181            ModelElementItem.on_subject_update(self, name, old_value, new_value) 
    183182    def on_text_changed(self, text): 
    184183        if text != self.subject.name: 
  • trunk/gaphor/gaphor/diagram/comment.py

    r100 r101  
    113113            return -1 
    114114 
    115     def on_subject_update(self, name): 
     115    def on_subject_update(self, name, old_value, new_value): 
    116116        if name == 'body': 
    117117            self.__body.set(text=self.subject.body) 
    118118            self.__body_update() 
    119119        else: 
    120             ModelElementItem.on_subject_update(self, name
     120            ModelElementItem.on_subject_update(self, name, old_value, new_value
    121121 
    122122    def on_text_changed(self, text): 
  • trunk/gaphor/gaphor/diagram/commentline.py

    r100 r101  
    7171            raise AttributeError, 'Unknown property %s' % pspec.name 
    7272 
     73    def on_glue(self, handle, wx, wy): 
     74        "No connections are allowed on a CommentLine." 
     75        return None 
     76 
    7377    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." 
    7779        return 0 
    7880 
    7981    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." 
    8383        return 0 
    8484 
  • trunk/gaphor/gaphor/diagram/diagramitemfactory.py

    r96 r101  
    3030        return obj 
    3131 
     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 
    3243    def register(self, item_class, uml_class): 
    3344        gobject.type_register(item_class) 
  • trunk/gaphor/gaphor/diagram/modelelement.py

    r99 r101  
    66''' 
    77 
    8 if __name__ == '__main__': 
    9     import sys 
    10     sys.path.append('..') 
    11     del sys 
    12  
    138import gobject 
    149import diacanvas 
     10from diagramitem import DiagramItem 
    1511 
    1612__revision__ = '$revision$' 
     
    1915 
    2016 
    21 class ModelElementItem (diacanvas.CanvasElement, diacanvas.CanvasAbstractGroup): 
     17class ModelElementItem (diacanvas.CanvasElement, diacanvas.CanvasAbstractGroup, DiagramItem): 
    2218    __gproperties__ = { 
    2319        'id':           (gobject.TYPE_PYOBJECT, 'id', 
     
    3430    def __init__(self): 
    3531        self.__gobject_init__() 
     32        DiagramItem.__init__(self) 
    3633        self.subject = None 
    3734        self.auto_resize = 0 
    3835        self.__id = -1 
    39         self.connect ('notify::parent', ModelElementItem.on_parent_notify) 
    4036 
    4137    def save (self, store): 
     
    5349    def postload(self, store): 
    5450        pass 
     51 
    5552    def do_set_property (self, pspec, value): 
    5653        if pspec.name == 'id': 
     
    5956        elif pspec.name == 'subject': 
    6057            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) 
    7159        elif pspec.name == 'auto-resize': 
    7260            self.auto_resize = value 
     
    8674    # DiaCanvasItem callbacks 
    8775    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) 
    9277 
    9378    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) 
    10080 
    10181    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) 
    10883 
    109     def on_parent_notify (self, parent): 
    110         print self 
    111         if self.subject: 
    112             if self.parent: 
    113                 print 'Have Parent', self, parent 
    114                 self.subject.add_presentation (self) 
    115             else: 
    116                 print 'No parent...', self, parent 
    117                 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) 
    12684 
    12785gobject.type_register(ModelElementItem) 
  • trunk/gaphor/gaphor/diagram/usecase.py

    r100 r101  
    5353        self.__name.update_now() 
    5454 
     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 
    5560    def on_get_shape_iter(self): 
    5661        return self.__border 
     
    6166    def on_shape_value(self, iter): 
    6267        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 retval 
    7268 
    7369    # Groupable 
     
    105101            return -1 
    106102 
    107     def on_subject_update(self, name): 
     103    def on_subject_update(self, name, old_value, new_value): 
    108104        if name == 'name': 
    109105            self.__name.set(text=self.subject.name) 
    110106            self.__name_update() 
    111107        else: 
    112             ModelElementItem.on_subject_update(self, name
     108            ModelElementItem.on_subject_update(self, name, old_value, new_value
    113109 
    114110    def on_text_changed(self, text): 
  • trunk/gaphor/gaphor/misc/Makefile.am

    r57 r101  
    55        __init__.py     \ 
    66        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 
    813 
    914CLEANFILES = *.pyc *.pyo 
  • trunk/gaphor/gaphor/misc/__init__.py

    r92 r101  
    11 
    22__all__ = [ 'singleton', 'command', 'signal', 'storage' ] 
    3 #from singleton import * 
    4 #from command import * 
    5 #from signal import * 
    6 #from storage import * 
     3 
     4from gaphorerror import GaphorError 
     5 
  • trunk/gaphor/gaphor/misc/signal.py

    r99 r101  
    1919        # Signals are stored in a list as [ (signal_func, (data)), <next sig> ] 
    2020        self.__signals = [ ] 
     21        self.__queue = [ ] 
    2122 
    2223    def connect (self, signal_handler, *data): 
     
    3536                                 self.__signals) 
    3637 
     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 
    3756    def emit (self, *keys): 
    3857        """ 
     
    4059        passed to the signal handler. Those parameters will be set before 
    4160        the parameters provided through the connect() method. 
     61        In case there are queued emisions, this function will queue the 
     62        signal emision too. 
    4263 
    4364        Note that you should define how many parameters are provided by the 
    4465        owner of the signal. 
    4566        """ 
    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_