프로젝트

일반

사용자정보

통계
| 개정판:

hytos / DTI_PID / DTI_PID / ItemTreeWidget.py @ b6c7a71b

이력 | 보기 | 이력해설 | 다운로드 (40.4 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
                showAction = QAction(self.tr("Show/ Hide From, To"))
152
                showAction.triggered.connect(lambda: self.showFromToALLEvent(item))
153
                menu.addAction(showAction)
154
                menu.exec_(self.viewport().mapToGlobal(position))
155
            else:
156
                data = item.data(0, self.TREE_DATA_ROLE)
157
                if len(indexes) > 0 and data is not None and issubclass(type(data), QEngineeringLineNoTextItem):
158
                    menu = QMenu()
159
                    pickColorAction = QAction(self.tr("Select Line Color"))
160
                    pickColorAction.triggered.connect(lambda: self.pickColorClickEvent(item))
161
                    menu.addAction(pickColorAction)
162
                    explode_action = QAction(self.tr("Explode"))
163
                    freeze = data.prop('Freeze')
164
                    explode_action.setEnabled(not freeze)
165
                    explode_action.triggered.connect(lambda: self.explode_line_no(item))
166
                    menu.addAction(explode_action)
167
                    if type(data) is QEngineeringLineNoTextItem:
168
                        explodeKeepFromTo_action = QAction(self.tr("Explode(keep from, to)"))
169
                        explodeKeepFromTo_action.setEnabled(not freeze)
170
                        explodeKeepFromTo_action.triggered.connect(lambda: self.explode_line_no(item, True))
171
                        menu.addAction(explodeKeepFromTo_action)
172
                    showAction = QAction(self.tr("Show/ Hide From, To"))
173
                    showAction.triggered.connect(lambda: self.showFromToEvent(item))
174
                    menu.addAction(showAction)
175
                    reverse_flow_action = QAction(self.tr("Reverse Flow"))
176
                    reverse_flow_action.triggered.connect(lambda: self.reverse_line_flow(item))
177
                    menu.addAction(reverse_flow_action)
178
                    menu.exec_(self.viewport().mapToGlobal(position))
179
                elif len(indexes) > 0 and data is not None and issubclass(type(data), QEngineeringRunItem):
180
                    menu = QMenu()
181
                    lineTypeAction = QAction(self.tr("Select Line Type"))
182
                    lineTypeAction.triggered.connect(lambda: self.lineTypeClickEvent(item))
183
                    menu.addAction(lineTypeAction)
184
                    line_no = item.parent().data(0, self.TREE_DATA_ROLE)
185
                    freeze = line_no.prop('Freeze')
186
                    explode_action = QAction(self.tr("Explode"))
187
                    explode_action.setEnabled(not freeze)
188
                    explode_action.triggered.connect(lambda: self.explode_line_run(item))
189
                    menu.addAction(explode_action)
190
                    reverse_flow_action = QAction(self.tr("Reverse Flow"))
191
                    reverse_flow_action.triggered.connect(lambda: self.reverse_line_flow(item))
192
                    menu.addAction(reverse_flow_action)
193
                    menu.exec_(self.viewport().mapToGlobal(position))
194

    
195
            self.SymbolsTreeItem.sortChildren(0, Qt.AscendingOrder)
196
            self.EqpTreeItem.sortChildren(0, Qt.AscendingOrder)
197

    
198
    '''
199
        @brief      Pick Color for Line No
200
        @author     Jeongwoo
201
        @date       18.05.11
202
        @history    18.05.14    Jeongwoo    Change method to change color by changeTreeWidgetItemColorRecursively()
203
    '''
204

    
205
    def pickColorClickEvent(self, lineNoTreeWidgetItem):
206
        color = QColorDialog.getColor()  # Dialog returns QColor
207

    
208
        if color is not None:
209
            lineNoTreeWidgetItem.setForeground(0, QBrush(color))
210
            lineNoTreeWidgetItem.setFont(0, lineNoTreeWidgetItem.font(0))
211
            lineNoItem = lineNoTreeWidgetItem.data(0, self.TREE_DATA_ROLE)
212
            if lineNoItem:
213
                lineNoItem.change_color(color.name())
214
                lineNoItem.setColor(color.name())
215
                connectedItems = lineNoItem.getConnectedItems()
216
                if connectedItems is not None:
217
                    for connectedItem in connectedItems:
218
                        connectedItem.setColor(color.name())
219
                        connectedItem.update()
220
                    self.changeTreeWidgetItemColorRecursively(lineNoTreeWidgetItem, color)
221

    
222
    def explode_line_run(self, tree_widget_item):
223
        """ explode line run """
224

    
225
        try:
226
            line_run = tree_widget_item.data(0, self.TREE_DATA_ROLE)
227
            if line_run:
228
                for item in line_run.items:
229
                    if issubclass(type(item), SymbolSvgItem): self.addTreeItem(self.SymbolsTreeItem, item)
230

    
231
                for i in reversed(range(tree_widget_item.childCount())):
232
                    tree_widget_item.takeChild(i)
233

    
234
                line_run.explode()
235
                tree_widget_item.parent().takeChild(tree_widget_item.parent().indexOfChild(tree_widget_item))
236
        finally:
237
            pass
238

    
239
    def explode_all_line_nos(self, tree_widget_item, remainFromTo=False):
240
        """ explode all line nos """
241

    
242
        for i in reversed(range(self.LineNoTreeItem.childCount())):
243
            if not self.LineNoTreeItem.child(i).data(0, self.TREE_DATA_ROLE).prop('Freeze'):
244
                self.explode_line_no(self.LineNoTreeItem.child(i), remainFromTo)
245

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

    
248
    def reverse_line_flow(self, lineTreeWidgetItem):
249
        """ reverse line flow """
250

    
251
        try:
252
            line_item = lineTreeWidgetItem.data(0, self.TREE_DATA_ROLE)
253
            if line_item:
254
                line_item.reverse()
255
        finally:
256
            pass
257

    
258
    def showFromToALLEvent(self, tree_widget_item):
259
        for i in reversed(range(self.LineNoTreeItem.childCount())):
260
            if not self.LineNoTreeItem.child(i).data(0, self.TREE_DATA_ROLE).prop('Freeze'):
261
                self.showFromToEvent(self.LineNoTreeItem.child(i))
262

    
263
    def showFromToEvent(self, lineNoTreeWidgetItem):
264
        try:
265
            line_no_item = lineNoTreeWidgetItem.data(0, self.TREE_DATA_ROLE)
266
            if line_no_item and type(line_no_item) is QEngineeringLineNoTextItem:
267
                line_no_item.contextShow()
268
        finally:
269
            pass
270
        
271
    def explode_line_no(self, lineNoTreeWidgetItem, remainFromTo=False):
272
        """ explode line no """
273

    
274
        try:
275
            line_no_item = lineNoTreeWidgetItem.data(0, self.TREE_DATA_ROLE)
276
            if line_no_item:
277
                connected_items = line_no_item.getConnectedItems()
278
                for item in connected_items:
279
                    self.addTreeItem(self.SymbolsTreeItem, item)
280

    
281
                for i in reversed(range(lineNoTreeWidgetItem.childCount())):
282
                    lineNoTreeWidgetItem.takeChild(i)
283

    
284
                line_no_item.explode(remainFromTo)
285
        finally:
286
            pass
287

    
288
    '''
289
        @brief      pick line type
290
        @author     humkyung 
291
        @date       2018.06.27
292
    '''
293
    def lineTypeClickEvent(self, item):
294
        pass
295

    
296
    '''
297
        @brief      Change Color recursively
298
        @author     Jeongwoo
299
        @date       18.05.14
300
    '''
301

    
302
    def changeTreeWidgetItemColorRecursively(self, item, color):
303
        for index in range(item.childCount()):
304
            child = item.child(index)
305
            child.setForeground(0, QBrush(color))
306
            child.setFont(0, child.font(0))
307
            self.changeTreeWidgetItemColorRecursively(child, color)
308

    
309
    '''
310
        @brief      Clear TreeWidget and Set Current PID
311
        @author     Jeongwoo
312
        @date       18.04.11
313
        @history    2018.04.26  Jeongwoo    Add Child [SYMBOLS, NOTES] into root item
314
                    2018.05.09  Jeongwoo    Change method to add default tree items
315
                    humkyung 2018.06.10 add tree item for Line No and Unknown Item
316
    '''
317

    
318
    def setCurrentPID(self, drawingName):
319
        appDocData = AppDocData.instance()
320

    
321
        self.clear()
322
        self.root = QTreeWidgetItem(self, [drawingName])
323
        self.root.setIcon(0, QIcon(':newPrefix/objects.png'))
324
        self.root.setData(0, self.TREE_DATA_ROLE, appDocData.activeDrawing)
325
        child = self.root.addChild(QTreeWidgetItem(['LINE NO']))
326
        self.LineNoTreeItem = self.root.child(self.root.childCount() - 1)
327
        self.LineNoTreeItem.setFlags(self.root.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
328
        self.LineNoTreeItem.setCheckState(0, Qt.Checked)
329
        self.root.addChild(QTreeWidgetItem(['EQUIPMENTS']))
330
        self.EqpTreeItem = self.root.child(self.root.childCount() - 1)
331
        self.root.addChild(QTreeWidgetItem(['SYMBOLS']))
332
        self.SymbolsTreeItem = self.root.child(self.root.childCount() - 1)
333
        self.root.addChild(QTreeWidgetItem(['NOTES']))
334
        self.NotesTreeItem = self.root.child(self.root.childCount() - 1)
335
        self.root.addChild(QTreeWidgetItem(['UNKNOWN']))
336
        self.UnknownTreeItem = self.root.child(self.root.childCount() - 1)
337

    
338
        for idx in range(self.root.childCount()):
339
            child = self.root.child(idx)
340
            child.setIcon(0, QIcon(':newPrefix/folder-black.png'))
341

    
342
    '''
343
        @brief  create tree item for pipe run if need
344
        @author humkyung
345
        @date   2018.05.15
346
        @history    2018.05.17  Jeongwoo    Change run item color with parent(LineNo Item) color
347
    '''
348

    
349
    def addPipeRunTreeItemIfNeed(self, lineNoTreeItem, pipeRun):
350
        for index in range(lineNoTreeItem.childCount()):
351
            treeItem = lineNoTreeItem.child(index)
352
            itemData = treeItem.data(0, self.TREE_DATA_ROLE)
353
            if itemData is not None and itemData == pipeRun:
354
                return treeItem
355

    
356
        runItem = QTreeWidgetItem(['RUNS {}'.format(lineNoTreeItem.childCount() + 1)])
357
        runItem.setData(0, self.TREE_DATA_ROLE, pipeRun)
358

    
359
        brush = lineNoTreeItem.foreground(0)
360
        runItem.setForeground(0, brush)
361
        runItem.setFont(0, runItem.font(0))
362

    
363
        lineNoTreeItem.addChild(runItem)
364

    
365
        return runItem
366

    
367
    '''
368
        @brief      add a tree item
369
        @author     humkyung
370
        @date       2018.04.17
371
        @history    humkyung 2018.04.19 treat a case parent is changed
372
                    Jeongwoo 2018.04.26 QEngineeringTextItem → QEngineeringLineNoTextItem
373
                                        Insert if-statement for QEngineeringNoteItem
374
                                        Add if-statement for QEngineeringLineNoTextItem
375
                    Jeongwoo 2018.05.11 Set color when SymbolSvgItem moved into new parent(Line No)
376
                    Jeongwoo 2018.05.15 Add break keyword on if-statement
377
                    Jeongwoo 2018.05.17 Set TreeWidgetItem's color with data's color And Set Data's color on LineNoTextItem Setting
378
                    humkyung 2018.06.12 add unknown item
379
                    humkyung 2018.07.20 append nozzle to equipment
380
    '''
381

    
382
    def addTreeItem(self, parent, child):
383
        item = None
384
        appDocData = AppDocData.instance()
385

    
386
        try:
387
            if (not hasattr(child, 'treeItem')) or (child.treeItem is None):
388
                if issubclass(type(child), SymbolSvgItem):
389
                    isEquipmentType = appDocData.isEquipmentType(child.type)
390
                    if isEquipmentType:
391
                        item = QTreeWidgetItem(self.EqpTreeItem, [child.name])
392
                        item.setData(0, self.TREE_DATA_ROLE, child)
393
                        # elif child.type == 'Nozzles':
394
                        #    for i in range(self.EqpTreeItem.childCount()):
395
                        #        eqpTreeItem = eqpRootTreeItem[0].child(i)
396
                        #        eqpSymbol = eqpTreeItem.data(0, self.TREE_DATA_ROLE)
397
                        #        if child.owner is eqpSymbol:
398
                        #            item = QTreeWidgetItem(eqpTreeItem, [child.name])
399
                        #            item.setData(0, self.TREE_DATA_ROLE, child)
400
                        #            break
401

    
402
                        if item is None:
403
                            item = QTreeWidgetItem(self.SymbolsTreeItem, [child.name])
404
                    elif child.type == 'Notes':
405
                        child.treeItem = True
406
                        return item
407
                    else:
408
                        item = QTreeWidgetItem(self.SymbolsTreeItem, [child.name])
409

    
410
                    if item is not None:
411
                        iconPath = os.path.join(AppDocData.instance().getCurrentProject().getSvgFilePath(), child.type,
412
                                                child.name + ".svg")
413
                        item.setIcon(0, QIcon(iconPath))
414
                        item.setData(0, self.TREE_DATA_ROLE, child)
415
                        brush = QBrush()
416
                        brush.setColor(QColor(child.getColor()))
417
                        item.setForeground(0, brush)
418
                        item.setFont(0, item.font(0))
419
                        child.treeItem = item
420
                        if isEquipmentType:
421
                            self.EqpTreeItem.addChild(item)
422
                            self.EqpTreeItem.sortChildren(0, Qt.AscendingOrder)  # sort childrens
423
                        else:
424
                            self.SymbolsTreeItem.addChild(item)
425
                            self.SymbolsTreeItem.sortChildren(0, Qt.AscendingOrder)  # sort childrens
426
                elif type(child) is QEngineeringLineNoTextItem:
427
                    for index in range(self.LineNoTreeItem.childCount()):
428
                        if child.text() == self.LineNoTreeItem.child(0).text(index) and self.LineNoTreeItem.child(
429
                                0).childCount() is 0:
430
                            self.LineNoTreeItem.takeChild(index)
431
                            break
432
                    item = CustomTreeWidgetItem([child.text().replace('\n', '')])
433
                    item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
434
                    item.setData(0, self.TREE_DATA_ROLE, child)
435
                    item.setCheckState(0, Qt.Checked if child.isVisible() else Qt.Unchecked)
436
                    brush = QBrush()
437
                    brush.setColor(QColor(child.getColor()))
438
                    item.setForeground(0, brush)
439
                    item.setFont(0, item.font(0))
440
                    child.treeItem = item
441
                    self.LineNoTreeItem.addChild(item)
442
                    self.LineNoTreeItem.sortChildren(0, Qt.AscendingOrder)  # sort line nos
443
                elif type(child) is QEngineeringTrimLineNoTextItem:
444
                    item = CustomTreeWidgetItem(['Unknown Line'])
445
                    item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
446
                    item.setData(0, self.TREE_DATA_ROLE, child)
447
                    item.setCheckState(0, Qt.Checked if child.isVisible() else Qt.Unchecked)
448
                    brush = QBrush()
449
                    brush.setColor(QColor(child.getColor()))
450
                    item.setForeground(0, brush)
451
                    item.setFont(0, item.font(0))
452
                    child.treeItem = item
453
                    self.LineNoTreeItem.addChild(item)
454
                elif (type(child) is QEngineeringNoteItem):
455
                    founds = None
456
                    for i in range(self.NotesTreeItem.childCount()):
457
                        item = self.NotesTreeItem.child(i)
458
                        notes = item.data(0, self.TREE_DATA_ROLE)
459
                        founds = [note for note in notes if note.text() == child.text()]
460
                        if founds: break
461

    
462
                    if founds:
463
                        item.setData(0, self.TREE_DATA_ROLE, founds + [child, ])
464
                    else:
465
                        item = QTreeWidgetItem([child.text()])
466
                        item.setData(0, self.TREE_DATA_ROLE, [child, ])
467
                        if parent is not None:
468
                            parent.addChild(item)
469
                            parent.sortChildren(0, Qt.AscendingOrder)  # sort childrens
470
                    child.treeItem = item
471
                    item.setText(0, '{}({})'.format(child.text(), len(item.data(0, self.TREE_DATA_ROLE))))
472

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

    
526
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
527
                                                           sys.exc_info()[-1].tb_lineno)
528
            App.mainWnd().addMessage.emit(MessageType.Error, message)
529

    
530
        return item
531

    
532
    '''
533
        @brief      Scene Changed Listener
534
        @author     Jeongwoo
535
        @date       18.04.11
536
        @history    Jeongwoo 2018.04.25 Add QEngineeringNoteItem to list for loop  / NOT QEngineeringTextItem
537
                    Jeongwoo 2018.04.26 Change changedSceneItems conditions in loop (QEngineeringTextItem → QEngineeringLineNoTextItem)
538
                    humkyung 2018.07.20 put items which's owner is None before item which's owner is not None
539
    '''
540
    lastSceneItems = None
541

    
542
    def sceneChanged(self, items):
543
        try:
544
            changedSceneItems = [item for item in items if ((issubclass(type(item), SymbolSvgItem) and
545
                                                                  type(item) is not QEngineeringErrorItem and
546
                                                                  type(item) is not QEngineeringEndBreakItem and
547
                                                                  type(item) is not QEngineeringFlowMarkItem) or
548
                                                                 (type(item) is QEngineeringNoteItem) or (type(item) is QEngineeringLineNoTextItem) or
549
                                                                 (type(item) is QEngineeringUnknownItem)) and
550
                                 (not hasattr(item, 'treeItem') or item.treeItem is None)]
551
            first = [item for item in changedSceneItems if item.owner is None]
552
            second = [item for item in changedSceneItems if item.owner is not None]
553
            if first + second:
554
                self.initResultTreeWidget(first + second)
555
        finally:
556
            self.update_item_count()
557

    
558
    '''
559
        @brief      Initialize TreeWidget
560
                    Tree Item Clear and Add Item
561
        @author     Jeongwoo
562
        @date       2018.04.11
563
        @history    2018.04.12 Jeongwoo    Declare self.TREE_DATA_ROLE for QTreeWidgetItem.data(column, role)
564
        @history    2018.04.17 humkyung NOT remove child of root
565
                    2018.04.25 Jeongwoo     Add QEngineeringNoteItem Child
566
                    2018.04.26 Jeongwoo     Change method to insert child
567
    '''
568

    
569
    def initResultTreeWidget(self, items):
570
        for item in items:
571
            if (type(item) is QEngineeringNoteItem):
572
                self.addTreeItem(self.NotesTreeItem, item)
573
            else:
574
                self.addTreeItem(self.root, item)
575

    
576
        if self.NotesTreeItem is not None:
577
            self.NotesTreeItem.sortChildren(0, Qt.AscendingOrder)
578

    
579
        self.expandAll()
580

    
581
    def itemCheckBoxToggled(self, item, checkState):
582
        """
583
        set visible of invisible of item
584
        """
585
        try:
586
            itemData = item.data(0, self.TREE_DATA_ROLE)
587
            if (type(itemData) is QEngineeringLineNoTextItem) or (type(itemData) is QEngineeringTrimLineNoTextItem):
588
                itemData.setVisible(checkState == Qt.CheckState.Checked)
589
        except Exception as ex:
590
            from App import App
591
            from AppDocData import MessageType
592

    
593
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
594
                                                           sys.exc_info()[-1].tb_lineno)
