root/gaphor/tags/gaphor-0.12.0/gaphor/diagram/klass.py

Revision 2090, 4.4 kB (checked in by arj..@yirdis.nl, 1 year ago)

Move need_sync logic from features to classes. Feature was expecting obsolete "parent" attribute in the update context.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 """
2 ClassItem diagram item
3 """
4
5 from gaphas.state import observed, reversible_property
6
7 from gaphor import UML
8 from gaphor.i18n import _
9
10 from classifier import ClassifierItem
11 from feature import AttributeItem, OperationItem
12
13        
14 class ClassItem(ClassifierItem):
15     """
16     This item visualizes a Class instance.
17
18     A ClassItem contains two compartments (Compartment): one for
19     attributes and one for operations. To add and remove such features
20     the ClassItem implements the CanvasGroupable interface.
21     Items can be added by callling class.add() and class.remove().
22     This is used to handle CanvasItems, not UML objects!
23     """
24
25     __uml__ = UML.Class, UML.Stereotype
26     __stereotype__ = {
27         'stereotype': UML.Stereotype,
28          'metaclass': lambda self: (not isinstance(self.subject, UML.Stereotype)) and hasattr(self.subject, 'extension') and self.subject.extension,
29     }
30    
31     def __init__(self, id=None):
32         ClassifierItem.__init__(self, id)
33         self.drawing_style = self.DRAW_COMPARTMENT
34         self._attributes = self.create_compartment('attributes')
35         self._operations = self.create_compartment('operations')
36
37     def save(self, save_func):
38         # Store the show- properties *before* the width/height properties,
39         # otherwise the classes will unintentionally grow due to "visible"
40         # attributes or operations.
41         self.save_property(save_func, 'show-attributes')
42         self.save_property(save_func, 'show-operations')
43         ClassifierItem.save(self, save_func)
44
45     def postload(self):
46         ClassifierItem.postload(self)
47         self.sync_attributes()
48         self.sync_operations()
49
50     @observed
51     def _set_show_operations(self, value):
52             self._operations.visible = value
53
54     show_operations = reversible_property(fget=lambda s: s._operations.visible,
55                                fset=_set_show_operations)
56
57     @observed
58     def _set_show_attributes(self, value):
59         self._attributes.visible = value
60
61     show_attributes = reversible_property(fget=lambda s: s._attributes.visible,
62                                fset=_set_show_attributes)
63
64     def _create_attribute(self, attribute):
65         """
66         Create a new attribute item.
67         """
68         new = AttributeItem()
69         new.subject = attribute
70         self._attributes.append(new)
71
72     def _create_operation(self, operation):
73         """
74         Create a new operation item.
75         """
76         new = OperationItem()
77         new.subject = operation
78         self._operations.append(new)
79
80     def sync_attributes(self):
81         """
82         Sync the contents of the attributes compartment with the data
83         in self.subject.
84         """
85         owned_attributes = [a for a in self.subject.ownedAttribute if not a.association]
86         #log.debug('sync_attributes %s' % owned_attributes)
87         self.sync_uml_elements(owned_attributes, self._attributes,
88                            self._create_attribute)
89
90     def sync_operations(self):
91         """
92         Sync the contents of the operations compartment with the data
93         in self.subject.
94         """
95         self.sync_uml_elements(self.subject.ownedOperation, self._operations,
96                            self._create_operation)
97
98
99     def on_subject_notify(self, pspec, notifiers=()):
100         #log.debug('Class.on_subject_notify(%s, %s)' % (pspec, notifiers))
101         ClassifierItem.on_subject_notify(self, pspec,
102                                     ('ownedAttribute', 'ownedOperation') + notifiers)
103         # Create already existing attributes and operations:
104         if self.subject:
105             self.sync_attributes()
106             self.sync_operations()
107         self.request_update()
108
109     def on_subject_notify__ownedAttribute(self, subject, pspec=None):
110         """
111         Called when the ownedAttribute property of our subject changes.
112         """
113         #log.debug('on_subject_notify__ownedAttribute')
114         self.sync_attributes()
115
116     def on_subject_notify__ownedOperation(self, subject, pspec=None):
117         """
118         Called when the ownedOperation property of our subject changes.
119         """
120         #log.debug('on_subject_notify__ownedOperation')
121         self.sync_operations()
122
123     def pre_update(self, context):
124         if self._attributes.need_sync:
125             self.sync_attributes()
126         if self._operations.need_sync:
127             self.sync_operations()
128         super(ClassItem, self).pre_update(context)
129
130
131 # vim:sw=4:et:ai
Note: See TracBrowser for help on using the browser.