hytos / DTI_PID / DTI_PID / Shapes / EngineeringLineNoTextItem.py @ 9424bdca
이력 | 보기 | 이력해설 | 다운로드 (35.5 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 |
try:
|
9 |
from PyQt5.QtCore import Qt, QPointF, QRectF, pyqtSignal, QT_VERSION_STR, QRect |
10 |
from PyQt5.QtGui import QImage, QPixmap, QPainterPath, QBrush, QPen, QTransform, QFont |
11 |
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QFileDialog, QGraphicsItem, QAbstractGraphicsShapeItem, \ |
12 |
QGraphicsTextItem
|
13 |
except ImportError: |
14 |
try:
|
15 |
from PyQt4.QtCore import Qt, QRectF, pyqtSignal, QT_VERSION_STR, QRect |
16 |
from PyQt4.QtGui import QGraphicsView, QGraphicsScene, QImage, QPixmap, QPainterPath, QFileDialog, QFont |
17 |
except ImportError: |
18 |
raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.") |
19 |
|
20 |
from EngineeringPolylineItem import QEngineeringPolylineItem |
21 |
from GraphicsBoundingBoxItem import QGraphicsBoundingBoxItem |
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} # , SymbolProp(None, 'Freeze', 'Boolean'):False} |
48 |
self._runs = []
|
49 |
|
50 |
""" create freeze control """
|
51 |
# self.freeze_item = QEngineeringFreezeItem(-QEngineeringFreezeItem.FREEZE_SIZE*0.5, -QEngineeringFreezeItem.FREEZE_SIZE*0.5, QEngineeringFreezeItem.FREEZE_SIZE, QEngineeringFreezeItem.FREEZE_SIZE)
|
52 |
# self.freeze_item.setParentItem(self)
|
53 |
# self.freeze_item.setZValue(self.zValue() + 1)
|
54 |
# self.freeze_item.setPen(Qt.black)
|
55 |
|
56 |
@property
|
57 |
def Size(self): |
58 |
""" return line no's size """
|
59 |
attrs = self.getAttributes()
|
60 |
matches = [value for attr, value in attrs.items() if attr.Attribute.upper() == 'NOMINALDIAMETER'] |
61 |
return matches[0] if matches else None |
62 |
|
63 |
def empty(self): |
64 |
""" return True if run is empty else return False """
|
65 |
return False if self._runs else True |
66 |
|
67 |
def setVisible(self, visible): |
68 |
""" override visible value """
|
69 |
super(QEngineeringTextItem, self).setVisible(visible) |
70 |
for run in self.runs: |
71 |
run.visible = visible |
72 |
|
73 |
@property
|
74 |
def connected_line(self): |
75 |
"""return connected line"""
|
76 |
if self.conns: |
77 |
if type(self.conns[0]) is str: |
78 |
matches = [x for x in self.scene().items() if hasattr(x, 'uid') and str(x.uid) == str(self.conns[0])] |
79 |
if matches:
|
80 |
self.conns[0] = matches[0] |
81 |
|
82 |
return self.conns[0] |
83 |
|
84 |
return None |
85 |
|
86 |
'''
|
87 |
@brief getter of runs
|
88 |
@author humkyung
|
89 |
@date 2018.05.11
|
90 |
'''
|
91 |
|
92 |
@property
|
93 |
def runs(self): |
94 |
return self._runs |
95 |
|
96 |
'''
|
97 |
@brief setter of runs
|
98 |
@author humkyung
|
99 |
@date 2018.05.11
|
100 |
'''
|
101 |
|
102 |
@runs.setter
|
103 |
def runs(self, value): |
104 |
self._runs = value
|
105 |
|
106 |
def hoverEnterEvent(self, event): |
107 |
""" highlight line no text and run's item """
|
108 |
self.hover = True |
109 |
self.update()
|
110 |
|
111 |
for run in self.runs: |
112 |
for item in run.items: |
113 |
item.hoverEnterEvent(event) |
114 |
|
115 |
def hoverLeaveEvent(self, event): |
116 |
""" unhighlight line no text and run's item """
|
117 |
self.hover = False |
118 |
self.update()
|
119 |
|
120 |
for run in self.runs: |
121 |
for item in run.items: |
122 |
item.hoverLeaveEvent(event) |
123 |
|
124 |
def keyPressEvent(self, event): |
125 |
""" reverse line routine when user press 'C' key """
|
126 |
if event.key() == Qt.Key_C:
|
127 |
self.reverse()
|
128 |
|
129 |
QEngineeringTextItem.keyPressEvent(self, event)
|
130 |
|
131 |
def update_flow_mark(self, position, minLength): |
132 |
""" update line flow mark """
|
133 |
import math |
134 |
from EngineeringLineItem import QEngineeringLineItem |
135 |
|
136 |
allowed_error_radian = 0.09
|
137 |
|
138 |
try:
|
139 |
for run in self.runs: |
140 |
pre = None
|
141 |
preRadian = None
|
142 |
for item in run.items: |
143 |
if pre is None and type(item) is QEngineeringLineItem and ( |
144 |
item._lineType == 'Primary' or item._lineType == 'Secondary') and item.length() > minLength: |
145 |
pre = item |
146 |
start = item.line().p1() |
147 |
end = item.line().p2() |
148 |
_dir = [(end.x() - start.x()) / item.length(), (end.y() - start.y()) / item.length()] |
149 |
radian = math.atan2(_dir[1], _dir[0]) - math.pi / 2 |
150 |
preRadian = radian if radian >= 0 else radian + 2 * math.pi |
151 |
preRadian = abs(preRadian - math.pi)
|
152 |
|
153 |
elif pre and type(pre) is QEngineeringLineItem and type(item) is QEngineeringLineItem and ( |
154 |
item._lineType == 'Primary' or item._lineType == 'Secondary'): |
155 |
start = item.line().p1() |
156 |
end = item.line().p2() |
157 |
_dir = [(end.x() - start.x()) / item.length(), (end.y() - start.y()) / item.length()] |
158 |
radian = math.atan2(_dir[1], _dir[0]) - math.pi / 2 |
159 |
currRadian = radian if radian >= 0 else radian + 2 * math.pi |
160 |
currRadian = abs(currRadian - math.pi)
|
161 |
if abs(currRadian - preRadian) > allowed_error_radian: |
162 |
# insert flow mark at pre line
|
163 |
if pre.length() > minLength:
|
164 |
# if str(pre.uid) == '62edfbe5-29fd-49af-840b-6dce051e04d1':
|
165 |
# print(math.atan2(preDir[0], preDir[1]) - math.pi / 2)
|
166 |
# print(currRadian)
|
167 |
# print(preRadian)
|
168 |
pre.flowMark = position |
169 |
pre.update_arrow() |
170 |
|
171 |
pre = item |
172 |
preRadian = currRadian |
173 |
|
174 |
if pre and type(item) is QEngineeringLineItem and ( |
175 |
item._lineType == 'Primary' or item._lineType == 'Secondary') and item.length() > minLength: |
176 |
pre.flowMark = position |
177 |
pre.update_arrow() |
178 |
|
179 |
except Exception as ex: |
180 |
from App import App |
181 |
from AppDocData import MessageType |
182 |
|
183 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
184 |
sys.exc_info()[-1].tb_lineno)
|
185 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
186 |
|
187 |
"""
|
188 |
def paint(self, painter, options=None, widget=None):
|
189 |
QEngineeringTextItem.paint(self, painter, options, widget)
|
190 |
if self.freeze_item is None:
|
191 |
from EngineeringFreezeItem import QEngineeringFreezeItem
|
192 |
|
193 |
self.freeze_item = QEngineeringFreezeItem(0, 0, QEngineeringFreezeItem.FREEZE_SIZE, QEngineeringFreezeItem.FREEZE_SIZE)
|
194 |
self.freeze_item.setParentItem(self)
|
195 |
self.freeze_item.setZValue(self.zValue() + 1)
|
196 |
self.freeze_item.setPen(Qt.black)
|
197 |
"""
|
198 |
|
199 |
def reverse(self): |
200 |
""" reverse line routine """
|
201 |
|
202 |
if self.runs: |
203 |
self.runs[0].reverse() |
204 |
_from = self.prop('From') |
205 |
_to = self.prop('To') |
206 |
self.set_property('From', _to) |
207 |
self.set_property('To', _from) |
208 |
|
209 |
def getLongestTwoPoints(self, pts): |
210 |
import math |
211 |
res = [None, None] |
212 |
|
213 |
maxDistance = None
|
214 |
for i in range(len(pts)): |
215 |
for j in range(i + 1, len(pts)): |
216 |
dx = pts[i][0] - pts[j][0] |
217 |
dy = pts[i][1] - pts[j][1] |
218 |
dist = math.sqrt(dx * dx + dy * dy) |
219 |
if (maxDistance is None) or (maxDistance < dist): |
220 |
maxDistance = dist |
221 |
res[0] = pts[i]
|
222 |
res[1] = pts[j]
|
223 |
|
224 |
return res
|
225 |
|
226 |
'''
|
227 |
@brief set attribute
|
228 |
@author humkyung
|
229 |
@date 2018.07.20
|
230 |
'''
|
231 |
|
232 |
def set_attrib(self, attrib, value): |
233 |
matches = [attr for attr in self.attrs if attr.UID == attrib.UID] |
234 |
if len(matches) == 1: |
235 |
self.attrs[matches[0]] = value |
236 |
else:
|
237 |
self.attrs[attrib] = value
|
238 |
|
239 |
def removeSelfAttr(self, attributeName): |
240 |
pass
|
241 |
|
242 |
'''
|
243 |
@brief get attribute
|
244 |
@author kyouho
|
245 |
@date 2018.09.06
|
246 |
'''
|
247 |
|
248 |
def getLineNoAttributes(self, _attrs=None): |
249 |
from SymbolAttr import SymbolAttr |
250 |
from Configs import LineNoConfig |
251 |
|
252 |
if _attrs is None: |
253 |
_attrs = {} |
254 |
|
255 |
try:
|
256 |
docData = AppDocData.instance() |
257 |
|
258 |
line_no_configs = LineNoConfig.instance() |
259 |
config = None
|
260 |
if line_no_configs:
|
261 |
for line_no_config in line_no_configs: |
262 |
item = line_no_config.parse(self.text())
|
263 |
if item[0]: |
264 |
config = line_no_config |
265 |
break
|
266 |
else:
|
267 |
item = (False,)
|
268 |
|
269 |
# Line No 부분
|
270 |
if item[0]: |
271 |
attr = SymbolAttr() |
272 |
attr.Attribute = 'LINE NO'
|
273 |
attr.DisplayAttribute = 'Line No'
|
274 |
attr.AttributeType = 'String'
|
275 |
attr.IsProp = 5
|
276 |
_attrs[attr] = self.text()
|
277 |
|
278 |
result = item[1]
|
279 |
configs = config.value.split(self.delimiter)
|
280 |
props = docData.getLineProperties() |
281 |
for prop in props: |
282 |
if prop.UID in configs: |
283 |
for i in range(len(configs)): |
284 |
if prop.UID == configs[i]:
|
285 |
_attrs[prop] = result[i] |
286 |
break
|
287 |
else:
|
288 |
matches = [attr for attr in self.attrs if attr.UID == prop.UID] |
289 |
if len(matches) == 1: |
290 |
_attrs[matches[0]] = self.attrs[matches[0]] |
291 |
# else:
|
292 |
# _attrs[prop] = ''
|
293 |
except Exception as ex: |
294 |
from App import App |
295 |
from AppDocData import MessageType |
296 |
|
297 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
298 |
sys.exc_info()[-1].tb_lineno)
|
299 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
300 |
|
301 |
return _attrs
|
302 |
|
303 |
@staticmethod
|
304 |
def from_database(component): |
305 |
""" get line no item from database """
|
306 |
import uuid |
307 |
from AppDocData import AppDocData |
308 |
from TextItemFactory import TextItemFactory |
309 |
from SymbolAttr import SymbolAttr |
310 |
|
311 |
item = None
|
312 |
|
313 |
try:
|
314 |
x = float(component['X']) |
315 |
y = float(component['Y']) |
316 |
width = float(component['Width']) if component['Width'] is not None else 0 |
317 |
height = float(component['Height']) if component['Height'] is not None else 0 |
318 |
angle = float(component['Rotation']) if component['Rotation'] is not None else 0 |
319 |
text = component['Value']
|
320 |
textInfo = TextInfo(text, x, y, width, height, angle) |
321 |
connline = component['Connected'] if component['Connected'] is not None else None |
322 |
|
323 |
item = TextItemFactory.instance().createTextItem(textInfo) |
324 |
if item is not None: |
325 |
item.setVisible(False)
|
326 |
for key in item._properties.keys(): |
327 |
item._properties[key] = key.parse_value(component[key.Attribute]) |
328 |
|
329 |
app_doc_data = AppDocData.instance() |
330 |
|
331 |
# get associations
|
332 |
associations = app_doc_data.get_component_associations(uid) |
333 |
if associations:
|
334 |
for assoc in associations: |
335 |
_attrType = assoc['Type']
|
336 |
if not _attrType in item._associations: |
337 |
item._associations[_attrType] = [] |
338 |
item._associations[_attrType].append( |
339 |
uuid.UUID(assoc['Association']) if assoc['Association'] != 'None' else None) |
340 |
# up to here
|
341 |
|
342 |
# get associations
|
343 |
associations = app_doc_data.get_component_associations(component['UID'])
|
344 |
if associations:
|
345 |
for assoc in associations: |
346 |
_attrType = assoc['Type']
|
347 |
if not _attrType in item._associations: |
348 |
item._associations[_attrType] = [] |
349 |
item._associations[_attrType].append( |
350 |
uuid.UUID(assoc['Association']) if assoc['Association'] != 'None' else None) |
351 |
# up to here
|
352 |
|
353 |
attrs = app_doc_data.get_component_attributes(component['UID'])
|
354 |
for _attr in attrs: |
355 |
attr = SymbolAttr.from_record(_attr) |
356 |
item.attrs[attr] = _attr['Value']
|
357 |
|
358 |
item.uid = uuid.UUID(component['UID'])
|
359 |
item.loc = [x, y] |
360 |
item.size = (width, height) |
361 |
item.angle = angle |
362 |
item.setToolTip('<b>{}</b><br>LINE NO={}'.format(str(item.uid), text)) |
363 |
|
364 |
""" apply freeze value """
|
365 |
# item.freeze_item.update_freeze(item.prop('Freeze'))
|
366 |
|
367 |
if connline is not None: |
368 |
item.conns.append(connline) |
369 |
except Exception as ex: |
370 |
from App import App |
371 |
from AppDocData import MessageType |
372 |
|
373 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
374 |
sys.exc_info()[-1].tb_lineno)
|
375 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
376 |
return None |
377 |
|
378 |
return item
|
379 |
|
380 |
@staticmethod
|
381 |
def fromXml(node): |
382 |
""" generate EngineeringLineNoTextItem from xml node """
|
383 |
import uuid |
384 |
from TextItemFactory import TextItemFactory |
385 |
from SymbolAttr import SymbolAttr |
386 |
|
387 |
item = None
|
388 |
|
389 |
try:
|
390 |
location = node.find('LOCATION').text if node.find('LOCATION') is not None else '0,0' |
391 |
x = float(location.split(',')[0]) |
392 |
y = float(location.split(',')[1]) |
393 |
width = float(node.find('WIDTH').text) if node.find('WIDTH') is not None else 0 |
394 |
height = float(node.find('HEIGHT').text) if node.find('HEIGHT') is not None else 0 |
395 |
angle = float(node.find('ANGLE').text) if node.find('ANGLE') is not None else 0 |
396 |
text = node.find('TEXT').text
|
397 |
textInfo = TextInfo(text, x, y, width, height, angle) |
398 |
connline = node.find('CONNLINE').text if node.find('CONNLINE') is not None else None |
399 |
|
400 |
item = TextItemFactory.instance().createTextItem(textInfo) |
401 |
if item is not None: |
402 |
item.setVisible(False)
|
403 |
for prop_node in node.iter('PROPERTY'): |
404 |
matches = [prop for prop in item._properties.keys() if |
405 |
prop.Attribute == prop_node.attrib['Attribute']]
|
406 |
if matches:
|
407 |
item._properties[matches[0]] = matches[0].parse_value(prop_node.text) |
408 |
|
409 |
for attr_node in node.iter('ATTRIBUTE'): |
410 |
attr = SymbolAttr.fromXml(attr_node) |
411 |
item.attrs[attr] = attr_node.text |
412 |
|
413 |
item.uid = uuid.UUID(node.find('UID').text)
|
414 |
item.loc = [x, y] |
415 |
item.size = (width, height) |
416 |
item.angle = angle |
417 |
item.setToolTip('<b>{}</b><br>LINE NO={}'.format(str(item.uid), text)) |
418 |
|
419 |
# get associations
|
420 |
attributeValue = node.find('ASSOCIATIONS')
|
421 |
if attributeValue is not None: |
422 |
for assoc in attributeValue.iter('ASSOCIATION'): |
423 |
_attrType = assoc.attrib['TYPE']
|
424 |
if not _attrType in item._associations: |
425 |
item._associations[_attrType] = [] |
426 |
item._associations[_attrType].append(uuid.UUID(assoc.text) if assoc.text != 'None' else None) |
427 |
# up to here
|
428 |
|
429 |
""" apply freeze value """
|
430 |
# item.freeze_item.update_freeze(item.prop('Freeze'))
|
431 |
|
432 |
if connline is not None: |
433 |
item.conns.append(connline) |
434 |
except Exception as ex: |
435 |
from App import App |
436 |
from AppDocData import MessageType |
437 |
|
438 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
439 |
sys.exc_info()[-1].tb_lineno)
|
440 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
441 |
return None |
442 |
|
443 |
return item
|
444 |
|
445 |
'''
|
446 |
@brief generate xml code
|
447 |
@author humkyung
|
448 |
@date 2018.04.23
|
449 |
@history humkyung 2018.05.02 write symbol's attribute
|
450 |
humkyung 2018.05.16 write run information to xml
|
451 |
'''
|
452 |
|
453 |
def toXml(self): |
454 |
from xml.etree.ElementTree import Element, SubElement, dump, ElementTree |
455 |
from EngineeringLineItem import QEngineeringLineItem |
456 |
from SymbolSvgItem import SymbolSvgItem |
457 |
|
458 |
try:
|
459 |
docData = AppDocData.instance() |
460 |
configs = docData.getConfigs('Line No', 'Delimiter') |
461 |
delimiter = configs[0].value if 1 == len(configs) else '-' |
462 |
lineNoconfigs = docData.getConfigs('Line No', 'Configuration') |
463 |
|
464 |
node = Element('LINE_NO')
|
465 |
uidNode = Element('UID')
|
466 |
uidNode.text = str(self.uid) |
467 |
node.append(uidNode) |
468 |
|
469 |
textNode = Element('TEXT')
|
470 |
textNode.text = self.text()
|
471 |
node.append(textNode) |
472 |
|
473 |
locNode = Element('LOCATION')
|
474 |
locNode.text = '{},{}'.format(self.loc[0], self.loc[1]) |
475 |
node.append(locNode) |
476 |
|
477 |
widthNode = Element('WIDTH')
|
478 |
widthNode.text = str(self.size[0]) |
479 |
node.append(widthNode) |
480 |
|
481 |
heightNode = Element('HEIGHT')
|
482 |
heightNode.text = str(self.size[1]) |
483 |
node.append(heightNode) |
484 |
|
485 |
angleNode = Element('ANGLE')
|
486 |
angleNode.text = str(self.angle) |
487 |
node.append(angleNode) |
488 |
|
489 |
areaNode = Element('AREA')
|
490 |
areaNode.text = self.area
|
491 |
node.append(areaNode) |
492 |
|
493 |
for run in self.runs: |
494 |
node.append(run.toXml()) |
495 |
|
496 |
attributeValueNode = Element('ASSOCIATIONS')
|
497 |
for key, value in self._associations.items(): |
498 |
for assoc in value: |
499 |
assoc_node = Element('ASSOCIATION')
|
500 |
assoc_node.attrib['TYPE'] = str(key) |
501 |
assoc_node.text = str(assoc)
|
502 |
attributeValueNode.append(assoc_node) |
503 |
node.append(attributeValueNode) |
504 |
|
505 |
properties_node = Element('PROPERTIES')
|
506 |
for prop, value in self.properties.items(): |
507 |
prop_node = prop.toXml() |
508 |
prop_node.text = str(value) if value else '' |
509 |
properties_node.append(prop_node) |
510 |
node.append(properties_node) |
511 |
|
512 |
_attrs = self.getAttributes()
|
513 |
for key in _attrs.keys(): |
514 |
if key.UID is not None: |
515 |
attrNode = key.toXml() |
516 |
attrNode.text = str(_attrs[key])
|
517 |
node.append(attrNode) |
518 |
|
519 |
if self.conns: |
520 |
connNode = Element('CONNLINE')
|
521 |
connNode.text = str(self.conns[0].uid) if hasattr(self.conns[0], 'uid') else str(self.conns[0]) |
522 |
node.append(connNode) |
523 |
|
524 |
sceneNode = Element('SCENE')
|
525 |
sceneNode.text = str(self.sceneBoundingRect()).replace('PyQt5.QtCore.QRectF(', '').replace(' ', '').replace( |
526 |
')', '') |
527 |
node.append(sceneNode) |
528 |
|
529 |
except Exception as ex: |
530 |
from App import App |
531 |
from AppDocData import MessageType |
532 |
|
533 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
534 |
sys.exc_info()[-1].tb_lineno)
|
535 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
536 |
|
537 |
return None |
538 |
|
539 |
return node
|
540 |
|
541 |
def to_svg(self, parent) -> list: |
542 |
"""convert line no item to svg"""
|
543 |
import re |
544 |
from xml.etree.ElementTree import Element, SubElement, dump, ElementTree |
545 |
from App import App |
546 |
|
547 |
res = [] |
548 |
try:
|
549 |
app_doc_data = AppDocData.instance() |
550 |
prj = app_doc_data.getCurrentProject() |
551 |
|
552 |
node = Element('g')
|
553 |
node.attrib['id'] = str(self.uid) |
554 |
node.attrib['class'] = 'Pipe' |
555 |
node.attrib['data-tag-name'] = self.toPlainText() |
556 |
node.attrib['font-family'] = self.font().family() |
557 |
node.attrib['font-size'] = str(self.boundingRect().height()) # str(self.font().pointSizeF()) |
558 |
node.attrib['font-weight'] = str(self.font().weight()) |
559 |
|
560 |
except_pattern = re.compile('[^a-zA-Z0-9-_]')
|
561 |
for attr, value in self.getAttributes().items(): |
562 |
node.attrib[re.sub(except_pattern, '_', attr.Attribute)] = value if value else '' |
563 |
trans = self.sceneTransform()
|
564 |
node.attrib['transform'] = f"matrix(" \ |
565 |
f"{trans.m11()},{trans.m12()}," \
|
566 |
f"{trans.m21()},{trans.m22()}," \
|
567 |
f"{trans.m31()},{trans.m32()}" \
|
568 |
f")"
|
569 |
|
570 |
text = Element('text')
|
571 |
text.text = self.toPlainText()
|
572 |
text.attrib['textLength'] = str(self.boundingRect().width()) |
573 |
text.attrib['lengthAdjust'] = 'spacingAndGlyphs' |
574 |
text.attrib['alignment-baseline'] = 'hanging' # align left-top corner |
575 |
node.append(text) |
576 |
|
577 |
connected_line = self.connected_line
|
578 |
if connected_line:
|
579 |
conn_node = connected_line.to_svg(self)
|
580 |
if conn_node:
|
581 |
node.extend(conn_node) |
582 |
|
583 |
res.append(node) |
584 |
except Exception as ex: |
585 |
from App import App |
586 |
from AppDocData import MessageType |
587 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
588 |
sys.exc_info()[-1].tb_lineno)
|
589 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
590 |
|
591 |
return res
|
592 |
|
593 |
def end_break(self): |
594 |
'''
|
595 |
@brief end break check
|
596 |
@author euisung
|
597 |
@date 2019.05.07
|
598 |
@history 2019.05.19 euisung can cover at both end that contact other line's middle
|
599 |
2019.05.19 euisung no more used integrated with linetracer
|
600 |
'''
|
601 |
from EngineeringLineItem import QEngineeringLineItem |
602 |
from SymbolSvgItem import SymbolSvgItem |
603 |
from AppDocData import AppDocData |
604 |
end_breaks = [] |
605 |
|
606 |
try:
|
607 |
docdata = AppDocData.instance() |
608 |
|
609 |
line_from = self.prop('From') |
610 |
line_to = self.prop('To') |
611 |
|
612 |
end_break_names = docdata.getSymbolListByType('type', 'End Break') |
613 |
if len(end_break_names) is 0: |
614 |
return end_breaks
|
615 |
|
616 |
svgFileName = end_break_names[0].sName
|
617 |
symbol = AppDocData.instance().getSymbolByQuery('name', svgFileName)
|
618 |
svgFilePath = os.path.join(AppDocData.instance().getCurrentProject().getSvgFilePath(), symbol.getType(), |
619 |
svgFileName + '.svg')
|
620 |
|
621 |
for line_end in [line_from, line_to]: |
622 |
for connector in line_end.connectors: |
623 |
if connector.connectedItem is not None and connector.connectedItem.owner is not self: |
624 |
end_break = SymbolSvgItem.createItem(symbol.getType(), None, svgFilePath)
|
625 |
pt = [connector.center()[0] - float(symbol.getOriginalPoint().split(',')[0]), |
626 |
connector.center()[1] - float(symbol.getOriginalPoint().split(',')[1])] |
627 |
origin = [0, 0] |
628 |
if 2 == len(symbol.getOriginalPoint().split(',')): |
629 |
tokens = symbol.getOriginalPoint().split(',')
|
630 |
origin = [pt[0] + float(tokens[0]), pt[1] + float(tokens[1])] |
631 |
end_break.buildItem(svgFileName, symbol.getType(), 5.7, pt,
|
632 |
[end_break.boundingRect().width(), end_break.boundingRect().height()], |
633 |
origin, [], symbol.getBaseSymbol(), symbol.getAdditionalSymbol(), |
634 |
symbol.getHasInstrumentLabel()) |
635 |
|
636 |
end_break.set_property('Connected Item', connector.connectedItem)
|
637 |
end_break.setToolTip('owner : ' + str(line_end)) |
638 |
end_break.area = 'Drawing'
|
639 |
end_break.owner = line_end |
640 |
end_breaks.append(end_break) |
641 |
except Exception as ex: |
642 |
from App import App |
643 |
from AppDocData import MessageType |
644 |
|
645 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
646 |
sys.exc_info()[-1].tb_lineno)
|
647 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
648 |
|
649 |
return end_breaks
|
650 |
|
651 |
'''
|
652 |
@Override (QEngineeringTextItem)
|
653 |
@brief get connected items
|
654 |
@author Jeongwoo
|
655 |
@date 2018.05.15
|
656 |
'''
|
657 |
|
658 |
def getConnectedItems(self): |
659 |
visited = [] |
660 |
|
661 |
try:
|
662 |
for run in self.runs: |
663 |
visited.extend(run.items) |
664 |
except Exception as ex: |
665 |
from App import App |
666 |
from AppDocData import MessageType |
667 |
|
668 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
669 |
sys.exc_info()[-1].tb_lineno)
|
670 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
671 |
|
672 |
return visited
|
673 |
|
674 |
def explode(self, remainFromTo=False): |
675 |
""" explode line no """
|
676 |
|
677 |
# if False == self.prop('Freeze'):
|
678 |
try:
|
679 |
for index in reversed(range(len(self.runs))): |
680 |
self.runs[index].explode()
|
681 |
finally:
|
682 |
self.runs.clear()
|
683 |
if not remainFromTo: |
684 |
self.set_property('From', None) |
685 |
self.set_property('To', None) |
686 |
|
687 |
'''
|
688 |
@brief generate sql phrase to save to database(Notice: Line No's symbol is is 1)
|
689 |
@author humkyung
|
690 |
@date 2018.08.14
|
691 |
'''
|
692 |
|
693 |
def toSql_return_separately(self): |
694 |
import uuid |
695 |
from EngineeringAbstractItem import QEngineeringAbstractItem |
696 |
|
697 |
res = [] |
698 |
resLater = [] |
699 |
|
700 |
app_doc_data = AppDocData.instance() |
701 |
cols = ['UID', 'Drawings_UID', 'Symbol_UID', 'X', 'Y', 'Width', 'Height', 'Rotation', 'Value', 'Connected', |
702 |
'[From]', '[To]'] |
703 |
if type(self) is QEngineeringLineNoTextItem: |
704 |
values = ['?', '?', "(select UID from Symbol where Name='Line NO' and SymbolType_UID=-1)", '?', '?', '?', |
705 |
'?', '?', '?', '?', '?', '?'] |
706 |
else:
|
707 |
values = ['?', '?', "(select UID from Symbol where Name='Trim Line NO' and SymbolType_UID=-1)", '?', '?', |
708 |
'?', '?', '?', '?', '?', '?', '?'] |
709 |
params = [(str(self.uid), str(app_doc_data.activeDrawing.UID), self.loc[0], self.loc[1], self.size[0], |
710 |
self.size[1], str(self.angle), \ |
711 |
self.text(), str(self.conns[0]) if self.conns else None, str(self.prop('From')), |
712 |
str(self.prop('To')))] |
713 |
sql = 'insert into Components({}) values({})'.format(','.join(cols), ','.join(values)) |
714 |
res.append((sql, tuple(params)))
|
715 |
|
716 |
cols = ['UID', 'Components_UID', 'LineProperties_UID', 'Value'] |
717 |
values = ['?', '?', '?', '?'] |
718 |
params = [] |
719 |
attrs = self.getAttributes()
|
720 |
for key, value in attrs.items(): |
721 |
if key.Attribute == 'LINE NO': # or key.IsProp != 5: |
722 |
continue
|
723 |
params.append((str(uuid.uuid4()), str(self.uid), str(key.UID), str(value))) |
724 |
sql = 'insert into LineNoAttributes({}) values({})'.format(','.join(cols), ','.join(values)) |
725 |
resLater.append((sql, tuple(params)))
|
726 |
|
727 |
if self.associations(): |
728 |
cols = ['UID', '[Type]', 'Components_UID', 'Association'] |
729 |
values = ['?', '?', '?', '?'] |
730 |
params = [] |
731 |
for assoc in self.associations(): |
732 |
params.append( |
733 |
(str(uuid.uuid4()), QEngineeringAbstractItem.assoc_type(assoc), str(self.uid), str(assoc.uid))) |
734 |
sql = 'insert into Associations({}) values({})'.format(','.join(cols), ','.join(values)) |
735 |
resLater.append((sql, tuple(params)))
|
736 |
|
737 |
# insert line no's Attributes
|
738 |
cols = ['UID', 'Components_UID', 'SymbolAttribute_UID', 'Value', 'Association_UID', 'Freeze'] |
739 |
values = ['?', '?', '?', '?', '?', '?'] |
740 |
params = [] |
741 |
for key in attrs.keys(): |
742 |
if key.IsProp != 5: |
743 |
params.append((str(uuid.uuid4()), str(self.uid), str(key.UID), str(attrs[key]), str(key.AssocItem), |
744 |
str(key.Freeze)))
|
745 |
sql = 'insert into Attributes({}) values({})'.format(','.join(cols), ','.join(values)) |
746 |
res.append((sql, tuple(params)))
|
747 |
|
748 |
if self.associations(): |
749 |
cols = ['UID', '[Type]', 'Components_UID', 'Association'] |
750 |
values = ['?', '?', '?', '?'] |
751 |
params = [] |
752 |
for assoc in self.associations(): |
753 |
params.append( |
754 |
(str(uuid.uuid4()), QEngineeringAbstractItem.assoc_type(assoc), str(self.uid), str(assoc.uid))) |
755 |
sql = 'insert into Associations({}) values({})'.format(','.join(cols), ','.join(values)) |
756 |
resLater.append((sql, tuple(params)))
|
757 |
|
758 |
_index = 0
|
759 |
for run in self.runs: |
760 |
resLater.extend(run.to_sql(_index, self))
|
761 |
_index += 1
|
762 |
|
763 |
return res, resLater
|
764 |
|
765 |
'''
|
766 |
@brief return Line Data List
|
767 |
@author kyouho
|
768 |
@date 2018.08.14
|
769 |
'''
|
770 |
|
771 |
def getLineDataList(self): |
772 |
dataList = [] |
773 |
try:
|
774 |
import uuid |
775 |
global lineColumnList
|
776 |
|
777 |
docData = AppDocData.instance() |
778 |
attrs = self.getAttributes()
|
779 |
for index in range(len(lineColumnList)): |
780 |
dataList.append('')
|
781 |
|
782 |
dataList[20] = docData.imgName
|
783 |
|
784 |
for key in attrs.keys(): |
785 |
if type(key) is not UserInputAttribute: |
786 |
lineProp = docData.getLinePropertiesByUID(key.UID) |
787 |
if lineProp:
|
788 |
attrName = lineProp[0].Attribute.upper().replace(' ', '') |
789 |
else:
|
790 |
attrName = key.Attribute.upper().replace(' ', '') |
791 |
|
792 |
data = attrs[key] |
793 |
if attrName == 'NOMINALDIAMETER': |
794 |
dataList[1] = data
|
795 |
elif attrName == 'FLUIDCODE': |
796 |
dataList[2] = data
|
797 |
dataList[7] = data
|
798 |
elif attrName == 'TAGSEQNO': |
799 |
pass
|
800 |
elif attrName == 'INSULATIONPURPOSE': |
801 |
dataList[16] = data
|
802 |
elif attrName == 'STREAMNO': |
803 |
pass
|
804 |
elif attrName == 'LINENO' or attrName == 'LINE NO': |
805 |
dataList[3] = data
|
806 |
elif attrName == 'PNIDNUMBER': |
807 |
pass
|
808 |
elif attrName == 'PIPINGMATERIALSCLASS': |
809 |
dataList[4] = data
|
810 |
elif attrName == '': |
811 |
pass
|
812 |
else:
|
813 |
typeUID = key.Attribute |
814 |
value = key.text |
815 |
lineAttr = docData.getLinePropertiesByUID(key.UD) |
816 |
|
817 |
for index in range(len(lineColumnList)): |
818 |
if lineColumnList[index] == lineAttr[0].Attribute: |
819 |
dataList[index] = value |
820 |
except Exception as ex: |
821 |
from App import App |
822 |
from AppDocData import MessageType |
823 |
|
824 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
825 |
sys.exc_info()[-1].tb_lineno)
|
826 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
827 |
|
828 |
if dataList[0] == '': |
829 |
dataList[0] = str(uuid.uuid4()) |
830 |
|
831 |
return dataList
|
832 |
|
833 |
def EvaluatedEQ(self): |
834 |
''' evaluate line no's From / To equipment '''
|
835 |
|
836 |
from EngineeringNozzleItem import QEngineeringNozzleItem |
837 |
from EngineeringVendorItem import QEngineeringVendorItem |
838 |
from EngineeringEquipmentItem import QEngineeringEquipmentItem |
839 |
|
840 |
if self.runs and self.runs[0]: |
841 |
items = self.runs[0].items |
842 |
if len(items) > 2: |
843 |
_attrs = self.getAttributes()
|
844 |
if type(items[0]) is QEngineeringNozzleItem: |
845 |
for connector in items[0].connectors: |
846 |
# From
|
847 |
if (type(connector.connectedItem) is QEngineeringVendorItem or type( |
848 |
connector.connectedItem) is QEngineeringEquipmentItem) and \ |
849 |
connector.connectedItem not in items: |
850 |
for _attr in _attrs: |
851 |
if _attr.Attribute == 'From_eq' and self.add_assoc_item(connector.connectedItem, |
852 |
at=_attr.AttrAt): |
853 |
_attr.AssocItem = connector.connectedItem |
854 |
break
|
855 |
break
|
856 |
|
857 |
if type(items[-1]) is QEngineeringNozzleItem: |
858 |
for connector in items[-1].connectors: |
859 |
# To
|
860 |
if (type(connector.connectedItem) is QEngineeringVendorItem or type( |
861 |
connector.connectedItem) is QEngineeringEquipmentItem) and \ |
862 |
connector.connectedItem not in items: |
863 |
for _attr in _attrs: |
864 |
if _attr.Attribute == 'To_eq' and self.add_assoc_item(connector.connectedItem, |
865 |
at=_attr.AttrAt): |
866 |
_attr.AssocItem = connector.connectedItem |
867 |
break
|
868 |
break
|