595
            App.mainWnd().addMessage.emit(MessageType.Error, message)
596
        finally:
597
            pass
598

    
599
    '''
600
        @brief      TreeWidget Item click listener
601
        @author     Jeongwoo
602
        @date       18.04.11
603
        @history    18.04.12    Jeongwoo    Declare self.TREE_DATA_ROLE for QTreeWidgetItem.data(column, role)
604
                    18.04.13    Jeongwoo    Signal 'singleClicked' emit SymbolSvgItem
605
                                            CenterOn() with Symbol's center
606
                    18.04.25    Jeongwoo    Add QEngineeringNoteItem Click event
607
                    18.04.26    Jeongwoo    QEngineeringTextItem → QEngineeringLineNoTextItem
608
                    18.04.27    Jeongwoo    Find NOTE Contents when NOTE No. Clicked
609
                                            Move singClicked to if-statement type(itemData) is SymbolSvgItem:
610
                    18.05.10    Jeongwoo    Add lineNoSingleClicked emit
611
                    humkyung 2018.07.07 emit singleClicked signal when user click drawing name
612
    '''
613

    
614
    def itemClickEvent(self, item, columnNo, isSvgClick=False):
615
        from Drawing import Drawing
616
        from EngineeringRunItem import QEngineeringRunItem
