프로젝트

일반

사용자정보

통계
| 개정판:

hytos / DTI_PID / DTI_PID / Shapes / EngineeringAbstractItem.py @ baa87c88

이력 | 보기 | 이력해설 | 다운로드 (54.1 KB)

1
# coding: utf-8
2
""" This is engineering abstract item module """
3

    
4
import sys
5
#import random
6

    
7

    
8
class QEngineeringAbstractItem:
9
    '''
10
        @history    2018.05.15  Jeongwoo    Remove call super
11
                    2018.05.17  Jeongwoo    Add DEFAULT_COLOR Variable
12
    '''
13
    DEFAULT_COLOR = '#0000FF'
14
    HOVER_COLOR = '#BC4438'
15
    SELECTED_COLOR = '#FF00BF'
16

    
17
    CONNECTED_AT_PT = 0
18
    CONNECTED_AT_BODY = 1
19

    
20
    HOVER_ZVALUE = 200
21

    
22
    def __init__(self, parent=None):
23
        self._color = self.DEFAULT_COLOR  # default color
24
        self._owner = None
25
        self.conns = []
26
        self.special_item_type = None  # UID for special item type
27
        self._hover = False
28
        self._area = None
29
        self.connectors = []
30
        self.attrs = {}  # attributes
31
        self._associations = {'Text Item': [], 'Symbol Item': []}  # associated items
32
        self.sizeDepth = 0
33

    
34
        #self.refresh_count = random.randint(0, 9)
35

    
36
    @property
37
    def hover(self):
38
        """ return hover """
39
        return self._hover
40

    
41
    @hover.setter
42
    def hover(self, value):
43
        """ set hover """
44
        self._hover = value
45

    
46
    def change_color(self, value):
47
        """ change item's color """
48
        self._color = value
49

    
50
    def highlight(self, flag):
51
        pass
52

    
53
    '''
54
        @brief      Abstract method. Variable [color] is RGB hex code
55
        @author     Jeongwoo
56
        @date       2018.05.11
57
    '''
58

    
59
    def setColor(self, color):
60
        raise NotImplementedError
61

    
62
    '''
63
        @brief  return color
64
        @author Jeongwoo
65
        @date   2018.05.11
66
    '''
67

    
68
    def getColor(self):
69
        from SymbolSvgItem import SymbolSvgItem
70
        from EngineeringEquipmentItem import QEngineeringEquipmentItem
71
        from EngineeringInstrumentItem import QEngineeringInstrumentItem
72
        from AppDocData import AppDocData
73
        from DisplayColors import DisplayColors
74
        from DisplayColors import DisplayOptions
75
        from EngineeringAbstractItem import QEngineeringAbstractItem
76
        from EngineeringLineItem import QEngineeringLineItem
77

    
78
        def check_stream_no_attribute():
79
            """ return stream no if item has stream no attribute else return False """
80
            _attrs = self.getAttributes(findOwner=True)
81
            for key, value in _attrs.items():
82
                if key.Attribute == 'Stream No':
83
                    if value:
84
                        return value
85
                    elif value == '' or value == None:
86
                        return None
87
                    else:
88
                        return False
89

    
90
        try:
91
            app_doc_data = AppDocData.instance()
92

    
93
            if DisplayOptions.DisplayByStreamNo == DisplayColors.instance().option and \
94
                    (issubclass(type(self), SymbolSvgItem) or type(self) is QEngineeringLineItem):
95
                res = check_stream_no_attribute()
96
                if res and res in app_doc_data._hmbColors:
97
                    return app_doc_data._hmbColors[res]
98
                else:
99
                    return QEngineeringAbstractItem.DEFAULT_COLOR
100
                
101
            if DisplayOptions.DisplayByARS == DisplayColors.instance().option and \
102
                    (issubclass(type(self), SymbolSvgItem) or type(self) is QEngineeringLineItem):
103
                if str(self.uid) in app_doc_data._arsColors:
104
                    return app_doc_data._arsColors[str(self.uid)]
105
                else:
106
                    return QEngineeringAbstractItem.DEFAULT_COLOR
107

    
108
            if type(self) is QEngineeringEquipmentItem:
109
                # if DisplayOptions.DisplayByLineType == DisplayColors.instance().option:
110
                if self.hover:
111
                    return SymbolSvgItem.HOVER_COLOR
112
                elif not QEngineeringEquipmentItem.EQUIP_COLOR:
113
                    configs = app_doc_data.getConfigs('Equipment', 'Color')
114
                    QEngineeringEquipmentItem.EQUIP_COLOR = configs[
115
                        0].value if configs else QEngineeringAbstractItem.DEFAULT_COLOR
116

    
117
                return QEngineeringEquipmentItem.EQUIP_COLOR
118

    
119
            elif type(self) is QEngineeringInstrumentItem:
120
                if self.hover:
121
                        return SymbolSvgItem.HOVER_COLOR
122
                elif DisplayOptions.DisplayByLineType == DisplayColors.instance().option:
123
                    if not QEngineeringInstrumentItem.INST_COLOR:
124
                        configs = app_doc_data.getConfigs('Instrument', 'Color')
125
                        QEngineeringInstrumentItem.INST_COLOR = configs[
126
                            0].value if configs else QEngineeringAbstractItem.DEFAULT_COLOR
127
                    return QEngineeringInstrumentItem.INST_COLOR
128
                else:
129
                    return self.owner._color if self.owner and hasattr(self.owner, '_color') else self._color
130

    
131
            elif type(self) is SymbolSvgItem:
132
                return SymbolSvgItem.HOVER_COLOR if self.hover else ( \
133
                    self.owner._color if self.owner and hasattr(self.owner, '_color') else self._color)
134

    
135
            elif type(self) is QEngineeringLineItem:
136
                if self.hover:
137
                    return QEngineeringAbstractItem.HOVER_COLOR
138
                elif self.isSelected():
139
                    return QEngineeringAbstractItem.SELECTED_COLOR
140
                elif DisplayOptions.DisplayByLineType == DisplayColors.instance().option:
141
                    if self.lineType in QEngineeringLineItem.LINE_TYPE_COLORS:
142
                        return QEngineeringLineItem.LINE_TYPE_COLORS[self.lineType]
143
                    else:
144
                        configs = app_doc_data.getConfigs('LineTypes', self.lineType)
145
                        if configs:
146
                            tokens = configs[0].value.split(',')
147
                            QEngineeringLineItem.LINE_TYPE_COLORS[self.lineType] = tokens[0] if len(tokens) == 4 else \
148
                                QEngineeringAbstractItem.DEFAULT_COLOR
149
                            return QEngineeringLineItem.LINE_TYPE_COLORS[self.lineType]
