프로젝트

일반

사용자정보

통계
| 개정판:

hytos / DTI_PID / DTI_PID / ItemTreeWidget.py @ 3ba088c3

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

1
# coding: utf-8
2
""" This is item tree widget module """
3

    
4
import os
5
import re
6
import sys
7

    
8
try:
9
    from PyQt5.QtCore import *
10
    from PyQt5.QtGui import *
11
    from PyQt5.QtWidgets import *
12
except ImportError:
13
    try:
14
        from PyQt4.QtCore import *
15
        from PyQt4.QtGui import *
16
    except ImportError:
17
        raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.")
18

    
19
from EngineeringAbstractItem import QEngineeringAbstractItem
20
from SymbolSvgItem import SymbolSvgItem
21
from EngineeringTextItem import QEngineeringTextItem
22
from EngineeringNoteItem import QEngineeringNoteItem
23
from EngineeringLineNoTextItem import QEngineeringLineNoTextItem
24
from EngineeringEquipmentItem import QEngineeringEquipmentItem
25
from EngineeringInstrumentItem import QEngineeringInstrumentItem
26
from QEngineeringTrimLineNoTextItem import QEngineeringTrimLineNoTextItem
27
from EngineeringUnknownItem import QEngineeringUnknownItem
28
from EngineeringErrorItem import QEngineeringErrorItem
29
from EngineeringEndBreakItem import QEngineeringEndBreakItem
30
from EngineeringFlowMarkItem import QEngineeringFlowMarkItem
31
from AppDocData import AppDocData
32
from Drawing import Drawing
33

    
34

    
35
class CustomTreeWidgetItem(QTreeWidgetItem):
36
    def __init__(self, *args, **kwargs):
37
        super(CustomTreeWidgetItem, self).__init__(*args, **kwargs)
38

    
39
    def setData(self, column, role, value):
40
        if role == Qt.EditRole:
41
            pass
42
        elif role == Qt.CheckStateRole:
43
            if self.treeWidget() is not None:
44
                state = Qt.CheckState.Unchecked if value is 0 else Qt.CheckState.Checked
45
                self.treeWidget().checkBoxToggled.emit(self, state)
46

    
47
        super(CustomTreeWidgetItem, self).setData(column, role, value)
48

    
49

    
50
class QItemTreeWidget(QTreeWidget):
51
    """ This is item tree widget """
52
    TREE_DATA_ROLE = Qt.UserRole
53

    
54
    # Add Signal
55
    singleClicked = pyqtSignal(QEngineeringAbstractItem)
56
    noteNoSingleClicked = pyqtSignal(str, dict)
57
    #lineNoSingleClicked = pyqtSignal(QEngineeringAbstractItem)
58
    drawingClicked = pyqtSignal(Drawing)
59
    checkBoxToggled = pyqtSignal(QTreeWidgetItem, Qt.CheckState)
60

    
61
    '''
62
        @history    2018.05.11  Jeongwoo    Add Context Menu settings
63
    '''
64

    
65
    def __init__(self, imageViewer):
66
        QTreeWidget.__init__(self)
67

    
68
        self.checkBoxToggled.connect(self.itemCheckBoxToggled)
69

    
70
        self.itemClicked.connect(self.itemClickEvent)
71
        self.imageViewer = imageViewer
72
        self.scene = imageViewer.scene
73
        self.root = None
74
        self.setContextMenuPolicy(Qt.CustomContextMenu)
75
        self.customContextMenuRequested.connect(self.openContextMenu)
76

    
77
    '''
78
        @brief      delete selected symbol
79
        @author     humkyung
80
        @date       2018.07.20
81
    '''
82

    
83
    def keyPressEvent(self, event):
84
        try:
85
            if event.key() == Qt.Key_Delete:
86
                if self.selectedItems():
87
                    for item in self.selectedItems():
88
                        data = item.data(0, self.TREE_DATA_ROLE)
89
                        if data is not None:
90
                            data.transfer.onRemoved.emit(data)
91
                            # self.imageViewer.scene.removeItem(data)
92

    
93
                            # if type(data) is QEngineeringLineNoTextItem:
94
                            #    self.imageViewer.mainWindow.removedItems['LINE'].append(str(data.uid))
95
                            # elif type(data) is QEngineeringInstrumentItem:
96
                            #    self.imageViewer.mainWindow.removedItems['INST'].append(str(data.uid))
97
                            # elif type(data) is QEngineeringEquipmentItem:
98
                            #    self.imageViewer.mainWindow.removedItems['EQUIP'].append(str(data.uid))
99
                            # elif type(data) is QEngineeringNoteItem:
100
                            #    self.imageViewer.mainWindow.removedItems['NOTE'].append(str(data.uid))
101

    
102
                            # item.parent().removeChild(item)
103
                event.accept()
104
            elif event.key() == Qt.Key_Up:
105
                if self.selectedItems():
106
                    item = self.selectedItems()[0]
107
                    aboveItem = self.itemAbove(item)
108
                    if aboveItem is not None:
109
                        self.setCurrentItem(aboveItem)
110
                        self.scrollToItem(aboveItem, QAbstractItemView.EnsureVisible)
111
                        self.itemClickEvent(aboveItem, 0)