617
        from HighlightCommand import HighlightCommand
618

    
619
        hilightColor = QColor(255, 0, 0, 127)
620

    
621
        itemData = item.data(0, self.TREE_DATA_ROLE)
622

    
623
        if itemData is not None:  ## Not PID Name
624
            if issubclass(type(itemData), SymbolSvgItem):
625
                HighlightCommand(self.imageViewer).execute(itemData)
626
                ## Draw rectangle on selected symbol
627
                # rect = itemData.sceneBoundingRect()
628
                # if isSvgClick == False:
629
                #    self.imageViewer.centerOn(rect.center())
630
                ## Send new event to imageViewer's zoomImage Method
631
                # self.imageViewer.zoomImage(True, QMouseEvent(QEvent.MouseButtonPress, self.imageViewer.mapFromScene(QPointF(rect.left(), rect.top())), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier), 3)
632

    
633
                # self.singleClicked.emit(itemData)
634
            elif type(itemData) is QEngineeringRunItem:
635
                HighlightCommand(self.imageViewer).execute(itemData)
636
                self.singleClicked.emit(itemData)
637
                for child in range(item.childCount()):
638
                    item.child(child).setSelected(True)
639
            elif type(itemData) is QEngineeringLineNoTextItem:
640
                HighlightCommand(self.imageViewer).execute(itemData)