150
                        else:
151
                            return QEngineeringAbstractItem.DEFAULT_COLOR
152
                else:
153
                    return self.owner._color if self.owner and hasattr(self.owner, '_color') else self._color
154
                    '''
155
                    if self.owner is None:
156
                        return self._color
157
                    else:
158
                        return self.owner.getColor()
159
                    '''
160
        except Exception as ex:
161
            from App import App
162
            from AppDocData import MessageType
163

    
164
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
165
                                                           sys.exc_info()[-1].tb_lineno)
166
            App.mainWnd().addMessage.emit(MessageType.Error, message)
167

    
168
            return  QEngineeringAbstractItem.DEFAULT_COLOR
169

    
170
        return QEngineeringAbstractItem.HOVER_COLOR if self.hover else (
171
            self.owner.getColor() if (self.owner and hasattr(self.owner, '_color')) else self._color)
172

    
173
    '''
174
        @brief  getter of owner
175
        @author humkyung
176
        @date   2018.05.12
177
    '''
178

    
179
    @property
180
    def owner(self):
181
        return self._owner
182

    
183
    '''
184
        @brief  setter of owner
185
        @author humkyung
186
        @date   2018.05.12
187
    '''
188

    
189
    @owner.setter
190
    def owner(self, value):
191
        self._owner = value
192

    
193
    @property
194
    def has_connection(self):
195
        """ check this is connected to other """
196
        for connector in self.connectors:
197
            if connector.connectedItem: return True
198

    
199
        return False
200

    
201
    def validate(self):
202
        """ validate this """
203
        raise NotImplementedError('To be implemented')
204

    
205
    '''
206
        @brief  getter of area
207
        @author humkyung
208
        @date   2018.09.06
209
    '''
210

    
211
    @property
212
    def area(self):
213
        return self._area if self._area is not None else 'None'
214

    
215
    '''
216
        @brief  setter of area
217
        @author humkyung
218
        @date   2018.09.06
219
    '''
220

    
221
    @area.setter
222
    def area(self, value):
223
        self._area = value
224

    
225
    '''
226
        @brief  write to xml
227
        @author humkyung
228
        @date   2018.05.16
229
    '''
230

    
231
    def toXml(self):
232
        pass
233

    
234
    def to_svg(self, parent=None) -> list:
235
        pass
236

    
237
    '''
238
        @brief  write attribute to xml
239
        @author humkyung
240
        @date   2018.05.16
241
    '''
242

    
243
    def toXmlAsAttribute(self, parent):
244
        pass
245

    
246
    def toSql(self):
247
        """convert to sql query"""
248
        pass
249

    
250
    def isOverlap(self, rect1, rect2):
251
        """
252
        @brief  return true if rects have intersection, rect is QRect
253
        @author euisung
254
        @date   2019.09.02
255
        """
256
        lt1, rb1 = (rect1.left(), rect1.top()), (rect1.right(), rect1.bottom())
257
        lt2, tb2 = (rect2.left(), rect2.top()), (rect2.right(), rect2.bottom())
258
        if rect1.left() > rect2.right() or rect2.left() > rect1.right():
259
            return False
260
        if rect1.bottom() < rect2.top() or rect2.bottom() < rect1.top():
261
            return False
262

    
263
        return True
264

    
265
    def associations(self):
266
        """ return associated instance """
267
        # move to abstractitem
268
        import uuid
269

    
270
        try:
271
            res = []
272
            for key in self._associations.keys():
273
                index = 0
274
                for assoc in list(self._associations[key]):
275
                    # find owner with uid if self.scene() is valid
276
                    if self.scene() and assoc and type(assoc) is uuid.UUID:
277
                        #matches = [x for x in self.scene().items() if hasattr(x, 'uid') and str(x.uid) == str(assoc)]
278
                        matches = []
279
                        for item in self.scene().items():
280
                            if hasattr(item, 'uid') and str(item.uid) == str(assoc):
281
                                matches = [item]
282
                                break
283
                        if matches:
284
                            res.append(matches[0])
285
                            self._associations[key][index] = matches[0]
286
                    # up to here
287
                    elif assoc:
288
                        res.append(assoc)
289
                    index += 1
290

    
291
            for key in self.attrs.keys():
292
                if type(key.AssocItem) is uuid.UUID:
293
                    for assoc in res:
294
                        if str(key.AssocItem) == str(assoc.uid):
295
                            key.AssocItem = assoc
296

    
297
            return res
298
        except Exception as ex:
299
            from App import App
300
            from AppDocData import MessageType
301

    
302
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
303
                                                           sys.exc_info()[-1].tb_lineno)
304
            App.mainWnd().addMessage.emit(MessageType.Error, message)
305
            return []
306

    
307
    def get_assoc_item(self, assoc):
308
        """ get associated item of given object """
309
        import uuid
310

    
311
        if assoc and type(assoc) is uuid.UUID:
312
            #matches = [x for x in self.scene().items() if hasattr(x, 'uid') and str(x.uid) == str(assoc)]
313
            matches = []
314
            for item in self.scene().items():
315
                if hasattr(item, 'uid') and str(item.uid) == str(assoc):
316
                    matches = [item]
317
                    break
318
            if matches:
319
                return matches[0]
320

    
321
        return assoc
322

    
323
    def texts(self):
324
        """ return text type of associations """
325
        res = []
326

    
327
        for text in self.texts_order():
328
            consumed = False
329
            for key in list(self.attrs.keys()):
330
                if key.AssocItem and key.AssocItem is text:
331
                    consumed = True
332
            if not consumed:
333
                res.append(text)
334

    
335
        return res
336

    
337
    def texts_order(self):
338
        from EngineeringTextItem import QEngineeringTextItem
339
        
340
        return sorted([x for x in self.associations() if issubclass(type(x), QEngineeringTextItem)],
341
                           key=lambda attr: attr.loc[1])
342

    
343
    def symbols(self, symbol_attr_number):
344
        """ return symbol type of associations """
345
        from SymbolSvgItem import SymbolSvgItem
346
        from EngineeringVendorItem import QEngineeringVendorItem
347
        from EngineeringLineItem import QEngineeringLineItem
348
        from EngineeringLineNoTextItem import QEngineeringLineNoTextItem
349

    
350
        res = []
351
        for symbol in [x for x in self.associations() if
352
                       issubclass(type(x), SymbolSvgItem) or type(x) is QEngineeringVendorItem or type(x) is QEngineeringLineItem]:
353
            if symbol_attr_number > 1:
354
                consumed = False
355
                for key in list(self.attrs.keys()):
356
                    if key.AssocItem and key.AssocItem is symbol:
357
                        consumed = True
358
                if not consumed:
