| 1 |
""" |
|---|
| 2 |
Common dependencies likeq dependency, usage, realization and implementation. |
|---|
| 3 |
""" |
|---|
| 4 |
|
|---|
| 5 |
from gaphor import UML |
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
from gaphor.diagram.diagramline import DiagramLine |
|---|
| 9 |
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 |
|
|---|
| 17 |
|
|---|
| 18 |
|
|---|
| 19 |
|
|---|
| 20 |
|
|---|
| 21 |
|
|---|
| 22 |
|
|---|
| 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 |
|
|---|
| 54 |
|
|---|
| 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 |
|
|---|
| 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 |
|
|---|
| 77 |
|
|---|
| 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 |
|
|---|