Skip to content

Commit

Permalink
Merge pull request #1084 from gaphor/ordered-presentation
Browse files Browse the repository at this point in the history
Show relationships on top of other elements
  • Loading branch information
danyeaw committed Oct 17, 2021
2 parents 5f83bae + 4122aff commit a1e6995
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 49 deletions.
13 changes: 9 additions & 4 deletions gaphor/core/modeling/diagram.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,10 +323,15 @@ def iter_children(item):
yield child
yield from iter_children(child)

for root in self.ownedPresentation:
if not root.parent:
yield root
yield from iter_children(root)
def traverse_items() -> Iterable[Presentation]:
for root in self.ownedPresentation:
if not root.parent:
yield root
yield from iter_children(root)

yield from sorted(
traverse_items(), key=lambda e: int(isinstance(e, gaphas.Line))
)

def get_parent(self, item: Presentation) -> Presentation | None:
return item.parent
Expand Down
5 changes: 0 additions & 5 deletions gaphor/core/modeling/element.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import logging
import uuid
from contextlib import contextmanager
from typing import TYPE_CHECKING, Callable, Iterator, Protocol, TypeVar, overload

from gaphor.core.modeling.event import ElementUpdated
Expand Down Expand Up @@ -200,10 +199,6 @@ def watcher(
def handle(self, event: object) -> None:
...

@contextmanager
def block_events(self) -> Iterator[RepositoryProtocol]:
...


class EventWatcherProtocol(Protocol):
def watch(self, path: str, handler: Handler | None = None) -> EventWatcherProtocol:
Expand Down
9 changes: 1 addition & 8 deletions gaphor/core/modeling/presentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,7 @@

class Presentation(Matrices, Element, Generic[S]):
"""This presentation is used to link the behaviors of
`gaphor.core.modeling` and `gaphas.Item`.
Note that Presentations are not managed by the Element Factory.
Instead, Presentation objects are owned by Diagram. As a result they
do not emit ElementCreated and ElementDeleted events. Presentations
have their own create and delete events: ElementCreated and
ElementDeleted.
"""
`gaphor.core.modeling` and `gaphas.Item`."""

def __init__(self, diagram: Diagram, id: Id | None = None) -> None:
super().__init__(id=id, model=diagram.model)
Expand Down
51 changes: 38 additions & 13 deletions gaphor/core/modeling/tests/test_diagram.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import gaphas
import pytest

from gaphor.core.eventmanager import EventManager
from gaphor.core.modeling import Diagram, ElementFactory, Presentation, StyleSheet
from gaphor.core.modeling.elementdispatcher import ElementDispatcher
from gaphor.UML.modelinglanguage import UMLModelingLanguage
from gaphor.core.modeling import Diagram, Presentation, StyleSheet


class Example(gaphas.Element, Presentation):
Expand All @@ -16,15 +13,18 @@ def unlink(self):
super().unlink()


class ExampleLine(gaphas.Line, Presentation):
def __init__(self, diagram, id):
super().__init__(connections=diagram.connections, diagram=diagram, id=id)

def unlink(self):
self.test_unlinked = True
super().unlink()


@pytest.fixture
def element_factory():
event_manager = EventManager()
element_dispatcher = ElementDispatcher(event_manager, UMLModelingLanguage())
element_factory = ElementFactory(event_manager, element_dispatcher)
yield element_factory
element_factory.shutdown()
element_dispatcher.shutdown()
event_manager.shutdown()
def diagram(element_factory):
return element_factory.create(Diagram)


def test_diagram_can_be_used_as_gtkview_model():
Expand Down Expand Up @@ -82,7 +82,6 @@ def request_update(self, items, removed_items) -> None:

def test_remove_presentation_triggers_view(element_factory):
diagram = element_factory.create(Diagram)
print(diagram.watcher())
view = ViewMock()
diagram.register_view(view)

Expand All @@ -93,3 +92,29 @@ def test_remove_presentation_triggers_view(element_factory):
assert example.diagram is None
assert example not in diagram.ownedPresentation
assert example in view.removed_items


def test_order_presentations_lines_are_last(diagram):
example_line = diagram.create(ExampleLine)
example = diagram.create(Example)

assert list(diagram.get_all_items()) == [example, example_line]


def test_order_presentations_line_is_grouped(diagram):
example_line = diagram.create(ExampleLine)
example_1 = diagram.create(Example)
example_2 = diagram.create(Example)

example_line.parent = example_1

assert list(diagram.get_all_items()) == [example_1, example_2, example_line]


def test_order_grouped_presentations(diagram):
example_1 = diagram.create(Example)
example_2 = diagram.create(Example)

example_1.parent = example_2

assert list(diagram.get_all_items()) == [example_2, example_1]
6 changes: 3 additions & 3 deletions gaphor/services/tests/test_undo_presentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def test_line_delete(diagram, undo_manager, event_manager):

def test_line_orthogonal_property(diagram, undo_manager, event_manager):
with Transaction(event_manager):
line = LinePresentation(diagram)
line = diagram.create(LinePresentation)
line.insert_handle(0, Handle())

with Transaction(event_manager):
Expand All @@ -70,7 +70,7 @@ def test_line_orthogonal_property(diagram, undo_manager, event_manager):

def test_line_horizontal_property(diagram, undo_manager, event_manager):
with Transaction(event_manager):
line = LinePresentation(diagram)
line = diagram.create(LinePresentation)
line.insert_handle(0, Handle())

with Transaction(event_manager):
Expand Down Expand Up @@ -99,7 +99,7 @@ def test_line_horizontal_property(diagram, undo_manager, event_manager):
def test_matrix_operation(action, diagram, undo_manager, event_manager):

with Transaction(event_manager):
line = LinePresentation(diagram)
line = diagram.create(LinePresentation)
line.matrix.translate(10, 0)

original = tuple(line.matrix)
Expand Down
27 changes: 11 additions & 16 deletions gaphor/services/undomanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,14 +265,9 @@ def _action_executed(self, event=None):
self.event_manager.handle(ActionEnabled("win.edit-redo", self.can_redo()))
self.event_manager.handle(UndoManagerStateChanged(self))

def deep_lookup(self, id: str) -> Element:
def lookup(self, id: str) -> Element:
element: Optional[Element] = self.element_factory.lookup(id)
if not element:
for diagram in self.element_factory.select(Diagram):
presentation: Element
for presentation in diagram.ownedPresentation:
if presentation.id == id:
return presentation
raise ValueError(f"Element with id {id} not found in model")
return element

Expand Down Expand Up @@ -309,7 +304,7 @@ def undo_reversible_event(self, event: RevertibeEvent):
element_id = event.element.id

def b_undo_reversible_event():
element = self.deep_lookup(element_id)
element = self.lookup(element_id)
event.revert(element)

b_undo_reversible_event.__doc__ = (
Expand All @@ -325,7 +320,7 @@ def undo_create_element_event(self, event: ElementCreated):
element_id = event.element.id

def d_undo_create_event():
element = self.deep_lookup(element_id)
element = self.lookup(element_id)
element.unlink()

d_undo_create_event.__doc__ = f"Undo create element {event.element}."
Expand All @@ -348,7 +343,7 @@ def save_func(name, value):
event.element.save(save_func)

def b_undo_delete_event():
diagram: Diagram = self.deep_lookup(diagram_id) # type: ignore[assignment]
diagram: Diagram = self.lookup(diagram_id) # type: ignore[assignment]
element = diagram.create_as(element_type, element_id)
for name, ser in data.items():
for value in deserialize(ser, lambda ref: None):
Expand All @@ -374,7 +369,7 @@ def undo_attribute_change_event(self, event: AttributeUpdated):
value = event.old_value

def c_undo_attribute_change_event():
element = self.deep_lookup(element_id)
element = self.lookup(element_id)
attribute._set(element, value)

c_undo_attribute_change_event.__doc__ = (
Expand All @@ -393,8 +388,8 @@ def undo_association_set_event(self, event: AssociationSet):
value_id = event.old_value and event.old_value.id

def c_undo_association_set_event():
element = self.deep_lookup(element_id)
value = value_id and self.deep_lookup(value_id)
element = self.lookup(element_id)
value = value_id and self.lookup(value_id)
association._set(element, value, from_opposite=True)

c_undo_association_set_event.__doc__ = (
Expand All @@ -413,8 +408,8 @@ def undo_association_add_event(self, event: AssociationAdded):
value_id = event.new_value.id

def c_undo_association_add_event():
element = self.deep_lookup(element_id)
value = self.deep_lookup(value_id)
element = self.lookup(element_id)
value = self.lookup(value_id)
association._del(element, value, from_opposite=True)

c_undo_association_add_event.__doc__ = (
Expand All @@ -433,8 +428,8 @@ def undo_association_delete_event(self, event: AssociationDeleted):
value_id = event.old_value.id

def c_undo_association_delete_event():
element = self.deep_lookup(element_id)
value = self.deep_lookup(value_id)
element = self.lookup(element_id)
value = self.lookup(value_id)
association._set(element, value, from_opposite=True)

c_undo_association_delete_event.__doc__ = (
Expand Down

0 comments on commit a1e6995

Please sign in to comment.