프로젝트

일반

사용자정보

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

hytos / DTI_PID / DTI_PID / MainWindow.py @ 4af2f2de

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

1
# coding: utf-8
2

    
3
import sys
4
import os
5
import subprocess
6
from functools import partial
7

    
8
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
9
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Commands')
10
import CreateCommand
11
import CropCommand
12
import AreaOcrCommand
13
import CreateSymbolCommand
14
import AreaZoomCommand
15
import FenceCommand
16
import PlaceLineCommand
17

    
18
import cv2
19
import numpy as np
20

    
21
from PyQt5.QtCore import *
22
from PyQt5.QtGui import *
23
from PyQt5.QtWidgets import *
24
from PyQt5.QtSvg import *
25

    
26
from PIL import Image
27

    
28
import MainWindow_UI
29
import QtImageViewer
30
from SingletonInstance import SingletonInstane
31

    
32
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Shapes')
33
from EngineeringPolylineItem import QEngineeringPolylineItem
34
from EngineeringLineItem import QEngineeringLineItem
35
from SymbolSvgItem import SymbolSvgItem
36
from GraphicsBoundingBoxItem import QGraphicsBoundingBoxItem
37
from EngineeringTextItem import QEngineeringTextItem
38
from EngineeringLineNoTextItem import QEngineeringLineNoTextItem
39
from QEngineeringNoteItem import QEngineeringNoteItem
40
from QEngineeringSizeTextItem import QEngineeringSizeTextItem
41
from EngineeringUnknownItem import QEngineeringUnknownItem
42
from QEngineeringEquipmentItem import QEngineeringEquipmentItem
43
from EngineeringInstrumentItem import QEngineeringInstrumentItem
44
from EngineeringSpecBreakItem import QEngineeringSpecBreakItem
45
from AppDocData import *
46
import SymbolTreeWidget, SymbolPropertyTableWidget
47
import SymbolEditorDialog
48
import ItemTreeWidget
49
import ItemPropertyTableWidget
50
from UserInputAttribute import UserInputAttribute
51
from TextItemFactory import TextItemFactory
52

    
53
class MainWindow(QMainWindow, MainWindow_UI.Ui_MainWindow, SingletonInstane):
54
    """
55
    This is MainWindow class
56
    """
57
    addMessage = pyqtSignal(Enum, str)
58

    
59
    '''
60
        @brief      initialize
61
        @author 
62
        @date   
63
        @history    humkyung 2018.04.12 add splitter widget
64
                    Jeongwoo 2018.04.27 Add Signal/Slot Connection 'noteNoSingleClicked'
65
                    Jeongwoo 2018.05.09 Initialize Action group
66
                    Jeongwoo 2018.05.10 Add Signal/Slot Connection 'lineNoSingleClicked'
67
                                        Add QActionGroup for managing checkable action
68
                    Jeongwoo 2018.06.27 Add Action [Zoom, Fit Window] and Add new actions into ActionGroup
69
                    humkyung 2018.08.23 add labelStatus to statusbar
70
                    Euisung 2018.09.27 add OCR Training , Signal/Slot Connection 'oCRTrainingClicked'
71
                    Euisung 2018.10.05 add OCR Editor , Signal/Slot Connection 'oCRTrainingEdidorClicked'
72
                    Euisung 2018.10.22 delete Signal/Slot Connection 'oCRTrainingEdidorClicked'
73
    '''
74
    def __init__(self):
75
        super(self.__class__, self).__init__()
76
        self.setupUi(self)
77
        self.labelStatus = QLabel(self.statusbar)
78
        self.labelStatus.setText('미인식 : ')
79
        self.labelSymbolStatus = QLabel(self.statusbar)
80
        self.labelSymbolStatus.setText('심볼 : ')
81
        self.labelLineStatus = QLabel(self.statusbar)
82
        self.labelLineStatus.setText('라인 : ')
83
        self.labelTextStatus = QLabel(self.statusbar)
84
        self.labelTextStatus.setText('텍스트 : ')
85
        self.statusbar.addPermanentWidget(self.labelSymbolStatus)
86
        self.statusbar.addPermanentWidget(self.labelLineStatus)
87
        self.statusbar.addPermanentWidget(self.labelTextStatus)
88
        self.statusbar.addPermanentWidget(self.labelStatus) 
89

    
90
        docData = AppDocData.instance()
91
        project = docData.getCurrentProject()
92
        _translate = QCoreApplication.translate
93
        self.setWindowTitle(_translate("Digital P&ID - {}".format(project.name), "Digital P&ID - {}".format(project.name)))
94

    
95
        self.lineComboBox = QComboBox(self.toolBar)
96
        lineTypes = docData.getLineTypes()
97
        for lineType in lineTypes:
98
            self.lineComboBox.addItem(lineType)
99
        self.lineComboBox.currentIndexChanged.connect(self.onLineTypeChanged)
100

    
101
        self.toolBar.insertWidget(self.actionOCR, self.lineComboBox)
102
        self.toolBar.insertSeparator(self.actionOCR)
103
        self.graphicsView = QtImageViewer.QtImageViewer(self)
104
        self.graphicsView.setParent(self.centralwidget)
105
        self.graphicsView.useDefaultCommand() ##### USE DEFAULT COMMAND
106

    
107
        self.verticalLayout.addWidget(self.graphicsView)
108

    
109
        # Add Custom TreeWidget
110
        self.dirTreeWidget = SymbolTreeWidget.QSymbolTreeWidget()
111
        self.dirTreeWidget.header().hide()
112
        self.symbolTabVerticalLayout.addWidget(self.dirTreeWidget)
113

    
114
        # Add Custom Property TableWidget
115
        self.propertyTableWidget = SymbolPropertyTableWidget.QSymbolPropertyTableWidget()
116
        self.symbolTabVerticalLayout.addWidget(self.propertyTableWidget)
117
        self.dirTreeWidget.singleClicked.connect(self.propertyTableWidget.getClickedSymbol)
118
        # add splitter widget
119
        splitter = QSplitter(Qt.Vertical)
120
        splitter.addWidget(self.dirTreeWidget)
121
        splitter.addWidget(self.propertyTableWidget)
122
        self.symbolTabVerticalLayout.addWidget(splitter)
123
        # up to here
124

    
125
        # Add Custom Result Tree Widget (Symbol Explorer)
126
        self.resultTreeWidget = ItemTreeWidget.QItemTreeWidget(self.graphicsView)
127
        self.resultTreeWidget.header().hide()
128
        self.symbolExplorerVerticalLayout.addWidget(self.resultTreeWidget)
129

    
130
        # Add Empty Widget
131
        self.resultPropertyTableWidget = ItemPropertyTableWidget.QItemPropertyTableWidget(self)
132
        self.symbolExplorerVerticalLayout.addWidget(self.resultPropertyTableWidget)
133
        self.resultTreeWidget.singleClicked.connect(self.resultPropertyTableWidget.onSymbolClicked)
134
        self.resultTreeWidget.noteNoSingleClicked.connect(self.resultPropertyTableWidget.onNoteClicked)
135
        self.resultTreeWidget.lineNoSingleClicked.connect(self.resultPropertyTableWidget.onLineNoClicked)
136
        self.resultTreeWidget.drawingClicked.connect(self.resultPropertyTableWidget.onDrawingClicked)
137
        # add splitter widget
138
        splitter = QSplitter(Qt.Vertical)
139
        splitter.addWidget(self.resultTreeWidget)
140
        splitter.addWidget(self.resultPropertyTableWidget)
141
        self.symbolExplorerVerticalLayout.addWidget(splitter)
142
        # up to here
143

    
144
        # Initialize Action group
145
        self.actionGroup = QActionGroup(self)
146
        self.actionGroup.addAction(self.actionRecognition)
147
        self.actionGroup.addAction(self.actionLineRecognition)
148
        self.actionGroup.addAction(self.actionLine)
149
        self.actionGroup.addAction(self.actionGenerateOutput)
150
        self.actionGroup.addAction(self.actionOCR)
151
        self.actionGroup.addAction(self.actionZoom)
152
        self.actionGroup.addAction(self.actionFitWindow)
153
        self.actionGroup.addAction(self.actionSave)
154
        self.actionGroup.triggered.connect(self.actionGroupTriggered)
155

    
156
        # connect signals and slots
157
        self.actionClose.triggered.connect(self.close)
158
        self.actionOpen.triggered.connect(self.onOpenImageDrawing)
159
        self.actionLine.triggered.connect(self.onPlaceLine)
160
        self.actionRecognition.triggered.connect(self.recognize)
161
        self.actionLineRecognition.triggered.connect(self.recognizeLine)
162
        self.actionArea.triggered.connect(self.areaConfiguration)
163
        self.actionConfiguration.triggered.connect(self.configuration)
164
        self.actionOCR.triggered.connect(self.onAreaOcr)
165
        self.actionGenerateOutput.triggered.connect(self.generateOutput)
166
        self.pushButtonCreateSymbol.clicked.connect(self.onCreateSymbolClicked)
167
        self.pushButtonClearLog.clicked.connect(self.onClearLog)
168
        self.actionHMB_DATA.triggered.connect(self.onHMBData)
169
        self.actionItem_Data_List.triggered.connect(self.showItemDataList)
170
        self.actionCodeTable.triggered.connect(self.onShowCodeTable)
171
        self.actionImage_Drawing.triggered.connect(self.onViewImageDrawing)
172
        self.actionViewText.triggered.connect(self.onViewText)
173
        self.actionViewSymbol.triggered.connect(self.onViewSymbol)
174
        self.actionViewLine.triggered.connect(self.onViewLine)
175
        self.actionViewUnknown.triggered.connect(self.onViewUnknown)
176
        self.actionRotate.triggered.connect(self.onRotate)