359
                    res.append(symbol)
360
            elif type(self) is not QEngineeringLineNoTextItem:
361
                res.append(symbol)
362

    
363
        return res
364

    
365
    @property
366
    def Size(self):
367
        """ return symbol's size """
368
        from QEngineeringSizeTextItem import QEngineeringSizeTextItem
369

    
370
        matches = [assoc for assoc in self.associations() if type(assoc) is QEngineeringSizeTextItem]
371
        if matches:
372
            attrs = [attr for attr in self.getTargetAttributes() if attr.AttributeType == 'Size Text Item']
373
            if attrs:
374
                return matches[0].mainSize
375

    
376
        return None
377

    
378
    @property
379
    def EvaluatedSize(self):
380
        from EngineeringReducerItem import QEngineeringReducerItem
381
        from EngineeringLineNoTextItem import QEngineeringLineNoTextItem
382
        from SymbolSvgItem import SymbolSvgItem
383
        from EngineeringLineItem import QEngineeringLineItem
384
        from EngineeringInstrumentItem import QEngineeringInstrumentItem
385
        from AppDocData import AppDocData
386

    
387
        try:
388
            if self.Size:
389
                self.sizeDepth = 0
390
                return self.Size
391
            if self.owner and issubclass(type(self.owner), QEngineeringLineNoTextItem):
392
                matches = [run for run in self.owner.runs if self in run.items]
393
                if matches:
394
                    at = matches[0].items.index(self)
395
                    upstream = matches[0].items[:at]
396
                    upstream.reverse()
397
                    prev = self
398
                    for item in upstream:
399
                        if type(item) is QEngineeringReducerItem:
400
                            if item.connectors[0].connectedItem is prev:  ### Main Size
401
                                if item.mainSubSize and item.mainSubSize[0]:
402
                                    self.sizeDepth = 0
403
                                    return item.mainSubSize[0]
404
                            elif item.connectors[1].connectedItem is prev:  ### Sub Size
405
                                if item.mainSubSize and item.mainSubSize[1]:
406
                                    self.sizeDepth = 0
407
                                    return item.mainSubSize[1]
408
                        elif type(item) is QEngineeringInstrumentItem and item.iType == 22: # Relief Valve -> upstream always false
409
                            if item.mainSubSize and item.mainSubSize[0]:
410
                                self.sizeDepth = 0
411
                                return item.mainSubSize[0]
412
                        else:
413
                            if item.Size:
414
                                self.sizeDepth = 0
415
                                return item.Size
416
                        prev = item
417

    
418
                    downstream = matches[0].items[at:]
419
                    prev = self
420
                    for item in downstream:
421
                        if type(item) is QEngineeringReducerItem:
422
                            if item.connectors[0].connectedItem is prev:  ### Main Size
423
                                if item.mainSubSize and item.mainSubSize[0]:
424
                                    self.sizeDepth = 0
425
                                    return item.mainSubSize[0]
426
                            elif item.connectors[1].connectedItem is prev:  ### Sub Size
427
                                if item.mainSubSize and item.mainSubSize[1]:
428
                                    self.sizeDepth = 0
429
                                    return item.mainSubSize[1]
430
                        elif type(item) is QEngineeringInstrumentItem and item.iType == 22: # Relief Valve
431
                            if item.mainSubSize and item.mainSubSize[1]:
432
                                self.sizeDepth = 0
433
                                return item.mainSubSize[1]
434
                        else:
435
                            if item.Size:
436
                                self.sizeDepth = 0
437
                                return item.Size
438
                        prev = item
439

    
440
                    #if 'Drain' == matches[0].Type:
441
                    #    self.sizeDepth = 0
442
                    #    return ''
443
                    #    #return AppDocData.instance().drain_size
444

    
445
                if self.owner.runs and self in self.owner.runs[0].items:
446
                    self.sizeDepth = 0
447
                    return self.owner.Size 
448
                elif self.sizeDepth < 2:
449
                    matches = [run for run in self.owner.runs if self in run.items]
450
                    if matches:
451
                        if type(matches[0].items[0]) is QEngineeringLineItem:
452
                            _item = matches[0].items[0]
453
                            connectedItems = [conn.connectedItem for conn in _item.connectors if conn._connected_at == QEngineeringAbstractItem.CONNECTED_AT_PT and \
454
                                                                                                            conn.connectedItem and conn.connectedItem not in matches[0].items]
455
                            if connectedItems:
456
                                connectedItems[0].sizeDepth = self.sizeDepth + 1
457
                                res  = connectedItems[0].EvaluatedSize
458
                                if res:
459
                                    self.sizeDepth = 0
460
                                    return res
461
                        if type(matches[0].items[-1]) is QEngineeringLineItem:
462
                            _item = matches[0].items[-1]
463
                            connectedItems = [conn.connectedItem for conn in _item.connectors if conn._connected_at == QEngineeringAbstractItem.CONNECTED_AT_PT and \
464
                                                                                                            conn.connectedItem and conn.connectedItem not in matches[0].items]
465
                            if connectedItems:
466
                                connectedItems[0].sizeDepth = self.sizeDepth + 1
467
                                res  = connectedItems[0].EvaluatedSize
468
                                if res:
469
                                    self.sizeDepth = 0
470
                                    return res
471
                        if issubclass(type(matches[0].items[0]), SymbolSvgItem):
472
                            _item = matches[0].items[0]
473
                            connectedItems = [_item.connectors[index].connectedItem for index in range(len(_item.conn_type)) if (_item.conn_type[index] == 'Secondary' or _item.conn_type[index] == 'Primary') and \
474
                                                                                                            _item.connectors[index].connectedItem and _item.connectors[index].connectedItem not in matches[0].items]
475
                            if connectedItems:
476
                                connectedItems[0].sizeDepth = self.sizeDepth + 1
477
                                res  = connectedItems[0].EvaluatedSize
478
                                if res:
479
                                    self.sizeDepth = 0
480
                                    return res
481
                        if issubclass(type(matches[0].items[-1]), SymbolSvgItem):
482
                            _item = matches[0].items[-1]
483
                            connectedItems = [_item.connectors[index].connectedItem for index in range(len(_item.conn_type)) if (_item.conn_type[index] == 'Secondary' or _item.conn_type[index] == 'Primary') and \
484
                                                                                                            _item.connectors[index].connectedItem and _item.connectors[index].connectedItem not in matches[0].items]
485
                            if connectedItems:
486
                                connectedItems[0].sizeDepth = self.sizeDepth + 1
487
                                res  = connectedItems[0].EvaluatedSize
488
                                if res:
489
                                    self.sizeDepth = 0
490
                                    return res