112
                event.accept()
113
            elif event.key() == Qt.Key_Down:
114
                if self.selectedItems():
115
                    item = self.selectedItems()[0]
116
                    belowItem = self.itemBelow(item)
117
                    if belowItem is not None:
118
                        self.setCurrentItem(belowItem)
119
                        self.scrollToItem(belowItem, QAbstractItemView.EnsureVisible)
120
                        self.itemClickEvent(belowItem, 0)
121
                event.accept()
122
            else:
123
                event.ignore()
124
        except Exception as ex:
125
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
126
                                                       sys.exc_info()[-1].tb_lineno))
127

    
128
    '''
129
        @brief      Show Context Menu
130
        @author     Jeongwoo
131
        @date       18.05.11
132
        @history    18.06.14    Jeongwoo    Add item None check
133
                    humkyung 2018.06.27 add menu of run item for selecting line type
134
    '''
135

    
136
    def openContextMenu(self, position):
137
        from EngineeringRunItem import QEngineeringRunItem
138

    
139
        indexes = self.selectedIndexes()
140
        itemPosition = self.mapTo(self, position)
141
        item = self.itemAt(itemPosition)
142
        if item is not None:
143
            if item is self.LineNoTreeItem:
144
                menu = QMenu()
145
                explode_action = QAction(self.tr("Explode"))
146
                explode_action.triggered.connect(lambda: self.explode_all_line_nos(item))
147
                menu.addAction(explode_action)
148
                explodeKeepFromTo_action = QAction(self.tr("Explode(keep from, to)"))
149
                explodeKeepFromTo_action.triggered.connect(lambda: self.explode_all_line_nos(item, True))
150
                menu.addAction(explodeKeepFromTo_action)
151
                menu.exec_(self.viewport().mapToGlobal(position))
152
            else:
153
                data = item.data(0, self.TREE_DATA_ROLE)
154
                if len(indexes) > 0 and data is not None and issubclass(type(data), QEngineeringLineNoTextItem):
155
                    menu = QMenu()
156
                    pickColorAction = QAction(self.tr("Select Line Color"))
157
                    pickColorAction.triggered.connect(lambda: self.pickColorClickEvent(item))
158
                    menu.addAction(pickColorAction)
159
                    explode_action = QAction(self.tr("Explode"))
160
                    freeze = data.prop('Freeze')
161
                    explode_action.setEnabled(not freeze)
162
                    explode_action.triggered.connect(lambda: self.explode_line_no(item))
163
                    menu.addAction(explode_action)
164
                    if type(data) is QEngineeringLineNoTextItem:
165
                        explodeKeepFromTo_action = QAction(self.tr("Explode(keep from, to)"))
166
                        explodeKeepFromTo_action.setEnabled(not freeze)
167
                        explodeKeepFromTo_action.triggered.connect(lambda: self.explode_line_no(item, True))
168
                        menu.addAction(explodeKeepFromTo_action)
169
                    reverse_flow_action = QAction(self.tr("Reverse Flow"))
170
                    reverse_flow_action.triggered.connect(lambda: self.reverse_line_flow(item))
171
                    menu.addAction(reverse_flow_action)
172
                    menu.exec_(self.viewport().mapToGlobal(position))
173
                elif len(indexes) > 0 and data is not None and issubclass(type(data), QEngineeringRunItem):
174
                    menu = QMenu()
175
                    lineTypeAction = QAction(self.tr("Select Line Type"))
176
                    lineTypeAction.triggered.connect(lambda: self.lineTypeClickEvent(item))
177
                    menu.addAction(lineTypeAction)
178
                    line_no = item.parent().data(0, self.TREE_DATA_ROLE)
179
                    freeze = line_no.prop('Freeze')
180
                    explode_action = QAction(self.tr("Explode"))
181
                    explode_action.setEnabled(not freeze)
182
                    explode_action.triggered.connect(lambda: self.explode_line_run(item))
183
                    menu.addAction(explode_action)
184
                    reverse_flow_action = QAction(self.tr("Reverse Flow"))
185
                    reverse_flow_action.triggered.connect(lambda: self.reverse_line_flow(item))
186
                    menu.addAction(reverse_flow_action)
187
                    menu.exec_(self.viewport().mapToGlobal(position))
188

    
189
            self.SymbolsTreeItem.sortChildren(0, Qt.AscendingOrder)
190
            self.EqpTreeItem.sortChildren(0, Qt.AscendingOrder)
191

    
192
    '''
193
        @brief      Pick Color for Line No
194
        @author     Jeongwoo
195
        @date       18.05.11
196
        @history    18.05.14    Jeongwoo    Change method to change color by changeTreeWidgetItemColorRecursively()
197
    '''
198

    
199
    def pickColorClickEvent(self, lineNoTreeWidgetItem):
200
        color = QColorDialog.getColor()  # Dialog returns QColor
201

    
202
        if color is not None:
203
            lineNoTreeWidgetItem.setForeground(0, QBrush(color))
204
            lineNoTreeWidgetItem.setFont(0, lineNoTreeWidgetItem.font(0))
205
            lineNoItem = lineNoTreeWidgetItem.data(0, self.TREE_DATA_ROLE)
