hytos / DTI_PID / DTI_PID / Shapes / EngineeringLineNoTextItem.py @ fceaf69c
이력 | 보기 | 이력해설 | 다운로드 (63.3 KB)
1 |
# coding: utf-8
|
---|---|
2 |
""" This is engineering line no text item module """
|
3 |
|
4 |
import os.path |
5 |
import sys |
6 |
import copy |
7 |
|
8 |
from EngineeringFromMarkItem import EngineeringFromMarkItem |
9 |
from EngineeringToMarkItem import EngineeringToMarkItem |
10 |
|
11 |
try:
|
12 |
from PyQt5.QtCore import * |
13 |
from PyQt5.QtGui import * |
14 |
from PyQt5.QtWidgets import * |
15 |
except ImportError: |
16 |
try:
|
17 |
from PyQt4.QtCore import Qt, QRectF, pyqtSignal, QT_VERSION_STR, QRect |
18 |
from PyQt4.QtGui import QGraphicsView, QGraphicsScene, QImage, QPixmap, QPainterPath, QFileDialog, QFont |
19 |
except ImportError: |
20 |
raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.") |
21 |
|
22 |
#from UserInputAttribute import UserInputAttribute
|
23 |
from OcrResultDialog import QOcrResultDialog |
24 |
from AppDocData import AppDocData |
25 |
from EngineeringTextItem import QEngineeringTextItem |
26 |
from TextInfo import TextInfo |
27 |
|
28 |
lineColumnList = ['UID', 'LINE_SIZE', 'LINE_SYMBOL', 'LINE_NO', 'LINE_CLASS', 'LINE_ROUTING_FROM', 'LINE_ROUTING_TO', |
29 |
'SERVICE_FLUID', 'SERVICE_DENSITY', 'SERVICE_STATE', 'OPERATION_CONDITION_TEMP', |
30 |
'OPERATION_CONDITION_PRESS', 'DESIGN_CONDITION_TEMP', 'DESIGN_CONDITION_PRESS', 'TEST_CONDITION_TEMP', |
31 |
'TEST_CONDITION_PRESS', 'INSUL_CODE', 'PAINT_CODE', 'NDE_CODE', 'PWHT', 'PNID_NO'] |
32 |
|
33 |
|
34 |
class QEngineeringLineNoTextItem(QEngineeringTextItem): |
35 |
'''
|
36 |
@history 18.05.14 Jeongwoo Add variable self.runs
|
37 |
humkyung 2018.07.09 add stream no
|
38 |
'''
|
39 |
|
40 |
def __init__(self, uid=None, parent=None): |
41 |
from SymbolAttr import SymbolProp |
42 |
from EngineeringFreezeItem import QEngineeringFreezeItem |
43 |
|
44 |
QEngineeringTextItem.__init__(self, uid, parent)
|
45 |
|
46 |
self._properties = { SymbolProp(None, 'From', 'Comp Item'): None, \ |
47 |
SymbolProp(None, 'To', 'Comp Item'): None, \ |
48 |
SymbolProp(None, 'Config', 'String'): None } # , SymbolProp(None, 'Freeze', 'Boolean'):False} |
49 |
self._runs = []
|
50 |
|
51 |
self.lineNoFromToIndicator = []
|
52 |
self.lineNoFromToIndicatorShowFlag = False |
53 |
|
54 |
""" create freeze control """
|
55 |
# self.freeze_item = QEngineeringFreezeItem(-QEngineeringFreezeItem.FREEZE_SIZE*0.5, -QEngineeringFreezeItem.FREEZE_SIZE*0.5, QEngineeringFreezeItem.FREEZE_SIZE, QEngineeringFreezeItem.FREEZE_SIZE)
|
56 |
# self.freeze_item.setParentItem(self)
|
57 |
# self.freeze_item.setZValue(self.zValue() + 1)
|
58 |
# self.freeze_item.setPen(Qt.black)
|
59 |
|
60 |
@property
|
61 |
def Size(self): |
62 |
""" return line no's size """
|
63 |
attrs = self.getAttributes()
|
64 |
matches = [value for attr, value in attrs.items() if attr.Attribute.upper() == 'NOMINALDIAMETER'] |
65 |
return matches[0] if matches else '' |
66 |
|
67 |
def empty(self): |
68 |
""" return True if run is empty else return False """
|
69 |
return False if self._runs else True |
70 |
|
71 |
#def setVisible(self, visible):
|
72 |
# """ override visible value """
|
73 |
# super(QEngineeringTextItem, self).setVisible(visible)
|
74 |
# for run in self.runs:
|
75 |
# run.visible = visible
|
76 |
|
77 |
@property
|
78 |
def connected_line(self): |
79 |
"""return connected line"""
|
80 |
if self.conns: |
81 |
if type(self.conns[0]) is str: |
82 |
matches = [x for x in self.scene().items() if hasattr(x, 'uid') and str(x.uid) == str(self.conns[0])] |
83 |
if matches:
|
84 |
self.conns[0] = matches[0] |
85 |
|
86 |
return self.conns[0] |
87 |
|
88 |
return None |
89 |
|
90 |
'''
|
91 |
@brief getter of runs
|
92 |
@author humkyung
|
93 |
@date 2018.05.11
|
94 |
'''
|
95 |
|
96 |
@property
|
97 |
def runs(self): |
98 |
return self._runs |
99 |
|
100 |
'''
|
101 |
@brief setter of runs
|
102 |
@author humkyung
|
103 |
@date 2018.05.11
|
104 |
'''
|
105 |
|
106 |
@runs.setter
|
107 |
def runs(self, value): |
108 |
self._runs = value
|
109 |
|
110 |
def hoverEnterEvent(self, event): |
111 |
""" highlight line no text and run's item """
|
112 |
from App import App |
113 |
|
114 |
try:
|
115 |
self.hover = True |
116 |
self.update()
|
117 |
|
118 |
for run in self.runs: |
119 |
for item in run.items: |
120 |
item.hoverEnterEvent(event, True)
|
121 |
|
122 |
# display from / to indicator
|
123 |
if not self.lineNoFromToIndicatorShowFlag: |
124 |
if not self.lineNoFromToIndicator or len(self.lineNoFromToIndicator) < 2: |
125 |
if run is self.runs[0] and (item is run.items[0] or item is run.items[-1]): |
126 |
_label = EngineeringFromMarkItem(10, color=self._color) \ |
127 |
if not self.lineNoFromToIndicator else EngineeringToMarkItem(10, color=self._color) |
128 |
_label.setZValue(500)
|
129 |
self.scene().addItem(_label)
|
130 |
#_label.setParentItem(self)
|
131 |
_label.setPos(QPointF(item.origin[0], item.origin[1])) |
132 |
self.lineNoFromToIndicator.append(_label)
|
133 |
elif self.lineNoFromToIndicator: |
134 |
if run is self.runs[0] and (item is run.items[0]): |
135 |
self.lineNoFromToIndicator[0].setPos(QPointF(item.origin[0], item.origin[1])) |
136 |
self.lineNoFromToIndicator[0].setVisible(True) |
137 |
elif run is self.runs[0] and (item is run.items[-1]): |
138 |
self.lineNoFromToIndicator[1].setPos(QPointF(item.origin[0], item.origin[1])) |
139 |
self.lineNoFromToIndicator[1].setVisible(True) |
140 |
|
141 |
if not self.runs: |
142 |
_from = self.prop('From') |
143 |
_to = self.prop('To') |
144 |
if _from and _to: |
145 |
for item in [_from, _to]: |
146 |
# display from / to indicator
|
147 |
if not self.lineNoFromToIndicator or len(self.lineNoFromToIndicator) < 2: |
148 |
_label = EngineeringFromMarkItem(10, color=self._color) \ |
149 |
if not self.lineNoFromToIndicator else EngineeringToMarkItem(10, color=self._color) |
150 |
_label.setZValue(500)
|
151 |
self.scene().addItem(_label)
|
152 |
_label.setPos(QPointF(item.origin[0], item.origin[1])) |
153 |
self.lineNoFromToIndicator.append(_label)
|
154 |
elif self.lineNoFromToIndicator: |
155 |
if item is _from: |
156 |
self.lineNoFromToIndicator[0].setPos(QPointF(item.origin[0], item.origin[1])) |
157 |
self.lineNoFromToIndicator[0].setVisible(True) |
158 |
elif item is _to: |
159 |
self.lineNoFromToIndicator[1].setPos(QPointF(item.origin[0], item.origin[1])) |
160 |
self.lineNoFromToIndicator[1].setVisible(True) |
161 |
|
162 |
except Exception as ex: |
163 |
from App import App |
164 |
from AppDocData import MessageType |
165 |
|
166 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
167 |
sys.exc_info()[-1].tb_lineno)
|
168 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
169 |
|
170 |
def contextMenuEvent(self, event): |
171 |
items = self.scene().selectedItems()
|
172 |
menu = QMenu() |
173 |
if len(items) == 1 and self in items: |
174 |
'''
|
175 |
explodeAction = QAction('Explode', None)
|
176 |
explodeAction.triggered.connect(self.contextExplode)
|
177 |
menu.addAction(explodeAction)
|
178 |
|
179 |
explodeKeepAction = QAction('Explode(keep from, to)', None)
|
180 |
explodeKeepAction.triggered.connect(self.contextExplodeKeep)
|
181 |
menu.addAction(explodeKeepAction)
|
182 |
'''
|
183 |
|
184 |
explodeAction = QAction('Explode', None) |
185 |
explodeAction.triggered.connect(self.contextExplode)
|
186 |
menu.addAction(explodeAction) |
187 |
|
188 |
explodeKeepAction = QAction('Explode(keep from, to)', None) |
189 |
explodeKeepAction.triggered.connect(self.contextExplodeKeep)
|
190 |
menu.addAction(explodeKeepAction) |
191 |
|
192 |
freezeAction = QAction("Freeze Attributes of All Child Items" , None) |
193 |
freezeAction.triggered.connect(lambda: self.freeze_attriute(True)) |
194 |
menu.addAction(freezeAction) |
195 |
|
196 |
unfreezeAction = QAction("Un-Freeze Attributes of All Child Items" , None) |
197 |
unfreezeAction.triggered.connect(lambda: self.freeze_attriute(False)) |
198 |
menu.addAction(unfreezeAction) |
199 |
|
200 |
fromAction = QAction('Set From(S)', None) |
201 |
fromAction.triggered.connect(self.contextFrom)
|
202 |
menu.addAction(fromAction) |
203 |
|
204 |
toAction = QAction('Set To(D)', None) |
205 |
toAction.triggered.connect(self.contextTo)
|
206 |
menu.addAction(toAction) |
207 |
|
208 |
showAction = QAction('Show From, To(H)', None) if not self.lineNoFromToIndicatorShowFlag else QAction('Hide From, To(H)', None) |
209 |
showAction.triggered.connect(self.contextShow)
|
210 |
menu.addAction(showAction) |
211 |
|
212 |
allAction = QAction('Select All in View(A)', None) |
213 |
allAction.triggered.connect(self.contextSelectAll)
|
214 |
menu.addAction(allAction) |
215 |
|
216 |
searchAction = QAction('Search All Duplicate Line No', None) |
217 |
searchAction.triggered.connect(self.contextSearch)
|
218 |
menu.addAction(searchAction) |
219 |
|
220 |
highlightAction = QAction('Highlight', None) |
221 |
highlightAction.triggered.connect(lambda: self.contextHighlight(self)) |
222 |
menu.addAction(highlightAction) |
223 |
|
224 |
actions = [] |
225 |
for index in range(len(self.runs)): |
226 |
actions.append(QAction('Highlight Run ' + str(index + 1), None)) |
227 |
|
228 |
binding = [lambda index=index: actions[index].triggered.connect(lambda: self.contextHighlight(self.runs[index])) for index in range(len(self.runs))] |
229 |
|
230 |
for index in range(len(actions)): |
231 |
binding[index]() |
232 |
menu.addAction(actions[index]) |
233 |
|
234 |
editAction = QAction('Edit(Return)', None) |
235 |
editAction.triggered.connect(self.contextEdit)
|
236 |
menu.addAction(editAction) |
237 |
|
238 |
rotateAction = QAction('Rotate(R)', None) |
239 |
rotateAction.triggered.connect(self.contextRotate)
|
240 |
menu.addAction(rotateAction) |
241 |
|
242 |
deleteAction = QAction('Delete(E)', None) |
243 |
deleteAction.triggered.connect(self.contextDelete)
|
244 |
menu.addAction(deleteAction) |
245 |
else:
|
246 |
alignAction = QAction('Resize Selected Texts with This ', None) |
247 |
alignAction.triggered.connect(self.contextResizeText)
|
248 |
menu.addAction(alignAction) |
249 |
|
250 |
menu.exec_(event.screenPos()) |
251 |
|
252 |
def contextResizeText(self): |
253 |
textItems = [item for item in self.scene().selectedItems() if item is not self and type(item) is QEngineeringLineNoTextItem] |
254 |
allowed_error = 0.01
|
255 |
|
256 |
for text in textItems: |
257 |
if abs(self.angle - text.angle) < allowed_error: |
258 |
dx = round(self.size[0] - text.size[0]) |
259 |
dy = round(self.size[1] - text.size[1]) |
260 |
else:
|
261 |
dx = round(self.size[1] - text.size[0]) |
262 |
dy = round(self.size[0] - text.size[1]) |
263 |
|
264 |
text.size[1] = text.size[1] + dy |
265 |
if abs(text.angle - 1.57) < allowed_error or abs(text.angle - 3.14) < allowed_error: |
266 |
text.loc[1] = text.loc[1] - dy |
267 |
|
268 |
text.size[0] = text.size[0] + dx |
269 |
if abs(text.angle - 4.71) < allowed_error or abs(text.angle - 4.71) < allowed_error or abs(text.angle - 3.14) < allowed_error: |
270 |
text.loc[0] = text.loc[0] - dx |
271 |
|
272 |
text.update_font() |
273 |
text.update() |
274 |
|
275 |
def contextSearch(self): |
276 |
from App import App |
277 |
from TextItemEditDialog import QTextItemEditDialog |
278 |
|
279 |
dlgTextItemEdit = QTextItemEditDialog(App.mainWnd(), 'Line No')
|
280 |
dlgTextItemEdit.show() |
281 |
dlgTextItemEdit.exec_() |
282 |
|
283 |
def contextSelectAll(self): |
284 |
from App import App |
285 |
|
286 |
rect = App.mainWnd().graphicsView.viewport().rect() |
287 |
view_rect = App.mainWnd().graphicsView.mapToScene(rect).boundingRect() |
288 |
lineNos = [item for item in self.scene().items() if type(item) is QEngineeringLineNoTextItem and view_rect.contains(item.sceneBoundingRect().center())] |
289 |
for lineNo in lineNos: |
290 |
lineNo.setSelected(True)
|
291 |
|
292 |
def freeze_attriute(self, freeze): |
293 |
for run in self.runs: |
294 |
for item in run.items: |
295 |
item.freeze_attriute(freeze) |
296 |
|
297 |
def contextShow(self): |
298 |
self.lineNoFromToIndicatorShowFlag = not self.lineNoFromToIndicatorShowFlag |
299 |
if self.lineNoFromToIndicatorShowFlag: |
300 |
if self.runs and self.runs[0].items: |
301 |
for item in [self.runs[0].items[0], self.runs[0].items[-1]]: |
302 |
# display from / to indicator
|
303 |
if not self.lineNoFromToIndicator or len(self.lineNoFromToIndicator) < 2: |
304 |
_label = EngineeringFromMarkItem(10, color=self._color) \ |
305 |
if not self.lineNoFromToIndicator else EngineeringToMarkItem(10, color=self._color) |
306 |
_label.setZValue(500)
|
307 |
self.scene().addItem(_label)
|
308 |
_label.setPos(QPointF(item.origin[0], item.origin[1])) |
309 |
self.lineNoFromToIndicator.append(_label)
|
310 |
elif self.lineNoFromToIndicator: |
311 |
if item is self.runs[0].items[0]: |
312 |
self.lineNoFromToIndicator[0].setPos(QPointF(item.origin[0], item.origin[1])) |
313 |
self.lineNoFromToIndicator[0].setVisible(True) |
314 |
elif item is self.runs[0].items[-1]: |
315 |
self.lineNoFromToIndicator[1].setPos(QPointF(item.origin[0], item.origin[1])) |
316 |
self.lineNoFromToIndicator[1].setVisible(True) |
317 |
elif not self.runs: |
318 |
_from = self.prop('From') |
319 |
_to = self.prop('To') |
320 |
if _from and _to: |
321 |
for item in [_from, _to]: |
322 |
# display from / to indicator
|
323 |
if not self.lineNoFromToIndicator or len(self.lineNoFromToIndicator) < 2: |
324 |
_label = EngineeringFromMarkItem(10, color=self._color) \ |
325 |
if not self.lineNoFromToIndicator else EngineeringToMarkItem(10, color=self._color) |
326 |
_label.setZValue(500)
|
327 |
self.scene().addItem(_label)
|
328 |
_label.setPos(QPointF(item.origin[0], item.origin[1])) |
329 |
self.lineNoFromToIndicator.append(_label)
|
330 |
elif self.lineNoFromToIndicator: |
331 |
if item is _from: |
332 |
self.lineNoFromToIndicator[0].setPos(QPointF(item.origin[0], item.origin[1])) |
333 |
self.lineNoFromToIndicator[0].setVisible(True) |
334 |
elif item is _to: |
335 |
self.lineNoFromToIndicator[1].setPos(QPointF(item.origin[0], item.origin[1])) |
336 |
self.lineNoFromToIndicator[1].setVisible(True) |
337 |
else:
|
338 |
if self.lineNoFromToIndicator: |
339 |
for _label in self.lineNoFromToIndicator: |
340 |
_label.setVisible(False)
|
341 |
|
342 |
def contextFrom(self): |
343 |
from App import App |
344 |
import SelectAttributeCommand |
345 |
_from = None
|
346 |
for prop, value in self.properties.items(): |
347 |
if prop.Attribute == 'From': |
348 |
_from = prop |
349 |
break
|
350 |
cmd = SelectAttributeCommand.SelectAttributeCommand(self, _from, App.mainWnd().graphicsView)
|
351 |
cmd.onSuccess.connect(App.mainWnd().resultPropertyTableWidget.onSuccessSelectAttribute) |
352 |
App.mainWnd().graphicsView.command = cmd |
353 |
|
354 |
def contextTo(self): |
355 |
from App import App |
356 |
import SelectAttributeCommand |
357 |
_to = None
|
358 |
for prop, value in self.properties.items(): |
359 |
if prop.Attribute == 'To': |
360 |
_to = prop |
361 |
break
|
362 |
cmd = SelectAttributeCommand.SelectAttributeCommand(self, _to, App.mainWnd().graphicsView)
|
363 |
cmd.onSuccess.connect(App.mainWnd().resultPropertyTableWidget.onSuccessSelectAttribute) |
364 |
App.mainWnd().graphicsView.command = cmd |
365 |
|
366 |
def contextHighlight(self, item): |
367 |
from App import App |
368 |
from HighlightCommand import HighlightCommand |
369 |
HighlightCommand(App.mainWnd().graphicsView).execute(item) |
370 |
|
371 |
def contextExplode(self): |
372 |
from App import App |
373 |
App.mainWnd().itemTreeWidget.explode_line_no_from_context(self)
|
374 |
|
375 |
def contextExplodeKeep(self): |
376 |
from App import App |
377 |
App.mainWnd().itemTreeWidget.explode_line_no_from_context(self, True) |
378 |
|
379 |
def contextReverse(self): |
380 |
self.reverse()
|
381 |
|
382 |
def contextDelete(self): |
383 |
event = QKeyEvent(QEvent.KeyPress, Qt.Key_Delete, Qt.NoModifier) |
384 |
self.scene().keyPressEvent(event)
|
385 |
|
386 |
def contextEdit(self): |
387 |
event = QKeyEvent(QEvent.KeyPress, Qt.Key_Return, Qt.NoModifier) |
388 |
self.keyPressEvent(event)
|
389 |
|
390 |
def contextRotate(self): |
391 |
event = QKeyEvent(QEvent.KeyPress, Qt.Key_R, Qt.NoModifier) |
392 |
self.keyPressEvent(event)
|
393 |
|
394 |
def hoverLeaveEvent(self, event): |
395 |
""" unhighlight line no text and run's item """
|
396 |
try:
|
397 |
self.hover = False |
398 |
self.update()
|
399 |
|
400 |
for run in self.runs: |
401 |
for item in run.items: |
402 |
item.hoverLeaveEvent(event, True)
|
403 |
|
404 |
if not self.lineNoFromToIndicatorShowFlag: |
405 |
if self.lineNoFromToIndicator: |
406 |
for _label in self.lineNoFromToIndicator: |
407 |
_label.setVisible(False)
|
408 |
except Exception as ex: |
409 |
from App import App |
410 |
from AppDocData import MessageType |
411 |
|
412 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
413 |
sys.exc_info()[-1].tb_lineno)
|
414 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
415 |
|
416 |
|
417 |
def keyPressEvent(self, event): |
418 |
""" reverse line routine when user press 'C' key """
|
419 |
if event.key() == Qt.Key_C:
|
420 |
self.reverse()
|
421 |
elif event.key() == Qt.Key_S:
|
422 |
self.contextFrom()
|
423 |
elif event.key() == Qt.Key_D:
|
424 |
self.contextTo()
|
425 |
elif event.key() == Qt.Key_H:
|
426 |
self.contextShow()
|
427 |
elif event.key() == Qt.Key_A:
|
428 |
self.contextSelectAll()
|
429 |
|
430 |
QEngineeringTextItem.keyPressEvent(self, event)
|
431 |
|
432 |
def update_flow_mark(self, position, minLength): |
433 |
""" update line flow mark """
|
434 |
import math |
435 |
from EngineeringLineItem import QEngineeringLineItem |
436 |
|
437 |
allowed_error_radian = 0.09
|
438 |
|
439 |
try:
|
440 |
for run in self.runs: |
441 |
pre = None
|
442 |
preRadian = None
|
443 |
for item in run.items: |
444 |
if pre is None and type(item) is QEngineeringLineItem and item.is_piping(True) and item.length() > minLength: |
445 |
pre = item |
446 |
start = item.line().p1() |
447 |
end = item.line().p2() |
448 |
_dir = [(end.x() - start.x()) / item.length(), (end.y() - start.y()) / item.length()] |
449 |
radian = math.atan2(_dir[1], _dir[0]) - math.pi / 2 |
450 |
preRadian = radian if radian >= 0 else radian + 2 * math.pi |
451 |
preRadian = abs(preRadian - math.pi)
|
452 |
|
453 |
elif pre and type(pre) is QEngineeringLineItem and type(item) is QEngineeringLineItem and item.is_piping(True): |
454 |
start = item.line().p1() |
455 |
end = item.line().p2() |
456 |
_dir = [(end.x() - start.x()) / item.length(), (end.y() - start.y()) / item.length()] |
457 |
radian = math.atan2(_dir[1], _dir[0]) - math.pi / 2 |
458 |
currRadian = radian if radian >= 0 else radian + 2 * math.pi |
459 |
currRadian = abs(currRadian - math.pi)
|
460 |
if abs(currRadian - preRadian) > allowed_error_radian: |
461 |
# insert flow mark at pre line
|
462 |
if pre.length() > minLength:
|
463 |
# if str(pre.uid) == '62edfbe5-29fd-49af-840b-6dce051e04d1':
|
464 |
# print(math.atan2(preDir[0], preDir[1]) - math.pi / 2)
|
465 |
# print(currRadian)
|
466 |
# print(preRadian)
|
467 |
pre.flowMark = position |
468 |
pre.update_arrow() |
469 |
|
470 |
pre = item |
471 |
preRadian = currRadian |
472 |
|
473 |
if pre and type(item) is QEngineeringLineItem and item.is_piping(True) and item.length() > minLength: |
474 |
pre.flowMark = position |
475 |
pre.update_arrow() |
476 |
|
477 |
except Exception as ex: |
478 |
from App import App |
479 |
from AppDocData import MessageType |
480 |
|
481 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
482 |
sys.exc_info()[-1].tb_lineno)
|
483 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
484 |
|
485 |
"""
|
486 |
def paint(self, painter, options=None, widget=None):
|
487 |
QEngineeringTextItem.paint(self, painter, options, widget)
|
488 |
if self.freeze_item is None:
|
489 |
from EngineeringFreezeItem import QEngineeringFreezeItem
|
490 |
|
491 |
self.freeze_item = QEngineeringFreezeItem(0, 0, QEngineeringFreezeItem.FREEZE_SIZE, QEngineeringFreezeItem.FREEZE_SIZE)
|
492 |
self.freeze_item.setParentItem(self)
|
493 |
self.freeze_item.setZValue(self.zValue() + 1)
|
494 |
self.freeze_item.setPen(Qt.black)
|
495 |
"""
|
496 |
|
497 |
def reverse(self): |
498 |
""" reverse line routine """
|
499 |
|
500 |
if self.runs: |
501 |
self.runs[0].reverse() |
502 |
_from = self.prop('From') |
503 |
_to = self.prop('To') |
504 |
self.set_property('From', _to) |
505 |
self.set_property('To', _from) |
506 |
|
507 |
def getLongestTwoPoints(self, pts): |
508 |
import math |
509 |
res = [None, None] |
510 |
|
511 |
maxDistance = None
|
512 |
for i in range(len(pts)): |
513 |
for j in range(i + 1, len(pts)): |
514 |
dx = pts[i][0] - pts[j][0] |
515 |
dy = pts[i][1] - pts[j][1] |
516 |
dist = math.sqrt(dx * dx + dy * dy) |
517 |
if (maxDistance is None) or (maxDistance < dist): |
518 |
maxDistance = dist |
519 |
res[0] = pts[i]
|
520 |
res[1] = pts[j]
|
521 |
|
522 |
return res
|
523 |
|
524 |
'''
|
525 |
@brief set attribute
|
526 |
@author humkyung
|
527 |
@date 2018.07.20
|
528 |
'''
|
529 |
|
530 |
def set_attrib(self, attrib, value): |
531 |
matches = [attr for attr in self.attrs if attr.UID == attrib.UID] |
532 |
if len(matches) == 1: |
533 |
self.attrs[matches[0]] = value |
534 |
else:
|
535 |
self.attrs[attrib] = value
|
536 |
|
537 |
def removeSelfAttr(self, attributeName): |
538 |
pass
|
539 |
|
540 |
'''
|
541 |
@brief get attribute
|
542 |
@author kyouho
|
543 |
@date 2018.09.06
|
544 |
'''
|
545 |
def getLineNoAttributes(self, _attrs=None): |
546 |
from SymbolAttr import SymbolAttr |
547 |
from Configs import LineNoConfig |
548 |
import csv |
549 |
|
550 |
if _attrs is None: |
551 |
_attrs = {} |
552 |
|
553 |
try:
|
554 |
docData = AppDocData.instance() |
555 |
|
556 |
line_no_configs = LineNoConfig.instance() |
557 |
config = None
|
558 |
if line_no_configs:
|
559 |
for line_no_config in line_no_configs: |
560 |
item = line_no_config.parse(self.text())
|
561 |
if item[0]: |
562 |
config = line_no_config |
563 |
break
|
564 |
else:
|
565 |
item = (False,)
|
566 |
|
567 |
if item[0]: |
568 |
# Line No 부분
|
569 |
attr = SymbolAttr() |
570 |
attr.Attribute = 'LINE NO'
|
571 |
attr.DisplayAttribute = 'Line No'
|
572 |
attr.AttributeType = 'String'
|
573 |
attr.IsProp = 5
|
574 |
attr.Index = -1
|
575 |
_attrs[attr] = self.text()
|
576 |
|
577 |
result = item[1]
|
578 |
configs = list(csv.reader([config.value], delimiter=self.delimiter, escapechar='^'))[0] |
579 |
props = docData.getLineProperties() |
580 |
for prop in props: |
581 |
if prop.UID in configs: |
582 |
for i in range(len(configs)): |
583 |
if prop.UID == configs[i]:
|
584 |
_attrs[prop] = result[i] |
585 |
break
|
586 |
else:
|
587 |
matches = [attr for attr in self.attrs if attr.UID == prop.UID] |
588 |
if len(matches) == 1: |
589 |
_attrs[matches[0]] = self.attrs[matches[0]] |
590 |
# else:
|
591 |
# _attrs[prop] = ''
|
592 |
except Exception as ex: |
593 |
from App import App |
594 |
from AppDocData import MessageType |
595 |
|
596 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
597 |
sys.exc_info()[-1].tb_lineno)
|
598 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
599 |
|
600 |
return _attrs
|
601 |
|
602 |
@staticmethod
|
603 |
def from_database(component): |
604 |
""" get line no item from database """
|
605 |
import uuid |
606 |
from AppDocData import AppDocData |
607 |
from TextItemFactory import TextItemFactory |
608 |
from SymbolAttr import SymbolAttr |
609 |
|
610 |
item = None
|
611 |
|
612 |
try:
|
613 |
x = float(component['X']) |
614 |
y = float(component['Y']) |
615 |
width = float(component['Width']) if component['Width'] is not None else 0 |
616 |
height = float(component['Height']) if component['Height'] is not None else 0 |
617 |
angle = float(component['Rotation']) if component['Rotation'] is not None else 0 |
618 |
text = component['Value']
|
619 |
|
620 |
configs = AppDocData.instance().getConfigs('Data', 'Grid') |
621 |
grid = int(configs[0].value) if 1 == len(configs) else -1 |
622 |
if grid == 1: |
623 |
x = round(x)
|
624 |
y = round(y)
|
625 |
width = round(width)
|
626 |
height = round(height)
|
627 |
|
628 |
textInfo = TextInfo(text, x, y, width, height, angle) |
629 |
connline = component['Connected'] if component['Connected'] is not None else None |
630 |
|
631 |
item = TextItemFactory.instance().createTextItem(textInfo) |
632 |
if item is not None: |
633 |
item.setVisible(False)
|
634 |
for key in item._properties.keys(): |
635 |
if key.Attribute != 'Config': |
636 |
item._properties[key] = key.parse_value(component[key.Attribute]) |
637 |
|
638 |
app_doc_data = AppDocData.instance() |
639 |
|
640 |
# get associations
|
641 |
associations = app_doc_data.get_component_associations(component['UID'])
|
642 |
if associations:
|
643 |
for assoc in associations: |
644 |
_attrType = assoc['Type']
|
645 |
if not _attrType in item._associations: |
646 |
item._associations[_attrType] = [] |
647 |
item._associations[_attrType].append( |
648 |
uuid.UUID(assoc['Association']) if assoc['Association'] != 'None' else None) |
649 |
# up to here
|
650 |
|
651 |
'''
|
652 |
# get associations
|
653 |
associations = app_doc_data.get_component_associations(component['UID'])
|
654 |
if associations:
|
655 |
for assoc in associations:
|
656 |
_attrType = assoc['Type']
|
657 |
if not _attrType in item._associations:
|
658 |
item._associations[_attrType] = []
|
659 |
item._associations[_attrType].append(
|
660 |
uuid.UUID(assoc['Association']) if assoc['Association'] != 'None' else None)
|
661 |
# up to here
|
662 |
'''
|
663 |
|
664 |
attrs = app_doc_data.get_component_attributes(component['UID'])
|
665 |
for _attr in attrs: |
666 |
attr = SymbolAttr.from_record(_attr) |
667 |
item.attrs[attr] = _attr['Value']
|
668 |
|
669 |
item.uid = uuid.UUID(component['UID'])
|
670 |
item.loc = [x, y] |
671 |
item.size = [width, height] |
672 |
item.angle = angle |
673 |
item.setToolTip('<b>{}</b><br>LINE NO={}'.format(str(item.uid), text)) |
674 |
|
675 |
""" apply freeze value """
|
676 |
# item.freeze_item.update_freeze(item.prop('Freeze'))
|
677 |
|
678 |
if connline is not None: |
679 |
item.conns.append(connline) |
680 |
except Exception as ex: |
681 |
from App import App |
682 |
from AppDocData import MessageType |
683 |
|
684 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
685 |
sys.exc_info()[-1].tb_lineno)
|
686 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
687 |
return None |
688 |
|
689 |
return item
|
690 |
|
691 |
@staticmethod
|
692 |
def fromXml(node): |
693 |
""" generate EngineeringLineNoTextItem from xml node """
|
694 |
import uuid |
695 |
from TextItemFactory import TextItemFactory |
696 |
from SymbolAttr import SymbolAttr |
697 |
|
698 |
item = None
|
699 |
|
700 |
try:
|
701 |
location = node.find('LOCATION').text if node.find('LOCATION') is not None else '0,0' |
702 |
x = float(location.split(',')[0]) |
703 |
y = float(location.split(',')[1]) |
704 |
width = float(node.find('WIDTH').text) if node.find('WIDTH') is not None else 0 |
705 |
height = float(node.find('HEIGHT').text) if node.find('HEIGHT') is not None else 0 |
706 |
angle = float(node.find('ANGLE').text) if node.find('ANGLE') is not None else 0 |
707 |
text = node.find('TEXT').text
|
708 |
|
709 |
configs = AppDocData.instance().getConfigs('Data', 'Grid') |
710 |
grid = int(configs[0].value) if 1 == len(configs) else -1 |
711 |
if grid == 1: |
712 |
x = round(x)
|
713 |
y = round(y)
|
714 |
width = round(width)
|
715 |
height = round(height)
|
716 |
|
717 |
textInfo = TextInfo(text, x, y, width, height, angle) |
718 |
connline = node.find('CONNLINE').text if node.find('CONNLINE') is not None else None |
719 |
|
720 |
configs = AppDocData.instance().getConfigs('Data', 'Grid') |
721 |
grid = int(configs[0].value) if 1 == len(configs) else -1 |
722 |
if grid == 1: |
723 |
x = round(x)
|
724 |
y = round(y)
|
725 |
width = round(width)
|
726 |
height = round(height)
|
727 |
|
728 |
matches = [prop_node for prop_node in node.iter('PROPERTY') if prop_node.attrib['Attribute'] == 'Config'] |
729 |
if matches:
|
730 |
item = TextItemFactory.instance().createTextItem(textInfo, matches[0].text)
|
731 |
else:
|
732 |
item = TextItemFactory.instance().createTextItem(textInfo) |
733 |
|
734 |
if item is not None: |
735 |
item.setVisible(False)
|
736 |
for prop_node in node.iter('PROPERTY'): |
737 |
matches = [prop for prop in item._properties.keys() if |
738 |
prop.Attribute == prop_node.attrib['Attribute'] and prop.Attribute != 'Config'] |
739 |
if matches:
|
740 |
item._properties[matches[0]] = matches[0].parse_value(prop_node.text) |
741 |
|
742 |
for attr_node in node.iterfind('ATTRIBUTE'): |
743 |
attr = SymbolAttr.fromXml(attr_node) |
744 |
item.attrs[attr] = attr_node.text |
745 |
|
746 |
item.uid = uuid.UUID(node.find('UID').text)
|
747 |
item.loc = [x, y] |
748 |
item.size = [width, height] |
749 |
item.angle = angle |
750 |
item.setToolTip('<b>{}</b><br>LINE NO={}'.format(str(item.uid), text)) |
751 |
|
752 |
# get associations
|
753 |
attributeValue = node.find('ASSOCIATIONS')
|
754 |
if attributeValue is not None: |
755 |
for assoc in attributeValue.iter('ASSOCIATION'): |
756 |
_attrType = assoc.attrib['TYPE']
|
757 |
if not _attrType in item._associations: |
758 |
item._associations[_attrType] = [] |
759 |
item._associations[_attrType].append(uuid.UUID(assoc.text) if assoc.text != 'None' else None) |
760 |
# up to here
|
761 |
|
762 |
""" apply freeze value """
|
763 |
# item.freeze_item.update_freeze(item.prop('Freeze'))
|
764 |
|
765 |
if connline is not None: |
766 |
item.conns.append(connline) |
767 |
except Exception as ex: |
768 |
from App import App |
769 |
from AppDocData import MessageType |
770 |
|
771 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
772 |
sys.exc_info()[-1].tb_lineno)
|
773 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
774 |
return None |
775 |
|
776 |
return item
|
777 |
|
778 |
'''
|
779 |
@brief generate xml code
|
780 |
@author humkyung
|
781 |
@date 2018.04.23
|
782 |
@history humkyung 2018.05.02 write symbol's attribute
|
783 |
humkyung 2018.05.16 write run information to xml
|
784 |
'''
|
785 |
|
786 |
def toXml(self): |
787 |
from xml.etree.ElementTree import Element, SubElement, dump, ElementTree |
788 |
from EngineeringLineItem import QEngineeringLineItem |
789 |
from SymbolSvgItem import SymbolSvgItem |
790 |
|
791 |
try:
|
792 |
#docData = AppDocData.instance()
|
793 |
#configs = docData.getConfigs('Line No', 'Delimiter')
|
794 |
#delimiter = configs[0].value if 1 == len(configs) else '-'
|
795 |
#lineNoconfigs = docData.getConfigs('Line No', 'Configuration')
|
796 |
|
797 |
node = Element('LINE_NO')
|
798 |
uidNode = Element('UID')
|
799 |
uidNode.text = str(self.uid) |
800 |
node.append(uidNode) |
801 |
|
802 |
textNode = Element('TEXT')
|
803 |
textNode.text = self.text()
|
804 |
node.append(textNode) |
805 |
|
806 |
locNode = Element('LOCATION')
|
807 |
locNode.text = '{},{}'.format(self.loc[0], self.loc[1]) |
808 |
node.append(locNode) |
809 |
|
810 |
widthNode = Element('WIDTH')
|
811 |
widthNode.text = str(self.size[0]) |
812 |
node.append(widthNode) |
813 |
|
814 |
heightNode = Element('HEIGHT')
|
815 |
heightNode.text = str(self.size[1]) |
816 |
node.append(heightNode) |
817 |
|
818 |
angleNode = Element('ANGLE')
|
819 |
angleNode.text = str(self.angle) |
820 |
node.append(angleNode) |
821 |
|
822 |
areaNode = Element('AREA')
|
823 |
areaNode.text = self.area
|
824 |
node.append(areaNode) |
825 |
|
826 |
for run in self.runs: |
827 |
if run and run.items: |
828 |
node.append(run.toXml()) |
829 |
|
830 |
attributeValueNode = Element('ASSOCIATIONS')
|
831 |
for key, value in self._associations.items(): |
832 |
for assoc in value: |
833 |
assoc_node = Element('ASSOCIATION')
|
834 |
assoc_node.attrib['TYPE'] = str(key) |
835 |
assoc_node.text = str(assoc)
|
836 |
attributeValueNode.append(assoc_node) |
837 |
node.append(attributeValueNode) |
838 |
|
839 |
properties_node = Element('PROPERTIES')
|
840 |
for prop, value in self.properties.items(): |
841 |
prop_node = prop.toXml() |
842 |
prop_node.text = str(value) if value else '' |
843 |
properties_node.append(prop_node) |
844 |
node.append(properties_node) |
845 |
|
846 |
_attrs = self.getAttributes()
|
847 |
for key in _attrs.keys(): |
848 |
if key.UID is not None: |
849 |
attrNode = key.toXml() |
850 |
attrNode.text = str(_attrs[key])
|
851 |
node.append(attrNode) |
852 |
|
853 |
if self.conns: |
854 |
connNode = Element('CONNLINE')
|
855 |
connNode.text = str(self.conns[0].uid) if hasattr(self.conns[0], 'uid') else str(self.conns[0]) |
856 |
node.append(connNode) |
857 |
|
858 |
sceneNode = Element('SCENE')
|
859 |
sceneNode.text = str(self.sceneBoundingRect()).replace('PyQt5.QtCore.QRectF(', '').replace(' ', '').replace( |
860 |
')', '') if self.scene() else '{},{},{},{}'.format(self.loc[0], self.loc[1], self.size[0], self.size[1]) |
861 |
node.append(sceneNode) |
862 |
|
863 |
except Exception as ex: |
864 |
from App import App |
865 |
from AppDocData import MessageType |
866 |
|
867 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
868 |
sys.exc_info()[-1].tb_lineno)
|
869 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
870 |
|
871 |
return None |
872 |
|
873 |
return node
|
874 |
|
875 |
def to_svg(self, parent) -> list: |
876 |
"""convert line no item to svg"""
|
877 |
import re |
878 |
from xml.etree.ElementTree import Element, SubElement, dump, ElementTree |
879 |
from App import App |
880 |
|
881 |
res = [] |
882 |
try:
|
883 |
app_doc_data = AppDocData.instance() |
884 |
prj = app_doc_data.getCurrentProject() |
885 |
|
886 |
node = Element('g')
|
887 |
node.attrib['id'] = str(self.uid) |
888 |
node.attrib['class'] = 'Pipe' |
889 |
node.attrib['data-tag-name'] = self.toPlainText() |
890 |
node.attrib['font-family'] = self.font().family() |
891 |
node.attrib['font-size'] = str(self.boundingRect().height()) # str(self.font().pointSizeF()) |
892 |
node.attrib['font-weight'] = str(self.font().weight()) |
893 |
|
894 |
except_pattern = re.compile('[^a-zA-Z0-9-_]')
|
895 |
for attr, value in self.getAttributes().items(): |
896 |
node.attrib[re.sub(except_pattern, '_', attr.Attribute)] = value if value else '' |
897 |
trans = self.sceneTransform()
|
898 |
node.attrib['transform'] = f"matrix(" \ |
899 |
f"{trans.m11()},{trans.m12()}," \
|
900 |
f"{trans.m21()},{trans.m22()}," \
|
901 |
f"{trans.m31()},{trans.m32()}" \
|
902 |
f")"
|
903 |
|
904 |
text = Element('text')
|
905 |
text.text = self.toPlainText()
|
906 |
text.attrib['textLength'] = str(self.boundingRect().width()) |
907 |
text.attrib['lengthAdjust'] = 'spacingAndGlyphs' |
908 |
text.attrib['alignment-baseline'] = 'hanging' # align left-top corner |
909 |
node.append(text) |
910 |
|
911 |
connected_line = self.connected_line
|
912 |
if connected_line:
|
913 |
conn_node = connected_line.to_svg(self)
|
914 |
if conn_node:
|
915 |
node.extend(conn_node) |
916 |
|
917 |
res.append(node) |
918 |
except Exception as ex: |
919 |
from App import App |
920 |
from AppDocData import MessageType |
921 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
922 |
sys.exc_info()[-1].tb_lineno)
|
923 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
924 |
|
925 |
return res
|
926 |
|
927 |
def end_break(self): |
928 |
'''
|
929 |
@brief end break check
|
930 |
@author euisung
|
931 |
@date 2019.05.07
|
932 |
@history 2019.05.19 euisung can cover at both end that contact other line's middle
|
933 |
2019.05.19 euisung no more used integrated with linetracer
|
934 |
'''
|
935 |
from EngineeringLineItem import QEngineeringLineItem |
936 |
from SymbolSvgItem import SymbolSvgItem |
937 |
from AppDocData import AppDocData |
938 |
end_breaks = [] |
939 |
|
940 |
try:
|
941 |
docdata = AppDocData.instance() |
942 |
|
943 |
line_from = self.prop('From') |
944 |
line_to = self.prop('To') |
945 |
|
946 |
end_break_names = docdata.getSymbolListByType('type', 'End Break') |
947 |
if len(end_break_names) is 0: |
948 |
return end_breaks
|
949 |
|
950 |
svgFileName = end_break_names[0].sName
|
951 |
symbol = AppDocData.instance().getSymbolByQuery('name', svgFileName)
|
952 |
svgFilePath = os.path.join(AppDocData.instance().getCurrentProject().getSvgFilePath(), symbol.getType(), |
953 |
svgFileName + '.svg')
|
954 |
|
955 |
for line_end in [line_from, line_to]: |
956 |
for connector in line_end.connectors: |
957 |
if connector.connectedItem is not None and connector.connectedItem.owner is not self: |
958 |
end_break = SymbolSvgItem.createItem(symbol.getType(), None, svgFilePath)
|
959 |
pt = [connector.center()[0] - float(symbol.getOriginalPoint().split(',')[0]), |
960 |
connector.center()[1] - float(symbol.getOriginalPoint().split(',')[1])] |
961 |
origin = [0, 0] |
962 |
if 2 == len(symbol.getOriginalPoint().split(',')): |
963 |
tokens = symbol.getOriginalPoint().split(',')
|
964 |
origin = [pt[0] + float(tokens[0]), pt[1] + float(tokens[1])] |
965 |
end_break.buildItem(svgFileName, symbol.getType(), 5.7, pt,
|
966 |
[end_break.boundingRect().width(), end_break.boundingRect().height()], |
967 |
origin, [], symbol.getBaseSymbol(), symbol.getAdditionalSymbol(), |
968 |
symbol.getHasInstrumentLabel()) |
969 |
|
970 |
end_break.set_property('Connected Item', connector.connectedItem)
|
971 |
end_break.setToolTip('owner : ' + str(line_end)) |
972 |
end_break.area = 'Drawing'
|
973 |
end_break.owner = line_end |
974 |
end_breaks.append(end_break) |
975 |
except Exception as ex: |
976 |
from App import App |
977 |
from AppDocData import MessageType |
978 |
|
979 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
980 |
sys.exc_info()[-1].tb_lineno)
|
981 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
982 |
|
983 |
return end_breaks
|
984 |
|
985 |
'''
|
986 |
@Override (QEngineeringTextItem)
|
987 |
@brief get connected items
|
988 |
@author Jeongwoo
|
989 |
@date 2018.05.15
|
990 |
'''
|
991 |
|
992 |
def getConnectedItems(self): |
993 |
visited = [] |
994 |
|
995 |
try:
|
996 |
for run in self.runs: |
997 |
visited.extend(run.items) |
998 |
except Exception as ex: |
999 |
from App import App |
1000 |
from AppDocData import MessageType |
1001 |
|
1002 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
1003 |
sys.exc_info()[-1].tb_lineno)
|
1004 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
1005 |
|
1006 |
return visited
|
1007 |
|
1008 |
def explode(self, remainFromTo=False): |
1009 |
""" explode line no """
|
1010 |
|
1011 |
# if False == self.prop('Freeze'):
|
1012 |
try:
|
1013 |
for index in reversed(range(len(self.runs))): |
1014 |
self.runs[index].explode()
|
1015 |
except Exception as ex: |
1016 |
from App import App |
1017 |
from AppDocData import MessageType |
1018 |
|
1019 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
1020 |
sys.exc_info()[-1].tb_lineno) + ' Item UID : ' + str(self.uid) |
1021 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
1022 |
finally:
|
1023 |
self.runs.clear()
|
1024 |
if not remainFromTo: |
1025 |
self.set_property('From', None) |
1026 |
self.set_property('To', None) |
1027 |
|
1028 |
if hasattr(self, 'lineNoFromToIndicator') and self.lineNoFromToIndicator: |
1029 |
self.lineNoFromToIndicatorShowFlag = False |
1030 |
if self.scene(): |
1031 |
self.lineNoFromToIndicator[0].setVisible(False) |
1032 |
if len(self.lineNoFromToIndicator) == 2: |
1033 |
self.lineNoFromToIndicator[1].setVisible(False) |
1034 |
|
1035 |
'''
|
1036 |
@brief generate sql phrase to save to database(Notice: Line No's symbol is is 1)
|
1037 |
@author humkyung
|
1038 |
@date 2018.08.14
|
1039 |
'''
|
1040 |
def toSql_return_separately(self): |
1041 |
import uuid |
1042 |
from EngineeringAbstractItem import QEngineeringAbstractItem |
1043 |
|
1044 |
res = [] |
1045 |
resLater = [] |
1046 |
|
1047 |
app_doc_data = AppDocData.instance() |
1048 |
cols = ['UID', 'Drawings_UID', 'Symbol_UID', 'X', 'Y', 'Width', 'Height', 'Rotation', 'Value', 'Connected', |
1049 |
'[From]', '[To]'] |
1050 |
if type(self) is QEngineeringLineNoTextItem: |
1051 |
values = ['?', '?', "(select UID from Symbol where Name='Line NO' and SymbolType_UID=-1)", '?', '?', '?', |
1052 |
'?', '?', '?', '?', '?', '?'] |
1053 |
else:
|
1054 |
values = ['?', '?', "(select UID from Symbol where Name='Trim Line NO' and SymbolType_UID=-1)", '?', '?', |
1055 |
'?', '?', '?', '?', '?', '?', '?'] |
1056 |
_from = self.prop('From') |
1057 |
if not _from: |
1058 |
_from = ''
|
1059 |
_to = self.prop('To') |
1060 |
if not _to: |
1061 |
_to = ''
|
1062 |
params = [(str(self.uid), str(app_doc_data.activeDrawing.UID), self.loc[0], self.loc[1], self.size[0], |
1063 |
self.size[1], str(self.angle), \ |
1064 |
self.text(), str(self.conns[0]) if self.conns else None, str(_from), str(_to))] |
1065 |
sql = 'insert into Components({}) values({})'.format(','.join(cols), ','.join(values)) |
1066 |
res.append((sql, tuple(params)))
|
1067 |
|
1068 |
cols = ['UID', 'Components_UID', 'LineProperties_UID', 'Value'] |
1069 |
values = ['?', '?', '?', '?'] |
1070 |
params = [] |
1071 |
attrs = self.getAttributes()
|
1072 |
for key, value in attrs.items(): |
1073 |
if key.Attribute == 'LINE NO': # or key.IsProp != 5: |
1074 |
continue
|
1075 |
params.append((str(uuid.uuid4()), str(self.uid), str(key.UID), str(value))) |
1076 |
sql = 'insert into LineNoAttributes({}) values({})'.format(','.join(cols), ','.join(values)) |
1077 |
resLater.append((sql, tuple(params)))
|
1078 |
|
1079 |
if self.associations(): |
1080 |
cols = ['UID', '[Type]', 'Components_UID', 'Association'] |
1081 |
values = ['?', '?', '?', '?'] |
1082 |
params = [] |
1083 |
for assoc in self.associations(): |
1084 |
params.append( |
1085 |
(str(uuid.uuid4()), QEngineeringAbstractItem.assoc_type(assoc), str(self.uid), str(assoc.uid))) |
1086 |
sql = 'insert into Associations({}) values({})'.format(','.join(cols), ','.join(values)) |
1087 |
resLater.append((sql, tuple(params)))
|
1088 |
|
1089 |
# insert line no's Attributes
|
1090 |
cols = ['UID', 'Components_UID', 'SymbolAttribute_UID', 'Value', 'Association_UID', 'Freeze'] |
1091 |
values = ['?', '?', '?', '?', '?', '?'] |
1092 |
params = [] |
1093 |
for key in attrs.keys(): |
1094 |
if key.IsProp != 5: |
1095 |
params.append((str(uuid.uuid4()), str(self.uid), str(key.UID), str(attrs[key]), str(key.AssocItem), |
1096 |
str(key.Freeze)))
|
1097 |
sql = 'insert into Attributes({}) values({})'.format(','.join(cols), ','.join(values)) |
1098 |
res.append((sql, tuple(params)))
|
1099 |
|
1100 |
if self.associations(): |
1101 |
cols = ['UID', '[Type]', 'Components_UID', 'Association'] |
1102 |
values = ['?', '?', '?', '?'] |
1103 |
params = [] |
1104 |
for assoc in self.associations(): |
1105 |
params.append( |
1106 |
(str(uuid.uuid4()), QEngineeringAbstractItem.assoc_type(assoc), str(self.uid), str(assoc.uid))) |
1107 |
sql = 'insert into Associations({}) values({})'.format(','.join(cols), ','.join(values)) |
1108 |
resLater.append((sql, tuple(params)))
|
1109 |
|
1110 |
_index = 0
|
1111 |
for run in self.runs: |
1112 |
if run and run.items: |
1113 |
resLater.extend(run.to_sql(_index, self))
|
1114 |
_index += 1
|
1115 |
|
1116 |
return res, resLater
|
1117 |
|
1118 |
'''
|
1119 |
@brief return Line Data List
|
1120 |
@author kyouho
|
1121 |
@date 2018.08.14
|
1122 |
@ no more used
|
1123 |
'''
|
1124 |
def getLineDataList(self): |
1125 |
dataList = [] |
1126 |
'''
|
1127 |
try:
|
1128 |
import uuid
|
1129 |
global lineColumnList
|
1130 |
|
1131 |
docData = AppDocData.instance()
|
1132 |
attrs = self.getAttributes()
|
1133 |
for index in range(len(lineColumnList)):
|
1134 |
dataList.append('')
|
1135 |
|
1136 |
dataList[20] = docData.imgName
|
1137 |
|
1138 |
for key in attrs.keys():
|
1139 |
if type(key) is not UserInputAttribute:
|
1140 |
lineProp = docData.getLinePropertiesByUID(key.UID)
|
1141 |
if lineProp:
|
1142 |
attrName = lineProp[0].Attribute.upper().replace(' ', '')
|
1143 |
else:
|
1144 |
attrName = key.Attribute.upper().replace(' ', '')
|
1145 |
|
1146 |
data = attrs[key]
|
1147 |
if attrName == 'NOMINALDIAMETER':
|
1148 |
dataList[1] = data
|
1149 |
elif attrName == 'FLUIDCODE':
|
1150 |
dataList[2] = data
|
1151 |
dataList[7] = data
|
1152 |
elif attrName == 'TAGSEQNO':
|
1153 |
pass
|
1154 |
elif attrName == 'INSULATIONPURPOSE':
|
1155 |
dataList[16] = data
|
1156 |
elif attrName == 'STREAMNO':
|
1157 |
pass
|
1158 |
elif attrName == 'LINENO' or attrName == 'LINE NO':
|
1159 |
dataList[3] = data
|
1160 |
elif attrName == 'PNIDNUMBER':
|
1161 |
pass
|
1162 |
elif attrName == 'PIPINGMATERIALSCLASS':
|
1163 |
dataList[4] = data
|
1164 |
elif attrName == '':
|
1165 |
pass
|
1166 |
else:
|
1167 |
typeUID = key.Attribute
|
1168 |
value = key.text
|
1169 |
lineAttr = docData.getLinePropertiesByUID(key.UD)
|
1170 |
|
1171 |
for index in range(len(lineColumnList)):
|
1172 |
if lineColumnList[index] == lineAttr[0].Attribute:
|
1173 |
dataList[index] = value
|
1174 |
except Exception as ex:
|
1175 |
from App import App
|
1176 |
from AppDocData import MessageType
|
1177 |
|
1178 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
|
1179 |
sys.exc_info()[-1].tb_lineno)
|
1180 |
App.mainWnd().addMessage.emit(MessageType.Error, message)
|
1181 |
|
1182 |
if dataList[0] == '':
|
1183 |
dataList[0] = str(uuid.uuid4())
|
1184 |
'''
|
1185 |
|
1186 |
return dataList
|
1187 |
|
1188 |
def EvaluatedEQ(self): |
1189 |
''' evaluate line no's From / To equipment '''
|
1190 |
|
1191 |
from EngineeringNozzleItem import QEngineeringNozzleItem |
1192 |
from EngineeringVendorItem import QEngineeringVendorItem |
1193 |
from EngineeringEquipmentItem import QEngineeringEquipmentItem |
1194 |
from EngineeringLineItem import QEngineeringLineItem |
1195 |
|
1196 |
pool = [] |
1197 |
visited = [] |
1198 |
if self.runs and self.runs[0]: |
1199 |
pool.append(self)
|
1200 |
_attrs = self.getAttributes()
|
1201 |
|
1202 |
from_found = False
|
1203 |
to_found = False
|
1204 |
|
1205 |
|
1206 |
try:
|
1207 |
while pool:
|
1208 |
lineNo = pool.pop() |
1209 |
if lineNo not in visited: |
1210 |
visited.append(lineNo) |
1211 |
else:
|
1212 |
continue
|
1213 |
|
1214 |
if lineNo.runs and lineNo.runs[0]: |
1215 |
items = lineNo.runs[0].items
|
1216 |
if len(items) > 2: |
1217 |
if type(items[0]) is QEngineeringNozzleItem and not from_found: |
1218 |
for connector in items[0].connectors: |
1219 |
# From
|
1220 |
if (type(connector.connectedItem) is QEngineeringVendorItem or type( |
1221 |
connector.connectedItem) is QEngineeringEquipmentItem) and \ |
1222 |
connector.connectedItem not in items: |
1223 |
for _attr in _attrs: |
1224 |
if _attr.Attribute == 'From_eq' and self.add_assoc_item(connector.connectedItem, |
1225 |
at=_attr.AttrAt): |
1226 |
_attr.AssocItem = connector.connectedItem |
1227 |
from_found = True
|
1228 |
break
|
1229 |
break
|
1230 |
elif not from_found: |
1231 |
if type(items[0]) is QEngineeringLineItem and items[0].connectors[0].connectedItem and items[0].connectors[0].connectedItem.owner: |
1232 |
pool.append(items[0].connectors[0].connectedItem.owner) |
1233 |
else:
|
1234 |
next_items = [connector.connectedItem for connector in items[0].connectors if connector.connectedItem and \ |
1235 |
connector.connectedItem is not items[1] and items[0].next_connected(items[1], connector.connectedItem)] |
1236 |
if next_items and next_items[0].owner: |
1237 |
pool.append(next_items[0].owner)
|
1238 |
|
1239 |
if type(items[-1]) is QEngineeringNozzleItem and not to_found: |
1240 |
for connector in items[-1].connectors: |
1241 |
# To
|
1242 |
if (type(connector.connectedItem) is QEngineeringVendorItem or type( |
1243 |
connector.connectedItem) is QEngineeringEquipmentItem) and \ |
1244 |
connector.connectedItem not in items: |
1245 |
for _attr in _attrs: |
1246 |
if _attr.Attribute == 'To_eq' and self.add_assoc_item(connector.connectedItem, |
1247 |
at=_attr.AttrAt): |
1248 |
_attr.AssocItem = connector.connectedItem |
1249 |
to_found = True
|
1250 |
break
|
1251 |
break
|
1252 |
elif not to_found: |
1253 |
if type(items[-1]) is QEngineeringLineItem and items[-1].connectors[1].connectedItem and items[-1].connectors[1].connectedItem.owner: |
1254 |
pool.append(items[-1].connectors[1].connectedItem.owner) |
1255 |
else:
|
1256 |
next_items = [connector.connectedItem for connector in items[-1].connectors if connector.connectedItem and \ |
1257 |
connector.connectedItem is not items[-2] and items[-1].next_connected(items[-2], connector.connectedItem)] |
1258 |
if next_items and next_items[0].owner: |
1259 |
pool.append(next_items[0].owner)
|
1260 |
except Exception as ex: |
1261 |
from App import App |
1262 |
from AppDocData import MessageType |
1263 |
|
1264 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
1265 |
sys.exc_info()[-1].tb_lineno)
|
1266 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
1267 |
|
1268 |
def sort_order_text(self): |
1269 |
""" return true if line no same"""
|
1270 |
|
1271 |
app_doc_data = AppDocData.instance() |
1272 |
|
1273 |
configs = app_doc_data.getConfigs('Sort', 'LineNoKeys') |
1274 |
targets = configs[0].value.split(',') if configs else [] |
1275 |
|
1276 |
if targets:
|
1277 |
attrs = self.getAttributes(True) |
1278 |
matches = [] |
1279 |
|
1280 |
for key in targets: |
1281 |
_matches = [_key for _key in list(attrs.keys()) if str(_key.UID) == key] |
1282 |
if _matches:
|
1283 |
matches.append(attrs[_matches[0]])
|
1284 |
else:
|
1285 |
matches = [self.text()]
|
1286 |
|
1287 |
return '_'.join(matches) |
1288 |
|
1289 |
def validate(self, rules): |
1290 |
""" validation check """
|
1291 |
|
1292 |
from SymbolSvgItem import SymbolSvgItem |
1293 |
from AppDocData import AppDocData |
1294 |
from EngineeringReducerItem import QEngineeringReducerItem |
1295 |
from EngineeringLineItem import QEngineeringLineItem |
1296 |
from EngineeringAbstractItem import QEngineeringAbstractItem |
1297 |
from ValidateCommand import LineNoValidation |
1298 |
|
1299 |
errors = [] |
1300 |
|
1301 |
try:
|
1302 |
_translate = QCoreApplication.translate |
1303 |
|
1304 |
docdata = AppDocData.instance() |
1305 |
dataPath = docdata.getErrorItemSvgPath() |
1306 |
|
1307 |
lineNoError = False
|
1308 |
|
1309 |
_error = super().validate(rules)
|
1310 |
errors.extend(_error) |
1311 |
|
1312 |
_from = self.prop('From') |
1313 |
_to = self.prop('To') |
1314 |
|
1315 |
if not _from or not _to: |
1316 |
lineNoError = True
|
1317 |
elif self.runs: |
1318 |
if self.runs[0].items[0] is not _from: |
1319 |
lineNoError = True
|
1320 |
elif self.runs[0].items[-1] is not _to: |
1321 |
lineNoError = True
|
1322 |
else:
|
1323 |
return errors
|
1324 |
|
1325 |
if LineNoValidation.BranchSizeError in rules or LineNoValidation.SizeChangeError in rules: |
1326 |
size_errors = [] |
1327 |
branch_errors = [] |
1328 |
for run in self.runs: |
1329 |
sizes = [] |
1330 |
for item in run.items: |
1331 |
item_size = None
|
1332 |
attrs = item.getAttributes() |
1333 |
for prop, value in attrs.items(): |
1334 |
if prop.Attribute.upper() == 'Size'.upper() or prop.Attribute.upper() == 'NominalDiameter'.upper(): |
1335 |
if value and value != 'None': |
1336 |
item_size = value |
1337 |
if type(item) is QEngineeringReducerItem or (issubclass(type(item), SymbolSvgItem) and item.iType == 22): # Relief Valve |
1338 |
sizes.append([item, item.mainSubSize[0], item.mainSubSize[1]]) |
1339 |
break
|
1340 |
else:
|
1341 |
sizes.append([item, value, value]) |
1342 |
break
|
1343 |
|
1344 |
if item_size and type(item) is QEngineeringLineItem: |
1345 |
for conn in item.connectors: |
1346 |
if conn.connectedItem and type(conn.connectedItem) is QEngineeringLineItem and \ |
1347 |
conn._connected_at == QEngineeringAbstractItem.CONNECTED_AT_BODY: |
1348 |
_item_size = None
|
1349 |
attrs = conn.connectedItem.getAttributes() |
1350 |
for prop, value in attrs.items(): |
1351 |
if prop.Attribute.upper() == 'Size'.upper() or prop.Attribute.upper() == 'NominalDiameter'.upper(): |
1352 |
if value and value != 'None': |
1353 |
_item_size = value |
1354 |
break
|
1355 |
|
1356 |
if _item_size and self.inch_to_number(item_size) > self.inch_to_number(_item_size): |
1357 |
branch_errors.append(item) |
1358 |
branch_errors.append(conn.connectedItem) |
1359 |
|
1360 |
if len(sizes) > 1: |
1361 |
for index in range(len(sizes) - 1): |
1362 |
if sizes[index][2] != sizes[index + 1][1] and \ |
1363 |
type(sizes[index][0]) is not QEngineeringReducerItem and type(sizes[index + 1][0]) is not QEngineeringReducerItem \ |
1364 |
and (hasattr(sizes[index][0], 'iType') and sizes[index][0].iType != 22) and \ |
1365 |
(hasattr(sizes[index + 1][0], 'iType') and sizes[index + 1][0].iType != 22): |
1366 |
size_errors.append(sizes[index][0])
|
1367 |
size_errors.append(sizes[index + 1][0]) |
1368 |
elif sizes[index][1] not in sizes[index + 1] and sizes[index][2] not in sizes[index + 1]: |
1369 |
size_errors.append(sizes[index][0])
|
1370 |
size_errors.append(sizes[index + 1][0]) |
1371 |
|
1372 |
if LineNoValidation.SizeChangeError in rules: |
1373 |
for size in size_errors: |
1374 |
error = SymbolSvgItem.createItem('Error', None, dataPath) |
1375 |
error.setPosition([size.sceneBoundingRect().center().x(), size.sceneBoundingRect().center().y()]) |
1376 |
error.parent = size |
1377 |
error.msg = _translate('Size change error', 'Size change error') |
1378 |
error.setToolTip(error.msg) |
1379 |
error.area = 'Drawing'
|
1380 |
error.name = 'Error'
|
1381 |
errors.append(error) |
1382 |
|
1383 |
if LineNoValidation.BranchSizeError in rules: |
1384 |
for size in branch_errors: |
1385 |
error = SymbolSvgItem.createItem('Error', None, dataPath) |
1386 |
error.setPosition([size.sceneBoundingRect().center().x(), size.sceneBoundingRect().center().y()]) |
1387 |
error.parent = size |
1388 |
error.msg = _translate('Branch size error', 'Branch size error') |
1389 |
error.setToolTip(error.msg) |
1390 |
error.area = 'Drawing'
|
1391 |
error.name = 'Error'
|
1392 |
errors.append(error) |
1393 |
|
1394 |
if LineNoValidation.MainRunSizeWarning in rules: |
1395 |
if self.runs and self.runs[0].items: |
1396 |
_size = self.Size
|
1397 |
found = False
|
1398 |
if _size:
|
1399 |
for item in self.runs[0].items: |
1400 |
if type(item) is QEngineeringReducerItem or (issubclass(type(item), SymbolSvgItem) and item.iType == 22): |
1401 |
continue
|
1402 |
_size2 = item.EvaluatedSize |
1403 |
if _size2 and _size2 != 'None' and _size2 == _size: |
1404 |
found = True
|
1405 |
break
|
1406 |
|
1407 |
#attrs = item.getAttributes()
|
1408 |
#for prop, value in attrs.items():
|
1409 |
# if prop.Attribute.upper() == 'Size'.upper() or prop.Attribute.upper() == 'NominalDiameter'.upper():
|
1410 |
# if value and value != 'None' and _size != value:
|
1411 |
# found = True
|
1412 |
# break
|
1413 |
|
1414 |
if found:
|
1415 |
break
|
1416 |
|
1417 |
if not found: |
1418 |
error = SymbolSvgItem.createItem('Error', None, dataPath) |
1419 |
error.setPosition([self.sceneBoundingRect().center().x(), self.sceneBoundingRect().center().y()]) |
1420 |
error.parent = self
|
1421 |
error.msg = _translate('Main run size warning', 'Main run size warning') |
1422 |
error.setToolTip(error.msg) |
1423 |
error.area = 'Drawing'
|
1424 |
error.name = 'Warning'
|
1425 |
errors.append(error) |
1426 |
|
1427 |
if LineNoValidation.FromToError in rules: |
1428 |
if lineNoError:
|
1429 |
error = SymbolSvgItem.createItem('Error', None, dataPath) |
1430 |
error.setPosition([self.sceneBoundingRect().center().x(), self.sceneBoundingRect().center().y()]) |
1431 |
error.parent = self
|
1432 |
error.msg = _translate('From/ To error', 'From/ To error') |
1433 |
error.setToolTip(error.msg) |
1434 |
error.area = 'Drawing'
|
1435 |
error.name = 'Error'
|
1436 |
errors.append(error) |
1437 |
|
1438 |
except Exception as ex: |
1439 |
from App import App |
1440 |
from AppDocData import MessageType |
1441 |
|
1442 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
1443 |
sys.exc_info()[-1].tb_lineno)
|
1444 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
1445 |
|
1446 |
return errors
|