491
                        '''
492
                        if type(matches[0].items[0]) is QEngineeringLineItem and type(matches[0].items[-1]) is QEngineeringLineItem:
493
                            res1 = None
494
                            res2 = None
495

496
                            _item = matches[0].items[0]
497
                            connectedItems = [conn.connectedItem for conn in _item.connectors if conn.connectedItem and conn.connectedItem not in matches[0].items]
498
                            if connectedItems:
499
                                connectedItems[0].sizeDepth = self.sizeDepth + 1
500
                                res1  = connectedItems[0].EvaluatedSize
501
                                
502
                            _item = matches[0].items[-1]
503
                            connectedItems = [conn.connectedItem for conn in _item.connectors if conn.connectedItem and conn.connectedItem not in matches[0].items]
504
                            connectedItems.reverse()
505
                            if connectedItems:
506
                                connectedItems[0].sizeDepth = self.sizeDepth + 1
507
                                res2  = connectedItems[0].EvaluatedSize
508
                                if res1 and res2:
509
                                    self.sizeDepth = 0
510
                                    return res1 if self.inch_to_number(res1) <= self.inch_to_number(res2) else res2
511
                        '''
512
                        if type(matches[0].items[0]) is QEngineeringLineItem:
513
                            _item = matches[0].items[0]
514
                            connectedItems = [conn.connectedItem for conn in _item.connectors if conn.connectedItem and conn.connectedItem not in matches[0].items]
515
                            if connectedItems:
516
                                connectedItems[0].sizeDepth = self.sizeDepth + 1
517
                                res  = connectedItems[0].EvaluatedSize
518
                                if res:
519
                                    self.sizeDepth = 0
520
                                    return res
521
                        if type(matches[0].items[-1]) is QEngineeringLineItem:
522
                            _item = matches[0].items[-1]
523
                            connectedItems = [conn.connectedItem for conn in _item.connectors if conn.connectedItem and conn.connectedItem not in matches[0].items]
524
                            if connectedItems:
525
                                connectedItems[0].sizeDepth = self.sizeDepth + 1
526
                                res  = connectedItems[0].EvaluatedSize
527
                                if res:
528
                                    self.sizeDepth = 0
529
                                    return res
530

    
531
            self.sizeDepth = 0
532
            return ''
533
        except Exception as ex:
534
            from App import App
535
            from AppDocData import MessageType
536

    
537
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
538
                                                          sys.exc_info()[-1].tb_lineno)
539
            #App.mainWnd().addMessage.emit(MessageType.Error, str(self.uid) + self.name + message)
540
            App.mainWnd().addMessage.emit(MessageType.Error, message)
541

    
542
            return ''
543

    
544
    def EvaluatedTable(self, old_code, table_name):
545
        """ return new attribute code """
546
        from AppDocData import AppDocData
547
        from CodeTables import CodeTable
548

    
549
        try:
550
            found = CodeTable.instance(table_name).find_match_exactly(old_code)
551

    
552
            return found if found else ''
553
        except Exception as ex:
554
            from App import App
555
            from AppDocData import MessageType
556

    
557
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
558
                                                          sys.exc_info()[-1].tb_lineno)
559
            App.mainWnd().addMessage.emit(MessageType.Error, message)
560

    
561
    def EvaluatedLineNo(self, prop):
562
        """ return line no attr """
563
        from EngineeringLineNoTextItem import QEngineeringLineNoTextItem
564

    
565
        if self.owner and type(self.owner) is QEngineeringLineNoTextItem:
566
            attrs = self.owner.getAttributes()
567
            for attr, value in attrs.items():
568
                if prop == attr.Attribute:
569
                    return value
570

    
571
        return ''
572

    
573
    def EvaluatedDrawing(self, prop=None):
574
        """ return text item that is in prop"""
575
        from EngineeringTextItem import QEngineeringTextItem
576
        from AppDocData import AppDocData
577

    
578
        if prop is not None:
579
            scene = self.scene()
580
            if scene:
581
                items = [item for item in scene.items() if issubclass(type(item), QEngineeringTextItem) and item.area == prop]
582
                if items:
583
                    return items[0]
584
            return QEngineeringTextItem()
585
        else:
586
            app_doc_data = AppDocData.instance()
587
            drawing_name = app_doc_data.activeDrawing.name
588
            drawing_text_item = QEngineeringTextItem()
589
            drawing_text_item.setPlainText(drawing_name)
590
            return drawing_text_item
591

    
592
    def EvaluatedLabel(self, prop):
593
        """ return label symbol's attribute """
594
        from SymbolSvgItem import SymbolSvgItem
595

    
596
        scene = self.scene()
597
        if not scene:
598
            return ''
599
            
600
        labels = [item for item in scene.items() if issubclass(type(item), SymbolSvgItem) and (item.iType == 19 or item.iType == 29 or item.iType == 30)]
601
        if labels:
602
            labels = [label for label in labels if label.EvaluatedAttribute('OWNERSYMBOL') == self]
603
            if labels and len(labels) == 1:
604
                return labels[0].EvaluatedAttribute(prop)
605
            else:
606
                for label in labels:
607
                    value = label.EvaluatedAttribute(prop)
608
                    if value and value != 'None':
609
                        return value
610

    
611
        return ''
612

    
613
    def EvaluatedAttribute(self, prop, cache=False):
614
        """ return item's attribute """
615
        attrs = self.getAttributes(findOwner=cache)
616
        if attrs:
617
            for key, value in attrs.items():
618
                if key.Attribute == prop:
619
                    return value
620

    
621
        return ''
622

    
623
    @property
624
    def stream_no(self):
625
        matches = [attr for attr in self.attrs if attr.Attribute.upper() == 'STREAM NO']
626
        if matches:
627
            return self.attrs[matches[0]]
628

    
629
        return ''
630

    
631
    @property
632
    def case(self):
633
        matches = [attr for attr in self.attrs if attr.Attribute.upper() == 'CASE']
634
        if matches:
635
            return self.attrs[matches[0]]
636

    
637
        return ''
638

    
639
    '''
640
    @stream_no.setter
641
    def stream_no(self, value):
642
        from AppDocData import AppDocData
643

644
        matches = [attr for attr in self.attrs if attr.Attribute.upper() == 'STREAM NO']
645
        if matches:
646
            self.attrs[matches[0]] = value
647
            """reset attributes for hmb with given stream no"""
648

649
            app_doc_data = AppDocData.instance()
650
            stream_data = app_doc_data.hmbTable.dataOfStreamNo(value)
651
            for attr in self.attrs:
652
                if attr.AttributeType == 'HMB':
653
                    matches = [data for data in stream_data if data.name == attr.Attribute]
654
                    if matches:
655
                        self.attrs[attr] = matches[0].value
656
                    else:
657
                        self.attrs[attr] = ''
658
    '''