206
            if lineNoItem:
207
                lineNoItem.change_color(color.name())
208
                lineNoItem.setColor(color.name())
209
                connectedItems = lineNoItem.getConnectedItems()
210
                if connectedItems is not None:
211
                    for connectedItem in connectedItems:
212
                        connectedItem.setColor(color.name())
213
                        connectedItem.update()
214
                    self.changeTreeWidgetItemColorRecursively(lineNoTreeWidgetItem, color)
215

    
216
    def explode_line_run(self, tree_widget_item):
217
        """ explode line run """
218

    
219
        try:
220
            line_run = tree_widget_item.data(0, self.TREE_DATA_ROLE)
221
            if line_run:
222
                for item in line_run.items:
223
                    if issubclass(type(item), SymbolSvgItem): self.addTreeItem(self.SymbolsTreeItem, item)
224

    
225
                for i in reversed(range(tree_widget_item.childCount())):
226
                    tree_widget_item.takeChild(i)
227

    
228
                line_run.explode()
229
                tree_widget_item.parent().takeChild(tree_widget_item.parent().indexOfChild(tree_widget_item))
230
        finally:
231
            pass
232

    
233
    def explode_all_line_nos(self, tree_widget_item, remainFromTo=False):
234
        """ explode all line nos """
235
        from EngineeringLineNoTextItem import QEngineeringLineNoTextItem
236

    
237
        for i in reversed(range(self.LineNoTreeItem.childCount())):
238
            if not self.LineNoTreeItem.child(i).data(0, self.TREE_DATA_ROLE).prop('Freeze'):
239
                self.explode_line_no(self.LineNoTreeItem.child(i), remainFromTo)
240

    
241
        # for item in [item for item in self.scene.items() if hasattr(item, 'owner')
242

    
243
    def reverse_line_flow(self, lineTreeWidgetItem):
244
        """ reverse line flow """
245

    
246
        try:
247
            line_item = lineTreeWidgetItem.data(0, self.TREE_DATA_ROLE)
248
            if line_item:
249
                line_item.reverse()
250
        finally:
251
            pass
252

    
253
    def explode_line_no(self, lineNoTreeWidgetItem, remainFromTo=False):
254
        """ explode line no """
255

    
256
        try:
257
            line_no_item = lineNoTreeWidgetItem.data(0, self.TREE_DATA_ROLE)
258
            if line_no_item:
259
                connected_items = line_no_item.getConnectedItems()
260
                for item in connected_items:
261
                    self.addTreeItem(self.SymbolsTreeItem, item)
262

    
263
                for i in reversed(range(lineNoTreeWidgetItem.childCount())):
264
                    lineNoTreeWidgetItem.takeChild(i)
265

    
266
                line_no_item.explode(remainFromTo)
267
        finally:
268
            pass
269

    
270
    '''
271
        @brief      pick line type
272
        @author     humkyung 
273
        @date       2018.06.27
274
    '''
275

    
276
    def lineTypeClickEvent(self, item):
277
        pass
278

    
279
    '''
280
        @brief      Change Color recursively
281
        @author     Jeongwoo
282
        @date       18.05.14
283
    '''
284

    
285
    def changeTreeWidgetItemColorRecursively(self, item, color):
286
        for index in range(item.childCount()):
287
            child = item.child(index)
288
            child.setForeground(0, QBrush(color))
289
            child.setFont(0, child.font(0))
290
            self.changeTreeWidgetItemColorRecursively(child, color)
291

    
292
    '''
293
        @brief      Clear TreeWidget and Set Current PID
294
        @author     Jeongwoo
295
        @date       18.04.11
296
        @history    2018.04.26  Jeongwoo    Add Child [SYMBOLS, NOTES] into root item
297
                    2018.05.09  Jeongwoo    Change method to add default tree items
298
                    humkyung 2018.06.10 add tree item for Line No and Unknown Item
299
    '''
300

    
301
    def setCurrentPID(self, drawingName):
302
        appDocData = AppDocData.instance()
303

    
304
        self.clear()
305
        self.root = QTreeWidgetItem(self, [drawingName])
306
        self.root.setIcon(0, QIcon(':newPrefix/objects.png'))
307
        self.root.setData(0, self.TREE_DATA_ROLE, appDocData.activeDrawing)
308
        child = self.root.addChild(QTreeWidgetItem(['LINE NO']))
309
        self.LineNoTreeItem = self.root.child(self.root.childCount() - 1)
