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

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

- removed out of date todo (we currently support stereotypes on higher

level)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 """
2 Common dependencies likeq dependency, usage, realization and implementation.
3 """
4
5 from gaphor import UML
6
7 #from gaphor.diagram.relationship import Relationship
8 from gaphor.diagram.diagramline import DiagramLine
9
10
11 #class DependencyRelationship(Relationship):
12 #    """
13 #    Relationship for dependencies including realization dependency between
14 #    classifiers and components.
15 #    """
16 #    def relationship(self, line, head_subject = None, tail_subject = None):
17 #        if line.get_dependency_type() == UML.Realization:
18 #            args = ('realizingClassifier', None), ('abstraction', 'realization')
19 #        else:
20 #            args = ('supplier', 'supplierDependency'), ('client', 'clientDependency')
21 #        args +=  head_subject, tail_subject
22 #        return self.find(line, *args)
23
24
25
26 class DependencyItem(DiagramLine):
27     """This class represents all types of dependencies.
28
29     Normally a dependency looks like a dashed line with an arrow head.
30     The dependency can have a stereotype attached to it, stating the kind of
31     dependency we're dealing with. The dependency kind can only be changed if
32     the dependency is not connected to two items.
33
34     In the special case of an Usage dependency, where one end is
35     connected to an InterfaceItem: the line is drawn as a solid line without
36     arrowhead.  The Interface will draw a half a circle on the side where the
37     Usage dep. is connected.
38
39     Although it is possible to add multiple Implementation and Usage
40     dependencies to an interface, it will probably not be very explaining
41     (esp. Usage dependencies).
42
43     Function get_dependency_type should be used to determine automatically
44     type of a dependency.
45
46     TODO (see also InterfaceItem): When a Usage dependency is drawn and is
47           connected to an InterfaceItem, draw a solid line, but stop drawing
48           the line 'x' points before the last handle.
49     """
50
51     __uml__ = UML.Dependency
52
53     # do not use issubclass, because issubclass(UML.Implementation, UML.Realization)
54     # we need to be very strict here
55     __stereotype__ = {
56         'use':        lambda self: self._dependency_type == UML.Usage,
57         'realize':    lambda self: self._dependency_type == UML.Realization,
58         'implements': lambda self: self._dependency_type == UML.Implementation,
59     }
60
61 #    relationship = DependencyRelationship()
62
63     def __init__(self, id=None):
64         DiagramLine.__init__(self, id)
65
66         self._dependency_type = UML.Dependency
67         self.auto_dependency = True
68         self._dash_style = True
69
70     def save(self, save_func):
71         DiagramLine.save(self, save_func)
72         save_func('auto_dependency', self.auto_dependency)
73
74
75     def load(self, name, value):
76         #if name == 'dependency_type':
77         #    self.set_dependency_type(getattr(UML, value))
78         if name == 'auto_dependency':
79             self.auto_dependency = eval(value)
80         else:
81             DiagramLine.load(self, name, value)
82
83     def postload(self):
84         if self.subject:
85             dependency_type = self.subject.__class__
86             DiagramLine.postload(self)
87             self._dependency_type = dependency_type
88         else:
89             DiagramLine.postload(self)
90
91     def get_dependency_type(self):
92         return self._dependency_type
93
94
95     def set_dependency_type(self, dependency_type=None):
96         if not dependency_type and self.auto_dependency:
97             dependency_type = self.determine_dependency_type(self.head.connected_to, self.tail.connected_to)
98         self._dependency_type = dependency_type
99         self.request_update()
100
101     dependency_type = property(lambda s: s._dependency_type,
102                                set_dependency_type, set_dependency_type)
103
104     def post_update(self, context):
105         super(DependencyItem, self).post_update(context)
106
107         from interface import InterfaceItem
108         dependency_type = self._dependency_type
109         c1 = self.head.connected_to
110         if c1 and dependency_type is UML.Usage \
111            and isinstance(c1, InterfaceItem) and c1.is_folded():
112             self._dash_style = False
113         else:
114             self._dash_style = True
115
116     def draw_head(self, context):
117         cr = context.cairo
118         if self._dash_style:
119             cr.set_dash((), 0)
120             cr.move_to(15, -6)
121             cr.line_to(0, 0)
122             cr.line_to(15, 6)
123             cr.stroke()
124         cr.move_to(0, 0)
125    
126     def draw(self, context):
127         if self._dash_style:
128             context.cairo.set_dash((7.0, 5.0), 0)
129         super(DependencyItem, self).draw(context)
130
131     @staticmethod
132     def is_usage(s):
133         """Return true if dependency should be usage dependency.
134         """
135         return isinstance(s, UML.Interface)
136
137
138     @staticmethod
139     def is_realization(ts, hs):
140         """Return true if dependency should be realization dependency.
141         """
142         return isinstance(ts, UML.Classifier) and isinstance(hs, UML.Component)
143
144
145     @staticmethod
146     def determine_dependency_type(ts, hs):
147         """
148         Determine dependency type:
149
150         - check if it is usage
151         - check if it is realization
152         - if none of above, then it is normal dependency
153
154         The checks should be performed in above order. For example if ts and hs
155         are Interface and Component, then we have two choices:
156
157         - claim it is an usage (as ts is an Interface)
158         - or claim it is a realization (as Interface is Classifier, too)
159
160         In this case we want usage to win over realization.
161         """
162         dt = UML.Dependency
163         if DependencyItem.is_usage(ts):
164             dt = UML.Usage
165         elif DependencyItem.is_realization(ts, hs):
166             dt = UML.Realization
167         return dt
168
169 # vim:sw=4:et
Note: See TracBrowser for help on using the browser.