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())) |