310
        self.LineNoTreeItem.setFlags(self.root.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
311
        self.LineNoTreeItem.setCheckState(0, Qt.Checked)
312
        self.root.addChild(QTreeWidgetItem(['EQUIPMENTS']))
313
        self.EqpTreeItem = self.root.child(self.root.childCount() - 1)
314
        self.root.addChild(QTreeWidgetItem(['SYMBOLS']))
315
        self.SymbolsTreeItem = self.root.child(self.root.childCount() - 1)
316
        self.root.addChild(QTreeWidgetItem(['NOTES']))
317
        self.NotesTreeItem = self.root.child(self.root.childCount() - 1)
318
        self.root.addChild(QTreeWidgetItem(['UNKNOWN']))
319
        self.UnknownTreeItem = self.root.child(self.root.childCount() - 1)
320

    
321
        for idx in range(self.root.childCount()):
322
            child = self.root.child(idx)
323
            child.setIcon(0, QIcon(':newPrefix/folder-black.png'))
324

    
325
    '''
326
        @brief  create tree item for pipe run if need
327
        @author humkyung
328
        @date   2018.05.15
329
        @history    2018.05.17  Jeongwoo    Change run item color with parent(LineNo Item) color
330
    '''
331

    
332
    def addPipeRunTreeItemIfNeed(self, lineNoTreeItem, pipeRun):
333
        for index in range(lineNoTreeItem.childCount()):
334
            treeItem = lineNoTreeItem.child(index)
335
            itemData = treeItem.data(0, self.TREE_DATA_ROLE)
336
            if itemData is not None and itemData == pipeRun:
337
                return treeItem
338

    
339
        runItem = QTreeWidgetItem(['RUNS {}'.format(lineNoTreeItem.childCount() + 1)])
340
        runItem.setData(0, self.TREE_DATA_ROLE, pipeRun)
341

    
342
        brush = lineNoTreeItem.foreground(0)
343
        runItem.setForeground(0, brush)
344
        runItem.setFont(0, runItem.font(0))
345

    
346
        lineNoTreeItem.addChild(runItem)
347

    
348
        return runItem
349

    
350
    '''
351
        @brief      add a tree item
352
        @author     humkyung
353
        @date       2018.04.17
354
        @history    humkyung 2018.04.19 treat a case parent is changed
355
                    Jeongwoo 2018.04.26 QEngineeringTextItem → QEngineeringLineNoTextItem
356
                                        Insert if-statement for QEngineeringNoteItem
357
                                        Add if-statement for QEngineeringLineNoTextItem
358
                    Jeongwoo 2018.05.11 Set color when SymbolSvgItem moved into new parent(Line No)
359
                    Jeongwoo 2018.05.15 Add break keyword on if-statement
360
                    Jeongwoo 2018.05.17 Set TreeWidgetItem's color with data's color And Set Data's color on LineNoTextItem Setting
361
                    humkyung 2018.06.12 add unknown item
362
                    humkyung 2018.07.20 append nozzle to equipment
363
    '''
364

    
365
    def addTreeItem(self, parent, child):
366
        item = None
367
        appDocData = AppDocData.instance()
368

    
369
        try:
370
            if (not hasattr(child, 'treeItem')) or (child.treeItem is None):
371
                if issubclass(type(child), SymbolSvgItem):
372
                    isEquipmentType = appDocData.isEquipmentType(child.type)
373
                    if isEquipmentType:
374
                        item = QTreeWidgetItem(self.EqpTreeItem, [child.name])
375
                        item.setData(0, self.TREE_DATA_ROLE, child)
376
                        # elif child.type == 'Nozzles':
377
                        #    for i in range(self.EqpTreeItem.childCount()):
378
                        #        eqpTreeItem = eqpRootTreeItem[0].child(i)
379
                        #        eqpSymbol = eqpTreeItem.data(0, self.TREE_DATA_ROLE)
380
                        #        if child.owner is eqpSymbol:
381
                        #            item = QTreeWidgetItem(eqpTreeItem, [child.name])
382
                        #            item.setData(0, self.TREE_DATA_ROLE, child)
383
                        #            break
384

    
385
                        if item is None:
386
                            item = QTreeWidgetItem(self.SymbolsTreeItem, [child.name])
387
                    elif child.type == 'Notes':
388
                        child.treeItem = True
389
                        return item
390
                    else:
391
                        item = QTreeWidgetItem(self.SymbolsTreeItem, [child.name])
392

    
393
                    if item is not None:
394
                        iconPath = os.path.join(AppDocData.instance().getCurrentProject().getSvgFilePath(), child.type,
395
                                                child.name + ".svg")
396
                        item.setIcon(0, QIcon(iconPath))
397
                        item.setData(0, self.TREE_DATA_ROLE, child)
398
                        brush = QBrush()
399
                        brush.setColor(QColor(child.getColor()))
400
                        item.setForeground(0, brush)
401
                        item.setFont(0, item.font(0))
402
                        child.treeItem = item
403
                        if isEquipmentType:
404
                            self.EqpTreeItem.addChild(item)
405
                            self.EqpTreeItem.sortChildren(0, Qt.AscendingOrder)  # sort childrens
406
                        else:
407
                            self.SymbolsTreeItem.addChild(item)
408
                            self.SymbolsTreeItem.sortChildren(0, Qt.AscendingOrder)  # sort childrens
409
                elif type(child) is QEngineeringLineNoTextItem:
410
                    for index in range(self.LineNoTreeItem.childCount()):
411
                        if child.text() == self.LineNoTreeItem.child(0).text(index) and self.LineNoTreeItem.child(
412
                                0).childCount() is 0:
413
                            self.LineNoTreeItem.takeChild(index)
414
                            break
415
                    item = CustomTreeWidgetItem([child.text().replace('\n', '')])
416
                    item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
417
                    item.setData(0, self.TREE_DATA_ROLE, child)
418
                    item.setCheckState(0, Qt.Checked if child.isVisible() else Qt.Unchecked)
419
                    brush = QBrush()
420
                    brush.setColor(QColor(child.getColor()))
421
                    item.setForeground(0, brush)
422
                    item.setFont(0, item.font(0))
423
                    child.treeItem = item
424
                    self.LineNoTreeItem.addChild(item)
425
                    self.LineNoTreeItem.sortChildren(0, Qt.AscendingOrder)  # sort line nos
426
                elif type(child) is QEngineeringTrimLineNoTextItem:
427
                    item = CustomTreeWidgetItem(['Unknown Line'])
428
                    item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
429
                    item.setData(0, self.TREE_DATA_ROLE, child)
430
                    item.setCheckState(0, Qt.Checked if child.isVisible() else Qt.Unchecked)
431
                    brush = QBrush()
432
                    brush.setColor(QColor(child.getColor()))
433
                    item.setForeground(0, brush)
434
                    item.setFont(0, item.font(0))
435
                    child.treeItem = item
436
                    self.LineNoTreeItem.addChild(item)
437
                elif (type(child) is QEngineeringNoteItem):
438
                    founds = None
439
                    for i in range(self.NotesTreeItem.childCount()):
440
                        item = self.NotesTreeItem.child(i)
441
                        notes = item.data(0, self.TREE_DATA_ROLE)
442
                        founds = [note for note in notes if note.text() == child.text()]
443
                        if founds: break
444

    
445
                    if founds:
446
                        item.setData(0, self.TREE_DATA_ROLE, founds + [child, ])
447
                    else:
448
                        item = QTreeWidgetItem([child.text()])
449
                        item.setData(0, self.TREE_DATA_ROLE, [child, ])
450
                        if parent is not None:
451
                            parent.addChild(item)
452
                            parent.sortChildren(0, Qt.AscendingOrder)  # sort childrens
453
                    child.treeItem = item
454
                    item.setText(0, '{}({})'.format(child.text(), len(item.data(0, self.TREE_DATA_ROLE))))
455

    
456
                    # show note icon if note icon is setted
457
                    if child.symbol:
458
                        iconPath = os.path.join(appDocData.getCurrentProject().getSvgFilePath(), 'Notes',
459
                                                child.symbol.name + '.svg')
460
                        item.setIcon(0, QIcon(iconPath))
461
                elif (type(child) is QEngineeringUnknownItem):
462
                    item = QTreeWidgetItem(['Unknown'])
463
                    item.setData(0, self.TREE_DATA_ROLE, child)
464
                    child.treeItem = item
465
                    self.UnknownTreeItem.addChild(item)
466
                    if child.lineIndicator == 'Match':
467
                        item.setHidden(True)
468
            elif issubclass(type(child), SymbolSvgItem):  # change item's parent
469
                foundItems = self.findItems(child.name, Qt.MatchExactly | Qt.MatchRecursive, 0)
470
                if foundItems is not None:
471
                    for item in foundItems:
472
                        data = item.data(0, self.TREE_DATA_ROLE)
473
                        if data is not None and (data == child) and (parent and parent is not item.parent()):
474
                            parentData = parent.data(0, self.TREE_DATA_ROLE)
475
                            if parentData is not None and issubclass(type(parentData), QEngineeringLineNoTextItem):
476
                                for index in range(len(parentData.runs)):
477
                                    runGroup = parentData.runs[index]
478
                                    if data in runGroup.items:
479
                                        item.parent().removeChild(item)  # remove item from original parent
480
                                        runItem = self.addPipeRunTreeItemIfNeed(parent, runGroup)  # parent.child(index)
481
                                        brush = QBrush()
482
                                        brush.setColor(QColor(item.data(0, self.TREE_DATA_ROLE).getColor()))
483
                                        item.setForeground(0, brush)
484
                                        # item.data(0, self.TREE_DATA_ROLE).setColor(brush.color().name())
485
                                        item.setFont(0, item.font(0))
486
                                        runItem.addChild(item)
487
                                        break
488
                                    else:
489
                                        pass
490
                            elif parent is not None:
491
                                item.parent().removeChild(item)  # remove item from original parent
492
                                parent.addChild(item)
493
                            break
494
            elif type(child) is QEngineeringLineNoTextItem:
495
                foundItems = self.findItems(child.text(), Qt.MatchExactly | Qt.MatchRecursive, 0)
496
                if foundItems is not None:
497
                    for item in foundItems:
498
                        data = item.data(0, self.TREE_DATA_ROLE)
499
                        if data is not None and (data == child):
500
                            connectedItems = data.getConnectedItems()
501
                            color = data.getColor()
502
                            for connectedItem in connectedItems:
503
                                connectedItem.setColor(color)
504
                            return item
505
        except Exception as ex:
506
            from App import App
507
            from AppDocData import MessageType
508

    
509
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
510
                                                           sys.exc_info()[-1].tb_lineno)