659

    
660
    def try_eval(self, item, expression):
661
        try:
662
            return eval(expression)
663
        except Exception as ex:
664
            from App import App
665
            from AppDocData import MessageType
666

    
667
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
668
                                                           sys.exc_info()[-1].tb_lineno) + ' Item UID : ' + str(self.uid)
669
            App.mainWnd().addMessage.emit(MessageType.Error, message)
670
        
671
        return ''
672

    
673
    def getTargetAttributes(self):
674
        """get target attributes"""
675
        from AppDocData import AppDocData
676
        from EngineeringLineItem import QEngineeringLineItem
677
        from EngineeringVendorItem import QEngineeringVendorItem
678
        from EngineeringLineNoTextItem import QEngineeringLineNoTextItem
679
        from EngineeringSpecBreakItem import QEngineeringSpecBreakItem
680
        from QEngineeringTagNoTextItem import QEngineeringTagNoTextItem
681

    
682
        """ get attributes of item from database """
683
        app_doc_data = AppDocData.instance()
684
        if type(self) is QEngineeringLineItem:
685
            symbolAttrs = app_doc_data.getSymbolAttribute('Line')
686
        elif type(self) is QEngineeringVendorItem:
687
            symbolAttrs = app_doc_data.getSymbolAttribute('Package')
688
        elif type(self) is QEngineeringLineNoTextItem:
689
            symbolAttrs = app_doc_data.getSymbolAttribute('Line No')
690
            self.getLineNoAttributes(_attrs)
691
        elif type(self) is QEngineeringTagNoTextItem:
692
            self.getTagNoAttributes(_attrs)
693
            self.attrs = _attrs
694
            return self.attrs
695
        else:
696
            symbolAttrs = app_doc_data.getSymbolAttribute(self.type)
697

    
698
        targetAttrs = []
699
        if not (type(self) is QEngineeringLineItem or type(self) is QEngineeringVendorItem or
700
                type(self) is QEngineeringLineNoTextItem or type(self) is QEngineeringTagNoTextItem):
701
            for attr in symbolAttrs:
702
                if not attr.Target and not type(self) is QEngineeringSpecBreakItem:
703
                    continue
704
                if attr.Target is None or attr.Target == 'ALL' or \
705
                        type(self) is QEngineeringSpecBreakItem or \
706
                            [target for target in attr.Target.split(',') if self.dbUid == int(target)]:
707
                    targetAttrs.append(attr)
708
        else:
709
            targetAttrs = symbolAttrs
710
        
711
        return targetAttrs
712

    
713
    def getAttributes(self, findOwner=False):
714
        """calculate all attributes of item"""
715
        import re
716

    
717
        if findOwner and not hasattr(self, '_skip'):
718
            self._skip = False
719
        elif findOwner and self._skip:
720
            return self.attrs
721
        elif findOwner:
722
            self._skip = True
723
        else:
724
            self._skip = False
725

    
726
        _attrs = {}
727
        try:
728
            from AppDocData import AppDocData
729
            from EngineeringLineItem import QEngineeringLineItem
730
            from EngineeringVendorItem import QEngineeringVendorItem
731
            from EngineeringLineNoTextItem import QEngineeringLineNoTextItem
732
            from EngineeringSpecBreakItem import QEngineeringSpecBreakItem
733
            from QEngineeringTagNoTextItem import QEngineeringTagNoTextItem
734
            from ItemDataExportDialog import QItemDataExportDialog
735

    
736
            """ get attributes of item from database """
737
            app_doc_data = AppDocData.instance()
738
            if type(self) is QEngineeringLineItem:
739
                symbolAttrs = app_doc_data.getSymbolAttribute('Line')
740
            elif type(self) is QEngineeringVendorItem:
741
                symbolAttrs = app_doc_data.getSymbolAttribute('Package')
742
            elif type(self) is QEngineeringLineNoTextItem:
743
                symbolAttrs = app_doc_data.getSymbolAttribute('Line No')
744
                self.getLineNoAttributes(_attrs)
745
            elif type(self) is QEngineeringTagNoTextItem:
746
                self.getTagNoAttributes(_attrs)
747
                self.attrs = _attrs
748
                return self.attrs
749
            else:
750
                symbolAttrs = app_doc_data.getSymbolAttribute(self.type)
751

    
752
            targetAttrs = []
753
            symbol_attr_number = 0
754
            if not (type(self) is QEngineeringLineItem or type(self) is QEngineeringVendorItem or
755
                    type(self) is QEngineeringLineNoTextItem or type(self) is QEngineeringTagNoTextItem):
756
                for attr in symbolAttrs:
757
                    if not attr.Target and not type(self) is QEngineeringSpecBreakItem:
758
                        continue
759
                    if attr.Target is None or attr.Target == 'ALL' or \
760
                            type(self) is QEngineeringSpecBreakItem or \
761
                                [target for target in attr.Target.split(',') if self.dbUid == int(target)]:
762
                        targetAttrs.append(attr)
763
                        if attr.AttributeType == 'Symbol Item' or attr.AttributeType == 'Line Item' or attr.AttributeType == 'EQ Item' or attr.AttributeType == 'Comp Item':
764
                            symbol_attr_number = max(symbol_attr_number, int(attr.AttrAt))
765
            else:
766
                targetAttrs = symbolAttrs
767

    
768
            _texts = self.texts()
769
            _symbols = self.symbols(symbol_attr_number + 1)
770

    
771
            # copy old values
772
            for attr in targetAttrs:
773
                #matches = [_attr for _attr, _ in self.attrs.items() if _attr.UID == attr.UID]
774
                matches = []
775
                for _attr, _ in self.attrs.items():
776
                    if _attr.UID == attr.UID:
777
                        matches = [_attr]
778
                        break
779
                if matches:
780
                    if matches[0].AttributeType == 'Spec' and not self.attrs[matches[0]]:
781
                        continue
782
                    attr.Freeze = matches[0].Freeze  # update freeze value
783
                    attr.AssocItem = matches[0].AssocItem
784
                    _attrs[attr] = self.attrs[matches[0]]  # copy attribute value
785
                else:
786
                    if attr.AttributeType != 'Spec':
787
                        _attrs[attr] = ''
788
            self.attrs = _attrs
789

    
790
            for attr in [_attr for _attr in sorted(self.attrs.keys(), key=lambda param:int(param.Index)) \
791
                            if _attr.AttributeType != 'Combined' and _attr.AttributeType != 'Reference' and _attr.AttributeType != 'HMB']:
792
                # if attr.Freeze: continue    # do not evaluate value if attribute is frozen