641
                # self.lineNoSingleClicked.emit(itemData)
642
                itemData.setSelected(True)
643
                # for child in range(item.childCount()):
644
                #    for cchild in range(item.child(child).childCount()):
645
                #        item.child(child).child(cchild).setSelected(True)
646
            elif type(itemData) is list and type(itemData[0]) is QEngineeringNoteItem:
647
                HighlightCommand(self.imageViewer).execute(itemData)
648
                '''
649
                rect = itemData.sceneBoundingRect()
650
                if isSvgClick == False:
651
                    self.imageViewer.centerOn(rect.center())
652
                ## Send new event to imageViewer's zoomImage Method
653
                self.imageViewer.zoomImage(True, QMouseEvent(QEvent.MouseButtonPress, self.imageViewer.mapFromScene(QPointF(rect.left(), rect.top())), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier), 3)
654
                '''
655
                noteContentsList = itemData[0].findNoteContents(itemData[0].text())
656

    
657
                self.noteNoSingleClicked.emit(itemData[0].text(), noteContentsList)
658
            elif type(itemData) is QEngineeringUnknownItem:
659
                HighlightCommand(self.imageViewer).execute(itemData)
660
            elif type(itemData) is Drawing:
661
                self.drawingClicked.emit(itemData)
662

    
663
            '''
664
            if issubclass(type(itemData), QGraphicsItem):
665
                itemData.setSelected(True)
666
                itemData.update()
667
            '''