511
            App.mainWnd().addMessage.emit(MessageType.Error, message)
512

    
513
        return item
514

    
515
    '''
516
        @brief      Scene Changed Listener
517
        @author     Jeongwoo
518
        @date       18.04.11
519
        @history    Jeongwoo 2018.04.25 Add QEngineeringNoteItem to list for loop  / NOT QEngineeringTextItem
520
                    Jeongwoo 2018.04.26 Change changedSceneItems conditions in loop (QEngineeringTextItem → QEngineeringLineNoTextItem)
521
                    humkyung 2018.07.20 put items which's owner is None before item which's owner is not None
522
    '''
523
    lastSceneItems = None
524

    
525
    def sceneChanged(self, items):
526
        try:
527
            changedSceneItems = [item for item in items if ((issubclass(type(item), SymbolSvgItem) and
528
                                                                  type(item) is not QEngineeringErrorItem and
529
                                                                  type(item) is not QEngineeringEndBreakItem and
530
                                                                  type(item) is not QEngineeringFlowMarkItem) or
531
                                                                 (type(item) is QEngineeringNoteItem) or (type(item) is QEngineeringLineNoTextItem) or
532
                                                                 (type(item) is QEngineeringUnknownItem)) and
533
                                 (not hasattr(item, 'treeItem') or item.treeItem is None)]
