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()
|