668

    
669
    '''
670
        @brief  find item which has data is given item
671
        @author humkyung
672
        @date   2018.04.23
673
        @history    2018.06.18  Jeongwoo    Add if-statement for QEngineeringUnknownItem
674
        @history    2018.11.22  euisung     add delete note
675
    '''
676

    
677
    def findItemByData(self, item):
678
        if issubclass(type(item), SymbolSvgItem):
679
            foundItems = self.findItems(item.name, Qt.MatchExactly | Qt.MatchRecursive, 0)
680
            for foundItem in foundItems:
681
                data = foundItem.data(0, self.TREE_DATA_ROLE)
682
                if data is not None and data is item:
683
                    return foundItem
684
        elif type(item) is QEngineeringLineNoTextItem:
685
            foundItems = self.findItems(item.text().replace('\n', ''), Qt.MatchExactly | Qt.MatchRecursive, 0)
686
            for foundItem in foundItems:
687
                data = foundItem.data(0, self.TREE_DATA_ROLE)
688
                if data is not None and data is item:
689
                    return foundItem
690
        elif type(item) is QEngineeringUnknownItem:
691
            foundItems = self.findItems('Unknown', Qt.MatchExactly | Qt.MatchRecursive, 0)
692
            for foundItem in foundItems:
693
                data = foundItem.data(0, self.TREE_DATA_ROLE)