534
            first = [item for item in changedSceneItems if item.owner is None]
535
            second = [item for item in changedSceneItems if item.owner is not None]
536
            if first + second:
537
                self.initResultTreeWidget(first + second)
538
        finally:
539
            self.update_item_count()
540

    
541
    '''
542
        @brief      Initialize TreeWidget
543
                    Tree Item Clear and Add Item
544
        @author     Jeongwoo
545
        @date       2018.04.11
546
        @history    2018.04.12 Jeongwoo    Declare self.TREE_DATA_ROLE for QTreeWidgetItem.data(column, role)
547
        @history    2018.04.17 humkyung NOT remove child of root
548
                    2018.04.25 Jeongwoo     Add QEngineeringNoteItem Child
549
                    2018.04.26 Jeongwoo     Change method to insert child
550
    '''
551

    
552
    def initResultTreeWidget(self, items):
553
        for item in items:
554
            if (type(item) is QEngineeringNoteItem):
555
                self.addTreeItem(self.NotesTreeItem, item)
556
            else:
557
                self.addTreeItem(self.root, item)
558

    
559
        if self.NotesTreeItem is not None:
560
            self.NotesTreeItem.sortChildren(0, Qt.AscendingOrder)
561

    
562
        self.expandAll()
563

    
564
    def itemCheckBoxToggled(self, item, checkState):
565
        """
566
        set visible of invisible of item
567
        """
568
        try:
569
            itemData = item.data(0, self.TREE_DATA_ROLE)
570
            if (type(itemData) is QEngineeringLineNoTextItem) or (type(itemData) is QEngineeringTrimLineNoTextItem):
571
                itemData.setVisible(checkState == Qt.CheckState.Checked)
572
        except Exception as ex:
573
            from App import App
574
            from AppDocData import MessageType
575

    
576
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
577
                                                           sys.exc_info()[-1].tb_lineno)
578
            App.mainWnd().addMessage.emit(MessageType.Error, message)
579
        finally:
580
            pass
581

    
582
    '''
583
        @brief      TreeWidget Item click listener
584
        @author     Jeongwoo
585
        @date       18.04.11
586
        @history    18.04.12    Jeongwoo    Declare self.TREE_DATA_ROLE for QTreeWidgetItem.data(column, role)
587
                    18.04.13    Jeongwoo    Signal 'singleClicked' emit SymbolSvgItem
588
                                            CenterOn() with Symbol's center
589
                    18.04.25    Jeongwoo    Add QEngineeringNoteItem Click event
590
                    18.04.26    Jeongwoo    QEngineeringTextItem → QEngineeringLineNoTextItem
591
                    18.04.27    Jeongwoo    Find NOTE Contents when NOTE No. Clicked
592
                                            Move singClicked to if-statement type(itemData) is SymbolSvgItem:
593
                    18.05.10    Jeongwoo    Add lineNoSingleClicked emit
594
                    humkyung 2018.07.07 emit singleClicked signal when user click drawing name
595
    '''
596

    
597
    def itemClickEvent(self, item, columnNo, isSvgClick=False):
598
        from Drawing import Drawing
599
        from EngineeringRunItem import QEngineeringRunItem
600
        from HighlightCommand import HighlightCommand
601

    
602
        hilightColor = QColor(255, 0, 0, 127)
603

    
604
        itemData = item.data(0, self.TREE_DATA_ROLE)
605

    
606
        if itemData is not None:  ## Not PID Name
607
            if issubclass(type(itemData), SymbolSvgItem):
608
                HighlightCommand(self.imageViewer).execute(itemData)
609
                ## Draw rectangle on selected symbol
610
                # rect = itemData.sceneBoundingRect()
611
                # if isSvgClick == False:
612
                #    self.imageViewer.centerOn(rect.center())
613
                ## Send new event to imageViewer's zoomImage Method
614
                # self.imageViewer.zoomImage(True, QMouseEvent(QEvent.MouseButtonPress, self.imageViewer.mapFromScene(QPointF(rect.left(), rect.top())), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier), 3)
615

    
616
                # self.singleClicked.emit(itemData)
617
            elif type(itemData) is QEngineeringRunItem:
618
                HighlightCommand(self.imageViewer).execute(itemData)