177
        self.actionZoom.triggered.connect(self.onAreaZoom)
178
        self.actionFitWindow.triggered.connect(self.fitWindow)
179
        self.actionpdf_to_image.triggered.connect(self.onConvertPDFToImage)
180
        self.graphicsView.scene.changed.connect(lambda: self.resultTreeWidget.sceneChanged(self.graphicsView.scene.items()))
181
        self.graphicsView.scene.changed.connect(self.onSceneChanged)
182
        self.graphicsView.scene.selectionChanged.connect(self.onSelectionChanged)
183
        self.actionInitialize.triggered.connect(self.onInitializeScene)
184
        self.resultPropertyTableWidget.cellDoubleClicked.connect(self.resultPropertyTableWidget.cellDoubleClickedEvent)
185
        self.resultPropertyTableWidget.cellClicked.connect(self.cellClickedEvent)
186
        self.actionSave.triggered.connect(self.actionSaveCliked)
187
        self.addMessage.connect(self.onAddMessage)
188
        self.actionFindReplaceText.triggered.connect(self.findReplaceTextClicked)
189
        self.pushButtonDetectSymbol.clicked.connect(self.onShowDetectSymbol)
190
        self.actionOCR_Training.triggered.connect(self.oCRTrainingClicked)
191
        #self.actionOCR_Training_Editor.triggered.connect(self.oCRTrainingEdidorClicked)
192

    
193
        # removedItems
194
        self.removedItems = {}
195
        self.removedItems['LINE'] = []
196
        self.removedItems['EQUIP'] = []
197
        self.removedItems['INST'] = []
198
        self.removedItems['NOTE'] = []
199

    
200
        self.delimiter = '"'
201
    
202
        self.resizeDocks({self.dockWidget}, {self.dockWidgetObjectExplorer.sizeHint().width()}, Qt.Horizontal)
203

    
204
        # load stylesheet file list
205
        stylesheet_name = QtWidgets.qApp.stylesheet_name
206
        files = [os.path.splitext(file)[0] for file in os.listdir(os.path.dirname(os.path.realpath(__file__))) if os.path.splitext(file)[1] == '.qss']
207
        for file in files:
208
            action = self.menuTheme.addAction(file)
209
            action.setCheckable(True)
210
            action.setChecked(True) if stylesheet_name == file else action.setChecked(False)
211
            action.triggered.connect(partial(self.load_stylesheet, file))
212
        # up to here
213

    
214
    def load_stylesheet(self, file):
215
        """
216
        @brief  load stylesheets
217
        @author humkyung
218
        @date   2018.10.29
219
        """
220

    
221
        QtWidgets.qApp.loadStyleSheet(os.path.join(os.path.dirname(os.path.realpath(__file__)), file))
222

    
223
        app_doc_data = AppDocData.instance()
224
        configs = [Config('app', 'stylesheet', file)]
225
        app_doc_data.saveAppConfigs(configs)
226
        
227
        for action in self.menuTheme.actions():
228
            if action.text() == file: continue
229
            action.setChecked(False)
230

    
231
    def onShowDetectSymbol(self):
232
        from DetectSymbolDialog import QDetectSymbolDialog
233

    
234
        dlgDetectSymbol = QDetectSymbolDialog(self)
235
        dlgDetectSymbol.show()
236
        dlgDetectSymbol.exec_()
237
        
238
    '''
239
        @brief      OCR Editor
240
        @author     euisung
241
        @date       2018.10.05
242
        @history    2018.10.16 euisung      no more used, Integrated with oCRTrainingClicked
243
    '''
244
    def oCRTrainingEdidorClicked(self):
245
        from TrainingEditorDialog import QTrainingEditorDialog
246

    
247
        try:
248
            dialog = QTrainingEditorDialog(self)
249
            dialog.exec_()
250
        except Exception as ex:
251
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
252
            self.addMessage.emit(MessageType.Error, message)
253
            
254
        return
255

    
256
    '''
257
        @brief      OCR Training
258
        @author     euisung
259
        @date       2018.09.27
260
        @history    euisung 2018.10.16 TrainingListDialog -> TrainingImageListDialog
261
    '''
262
    def oCRTrainingClicked(self):
263
        from TrainingImageListDialog import QTrainingImageListDialog
264
        #import ctypes
265
        #if not ctypes.windll.shell32.IsUserAnAdmin():
266
        #    reply = QMessageBox.information(self, 'Error', '관리자 권한으로 실행해 주세요.')
267
        #    #return
268
        try:
269
            dialog = QTrainingImageListDialog(self)
270
            dialog.exec_()
271
        except Exception as ex:
272
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
273
            self.addMessage.emit(MessageType.Error, message)
274
            
275
        return
276

    
277
    '''
278
        @brief      show unknownitem's count
279
        @author     kyouho
280
        @date       2018.08.27
281
    '''
282
    def findReplaceTextClicked(self):
283
        if not self.graphicsView.hasImage():
284
            self.showImageSelectionMessageBox()
285
            return
286

    
287
        from TextItemEditDialog import QTextItemEditDialog
288

    
289
        self.dlgTextItemEdit = QTextItemEditDialog(self)
290
        self.dlgTextItemEdit.show()
291
        self.dlgTextItemEdit.exec_()
292

    
293
    '''
294
        @brief      show unknownitem's count
295
        @author     humkyung
296
        @date       2018.08.23
297
        @history    humkyung 2018.08.30 display count of symbol, line, text
298
    '''
299
    def onSceneChanged(self):
300
        items = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringUnknownItem]
301
        if len(items) > 0:
302
            self.labelStatus.setText("<font color='red'>미인식 : {}</font>".format(len(items)))
303
        else:
304
            self.labelStatus.setText("<font color='black'>미인식 : {}</font>".format(len(items)))
305

    
306
        items = [item for item in self.graphicsView.scene.items() if issubclass(type(item), SymbolSvgItem)]
307
        self.labelSymbolStatus.setText("<font color='blue'>심볼 : {}</font>".format(len(items)))
308

    
309
        items = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringLineItem]
310
        self.labelLineStatus.setText("<font color='blue'>라인 : {}</font>".format(len(items)))
311

    
312
        items = [item for item in self.graphicsView.scene.items() if issubclass(type(item), QEngineeringTextItem)]
313
        self.labelTextStatus.setText("<font color='blue'>텍스트 : {}</font>".format(len(items)))
314

    
315
    '''
316
        @brief      action save click event
317
        @author     kyouho
318
        @date       2018.08.09
319
    '''
320
    def actionSaveCliked(self):
321
        self.saveToXml(True)
322

    
323
    '''
324
        @brief      save items to xml
325
        @author     kyouho
326
        @date       2018.07.31
327
    '''
328
    def saveToXml(self, alert = True):
329
        import XmlGenerator as xg
330
        from AppDocData import AppDocData
331
        docData = AppDocData.instance()
332
        if docData.imgName is None:
333
            self.showImageSelectionMessageBox()
334
            return
335
        result = xg.writeXmlOnScene(docData.imgName, docData.imgWidth, docData.imgHeight, self.graphicsView.scene)
336
        
337
        if len(self.removedItems['LINE']):
338
            docData.deleteLineDataList_LineNo(self.removedItems['LINE'])
339
            self.removedItems['LINE'] = []
340

    
341
        if len(self.removedItems['EQUIP']):
342
            docData.deleteEquipDataList(self.removedItems['EQUIP'])
343
            self.removedItems['EQUIP'] = []
344

    
345
        if len(self.removedItems['INST']):
346
            docData.deleteInstDataList(self.removedItems['INST'])
347
            self.removedItems['INST'] = []
348

    
349
        if len(self.removedItems['NOTE']):
350
            docData.deleteNoteDataList(self.removedItems['NOTE'])
351
            self.removedItems['NOTE'] = []
352

    
353

    
354
        if alert:
355
            resultStr = '[저장 결과]'
356

    
357
            for item in result.items():
358
                itemName = str(item[0])
359
                itemSuccessCount = str(item[1][0])
360
                itemFailUidList = item[1][1]
361
                resultStr += "\r\n" + itemName + " Save Count : " + itemSuccessCount
362
                if len(itemFailUidList) > 0:
363
                    resultStr += "\r\n" + itemName + " Error List(UID)"
364
                    for uid in itemFailUidList:
365
                        resultStr += "\r\n" + uid
366

    
367
            QMessageBox.about(self.graphicsView, "알림", resultStr)
368

    
369
    '''
370
        @brief      refresh resultPropertyTableWidget
371
        @author     kyouho
372
        @date       2018.07.19
373
    '''
374
    def refreshResultPropertyTableWidget(self):
375
        items = self.graphicsView.scene.selectedItems()
376
        if len(items) == 1:
377
            self.resultPropertyTableWidget.onSymbolClicked(items[0])
378
    
379
    '''
380
        @brief      resultPropertyTableWidget Cell Click Event
381
        @author     kyouho
382
        @date       2018.08.23
383
    '''
384
    def cellClickedEvent(self, row, column):
385
        item = self.graphicsView.scene.selectedItems()
386
        if len(item) != 1:
387
            return
388
        item = item[0]
389

    
390
        cell = self.resultPropertyTableWidget.item(row, column)
391
        for valueCell, uid in self.resultPropertyTableWidget.attrValueList:
392
            if valueCell == cell and issubclass(type(item), SymbolSvgItem):
393
                for attr in item.attrs:
394
                    if attr.attribute == uid and (issubclass(type(attr), SymbolSvgItem) or type(attr) is QEngineeringTextItem):
395
                        prevItem = item
396
                        currentItem = attr
397

    
398
                        rect = currentItem.sceneBoundingRect()
399
                        self.graphicsView.centerOn(rect.center())
400
                        self.graphicsView.zoomImage(True, QMouseEvent(QEvent.MouseButtonPress, self.graphicsView.mapFromScene(QPointF(rect.left(), rect.top())), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier), 3)
