Beispiel #1
0
def test_can_undo_connected_generalization(event_manager, element_factory,
                                           undo_manager, caplog):
    caplog.set_level(logging.INFO)
    with Transaction(event_manager):
        diagram: Diagram = element_factory.create(Diagram)
        general = diagram.create(ClassItem,
                                 subject=element_factory.create(UML.Class))
        specific = diagram.create(ClassItem,
                                  subject=element_factory.create(UML.Class))

    with Transaction(event_manager):
        generalization = diagram.create(GeneralizationItem)
        connect(generalization, generalization.head, general)
        connect(generalization, generalization.tail, specific)

    assert not caplog.records

    undo_manager.undo_transaction()

    assert not list(diagram.select(GeneralizationItem))
    assert not caplog.records

    undo_manager.redo_transaction()
    new_generalization_item = next(diagram.select(GeneralizationItem))
    new_generalization = next(element_factory.select(UML.Generalization))

    assert len(list(diagram.select(GeneralizationItem))) == 1
    assert len(element_factory.lselect(UML.Generalization)) == 1
    assert new_generalization_item.subject is new_generalization
    assert not caplog.records
Beispiel #2
0
    def on_button_press(self, event):
        assert not self._tx
        self._tx = Transaction()
        view = self.view
        view.unselect_all()
        if _PlacementTool.on_button_press(self, event):
            try:
                opposite = self.new_item.opposite(
                    self.new_item.handles()[self._handle_index])
            except (KeyError, AttributeError):
                pass
            else:
                # Connect opposite handle first, using the HandleTool's
                # mechanisms

                # First make sure all matrices are updated:
                view.canvas.update_matrix(self.new_item)
                view.update_matrix(self.new_item)

                vpos = event.x, event.y

                item = self.handle_tool.glue(self.new_item, opposite, vpos)
                if item:
                    self.handle_tool.connect(self.new_item, opposite, vpos)
            return True
        return False
Beispiel #3
0
def test_can_undo_connected_association(event_manager, element_factory,
                                        undo_manager, caplog):
    caplog.set_level(logging.INFO)
    with Transaction(event_manager):
        diagram: Diagram = element_factory.create(Diagram)
        parent = diagram.create(ClassItem,
                                subject=element_factory.create(UML.Class))
        child = diagram.create(ClassItem,
                               subject=element_factory.create(UML.Class))

    with Transaction(event_manager):
        association = diagram.create(AssociationItem)
        connect(association, association.head, parent)
        connect(association, association.tail, child)

    assert not caplog.records

    undo_manager.undo_transaction()

    assert not list(diagram.select(AssociationItem))
    assert not caplog.records

    undo_manager.redo_transaction()
    new_association_item = next(diagram.select(AssociationItem))
    new_association = next(element_factory.select(UML.Association))

    assert len(list(diagram.select(AssociationItem))) == 1
    assert len(element_factory.lselect(UML.Association)) == 1

    assert len(new_association.memberEnd) == 2
    assert new_association_item.subject is new_association
    assert new_association_item.head_subject
    assert new_association_item.tail_subject
    assert not caplog.records
Beispiel #4
0
class PlacementTool(_PlacementTool):
    """
    PlacementTool is used to place items on the canvas.
    """

    def __init__(self, view, item_factory, after_handler=None, handle_index=-1):
        """
        item_factory is a callable. It is used to create a CanvasItem
        that is displayed on the diagram.
        """
        _PlacementTool.__init__(
            self,
            view,
            factory=item_factory,
            handle_tool=ConnectHandleTool(),
            handle_index=handle_index,
        )
        self.after_handler = after_handler
        self._tx = None

    @transactional
    def create_item(self, pos):
        return self._create_item(pos)

    def on_button_press(self, event):
        assert not self._tx
        self._tx = Transaction()
        view = self.view
        view.unselect_all()
        if _PlacementTool.on_button_press(self, event):
            try:
                opposite = self.new_item.opposite(
                    self.new_item.handles()[self._handle_index]
                )
            except (KeyError, AttributeError):
                pass
            else:
                # Connect opposite handle first, using the HandleTool's
                # mechanisms

                # First make sure all matrices are updated:
                view.canvas.update_matrix(self.new_item)
                view.update_matrix(self.new_item)

                vpos = event.x, event.y

                item = self.handle_tool.glue(self.new_item, opposite, vpos)
                if item:
                    self.handle_tool.connect(self.new_item, opposite, vpos)
            return True
        return False

    def on_button_release(self, event):
        try:
            if self.after_handler:
                self.after_handler(self.new_item)
            return _PlacementTool.on_button_release(self, event)
        finally:
            self._tx.commit()
            self._tx = None