619
                self.singleClicked.emit(itemData)
620
                for child in range(item.childCount()):
621
                    item.child(child).setSelected(True)
622
            elif type(itemData) is QEngineeringLineNoTextItem:
623
                HighlightCommand(self.imageViewer).execute(itemData)
624
                # self.lineNoSingleClicked.emit(itemData)
625
                itemData.setSelected(True)
626
                # for child in range(item.childCount()):
627
                #    for cchild in range(item.child(child).childCount()):
628
                #        item.child(child).child(cchild).setSelected(True)
629
            elif type(itemData) is list and type(itemData[0]) is QEngineeringNoteItem:
630
                HighlightCommand(self.imageViewer).execute(itemData)
631
                '''
632
                rect = itemData.sceneBoundingRect()
633
                if isSvgClick == False:
634
                    self.imageViewer.centerOn(rect.center())
635
                ## Send new event to imageViewer's zoomImage Method
636
                self.imageViewer.zoomImage(True, QMouseEvent(QEvent.MouseButtonPress, self.imageViewer.mapFromScene(QPointF(rect.left(), rect.top())), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier), 3)
637
                '''
638
                noteContentsList = itemData[0].findNoteContents(itemData[0].text())
639

    
640
                self.noteNoSingleClicked.emit(itemData[0].text(), noteContentsList)
641
            elif type(itemData) is QEngineeringUnknownItem:
642
                HighlightCommand(self.imageViewer).execute(itemData)
643
            elif type(itemData) is Drawing:
644
                self.drawingClicked.emit(itemData)
645

    
646
            '''
647
            if issubclass(type(itemData), QGraphicsItem):
648
                itemData.setSelected(True)
649
                itemData.update()
650
            '''
651

    
652
    '''
653
        @brief  find item which has data is given item
654
        @author humkyung
655
        @date   2018.04.23
656
        @history    2018.06.18  Jeongwoo    Add if-statement for QEngineeringUnknownItem
657
        @history    2018.11.22  euisung     add delete note
658
    '''
659

    
660
    def findItemByData(self, item):
661
        if issubclass(type(item), SymbolSvgItem):
662
            foundItems = self.findItems(item.name, Qt.MatchExactly | Qt.MatchRecursive, 0)
663
            for foundItem in foundItems:
664
                data = foundItem.data(0, self.TREE_DATA_ROLE)
665
                if data is not None and data is item:
666
                    return foundItem
667
        elif type(item) is QEngineeringLineNoTextItem:
668
            foundItems = self.findItems(item.text().replace('\n', ''), Qt.MatchExactly | Qt.MatchRecursive, 0)
669
            for foundItem in foundItems:
670
                data = foundItem.data(0, self.TREE_DATA_ROLE)
671
                if data is not None and data is item:
672
                    return foundItem
673
        elif type(item) is QEngineeringUnknownItem:
674
            foundItems = self.findItems('Unknown', Qt.MatchExactly | Qt.MatchRecursive, 0)
675
            for foundItem in foundItems:
676
                data = foundItem.data(0, self.TREE_DATA_ROLE)
677
                if data is not None and data is item:
678
                    return foundItem
679
        elif type(item) is QEngineeringNoteItem:
680
            foundItems = self.findItems(item.text(), Qt.MatchExactly | Qt.MatchRecursive, 0)
681
            for foundItem in foundItems:
682
                data = foundItem.data(0, self.TREE_DATA_ROLE)
683
                if data is not None and data is item:
684
                    return foundItem
685
        elif type(item) is QEngineeringTrimLineNoTextItem:
686
            foundItems = self.findItems('Unknown Line', Qt.MatchExactly | Qt.MatchRecursive, 0)
687
            for foundItem in foundItems:
688
                data = foundItem.data(0, self.TREE_DATA_ROLE)
689
                if data is not None and data is item:
690
                    return foundItem
691

    
692
        return None
693

    
694
    '''
695
        @brief  Init LineNoItems child
696
        @author kyouho
697
        @date   2018.09.17
698
    '''
699

    
700
    def InitLineNoItems(self):
701
        try:
702
            removeLineItem = []
703
            for lineIndex in range(self.LineNoTreeItem.childCount()):
704
                ## LineNoItem, TrimLine Item
705
                lineItem = self.LineNoTreeItem.child(lineIndex)
706

    
707
                removeRunItem = []
708
                for runIndex in range(lineItem.childCount()):
709
                    ## RUN Item
710
                    runItem = lineItem.child(runIndex)
711
                    for symbolIndex in range(runItem.childCount()):
712
                        symbolItem = runItem.child(0)
713
                        symbol = symbolItem.data(0, self.TREE_DATA_ROLE)
714

    
715
                        symbolItem.parent().removeChild(symbolItem)
716

    
717
                        if AppDocData.instance().isEquipmentType(symbol.type):
718
                            self.EqpTreeItem.addChild(symbolItem)
719
                        else:
720
                            self.SymbolsTreeItem.addChild(symbolItem)
721

    
722
                    ## 지울 Item 모음
723
                    removeRunItem.append(runItem)
724
                ## Run Item들 삭제
725
                for removeItem in removeRunItem:
726
                    lineItem.removeChild(removeItem)