401
                        prevItem.setSelected(True)
402

    
403
                        currentItem.setHightlight()
404
                    elif (issubclass(type(attr), SymbolSvgItem) or type(attr) is QEngineeringTextItem):
405
                        attr.unsetHightlight()
406

    
407

    
408
    '''
409
        @brief  add message listwidget
410
        @author humkyung
411
        @date   2018.07.31
412
    '''
413
    def onAddMessage(self, messageType, message):
414
        from AppDocData import MessageType
415

    
416
        try:
417
            current = QDateTime.currentDateTime()
418

    
419
            item = QListWidgetItem('{}: {}'.format(current.toString('hh:mm:ss'), message))
420
            if messageType == MessageType.Error:
421
                item.setBackground(Qt.red)
422

    
423
            self.listWidgetLog.insertItem(0, item)
424
        except Exception as ex:
425
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
426

    
427
    '''
428
        @brief      clear log
429
        @author     humkyung
430
        @date       2018.08.01
431
    '''
432
    def onClearLog(self):
433
        self.listWidgetLog.clear()
434

    
435
    '''
436
        @brief      rotate selected symbol
437
        @author     humkyung
438
        @date       2018.08.15
439
    '''
440
    def onRotate(self, action):
441
        selected = [item for item in self.graphicsView.scene.selectedItems() if issubclass(type(item), SymbolSvgItem)]
442
        if len(selected) == 1:
443
            selected[0].rotateSymbol()
444

    
445
    '''
446
        @brief      Area Zoom
447
        @author     Jeongwoo
448
        @date       2018.06.27
449
        @history    connect command's rejected signal
450
    '''
451
    def onAreaZoom(self, action):
452
        if self.actionZoom.isChecked():
453
            cmd = AreaZoomCommand.AreaZoomCommand(self.graphicsView)
454
            cmd.onRejected.connect(self.onCommandRejected)
455
            self.graphicsView.command = cmd
456

    
457
    '''
458
        @brief      Fit Window
459
        @author     Jeongwoo
460
        @date       2018.06.27
461
        @history    2018.06.27  Jeongwoo    Chnage method to initialize command [Set None → DefaultCommand]
462
    '''
463
    def fitWindow(self, action):
464
        self.graphicsView.useDefaultCommand()
465
        self.graphicsView.zoomImageInit()
466

    
467
    def onConvertPDFToImage(self):
468
        """
469
        @brief      convert to selected pdf to image
470
        @author     humkyung 
471
        @date       2018.07.09
472
        @history    Euisung 2018.10.11 hide shell
473
        """
474
        try: 
475
            filePath = os.path.join(os.path.dirname(os.path.realpath(__file__)) , 'bin64', 'PDF_TO_IMAGE.exe')
476
            subprocess.call(filePath, shell = False)
477
        except Exception as ex:
478
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
479

    
480
    '''
481
        @brief      selection changed
482
        @author     humkyung
483
        @date       2018.06.27
484
        @history    humkung 2018.07.08 call tree widget's findItem
485
    '''
486
    def onSelectionChanged(self):
487
        items = [item for item in self.graphicsView.scene.selectedItems() if issubclass(type(item), SymbolSvgItem) or \
488
            type(item) is QEngineeringLineItem or type(item) is QEngineeringLineNoTextItem or type(item) is QEngineeringNoteItem]
489
        if items:
490
            item = items[-1]
491
            self.resultTreeWidget.findItem(item)
492
            self.resultPropertyTableWidget.showItemProperty(item)
493
        else:
494
            self.resultPropertyTableWidget.showItemProperty(None)
495
        
496
    '''
497
        @brief      Initialize scene and ResultTreeWidget
498
        @author     Jeongwoo
499
        @date       2018.06.14
500
        @history    humkyung 2018.08.16 ask to delete recognized items before remove
501
    '''
502
    def onInitializeScene(self, action):
503
        if not self.graphicsView.hasImage():
504
            self.actionEquipment.setChecked(False)
505
            self.showImageSelectionMessageBox()
506

    
507
            return
508

    
509
        msg = QMessageBox()
510
        msg.setIcon(QMessageBox.Critical)
511
        msg.setText("선택한 인식한 항목들을 삭제하시겠습니까?\n삭제된 항목들은 복구할 수 없습니다.")
512
        msg.setWindowTitle("항목 삭제")
513
        msg.setStandardButtons(QMessageBox.Ok|QMessageBox.Cancel)
514
        if QMessageBox.Ok == msg.exec_():
515
            items = self.graphicsView.scene.items()
516
            for item in items:
517
                if type(item) is not QGraphicsPixmapItem:
518
                    self.graphicsView.scene.removeItem(item)
519

    
520
                    if type(item) is QEngineeringLineNoTextItem:
521
                        self.removedItems['LINE'].append(str(item.uid))
522
                    elif type(item) is QEngineeringInstrumentItem:
523
                        self.removedItems['INST'].append(str(item.uid))
524
                    elif type(item) is QEngineeringEquipmentItem:
525
                        self.removedItems['EQUIP'].append(str(item.uid))
526
                    elif type(item) is QEngineeringNoteItem:
527
                        self.removedItems['NOTE'].append(str(item.uid))
528
                    
529
            if self.path is not None:
530
                baseName = os.path.basename(self.path)
531
                self.resultTreeWidget.setCurrentPID(baseName)
532

    
533
    '''
534
        @brief      Manage Checkable Action statement
535
        @author     Jeongwoo
536
        @date       2018.05.10
537
        @history    2018.06.27  Jeongwoo    Chnage method to initialize command [Set None → DefaultCommand]
538
    '''
539
    def actionGroupTriggered(self, action):
540
        if self.graphicsView.command is not None:
541
            self.graphicsView.useDefaultCommand()
542

    
543
        for _action in self.actionGroup.actions():
544
            _action.setChecked(False)
545

    
546
        action.setChecked(True)
547

    
548
    '''
549
        @brief      Create Equipment
550
        @author     Jeongwoo
551
        @date       18.05.03
552
        @history    2018.05.04  Jeongwoo    Add Parameter on CreateSymbolCommand
553
    '''
554
    def createEquipment(self):
555
        if not self.graphicsView.hasImage():
556
            self.actionEquipment.setChecked(False)
557
            self.showImageSelectionMessageBox()
558
            return
559
        if self.actionEquipment.isChecked():
560
            self.graphicsView.command = CreateSymbolCommand.CreateSymbolCommand(self.graphicsView, self.resultTreeWidget, self.dirTreeWidget)
561
        else:
562
            self.graphicsView.useDefaultCommand()
563

    
564

    
565
    '''
566
        @brief      Create Nozzle
567
        @author     Jeongwoo
568
        @date       2018.05.03
569
        @history    2018.05.04  Jeongwoo    Add Parameter on CreateSymbolCommand
570
    '''
571
    def createNozzle(self):
572
        if not self.graphicsView.hasImage():
573
            self.actionNozzle.setChecked(False)
574
            self.showImageSelectionMessageBox()
575
            return
576
        if self.actionNozzle.isChecked():
577
            self.graphicsView.command = CreateSymbolCommand.CreateSymbolCommand(self.graphicsView, self.resultTreeWidget, self.dirTreeWidget)
578
        else:
579
            self.graphicsView.useDefaultCommand()
580

    
581
    '''
582
        @brief      Area OCR
583
        @author     Jeongwoo
584
        @date       18.04.18
585
        @history    2018.05.02  Jeongwoo    Change graphicsView.command by actionOCR checked state
586
                                            Show MessageBox when imageviewer doesn't have image
587
    '''
588
    def onAreaOcr(self):
589
        if not self.graphicsView.hasImage():
590
            self.actionOCR.setChecked(False)
591
            self.showImageSelectionMessageBox()
592
            return
593

    
594
        if self.actionOCR.isChecked():
595
            cmd = AreaOcrCommand.AreaOcrCommand(self.graphicsView)
596
            cmd.onSuccess.connect(self.onRecognizeText)
597
            cmd.onRejected.connect(self.onCommandRejected)
598
            self.graphicsView.command = cmd
599
        else:
600
            self.graphicsView.useDefaultCommand()
601
    
602
    '''
603
        @brief      show text recognition dialog
604
        @author     humkyung
605
        @date       2018.08.08
606
    '''
607
    def onRecognizeText(self, x, y, width, height):
608
        from OcrResultDialog import QOcrResultDialog
609

    
610
        try:
611
            image = self.graphicsView.image().copy(x, y, width, height)
612
            dialog = QOcrResultDialog(self.graphicsView, image, QRectF(x, y, width, height))
613
            (isAccept, textInfoList) = dialog.showDialog()
614
            if isAccept:
615
                if textInfoList is not None and len(textInfoList) > 0:
616
                    docData = AppDocData.instance()
617
                    configs = docData.getConfigs('Line No', 'Delimiter')
618
                    delimiter = configs[0].value if 1 == len(configs) else '-'
619
                    lineNoconfigs = docData.getConfigs('Line No', 'Configuration')
620
                    for textInfo in textInfoList:
621
                        x = textInfo.getX()
622
                        y = textInfo.getY()
623
                        angle = textInfo.getAngle()
624
                        text = textInfo.getText()
625
                        width = textInfo.getW()
626
                        height = textInfo.getH()
627
                        item = TextItemFactory.instance().createTextItem(text)
628
                        if item is not None:
629
                            item.loc = (x, y)
630
                            item.size = (width, height)
631
                            item.angle = angle
632
                            item.setPlainText(text)
633
                            item.setDefaultTextColor(Qt.blue)
634
                            item.addTextItemToScene(self.graphicsView.scene)
635
                            item.transfer.onRemoved.connect(self.itemRemoved)