Beispiel #5
0
class TransactionalToolChain(ToolChain):
    """
    In addition to a normal toolchain, this chain begins an undo-transaction
    at button-press and commits the transaction at button-release.
    """

    def __init__(self, view=None):
        super(TransactionalToolChain, self).__init__(view)
        self._tx = None

    def handle(self, event):
        # For double click: button_press, double_click, button_release
        # print 'event', self.EVENT_HANDLERS.get(event.type)
        if self.EVENT_HANDLERS.get(event.type) in ("on_button_press",):
            assert not self._tx
            self._tx = Transaction()

        try:
            super(TransactionalToolChain, self).handle(event)
        finally:
            if self._tx and self.EVENT_HANDLERS.get(event.type) in (
                "on_button_release",
                "on_double_click",
                "on_triple_click",
            ):
                self._tx.commit()
                self._tx = None
Beispiel #6
0
def test_line_merge_segment(diagram, undo_manager, event_manager):
    with Transaction(event_manager):
        line = diagram.create(LinePresentation)
        segment = Segment(line, diagram)
        segment.split((5, 5))

    head_handle = line.head
    tail_handle = line.tail

    with Transaction(event_manager):
        segment = Segment(line, diagram)
        segment.merge_segment(0)

    assert len(line.handles()) == 2
    assert line.head is head_handle
    assert line.tail is tail_handle

    undo_manager.undo_transaction()

    assert len(line.handles()) == 3
    assert line.head is head_handle
    assert line.tail is tail_handle

    undo_manager.redo_transaction()

    assert len(line.handles()) == 2
Beispiel #7
0
class PlacementTool(_PlacementTool):
    """
    PlacementTool is used to place items on the canvas.
    """
    def __init__(self,
                 view,
                 item_factory,
                 after_handler=None,
                 handle_index=-1):
        """
        item_factory is a callable. It is used to create a CanvasItem
        that is displayed on the diagram.
        """
        _PlacementTool.__init__(self,
                                view,
                                factory=item_factory,
                                handle_tool=ConnectHandleTool(),
                                handle_index=handle_index)
        self.after_handler = after_handler
        self._tx = None

    @transactional
    def create_item(self, pos):
        return self._create_item(pos)

    def on_button_press(self, event):
        assert not self._tx
        self._tx = Transaction()
        view = self.view
        view.unselect_all()
        if _PlacementTool.on_button_press(self, event):
            try:
                opposite = self.new_item.opposite(
                    self.new_item.handles()[self._handle_index])
            except (KeyError, AttributeError):
                pass
            else:
                # Connect opposite handle first, using the HandleTool's
                # mechanisms

                # First make sure all matrices are updated:
                view.canvas.update_matrix(self.new_item)
                view.update_matrix(self.new_item)

                vpos = event.x, event.y

                item = self.handle_tool.glue(self.new_item, opposite, vpos)
                if item:
                    self.handle_tool.connect(self.new_item, opposite, vpos)
            return True
        return False

    def on_button_release(self, event):
        try:
            if self.after_handler:
                self.after_handler(self.new_item)
            return _PlacementTool.on_button_release(self, event)
        finally:
            self._tx.commit()
            self._tx = None
