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