636
                        else:
637
                            message = 'error occured({}) in {}:{}'.format('텍스트 생성에 실패했습니다.', sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
638
                            self.addMessage.emit(MessageType.Normal, message)
639
                else:
640
                    QMessageBox.about(self.graphicsView, "알림", "텍스트 검출 실패")
641
        except Exception as ex:
642
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
643
            self.addMessage.emit(MessageType.Error, message)
644

    
645
    '''
646
        @brief  area configuration
647
    '''
648
    def areaConfiguration(self):
649
        from ConfigurationAreaDialog import QConfigurationAreaDialog
650

    
651
        self.dlgConfigurationArea = QConfigurationAreaDialog(self)
652
        self.dlgConfigurationArea.show()
653
        self.dlgConfigurationArea.exec_()
654

    
655
    '''
656
        @brief  configuration
657
    '''
658
    def configuration(self):
659
        from ConfigurationDialog import QConfigurationDialog
660

    
661
        self.dlgConfiguration = QConfigurationDialog(self)
662
        self.dlgConfiguration.show()
663
        self.dlgConfiguration.exec_()
664

    
665
    '''
666
        @brief  show nominal diameter dialog 
667
        @author humkyung
668
        @date   2018.06.28
669
    '''
670
    def onShowCodeTable(self):
671
        from CodeTableDialog import QCodeTableDialog
672

    
673
        dlg = QCodeTableDialog(self)
674
        dlg.exec_()
675

    
676
    '''
677
        @brief  show HMB data
678
        @author humkyung
679
        @date   2018.07.11
680
    '''
681
    def onHMBData(self):
682
        from HMBDialog import QHMBDialog
683

    
684
        dlg = QHMBDialog(self)
685
        dlg.show()
686
        dlg.exec_()
687

    
688
    '''
689
        @brief  show line data list 
690
        @author humkyung
691
        @date   2018.05.03
692
    '''
693
    def showItemDataList(self):
694
        from ItemDataExportDialog import QItemDataExportDialog
695

    
696
        self.dlgLineDataList = QItemDataExportDialog(self)
697
        self.dlgLineDataList.exec_()
698

    
699
    '''
700
        @brief  Show Image Selection Guide MessageBox
701
        @author Jeongwoo
702
        @date   2018.05.02
703
    '''
704
    def showImageSelectionMessageBox(self):
705
        QMessageBox.about(self.graphicsView, "알림", "이미지를 선택하신 후 시도해주세요.")
706
        
707
    '''
708
        @brief  change selected lines' type by selected line type
709
        @author humkyung
710
        @date   2018.06.27
711
    '''
712
    def onLineTypeChanged(self, param):
713
        lineType = self.lineComboBox.itemText(param)
714
        selected = [item for item in self.graphicsView.scene.selectedItems() if type(item) is QEngineeringLineItem]
715
        if selected:
716
            for item in selected:
717
                item.lineType = lineType
718

    
719
    '''
720
        @brief      Open image drawing file and then display it
721
        @author     humkyung
722
        @date       2018.??.??
723
        @history    18.04.23 Jeongwoo    Add AppDocData.instance().setCurrentPidSource
724
                    18.04.23 Jeongwoo    Add Store Set Current Pid Image on AppDocData
725
                    18.05.02 Jeongwoo    Add useDefaultCommand()
726
                    humkyung 2018.05.24 load recognition result file if exists
727
                    Jeongwoo 2018.05.29 load data on xml if xml file exist
728
                    humkyung 2018.08.22 clear scene before loading xml file
729
    '''
730
    def onOpenImageDrawing(self, MainWindow):
731
        from Drawing import Drawing
732

    
733
        try:
734
            appDocData = AppDocData.instance()
735
            project = appDocData.getCurrentProject()
736
            
737
            for item in self.graphicsView.scene.items():
738
                self.graphicsView.scene.removeItem(item)
739

    
740
            self.path = self.graphicsView.loadImageFromFile(project.getDrawingFilePath())
741
            if os.path.isfile(self.path):
742
                appDocData.clear()
743
                self.graphicsView.useDefaultCommand()
744

    
745
                appDocData.setImgFilePath(self.path)
746
                appDocData.activeDrawing = Drawing(appDocData.imgName)
747
                appDocData.setCurrentPidSource(Image.open(self.path))
748
                self.resultTreeWidget.setCurrentPID(appDocData.activeDrawing.name)
749

    
750
                self.progress = QProgressDialog("잠시만 기다려주세요", "Cancel", 0, 100, self)
751
                self.progress.setWindowModality(Qt.WindowModal)
752
                self.progress.setAutoReset(True)
753
                self.progress.setAutoClose(True)
754
                self.progress.setMinimum(0)
755
                self.progress.resize(600,100)
756
                self.progress.setWindowTitle("파일 읽는 중...")
757
                self.progress.show()
758

    
759
                ## Load data on xml
760
                try:
761
                    path = os.path.join(appDocData.getCurrentProject().getTempPath(), appDocData.imgName + '.xml')
762
                    if os.path.isfile(path):
763
                        self.loadRecognitionResultFromXml(path)
764
                        self.checkAttribute()
765
                finally:
766
                    self.progress.setValue(self.progress.maximum())
767
                    self.progress.hide()
768
        except Exception as ex:
769
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
770
            self.addMessage.emit(MessageType.Error, message)
771

    
772
        return self.path
773

    
774
    '''
775
        @brief  visible/invisible image drawing
776
        @author humkyung
777
        @date   2018.06.25
778
    '''
779
    def onViewImageDrawing(self, isChecked):
780
        for item in self.graphicsView.scene.items():
781
            if type(item) is QGraphicsPixmapItem:
782
                item.setVisible(isChecked)
783
                break
784

    
785
    '''
786
        @brief  visible/invisible Text 
787
        @author humkyung
788
        @date   2018.06.28
789
    '''
790
    def onViewText(self, isChecked):
791
        selected = [item for item in self.graphicsView.scene.items() if issubclass(type(item), QEngineeringTextItem)]
792
        for item in selected:
793
            item.setVisible(isChecked)
794

    
795
    '''
796
        @brief  visible/invisible Symbol 
797
        @author humkyung
798
        @date   2018.06.28
799
    '''
800
    def onViewSymbol(self, isChecked):
801
        selected = [item for item in self.graphicsView.scene.items() if issubclass(type(item), SymbolSvgItem)]
802
        for item in selected:
803
            item.setVisible(isChecked)
804

    
805
    '''
806
        @brief  visible/invisible Line
807
        @author humkyung
808
        @date   2018.06.28
809
    '''
810
    def onViewLine(self, isChecked):
811
        selected = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringLineItem]
812
        for item in selected:
813
            item.setVisible(isChecked)
814

    
815
    '''
816
        @brief  visible/invisible Unknown 
817
        @author humkyung
818
        @date   2018.06.28
819
    '''
820
    def onViewUnknown(self, isChecked):
821
        selected = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringUnknownItem]
822
        for item in selected:
823
            item.setVisible(isChecked)
824

    
825
    '''
826
        @brief  create a symbol
827
        @history    2018.05.02  Jeongwoo    Change return value of QSymbolEditorDialog (Single variable → Tuple)
828
                                            Add SymbolSvgItem
829
                    2018.05.03  Jeongwoo    Change method to draw Svg Item on Scene (svg.addSvgItemToScene)
830
                                            Change method to make svg and image path
831
                    2018.06.08  Jeongwoo    Add Paramter on SymbolSvgItem.buildItem()
832
    '''
833
    def onCreateSymbolClicked(self):
834
        cmd = FenceCommand.FenceCommand(self.graphicsView)
835
        cmd.onSuccess.connect(self.onAreaSelected)
836
        self.graphicsView.command = cmd
837
        QApplication.setOverrideCursor(Qt.CrossCursor)
838

    
839
    '''
840
        @brief      show SymbolEditorDialog with image selected by user
841
        @author     humkyung
842
        @date       2018.07.20
843
    '''
844
    def onAreaSelected(self, x, y, width, height):
845
        try:
846
            image = self.graphicsView.image()
847
            if image is not None:
848
                symbolEditorDialog = SymbolEditorDialog.QSymbolEditorDialog(self, image.copy(x, y, width, height), AppDocData.instance().getCurrentProject())
849
                (isAccepted, isImmediateInsert, offsetX, offsetY, newSym) = symbolEditorDialog.showDialog()
850
                self.dirTreeWidget.initDirTreeWidget()
851
                if isAccepted:
852
                    if isImmediateInsert:
853
                        svgPath = newSym.getSvgFileFullPath()
854
                        img = cv2.imread(newSym.getImageFileFullPath(), 1)
855
                        w, h = (0, 0)
856
                        if len(img.shape[::-1]) == 2:
857
                            w, h = img.shape[::-1]
858
                        else:
859
                            _chan, w, h = img.shape[::-1]
860
                        svg = SymbolSvgItem(svgPath)
861
                        svg.buildItem(newSym.getName(), newSym.getType(), 0, [offsetX, offsetY], [w, h], [float(x) for x in newSym.getOriginalPoint().split(',')], [(float(x.split(',')[0]), float(x.split(',')[1])) for x in newSym.getConnectionPoint().split('/')], newSym.getBaseSymbol(), newSym.getAdditionalSymbol(), newSym.getHasInstrumentLabel)
862

    
863
                        svg.transfer.onRemoved.connect(self.resultTreeWidget.itemRemoved)
864
                        svg.addSvgItemToScene(self.graphicsView.scene)
865
                        for connector in svg.connectors:
866
                            self.graphicsView.scene.addItem(connector)
867
        finally:
868
            self.graphicsView.useDefaultCommand()
869
            QApplication.restoreOverrideCursor()
870
    