694
                if data is not None and data is item:
695
                    return foundItem
696
        elif type(item) is QEngineeringNoteItem:
697
            foundItems = self.findItems(item.text(), Qt.MatchExactly | Qt.MatchRecursive, 0)
698
            for foundItem in foundItems:
699
                data = foundItem.data(0, self.TREE_DATA_ROLE)
700
                if data is not None and data is item:
701
                    return foundItem
702
        elif type(item) is QEngineeringTrimLineNoTextItem:
703
            foundItems = self.findItems('Unknown Line', Qt.MatchExactly | Qt.MatchRecursive, 0)
704
            for foundItem in foundItems:
705
                data = foundItem.data(0, self.TREE_DATA_ROLE)
706
                if data is not None and data is item:
707
                    return foundItem
708

    
709
        return None
710

    
711
    '''
712
        @brief  Init LineNoItems child
713
        @author kyouho
714
        @date   2018.09.17
715
    '''
716

    
717
    def InitLineNoItems(self):
718
        try:
719
            removeLineItem = []
720
            for lineIndex in range(self.LineNoTreeItem.childCount()):
721
                ## LineNoItem, TrimLine Item
722
                lineItem = self.LineNoTreeItem.child(lineIndex)
723

    
724
                removeRunItem = []
725
                for runIndex in range(lineItem.childCount()):
