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

Revision 1998, 4.4 kB (checked in by wrobe..@pld-linux.org, 1 year ago)

- allow align text elements on a string
- align messages on a ':' character on communication diagram

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 """
2 The diagram package contains items (to be drawn on the diagram), tools
3 (used for interacting with the diagram) and interfaces (used for adapting the
4 diagram).
5 """
6
7 __version__ = '$revision$'
8 __author__ = 'Arjan J. Molenaar'
9 __date__ = '$date$'
10
11 import inspect
12 import gobject
13
14 from gaphor.misc import uniqueid
15 from gaphor.diagram.style import Style
16
17 # Map UML elements to their (default) representation.
18 _uml_to_item_map = { }
19
20 def create(type):
21     return create_as(type, uniqueid.generate_id())
22
23 def create_as(type, id):
24     return type(id)
25
26 def get_diagram_item(element):
27     global _uml_to_item_map
28     return _uml_to_item_map.get(element)
29
30 def set_diagram_item(element, item):
31     global _uml_to_item_map
32     _uml_to_item_map[element] = item
33
34
35 def namedelement(f):
36     """
37     Decorator for named items constructors. Injects name text element into
38     an object.
39     """
40     def wrapper(*args, **kw):
41         obj = args[0]
42         f(*args, **kw)
43
44         style = {
45                 'text-align': obj.style.name_align,
46                 'text-padding': obj.style.name_padding,
47                 'text-outside': obj.style.name_outside,
48                 'text-align-str': obj.style.name_align_str,
49                 'text-align-group': 'stereotype',
50         }
51         obj._name = obj.add_text('name', style=style, editable=True)
52
53     return wrapper
54
55
56 def nd_subject(f):
57     """
58     Named item subject notification decorator. Updates subject notification
59     with subject's name notification.
60     """
61     def wrapper(obj, pspec, notifiers=()):
62         notifiers = ('name',) + notifiers
63         f(obj, pspec, notifiers)
64         if obj.subject:
65             obj.on_subject_notify__name(obj.subject)
66         obj.request_update()
67     return wrapper
68
69
70 def nd_subject_name(f):
71     """
72     Named item subject name notification decorator. Updates text of name text
73     element.
74     """
75     def wrapper(obj, subject, pspec=None):
76         obj._name.text = subject.name
77         obj.request_update()
78         f(obj, subject, pspec)
79        
80     return wrapper
81
82
83 class DiagramItemMeta(type):
84     """
85     Initialize a new diagram item.
86     1. Register UML.Elements by means of the __uml__ attribute (see
87        map_uml_class method).
88     2. Set items style information.
89
90     @ivar style: style information
91     """
92
93     def __init__(self, name, bases, data):
94         type.__init__(self, name, bases, data)
95
96         self.map_uml_class(data)
97         self.set_style(data)
98         self.set_namedelement(data)
99
100
101     def set_namedelement(self, data):
102         """
103         If an diagram item is named element, then inject appropriate
104         decorators and notification methods.
105         """
106         if '__namedelement__' in data and data['__namedelement__']:
107
108             cls = self
109
110             # inject or decorate notification methods
111             if hasattr(self, 'on_subject_notify'):
112                 self.on_subject_notify = nd_subject(self.on_subject_notify)
113             else:
114                 self.on_subject_notify = nd_subject(lambda *args: None)
115
116             if hasattr(self, 'on_subject_notify__name'):
117                 self.on_subject_notify__name = nd_subject_name(self.on_subject_notify__name)
118             else:
119                 self.on_subject_notify__name = nd_subject_name(lambda *args: None)
120
121             # decorate constructor
122             self.__init__ = namedelement(self.__init__)
123
124
125     def map_uml_class(self, data):
126         """
127         Map UML class to diagram item.
128
129         @param cls:  new instance of item class
130         @param data: metaclass data with UML class information
131
132         """
133         if '__uml__' in data:
134             obj = data['__uml__']
135             if isinstance(obj, (tuple, set, list)):
136                 for c in obj:
137                     set_diagram_item(c, self)
138             else:
139                 set_diagram_item(obj, self)
140
141
142     def set_style(self, data):
143         """
144         Set item style information by merging provided information with
145         style information from base classes.
146
147         @param cls:   new instance of diagram item class
148         @param bases: base classes of an item
149         @param data:  metaclass data with style information
150         """
151         style = Style()
152         for c in self.__bases__:
153             if hasattr(c, 'style'):
154                 for (name, value) in c.style.items():
155                     style.add(name, value)
156
157         if '__style__' in data:
158             for (name, value) in data['__style__'].iteritems():
159                 style.add(name, value)
160
161         self.style = style
162
163
164 # vim:sw=4:et
Note: See TracBrowser for help on using the browser.