871
    '''
872
        @brief      create a line
873
        @author     humkyung
874
        @history    Jeongwoo 2018.05.10 Change method for Checkable action
875
    '''
876
    def onPlaceLine(self):        
877
        if not self.graphicsView.hasImage():
878
            self.actionLine.setChecked(False)
879
            self.showImageSelectionMessageBox()
880
            return
881

    
882
        self.actionLine.setChecked(True)
883
        if not hasattr(self.actionLine, 'tag'):
884
            self.actionLine.tag = PlaceLineCommand.PlaceLineCommand(self.graphicsView)
885
            self.actionLine.tag.onSuccess.connect(self.onLineCreated)
886
            self.actionLine.tag.onRejected.connect(self.onCommandRejected)
887

    
888
        self.graphicsView.command = self.actionLine.tag
889

    
890
    '''
891
        @brief      add created lines to scene
892
        @author     humkyung
893
        @date       2018.07.23
894
    '''
895
    def onLineCreated(self):
896
        from EngineeringConnectorItem import QEngineeringConnectorItem
897

    
898
        try:
899
            count = len(self.actionLine.tag._polyline._vertices)
900
            if count > 1:
901
                items = []
902

    
903
                lineType = self.lineComboBox.currentText()
904
                for index in range(count - 1):
905
                    start = self.actionLine.tag._polyline._vertices[index]
906
                    end  = self.actionLine.tag._polyline._vertices[index + 1]
907
                    
908
                    lineItem = QEngineeringLineItem(vertices=[start, end])
909
                    lineItem.transfer.onRemoved.connect(self.itemRemoved)
910
                    lineItem.lineType = lineType
911
                    if items:
912
                        lineItem.connectIfPossible(items[-1], 5)
913
                    else:
914
                        pt = lineItem.startPoint()
915
                        selected = self.graphicsView.scene.itemAt(QPointF(pt[0], pt[1]), QTransform())
916
                        if selected is not None and type(selected) is QEngineeringConnectorItem:
917
                            lineItem.connectIfPossible(selected.parent, 5)
918
                    
919
                    items.append(lineItem)
920
                    self.graphicsView.scene.addItem(lineItem)
921

    
922
                pt = items[-1].endPoint()
923
                selected = self.graphicsView.scene.itemAt(QPointF(pt[0], pt[1]), QTransform())
924
                if selected is not None and type(selected) is QEngineeringConnectorItem:
925
                    items[-1].connectIfPossible(selected.parent, 5)
926
        finally:
927
            self.graphicsView.scene.removeItem(self.actionLine.tag._polyline)
928
            self.actionLine.tag.reset()
929

    
930
    '''
931
        @brief      refresh scene
932
        @author     humkyung
933
        @date       2018.07.23
934
    '''
935
    def onCommandRejected(self, cmd):
936
        try:
937
            if type(cmd) is PlaceLineCommand.PlaceLineCommand:
938
                self.graphicsView.scene.removeItem(self.actionLine.tag._polyline)
939
                self.graphicsView.scene.update()
940
                self.actionLine.tag.reset()
941

    
942
                self.actionLine.setChecked(False)
943
            elif type(cmd) is AreaZoomCommand.AreaZoomCommand:
944
                self.actionZoom.setChecked(False)
945
            elif type(cmd) is AreaOcrCommand.AreaOcrCommand:
946
                self.actionOCR.setChecked(False)
947
        finally:
948
            self.graphicsView.useDefaultCommand()
949
     
950
    '''
951
        @brief      restore to default command when user press Escape key
952
        @author     humkyung 
953
        @date       2018.08.09
954
    '''
955
    def keyPressEvent(self, event):
956
        try:
957
            if event.key() == Qt.Key_Escape:
958
                checked = self.actionGroup.checkedAction()
959
                if checked:
960
                    checked.setChecked(False)
961
                    self.graphicsView.useDefaultCommand()
962

    
963
            QMainWindow.keyPressEvent(self, event)
964
        except Exception as ex:
965
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
966
            self.addMessage.emit(MessageType.Error, message)
967
       
968
    '''
969
        @brief      recognize symbol and text
970
        @author     humkyung
971
        @date       2018.04.??
972
        @history    2018.04.16  humkyung    execute line no tracing
973
                    2018.05.02  Jeongwoo    Show MessageBox when imageviewer doesn't have image
974
                    2018.05.25  Jeongwoo    Add parameter on QRecognitionDialog.__init__() and Move thread to QRecognitionDialog
975
                                            Remove codes below if self.dlg.isAccepted == True
976
                    2018.05.29  Jeongwoo    Remove connects and comments
977
    '''
978
    def recognize(self, MainWindow):
979
        from RecognitionDialog import QRecognitionDialog
980

    
981
        if not self.graphicsView.hasImage():
982
            self.showImageSelectionMessageBox()
983
            return
984

    
985
        try:
986
            self.removedItems['LINE'] = []
987
            self.removedItems['EQUIP'] = []
988
            self.removedItems['INST'] = []
989
            self.removedItems['NOTE'] = []
990

    
991
            appDocData = AppDocData.instance()
992
            self.resultTreeWidget.setCurrentPID(appDocData.activeDrawing.name)
993
            ## up to here
994

    
995
            self.onClearLog()
996
            self.dlg = QRecognitionDialog(self, self.path)
997
            self.dlg.exec_()
998
            if self.dlg.isAccepted == True:
999
                '''DO NOTHING'''
1000
        except Exception as ex:
1001
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1002
            self.addMessage.emit(MessageType.Error, message)
1003

    
1004
    '''
1005
        @brief      remove item from tree widget and then remove from scene
1006
        @date       2018.05.25
1007
        @author     Jeongwoo
1008
    '''
1009
    def itemRemoved(self, item):
1010
        try:
1011
            self.resultTreeWidget.itemRemoved(item)
1012

    
1013
            if type(item) is QEngineeringLineNoTextItem:
1014
                self.removedItems['LINE'].append(str(item.uid))
1015
            elif type(item) is QEngineeringInstrumentItem:
1016
                self.removedItems['INST'].append(str(item.uid))
1017
            elif type(item) is QEngineeringEquipmentItem:
1018
                self.removedItems['EQUIP'].append(str(item.uid))
1019
            elif type(item) is QEngineeringNoteItem:
1020
                self.removedItems['NOTE'].append(str(item.uid))
1021

    
1022
            if item.scene() is not None: item.scene().removeItem(item)
1023
        except Exception as ex:
1024
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1025
            self.addMessage.emit(MessageType.Error, message)
1026

    
1027
    '''
1028
        @brief      recognize line
1029
        @author     humkyung
1030
        @date       2018.04.19
1031
        @history    Jeongwoo 2018.04.26 Variable name changed (texts → lineNos)
1032
                                        TextItem type changed (QEngineeringTextItem → QEngineeringLineNoTextItem)
1033
                    humkyung 2018.04.26 remove small objects before recognizing line
1034
                    Jeongwoo 2018.05.02 Show MessageBox when imageviewer doesn't have image
1035
                    Jeongwoo 2018.05.25 Move codes about LineDetector
1036
                    humkyung 2018.06.17 show progress dialog
1037
    '''
1038
    def recognizeLine(self, MainWindow):
1039
        from LineNoTracer import LineNoTracer
1040
        from ConnectAttrDialog import QConnectAttrDialog
1041

    
1042
        if not self.graphicsView.hasImage():
1043
            self.showImageSelectionMessageBox()
1044
            return
1045

    
1046
        try:
1047
            self.dlgConnectAttr = QConnectAttrDialog(self, self.graphicsView)
1048
            self.dlgConnectAttr.exec_()
1049

    
1050
            self.resultTreeWidget.InitLineNoItems()
1051

    
1052
            # construct line no item
1053
            docData = AppDocData.instance()
1054
            for lineno in docData.lineNos:
1055
                item = self.resultTreeWidget.addTreeItem(self.resultTreeWidget.root, lineno)
1056
                connectedItems = lineno.getConnectedItems()
1057
                for connectedItem in connectedItems:
1058
                    if issubclass(type(connectedItem), SymbolSvgItem): 
1059
                        self.resultTreeWidget.addTreeItem(item, connectedItem)
1060
            # up to here
1061
        except Exception as ex:
1062
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1063
            self.addMessage.emit(MessageType.Error, message)
1064

    
1065
    '''
1066
        @history    2018.05.25  Jeongwoo    Moved from MainWindow
1067
                                            SvgItem and TextItem Connect with method in this class
1068
                                            Change method to add GraphicsItem
1069
                    2018.05.28  Jeongwoo    Make QGraphicsItem by symbol, text object. Not xml
1070
                    2018.05.29  Jeongwoo    Change method name and Moved from QRecognitionDialog
1071
                    2018.05.30  Jeongwoo    Add parameters on SymbolSvgItem.__init__() (parentSymbol, childSymbol)
1072
                                            Change Method name and seperate each item
1073
                    humkyung 2018.06.11     display difference between original and recognized image
1074
                    Jeongwoo 2018.06.18     Update Scene after all item added
1075
    '''
1076
    def drawDetectedItems(self, symbolList, textInfoList, otherTextInfoList):
1077
        QApplication.processEvents()
1078
        self.drawDetectedSymbolItem(symbolList)
1079
        QApplication.processEvents()
1080
        self.drawDetectedTextItem(textInfoList)
1081
        QApplication.processEvents()
1082
        self.drawDetectedOtherTextItem(otherTextInfoList)
1083

    
1084
        # Update Scene
1085
        self.graphicsView.scene.update(self.graphicsView.sceneRect())
1086

    
1087
    '''
1088
        @brief      
1089
        @author     humkyung
1090
        @date       2018.08.23
1091
    '''
1092
    def drawDetectedLines(self, lineList, worker):
1093
        area = AppDocData.instance().getArea('Drawing')
