| 1 |
""" |
|---|
| 2 |
Base classes related to items, which represent UML classes deriving |
|---|
| 3 |
from NamedElement. |
|---|
| 4 |
""" |
|---|
| 5 |
|
|---|
| 6 |
from gaphor import UML |
|---|
| 7 |
from gaphor.UML.interfaces import IAttributeChangeEvent |
|---|
| 8 |
from gaphor.application import Application |
|---|
| 9 |
from gaphor.diagram.elementitem import ElementItem |
|---|
| 10 |
from gaphor.diagram.style import get_min_size, ALIGN_CENTER, ALIGN_TOP |
|---|
| 11 |
import gaphor.diagram.font as font |
|---|
| 12 |
|
|---|
| 13 |
class NamedItem(ElementItem): |
|---|
| 14 |
|
|---|
| 15 |
__style__ = { |
|---|
| 16 |
'min-size' : (100, 50), |
|---|
| 17 |
'name-align' : (ALIGN_CENTER, ALIGN_TOP), |
|---|
| 18 |
'name-padding': (5, 10, 5, 10), |
|---|
| 19 |
'name-outside': False, |
|---|
| 20 |
'name-align-str': None, |
|---|
| 21 |
} |
|---|
| 22 |
|
|---|
| 23 |
def __init__(self, id=None): |
|---|
| 24 |
""" |
|---|
| 25 |
Create named item. |
|---|
| 26 |
""" |
|---|
| 27 |
ElementItem.__init__(self, id) |
|---|
| 28 |
|
|---|
| 29 |
|
|---|
| 30 |
|
|---|
| 31 |
self._from = self.add_text('from', |
|---|
| 32 |
pattern='(from %s)', |
|---|
| 33 |
style={'text-align-group': 'stereotype'}, |
|---|
| 34 |
visible=self.is_namespace_info_visible, |
|---|
| 35 |
font=font.FONT_SMALL) |
|---|
| 36 |
|
|---|
| 37 |
self._name = self.add_text('name', style={ |
|---|
| 38 |
'text-align': self.style.name_align, |
|---|
| 39 |
'text-padding': self.style.name_padding, |
|---|
| 40 |
'text-outside': self.style.name_outside, |
|---|
| 41 |
'text-align-str': self.style.name_align_str, |
|---|
| 42 |
'text-align-group': 'stereotype', |
|---|
| 43 |
}, editable=True) |
|---|
| 44 |
|
|---|
| 45 |
|
|---|
| 46 |
self._header_size = 0, 0 |
|---|
| 47 |
self.add_watch(UML.NamedElement.name, self.on_named_element_name) |
|---|
| 48 |
self.add_watch(UML.NamedElement.namespace, self.on_named_element_namespace) |
|---|
| 49 |
|
|---|
| 50 |
def is_namespace_info_visible(self): |
|---|
| 51 |
""" |
|---|
| 52 |
Display name space info when it is different, then diagram's or |
|---|
| 53 |
parent's namespace. |
|---|
| 54 |
""" |
|---|
| 55 |
subject = self.subject |
|---|
| 56 |
canvas = self.canvas |
|---|
| 57 |
|
|---|
| 58 |
if not subject or not canvas: |
|---|
| 59 |
return False |
|---|
| 60 |
|
|---|
| 61 |
namespace = subject.namespace |
|---|
| 62 |
parent = canvas.get_parent(self) |
|---|
| 63 |
|
|---|
| 64 |
|
|---|
| 65 |
if parent and parent.subject \ |
|---|
| 66 |
and parent.subject.namespace is not namespace: |
|---|
| 67 |
return False |
|---|
| 68 |
|
|---|
| 69 |
return self._from.text and namespace is not canvas.diagram.namespace |
|---|
| 70 |
|
|---|
| 71 |
|
|---|
| 72 |
def on_named_element_name(self, event): |
|---|
| 73 |
""" |
|---|
| 74 |
""" |
|---|
| 75 |
if self.subject and (event is None or self.subject is event.element): |
|---|
| 76 |
self._name.text = self.subject.name |
|---|
| 77 |
self.request_update() |
|---|
| 78 |
|
|---|
| 79 |
|
|---|
| 80 |
def on_named_element_namespace(self, event): |
|---|
| 81 |
""" |
|---|
| 82 |
Add a line '(from ...)' to the class item if subject's namespace |
|---|
| 83 |
is not the same as the namespace of this diagram. |
|---|
| 84 |
""" |
|---|
| 85 |
subject = self.subject |
|---|
| 86 |
if event is None or subject is event.element: |
|---|
| 87 |
if subject and subject.namespace: |
|---|
| 88 |
self._from.text = subject.namespace.name |
|---|
| 89 |
else: |
|---|
| 90 |
self._from.text = '' |
|---|
| 91 |
self.request_update() |
|---|
| 92 |
|
|---|
| 93 |
|
|---|
| 94 |
def pre_update(self, context): |
|---|
| 95 |
""" |
|---|
| 96 |
Calculate minimal size and header size. |
|---|
| 97 |
""" |
|---|
| 98 |
super(NamedItem, self).pre_update(context) |
|---|
| 99 |
|
|---|
| 100 |
style = self._name.style |
|---|
| 101 |
|
|---|
| 102 |
|
|---|
| 103 |
|
|---|
| 104 |
if not style.text_outside: |
|---|
| 105 |
|
|---|
| 106 |
assert 'stereotype' in self._text_groups_sizes |
|---|
| 107 |
|
|---|
| 108 |
nw, nh = self._text_groups_sizes['stereotype'] |
|---|
| 109 |
self._header_size = get_min_size(nw, nh, self.style.name_padding) |
|---|
| 110 |
|
|---|
| 111 |
self.min_width = max(self.style.min_size[0], self._header_size[0]) |
|---|
| 112 |
self.min_height = max(self.style.min_size[1], self._header_size[1]) |
|---|
| 113 |
|
|---|
| 114 |
|
|---|
| 115 |
|
|---|