Beispiel #8
0
class TransactionalToolChain(ToolChain):
    """
    In addition to a normal toolchain, this chain begins an undo-transaction
    at button-press and commits the transaction at button-release.
    """
    def __init__(self, event_manager, view=None):
        super().__init__(view)
        self.event_manager = event_manager
        self._tx = None

    def handle(self, event):
        # For double click: button_press, double_click, button_release
        # print 'event', self.EVENT_HANDLERS.get(event.type)
        if self.EVENT_HANDLERS.get(event.type) in ("on_button_press", ):
            assert not self._tx
            self._tx = Transaction(self.event_manager)

        try:
            return super().handle(event)
        finally:
            if self._tx and self.EVENT_HANDLERS.get(event.type) in (
                    "on_button_release",
                    "on_double_click",
                    "on_triple_click",
            ):
                self._tx.commit()
                self._tx = None
Beispiel #9
0
def test_class_association_undo_redo(event_manager, element_factory,
                                     undo_manager):
    with Transaction(event_manager):
        diagram = element_factory.create(Diagram)

    assert 0 == len(diagram.connections.solver.constraints)

    with Transaction(event_manager):
        ci1 = diagram.create(ClassItem,
                             subject=element_factory.create(UML.Class))
    assert 6 == len(diagram.connections.solver.constraints)

    with Transaction(event_manager):
        ci2 = diagram.create(ClassItem,
                             subject=element_factory.create(UML.Class))
    assert 12 == len(diagram.connections.solver.constraints)

    with Transaction(event_manager):
        a = diagram.create(AssociationItem)

        connect(a, a.head, ci1)
        connect(a, a.tail, ci2)

    # Diagram, Association, 2x Class, Property, LiteralSpecification
    assert 6 == len(element_factory.lselect())
    assert 14 == len(diagram.connections.solver.constraints)

    undo_manager.clear_undo_stack()
    assert not undo_manager.can_undo()

    with Transaction(event_manager):
        ci2.unlink()

    assert undo_manager.can_undo()

    def get_connected(handle):
        """Get item connected to line via handle."""
        cinfo = diagram.connections.get_connection(handle)
        if cinfo:
            return cinfo.connected
        return None

    assert ci1 == get_connected(a.head)
    assert None is get_connected(a.tail)

    for i in range(3):
        assert 7 == len(diagram.connections.solver.constraints)

        undo_manager.undo_transaction()

        assert 14 == len(diagram.connections.solver.constraints)

        assert ci1 == get_connected(a.head)
        assert ci2.id == get_connected(a.tail).id

        undo_manager.redo_transaction()
Beispiel #10
0
def test_diagram_item_should_not_end_up_in_element_factory(
        event_manager, element_factory, undo_manager):
    with Transaction(event_manager):
        diagram = element_factory.create(Diagram)

    with Transaction(event_manager):
        cls = diagram.create(ClassItem,
                             subject=element_factory.create(UML.Class))

    undo_manager.undo_transaction()
    undo_manager.redo_transaction()

    assert cls not in element_factory.lselect(), element_factory.lselect()
Beispiel #11
0
    def handle(self, event):
        # For double click: button_press, double_click, button_release
        #print 'event', self.EVENT_HANDLERS.get(event.type)
        if self.EVENT_HANDLERS.get(event.type) in ('on_button_press',):
            assert not self._tx
            self._tx = Transaction()

        try:
            super(TransactionalToolChain, self).handle(event)
        finally:
            if self._tx and self.EVENT_HANDLERS.get(event.type) in ('on_button_release', 'on_double_click', 'on_triple_click'):
                self._tx.commit()
                self._tx = None
Beispiel #12
0
def test_line_delete(diagram, undo_manager, event_manager):
    with Transaction(event_manager):
        line = LinePresentation(diagram)
        line.insert_handle(1, Handle((20, 20)))
        line.matrix.translate(10, 10)

    with Transaction(event_manager):
        line.unlink()

    undo_manager.undo_transaction()

    line = diagram.ownedPresentation[0]
    assert len(line.handles()) == 3
    assert line.handles()[1].pos.tuple() == (20, 20)
    assert line.matrix.tuple() == (1, 0, 0, 1, 10, 10)