727
                ## 지울 Trim Line 모음
728
                if lineItem.text(0) == 'Trim Line':
729
                    removeLineItem.append(lineItem)
730
            ## Trim Line들 삭제
731
            for removeItem in removeLineItem:
732
                self.LineNoTreeItem.removeChild(removeItem)
733

    
734
        except Exception as ex:
735
            from App import App
736
            from AppDocData import MessageType
737

    
738
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
739
                                                           sys.exc_info()[-1].tb_lineno)
740
            App.mainWnd().addMessage.emit(MessageType.Error, message)
741

    
742
    '''
743
        @brief      Find QTreeWidgetItem by SymbolSvgItem object
744
        @author     Jeongwoo
745
        @date       18.04.11
746
        @history    18.04.12    Jeongwoo    Change Flags (Qt.MatchExactly → Qt.MatchExactly|Qt.MatchRecursive)
747
                                            Declare self.TREE_DATA_ROLE for QTreeWidgetItem.data(column, role)
748
        @history    2018.11.22  euisung     add note, unknown
749
    '''
750

    
751
    @pyqtSlot(SymbolSvgItem)
752
    def findItem(self, item):
753
        if issubclass(type(item), SymbolSvgItem):
754
            foundItems = self.findItems(item.name, Qt.MatchExactly | Qt.MatchRecursive, 0)
755
            if foundItems is not None:
756
                for fItem in foundItems:
757
                    data = fItem.data(0, self.TREE_DATA_ROLE)
758
                    if data is not None and data == item:
759
                        self.setCurrentItem(fItem)
760
                        return
761
        elif type(item) is QEngineeringLineNoTextItem:
762
            foundItems = self.findItems(item.text().replace('\n', ''), Qt.MatchExactly | Qt.MatchRecursive, 0)
763
            if foundItems is not None:
764
                for fItem in foundItems:
765
                    data = fItem.data(0, self.TREE_DATA_ROLE)
766
                    if data is not None and data == item:
767
                        self.setCurrentItem(fItem)
768
                        return
769
        elif type(item) is QEngineeringNoteItem:
770
            founds = None
771
            for i in range(self.NotesTreeItem.childCount()):
772
                child = self.NotesTreeItem.child(i)
773
                notes = child.data(0, self.TREE_DATA_ROLE)
774
                founds = [note for note in notes if note.text() == item.text()]
775
                if founds:
776
                    self.setCurrentItem(child)
777
                    return
778
        elif type(item) is QEngineeringUnknownItem:
779
            foundItems = self.findItems('Unknown', Qt.MatchExactly | Qt.MatchRecursive, 0)
780
            if foundItems is not None:
781
                for fItem in foundItems:
782
                    data = fItem.data(0, self.TREE_DATA_ROLE)
783
                    if data is not None and data == item:
784
                        self.setCurrentItem(fItem)
785
                        return
786
        elif type(item) is QEngineeringTrimLineNoTextItem:
787
            foundItems = self.findItems('Unknown Line', Qt.MatchExactly | Qt.MatchRecursive, 0)
788
            if foundItems is not None:
789
                for fItem in foundItems:
790
                    data = fItem.data(0, self.TREE_DATA_ROLE)
791
                    if data is not None and data == item:
792
                        self.setCurrentItem(fItem)
793
                        return
794

    
795
        ## Not found
796
        # QMessageBox.warning(self, self.tr('Error'), self.tr('Can not find data for the selected symbol.'))
797

    
798
    '''
799
        @brief      remove given item
800
        @author     humkyung
801
        @date       2018.04.23
802
        @history    Jeongwoo 2018.05.25 Remove Highlighting when item removed
803
                    humkyung 2018.07.22 removed code to Remove highlighting
804
    '''
805

    
806
    @pyqtSlot(QGraphicsItem)
807
    def itemRemoved(self, item):
808
        try:
809
            found = self.findItemByData(item)
810
            if found and found.parent():
811
                found.data(0, self.TREE_DATA_ROLE).treeItem = None   # reset treeItem property
812
                found.parent().removeChild(found)
813
        finally:
814
            self.update_item_count()
815

    
816
    def update_item_count(self):
817
        """update items count"""
818
        if hasattr(self, 'LineNoTreeItem'):
819
            self.LineNoTreeItem.setText(0, 'LINE NO({})'.format(self.LineNoTreeItem.childCount()))
820
        if hasattr(self, 'EqpTreeItem'):
821
            self.EqpTreeItem.setText(0, 'EQUIPMENTS({})'.format(self.EqpTreeItem.childCount()))
822
        if hasattr(self, 'SymbolsTreeItem'):
823
            self.SymbolsTreeItem.setText(0, 'SYMBOLS({})'.format(self.SymbolsTreeItem.childCount()))
824
        if hasattr(self, 'NotesTreeItem'):
825
            self.NotesTreeItem.setText(0, 'NOTES({})'.format(self.NotesTreeItem.childCount()))
826
        if hasattr(self, 'UnknownTreeItem'):
827
            self.UnknownTreeItem.setText(0, 'UNKNOWN({})'.format(self.UnknownTreeItem.childCount()))
클립보드 이미지 추가 (최대 크기: 500 MB)