프로젝트

일반

사용자정보

통계
| 개정판:

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
클립보드 이미지 추가 (최대 크기: 500 MB)