Beispiel #13
0
def test_undo_should_not_cause_warnings(event_manager, element_factory,
                                        undo_manager, caplog):
    caplog.set_level(logging.INFO)
    with Transaction(event_manager):
        diagram = element_factory.create(Diagram)

    with Transaction(event_manager):
        diagram.create(ClassItem, subject=element_factory.create(UML.Class))

    assert not caplog.records

    undo_manager.undo_transaction()

    assert not diagram.ownedPresentation
    assert not caplog.records
Beispiel #14
0
    def handle(self, event):
        # For double click: button_press, double_click, button_release
        if self.EVENT_HANDLERS.get(event.type) in ("on_button_press", ):
            assert not self._tx
            self._tx = Transaction(self.event_manager)

        try:
            return super().handle(event)
        finally:
            if self._tx and self.EVENT_HANDLERS.get(event.type) in (
                    "on_button_release",
                    "on_double_click",
                    "on_triple_click",
            ):
                self._tx.commit()
                self._tx = None
def test_delete_original_association(class_and_association_with_copy,
                                     event_manager):

    c, a, aa = class_and_association_with_copy

    assert aa.subject.memberEnd[0].type
    assert aa.subject.memberEnd[1].type
    assert aa.subject.memberEnd[0].type is c.subject
    assert aa.subject.memberEnd[1].type is c.subject
    assert aa.subject.memberEnd[0] is aa.head_subject
    assert aa.subject.memberEnd[1] is aa.tail_subject
    assert aa.subject.memberEnd[0] in aa.subject.memberEnd[
        1].type.ownedAttribute

    # Now, when the original is deleted, the model is changed and made invalid

    with Transaction(event_manager):
        a.unlink()

    assert aa.subject.memberEnd[0].type
    assert aa.subject.memberEnd[1].type
    assert aa.subject.memberEnd[0].type is c.subject
    assert aa.subject.memberEnd[1].type is c.subject
    assert aa.subject.memberEnd[0] is aa.head_subject
    assert aa.subject.memberEnd[1] is aa.tail_subject
    assert aa.subject.memberEnd[0] in aa.subject.memberEnd[
        1].type.ownedAttribute
def test_delete_copied_associations(class_and_association_with_copy,
                                    event_manager):

    c, a, aa = class_and_association_with_copy

    assert a.subject.memberEnd[0].type
    assert a.subject.memberEnd[1].type
    assert a.subject.memberEnd[0].type is c.subject
    assert a.subject.memberEnd[1].type is c.subject
    assert a.subject.memberEnd[0] is a.head_subject
    assert a.subject.memberEnd[1] is a.tail_subject
    assert a.subject.memberEnd[0] in a.subject.memberEnd[1].type.ownedAttribute

    # Delete the copy and all is fine

    with Transaction(event_manager):
        aa.unlink()

    assert a.subject.memberEnd[0].type
    assert a.subject.memberEnd[1].type
    assert a.subject.memberEnd[0].type is c.subject
    assert a.subject.memberEnd[1].type is c.subject
    assert a.subject.memberEnd[0] is a.head_subject
    assert a.subject.memberEnd[1] is a.tail_subject
    assert a.subject.memberEnd[0] in a.subject.memberEnd[1].type.ownedAttribute
Beispiel #17
0
    def on_button_press(self, event):
        assert not self._tx
        self._tx = Transaction()
        view = self.view
        view.unselect_all()
        if _PlacementTool.on_button_press(self, event):
            try:
                opposite = self.new_item.opposite(self.new_item.handles()[self._handle_index])
            except (KeyError, AttributeError):
                pass
            else:
                # Connect opposite handle first, using the HandleTool's
                # mechanisms

                # First make sure all matrices are updated:
                view.canvas.update_matrix(self.new_item)
                view.update_matrix(self.new_item)

                vpos = event.x, event.y

                item = self.handle_tool.glue(self.new_item, opposite, vpos)
                if item:
                    self.handle_tool.connect(self.new_item, opposite, vpos)
            return True
        return False