793
                if attr.AttributeType == 'Text Item' or attr.AttributeType == 'Valve Oper Code':
794
                    at = int(attr.AttrAt)
795

    
796
                    # Text Item can contain Valve Oper Code
797
                    if attr.AttributeType == 'Text Item':
798
                        items = _texts
799
                    else:
800
                        items = [text for text in _texts if
801
                                 QEngineeringAbstractItem.assoc_type(text) == attr.AttributeType]
802

    
803
                    if not attr.AssocItem and len(items) > at and not attr.Codes.values:
804
                        attr.AssocItem = items[at]
805
                        item = attr.AssocItem
806
                        _attrs[attr] = self.try_eval(item, attr.Expression) if attr.Expression else ''
807
                    elif attr.AssocItem:
808
                        item = attr.AssocItem = self.get_assoc_item(attr.AssocItem)
809
                        _attrs[attr] = self.try_eval(item, attr.Expression) if attr.Expression else ''
810
                    else:
811
                        _attrs[attr] = ''
812
                elif attr.AttributeType == 'Size Text Item' or attr.AttributeType == 'Tag No':
813
                    at = int(attr.AttrAt)
814
                    items = [text for text in _texts if QEngineeringAbstractItem.assoc_type(text) == attr.AttributeType]
815
                    if not attr.AssocItem and len(items) > at:
816
                        attr.AssocItem = items[at]
817
                        item = attr.AssocItem
818
                        _attrs[attr] = self.try_eval(item, attr.Expression) if attr.Expression else ''
819
                    else:
820
                        item = attr.AssocItem = self.get_assoc_item(attr.AssocItem)
821
                        _attrs[attr] = self.try_eval(item, attr.Expression) if attr.Expression and (
822
                                (item and 'item' in attr.Expression) or 'self' in attr.Expression) else ''
823
                elif attr.AttributeType == 'Symbol Item' or attr.AttributeType == 'Line Item' or \
824
                        attr.AttributeType == 'Comp Item' or attr.AttributeType == 'EQ Item':
825
                    at = int(attr.AttrAt)
826
                    if not attr.AssocItem and len(_symbols) > at:
827
                        attr.AssocItem = _symbols[at]
828
                        item = attr.AssocItem
829
                        _attrs[attr] = self.try_eval(item, attr.Expression) if attr.Expression else ''
830
                    elif attr.AssocItem:
831
                        item = attr.AssocItem = self.get_assoc_item(attr.AssocItem)
832
                        _attrs[attr] = self.try_eval(item, attr.Expression) if attr.Expression else ''
833
                    else:
834
                        _attrs[attr] = ''
835
                elif attr.AttributeType == 'String':
836
                    #_attrs[attr] = attr.Expression if attr.Expression and not _attrs[attr] else _attrs[attr]
837
                    _attrs[attr] = self.try_eval(None, attr.Expression) if attr.Expression else _attrs[attr]
838

    
839
            """calculate attribute value for HMB type"""
840
            configs = app_doc_data.getConfigs('Line List', 'Use Stream No')
841
            if configs and int(configs[0].value) == 1:
842
                matches = [_attr for _attr in _attrs if _attr.Attribute.upper() == 'STREAM NO']
843
                matches_case = [_attr for _attr in _attrs if _attr.Attribute.upper() == 'CASE']
844
                hmb_attrs = [_attr for _attr in targetAttrs if _attr.AttributeType == 'HMB']
845
                hmb_datas = app_doc_data.get_hmb_data(None) if hmb_attrs else None
846
                if hmb_datas and hmb_attrs and matches and _attrs[matches[0]] and _attrs[matches[0]] != 'None':
847
                    stream_no = _attrs[matches[0]]
848
                    names = []
849
                    for data in hmb_datas[0].datas[0]:
850
                        if data.name not in names:
851
                            names.append(data.name)
852

    
853
                    matches = [hmb_data for hmb_data in hmb_datas if hmb_data.stream_no == stream_no]
854
                    if matches:
855
                        data = {}
856
                        if matches_case:
857
                            data['Case'] = _attrs[matches_case[0]]
858
                        hmb_data = matches[0]
859
                        data = QItemDataExportDialog.make_hmb_data(data, hmb_data, names)
860
                        for _attr in hmb_attrs:
861
                            if _attr.Attribute in data:
862
                                _attrs[_attr] = data[_attr.Attribute]
863
                            else:
864
                                _attrs[_attr] = ''
865
            """up to here"""
866

    
867
            """calculate attribute value for combined type"""
868
            p = re.compile('{[A-Za-z0-9_ ]+}')
869
            for attr in [_attr for _attr in targetAttrs if _attr.AttributeType == 'Combined']:
870
                value, pos = '', 0
871

    
872
                matches = p.finditer(attr.Expression)
873
                for match in matches:
874
                    attr_name = attr.Expression[(match.start() + 1):(match.end() - 1)]
875
                    values = [value for key, value in _attrs.items() if key.Attribute == attr_name]
876
                    if not values:
877
                        values = [""]
878
                    value += attr.Expression[pos:match.start()] + values[0]
879
                    pos = match.end()
880

    
881
                value += attr.Expression[pos:len(attr.Expression)]
882
                _attrs[attr] = value
883
            """up to here"""
884

    
885
            """calculate attribute value for Reference type"""
886
            for attr in [_attr for _attr in targetAttrs if _attr.AttributeType == 'Reference']:
887
                value, pos = '', 0
888

    
889
                matches = p.finditer(attr.Expression)
890
                for match in matches:
891
                    attr_name = attr.Expression[(match.start() + 1):(match.end() - 1)]
892
                    values = [value for key, value in _attrs.items() if key.Attribute == attr_name]
893
                    if not values:
894
                        values = []
895
                    value += attr.Expression[pos:match.start()] + '\'' + values[0] + '\''
896
                    pos = match.end()
897

    
898
                value += attr.Expression[pos:len(attr.Expression)]
899
                _attrs[attr] = self.try_eval(None, value) if attr.Expression else ''
900
            """up to here"""
901

    
902
            for _attr, _value in _attrs.items():
903
                if _value is None or _value == '':
904
                    _attr.AssocItem = None
905
        except Exception as ex:
906
            from App import App
907
            from AppDocData import MessageType
908

    
909
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
910
                                                           sys.exc_info()[-1].tb_lineno) + ' Item UID : ' + str(self.uid)
911
            App.mainWnd().addMessage.emit(MessageType.Error, message)
912

    
913
        return self.attrs
914

    
915
    def attrib(self, name):
916
        """ return the value of given attribute with name """
917
        matches = [(attr, value) for attr, value in self.getAttributes().items() if attr.Attribute == name]
