개정판 c86b77bd
issue #1048: 작업 뷰 저장
Change-Id: Icda0333faa8fc8856dff1a6437c97e491e8dd9ad
HYTOS/HYTOS/AppDocData.py | ||
---|---|---|
1382 | 1382 |
show_progress(100) |
1383 | 1383 |
|
1384 | 1384 |
def getDrawings(self): |
1385 |
""" |
|
1386 |
@brief get drawings |
|
1387 |
@author humkyung |
|
1388 |
@date 2018.11.03 |
|
1389 |
""" |
|
1385 |
"""get drawings""" |
|
1390 | 1386 |
from Drawing import Drawing |
1391 | 1387 |
|
1392 | 1388 |
res = [] |
1393 | 1389 |
# Creates or opens a file called mydb with a SQLite3 DB |
1394 | 1390 |
dbPath = self.getAppDbPath() |
1395 |
conn = sqlite3.connect(dbPath) |
|
1396 |
conn.execute('PRAGMA foreign_keys = ON') |
|
1397 |
with conn: |
|
1391 |
with sqlite3.connect(dbPath) as conn: |
|
1392 |
conn.execute('PRAGMA foreign_keys = ON') |
|
1398 | 1393 |
try: |
1399 | 1394 |
conn.row_factory = sqlite3.Row |
1400 | 1395 |
# Get a cursor object |
1401 | 1396 |
cursor = conn.cursor() |
1402 | 1397 |
|
1403 |
sql = 'select UID,[NAME],[DATETIME] from Drawings' |
|
1398 |
sql = 'select UID,[NAME],[DATETIME],' \ |
|
1399 |
'IFNULL(B.[X], 0) as X, IFNULL(B.[Y], 0) as Y,' \ |
|
1400 |
'IFNULL(B.[Width], 0) as Width, IFNULL(B.[Height], 0) as Height from ' \ |
|
1401 |
'Drawings A left join Views B on A.UID=B.Drawings_UID' |
|
1404 | 1402 |
cursor.execute(sql) |
1405 | 1403 |
rows = cursor.fetchall() |
1406 | 1404 |
for row in rows: |
1407 | 1405 |
if os.path.exists(row[1]): |
1408 |
res.append(Drawing(row[0], row[1], row[2])) |
|
1406 |
rect = QRectF(float(row['X']), float(row['Y']), float(row['Width']), float(row['Height'])) |
|
1407 |
res.append(Drawing(row[0], row[1], row[2], rect)) |
|
1409 | 1408 |
# Catch the exception |
1410 | 1409 |
except Exception as ex: |
1411 | 1410 |
# Roll back any change if something goes wrong |
1412 | 1411 |
conn.rollback() |
1413 | 1412 |
from App import App |
1414 | 1413 |
|
1415 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
|
|
1416 |
sys.exc_info()[-1].tb_lineno)
|
|
1414 |
message = f"error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:" \
|
|
1415 |
f"{sys.exc_info()[-1].tb_lineno}"
|
|
1417 | 1416 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
1418 | 1417 |
|
1419 | 1418 |
return res |
... | ... | |
1429 | 1428 |
|
1430 | 1429 |
# Creates or opens a file called mydb with a SQLite3 DB |
1431 | 1430 |
dbPath = self.getAppDbPath() |
1432 |
conn = sqlite3.connect(dbPath) |
|
1433 |
conn.execute('PRAGMA foreign_keys = ON') |
|
1434 |
with conn: |
|
1431 |
with sqlite3.connect(dbPath) as conn: |
|
1432 |
conn.execute('PRAGMA foreign_keys = ON') |
|
1435 | 1433 |
try: |
1436 | 1434 |
# Get a cursor object |
1437 | 1435 |
cursor = conn.cursor() |
1438 | 1436 |
|
1439 | 1437 |
sql = """update Drawings |
1440 |
set Name = ? |
|
1441 |
, DateTime = ? |
|
1442 |
where uid = ?""" |
|
1443 |
param = (drawing[0][1], drawing[0][2], drawing[0][0]) |
|
1438 |
set Name=?,DateTime=? where UID = ?""" |
|
1439 |
param = (drawing.path, drawing.date_time, drawing.UID) |
|
1444 | 1440 |
cursor.execute(sql, param) |
1445 | 1441 |
|
1446 | 1442 |
conn.commit() |
1447 |
|
|
1448 | 1443 |
# Catch the exception |
1449 | 1444 |
except Exception as ex: |
1450 | 1445 |
# Roll back any change if something goes wrong |
1451 | 1446 |
conn.rollback() |
1452 | 1447 |
from App import App |
1453 | 1448 |
|
1454 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
|
|
1455 |
sys.exc_info()[-1].tb_lineno)
|
|
1449 |
message = f"error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:" \
|
|
1450 |
f"{sys.exc_info()[-1].tb_lineno}"
|
|
1456 | 1451 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
1457 | 1452 |
|
1453 |
self.update_view_region(drawing) |
|
1454 |
|
|
1458 | 1455 |
''' |
1459 | 1456 |
@brief save drawings |
1460 | 1457 |
@author humkyung |
... | ... | |
1477 | 1474 |
|
1478 | 1475 |
conn.commit() |
1479 | 1476 |
|
1480 |
if not os.path.exists(drawing.path): copyfile(self.getTemplateDbPath(), drawing.path) |
|
1477 |
if not os.path.exists(drawing.path): |
|
1478 |
copyfile(self.getTemplateDbPath(), drawing.path) |
|
1481 | 1479 |
# Catch the exception |
1482 | 1480 |
except Exception as ex: |
1483 | 1481 |
# Roll back any change if something goes wrong |
... | ... | |
1488 | 1486 |
sys.exc_info()[-1].tb_lineno) |
1489 | 1487 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
1490 | 1488 |
|
1489 |
self.update_view_region(drawing) |
|
1490 |
|
|
1491 |
def update_view_region(self, drawing): |
|
1492 |
"""update view region""" |
|
1493 |
with sqlite3.connect(self.getAppDbPath()) as conn: |
|
1494 |
try: |
|
1495 |
# Get a cursor object |
|
1496 |
cursor = conn.cursor() |
|
1497 |
|
|
1498 |
# check if there is view region |
|
1499 |
sql = f"select count(*) from Views where Drawings_UID=?" |
|
1500 |
params = [drawing.UID] |
|
1501 |
cursor.execute(sql, params) |
|
1502 |
rows = cursor.fetchall() |
|
1503 |
if rows[0][0]: |
|
1504 |
sql = f"update Views set X=?,Y=?,Width=?,Height=? where Drawings_UID=?" |
|
1505 |
params = (drawing.view_rect.x(), drawing.view_rect.y(), |
|
1506 |
drawing.view_rect.width(), drawing.view_rect.height(), drawing.UID) |
|
1507 |
else: |
|
1508 |
sql = f"insert into Views(Drawings_UID,X,Y,Width,Height) values(?,?,?,?,?)" |
|
1509 |
params = (drawing.UID, drawing.view_rect.x(), drawing.view_rect.y(), |
|
1510 |
drawing.view_rect.width(), drawing.view_rect.height()) |
|
1511 |
|
|
1512 |
cursor.execute(sql, params) |
|
1513 |
conn.commit() |
|
1514 |
# Catch the exception |
|
1515 |
except Exception as ex: |
|
1516 |
from App import App |
|
1517 |
message = f"error occurred({repr(ex)}\\n{sql}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:" \ |
|
1518 |
f"{sys.exc_info()[-1].tb_lineno}" |
|
1519 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
|
1520 |
|
|
1491 | 1521 |
''' |
1492 | 1522 |
@brief Return Symbol Category Items |
1493 | 1523 |
@author yeonjin |
HYTOS/HYTOS/Commands/SaveWorkCommand.py | ||
---|---|---|
1 |
# coding: utf-8 |
|
2 |
""" This is SaveWork command module """ |
|
3 |
import os.path |
|
4 |
import sys |
|
5 |
from enum import Enum |
|
6 |
from PyQt5.QtCore import * |
|
7 |
from PyQt5.QtGui import * |
|
8 |
from PyQt5.QtWidgets import * |
|
9 |
|
|
10 |
class SaveWorkCommand(QThread): |
|
11 |
display_message = pyqtSignal(Enum, str) |
|
12 |
|
|
13 |
def __init__(self): |
|
14 |
QThread.__init__(self) |
|
15 |
self.resultStr = None |
|
16 |
|
|
17 |
def __del__(self): |
|
18 |
self.wait() |
|
19 |
|
|
20 |
def run(self): |
|
21 |
""" do given work""" |
|
22 |
from datetime import datetime |
|
23 |
from AppDocData import AppDocData |
|
24 |
from AppDocData import MessageType |
|
25 |
from SymbolSvgItem import SymbolSvgItem |
|
26 |
from EngineeringStreamlineItem import QEngineeringStreamlineItem |
|
27 |
|
|
28 |
try: |
|
29 |
appDocData = AppDocData.instance() |
|
30 |
items = appDocData.activeDrawing.allItems |
|
31 |
|
|
32 |
dbItems = [item for item in items if type(item) is SymbolSvgItem or type(item) is QEngineeringStreamlineItem] |
|
33 |
appDocData.saveToDatabase(dbItems) |
|
34 |
|
|
35 |
activeDrawing = appDocData.activeDrawing |
|
36 |
if activeDrawing is not None: |
|
37 |
activeDrawing.hmbTable.saveData() |
|
38 |
|
|
39 |
self.resultStr = SaveWorkCommand.save_to_database() |
|
40 |
|
|
41 |
""" update drawing's modified time """ |
|
42 |
drawings = appDocData.getDrawings() |
|
43 |
drawing = [drawing for drawing in drawings if appDocData.imgName == os.path.splitext(drawing[1])[0]] |
|
44 |
if drawing[0]: |
|
45 |
drawing[0][2] = datetime.now().strftime('%Y-%m-%d %H:%M:%S') |
|
46 |
appDocData.updateDrawing(drawing) |
|
47 |
except Exception as ex: |
|
48 |
from App import App |
|
49 |
|
|
50 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
|
51 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
|
52 |
|
|
53 |
@staticmethod |
|
54 |
def save_to_database(): |
|
55 |
""" save recognized items to database """ |
|
56 |
from AppDocData import AppDocData |
|
57 |
from SymbolSvgItem import SymbolSvgItem |
|
58 |
from EngineeringStreamlineItem import QEngineeringStreamlineItem |
|
59 |
|
|
60 |
appDocData = AppDocData.instance() |
|
61 |
items = appDocData.activeDrawing.allItems |
|
62 |
|
|
63 |
symbolCount = 0 |
|
64 |
streamCount = 0 |
|
65 |
|
|
66 |
for item in items: |
|
67 |
if type(item) is SymbolSvgItem: |
|
68 |
symbolCount += 1 |
|
69 |
elif type(item) is QEngineeringStreamlineItem: |
|
70 |
streamCount += 1 |
|
71 |
|
|
72 |
resultStr = "Symbol(s) = {}, Stream Line(s) = {}".format(symbolCount, streamCount) |
|
73 |
|
|
74 |
return resultStr |
|
75 |
|
|
76 |
@staticmethod |
|
77 |
def save(): |
|
78 |
""" do given work""" |
|
79 |
from datetime import datetime |
|
80 |
from AppDocData import AppDocData |
|
81 |
from AppDocData import MessageType |
|
82 |
from SymbolSvgItem import SymbolSvgItem |
|
83 |
from EngineeringStreamlineItem import QEngineeringStreamlineItem |
|
84 |
from HMBTable import HMBData |
|
85 |
|
|
86 |
try: |
|
87 |
appDocData = AppDocData.instance() |
|
88 |
items = appDocData.activeDrawing.allItems |
|
89 |
|
|
90 |
dbItems = [item for item in items if type(item) is SymbolSvgItem or type(item) is QEngineeringStreamlineItem] |
|
91 |
appDocData.saveToDatabase(dbItems) |
|
92 |
|
|
93 |
activeDrawing = appDocData.activeDrawing |
|
94 |
if activeDrawing is not None: |
|
95 |
activeDrawing.hmbTable.saveData() |
|
96 |
|
|
97 |
self.resultStr = SaveWorkCommand.save_to_database() |
|
98 |
|
|
99 |
except Exception as ex: |
|
100 |
from App import App |
|
101 |
|
|
102 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
|
103 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
HYTOS/HYTOS/Drawing.py | ||
---|---|---|
1 | 1 |
# coding: utf-8 |
2 | 2 |
import os |
3 | 3 |
import uuid |
4 |
from PyQt5.QtCore import * |
|
4 | 5 |
from AppDocData import AppDocData |
5 | 6 |
|
7 |
|
|
6 | 8 |
class Drawing: |
7 | 9 |
''' |
8 | 10 |
@brief construction |
9 | 11 |
@author humkyung |
10 | 12 |
@date 2018.07.07 |
11 | 13 |
''' |
12 |
def __init__(self, UID, path, date_time): |
|
14 |
def __init__(self, UID, path, date_time, rect: QRectF = QRectF()):
|
|
13 | 15 |
app_doc_data = AppDocData.instance() |
14 | 16 |
|
15 |
self._attrs = [['Drawing No', ''], ['Rev No', ''], ['Units', '']] # attributes |
|
17 |
self._attrs = [['Drawing No', ''], ['Rev No', ''], ['Units', '']] # attributes
|
|
16 | 18 |
|
17 | 19 |
self.UID = UID |
18 | 20 |
self.path = path |
... | ... | |
23 | 25 |
self._hmbTable = None |
24 | 26 |
self._modified = False |
25 | 27 |
self._loops = [] |
28 |
self._view_rect = rect |
|
26 | 29 |
|
27 | 30 |
@property |
28 | 31 |
def loops(self): |
... | ... | |
109 | 112 |
@hmbTable.setter |
110 | 113 |
def hmbTable(self, value): |
111 | 114 |
self._hmbTable = value |
115 |
|
|
116 |
@property |
|
117 |
def view_rect(self): |
|
118 |
return self._view_rect |
|
119 |
|
|
120 |
@view_rect.setter |
|
121 |
def view_rect(self, value): |
|
122 |
self._view_rect = value |
HYTOS/HYTOS/MainWindow.py | ||
---|---|---|
346 | 346 |
else: |
347 | 347 |
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tabLogs), 'Logs') |
348 | 348 |
|
349 |
def closeEvent(self, a0: QCloseEvent) -> None:
|
|
349 |
def closeEvent(self, event: QCloseEvent) -> None:
|
|
350 | 350 |
"""save geometry and state and then ask user to save drawing which is modified""" |
351 | 351 |
|
352 | 352 |
self.settings.setValue('geometry', self.saveGeometry()) |
353 | 353 |
self.settings.setValue('windowState', self.saveState()) |
354 | 354 |
|
355 | 355 |
self.save_drawing_if_necessary() |
356 |
a0.accept() |
|
356 |
|
|
357 |
"""update view region""" |
|
358 |
app_doc_data = AppDocData.instance() |
|
359 |
if app_doc_data.activeDrawing: |
|
360 |
rect = self.graphicsView.viewport().rect() |
|
361 |
app_doc_data.activeDrawing.view_rect = self.graphicsView.mapToScene(rect).boundingRect() |
|
362 |
app_doc_data.update_view_region(app_doc_data.activeDrawing) |
|
363 |
"""up to here""" |
|
364 |
|
|
365 |
event.accept() |
|
357 | 366 |
|
358 | 367 |
def openContextMenu(self, position): |
359 | 368 |
indexes = self.treeWidgetDrawingList.selectedIndexes() |
... | ... | |
906 | 915 |
|
907 | 916 |
"""update drawing's modified time""" |
908 | 917 |
drawings = app_doc_data.getDrawings() |
909 |
drawing = [drawing for drawing in drawings if app_doc_data.activeDrawing == drawing]
|
|
918 |
drawing = [drawing for drawing in drawings if app_doc_data.activeDrawing.UID == drawing.UID]
|
|
910 | 919 |
if drawing: |
911 |
drawing.date_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') |
|
912 |
app_doc_data.updateDrawing(drawing) |
|
920 |
drawing[0].date_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S') |
|
921 |
rect = self.graphicsView.viewport().rect() |
|
922 |
drawing[0].view_rect = self.graphicsView.mapToScene(rect).boundingRect() |
|
923 |
app_doc_data.updateDrawing(drawing[0]) |
|
913 | 924 |
|
914 | 925 |
app_doc_data.activeDrawing.modified = False |
915 | 926 |
self.setMainWindowTitle(f"{app_doc_data.activeDrawing.path}") |
916 | 927 |
|
917 | 928 |
except Exception as ex: |
918 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
|
|
919 |
sys.exc_info()[-1].tb_lineno)
|
|
929 |
message = f"error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:" \
|
|
930 |
f"{sys.exc_info()[-1].tb_lineno}"
|
|
920 | 931 |
self.addMessage.emit(MessageType.Error, message) |
921 | 932 |
|
922 | 933 |
''' |
... | ... | |
961 | 972 |
cmd.onRejected.connect(self.onCommandRejected) |
962 | 973 |
self.graphicsView.command = cmd |
963 | 974 |
|
964 |
''' |
|
965 |
@brief Fit Window |
|
966 |
@author Jeongwoo |
|
967 |
@date 2018.06.27 |
|
968 |
@history 2018.06.27 Jeongwoo Chnage method to initialize command [Set None → DefaultCommand] |
|
969 |
''' |
|
970 |
|
|
971 | 975 |
def fitWindow(self, action): |
976 |
"""fit window""" |
|
972 | 977 |
app_doc_data = AppDocData.instance() |
973 | 978 |
if app_doc_data.activeDrawing: |
974 | 979 |
self.graphicsView.useDefaultCommand() |
... | ... | |
983 | 988 |
scene_rect.setBottom(841) |
984 | 989 |
|
985 | 990 |
self.graphicsView.setSceneRect(scene_rect) |
986 |
self.graphicsView.zoomImageInit() |
|
991 |
if action is None and app_doc_data.activeDrawing.view_rect.isValid(): |
|
992 |
self.graphicsView.zoom_rect(app_doc_data.activeDrawing.view_rect) |
|
993 |
else: |
|
994 |
self.graphicsView.zoomImageInit() |
|
987 | 995 |
self.graphicsView.scene.invalidate() |
988 | 996 |
|
989 | 997 |
def on_view_connector(self, checked): |
HYTOS/HYTOS/QtImageViewer.py | ||
---|---|---|
213 | 213 |
|
214 | 214 |
return fileName |
215 | 215 |
|
216 |
def zoom_rect(self, rect: QRectF) -> None: |
|
217 |
"""zoom window within given rectangle""" |
|
218 |
self.fitInView(rect, Qt.KeepAspectRatio) |
|
219 |
if not self.zoomStack: |
|
220 |
self.zoomStack = [] |
|
221 |
|
|
222 |
self.zoomStack.append(rect) |
|
223 |
|
|
216 | 224 |
def updateViewer(self, zoomNewRect=None): |
217 | 225 |
"""Show current zoom (if showing entire image, apply current aspect ratio mode).""" |
218 | 226 |
if self.zoomStack: |
HYTOS/HYTOS/Scripts/App.sql | ||
---|---|---|
1 |
CREATE TABLE IF NOT EXISTS Views ( |
|
2 |
Drawings_UID VARCHAR (37) REFERENCES Drawings (UID) ON DELETE CASCADE, |
|
3 |
X REAL DEFAULT (0), |
|
4 |
Y REAL DEFAULT (0), |
|
5 |
Width REAL DEFAULT (0), |
|
6 |
Height REAL DEFAULT (0) |
|
7 |
); |
|
8 |
|
|
1 | 9 |
CREATE TABLE IF NOT EXISTS Configuration ( |
2 | 10 |
Section VARCHAR(37) NOT NULL, |
3 | 11 |
[Key] VARCHAR(37) NOT NULL, |
내보내기 Unified diff