Beispiel #18
0
def test_diagram_item_can_undo_(event_manager, element_factory, undo_manager,
                                caplog):
    caplog.set_level(logging.INFO)
    with Transaction(event_manager):
        diagram = element_factory.create(Diagram)

    with Transaction(event_manager):
        cls = diagram.create(ClassItem,
                             subject=element_factory.create(UML.Class))
        cls.matrix.translate(10, 10)

    undo_manager.undo_transaction()
    undo_manager.redo_transaction()

    assert diagram.ownedPresentation[0].matrix.tuple() == (1, 0, 0, 1, 10, 10)
    assert not caplog.records
def test_placement(view, event_manager):
    factory = new_item_factory(CommentLineItem)
    tool = placement_tool(view, factory, event_manager, handle_index=-1)

    with Transaction(event_manager):
        click(tool, event_manager)
        click(tool, event_manager)
Beispiel #20
0
def test_line_horizontal_property(diagram, undo_manager, event_manager):
    with Transaction(event_manager):
        line = LinePresentation(diagram)
        line.insert_handle(0, Handle())

    with Transaction(event_manager):
        line.horizontal = True

    assert line.horizontal

    undo_manager.undo_transaction()

    assert not line.horizontal

    undo_manager.redo_transaction()

    assert line.horizontal
Beispiel #21
0
def test_redo_should_show_item_on_diagram(event_manager, element_factory,
                                          undo_manager):
    with Transaction(event_manager):
        diagram = element_factory.create(UML.Diagram)

    view = ViewMock(diagram)

    with Transaction(event_manager):
        cls = diagram.create(ClassItem,
                             subject=element_factory.create(UML.Class))

    undo_manager.undo_transaction()
    undo_manager.redo_transaction()

    items, matrix_items, removed_items = view.updates[-1]

    assert cls in items, view.updates
Beispiel #22
0
def delete_selected_items(view: GtkView, event_manager):
    with Transaction(event_manager):
        items = view.selection.selected_items
        for i in list(items):
            if isinstance(i, Presentation):
                i.unlink()
            else:
                if i.diagram:
                    i.diagram.remove(i)
Beispiel #23
0
 def cut_action(self):
     view = self.diagrams.get_current_view()
     if view.is_focus():
         self.clipboard.set_text("", -1)
         items = view.selection.selected_items
         self.copy(items)
         with Transaction(self.event_manager):
             for i in list(items):
                 i.unlink()
def test_line_handle_no_events_for_removed_handle(diagram, undo_manager, event_manager):
    with Transaction(event_manager):
        line = diagram.create(LinePresentation)

    # Note that inserting and removing handles is *not* transactional
    handle = Handle()
    line.insert_handle(1, handle)
    line.remove_handle(handle)

    new_pos = (30, 40)

    with Transaction(event_manager):
        handle.pos = new_pos

    assert tuple(handle.pos) == new_pos

    undo_manager.undo_transaction()

    assert handle.pos.tuple() == new_pos
Beispiel #25
0
def test_remove_class_with_association(create, diagram, element_factory,
                                       event_manager):
    with Transaction(event_manager):
        c1 = create(ClassItem, UML.Class)
        c1.name = "klassitem1"
        c2 = create(ClassItem, UML.Class)
        c2.name = "klassitem2"

        a = create(AssociationItem)

        assert len(list(diagram.get_all_items())) == 3

        connect(a, a.head, c1)
        connect(a, a.tail, c2)

    assert a.subject
    assert element_factory.lselect(UML.Association)[0] is a.subject

    with Transaction(event_manager):
        c1.unlink()
Beispiel #26
0
def test_matrix_operation(action, diagram, undo_manager, event_manager):

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

    original = tuple(line.matrix)

    with Transaction(event_manager):
        action(line)

    assert tuple(line.matrix) != original

    undo_manager.undo_transaction()

    assert tuple(line.matrix) == original

    undo_manager.redo_transaction()

    assert tuple(line.matrix) != original
Beispiel #27
0
def test_line_handle_position(diagram, undo_manager, event_manager, index):
    with Transaction(event_manager):
        line = diagram.create(LinePresentation)

    handle = line.handles()[index]
    old_pos = handle.pos.tuple()
    new_pos = (30, 40)

    with Transaction(event_manager):
        handle.pos = new_pos

    assert tuple(handle.pos) == new_pos

    undo_manager.undo_transaction()

    assert handle.pos.tuple() == old_pos

    undo_manager.redo_transaction()

    assert tuple(handle.pos) == new_pos