918
        if matches: return matches[0][1]
919

    
920
        return None
921

    
922
    def set_attrib(self, attrib, value):
923
        """ set attribute with given value """
924
        matches = [attr for attr, _ in self.attrs.items() if attr.UID == attrib.UID]
925
        if len(matches) == 1: self.attrs[matches[0]] = value
926

    
927
    @staticmethod
928
    def assoc_type(item):
929
        """ return association type of given item """
930
        from EngineeringTextItem import QEngineeringTextItem
931
        from SymbolSvgItem import SymbolSvgItem
932
        from EngineeringValveOperCodeTextItem import QEngineeringValveOperCodeTextItem
933
        from QEngineeringSizeTextItem import QEngineeringSizeTextItem
934
        from QEngineeringTagNoTextItem import QEngineeringTagNoTextItem
935
        from EngineeringLineItem import QEngineeringLineItem
936
        from EngineeringEquipmentItem import QEngineeringEquipmentItem
937
        from EngineeringVendorItem import QEngineeringVendorItem
938

    
939
        _type = None
940

    
941
        if type(item) is QEngineeringSizeTextItem:
942
            _type = 'Size Text Item'
943
        elif type(item) is QEngineeringValveOperCodeTextItem:
944
            _type = 'Valve Oper Code'
945
        elif type(item) is QEngineeringTagNoTextItem:
946
            _type = 'Tag No'
947
        elif type(item) is QEngineeringTextItem or issubclass(type(item), QEngineeringTextItem):
948
            _type = 'Text Item'
949
        elif type(item) is QEngineeringEquipmentItem or type(item) is QEngineeringVendorItem:
950
            _type = 'EQ Item'
951
        elif type(item) is SymbolSvgItem or issubclass(type(item), SymbolSvgItem):
952
            _type = 'Symbol Item'
953
        elif type(item) is QEngineeringLineItem:
954
            _type = 'Line Item'
955
        elif issubclass(type(item), SymbolSvgItem) or type(item) is QEngineeringLineItem:
956
            _type = 'Comp Item'
957

    
958
        return _type
959

    
960
    def clear_attr_and_assoc_item(self, force=False):
961
        """ clear attrs, return true if clear attrs """
962
        if force:
963
            self.attrs.clear()
964
            self._associations.clear()
965
            return True
966
        else:
967
            freeze = False
968
            for key in self.attrs.keys():
969
                if key.Freeze:
970
                    freeze = True
971
                    break
972
            if freeze:
973
                return False
974
            else:
975
                self.attrs.clear()
976
                self._associations.clear()
977
                return True
978

    
979
    def add_assoc_item(self, item, at=None, force=False):
980
        """ add given item to association """
981

    
982
        from EngineeringTextItem import QEngineeringTextItem
983
        from SymbolSvgItem import SymbolSvgItem
984
        from EngineeringValveOperCodeTextItem import QEngineeringValveOperCodeTextItem
985
        from QEngineeringSizeTextItem import QEngineeringSizeTextItem
986

    
987
        if not force:
988
            for key in self.attrs.keys():
989
                if key.Freeze:
990
                    return False
991

    
992
        _type = QEngineeringAbstractItem.assoc_type(item)
993
        if _type is not None:
994
            if not _type in self._associations:
995
                self._associations[_type] = []
996

    
997
            if item in self._associations[_type]: return True
998

    
999
            if at is None:
1000
                self._associations[_type].append(item)
1001
            else:
1002
                while len(self._associations[_type]) <= at: self._associations[_type].append(None)
1003
                # if len(self._associations[_type]) > at and self._associations[_type][at] is not None:
1004
                #    self._associations[_type][at].owner = None
1005
                self._associations[_type][at] = item
1006

    
1007
            return True
1008

    
1009
        return False
1010

    
1011
    def remove_assoc_item(self, item):
1012
        """ remove given item from association """
1013
        _type = QEngineeringAbstractItem.assoc_type(item)
1014
        if _type is not None:
1015
            if _type in self._associations and item in self._associations[_type]:
1016
                index = self._associations[_type].index(item)
1017
                self._associations[_type].pop(index)
1018

    
1019
    @property
1020
    def properties(self):
1021
        """ getter of properties """
1022
        import uuid
1023
        from SymbolSvgItem import SymbolSvgItem
1024
        from EngineeringLineItem import QEngineeringLineItem
1025
        from EngineeringLineNoTextItem import QEngineeringLineNoTextItem
1026
        from EngineeringVendorItem import QEngineeringVendorItem
1027

    
1028
        if type(self) is QEngineeringLineNoTextItem:
1029
            for prop, value in self._properties.items():
1030
                if prop.is_selectable and type(value) is uuid.UUID and self.scene():
1031
                    #matches = [x for x in self.scene().items() if hasattr(x, 'uid') and str(x.uid) == str(value)]
1032
                    matches = []
1033
                    for item in self.scene().items():
1034
                        if hasattr(item, 'uid') and str(item.uid) == str(value):
1035
                            matches = [item]
1036
                            break
1037
                    if matches:
1038
                        self._properties[prop] = matches[0]
1039

    
1040
        elif type(self) is QEngineeringLineItem:
1041
            for prop, value in self._properties.items():
1042
                if prop.is_selectable and type(value) is uuid.UUID and self.scene():
1043
                    #matches = [x for x in self.scene().items() if hasattr(x, 'uid') and str(x.uid) == str(value)]
1044
                    matches = []
1045
                    for item in self.scene().items():
1046
                        if hasattr(item, 'uid') and str(item.uid) == str(value):
1047
                            matches = [item]
1048
                            break
1049
                    if matches:
1050
                        self._properties[prop] = matches[0]
1051

    
1052
                if prop.Expression: self._properties[prop] = eval(prop.Expression)
1053

    
1054
        elif issubclass(type(self), SymbolSvgItem):
1055
            for prop, value in self._properties.items():
1056
                try:
1057
                    if prop.is_selectable and type(value) is uuid.UUID and self.scene():
1058
                        #matches = [x for x in self.scene().items() if hasattr(x, 'uid') and str(x.uid) == str(value)]
1059
                        matches = []
1060
                        for item in self.scene().items():
1061
                            if hasattr(item, 'uid') and str(item.uid) == str(value):
1062
                                matches = [item]
1063
                                break
1064
                        if matches:
1065
                            self._properties[prop] = matches[0]
1066

    
1067
                    if prop.Expression:
1068
                        item = self._properties[prop]  # assign item
1069
                        self._properties[prop] = eval(prop.Expression)
1070
                except Exception as ex:
1071
                    from App import App
1072
                    from AppDocData import MessageType