1094

    
1095
        lines = []
1096
        for pts in lineList:
1097
            processLine = QEngineeringLineItem(vertices=[(area.x + param[0], area.y + param[1]) for param in pts])
1098
            processLine.area = 'Drawing'
1099
            self.graphicsView.scene.addItem(processLine)
1100
            lines.append(processLine)
1101

    
1102
            if processLine.length() > 100: # TODO: check critical length
1103
                processLine.addFlowArrow()
1104
        
1105
        # re-order process line's start,end according to flow mark
1106
        #worker.arrangeLinePosition(lines, symbols, listWidget)
1107
        # up to here
1108

    
1109
    '''
1110
        history    humkyung 2018.06.09 check length of original and connection point is 2 while parsing
1111
    '''
1112
    def drawDetectedSymbolItem(self, symbolList):
1113
        from GraphicsBoundingBoxItem import QGraphicsBoundingBoxItem
1114
        from SymbolSvgItem import SymbolSvgItem
1115
        import math
1116

    
1117
        try:
1118
            project = AppDocData.instance().getCurrentProject()
1119

    
1120
            searchedMap = []
1121
            for symbol in symbolList:
1122
                pt = [float(x) for x in symbol.getSp()]
1123
                size = [symbol.getWidth(), symbol.getHeight()]
1124
                name = symbol.getName()
1125
                angle = round(math.radians(symbol.getRotatedAngle()), 2)
1126
                _type = symbol.getType()
1127
                origin = [0,0]
1128
                if 2 == len(symbol.getOriginalPoint().split(',')):
1129
                    tokens = symbol.getOriginalPoint().split(',')
1130
                    origin = [pt[0] + float(tokens[0]), pt[1] + float(tokens[1])]
1131
                connPts = []
1132
                if symbol.getConnectionPoint() is not None:
1133
                    connPts = [(param.split(',')[0], pt[0] + float(param.split(',')[1]), pt[1] + float(param.split(',')[2])) for param in symbol.getConnectionPoint().split('/') if 3 == len(param.split(','))]
1134
                parentSymbol = symbol.getBaseSymbol()
1135
                childSymbol = symbol.getAdditionalSymbol()
1136
                hasInstrumentLabel = symbol.getHasInstrumentLabel()
1137

    
1138
                svgFilePath = os.path.join(project.getSvgFilePath(), _type, name + '.svg')
1139
                if os.path.isfile(svgFilePath):
1140
                    svg = SymbolSvgItem.createItem(_type, svgFilePath)
1141
                    svg.buildItem(name, _type, angle, pt, size, origin, connPts, parentSymbol, childSymbol, hasInstrumentLabel)
1142
                    svg.reCalculationRotatedItem()
1143
                    svg.area = 'Drawing'
1144

    
1145
                    # set owner - 2018.07.20 added by humkyung                   
1146
                    matches = [searched for searched in searchedMap if searched[0] == symbol.owner]
1147
                    if len(matches) == 1:
1148
                        svg.owner = matches[0][1]
1149
                    searchedMap.append((symbol, svg))
1150
                    # up to here
1151

    
1152
                    svg.transfer.onRemoved.connect(self.itemRemoved)
1153
                    self.addSvgItemToScene(svg)
1154
                    
1155
                    # Equipment Item 경우 저장
1156
                    if type(svg) is QEngineeringEquipmentItem:
1157
                        svg.saveEquipData()
1158

    
1159
                    # Instrument Item 경우 저장
1160
                    if type(svg) is QEngineeringInstrumentItem:
1161
                        svg.saveInstData()
1162
                else:
1163
                    item = QGraphicsBoundingBoxItem(pt[0], pt[1], size[0], size[1])
1164
                    item.isSymbol = True
1165
                    item.angle = angle
1166
                    item.setPen(QPen(Qt.red, 5, Qt.SolidLine))
1167
                    self.graphicsView.scene.addItem(item)
1168
            # up to here
1169
        except Exception as ex:
1170
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1171
            self.addMessage.emit(MessageType.Error, message)
1172

    
1173
    '''
1174
        @history    2018.06.08  Jeongwoo    Add parameter on round method
1175
    '''
1176
    def drawDetectedTextItem(self, textInfoList):
1177
        from TextItemFactory import TextItemFactory
1178
        import math
1179

    
1180
        try:
1181
            appDocData = AppDocData.instance()
1182

    
1183
            # parse texts
1184
            for textInfo in textInfoList:
1185
                x = textInfo.getX()
1186
                y = textInfo.getY()
1187
                width = textInfo.getW()
1188
                height = textInfo.getH()
1189
                angle = round(math.radians(textInfo.getAngle()), 2)
1190
                text = textInfo.getText()
1191
                item = TextItemFactory.instance().createTextItem(text)
1192

    
1193
                if item is not None:
1194
                    item.loc = (x, y)
1195
                    item.size = (width, height)
1196
                    item.angle = angle
1197
                    item.setPlainText(text)
1198
                    item.area = 'Drawing'
1199
                    item.transfer.onRemoved.connect(self.itemRemoved)
1200
                    self.addTextItemToScene(item)
1201
                    appDocData.texts.append(item)
1202

    
1203
                    # Line No Text Item 경우 저장
1204
                    if type(item) is QEngineeringLineNoTextItem:
1205
                        item.saveLineData()
1206
        except Exception as ex:
1207
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1208
            self.addMessage.emit(MessageType.Error, message)
1209

    
1210
    '''
1211
        @brief      draw detected texts except which in drawing area
1212
    '''
1213
    def drawDetectedOtherTextItem(self, otherTextInfoList):
1214
        from TextItemFactory import TextItemFactory
1215
        import math
1216

    
1217
        try:
1218
            appDocData = AppDocData.instance()
1219

    
1220
            # parse notes
1221
            for textInfoMap in otherTextInfoList:
1222
                if textInfoMap[0]=='Note':
1223
                    pass
1224

    
1225
                for textInfo in textInfoMap[1]:
1226
                    x = textInfo.getX()
1227
                    y = textInfo.getY()
1228
                    width = textInfo.getW()
1229
                    height = textInfo.getH()
1230
                    angle = round(math.radians(textInfo.getAngle()))
1231
                    text = textInfo.getText()
1232

    
1233
                    item = TextItemFactory.instance().createTextItem(text)
1234

    
1235
                    item.loc = (x, y)
1236
                    item.size = (width, height)
1237
                    item.angle = angle
1238
                    item.setPlainText(text)
1239
                    item.area = textInfoMap[0]
1240
                    self.addTextItemToScene(item)
1241
                    appDocData.texts.append(item)
1242

    
1243
        except Exception as ex:
1244
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1245
            self.addMessage.emit(MessageType.Error, message)
1246

    
1247

    
1248
    '''
1249
        @brief  draw unknown items 
1250
        @author humkyung
1251
        @date   2018.06.12
1252
        @history    2018.06.14  Jeongwoo    Change method to add unknown item
1253
                    2018.06.18  Jeongwoo    Add connect on unknown item
1254
                                            Add [transfer] for using pyqtSignal
1255
    '''
1256
    def drawUnknownItems(self):
1257
        from QEngineeringFlowArrowItem import QEngineeringFlowArrowItem 
1258
        from EngineeringLineItem import QEngineeringLineItem
1259
        from EngineeringUnknownItem import QEngineeringUnknownItem
1260

    
1261
        try:
1262
            docData = AppDocData.instance()
1263
            project = docData.getCurrentProject()
1264
            windowSize = docData.getSlidingWindowSize()
1265
            thickness = int(windowSize[1])
1266

    
1267
            diffFilePath = os.path.join(project.getTempPath(), "DIFF_" + os.path.basename(self.path))
1268
            if os.path.isfile(diffFilePath):
1269
                imgDiff = cv2.threshold(cv2.cvtColor(cv2.imread(diffFilePath, 1), cv2.COLOR_BGR2GRAY), 127, 255, cv2.THRESH_BINARY)[1]
1270

    
1271
                ## remove line
1272
                lines = [item for item in self.graphicsView.scene.items() if (type(item) is QEngineeringLineItem)]
1273
                for line in lines:
1274
                    line.drawToImage(imgDiff, 255, thickness)
1275
                cv2.imwrite(diffFilePath, imgDiff)
1276
                ## up to here
1277

    
1278
                imgNot = np.ones(imgDiff.shape, np.uint8)
1279
                cv2.bitwise_not(imgDiff, imgNot)
1280
                imgNot = cv2.dilate(imgNot, np.ones((8,8), np.uint8))
1281

    
1282
                diffItems = []