Beispiel #28
0
def test_delete_and_undo_model_element(event_manager, element_factory,
                                       undo_manager):
    with Transaction(event_manager):
        diagram = element_factory.create(Diagram)

    with Transaction(event_manager):
        subject = element_factory.create(UML.Class)
        subject.name = "Name"
        diagram.create(ClassItem, subject=subject)

    with Transaction(event_manager):
        subject.unlink()

    undo_manager.undo_transaction()

    new_cls = diagram.ownedPresentation[0]
    new_elem = element_factory.lookup(subject.id)

    assert new_cls in new_elem.presentation
    assert new_cls.subject
    assert new_elem.name == "Name"
def test_line_connections(diagram, undo_manager, element_factory, event_manager):
    with Transaction(event_manager):
        class_item = diagram.create(ClassItem, subject=element_factory.create(Class))
        gen_item = diagram.create(GeneralizationItem)

    handle = gen_item.handles()[0]

    with Transaction(event_manager):
        connect(gen_item, handle, class_item)

    connections = diagram.connections

    assert connections.get_connection(handle)

    undo_manager.undo_transaction()

    assert not connections.get_connection(handle)

    undo_manager.redo_transaction()

    assert connections.get_connection(handle)
Beispiel #30
0
    def handle(self, event):
        # For double click: button_press, double_click, button_release
        #print 'event', self.EVENT_HANDLERS.get(event.type)
        if self.EVENT_HANDLERS.get(event.type) in ('on_button_press',):
            assert not self._tx
            self._tx = Transaction()

        try:
            super(TransactionalToolChain, self).handle(event)
        finally:
            if self._tx and self.EVENT_HANDLERS.get(event.type) in ('on_button_release', 'on_double_click', 'on_triple_click'):
                self._tx.commit()
                self._tx = None
def test_unioncache_in_derived_union(diagram, event_manager, element_factory):
    with Transaction(event_manager):
        uc1 = diagram.create(diagramitems.UseCaseItem,
                             subject=element_factory.create(UML.UseCase))
        uc2 = diagram.create(diagramitems.UseCaseItem,
                             subject=element_factory.create(UML.UseCase))
        include = diagram.create(diagramitems.IncludeItem)

        connect(include, include.handles()[0], uc1)
        connect(include, include.handles()[1], uc2)

    assert uc1.subject in include.subject.target
    assert include.subject.ownedElement == []
def test_line_loading_of_points(diagram, undo_manager, event_manager, element_factory):
    with Transaction(event_manager):
        line = diagram.create(LinePresentation)
        line.load("points", "[(0, 0), (5, 5), (10, 10)]")
        assert len(line.handles()) == 3

    handle = line.handles()[1]
    old_pos = handle.pos.tuple()
    new_pos = (30, 40)

    with Transaction(event_manager):
        handle.pos = new_pos

    assert tuple(handle.pos) == new_pos

    undo_manager.undo_transaction()

    assert handle.pos.tuple() == old_pos

    undo_manager.redo_transaction()

    assert tuple(handle.pos) == new_pos
Beispiel #33
0
    def paste(self, diagram):
        """Paste items in the copy-buffer to the diagram."""
        with Transaction(self.event_manager):
            # Create new id's that have to be used to create the items:
            new_items: Set[Presentation] = paste(
                copy_buffer, diagram, self.element_factory.lookup
            )

            # move pasted items a bit, so user can see result of his action :)
            for item in new_items:
                if item.parent not in new_items:
                    item.matrix.translate(10, 10)

        return new_items
Beispiel #34
0
def test_line_create(diagram, undo_manager, event_manager, caplog):
    with Transaction(event_manager):
        diagram.create(LinePresentation)

    assert diagram.ownedPresentation

    undo_manager.undo_transaction()

    assert not caplog.records
    assert not diagram.ownedPresentation

    undo_manager.redo_transaction()

    assert diagram.ownedPresentation