summaryrefslogtreecommitdiff
path: root/src/main/python/utils/undo.py
blob: 51610f532933e02fe7c0c211f6b6be9b8a2ff492 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
"""
Contains custom undo commands that can be pushed to undo stack
"""
from PyQt5.QtWidgets import QUndoCommand
from re import compile
import shapes

def repl(x):
    return f"{x[0][0]} {x[0][1].lower()}"

regex = compile(r"([a-z][A-Z])")

def objectName(obj):
    name = regex.sub(repl, obj.m_type if obj.__class__.__name__ == 'NodeItem' else obj.__class__.__name__)
    # if obj.__class__.__name__ != 'line':
    #     name = 'Draw ' + name[0].upper() + name[1:]
    # else:
    #     name = 'Add ' + 
    return name[0].upper() + name[1:] + ' symbol'

class addCommand(QUndoCommand):
    """
    QUndoCommand for add item event
    """
    def __init__(self, addItem, scene, parent = None):
        super(addCommand, self).__init__(parent)
        self.scene = scene
        self.diagramItem = addItem
        self.itemPos = addItem.pos()
        if(issubclass(self.diagramItem.__class__,shapes.Line) and addItem != None):
            self.startGripItem = addItem.startGripItem.parentItem()
            self.endGripItem = addItem.endGripItem.parentItem()
            self.indexLGS,self.indexLGE = self.findLGIndex()
        self.setText(f"Add {objectName(self.diagramItem)} at {self.itemPos.x()}, {self.itemPos.y()}")
        
    def undo(self):
        if self.diagramItem in self.scene.items():
            self.scene.removeItem(self.diagramItem)
            self.scene.update()
            self.scene.advance()
        
    def redo(self):
        if self.diagramItem not in self.scene.items():
            self.scene.addItem(self.diagramItem)
            self.diagramItem.setPos(self.itemPos)
            self.scene.clearSelection()
            self.scene.advance()
            if(issubclass(self.diagramItem.__class__,shapes.Line)):
                self.reconnectLines()

    def findLGIndex(self):
        startIndex = None
        endIndex = None
        for indexLG,i in enumerate(self.startGripItem.lineGripItems):
            for j in i.lines:
                if j == self.diagramItem:
                    startIndex = indexLG
        for indexLG,i in enumerate(self.endGripItem.lineGripItems):
            for j in i.lines:
                if j == self.diagramItem:
                    endIndex = indexLG
        return startIndex,endIndex
    
    def reconnectLines(self):
        if self.diagramItem not  in self.startGripItem.lineGripItems[self.indexLGS].lines:
            self.startGripItem.lineGripItems[self.indexLGS].lines.append(self.diagramItem)
        if self.diagramItem not  in self.endGripItem.lineGripItems[self.indexLGE].lines:
            self.endGripItem.lineGripItems[self.indexLGE].lines.append(self.diagramItem)

class deleteCommand(QUndoCommand):
    """
    QUndoCommand for delete item event
    """
    def __init__(self, item, scene,parent = None):
        super(deleteCommand, self).__init__(parent)
        self.scene = scene
        item.setSelected(False)
        self.diagramItem = item
        if(issubclass(self.diagramItem.__class__,shapes.Line)):
            self.startGripItem = item.startGripItem.parentItem()
            self.endGripItem = item.endGripItem.parentItem()
            self.indexLGS,self.indexLGE = self.findLGIndex()
        self.setText(f"Delete {objectName(self.diagramItem)} at {self.diagramItem.pos().x()}, {self.diagramItem.y()}")
        
    def undo(self):
        if self.diagramItem not in self.scene.items():
            self.scene.addItem(self.diagramItem)
            self.scene.update()
            self.scene.advance()
            self.scene.reInsertLines()
            if(issubclass(self.diagramItem.__class__,shapes.Line)):
                self.reconnectLines()
            
    def redo(self):
        if self.diagramItem in self.scene.items():
            self.scene.removeItem(self.diagramItem)
            self.scene.advance()
    
    def findLGIndex(self):
        startIndex = None
        endIndex = None
        for indexLG,i in enumerate(self.startGripItem.lineGripItems):
            for j in i.lines:
                if j == self.diagramItem:
                    startIndex = indexLG
        for indexLG,i in enumerate(self.endGripItem.lineGripItems):
            for j in i.lines:
                if j == self.diagramItem:
                    endIndex = indexLG
        return startIndex,endIndex
    
    def reconnectLines(self):
        if self.diagramItem not  in self.startGripItem.lineGripItems[self.indexLGS].lines:
            self.startGripItem.lineGripItems[self.indexLGS].lines.append(self.diagramItem)
        if self.diagramItem not  in self.endGripItem.lineGripItems[self.indexLGE].lines:
            self.endGripItem.lineGripItems[self.indexLGE].lines.append(self.diagramItem)

class moveCommand(QUndoCommand):
    """
    QUndoCommand for move item event
    """
    def __init__(self, item, lastPos, parent = None):
        super(moveCommand, self).__init__(parent)
        self.diagramItem = item
        self.lastPos = lastPos
        self.newPos = item.pos()
        
    def undo(self):
        self.diagramItem.setPos(self.lastPos)
        self.diagramItem.scene().update()
        self.setText(f"Move {objectName(self.diagramItem)} to {self.newPos.x()}, {self.newPos.y()}")
        
    def redo(self):
        self.diagramItem.setPos(self.newPos)
        self.setText(f"Move {objectName(self.diagramItem)} to {self.newPos.x()}, {self.newPos.y()}")
        
    def mergeWith(self, move):
        #merges multiple move commands so that a move event is not added twice.
        item = move.diagramItem
        
        if self.diagramItem != item:
            return False
        
        self.newPos = item.pos()
        self.setText(f"Move {objectName(self.diagramItem)} to {self.newPos.x()}, {self.newPos.y()}")
        return True
    
class resizeCommand(QUndoCommand):
    """
    Defines the resize event for the custom scene.
    """
    def __init__(self, new, canvas, widget, parent = None):
        super(resizeCommand, self).__init__(parent)
        self.parent = canvas
        self.old = self.parent.canvasSize, self.parent.ppi, self.parent.landscape
        self.new = new
        self.widget = widget
        self.setText(f'Change canvas dimensions to {new[0]} at {new[1]} ppi')
    
    def undo(self):
        self.parent.canvasSize, self.parent.ppi, self.parent.landscape = self.old
        self.widget.resizeHandler()
    
    def redo(self):
        self.parent.canvasSize, self.parent.ppi, self.parent.landscape = self.new
        self.widget.resizeHandler()