1283

    
1284
                image, contours, hierarchy = cv2.findContours(imgNot, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
1285
                for contour in contours:
1286
                    [x, y, w, h] = cv2.boundingRect(contour)
1287

    
1288
                    # remove too small one
1289
                    if (w < 10 or h < 10): continue
1290

    
1291
                    '''
1292
                    rect = QRectF(x, y, w, h)
1293
                    items = [item for item in diffItems if item.boundingRect().contains(rect)]
1294
                    if len(items) > 0: continue
1295
                    
1296
                    items = [item for item in diffItems if rect.contains(item.boundingRect())]
1297
                    for item in items:
1298
                        diffItems.remove(item)
1299
                    '''
1300

    
1301
                    # create unknown item
1302
                    epsilon = cv2.arcLength(contour, True)*0.001
1303
                    approx = cv2.approxPolyDP(contour, epsilon, True)
1304
                    approx = [pt[0] for pt in approx]
1305
                    item = QEngineeringUnknownItem(approx)
1306
                    item.ara = 'Drawing'
1307
                    diffItems.append(item)
1308
                    # up to here
1309

    
1310
                for item in diffItems:
1311
                    item.transfer.onRemoved.connect(self.itemRemoved)
1312
                    self.addUnknownItemToScene(item)
1313

    
1314
                notFilePath = os.path.join(project.getTempPath(), "NOT_" + os.path.basename(self.path))
1315
                cv2.imwrite(notFilePath, imgNot)
1316
            else:
1317
                message = 'can\'t found {}'.format(diffFilePath)
1318
                self.addMessage.emit(MessageType.Normal, message)
1319
        except Exception as ex:
1320
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1321
            self.addMessage.emit(MessageType.Error, message)
1322

    
1323
    '''
1324
        @brief      load recognition result
1325
        @author     humkyung
1326
        @date       2018.04.??
1327
        @history    humkyung 2018.01.12 parse originalpoint and connectionpoint
1328
                    Jeongwoo 2018.04.17 add QGraphicItem with Rotated text
1329
                    Jeongwoo 2018.04.23 Change to Draw texts on QEngineeringTextItem
1330
                    humkyung 2018.04.23 connect item remove slot to result tree
1331
                    Jeongwoo 2018.04.25 Add if state with QEngineeringNoteItem
1332
                    Jeongwoo 2018.04.26 Change method to create TextItem object with TextItemFactory
1333
                    Jeongwoo 2018.05.03 Change method to draw Svg Item on Scene (svg.addSvgItemToScene)
1334
                    Jeongwoo 2018.05.29 Change method name / Change method to add item / Add Line item
1335
                    Jeongwoo 2018.05.30 Add parameters on SymbolSvgItem.__init__() (parentSymbol, childSymbol) / Change method name / Change XML NODE NAMES
1336
                    Jeongwoo 2018.06.12 Add LineNoTextItem from LINE_NO
1337
                    Jeongwoo 2018.06.14 Add UnknownItem from UNKNOWN
1338
                    Jeongwoo 2018.06.18 Update Scene after all item added
1339
                                        Add connect on unknown item
1340
                                        Add [transfer] for using pyqtSignal
1341
                    kyouho  2018.07.12  Add line property logic
1342
                    humkyung 2018.08.22 show progress while loading xml file
1343
    '''
1344
    def loadRecognitionResultFromXml(self, xmlPath):
1345
        docData = AppDocData.instance()
1346
        from xml.etree.ElementTree import Element, SubElement, dump, ElementTree, parse
1347
        from EngineeringRunItem import QEngineeringRunItem
1348
        from QEngineeringTrimLineNoTextItem import QEngineeringTrimLineNoTextItem
1349

    
1350
        try:
1351
            symbols = []
1352

    
1353
            xml = parse(xmlPath)
1354
            root = xml.getroot()
1355
            
1356
            maxValue = 0
1357
            maxValue = maxValue + len(list(root.iter('SYMBOL')))
1358
            maxValue = maxValue + len(list(root.iter('ATTRIBUTE')))
1359
            maxValue = maxValue + len(list(root.iter('LINE_NO')))
1360
            maxValue = maxValue + len(list(root.iter('LINE')))
1361
            maxValue = maxValue + len(list(root.iter('UNKNOWN')))
1362
            self.progress.setMaximum(maxValue)
1363

    
1364
            for symbol in root.find('SYMBOLS').iter('SYMBOL'):
1365
                item = SymbolSvgItem.fromXml(symbol)
1366
                if item[0] is not None:
1367
                    item[0].transfer.onRemoved.connect(self.itemRemoved)
1368
                    symbols.append(item)
1369
                else:
1370
                    pt = [float(x) for x in symbol.find('LOCATION').text.split(',')]
1371
                    size = [float(x) for x in symbol.find('SIZE').text.split(',')]
1372
                    angle = float(symbol.find('ANGLE').text)
1373
                    item = QGraphicsBoundingBoxItem(pt[0], pt[1], size[0], size[1])
1374
                    item.isSymbol = True
1375
                    item.angle = angle
1376
                    item.setPen(QPen(Qt.red, 5, Qt.SolidLine))
1377
                    self.graphicsView.scene.addItem(item)
1378

    
1379
                self.progress.setValue(self.progress.value() + 1)
1380
                
1381
            QApplication.processEvents()
1382

    
1383
            # set symbol's owner
1384
            childItems = [item for item in symbols if item[1] is not None]
1385
            for item in childItems:
1386
                matches = [param for param in symbols if str(param[0].uid) == item[1]]
1387
                if len(matches) == 1:
1388
                    item[0].owner = matches[0][0]
1389
            # up to here
1390
           
1391
            for item in symbols:
1392
                self.addSvgItemToScene(item[0])
1393

    
1394
            # parse texts
1395
            for text in root.iter('ATTRIBUTE'):
1396
                item = QEngineeringTextItem.fromXml(text)
1397
                if item is not None:
1398
                    uid = text.find('UID')
1399
                    attributeValue = text.find('ATTRIBUTEVALUE')
1400
                    name = text.find('NAME').text
1401
                    item.transfer.onRemoved.connect(self.itemRemoved)
1402
                    self.addTextItemToScene(item)
1403

    
1404
                    if name == 'TEXT':
1405
                        if uid is not None and attributeValue is not None:
1406
                            item.uid = uid.text
1407
                            item.attribute = attributeValue.text
1408
                    elif name == 'NOTE':
1409
                        if uid is not None:
1410
                            item.uid = uid.text
1411

    
1412
                self.progress.setValue(self.progress.value() + 1)
1413
                
1414
            QApplication.processEvents()
1415

    
1416
            for line in root.find('LINEINFOS').iter('LINE'):
1417
                item = QEngineeringLineItem.fromXml(line)
1418
                item.transfer.onRemoved.connect(self.itemRemoved)
1419
                if item: self.addLineItemToScene(item)
1420

    
1421
                self.progress.setValue(self.progress.value() + 1)
1422
                
1423
            QApplication.processEvents()
1424

    
1425
            for unknown in root.iter('UNKNOWN'):
1426
                item = QEngineeringUnknownItem.fromXml(unknown)
1427
                item.transfer.onRemoved.connect(self.itemRemoved)
1428
                if item is not None:
1429
                    item.transfer.onRemoved.connect(self.itemRemoved)
1430
                    self.addUnknownItemToScene(item)
1431

    
1432
                self.progress.setValue(self.progress.value() + 1)
1433
                
1434
            QApplication.processEvents()
1435

    
1436
            for lineNo in root.iter('LINE_NO'):
1437
                location = lineNo.find('LOCATION').text if lineNo.find('LOCATION') is not None else '0,0'
1438
                x = float(location.split(',')[0])
1439
                y = float(location.split(',')[1])
1440
                width = float(lineNo.find('WIDTH').text) if lineNo.find('WIDTH') is not None else 0
1441
                height = float(lineNo.find('HEIGHT').text) if lineNo.find('HEIGHT') is not None else 0
1442
                angle = float(lineNo.find('ANGLE').text) if lineNo.find('ANGLE') is not None else 0
1443
                text = lineNo.find('TEXT').text
1444

    
1445
                item = TextItemFactory.instance().createTextItem(text)
1446
                if item is not None:
1447
                    item.loc = (x, y)
1448
                    item.size = (width, height)
1449
                    item.angle = angle
1450
                    item.setPlainText(text)
1451
                    item.transfer.onRemoved.connect(self.itemRemoved)
1452
                    self.addTextItemToScene(item)
1453

    
1454
                    # attr
1455
                    for userInputAttr in lineNo.iter('USERINPUTATTRIBUTE'):
1456
                        newAttr = UserInputAttribute(userInputAttr.find('TYPEUID').text, userInputAttr.find('TYPEVALUE').text)
1457
                        item.attrs.append(newAttr)
1458
                    for attr in lineNo.iter('ATTRIBUTE'):
1459
                        item.attrs[docData.getLinePropertiesByUID(attr.find('UID').text)[0]] = attr.find('VALUE').text
1460

    
1461
                connLine = lineNo.find('CONNLINE')
1462
                if connLine is not None:
1463
                    lineUID = connLine.text
1464
                    connLine = self.graphicsView.findItemByUid(lineUID)
1465
                    if connLine is not None:
1466
                        item.conns.append(connLine)
1467

    
1468
                run = lineNo.find('RUN')
1469
                if run is not None:
1470
                    lineRunItem = QEngineeringRunItem()
1471
                    for child in run:
1472
                        uidElement = child.find('UID')
1473
                        if uidElement is not None:
1474
                            uid = uidElement.text
1475
                            runItem = self.graphicsView.findItemByUid(uid)
1476
                            if runItem is not None:
1477
                                lineRunItem.items.append(runItem)
1478

    
1479
                    item.runs.append(lineRunItem)
1480
                    treeItem = self.resultTreeWidget.addTreeItem(self.resultTreeWidget.root, item)
1481
                    for connectedItem in lineRunItem.items:
1482
                        if issubclass(type(connectedItem), SymbolSvgItem): self.resultTreeWidget.addTreeItem(treeItem, connectedItem)
1483
                    docData.lineNos.append(item)
1484

    
1485
                self.progress.setValue(self.progress.value() + 1)
1486
            QApplication.processEvents()
1487

    
1488
            for trimLineNo in root.iter('TRIM_LINE_NO'):
1489
                item = QEngineeringTrimLineNoTextItem()
1490
                item.uid = trimLineNo.find('UID')
1491

    
1492
                run = trimLineNo.find('RUN')
1493
                if run is not None:
1494
                    lineRunItem = QEngineeringRunItem()
1495
                    for child in run:
1496
                        uidElement = child.find('UID')
1497
                        if uidElement is not None:
1498
                            uid = uidElement.text
1499
                            runItem = self.graphicsView.findItemByUid(uid)
1500
                            if runItem is not None:
1501
                                lineRunItem.items.append(runItem)
1502

    
1503
                    item.runs.append(lineRunItem)
1504
                    treeItem = self.resultTreeWidget.addTreeItem(self.resultTreeWidget.root, item)
1505
                    for connectedItem in lineRunItem.items:
1506
                        if issubclass(type(connectedItem), SymbolSvgItem): self.resultTreeWidget.addTreeItem(treeItem, connectedItem)
1507
                    docData.lineNos.append(item)
1508
            # up to here
1509

    
1510
            # set symbol's connectItem
1511
            from EngineeringConnectorItem import QEngineeringConnectorItem
1512
            connectors = [item for item in self.graphicsView.scene.items() if type(item) == QEngineeringConnectorItem and item.connectedItem is not None]
1513
            for connector in connectors:
1514
                # 처음에는 UID가 connectedItem에 String으로 들어가있기 때문에
1515
                connector.connectedItem = self.graphicsView.findItemByUid(connector.connectedItem)
1516

    
1517
            symbols = [item for item in self.graphicsView.scene.items() if issubclass(type(item), SymbolSvgItem) and len(item.attrs) > 0]
1518
            for symbol in symbols:
1519
                # 처음에는 attrs의 uid가 connectedItem에 String으로 들어가있기 때문에
1520
                for index in range(len(symbol.attrs)):
1521
                    if type(symbol.attrs[index]) is not UserInputAttribute and type(symbol.attrs[index]) is not tuple:
1522
                        symbol.attrs[index] = self.graphicsView.findItemByUid(symbol.attrs[index])
1523
                        
1524
            # Update Scene
1525
            self.graphicsView.scene.update(self.graphicsView.sceneRect())
1526

    
1527
        except Exception as ex:
1528
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1529
            self.addMessage.emit(MessageType.Error, message)
1530

    
1531
    '''
1532
        @brief      Remove added item on same place and Add GraphicsItem
1533
        @author     Jeongwoo
1534
        @date       2018.05.25
1535
        @history    2018.05.29  Jeongwoo    Moved from QRecognitionDialog
1536
                    2018.06.18  Jeongwoo    Set Z-index
1537
    '''
1538
    def addSvgItemToScene(self, svgItem):
1539
        svgItem.addSvgItemToScene(self.graphicsView.scene)
1540
        
1541
    '''
1542
        @brief      Remove added item on same place and Add GraphicsItem
1543
        @author     Jeongwoo
1544
        @date       2018.05.25
1545
        @history    2018.05.29  Jeongwoo    Moved from QRecognitionDialog
1546
                    2018.06.05  Jeongwoo    Remove Size condition
1547
                    2018.06.18  Jeongwoo    Set Z-index
1548
    '''
1549
    def addTextItemToScene(self, textItem):
1550
        textItem.addTextItemToScene(self.graphicsView.scene)
1551
        
1552
    '''
1553
        @brief      Remove added item on same place and Add GraphicsItem
1554
        @author     Jeongwoo
1555
        @date       2018.05.29
1556
        @history    2018.06.18  Jeongwoo    Set Z-index
1557
    '''
1558
    def addLineItemToScene(self, lineItem):
1559
        lineItem.addLineItemToScene(self.graphicsView.scene)
1560

    
1561
    '''
1562
        @brief      Remove added item on same place and Add Unknown Item
1563
        @author     Jeongwoo
1564
        @date       2018.06.14
1565
        @history    2018.06.18  Jeongwoo    Set Z-index
1566
    '''
1567
    def addUnknownItemToScene(self, unknownItem):
1568
        try:
1569
            unknownItem.addUnknownItemToScene(self.graphicsView.scene)
1570
        except Exception as ex:
1571
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1572
            self.addMessage.emit(MessageType.Error, message)
1573

    
1574
    '''
1575
        @brief      generate output xml file
1576
        @author     humkyung
1577
        @date       2018.04.23
1578
        @history    2018.05.02  Jeongwoo    Show MessageBox when imageviewer doesn't have image
1579
    '''
1580
    def generateOutput(self):
1581
        import XmlGenerator as xg
1582

    
1583
        if not self.graphicsView.hasImage():
1584
            self.showImageSelectionMessageBox()
1585
            return
1586

    
1587
        try:
1588
            appDocData = AppDocData.instance()
1589

    
1590
            ## collect items
1591
            appDocData.lines.clear()
1592
            appDocData.lines = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringLineItem and item.owner is None]