726
                    ## RUN Item
727
                    runItem = lineItem.child(runIndex)
728
                    for symbolIndex in range(runItem.childCount()):
729
                        symbolItem = runItem.child(0)
730
                        symbol = symbolItem.data(0, self.TREE_DATA_ROLE)
731

    
732
                        symbolItem.parent().removeChild(symbolItem)
733

    
734
                        if AppDocData.instance().isEquipmentType(symbol.type):
735
                            self.EqpTreeItem.addChild(symbolItem)
736
                        else:
737
                            self.SymbolsTreeItem.addChild(symbolItem)
738

    
739
                    ## 지울 Item 모음
740
                    removeRunItem.append(runItem)
741
                ## Run Item들 삭제
742
                for removeItem in removeRunItem:
743
                    lineItem.removeChild(removeItem)
744
                ## 지울 Trim Line 모음
745
                if lineItem.text(0) == 'Trim Line':
746
                    removeLineItem.append(lineItem)
747
            ## Trim Line들 삭제
748
            for removeItem in removeLineItem:
749
                self.LineNoTreeItem.removeChild(removeItem)
750

    
751
        except Exception as ex:
752
            from App import App
753
            from AppDocData import MessageType
754

    
755
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
756
                                                           sys.exc_info()[-1].tb_lineno)
757
            App.mainWnd().addMessage.emit(MessageType.Error, message)
