개정판 a9773437
issue #637: add spec break auto creating function
Change-Id: I853e9b09e7982c131e7907bd0378ac1dd72dcc63
DTI_PID/DTI_PID/Commands/ValidateCommand.py | ||
---|---|---|
36 | 36 |
if type(item) is QEngineeringLineItem or issubclass(type(item), SymbolSvgItem): |
37 | 37 |
errors.extend(item.validate()) |
38 | 38 |
|
39 |
# check line no spec change |
|
40 |
appDocData = AppDocData.instance() |
|
41 |
specBreakAttrs = [attr.Attribute for attr in appDocData.getSymbolAttribute('Segment Breaks') if attr.Target == 'ALL' and attr.AttributeType == 'Spec'] |
|
42 |
dataPath = appDocData.getErrorItemSvgPath() |
|
43 |
#lineProps = appDocData.getLineProperties() |
|
44 |
|
|
45 |
line_ends = [] |
|
46 |
for lineNo in [lineNo for lineNo in param if type(lineNo) is QEngineeringLineNoTextItem]: |
|
47 |
#line_ends.append(lineNo.prop('From')) if lineNo.prop('From') is not None else None |
|
48 |
#line_ends.append(lineNo.prop('To')) if lineNo.prop('To') is not None else None |
|
49 |
for run in lineNo.runs: |
|
50 |
line_ends.append(run.items[0]) if issubclass(type(run.items[0]), SymbolSvgItem) or (type(run.items[0]) is QEngineeringLineItem and (run.items[0].lineType == 'Secondary' or run.items[0].lineType == 'Primary')) else None |
|
51 |
if run.items[0] is not run.items[-1]: |
|
52 |
line_ends.append(run.items[-1]) if issubclass(type(run.items[-1]), SymbolSvgItem) or (type(run.items[-1]) is QEngineeringLineItem and (run.items[-1].lineType == 'Secondary' or run.items[-1].lineType == 'Primary')) else None |
|
53 |
|
|
54 |
spec_break = [] |
|
55 |
for line_end in line_ends: |
|
56 |
for connector in line_end.connectors: |
|
57 |
if connector.connectedItem is not None and type(connector.connectedItem.owner) is QEngineeringLineNoTextItem and connector.connectedItem.owner is not line_end.owner: |
|
58 |
for prop, value in [[prop, value] for prop, value in line_end.owner.getAttributes().items() if prop.Attribute in specBreakAttrs]: |
|
59 |
done = False |
|
60 |
for prop2, value2 in [[prop2, value2] for prop2, value2 in connector.connectedItem.owner.getAttributes().items() if prop2.Attribute in specBreakAttrs]: |
|
61 |
if str(prop.UID) == str(prop2.UID) and value != value2: |
|
62 |
spec_break.append([line_end, connector.connectedItem]) |
|
63 |
done = True |
|
64 |
break |
|
65 |
if done: |
|
66 |
break |
|
67 |
|
|
68 |
if spec_break: |
|
69 |
# check dulplication |
|
70 |
dupl = set() |
|
71 |
for i in range(len(spec_break)): |
|
72 |
for j in range(len(spec_break)): |
|
73 |
if i == j: continue |
|
74 |
else: |
|
75 |
setI = set(spec_break[i]) |
|
76 |
setJ = set(spec_break[j]) |
|
77 |
if not (setI - setJ): |
|
78 |
index = [i, j] |
|
79 |
index.sort() |
|
80 |
index = tuple(index) |
|
81 |
dupl.add(index) |
|
82 |
dupl = list(set([(indexSet[1]) for indexSet in list(dupl)])) |
|
83 |
dupl.sort(reverse=True) |
|
84 |
for index in dupl: |
|
85 |
spec_break.pop(index) |
|
86 |
|
|
87 |
for spec in spec_break: |
|
88 |
for connector in spec[0].connectors: |
|
89 |
if connector.connectedItem is spec[1]: |
|
90 |
error = SymbolSvgItem.createItem('Error', dataPath) |
|
91 |
error.setPosition(connector.center()) |
|
92 |
error.parent = self |
|
93 |
error.msg = _translate('may need spec break', 'may need spec break') |
|
94 |
error.setToolTip(error.msg) |
|
95 |
error.area = 'Drawing' |
|
96 |
error.name = 'Error' |
|
97 |
errors.append(error) |
|
98 |
|
|
99 | 39 |
finally: |
100 | 40 |
QApplication.restoreOverrideCursor() |
101 | 41 |
|
DTI_PID/DTI_PID/ConnectAttrDialog.py | ||
---|---|---|
31 | 31 |
displayMessage = pyqtSignal(str) |
32 | 32 |
updateProgress = pyqtSignal(int) |
33 | 33 |
|
34 |
def __init__(self, graphicsView, update_line_type, update_flow_mark): |
|
34 |
def __init__(self, graphicsView, update_line_type, update_flow_mark, update_spec):
|
|
35 | 35 |
QThread.__init__(self) |
36 | 36 |
self.graphicsView = graphicsView |
37 | 37 |
self._update_line_type = update_line_type |
38 | 38 |
self._update_flow_mark = update_flow_mark |
39 |
self._update_spec = update_spec |
|
39 | 40 |
|
40 | 41 |
''' |
41 | 42 |
@brief execute connecting attributes |
... | ... | |
46 | 47 |
from LineNoTracer import connectAttrImpl |
47 | 48 |
|
48 | 49 |
try: |
49 |
connectAttrImpl(self, self._update_line_type, self._update_flow_mark) |
|
50 |
connectAttrImpl(self, self._update_line_type, self._update_flow_mark, self._update_spec)
|
|
50 | 51 |
except Exception as ex: |
51 | 52 |
from App import App |
52 | 53 |
message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
... | ... | |
126 | 127 |
self.ui.buttonBox.setDisabled(True) |
127 | 128 |
|
128 | 129 |
# 1 - create Worker and Thread inside the Form |
129 |
self.obj = Worker(self.graphicsView, self.ui.checkBoxUpdateLineType.isChecked(), self.ui.checkBoxUpdateFlowMark.isChecked()) |
|
130 |
self.obj = Worker(self.graphicsView, self.ui.checkBoxUpdateLineType.isChecked(), self.ui.checkBoxUpdateFlowMark.isChecked(), self.ui.checkBoxUpdateSpec.isChecked())
|
|
130 | 131 |
|
131 | 132 |
# 2 - Connect Worker Signals to the Thread slots |
132 | 133 |
self.obj.displayMessage.connect(self.addListItem) |
DTI_PID/DTI_PID/ConnectAttr_UI.py | ||
---|---|---|
47 | 47 |
self.checkBoxUpdateFlowMark = QtWidgets.QCheckBox(ConnectAttr) |
48 | 48 |
self.checkBoxUpdateFlowMark.setObjectName("checkBoxUpdateFlowMark") |
49 | 49 |
self.horizontalLayout_2.addWidget(self.checkBoxUpdateFlowMark) |
50 |
self.checkBoxUpdateSpec = QtWidgets.QCheckBox(ConnectAttr) |
|
51 |
self.checkBoxUpdateSpec.setObjectName("checkBoxUpdateSpec") |
|
52 |
self.horizontalLayout_2.addWidget(self.checkBoxUpdateSpec) |
|
50 | 53 |
self.checkBoxUpdateLineType = QtWidgets.QCheckBox(ConnectAttr) |
51 | 54 |
self.checkBoxUpdateLineType.setObjectName("checkBoxUpdateLineType") |
52 | 55 |
self.horizontalLayout_2.addWidget(self.checkBoxUpdateLineType) |
... | ... | |
72 | 75 |
ConnectAttr.setWindowTitle(_translate("ConnectAttr", "Connect Attribute")) |
73 | 76 |
self.checkBoxValidation.setText(_translate("ConnectAttr", "Close with Validation Check")) |
74 | 77 |
self.checkBoxUpdateFlowMark.setText(_translate("ConnectAttr", "Update Flow Mark")) |
78 |
self.checkBoxUpdateSpec.setText(_translate("ConnectAttr", "Update Segment Break")) |
|
75 | 79 |
self.checkBoxUpdateLineType.setText(_translate("ConnectAttr", "Update Line Type")) |
76 | 80 |
self.pushButtonStart.setText(_translate("ConnectAttr", "Start")) |
77 | 81 |
|
DTI_PID/DTI_PID/LineNoTracer.py | ||
---|---|---|
358 | 358 |
@history humkyung 2018.06.21 paste connect attributes codes from recognizeLine function |
359 | 359 |
kyouho 2018.09.14 clear Item's owner |
360 | 360 |
''' |
361 |
def connectAttrImpl(worker, update_line_type, update_flow_mark): |
|
361 |
def connectAttrImpl(worker, update_line_type, update_flow_mark, update_spec):
|
|
362 | 362 |
import os, math |
363 | 363 |
from App import App |
364 | 364 |
import uuid |
... | ... | |
388 | 388 |
symbols = [] |
389 | 389 |
lines = [] |
390 | 390 |
lineNos = [] |
391 |
specBreak = []
|
|
391 |
spec_breaks = []
|
|
392 | 392 |
lineIndicator = [] |
393 | 393 |
vendor_packages = [item for item in worker.graphicsView.scene.items() if type(item) is QEngineeringVendorItem] |
394 | 394 |
end_breaks = [] |
395 | 395 |
notes = [] |
396 |
#flow_marks = []
|
|
396 |
flow_marks = [] |
|
397 | 397 |
|
398 | 398 |
for error_item in [item for item in worker.graphicsView.scene.items() if type(item) is QEngineeringErrorItem]: |
399 | 399 |
error_item.transfer.onRemoved.emit(error_item) |
... | ... | |
416 | 416 |
vendorTag = configs[0].value if configs else 'By Vendor' |
417 | 417 |
for item in worker.graphicsView.scene.items(): |
418 | 418 |
if type(item) is QEngineeringSpecBreakItem: |
419 |
specBreak.append(item)
|
|
419 |
spec_breaks.append(item)
|
|
420 | 420 |
elif issubclass(type(item), SymbolSvgItem) and not (type(item) is QEngineeringErrorItem) and not (type(item) is QEngineeringUnknownItem) and item.type != 'Notes': |
421 | 421 |
matches = [vendor_package for vendor_package in vendor_packages if vendor_package.includes(item)] |
422 | 422 |
if matches: |
... | ... | |
451 | 451 |
pass |
452 | 452 |
|
453 | 453 |
# trace line no |
454 |
tracer = LineNoTracer(symbols, lines, lineNos, specBreak, lineIndicator, vendor_packages, end_breaks)
|
|
454 |
tracer = LineNoTracer(symbols, lines, lineNos, spec_breaks, lineIndicator, vendor_packages, end_breaks)
|
|
455 | 455 |
tracer.execute(worker.displayMessage, worker.updateProgress) |
456 | 456 |
# up to here |
457 | 457 |
|
... | ... | |
555 | 555 |
end_breaks.append(end_break) |
556 | 556 |
|
557 | 557 |
if end_breaks: |
558 |
# check dulplication
|
|
558 |
# check duplication |
|
559 | 559 |
dupl = set() |
560 | 560 |
for i in range(len(end_breaks)): |
561 | 561 |
for j in range(len(end_breaks)): |
... | ... | |
582 | 582 |
if (type(end_break.owner) is not QEngineeringLineItem or (type(end_break.owner) is QEngineeringLineItem and (end_break.owner.lineType == 'Secondary' or end_break.owner.lineType == 'Primary'))) \ |
583 | 583 |
and (type(end_break.prop('Connected Item')) is not QEngineeringLineItem or (type(end_break.prop('Connected Item')) is QEngineeringLineItem and (end_break.prop('Connected Item').lineType == 'Secondary' or end_break.prop('Connected Item').lineType == 'Primary'))): |
584 | 584 |
end_break.addSvgItemToScene(worker.graphicsView.scene) |
585 |
|
|
585 |
|
|
586 |
""" update spec break """ |
|
587 |
if update_spec: |
|
588 |
for spec_break in spec_breaks: |
|
589 |
spec_break.transfer.onRemoved.emit(spec_break) |
|
590 |
|
|
591 |
spec_break_names = docdata.getSymbolListByType('type', 'Segment Breaks') |
|
592 |
if len(spec_break_names) is not 0: |
|
593 |
svgFileName = spec_break_names[0].sName |
|
594 |
symbol = docdata.getSymbolByQuery('name', svgFileName) |
|
595 |
svgFilePath = os.path.join(docdata.getCurrentProject().getSvgFilePath(), symbol.getType(), svgFileName + '.svg') |
|
596 |
|
|
597 |
specBreakAttrsFull = [attr for attr in docdata.getSymbolAttribute('Segment Breaks') if attr.Target == 'ALL' and attr.AttributeType == 'Spec'] |
|
598 |
specBreakAttrs = [attr.Attribute for attr in specBreakAttrsFull] |
|
599 |
|
|
600 |
line_ends = [] |
|
601 |
# append upstream first and append downstream |
|
602 |
for lineNo in lineNos: |
|
603 |
for run in lineNo.runs: |
|
604 |
line_ends.append(run.items[0]) if issubclass(type(run.items[0]), SymbolSvgItem) or (type(run.items[0]) is QEngineeringLineItem and (run.items[0].lineType == 'Secondary' or run.items[0].lineType == 'Primary')) else None |
|
605 |
for lineNo in lineNos: |
|
606 |
for run in lineNo.runs: |
|
607 |
if run.items[0] is not run.items[-1]: |
|
608 |
line_ends.append(run.items[-1]) if issubclass(type(run.items[-1]), SymbolSvgItem) or (type(run.items[-1]) is QEngineeringLineItem and (run.items[-1].lineType == 'Secondary' or run.items[-1].lineType == 'Primary')) else None |
|
609 |
|
|
610 |
spec_breaks = [] |
|
611 |
for line_end in line_ends: |
|
612 |
for connector in line_end.connectors: |
|
613 |
if connector.connectedItem is not None and type(connector.connectedItem.owner) is QEngineeringLineNoTextItem and connector.connectedItem.owner is not line_end.owner: |
|
614 |
spec_break = [] # upstream, downstream, [spec, up value, down value], ... , [ ... ] |
|
615 |
match = False |
|
616 |
for prop, value in [[prop, value] for prop, value in line_end.owner.getAttributes().items() if prop.Attribute in specBreakAttrs]: |
|
617 |
for prop2, value2 in [[prop2, value2] for prop2, value2 in connector.connectedItem.owner.getAttributes().items() if prop2.Attribute in specBreakAttrs and prop2.UID == prop.UID]: |
|
618 |
if str(prop.UID) == str(prop2.UID) and value != value2: |
|
619 |
if not match: |
|
620 |
spec_break.extend([line_end, connector.connectedItem]) |
|
621 |
match = True |
|
622 |
spec_break.append([prop.Attribute, value, value2]) |
|
623 |
if match: |
|
624 |
spec_breaks.append(spec_break) |
|
625 |
|
|
626 |
if spec_breaks: |
|
627 |
# check duplication |
|
628 |
dupl = set() |
|
629 |
for i in range(len(spec_breaks)): |
|
630 |
for j in range(len(spec_breaks)): |
|
631 |
if i == j: |
|
632 |
continue |
|
633 |
else: |
|
634 |
setI = set([spec_breaks[i][0], spec_breaks[i][1]]) |
|
635 |
setJ = set([spec_breaks[j][0], spec_breaks[j][1]]) |
|
636 |
if not (setI - setJ): |
|
637 |
index = [i, j] |
|
638 |
index.sort() |
|
639 |
index = tuple(index) |
|
640 |
dupl.add(index) |
|
641 |
dupl = list(set([(indexSet[1]) for indexSet in list(dupl)])) |
|
642 |
dupl.sort(reverse=True) |
|
643 |
for index in dupl: |
|
644 |
spec_breaks.pop(index) |
|
645 |
|
|
646 |
|
|
647 |
spec_break_items = [] |
|
648 |
for spec in spec_breaks: |
|
649 |
for connector in spec[0].connectors: |
|
650 |
if connector.connectedItem is spec[1]: |
|
651 |
spec_break = SymbolSvgItem.createItem(symbol.getType(), svgFilePath) |
|
652 |
pt = [connector.center()[0] - float(symbol.getOriginalPoint().split(',')[0]), connector.center()[1] - float(symbol.getOriginalPoint().split(',')[1])] |
|
653 |
origin = [0, 0] |
|
654 |
if 2 == len(symbol.getOriginalPoint().split(',')): |
|
655 |
tokens = symbol.getOriginalPoint().split(',') |
|
656 |
origin = [pt[0] + float(tokens[0]), pt[1] + float(tokens[1])] |
|
657 |
spec_break.buildItem(svgFileName, symbol.getType(), 0.0, pt, [spec_break.boundingRect().width(), spec_break.boundingRect().height()], origin, [], symbol.getBaseSymbol(), symbol.getAdditionalSymbol(), symbol.getHasInstrumentLabel()) |
|
658 |
|
|
659 |
attrs = spec_break.getAttributes() |
|
660 |
for key in attrs.keys(): |
|
661 |
if key.Attribute == 'UpStream': |
|
662 |
attrs[key] = spec[0] |
|
663 |
elif key.Attribute == 'DownStream': |
|
664 |
attrs[key] = spec[1] |
|
665 |
|
|
666 |
for attr, value, value2 in spec[2:]: |
|
667 |
for full in specBreakAttrsFull: |
|
668 |
if full.Attribute == attr: |
|
669 |
attrs[full] = [value, value2] |
|
670 |
|
|
671 |
spec_break_items.append(spec_break) |
|
672 |
|
|
673 |
for spec_break_item in spec_break_items: |
|
674 |
spec_break_item.transfer.onRemoved.connect(App.mainWnd().itemRemoved) |
|
675 |
spec_break_item.addSvgItemToScene(worker.graphicsView.scene) |
|
676 |
|
|
586 | 677 |
"""make flow mark""" |
587 | 678 |
if update_flow_mark: |
588 | 679 |
for line in lines: |
DTI_PID/DTI_PID/SpecBreakDialog.py | ||
---|---|---|
188 | 188 |
attrs = AppDocData.instance().getSymbolAttribute('Segment Breaks') |
189 | 189 |
for attr in attrs: |
190 | 190 |
if attr.DisplayAttribute == self.ui.tableWidgetSpec.cellWidget(row, 0).currentText(): |
191 |
attr.AttributeType = 'Spec' |
|
192 |
attr.DisplayAttribute = 'Spec' |
|
193 | 191 |
up = self.ui.tableWidgetSpec.cellWidget(row, 1).currentText() if self.ui.tableWidgetSpec.cellWidget(row, 1) else self.ui.tableWidgetSpec.item(row, 1).text() |
194 | 192 |
down = self.ui.tableWidgetSpec.cellWidget(row, 2).currentText() if self.ui.tableWidgetSpec.cellWidget(row, 2) else self.ui.tableWidgetSpec.item(row, 2).text() |
195 | 193 |
self.attrs[attr] = [up, down] |
DTI_PID/DTI_PID/UI/dlgConnectAttr.ui | ||
---|---|---|
72 | 72 |
</widget> |
73 | 73 |
</item> |
74 | 74 |
<item> |
75 |
<widget class="QCheckBox" name="checkBoxUpdateSpec"> |
|
76 |
<property name="text"> |
|
77 |
<string>Update Segment Break</string> |
|
78 |
</property> |
|
79 |
</widget> |
|
80 |
</item> |
|
81 |
<item> |
|
75 | 82 |
<widget class="QCheckBox" name="checkBoxUpdateLineType"> |
76 | 83 |
<property name="text"> |
77 | 84 |
<string>Update Line Type</string> |
내보내기 Unified diff