1593

    
1594
            appDocData.symbols.clear()
1595
            appDocData.symbols = [item for item in self.graphicsView.scene.items() if issubclass(type(item), SymbolSvgItem) and item.owner is None]
1596

    
1597
            appDocData.equipments.clear()
1598
            for item in self.graphicsView.scene.items():
1599
                if type(item) is QEngineeringEquipmentItem:
1600
                    appDocData.equipments.append(item)
1601

    
1602
            appDocData.texts.clear()
1603
            appDocData.texts = [item for item in self.graphicsView.scene.items() if issubclass(type(item), QEngineeringTextItem) and type(item) is not QEngineeringLineNoTextItem]
1604
            ## up to here
1605

    
1606
            appDocData.imgOutput = np.ones((appDocData.imgHeight, appDocData.imgWidth), np.uint8)*255
1607
            xg.writeOutputXml(appDocData.imgName, appDocData.imgWidth, appDocData.imgHeight) # TODO: check
1608
            project = appDocData.getCurrentProject()
1609
            cv2.imwrite(os.path.join(project.getTempPath() , 'OUTPUT.png') , appDocData.imgOutput)
1610
        except Exception as ex:
1611
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1612
            self.addMessage.emit(MessageType.Error, message)
1613

    
1614
    '''
1615
        @brief      resetting attribute at secne
1616
        @author     kyoyho
1617
        @date       2018.08.21
1618
    '''
1619
    def checkAttribute(self):
1620
        try:
1621

    
1622
            docData = AppDocData.instance()
1623
            if not self.graphicsView.hasImage():
1624
                return
1625

    
1626
            # symbol 경우
1627
            items = [item for item in self.graphicsView.scene.items() if issubclass(type(item), SymbolSvgItem)]
1628
            for item in items:
1629
                attrs = item.attrs
1630
                
1631
                removeAttrList = []
1632
                for attr in attrs:
1633
                    if type(attr) is tuple:
1634
                        continue
1635

    
1636
                    if attr is None:
1637
                        removeAttrList.append(attr)
1638
                        continue
1639

    
1640
                    attrInfo = docData.getSymbolAttributeByUID(attr.attribute)
1641
                    if attrInfo is None:
1642
                        removeAttrList.append(attr)
1643
                    # 해당 attribute가 맞는지 확인
1644
                    else:
1645
                        attrType = attrInfo[2]
1646
                        _type = type(attr)
1647
                        if attrType == 'Symbol Item':
1648
                            if not issubclass(_type, SymbolSvgItem):
1649
                                removeAttrList.append(attr)
1650
                        elif attrType == 'Text Item':
1651
                            if _type is not QEngineeringTextItem:
1652
                                removeAttrList.append(attr)
1653
                        elif attrType == 'Int':
1654
                            if _type is not UserInputAttribute and self.isNumber(attr.text):
1655
                                removeAttrList.append(attr)
1656
                        elif attrType == 'String':
1657
                            if _type is not UserInputAttribute:
1658
                                removeAttrList.append(attr)
1659

    
1660
                for attr in removeAttrList:
1661
                    attrs.remove(attr)
1662

    
1663
            # Line No Text Item의 경우
1664
            items = [item for item in self.graphicsView.scene.items() if issubclass(type(item), QEngineeringLineNoTextItem)]
1665
            for item in items:
1666
                attrs = item.attrs
1667
                
1668
                removeAttrList = []
1669
                for attr in attrs:
1670
                    if type(attr) is UserInputAttribute:
1671
                        attrInfo = docData.getLinePropertiesByUID(attr.attribute)
1672
                        if attrInfo is None:
1673
                            removeAttrList.append(attr)
1674

    
1675
                for attr in removeAttrList:
1676
                    attrs.remove(attr)
1677

    
1678
        except Exception as ex:
1679
                message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1680
                self.addMessage.emit(MessageType.Error, message)
1681
    '''
1682
        @brief      Check Number
1683
        @author     kyouho
1684
        @date       2018.08.20
1685
    '''
1686
    def isNumber(self, num):
1687
        p = re.compile('(^[0-9]+$)')
1688
        result = p.match(num)
1689

    
1690
        if result:
1691
            return True
1692
        else:
1693
            return False
1694

    
1695
    '''
1696
        @brief      find overlap Connector
1697
        @author     kyouho
1698
        @date       2018.08.28
1699
    '''
1700
    def findOverlapConnector(self, connectorItem):
1701
        from shapely.geometry import Point
1702
        from EngineeringConnectorItem import QEngineeringConnectorItem
1703
        itemList = []
1704
        
1705
        x = connectorItem.center()[0]
1706
        y = connectorItem.center()[1]
1707

    
1708
        connectors = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringConnectorItem and item != connectorItem]
1709
        for connector in connectors:
1710
            if Point(x, y).distance(Point(connector.center()[0], connector.center()[1])) < 5:
1711
                itemList.append(connector.parent)
1712

    
1713
        return itemList
1714

    
1715
            
1716
if __name__ == '__main__':
1717
    from ProjectDialog import Ui_Dialog
1718
    from App import App 
1719

    
1720
    app = App(sys.argv)
1721
    try:
1722
        dlg = Ui_Dialog()
1723
        selectedProject = dlg.showDialog()
1724
        if selectedProject is not None:
1725
            AppDocData.instance().setCurrentProject(selectedProject)
1726
            app._mainWnd = MainWindow.instance()
1727
            app._mainWnd.show()
1728
            sys.exit(app.exec_())
1729
    except Exception as ex:
1730
        print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
1731
    finally:
1732
        pass
클립보드 이미지 추가 (최대 크기: 500 MB)