758

    
759
    '''
760
        @brief      Find QTreeWidgetItem by SymbolSvgItem object
761
        @author     Jeongwoo
762
        @date       18.04.11
763
        @history    18.04.12    Jeongwoo    Change Flags (Qt.MatchExactly → Qt.MatchExactly|Qt.MatchRecursive)
764
                                            Declare self.TREE_DATA_ROLE for QTreeWidgetItem.data(column, role)
765
        @history    2018.11.22  euisung     add note, unknown
766
    '''
767

    
768
    @pyqtSlot(SymbolSvgItem)
769
    def findItem(self, item):
770
        if issubclass(type(item), SymbolSvgItem):
771
            foundItems = self.findItems(item.name, Qt.MatchExactly | Qt.MatchRecursive, 0)
772
            if foundItems is not None:
773
                for fItem in foundItems:
774
                    data = fItem.data(0, self.TREE_DATA_ROLE)
775
                    if data is not None and data == item:
776
                        self.setCurrentItem(fItem)
777
                        return
778
        elif type(item) is QEngineeringLineNoTextItem:
779
            foundItems = self.findItems(item.text().replace('\n', ''), 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 QEngineeringNoteItem:
787
            founds = None
788
            for i in range(self.NotesTreeItem.childCount()):
789
                child = self.NotesTreeItem.child(i)
790
                notes = child.data(0, self.TREE_DATA_ROLE)
791
                founds = [note for note in notes if note.text() == item.text()]
792
                if founds:
793
                    self.setCurrentItem(child)
794
                    return
795
        elif type(item) is QEngineeringUnknownItem:
796
            foundItems = self.findItems('Unknown', Qt.MatchExactly | Qt.MatchRecursive, 0)
797
            if foundItems is not None:
798
                for fItem in foundItems:
799
                    data = fItem.data(0, self.TREE_DATA_ROLE)
800
                    if data is not None and data == item:
801
                        self.setCurrentItem(fItem)
802
                        return
803
        elif type(item) is QEngineeringTrimLineNoTextItem:
804
            foundItems = self.findItems('Unknown Line', Qt.MatchExactly | Qt.MatchRecursive, 0)
805
            if foundItems is not None:
806
                for fItem in foundItems:
807
                    data = fItem.data(0, self.TREE_DATA_ROLE)
808
                    if data is not None and data == item:
809
                        self.setCurrentItem(fItem)
810
                        return
811

    
812
        ## Not found
813
        # QMessageBox.warning(self, self.tr('Error'), self.tr('Can not find data for the selected symbol.'))
814

    
815
    '''
816
        @brief      remove given item
817
        @author     humkyung
818
        @date       2018.04.23
819
        @history    Jeongwoo 2018.05.25 Remove Highlighting when item removed
820
                    humkyung 2018.07.22 removed code to Remove highlighting
821
    '''
822

    
823
    @pyqtSlot(QGraphicsItem)
824
    def itemRemoved(self, item):
825
        try:
826
            found = self.findItemByData(item)
827
            if found and found.parent():
828
                found.data(0, self.TREE_DATA_ROLE).treeItem = None   # reset treeItem property
829
                found.parent().removeChild(found)
830
        finally:
831
            self.update_item_count()
832

    
833
    def update_item_count(self):
834
        """update items count"""
835
        if hasattr(self, 'LineNoTreeItem'):
836
            self.LineNoTreeItem.setText(0, 'LINE NO({})'.format(self.LineNoTreeItem.childCount()))
837
        if hasattr(self, 'EqpTreeItem'):
838
            self.EqpTreeItem.setText(0, 'EQUIPMENTS({})'.format(self.EqpTreeItem.childCount()))
839
        if hasattr(self, 'SymbolsTreeItem'):
840
            self.SymbolsTreeItem.setText(0, 'SYMBOLS({})'.format(self.SymbolsTreeItem.childCount()))
841
        if hasattr(self, 'NotesTreeItem'):
842
            self.NotesTreeItem.setText(0, 'NOTES({})'.format(self.NotesTreeItem.childCount()))
843
        if hasattr(self, 'UnknownTreeItem'):
844
            self.UnknownTreeItem.setText(0, 'UNKNOWN({})'.format(self.UnknownTreeItem.childCount()))