개정판 702779b0
issue #366: Undo/Redo for line resizing
Change-Id: I785f92387264da38138c11e36fcdb238a83008c6
DTI_PID/DTI_PID/Commands/ResizeCommand.py | ||
---|---|---|
1 |
# coding: utf-8 |
|
2 |
""" This is resize command module """ |
|
3 |
import os.path |
|
4 |
import sys |
|
5 |
from enum import Enum |
|
6 |
from EngineeringLineItem import QEngineeringLineItem |
|
7 |
from PyQt5.QtCore import * |
|
8 |
from PyQt5.QtGui import * |
|
9 |
from PyQt5.QtWidgets import * |
|
10 |
|
|
11 |
|
|
12 |
class ResizeCommand(QUndoCommand): |
|
13 |
def __init__(self, scene, item, params, parent=None): |
|
14 |
|
|
15 |
super(ResizeCommand, self).__init__(parent) |
|
16 |
self._scene = scene |
|
17 |
self._item = item |
|
18 |
self._params = params |
|
19 |
self._resized = True |
|
20 |
|
|
21 |
def undo(self): |
|
22 |
"""undo""" |
|
23 |
if type(self._item) is QEngineeringLineItem: |
|
24 |
positions = [] |
|
25 |
for idx, conn in enumerate(self._item.connectors): |
|
26 |
positions.append(QPointF(conn.center()[0], conn.center()[1])) |
|
27 |
conn.setPos(self._params[idx]) |
|
28 |
self._item.setLine(self._params[0].x(), self._params[0].y(), self._params[-1].x(), self._params[-1].y()) |
|
29 |
self._item.update_arrow() |
|
30 |
|
|
31 |
self._params = positions |
|
32 |
|
|
33 |
self._scene.update() |
|
34 |
self._resized = False |
|
35 |
|
|
36 |
def redo(self): |
|
37 |
"""redo""" |
|
38 |
|
|
39 |
if not self._resized: |
|
40 |
if type(self._item) is QEngineeringLineItem: |
|
41 |
positions = [] |
|
42 |
for idx, conn in enumerate(self._item.connectors): |
|
43 |
positions.append(QPointF(conn.center()[0], conn.center()[1])) |
|
44 |
conn.setPos(self._params[idx]) |
|
45 |
self._item.setLine(self._params[0].x(), self._params[0].y(), self._params[-1].x(), self._params[-1].y()) |
|
46 |
self._item.update_arrow() |
|
47 |
|
|
48 |
self._params = positions |
DTI_PID/DTI_PID/QtImageViewerScene.py | ||
---|---|---|
108 | 108 |
|
109 | 109 |
super(QtImageViewerScene, self).keyReleaseEvent(event) |
110 | 110 |
|
111 |
def clear(self): |
|
112 |
"""clear undo stack""" |
|
113 |
self._undo_stack.clear() |
|
114 |
super(QtImageViewerScene, self).clear() |
|
115 |
|
|
111 | 116 |
def drawForeground(self, painter: QPainter, rect: QRectF) -> None: |
112 | 117 |
"""draw foreground""" |
113 | 118 |
if self.contours: |
DTI_PID/DTI_PID/Shapes/EngineeringConnectorItem.py | ||
---|---|---|
58 | 58 |
self.connectPoint = None |
59 | 59 |
self._hoverItem = None |
60 | 60 |
self._dir = None |
61 |
self._pressed_position = None |
|
61 | 62 |
|
62 | 63 |
self.setAcceptHoverEvents(True) |
63 | 64 |
self.transfer = Transfer() |
... | ... | |
75 | 76 |
self._label.setFont(font) |
76 | 77 |
|
77 | 78 |
@property |
79 |
def pressed_position(self): |
|
80 |
return self._pressed_position |
|
81 |
|
|
82 |
@property |
|
78 | 83 |
def label(self): |
79 | 84 |
return self._label.text() |
80 | 85 |
|
... | ... | |
214 | 219 |
''' |
215 | 220 |
|
216 | 221 |
def setPos(self, pos): |
217 |
self._loc = [pos[0], pos[1]] |
|
222 |
self._loc = [pos.x(), pos.y()] if type(pos) is QPointF else [pos[0], pos[1]]
|
|
218 | 223 |
self.setRect(self._loc[0] - round(self.SMALL_SIZE * 0.5), self._loc[1] - round(self.SMALL_SIZE * 0.5), |
219 | 224 |
self.SMALL_SIZE, self.SMALL_SIZE) |
220 | 225 |
self.update() |
... | ... | |
300 | 305 |
def mousePressEvent(self, event): |
301 | 306 |
if self.parentItem() is not None: |
302 | 307 |
if event.buttons() == Qt.LeftButton: |
303 |
self._savedPos = self._loc
|
|
308 |
self._pressed_position = QPointF(self.center()[0], self.center()[1])
|
|
304 | 309 |
self._savedConnectedItem = self.connectedItem |
305 |
# self.grabKeyboard() |
|
306 | 310 |
|
307 | 311 |
QGraphicsEllipseItem.mousePressEvent(self, event) |
308 | 312 |
|
... | ... | |
322 | 326 |
try: |
323 | 327 |
if not self.symbol: |
324 | 328 |
pass |
325 |
elif self.parentItem() is not None and hasattr(self, '_savedPos') and self._savedPos is not None:
|
|
329 |
elif self.parentItem() is not None and hasattr(self, '_pressed_position') and self._pressed_position is not None:
|
|
326 | 330 |
items = [item for item in self.scene().items(event.scenePos()) if |
327 | 331 |
item is not self and item is not self.parentItem() and \ |
328 | 332 |
(issubclass(type(item), SymbolSvgItem) or issubclass(type(item), |
... | ... | |
381 | 385 |
## up to here |
382 | 386 |
|
383 | 387 |
if self.parentItem() is not None: |
384 |
self._savedPos = None |
|
385 | 388 |
self._savedConnectedItem = None |
386 | 389 |
self.transfer.onPosChanged.emit(self) |
390 |
self._pressed_position = None |
|
387 | 391 |
finally: |
388 | 392 |
# self.ungrabKeyboard() |
389 | 393 |
pass |
... | ... | |
403 | 407 |
from EngineeringArrowItem import QEngineeringArrowItem |
404 | 408 |
from EngineeringTextItem import QEngineeringTextItem |
405 | 409 |
|
406 |
if self.parentItem() is not None and hasattr(self, '_savedPos') and self._savedPos is not None:
|
|
410 |
if self.parentItem() is not None and hasattr(self, '_pressed_position') and self._pressed_position is not None:
|
|
407 | 411 |
if event.buttons() == Qt.LeftButton: |
408 | 412 |
items = [item for item in self.scene().items(event.scenePos()) if |
409 | 413 |
item is not self and item is not self.parent and \ |
... | ... | |
467 | 471 |
|
468 | 472 |
def keyPressEvent(self, event): |
469 | 473 |
if event.key() == Qt.Key_Escape: |
470 |
if hasattr(self, '_savedPos') and self._savedPos is not None:
|
|
471 |
self.setPos(self._savedPos)
|
|
474 |
if hasattr(self, '_pressed_position') and self._pressed_position is not None:
|
|
475 |
self.setPos(self._pressed_position)
|
|
472 | 476 |
self.connectedItem = self._savedConnectedItem |
473 |
self._savedPos = None
|
|
477 |
self._pressed_position = None
|
|
474 | 478 |
self.update() |
475 | 479 |
elif event.key() == Qt.Key_F: |
476 | 480 |
if self._drawing_mode == QEngineeringConnectorItem.AXIS_MODE: |
DTI_PID/DTI_PID/Shapes/EngineeringLineItem.py | ||
---|---|---|
239 | 239 |
line_type_style = self.line_type_style |
240 | 240 |
if line_type_style: |
241 | 241 |
_pen = self.pen() |
242 |
c = QColor() |
|
243 |
c.setNamedColor(line_type_style[1]) |
|
244 |
_pen.setColor(c) |
|
242 | 245 |
_pen.setWidth(line_type_style[2]) |
243 | 246 |
_pen.setStyle(line_type_style[3]) |
244 | 247 |
self.setPen(_pen) |
... | ... | |
1925 | 1928 |
|
1926 | 1929 |
self.scene().contents_changed.emit() |
1927 | 1930 |
|
1931 |
# register resize command |
|
1932 |
pt_start = self.connectors[0].pressed_position if self.connectors[0].pressed_position else None |
|
1933 |
pt_end = self.connectors[-1].pressed_position if self.connectors[-1].pressed_position else None |
|
1934 |
if pt_start or pt_end: |
|
1935 |
from ResizeCommand import ResizeCommand |
|
1936 |
cmd = ResizeCommand(self.scene(), self, |
|
1937 |
[pt_start if pt_start else |
|
1938 |
QPointF(self.connectors[0].center()[0], self.connectors[0].center()[1]), |
|
1939 |
pt_end if pt_end else |
|
1940 |
QPointF(self.connectors[-1].center()[0], self.connectors[-1].center()[-1])]) |
|
1941 |
self.scene().undo_stack.push(cmd) |
|
1942 |
|
|
1928 | 1943 |
''' |
1929 | 1944 |
@brief |
1930 | 1945 |
@author humkyung |
build.bat | ||
---|---|---|
2 | 2 |
SET hhmmss=%TIME:~0,2%-%TIME:~3,2%-%TIME:~6,2% |
3 | 3 |
SET hhmmss=%hhmmss: =0% |
4 | 4 |
|
5 |
SET PYINSTALLER="C:\Users\humkyung.DOFTECH0\AppData\Local\Programs\Python\Python37\Scripts\pyinstaller.exe" |
|
6 |
SET PYQT5="C:\Users\humkyung.DOFTECH0\AppData\Local\Programs\Python\Python37\Lib\site-packages\PyQt5" |
|
5 | 7 |
SET CANDLE="C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe" |
6 | 8 |
SET LIGHT="C:\Program Files (x86)\WiX Toolset v3.11\bin\light.exe" |
7 | 9 |
SET SIGNTOOLPATH="C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x64\signtool.exe" |
8 | 10 |
SET SIGNPATH="c:\cert\www.doftech.co.kr.pfx" |
9 | 11 |
|
10 |
pyinstaller App.spec --onedir -p "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\Lib\site-packages\PyQt5" -w --log-level=DEBUG --hidden-import=tkinter,pyqtgraph -y
|
|
12 |
%PYINSTALLER% App.spec --onedir -p %PYQT5% -w --log-level=DEBUG --hidden-import=tkinter,pyqtgraph -y
|
|
11 | 13 |
IF %ERRORLEVEL% NEQ 0 goto :ERROR |
12 | 14 |
|
13 | 15 |
:EOF |
14 | 16 |
ECHO process completed |
15 |
exit |
|
17 |
REM exit
|
|
16 | 18 |
|
17 | 19 |
:ERROR |
18 |
exit 1 |
|
20 |
REM exit 1 |
version.rc | ||
---|---|---|
6 | 6 |
ffi=FixedFileInfo( |
7 | 7 |
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4) |
8 | 8 |
# Set not needed items to zero 0. |
9 |
filevers=(1,0,$BUILD_NUMBER,0),
|
|
10 |
prodvers=(1,0,$BUILD_NUMBER,0),
|
|
9 |
filevers=(1,0,0,0),
|
|
10 |
prodvers=(1,0,0,0),
|
|
11 | 11 |
# Contains a bitmask that specifies the valid bits 'flags'r |
12 | 12 |
mask=0x3f, |
13 | 13 |
# Contains a bitmask that specifies the Boolean attributes of the file. |
... | ... | |
31 | 31 |
u'040904B0', |
32 | 32 |
[StringStruct(u'CompanyName', u'DOFTECH'), |
33 | 33 |
StringStruct(u'FileDescription', u'Image Drawing to Intelligent Drawing'), |
34 |
StringStruct(u'FileVersion', u'1.0.$BUILD_NUMBER.0'),
|
|
34 |
StringStruct(u'FileVersion', u'1.0.0.0'),
|
|
35 | 35 |
StringStruct(u'InternalName', u'ID2'), |
36 | 36 |
StringStruct(u'LegalCopyright', u'Copyright(c) DOFTECH'), |
37 | 37 |
StringStruct(u'OriginalFilename', u'ID2.exe'), |
38 | 38 |
StringStruct(u'ProductName', u'ID2'), |
39 |
StringStruct(u'ProductVersion', u'1.0.$BUILD_NUMBER.0')])
|
|
39 |
StringStruct(u'ProductVersion', u'1.0.0.0')])
|
|
40 | 40 |
]), |
41 | 41 |
VarFileInfo([VarStruct(u'Translation', [1033, 1200])]) |
42 | 42 |
] |
내보내기 Unified diff