프로젝트

일반

사용자정보

통계
| 브랜치(Branch): | 개정판:

hytos / DTI_PID / DTI_PID / ItemTreeWidget.py @ d88d6f39

이력 | 보기 | 이력해설 | 다운로드 (38 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 AppDocData import AppDocData
31
from Drawing import Drawing
32

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

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

    
45
        super(CustomTreeWidgetItem, self).setData(column, role, value)
46

    
47
class QItemTreeWidget(QTreeWidget):
48
    """ This is item tree widget """
49
    TREE_DATA_ROLE = Qt.UserRole
50

    
51
    #Add Signal
52
    singleClicked = pyqtSignal(SymbolSvgItem)
53
    noteNoSingleClicked = pyqtSignal(str, dict)
54
    lineNoSingleClicked = pyqtSignal(QEngineeringAbstractItem)
55
    drawingClicked = pyqtSignal(Drawing)
56
    checkBoxToggled = pyqtSignal(QTreeWidgetItem, Qt.CheckState)
57

    
58
    '''
59
        @history    2018.05.11  Jeongwoo    Add Context Menu settings
60
    '''
61
    def __init__(self, imageViewer):
62
        QTreeWidget.__init__(self)
63

    
64
        self.checkBoxToggled.connect(self.itemCheckBoxToggled)
65

    
66
        self.itemClicked.connect(self.itemClickEvent)
67
        self.imageViewer = imageViewer
68
        self.scene = imageViewer.scene
69
        self.root = None
70
        self.setContextMenuPolicy(Qt.CustomContextMenu)
71
        self.customContextMenuRequested.connect(self.openContextMenu)
72

    
73
    '''
74
        @brief      delete selected symbol
75
        @author     humkyung
76
        @date       2018.07.20
77
    '''
78
    def keyPressEvent(self, event):
79
        try:
80
            if event.key() == Qt.Key_Delete:
81
                if self.selectedItems():
82
                    for item in self.selectedItems():
83
                        data = item.data(0, self.TREE_DATA_ROLE)
84
                        if data is not None:
85
                            self.imageViewer.scene.removeItem(data)
86

    
87
                            if type(data) is QEngineeringLineNoTextItem:
88
                                self.imageViewer.mainWindow.removedItems['LINE'].append(str(data.uid))
89
                            elif type(data) is QEngineeringInstrumentItem:
90
                                self.imageViewer.mainWindow.removedItems['INST'].append(str(data.uid))
91
                            elif type(data) is QEngineeringEquipmentItem:
92
                                self.imageViewer.mainWindow.removedItems['EQUIP'].append(str(data.uid))
93
                            elif type(data) is QEngineeringNoteItem:
94
                                self.imageViewer.mainWindow.removedItems['NOTE'].append(str(data.uid))
95

    
96
                            item.parent().removeChild(item)
97
                event.accept()
98
            elif event.key() == Qt.Key_Up:
99
                if self.selectedItems():
100
                    item = self.selectedItems()[0]
101
                    aboveItem = self.itemAbove(item)
102
                    if aboveItem is not None:
103
                        self.setCurrentItem(aboveItem)
104
                        self.scrollToItem(aboveItem, QAbstractItemView.EnsureVisible)
105
                        self.itemClickEvent(aboveItem, 0)
106
                event.accept()
107
            elif event.key() == Qt.Key_Down:
108
                if self.selectedItems():
109
                    item = self.selectedItems()[0]
110
                    belowItem = self.itemBelow(item)
111
                    if belowItem is not None:
112
                        self.setCurrentItem(belowItem)
113
                        self.scrollToItem(belowItem, QAbstractItemView.EnsureVisible)
114
                        self.itemClickEvent(belowItem, 0)
115
                event.accept()
116
            else:
117
                event.ignore()
118
        except Exception as ex:
119
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
120
    
121
    '''
122
        @brief      Show Context Menu
123
        @author     Jeongwoo
124
        @date       18.05.11
125
        @history    18.06.14    Jeongwoo    Add item None check
126
                    humkyung 2018.06.27 add menu of run item for selecting line type
127
    '''
128
    def openContextMenu(self, position):
129
        from EngineeringRunItem import QEngineeringRunItem
130

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

    
181
    '''
182
        @brief      Pick Color for Line No
183
        @author     Jeongwoo
184
        @date       18.05.11
185
        @history    18.05.14    Jeongwoo    Change method to change color by changeTreeWidgetItemColorRecursively()
186
    '''
187
    def pickColorClickEvent(self, lineNoTreeWidgetItem):
188
        color = QColorDialog.getColor() # Dialog returns QColor
189
        
190
        if color is not None:
191
            lineNoTreeWidgetItem.setForeground(0, QBrush(color))
192
            lineNoTreeWidgetItem.setFont(0, lineNoTreeWidgetItem.font(0))
193
            lineNoItem = lineNoTreeWidgetItem.data(0, self.TREE_DATA_ROLE)
194
            if lineNoItem:
195
                lineNoItem.change_color(color.name())
196
                lineNoItem.setColor(color.name())
197
                connectedItems = lineNoItem.getConnectedItems()
198
                if connectedItems is not None:
199
                    for connectedItem in connectedItems:
200
                        connectedItem.setColor(color.name())
201
                    self.changeTreeWidgetItemColorRecursively(lineNoTreeWidgetItem, color)
202

    
203
    def explode_line_run(self, tree_widget_item):
204
        """ explode line run """
205

    
206
        try:
207
            line_run = tree_widget_item.data(0, self.TREE_DATA_ROLE)
208
            if line_run:
209
                for item in line_run.items:
210
                    if issubclass(type(item), SymbolSvgItem): self.addTreeItem(self.SymbolsTreeItem, item)
211

    
212
                for i in reversed(range(tree_widget_item.childCount())):
213
                    tree_widget_item.takeChild(i)
214

    
215
                line_run.explode()
216
                tree_widget_item.parent().takeChild(tree_widget_item.parent().indexOfChild(tree_widget_item))
217
        finally:
218
            pass
219

    
220
    def explode_all_line_nos(self, tree_widget_item, remainFromTo=False):
221
        """ explode all line nos """
222
        from EngineeringLineNoTextItem import QEngineeringLineNoTextItem
223

    
224
        for i in reversed(range(self.LineNoTreeItem.childCount())):
225
                if not self.LineNoTreeItem.child(i).data(0, self.TREE_DATA_ROLE).prop('Freeze'):
226
                    self.explode_line_no(self.LineNoTreeItem.child(i), remainFromTo)
227

    
228
        #for item in [item for item in self.scene.items() if hasattr(item, 'owner')
229
       
230
    def reverse_line_flow(self, lineTreeWidgetItem):
231
        """ reverse line flow """
232

    
233
        try:
234
            line_item = lineTreeWidgetItem.data(0, self.TREE_DATA_ROLE)
235
            if line_item:
236
                line_item.reverse()
237
        finally:
238
            pass
239

    
240
    def explode_line_no(self, lineNoTreeWidgetItem, remainFromTo=False):
241
        """ explode line no """
242

    
243
        try:
244
            line_no_item = lineNoTreeWidgetItem.data(0, self.TREE_DATA_ROLE)
245
            if line_no_item:
246
                connected_items = line_no_item.getConnectedItems()
247
                for item in connected_items:
248
                    self.addTreeItem(self.SymbolsTreeItem, item)
249

    
250
                for i in reversed(range(lineNoTreeWidgetItem.childCount())):
251
                    lineNoTreeWidgetItem.takeChild(i)
252

    
253
                line_no_item.explode(remainFromTo)
254
        finally:
255
            pass
256

    
257
    '''
258
        @brief      pick line type
259
        @author     humkyung 
260
        @date       2018.06.27
261
    '''
262
    def lineTypeClickEvent(self, item):
263
        pass
264

    
265
    '''
266
        @brief      Change Color recursively
267
        @author     Jeongwoo
268
        @date       18.05.14
269
    '''
270
    def changeTreeWidgetItemColorRecursively(self, item, color):
271
        for index in range(item.childCount()):
272
            child = item.child(index)
273
            child.setForeground(0, QBrush(color))
274
            child.setFont(0, child.font(0))
275
            self.changeTreeWidgetItemColorRecursively(child, color)
276

    
277
    '''
278
        @brief      Clear TreeWidget and Set Current PID
279
        @author     Jeongwoo
280
        @date       18.04.11
281
        @history    2018.04.26  Jeongwoo    Add Child [SYMBOLS, NOTES] into root item
282
                    2018.05.09  Jeongwoo    Change method to add default tree items
283
                    humkyung 2018.06.10 add tree item for Line No and Unknown Item
284
    '''
285
    def setCurrentPID(self, drawingName):
286
        appDocData = AppDocData.instance()
287

    
288
        self.clear()
289
        self.root = QTreeWidgetItem(self, [drawingName])
290
        self.root.setIcon(0, QIcon(':newPrefix/objects.png'))
291
        self.root.setData(0, self.TREE_DATA_ROLE, appDocData.activeDrawing)
292
        child = self.root.addChild(QTreeWidgetItem(['LINE NO']))
293
        self.LineNoTreeItem = self.root.child(self.root.childCount() - 1)
294
        self.LineNoTreeItem.setFlags(self.root.flags() | Qt.ItemIsTristate | Qt.ItemIsUserCheckable)
295
        self.LineNoTreeItem.setCheckState(0, Qt.Checked)
296
        self.root.addChild(QTreeWidgetItem(['EQUIPMENTS']))
297
        self.EqpTreeItem = self.root.child(self.root.childCount() - 1)
298
        self.root.addChild(QTreeWidgetItem(['SYMBOLS']))
299
        self.SymbolsTreeItem = self.root.child(self.root.childCount() - 1)
300
        self.root.addChild(QTreeWidgetItem(['NOTES']))
301
        self.NotesTreeItem = self.root.child(self.root.childCount() - 1)
302
        self.root.addChild(QTreeWidgetItem(['UNKNOWN']))
303
        self.UnknownTreeItem = self.root.child(self.root.childCount() - 1)
304

    
305
        for idx in range(self.root.childCount()):
306
            child = self.root.child(idx)
307
            child.setIcon(0, QIcon(':newPrefix/folder-black.png'))
308

    
309
    '''
310
        @brief  create tree item for pipe run if need
311
        @author humkyung
312
        @date   2018.05.15
313
        @history    2018.05.17  Jeongwoo    Change run item color with parent(LineNo Item) color
314
    '''
315
    def addPipeRunTreeItemIfNeed(self, lineNoTreeItem, pipeRun):
316
        for index in range(lineNoTreeItem.childCount()):
317
            treeItem = lineNoTreeItem.child(index)
318
            itemData = treeItem.data(0, self.TREE_DATA_ROLE)
319
            if itemData is not None and itemData == pipeRun:
320
                return treeItem
321

    
322
        runItem = QTreeWidgetItem(['RUNS {}'.format(lineNoTreeItem.childCount()+1)])
323
        runItem.setData(0, self.TREE_DATA_ROLE, pipeRun)
324

    
325
        brush = lineNoTreeItem.foreground(0)
326
        runItem.setForeground(0, brush)
327
        runItem.setFont(0, runItem.font(0))
328

    
329
        lineNoTreeItem.addChild(runItem)
330

    
331
        return runItem
332

    
333
    '''
334
        @brief      add a tree item
335
        @author     humkyung
336
        @date       2018.04.17
337
        @history    humkyung 2018.04.19 treat a case parent is changed
338
                    Jeongwoo 2018.04.26 QEngineeringTextItem → QEngineeringLineNoTextItem
339
                                        Insert if-statement for QEngineeringNoteItem
340
                                        Add if-statement for QEngineeringLineNoTextItem
341
                    Jeongwoo 2018.05.11 Set color when SymbolSvgItem moved into new parent(Line No)
342
                    Jeongwoo 2018.05.15 Add break keyword on if-statement
343
                    Jeongwoo 2018.05.17 Set TreeWidgetItem's color with data's color And Set Data's color on LineNoTextItem Setting
344
                    humkyung 2018.06.12 add unknown item
345
                    humkyung 2018.07.20 append nozzle to equipment
346
    '''
347
    def addTreeItem(self, parent, child):
348
        item = None
349
        appDocData = AppDocData.instance()
350

    
351
        try:
352
            if (not hasattr(child, 'treeItem')) or (child.treeItem is None):
353
                if issubclass(type(child), SymbolSvgItem):
354
                    isEquipmentType = appDocData.isEquipmentType(child.type)
355
                    if isEquipmentType:
356
                        item = QTreeWidgetItem(self.EqpTreeItem, [child.name])
357
                        item.setData(0, self.TREE_DATA_ROLE, child)
358
                    #elif child.type == 'Nozzles':
359
                    #    for i in range(self.EqpTreeItem.childCount()):
360
                    #        eqpTreeItem = eqpRootTreeItem[0].child(i)
361
                    #        eqpSymbol = eqpTreeItem.data(0, self.TREE_DATA_ROLE)
362
                    #        if child.owner is eqpSymbol:
363
                    #            item = QTreeWidgetItem(eqpTreeItem, [child.name])
364
                    #            item.setData(0, self.TREE_DATA_ROLE, child)
365
                    #            break
366
                        
367
                        if item is None:
368
                            item = QTreeWidgetItem(self.SymbolsTreeItem, [child.name])
369
                    elif child.type == 'Notes':
370
                        return item
371
                    else:
372
                        item = QTreeWidgetItem(self.SymbolsTreeItem, [child.name])
373
                    
374
                    if item is not None:
375
                        iconPath = os.path.join(AppDocData.instance().getCurrentProject().getSvgFilePath(), child.type , child.name + ".svg")
376
                        item.setIcon(0, QIcon(iconPath))
377
                        item.setData(0, self.TREE_DATA_ROLE, child)
378
                        brush = QBrush()
379
                        brush.setColor(QColor(child.getColor()))
380
                        item.setForeground(0, brush)
381
                        item.setFont(0, item.font(0))
382
                        child.treeItem = item
383
                        if isEquipmentType:
384
                            self.EqpTreeItem.addChild(item)
385
                            self.EqpTreeItem.sortChildren(0, Qt.AscendingOrder)  # sort childrens
386
                        else:
387
                            self.SymbolsTreeItem.addChild(item)
388
                            self.SymbolsTreeItem.sortChildren(0, Qt.AscendingOrder)  # sort childrens
389
                elif type(child) is QEngineeringLineNoTextItem:
390
                    for index in range(self.LineNoTreeItem.childCount()):
391
                        if child.text() == self.LineNoTreeItem.child(0).text(index) and self.LineNoTreeItem.child(0).childCount() is 0:
392
                            self.LineNoTreeItem.takeChild(index)
393
                            break
394
                    item = CustomTreeWidgetItem([child.text()])
395
                    item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
396
                    item.setData(0, self.TREE_DATA_ROLE, child)
397
                    item.setCheckState(0, Qt.Checked if child.isVisible() else Qt.Unchecked)
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
                    self.LineNoTreeItem.addChild(item)
404
                    self.LineNoTreeItem.sortChildren(0, Qt.AscendingOrder)  # sort line nos
405
                elif type(child) is QEngineeringTrimLineNoTextItem:
406
                    item = CustomTreeWidgetItem(['Unknown Line'])
407
                    item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
408
                    item.setData(0, self.TREE_DATA_ROLE, child)
409
                    item.setCheckState(0, Qt.Checked if child.isVisible() else Qt.Unchecked)
410
                    brush = QBrush()
411
                    brush.setColor(QColor(child.getColor()))
412
                    item.setForeground(0, brush)
413
                    item.setFont(0, item.font(0))
414
                    child.treeItem = item
415
                    self.LineNoTreeItem.addChild(item)
416
                elif (type(child) is QEngineeringNoteItem):
417
                    founds = None
418
                    for i in range(self.NotesTreeItem.childCount()):
419
                        item = self.NotesTreeItem.child(i)
420
                        notes = item.data(0, self.TREE_DATA_ROLE)
421
                        founds = [note for note in notes if note.text() == child.text()]
422
                        if founds: break
423

    
424
                    if founds:
425
                        item.setData(0, self.TREE_DATA_ROLE, founds + [child, ])
426
                    else:
427
                        item = QTreeWidgetItem([child.text()])
428
                        item.setData(0, self.TREE_DATA_ROLE, [child, ])
429
                        if parent is not None:
430
                            parent.addChild(item)
431
                            parent.sortChildren(0, Qt.AscendingOrder)  # sort childrens
432
                    child.treeItem = item
433
                    item.setText(0, '{}({})'.format(child.text(), len(item.data(0, self.TREE_DATA_ROLE))))
434

    
435
                    # show note icon if note icon is setted
436
                    if child.symbol:
437
                        iconPath = os.path.join(appDocData.getCurrentProject().getSvgFilePath(), 'Notes' , child.symbol.name + '.svg')
438
                        item.setIcon(0, QIcon(iconPath))
439
                elif (type(child) is QEngineeringUnknownItem):
440
                    item = QTreeWidgetItem(['Unknown'])
441
                    item.setData(0, self.TREE_DATA_ROLE, child)
442
                    child.treeItem = item
443
                    self.UnknownTreeItem.addChild(item)
444
                    if child.lineIndicator == 'Match':
445
                        item.setHidden(True)
446
            elif issubclass(type(child), SymbolSvgItem):  # change item's parent
447
                foundItems = self.findItems(child.name, Qt.MatchExactly|Qt.MatchRecursive, 0)
448
                if foundItems is not None:
449
                    for item in foundItems:
450
                        data = item.data(0, self.TREE_DATA_ROLE)
451
                        if data is not None and (data == child) and (parent is not item.parent()):
452
                            parentData = parent.data(0, self.TREE_DATA_ROLE)
453
                            if parentData is not None and issubclass(type(parentData), QEngineeringLineNoTextItem):
454
                                for index in range(len(parentData.runs)):
455
                                    runGroup = parentData.runs[index]
456
                                    if data in runGroup.items:
457
                                        item.parent().removeChild(item) # remove item from original parent
458
                                        runItem = self.addPipeRunTreeItemIfNeed(parent, runGroup) #parent.child(index)
459
                                        brush = QBrush()
460
                                        brush.setColor(QColor(item.data(0, self.TREE_DATA_ROLE).getColor()))
461
                                        item.setForeground(0, brush)
462
                                        #item.data(0, self.TREE_DATA_ROLE).setColor(brush.color().name())
463
                                        item.setFont(0, item.font(0))
464
                                        runItem.addChild(item)
465
                                        break
466
                                    else:
467
                                        pass
468
                            elif parent is not None:
469
                                item.parent().removeChild(item) # remove item from original parent
470
                                parent.addChild(item)
471
                            break
472
            elif type(child) is QEngineeringLineNoTextItem:
473
                foundItems = self.findItems(child.text(), Qt.MatchExactly|Qt.MatchRecursive, 0)
474
                if foundItems is not None:
475
                    for item in foundItems:
476
                        data = item.data(0, self.TREE_DATA_ROLE)
477
                        if data is not None and (data == child):
478
                            connectedItems = data.getConnectedItems()
479
                            color = data.getColor()
480
                            for connectedItem in connectedItems:
481
                                connectedItem.setColor(color)
482
                            return item
483
        except Exception as ex:
484
            from App import App
485
            from AppDocData import MessageType
486

    
487
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
488
            App.mainWnd().addMessage.emit(MessageType.Error, message)
489

    
490
        return item
491

    
492
    '''
493
        @brief      Scene Changed Listener
494
        @author     Jeongwoo
495
        @date       18.04.11
496
        @history    Jeongwoo 2018.04.25 Add QEngineeringNoteItem to list for loop  / NOT QEngineeringTextItem
497
                    Jeongwoo 2018.04.26 Change changedSceneItems conditions in loop (QEngineeringTextItem → QEngineeringLineNoTextItem)
498
                    humkyung 2018.07.20 put items which's owner is None before item which's owner is not None
499
    '''
500
    lastSceneItems = None
501
    def sceneChanged(self, sceneItems):
502
        try:
503
            changedSceneItems = [item for item in sceneItems if ((issubclass(type(item), SymbolSvgItem) and type(item) is not QEngineeringErrorItem and type(item) is not QEngineeringEndBreakItem) or (type(item) is QEngineeringNoteItem) or (type(item) is QEngineeringLineNoTextItem) 
504
                                or (type(item) is QEngineeringUnknownItem)) and (not hasattr(item, 'treeItem') or item.treeItem is None)] # Sublist includes SymbolSvgItem
505
            first = [item for item in changedSceneItems if item.owner is None]
506
            second = [item for item in changedSceneItems if item.owner is not None]
507
            if first + second: self.initResultTreeWidget(first + second)
508
        finally:
509
            self.update_item_count()
510

    
511
    '''
512
        @brief      Initialize TreeWidget
513
                    Tree Item Clear and Add Item
514
        @author     Jeongwoo
515
        @date       2018.04.11
516
        @history    2018.04.12 Jeongwoo    Declare self.TREE_DATA_ROLE for QTreeWidgetItem.data(column, role)
517
        @history    2018.04.17 humkyung NOT remove child of root
518
                    2018.04.25 Jeongwoo     Add QEngineeringNoteItem Child
519
                    2018.04.26 Jeongwoo     Change method to insert child
520
    '''
521
    def initResultTreeWidget(self, items):
522
        for item in items:
523
            if (type(item) is QEngineeringNoteItem):
524
                self.addTreeItem(self.NotesTreeItem, item)
525
            else:
526
                self.addTreeItem(self.root, item)
527
                    
528
        if self.NotesTreeItem is not None:
529
            self.NotesTreeItem.sortChildren(0, Qt.AscendingOrder)
530

    
531
        self.expandAll()
532
        
533
    def itemCheckBoxToggled(self, item, checkState):
534
        """
535
        set visible of invisible of item
536
        """
537
        try:
538
            itemData = item.data(0, self.TREE_DATA_ROLE)   
539
            if (type(itemData) is QEngineeringLineNoTextItem) or (type(itemData) is QEngineeringTrimLineNoTextItem):
540
                itemData.setVisible(checkState == Qt.CheckState.Checked)
541
        except Exception as ex:
542
            from App import App
543
            from AppDocData import MessageType
544

    
545
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
546
            App.mainWnd().addMessage.emit(MessageType.Error, message)
547
        finally:
548
            pass
549

    
550
    '''
551
        @brief      TreeWidget Item click listener
552
        @author     Jeongwoo
553
        @date       18.04.11
554
        @history    18.04.12    Jeongwoo    Declare self.TREE_DATA_ROLE for QTreeWidgetItem.data(column, role)
555
                    18.04.13    Jeongwoo    Signal 'singleClicked' emit SymbolSvgItem
556
                                            CenterOn() with Symbol's center
557
                    18.04.25    Jeongwoo    Add QEngineeringNoteItem Click event
558
                    18.04.26    Jeongwoo    QEngineeringTextItem → QEngineeringLineNoTextItem
559
                    18.04.27    Jeongwoo    Find NOTE Contents when NOTE No. Clicked
560
                                            Move singClicked to if-statement type(itemData) is SymbolSvgItem:
561
                    18.05.10    Jeongwoo    Add lineNoSingleClicked emit
562
                    humkyung 2018.07.07 emit singleClicked signal when user click drawing name
563
    '''
564
    def itemClickEvent(self, item, columnNo, isSvgClick = False):
565
        from Drawing import Drawing
566
        from EngineeringRunItem import QEngineeringRunItem
567
        from HighlightCommand import HighlightCommand
568

    
569
        hilightColor = QColor(255, 0, 0, 127)
570

    
571
        itemData = item.data(0, self.TREE_DATA_ROLE)
572
        
573
        if itemData is not None: ## Not PID Name
574
            if issubclass(type(itemData), SymbolSvgItem):
575
                HighlightCommand(self.imageViewer).execute(itemData)
576
                ## Draw rectangle on selected symbol
577
                #rect = itemData.sceneBoundingRect()
578
                #if isSvgClick == False:
579
                #    self.imageViewer.centerOn(rect.center())
580
                ## Send new event to imageViewer's zoomImage Method
581
                #self.imageViewer.zoomImage(True, QMouseEvent(QEvent.MouseButtonPress, self.imageViewer.mapFromScene(QPointF(rect.left(), rect.top())), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier), 3)
582

    
583
                self.singleClicked.emit(itemData)
584
            elif (type(itemData) is QEngineeringLineNoTextItem) or (type(itemData) is QEngineeringRunItem):
585
                HighlightCommand(self.imageViewer).execute(itemData)
586
                self.lineNoSingleClicked.emit(itemData)
587
                for child in range(item.childCount()):
588
                    item.child(child).setSelected(True)
589
            elif type(itemData) is list and type(itemData[0]) is QEngineeringNoteItem:
590
                HighlightCommand(self.imageViewer).execute(itemData)
591
                '''
592
                rect = itemData.sceneBoundingRect()
593
                if isSvgClick == False:
594
                    self.imageViewer.centerOn(rect.center())
595
                ## Send new event to imageViewer's zoomImage Method
596
                self.imageViewer.zoomImage(True, QMouseEvent(QEvent.MouseButtonPress, self.imageViewer.mapFromScene(QPointF(rect.left(), rect.top())), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier), 3)
597
                '''
598
                noteContentsList = itemData[0].findNoteContents(itemData[0].text())
599

    
600
                self.noteNoSingleClicked.emit(itemData[0].text(), noteContentsList)
601
            elif type(itemData) is QEngineeringUnknownItem:
602
                HighlightCommand(self.imageViewer).execute(itemData)
603
            elif type(itemData) is Drawing:
604
                self.drawingClicked.emit(itemData)
605
                
606
            '''
607
            if issubclass(type(itemData), QGraphicsItem):
608
                itemData.setSelected(True)
609
                itemData.update()
610
            '''
611

    
612
    '''
613
        @brief  find item which has data is given item
614
        @author humkyung
615
        @date   2018.04.23
616
        @history    2018.06.18  Jeongwoo    Add if-statement for QEngineeringUnknownItem
617
        @history    2018.11.22  euisung     add delete note
618
    '''
619
    def findItemByData(self, item):
620
        if issubclass(type(item), SymbolSvgItem):
621
            foundItems = self.findItems(item.name, Qt.MatchExactly|Qt.MatchRecursive, 0)
622
            for foundItem in foundItems:
623
                data = foundItem.data(0, self.TREE_DATA_ROLE)
624
                if data is not None and data is item:
625
                    return foundItem
626
        elif type(item) is QEngineeringLineNoTextItem:
627
            foundItems = self.findItems(item.text() , Qt.MatchExactly|Qt.MatchRecursive, 0)
628
            for foundItem in foundItems:
629
                data = foundItem.data(0, self.TREE_DATA_ROLE)
630
                if data is not None and data is item:
631
                    return foundItem
632
        elif type(item) is QEngineeringUnknownItem:
633
            foundItems = self.findItems('Unknown' , Qt.MatchExactly|Qt.MatchRecursive, 0)
634
            for foundItem in foundItems:
635
                data = foundItem.data(0, self.TREE_DATA_ROLE)
636
                if data is not None and data is item:
637
                    return foundItem
638
        elif type(item) is QEngineeringNoteItem:
639
            foundItems = self.findItems(item.text() , Qt.MatchExactly|Qt.MatchRecursive, 0)
640
            for foundItem in foundItems:
641
                data = foundItem.data(0, self.TREE_DATA_ROLE)
642
                if data is not None and data is item:
643
                    return foundItem
644
        elif type(item) is QEngineeringTrimLineNoTextItem:
645
            foundItems = self.findItems('Unknown Line', Qt.MatchExactly|Qt.MatchRecursive, 0)
646
            for foundItem in foundItems:
647
                data = foundItem.data(0, self.TREE_DATA_ROLE)
648
                if data is not None and data is item:
649
                    return foundItem
650
        
651
        return None
652

    
653
    '''
654
        @brief  Init LineNoItems child
655
        @author kyouho
656
        @date   2018.09.17
657
    '''
658
    def InitLineNoItems(self):
659
        try: 
660
            removeLineItem = []
661
            for lineIndex in range(self.LineNoTreeItem.childCount()):
662
                ## LineNoItem, TrimLine Item
663
                lineItem = self.LineNoTreeItem.child(lineIndex)
664

    
665
                removeRunItem = []
666
                for runIndex in range(lineItem.childCount()):
667
                    ## RUN Item
668
                    runItem = lineItem.child(runIndex)
669
                    for symbolIndex in range(runItem.childCount()):
670
                        symbolItem = runItem.child(0)
671
                        symbol = symbolItem.data(0, self.TREE_DATA_ROLE)
672

    
673
                        symbolItem.parent().removeChild(symbolItem)
674

    
675
                        if AppDocData.instance().isEquipmentType(symbol.type):
676
                            self.EqpTreeItem.addChild(symbolItem)
677
                        else:
678
                            self.SymbolsTreeItem.addChild(symbolItem)
679

    
680
                    ## 지울 Item 모음
681
                    removeRunItem.append(runItem)
682
                ## Run Item들 삭제
683
                for removeItem in removeRunItem:
684
                    lineItem.removeChild(removeItem)
685
                ## 지울 Trim Line 모음
686
                if lineItem.text(0) == 'Trim Line':
687
                    removeLineItem.append(lineItem)
688
            ## Trim Line들 삭제
689
            for removeItem in removeLineItem:
690
                self.LineNoTreeItem.removeChild(removeItem)
691

    
692
        except Exception as ex:
693
            from App import App
694
            from AppDocData import MessageType
695

    
696
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
697
            App.mainWnd().addMessage.emit(MessageType.Error, message)
698

    
699
    '''
700
        @brief      Find QTreeWidgetItem by SymbolSvgItem object
701
        @author     Jeongwoo
702
        @date       18.04.11
703
        @history    18.04.12    Jeongwoo    Change Flags (Qt.MatchExactly → Qt.MatchExactly|Qt.MatchRecursive)
704
                                            Declare self.TREE_DATA_ROLE for QTreeWidgetItem.data(column, role)
705
        @history    2018.11.22  euisung     add note, unknown
706
    '''
707
    @pyqtSlot(SymbolSvgItem)
708
    def findItem(self, item):
709
        if issubclass(type(item), SymbolSvgItem):
710
            foundItems = self.findItems(item.name, Qt.MatchExactly|Qt.MatchRecursive, 0)
711
            if foundItems is not None:
712
                for fItem in foundItems:
713
                    data = fItem.data(0, self.TREE_DATA_ROLE)
714
                    if data is not None and data == item:
715
                        self.setCurrentItem(fItem)
716
                        return
717
        elif type(item) is QEngineeringLineNoTextItem:
718
            foundItems = self.findItems(item.text(), Qt.MatchExactly|Qt.MatchRecursive, 0)
719
            if foundItems is not None:
720
                for fItem in foundItems:
721
                    data = fItem.data(0, self.TREE_DATA_ROLE)
722
                    if data is not None and data == item:
723
                        self.setCurrentItem(fItem)
724
                        return
725
        elif type(item) is QEngineeringNoteItem:
726
            founds = None
727
            for i in range(self.NotesTreeItem.childCount()):
728
                child = self.NotesTreeItem.child(i)
729
                notes = child.data(0, self.TREE_DATA_ROLE)
730
                founds = [note for note in notes if note.text() == item.text()]
731
                if founds:
732
                    self.setCurrentItem(child)
733
                    return
734
        elif type(item) is QEngineeringUnknownItem:
735
            foundItems = self.findItems('Unknown', Qt.MatchExactly|Qt.MatchRecursive, 0)
736
            if foundItems is not None:
737
                for fItem in foundItems:
738
                    data = fItem.data(0, self.TREE_DATA_ROLE)
739
                    if data is not None and data == item:
740
                        self.setCurrentItem(fItem)
741
                        return
742
        elif type(item) is QEngineeringTrimLineNoTextItem:
743
            foundItems = self.findItems('Unknown Line', Qt.MatchExactly|Qt.MatchRecursive, 0)
744
            if foundItems is not None:
745
                for fItem in foundItems:
746
                    data = fItem.data(0, self.TREE_DATA_ROLE)
747
                    if data is not None and data == item:
748
                        self.setCurrentItem(fItem)
749
                        return
750

    
751
        ## Not found
752
        QMessageBox.warning(self, self.tr('Error'), self.tr('Can not find data for the selected symbol.'))
753
    
754
    '''
755
        @brief      remove given item
756
        @author     humkyung
757
        @date       2018.04.23
758
        @history    Jeongwoo 2018.05.25 Remove Highlighting when item removed
759
                    humkyung 2018.07.22 removed code to Remove highlighting
760
    '''
761
    @pyqtSlot(QGraphicsItem)
762
    def itemRemoved(self, item):
763
        try:
764
            foundItem = self.findItemByData(item)
765
            if foundItem is not None:
766
                foundItem.parent().removeChild(foundItem)
767
        finally:
768
            self.update_item_count()
769

    
770
    def update_item_count(self):
771
        """
772
        update items count
773
        """
774
        if hasattr(self, 'LineNoTreeItem'):
775
            self.LineNoTreeItem.setText(0, 'LINE NO({})'.format(self.LineNoTreeItem.childCount()))
776
        if hasattr(self, 'EqpTreeItem'):
777
            self.EqpTreeItem.setText(0, 'EQUIPMENTS({})'.format(self.EqpTreeItem.childCount()))
778
        if hasattr(self, 'SymbolsTreeItem'):
779
            self.SymbolsTreeItem.setText(0, 'SYMBOLS({})'.format(self.SymbolsTreeItem.childCount()))
780
        if hasattr(self, 'NotesTreeItem'):
781
            self.NotesTreeItem.setText(0, 'NOTES({})'.format(self.NotesTreeItem.childCount()))
782
        if hasattr(self, 'UnknownTreeItem'):
783
            self.UnknownTreeItem.setText(0, 'UNKNOWN({})'.format(self.UnknownTreeItem.childCount()))
클립보드 이미지 추가 (최대 크기: 500 MB)