1073
                    message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1074
                                                                   sys.exc_info()[-1].tb_lineno)
1075
                    App.mainWnd().addMessage.emit(MessageType.Error, message)
1076

    
1077
        elif type(self) is QEngineeringVendorItem:
1078
            for prop, value in self._properties.items():
1079
                try:
1080
                    if prop.is_selectable and type(value) is uuid.UUID and self.scene():
1081
                        #matches = [x for x in self.scene().items() if hasattr(x, 'uid') and str(x.uid) == str(value)]
1082
                        matches = []
1083
                        for item in self.scene().items():
1084
                            if hasattr(item, 'uid') and str(item.uid) == str(value):
1085
                                matches = [item]
1086
                                break
1087
                        if matches:
1088
                            self._properties[prop] = matches[0]
1089

    
1090
                    if prop.Expression:
1091
                        item = self._properties[prop]  # assign item
1092
                        self._properties[prop] = eval(prop.Expression)
1093
                except Exception as ex:
1094
                    from App import App
1095
                    from AppDocData import MessageType
1096
                    message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1097
                                                                   sys.exc_info()[-1].tb_lineno)
1098
                    App.mainWnd().addMessage.emit(MessageType.Error, message)
1099

    
1100
        return self._properties
1101

    
1102
    @properties.setter
1103
    def properties(self, value):
1104
        """ setter of properties """
1105
        self._properties = value
1106

    
1107
    def prop(self, name):
1108
        """ return property with given value """
1109
        from SymbolSvgItem import SymbolSvgItem
1110
        from EngineeringLineItem import QEngineeringLineItem
1111
        from EngineeringLineNoTextItem import QEngineeringLineNoTextItem
1112
        from EngineeringVendorItem import QEngineeringVendorItem
1113

    
1114
        if type(self) is QEngineeringLineNoTextItem:
1115
            #matches = [prop for prop, _ in self.properties.items() if prop.Attribute == name]
1116
            matches = []
1117
            for prop, _ in self.properties.items():
1118
                if prop.Attribute == name:
1119
                    matches = [prop]
1120
                    break
1121
            return self.properties[matches[0]] if matches else None
1122

    
1123
        elif type(self) is QEngineeringLineItem:
1124
            #matches = [(prop, value) for prop, value in self.properties.items() if prop.Attribute == name]
1125
            #if matches: return matches[0][1]
1126
            #return None
1127
            matches = []
1128
            for prop, value in self.properties.items():
1129
                if prop.Attribute == name:
1130
                    matches = [value]
1131
                    break
1132
            
1133
            return matches[0] if matches else None
1134

    
1135
        elif issubclass(type(self), SymbolSvgItem):
1136
            #matches = [(prop, value) for prop, value in self.properties.items() if prop.Attribute == name]
1137
            #if matches: return matches[0][1]
1138
            #return None
1139
            matches = []
1140
            for prop, value in self.properties.items():
1141
                if prop.Attribute == name:
1142
                    matches = [value]
1143
                    break
1144
            
1145
            return matches[0] if matches else None
1146

    
1147
        elif type(self) is QEngineeringVendorItem:
1148
            #matches = [(prop, value) for prop, value in self.properties.items() if prop.Attribute == name]
1149
            #if matches: return matches[0][1]
1150
            matches = []
1151
            for prop, value in self.properties.items():
1152
                if prop.Attribute == name:
1153
                    matches = [value]
1154
                    break
1155
            
1156
            return matches[0] if matches else None
1157

    
1158
    def set_property(self, property, value):
1159
        """ set property with given value """
1160
        from SymbolSvgItem import SymbolSvgItem
1161
        from EngineeringLineItem import QEngineeringLineItem
1162
        from EngineeringLineNoTextItem import QEngineeringLineNoTextItem
1163
        from EngineeringVendorItem import QEngineeringVendorItem
1164

    
1165
        if type(self) is QEngineeringLineNoTextItem:
1166
            matches = [prop for prop, _ in self._properties.items() if prop.Attribute == property]
1167
            if matches: self._properties[matches[0]] = value
1168

    
1169
        elif type(self) is QEngineeringLineItem:
1170
            if issubclass(type(value), QEngineeringAbstractItem): self.add_assoc_item(value, 0)
1171
            matches = [prop for prop, _ in self._properties.items() if prop.Attribute == property]
1172
            if matches: self._properties[matches[0]] = value
1173

    
1174
        elif issubclass(type(self), SymbolSvgItem):
1175
            if issubclass(type(value), QEngineeringAbstractItem): self.add_assoc_item(value, 0)
1176
            matches = [prop for prop, _ in self._properties.items() if prop.Attribute == property]
1177
            if matches: self._properties[matches[0]] = value
1178

    
1179
        elif type(self) is QEngineeringVendorItem:
1180
            if issubclass(type(value), QEngineeringAbstractItem):
1181
                self.add_assoc_item(value, 0)
1182
            matches = [prop for prop, _ in self._properties.items() if prop.Attribute == property]
1183
            if matches: self._properties[matches[0]] = value
1184

    
1185
    def center(self):
1186
        return self.sceneBoundingRect().center()
1187
    
1188
    def inch_to_number(self, inch_str):
1189
        from AppDocData import AppDocData
1190
        
1191
        app_doc_data = AppDocData.instance()
1192
        configs = app_doc_data.getConfigs('Size', 'Symbol')
1193
        size_symbols = configs[0].value.replace(' ', '').split(',') if 1 == len(configs) else ['"']
1194

    
1195
        inch_str = str(inch_str)
1196
        for symbol in size_symbols:
1197
            inchs = inch_str.replace(symbol, '')
1198
        inchs = inchs.replace('"', '').split('-')
1199

    
1200
        number = 0
1201
        for inch in inchs:
1202
            if '/' not in inch:
1203
                number += float(inch)
1204
            else:
1205
                fraction = inch.split('/')
1206
                number += float(fraction[0]) / float(fraction[1])
1207

    
1208
        return number
1209

    
1210

    
1211
if __name__ == '__main__':
1212
    import re
1213

    
1214
    p = re.compile('{[A-Za-z0-9]+}')
1215
    value, pos = '', 0
1216

    
1217
    _attrs = {'a': '~', 'b': '!', 'C': '+'}
1218
    expression = 'XXXXXXX{a}-{b}-{C}----'
1219
    matches = p.finditer(expression)
1220
    for match in matches:
1221
        attr_name = expression[(match.start() + 1):(match.end() - 1)]
1222
        value += expression[pos:match.start()] + _attrs[attr_name]
1223
        pos = match.end()
1224

    
1225
    value += expression[pos:len(expression)]
1226
    print(value)
클립보드 이미지 추가 (최대 크기: 500 MB)