프로젝트

일반

사용자정보

통계
| 개정판:

hytos / DTI_PID / DTI_PID / MainWindow.py @ 1669b150

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

1
# coding: utf-8
2

    
3
import sys
4
import os
5
import subprocess
6

    
7
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
8
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Commands')
9
import CreateCommand
10
import CropCommand
11
import AreaOcrCommand
12
import CreateSymbolCommand
13
import AreaZoomCommand
14
import SelectAttributeCommand
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 QEngineeringInstrumentItem 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
    '''
73
    def __init__(self):
74
        super(self.__class__, self).__init__()
75
        self.setupUi(self)
76
        self.labelStatus = QLabel(self.statusbar)
77
        self.labelStatus.setText('미인식 : ')
78
        self.labelSymbolStatus = QLabel(self.statusbar)
79
        self.labelSymbolStatus.setText('심볼 : ')
80
        self.labelLineStatus = QLabel(self.statusbar)
81
        self.labelLineStatus.setText('라인 : ')
82
        self.labelTextStatus = QLabel(self.statusbar)
83
        self.labelTextStatus.setText('텍스트 : ')
84
        self.statusbar.addPermanentWidget(self.labelSymbolStatus)
85
        self.statusbar.addPermanentWidget(self.labelLineStatus)
86
        self.statusbar.addPermanentWidget(self.labelTextStatus)
87
        self.statusbar.addPermanentWidget(self.labelStatus) 
88

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

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

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

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

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

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

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

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

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

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

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

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

    
203
    def onShowDetectSymbol(self):
204
        from DetectSymbolDialog import QDetectSymbolDialog
205

    
206
        dlgDetectSymbol = QDetectSymbolDialog(self)
207
        dlgDetectSymbol.show()
208
        dlgDetectSymbol.exec_()
209
        
210
    '''
211
        @brief      OCR Editor
212
        @author     euisung
213
        @date       2018.10.05
214
    '''
215
    def oCRTrainingEdidorClicked(self):
216
        from TrainingEditorDialog import QTrainingEditorDialog
217

    
218
        try:
219
            dialog = QTrainingEditorDialog(self)
220
            dialog.exec_()
221
        except Exception as ex:
222
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
223
            
224
        return
225

    
226
    '''
227
        @brief      OCR Training
228
        @author     euisung
229
        @date       2018.09.27
230
        @history    euisung 2018.10.16 TrainingListDialog -> TrainingImageListDialog
231
    '''
232
    def oCRTrainingClicked(self):
233
        from TrainingImageListDialog import QTrainingImageListDialog
234

    
235
        try:
236
            #appDocData = AppDocData.instance()
237
            #project = appDocData.getCurrentProject()
238

    
239
            #path = project.getDrawingFilePath()
240

    
241
            #print(path)
242
            dialog = QTrainingImageListDialog(self)
243
            dialog.exec_()
244
        except Exception as ex:
245
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
246
            
247
        return
248

    
249
    '''
250
        @brief      show unknownitem's count
251
        @author     kyouho
252
        @date       2018.08.27
253
    '''
254
    def findReplaceTextClicked(self):
255
        if not self.graphicsView.hasImage():
256
            self.showImageSelectionMessageBox()
257
            return
258

    
259
        from TextItemEditDialog import QTextItemEditDialog
260

    
261
        self.dlgTextItemEdit = QTextItemEditDialog(self)
262
        self.dlgTextItemEdit.show()
263
        self.dlgTextItemEdit.exec_()
264

    
265
    '''
266
        @brief      show unknownitem's count
267
        @author     humkyung
268
        @date       2018.08.23
269
        @history    humkyung 2018.08.30 display count of symbol, line, text
270
    '''
271
    def onSceneChanged(self):
272
        items = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringUnknownItem]
273
        if len(items) > 0:
274
            self.labelStatus.setText("<font color='red'>미인식 : {}</font>".format(len(items)))
275
        else:
276
            self.labelStatus.setText("<font color='black'>미인식 : {}</font>".format(len(items)))
277

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

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

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

    
287
    '''
288
        @brief      action save click event
289
        @author     kyouho
290
        @date       2018.08.09
291
    '''
292
    def actionSaveCliked(self):
293
        self.saveToXml(True)
294

    
295
    '''
296
        @brief      save items to xml
297
        @author     kyouho
298
        @date       2018.07.31
299
    '''
300
    def saveToXml(self, alert = True):
301
        import XmlGenerator as xg
302
        from AppDocData import AppDocData
303
        docData = AppDocData.instance()
304
        if docData.imgName is None:
305
            self.showImageSelectionMessageBox()
306
            return
307
        result = xg.writeXmlOnScene(docData.imgName, docData.imgWidth, docData.imgHeight, self.graphicsView.scene)
308
        
309
        if len(self.removedItems['LINE']):
310
            docData.deleteLineDataList_LineNo(self.removedItems['LINE'])
311
            self.removedItems['LINE'] = []
312

    
313
        if len(self.removedItems['EQUIP']):
314
            docData.deleteEquipDataList(self.removedItems['EQUIP'])
315
            self.removedItems['EQUIP'] = []
316

    
317
        if len(self.removedItems['INST']):
318
            docData.deleteInstDataList(self.removedItems['INST'])
319
            self.removedItems['INST'] = []
320

    
321
        if len(self.removedItems['NOTE']):
322
            docData.deleteNoteDataList(self.removedItems['NOTE'])
323
            self.removedItems['NOTE'] = []
324

    
325

    
326
        if alert:
327
            resultStr = '[저장 결과]'
328

    
329
            for item in result.items():
330
                itemName = str(item[0])
331
                itemSuccessCount = str(item[1][0])
332
                itemFailUidList = item[1][1]
333
                resultStr += "\r\n" + itemName + " Save Count : " + itemSuccessCount
334
                if len(itemFailUidList) > 0:
335
                    resultStr += "\r\n" + itemName + " Error List(UID)"
336
                    for uid in itemFailUidList:
337
                        resultStr += "\r\n" + uid
338

    
339
            QMessageBox.about(self.graphicsView, "알림", resultStr)
340

    
341
    '''
342
        @brief      refresh resultPropertyTableWidget
343
        @author     kyouho
344
        @date       2018.07.19
345
    '''
346
    def refreshResultPropertyTableWidget(self):
347
        items = self.graphicsView.scene.selectedItems()
348
        if len(items) == 1:
349
            self.resultPropertyTableWidget.onSymbolClicked(items[0])
350
    
351
    '''
352
        @brief      resultPropertyTableWidget Cell Click Event
353
        @author     kyouho
354
        @date       2018.08.23
355
    '''
356
    def cellClickedEvent(self, row, column):
357
        item = self.graphicsView.scene.selectedItems()
358
        if len(item) != 1:
359
            return
360
        item = item[0]
361

    
362
        cell = self.resultPropertyTableWidget.item(row, column)
363
        for valueCell, uid in self.resultPropertyTableWidget.attrValueList:
364
            if valueCell == cell and issubclass(type(item), SymbolSvgItem):
365
                for attr in item.attrs:
366
                    if attr.attribute == uid and (issubclass(type(attr), SymbolSvgItem) or type(attr) is QEngineeringTextItem):
367
                        prevItem = item
368
                        currentItem = attr
369

    
370
                        rect = currentItem.sceneBoundingRect()
371
                        self.graphicsView.centerOn(rect.center())
372
                        self.graphicsView.zoomImage(True, QMouseEvent(QEvent.MouseButtonPress, self.graphicsView.mapFromScene(QPointF(rect.left(), rect.top())), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier), 3)
373
                        prevItem.setSelected(True)
374

    
375
                        currentItem.setHightlight()
376
                    elif (issubclass(type(attr), SymbolSvgItem) or type(attr) is QEngineeringTextItem):
377
                        attr.unsetHightlight()
378

    
379
    '''
380
        @brief      resultPropertyTableWidget Cell Double Click Event
381
        @author     kyouho
382
        @date       2018.07.19
383
    '''
384
    def cellDoubleClickedEvent(self, row, column):
385
        if column == 1:
386
            cell = self.resultPropertyTableWidget.item(row, column)
387

    
388
            uid = None
389
            for data in self.resultPropertyTableWidget.attrValueList:
390
                if data[0] == cell:
391
                    uid = data[1]
392
                    break
393
            
394
            items = self.graphicsView.scene.selectedItems()
395
                
396
            if uid is not None:
397
                if items is not None and len(items) == 1:
398
                    if issubclass(type(items[0]), SymbolSvgItem):
399
                        docData = AppDocData.instance()
400
                        attrType = docData.getSymbolAttributeByUID(uid)
401
                        if attrType[2] == 'Text Item' or attrType[2] == 'Symbol Item':
402
                            self.graphicsView.command = SelectAttributeCommand.SelectAttributeCommand(self.graphicsView)
403
                            self.graphicsView.command.setType(attrType[2])
404
                            cursor = QCursor(Qt.PointingHandCursor)
405
                            QApplication.instance().setOverrideCursor(cursor)
406
                            self.graphicsView.currentAttribute = uid
407
                            
408
                            # 기존 cellText를 가진 attrs 삭제
409
                            items[0].removeSelfAttr(uid)
410

    
411
                            from PyQt5 import QtGui
412
                            cellItem = QTableWidgetItem('')
413
                            icon = QtGui.QIcon()
414
                            icon.addPixmap(QtGui.QPixmap(":/newPrefix/doubleclick.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
415
                            cellItem.setIcon(icon)
416
                            self.resultPropertyTableWidget.setItem(row, 1, cellItem)
417

    
418
                        else:
419
                            self.resultPropertyTableWidget.editItem(cell)
420
                    else:
421
                        self.resultPropertyTableWidget.editItem(cell)
422
            elif items is not None and len(items) == 1 and type(items[0]) is QEngineeringLineNoTextItem:
423
                connCell = self.resultPropertyTableWidget.item(row, 0)
424
                if connCell.text() == 'CONN':
425
                    ## Line No Text Item의 CONN 속성 초기화
426
                    items[0].conns.clear()
427

    
428
                    self.graphicsView.command = SelectAttributeCommand.SelectAttributeCommand(self.graphicsView)
429
                    self.graphicsView.command.setType('Line Item')
430
                    cursor = QCursor(Qt.PointingHandCursor)
431
                    QApplication.instance().setOverrideCursor(cursor)
432
                    
433
                    from PyQt5 import QtGui
434
                    cellItem = QTableWidgetItem('')
435
                    icon = QtGui.QIcon()
436
                    icon.addPixmap(QtGui.QPixmap(":/newPrefix/doubleclick.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
437
                    cellItem.setIcon(icon)
438
                    self.resultPropertyTableWidget.setItem(row, 1, cellItem)
439

    
440
            #cell = self.resultPropertyTableWidget.item(row, 0)
441
            #if cell is not None and self.resultPropertyTableWidget.item(row, 0).text():
442
            #    cellText = self.resultPropertyTableWidget.item(row, 0).text()
443
            #    docData = AppDocData.instance()
444

    
445

    
446
            #    if docData.checkAttribute(cellText):
447
            #        items = self.graphicsView.scene.selectedItems()
448
            #        if items is not None and len(items) == 1:
449
            #            self.graphicsView.command = SelectAttributeCommand.SelectAttributeCommand(self.graphicsView)
450
            #            cursor = QCursor(Qt.PointingHandCursor)
451
            #            QApplication.instance().setOverrideCursor(cursor)
452
            #            self.graphicsView.currentAttribute = cellText
453
                        
454
            #            # 기존 cellText를 가진 attrs 삭제
455
            #            items[0].removeSelfAttr(cellText)
456

    
457
            #            from PyQt5 import QtGui
458
            #            cellItem = QTableWidgetItem('')
459
            #            icon = QtGui.QIcon()
460
            #            icon.addPixmap(QtGui.QPixmap(":/newPrefix/doubleclick.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
461
            #            cellItem.setIcon(icon)
462
            #            self.resultPropertyTableWidget.setItem(row, 1, cellItem)
463
    
464
    '''
465
        @brief  add message listwidget
466
        @author humkyung
467
        @date   2018.07.31
468
    '''
469
    def onAddMessage(self, messageType, message):
470
        from AppDocData import MessageType
471

    
472
        try:
473
            current = QDateTime.currentDateTime()
474

    
475
            item = QListWidgetItem('{}: {}'.format(current.toString('hh:mm:ss'), message))
476
            if messageType == MessageType.Error:
477
                item.setBackground(Qt.red)
478

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

    
483
    '''
484
        @brief      clear log
485
        @author     humkyung
486
        @date       2018.08.01
487
    '''
488
    def onClearLog(self):
489
        self.listWidgetLog.clear()
490

    
491
    '''
492
        @brief      rotate selected symbol
493
        @author     humkyung
494
        @date       2018.08.15
495
    '''
496
    def onRotate(self, action):
497
        selected = [item for item in self.graphicsView.scene.selectedItems() if issubclass(type(item), SymbolSvgItem)]
498
        if len(selected) == 1:
499
            selected[0].rotateSymbol()
500

    
501
    '''
502
        @brief      Area Zoom
503
        @author     Jeongwoo
504
        @date       2018.06.27
505
        @history    connect command's rejected signal
506
    '''
507
    def onAreaZoom(self, action):
508
        if self.actionZoom.isChecked():
509
            cmd = AreaZoomCommand.AreaZoomCommand(self.graphicsView)
510
            cmd.onRejected.connect(self.onCommandRejected)
511
            self.graphicsView.command = cmd
512

    
513
    '''
514
        @brief      Fit Window
515
        @author     Jeongwoo
516
        @date       2018.06.27
517
        @history    2018.06.27  Jeongwoo    Chnage method to initialize command [Set None → DefaultCommand]
518
    '''
519
    def fitWindow(self, action):
520
        self.graphicsView.useDefaultCommand()
521
        self.graphicsView.zoomImageInit()
522

    
523
    def onConvertPDFToImage(self):
524
        """
525
        @brief      convert to selected pdf to image
526
        @author     humkyung 
527
        @date       2018.07.09
528
        @history    Euisung 2018.10.11 hide shell
529
        """
530
        try: 
531
            filePath = os.path.join(os.path.dirname(os.path.realpath(__file__)) , 'bin64', 'PDF_TO_IMAGE.exe')
532
            subprocess.call(filePath, shell = False)
533
        except Exception as ex:
534
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
535

    
536
    '''
537
        @brief      selection changed
538
        @author     humkyung
539
        @date       2018.06.27
540
        @history    humkung 2018.07.08 call tree widget's findItem
541
    '''
542
    def onSelectionChanged(self):
543
        items = [item for item in self.graphicsView.scene.selectedItems() if issubclass(type(item), SymbolSvgItem) or \
544
            type(item) is QEngineeringLineItem or type(item) is QEngineeringLineNoTextItem or type(item) is QEngineeringNoteItem]
545
        if items:
546
            item = items[-1]
547
            self.resultTreeWidget.findItem(item)
548
            self.resultPropertyTableWidget.showItemProperty(item)
549
        else:
550
            self.resultPropertyTableWidget.showItemProperty(None)
551
        
552
    '''
553
        @brief      Initialize scene and ResultTreeWidget
554
        @author     Jeongwoo
555
        @date       2018.06.14
556
        @history    humkyung 2018.08.16 ask to delete recognized items before remove
557
    '''
558
    def onInitializeScene(self, action):
559
        if not self.graphicsView.hasImage():
560
            self.actionEquipment.setChecked(False)
561
            self.showImageSelectionMessageBox()
562

    
563
            return
564

    
565
        msg = QMessageBox()
566
        msg.setIcon(QMessageBox.Critical)
567
        msg.setText("선택한 인식한 항목들을 삭제하시겠습니까?\n삭제된 항목들은 복구할 수 없습니다.")
568
        msg.setWindowTitle("항목 삭제")
569
        msg.setStandardButtons(QMessageBox.Ok|QMessageBox.Cancel)
570
        if QMessageBox.Ok == msg.exec_():
571
            items = self.graphicsView.scene.items()
572
            for item in items:
573
                if type(item) is not QGraphicsPixmapItem:
574
                    self.graphicsView.scene.removeItem(item)
575

    
576
                    if type(item) is QEngineeringLineNoTextItem:
577
                        self.removedItems['LINE'].append(str(item.uid))
578
                    elif type(item) is QEngineeringInstrumentItem:
579
                        self.removedItems['INST'].append(str(item.uid))
580
                    elif type(item) is QEngineeringEquipmentItem:
581
                        self.removedItems['EQUIP'].append(str(item.uid))
582
                    elif type(item) is QEngineeringNoteItem:
583
                        self.removedItems['NOTE'].append(str(item.uid))
584
                    
585
            if self.path is not None:
586
                baseName = os.path.basename(self.path)
587
                self.resultTreeWidget.setCurrentPID(baseName)
588

    
589
    '''
590
        @brief      Manage Checkable Action statement
591
        @author     Jeongwoo
592
        @date       2018.05.10
593
        @history    2018.06.27  Jeongwoo    Chnage method to initialize command [Set None → DefaultCommand]
594
    '''
595
    def actionGroupTriggered(self, action):
596
        if self.graphicsView.command is not None:
597
            self.graphicsView.useDefaultCommand()
598

    
599
        for _action in self.actionGroup.actions():
600
            _action.setChecked(False)
601

    
602
        action.setChecked(True)
603

    
604
    '''
605
        @brief      Create Equipment
606
        @author     Jeongwoo
607
        @date       18.05.03
608
        @history    2018.05.04  Jeongwoo    Add Parameter on CreateSymbolCommand
609
    '''
610
    def createEquipment(self):
611
        if not self.graphicsView.hasImage():
612
            self.actionEquipment.setChecked(False)
613
            self.showImageSelectionMessageBox()
614
            return
615
        if self.actionEquipment.isChecked():
616
            self.graphicsView.command = CreateSymbolCommand.CreateSymbolCommand(self.graphicsView, self.resultTreeWidget, self.dirTreeWidget)
617
        else:
618
            self.graphicsView.useDefaultCommand()
619

    
620

    
621
    '''
622
        @brief      Create Nozzle
623
        @author     Jeongwoo
624
        @date       2018.05.03
625
        @history    2018.05.04  Jeongwoo    Add Parameter on CreateSymbolCommand
626
    '''
627
    def createNozzle(self):
628
        if not self.graphicsView.hasImage():
629
            self.actionNozzle.setChecked(False)
630
            self.showImageSelectionMessageBox()
631
            return
632
        if self.actionNozzle.isChecked():
633
            self.graphicsView.command = CreateSymbolCommand.CreateSymbolCommand(self.graphicsView, self.resultTreeWidget, self.dirTreeWidget)
634
        else:
635
            self.graphicsView.useDefaultCommand()
636

    
637
    '''
638
        @brief      Area OCR
639
        @author     Jeongwoo
640
        @date       18.04.18
641
        @history    2018.05.02  Jeongwoo    Change graphicsView.command by actionOCR checked state
642
                                            Show MessageBox when imageviewer doesn't have image
643
    '''
644
    def onAreaOcr(self):
645
        if not self.graphicsView.hasImage():
646
            self.actionOCR.setChecked(False)
647
            self.showImageSelectionMessageBox()
648
            return
649

    
650
        if self.actionOCR.isChecked():
651
            cmd = AreaOcrCommand.AreaOcrCommand(self.graphicsView)
652
            cmd.onSuccess.connect(self.onRecognizeText)
653
            cmd.onRejected.connect(self.onCommandRejected)
654
            self.graphicsView.command = cmd
655
        else:
656
            self.graphicsView.useDefaultCommand()
657
    
658
    '''
659
        @brief      show text recognition dialog
660
        @author     humkyung
661
        @date       2018.08.08
662
    '''
663
    def onRecognizeText(self, x, y, width, height):
664
        from OcrResultDialog import QOcrResultDialog
665

    
666
        try:
667
            image = self.graphicsView.image().copy(x, y, width, height)
668
            dialog = QOcrResultDialog(self.graphicsView, image, QRectF(x, y, width, height))
669
            (isAccept, textInfoList) = dialog.showDialog()
670
            if isAccept:
671
                if textInfoList is not None and len(textInfoList) > 0:
672
                    docData = AppDocData.instance()
673
                    configs = docData.getConfigs('Line No', 'Delimiter')
674
                    delimiter = configs[0].value if 1 == len(configs) else '-'
675
                    lineNoconfigs = docData.getConfigs('Line No', 'Configuration')
676
                    for textInfo in textInfoList:
677
                        x = textInfo.getX()
678
                        y = textInfo.getY()
679
                        angle = textInfo.getAngle()
680
                        text = textInfo.getText()
681
                        width = textInfo.getW()
682
                        height = textInfo.getH()
683
                        item = TextItemFactory.instance().createTextItem(text)
684
                        if item is not None:
685
                            item.loc = (x, y)
686
                            item.size = (width, height)
687
                            item.angle = angle
688
                            item.setPlainText(text)
689
                            item.setDefaultTextColor(Qt.blue)
690
                            item.addTextItemToScene(self.graphicsView.scene)
691
                            item.transfer.onRemoved.connect(self.itemRemoved)
692
                        else:
693
                            message = 'error occured({}) in {}:{}'.format('텍스트 생성에 실패했습니다.', sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
694
                            self.addMessage.emit(MessageType.Normal, message)
695
                else:
696
                    QMessageBox.about(self.graphicsView, "알림", "텍스트 검출 실패")
697
        except Exception as ex:
698
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
699
            self.addMessage.emit(MessageType.Error, message)
700

    
701
    '''
702
        @brief  area configuration
703
    '''
704
    def areaConfiguration(self):
705
        from ConfigurationAreaDialog import QConfigurationAreaDialog
706

    
707
        self.dlgConfigurationArea = QConfigurationAreaDialog(self)
708
        self.dlgConfigurationArea.show()
709
        self.dlgConfigurationArea.exec_()
710

    
711
    '''
712
        @brief  configuration
713
    '''
714
    def configuration(self):
715
        from ConfigurationDialog import QConfigurationDialog
716

    
717
        self.dlgConfiguration = QConfigurationDialog(self)
718
        self.dlgConfiguration.show()
719
        self.dlgConfiguration.exec_()
720

    
721
    '''
722
        @brief  show nominal diameter dialog 
723
        @author humkyung
724
        @date   2018.06.28
725
    '''
726
    def onShowCodeTable(self):
727
        from CodeTableDialog import QCodeTableDialog
728

    
729
        dlg = QCodeTableDialog(self)
730
        dlg.exec_()
731

    
732
    '''
733
        @brief  show HMB data
734
        @author humkyung
735
        @date   2018.07.11
736
    '''
737
    def onHMBData(self):
738
        from HMBDialog import QHMBDialog
739

    
740
        dlg = QHMBDialog(self)
741
        dlg.show()
742
        dlg.exec_()
743

    
744
    '''
745
        @brief  show line data list 
746
        @author humkyung
747
        @date   2018.05.03
748
    '''
749
    def showItemDataList(self):
750
        from ItemDataExportDialog import QItemDataExportDialog
751

    
752
        self.dlgLineDataList = QItemDataExportDialog(self)
753
        self.dlgLineDataList.exec_()
754

    
755
    '''
756
        @brief  Show Image Selection Guide MessageBox
757
        @author Jeongwoo
758
        @date   2018.05.02
759
    '''
760
    def showImageSelectionMessageBox(self):
761
        QMessageBox.about(self.graphicsView, "알림", "이미지를 선택하신 후 시도해주세요.")
762
        
763
    '''
764
        @brief  change selected lines' type by selected line type
765
        @author humkyung
766
        @date   2018.06.27
767
    '''
768
    def onLineTypeChanged(self, param):
769
        lineType = self.lineComboBox.itemText(param)
770
        selected = [item for item in self.graphicsView.scene.selectedItems() if type(item) is QEngineeringLineItem]
771
        if selected:
772
            for item in selected:
773
                item.lineType = lineType
774

    
775
    '''
776
        @brief      Open image drawing file and then display it
777
        @author     humkyung
778
        @date       2018.??.??
779
        @history    18.04.23 Jeongwoo    Add AppDocData.instance().setCurrentPidSource
780
                    18.04.23 Jeongwoo    Add Store Set Current Pid Image on AppDocData
781
                    18.05.02 Jeongwoo    Add useDefaultCommand()
782
                    humkyung 2018.05.24 load recognition result file if exists
783
                    Jeongwoo 2018.05.29 load data on xml if xml file exist
784
                    humkyung 2018.08.22 clear scene before loading xml file
785
    '''
786
    def onOpenImageDrawing(self, MainWindow):
787
        from Drawing import Drawing
788

    
789
        try:
790
            appDocData = AppDocData.instance()
791
            project = appDocData.getCurrentProject()
792
            
793
            for item in self.graphicsView.scene.items():
794
                self.graphicsView.scene.removeItem(item)
795

    
796
            self.path = self.graphicsView.loadImageFromFile(project.getDrawingFilePath())
797
            if os.path.isfile(self.path):
798
                appDocData.clear()
799
                self.graphicsView.useDefaultCommand()
800

    
801
                appDocData.setImgFilePath(self.path)
802
                appDocData.activeDrawing = Drawing(appDocData.imgName)
803
                appDocData.setCurrentPidSource(Image.open(self.path))
804
                self.resultTreeWidget.setCurrentPID(appDocData.activeDrawing.name)
805

    
806
                self.progress = QProgressDialog("잠시만 기다려주세요", "Cancel", 0, 100, self)
807
                self.progress.setWindowModality(Qt.WindowModal)
808
                self.progress.setAutoReset(True)
809
                self.progress.setAutoClose(True)
810
                self.progress.setMinimum(0)
811
                self.progress.resize(600,100)
812
                self.progress.setWindowTitle("파일 읽는 중...")
813
                self.progress.show()
814

    
815
                ## Load data on xml
816
                try:
817
                    path = os.path.join(appDocData.getCurrentProject().getTempPath(), appDocData.imgName + '.xml')
818
                    if os.path.isfile(path):
819
                        self.loadRecognitionResultFromXml(path)
820
                        self.checkAttribute()
821
                finally:
822
                    self.progress.setValue(self.progress.maximum())
823
                    self.progress.hide()
824
        except Exception as ex:
825
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
826
            self.addMessage.emit(MessageType.Error, message)
827

    
828
        return self.path
829

    
830
    '''
831
        @brief  visible/invisible image drawing
832
        @author humkyung
833
        @date   2018.06.25
834
    '''
835
    def onViewImageDrawing(self, isChecked):
836
        for item in self.graphicsView.scene.items():
837
            if type(item) is QGraphicsPixmapItem:
838
                item.setVisible(isChecked)
839
                break
840

    
841
    '''
842
        @brief  visible/invisible Text 
843
        @author humkyung
844
        @date   2018.06.28
845
    '''
846
    def onViewText(self, isChecked):
847
        selected = [item for item in self.graphicsView.scene.items() if issubclass(type(item), QEngineeringTextItem)]
848
        for item in selected:
849
            item.setVisible(isChecked)
850

    
851
    '''
852
        @brief  visible/invisible Symbol 
853
        @author humkyung
854
        @date   2018.06.28
855
    '''
856
    def onViewSymbol(self, isChecked):
857
        selected = [item for item in self.graphicsView.scene.items() if issubclass(type(item), SymbolSvgItem)]
858
        for item in selected:
859
            item.setVisible(isChecked)
860

    
861
    '''
862
        @brief  visible/invisible Line
863
        @author humkyung
864
        @date   2018.06.28
865
    '''
866
    def onViewLine(self, isChecked):
867
        selected = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringLineItem]
868
        for item in selected:
869
            item.setVisible(isChecked)
870

    
871
    '''
872
        @brief  visible/invisible Unknown 
873
        @author humkyung
874
        @date   2018.06.28
875
    '''
876
    def onViewUnknown(self, isChecked):
877
        selected = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringUnknownItem]
878
        for item in selected:
879
            item.setVisible(isChecked)
880

    
881
    '''
882
        @brief  create a symbol
883
        @history    2018.05.02  Jeongwoo    Change return value of QSymbolEditorDialog (Single variable → Tuple)
884
                                            Add SymbolSvgItem
885
                    2018.05.03  Jeongwoo    Change method to draw Svg Item on Scene (svg.addSvgItemToScene)
886
                                            Change method to make svg and image path
887
                    2018.06.08  Jeongwoo    Add Paramter on SymbolSvgItem.buildItem()
888
    '''
889
    def onCreateSymbolClicked(self):
890
        cmd = FenceCommand.FenceCommand(self.graphicsView)
891
        cmd.onSuccess.connect(self.onAreaSelected)
892
        self.graphicsView.command = cmd
893
        QApplication.setOverrideCursor(Qt.CrossCursor)
894

    
895
    '''
896
        @brief      show SymbolEditorDialog with image selected by user
897
        @author     humkyung
898
        @date       2018.07.20
899
    '''
900
    def onAreaSelected(self, x, y, width, height):
901
        try:
902
            image = self.graphicsView.image()
903
            if image is not None:
904
                symbolEditorDialog = SymbolEditorDialog.QSymbolEditorDialog(self, image.copy(x, y, width, height), AppDocData.instance().getCurrentProject())
905
                (isAccepted, isImmediateInsert, offsetX, offsetY, newSym) = symbolEditorDialog.showDialog()
906
                self.dirTreeWidget.initDirTreeWidget()
907
                if isAccepted:
908
                    if isImmediateInsert:
909
                        svgPath = newSym.getSvgFileFullPath()
910
                        img = cv2.imread(newSym.getImageFileFullPath(), 1)
911
                        w, h = (0, 0)
912
                        if len(img.shape[::-1]) == 2:
913
                            w, h = img.shape[::-1]
914
                        else:
915
                            _chan, w, h = img.shape[::-1]
916
                        svg = SymbolSvgItem(svgPath)
917
                        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)
918

    
919
                        svg.transfer.onRemoved.connect(self.resultTreeWidget.itemRemoved)
920
                        svg.addSvgItemToScene(self.graphicsView.scene)
921
                        for connector in svg.connectors:
922
                            self.graphicsView.scene.addItem(connector)
923
        finally:
924
            self.graphicsView.useDefaultCommand()
925
            QApplication.restoreOverrideCursor()
926
    
927
    '''
928
        @brief      create a line
929
        @author     humkyung
930
        @history    Jeongwoo 2018.05.10 Change method for Checkable action
931
    '''
932
    def onPlaceLine(self):        
933
        if not self.graphicsView.hasImage():
934
            self.actionLine.setChecked(False)
935
            self.showImageSelectionMessageBox()
936
            return
937

    
938
        self.actionLine.setChecked(True)
939
        if not hasattr(self.actionLine, 'tag'):
940
            self.actionLine.tag = PlaceLineCommand.PlaceLineCommand(self.graphicsView)
941
            self.actionLine.tag.onSuccess.connect(self.onLineCreated)
942
            self.actionLine.tag.onRejected.connect(self.onCommandRejected)
943

    
944
        self.graphicsView.command = self.actionLine.tag
945

    
946
    '''
947
        @brief      add created lines to scene
948
        @author     humkyung
949
        @date       2018.07.23
950
    '''
951
    def onLineCreated(self):
952
        from EngineeringConnectorItem import QEngineeringConnectorItem
953

    
954
        try:
955
            count = len(self.actionLine.tag._polyline._vertices)
956
            if count > 1:
957
                items = []
958

    
959
                lineType = self.lineComboBox.currentText()
960
                for index in range(count - 1):
961
                    start = self.actionLine.tag._polyline._vertices[index]
962
                    end  = self.actionLine.tag._polyline._vertices[index + 1]
963
                    
964
                    lineItem = QEngineeringLineItem(vertices=[start, end])
965
                    lineItem.transfer.onRemoved.connect(self.itemRemoved)
966
                    lineItem.lineType = lineType
967
                    if items:
968
                        lineItem.connectIfPossible(items[-1], 5)
969
                    else:
970
                        pt = lineItem.startPoint()
971
                        selected = self.graphicsView.scene.itemAt(QPointF(pt[0], pt[1]), QTransform())
972
                        if selected is not None and type(selected) is QEngineeringConnectorItem:
973
                            lineItem.connectIfPossible(selected.parent, 5)
974
                    
975
                    items.append(lineItem)
976
                    self.graphicsView.scene.addItem(lineItem)
977

    
978
                pt = items[-1].endPoint()
979
                selected = self.graphicsView.scene.itemAt(QPointF(pt[0], pt[1]), QTransform())
980
                if selected is not None and type(selected) is QEngineeringConnectorItem:
981
                    items[-1].connectIfPossible(selected.parent, 5)
982
        finally:
983
            self.graphicsView.scene.removeItem(self.actionLine.tag._polyline)
984
            self.actionLine.tag.reset()
985

    
986
    '''
987
        @brief      refresh scene
988
        @author     humkyung
989
        @date       2018.07.23
990
    '''
991
    def onCommandRejected(self, cmd):
992
        try:
993
            if type(cmd) is PlaceLineCommand.PlaceLineCommand:
994
                self.graphicsView.scene.removeItem(self.actionLine.tag._polyline)
995
                self.graphicsView.scene.update()
996
                self.actionLine.tag.reset()
997

    
998
                self.actionLine.setChecked(False)
999
            elif type(cmd) is AreaZoomCommand.AreaZoomCommand:
1000
                self.actionZoom.setChecked(False)
1001
            elif type(cmd) is AreaOcrCommand.AreaOcrCommand:
1002
                self.actionOCR.setChecked(False)
1003
        finally:
1004
            self.graphicsView.useDefaultCommand()
1005
     
1006
    '''
1007
        @brief      restore to default command when user press Escape key
1008
        @author     humkyung 
1009
        @date       2018.08.09
1010
    '''
1011
    def keyPressEvent(self, event):
1012
        try:
1013
            if event.key() == Qt.Key_Escape:
1014
                checked = self.actionGroup.checkedAction()
1015
                if checked:
1016
                    checked.setChecked(False)
1017
                    self.graphicsView.useDefaultCommand()
1018

    
1019
            QMainWindow.keyPressEvent(self, event)
1020
        except Exception as ex:
1021
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1022
            self.addMessage.emit(MessageType.Error, message)
1023
       
1024
    '''
1025
        @brief      recognize symbol and text
1026
        @author     humkyung
1027
        @date       2018.04.??
1028
        @history    2018.04.16  humkyung    execute line no tracing
1029
                    2018.05.02  Jeongwoo    Show MessageBox when imageviewer doesn't have image
1030
                    2018.05.25  Jeongwoo    Add parameter on QRecognitionDialog.__init__() and Move thread to QRecognitionDialog
1031
                                            Remove codes below if self.dlg.isAccepted == True
1032
                    2018.05.29  Jeongwoo    Remove connects and comments
1033
    '''
1034
    def recognize(self, MainWindow):
1035
        from RecognitionDialog import QRecognitionDialog
1036

    
1037
        if not self.graphicsView.hasImage():
1038
            self.showImageSelectionMessageBox()
1039
            return
1040

    
1041
        try:
1042
            self.removedItems['LINE'] = []
1043
            self.removedItems['EQUIP'] = []
1044
            self.removedItems['INST'] = []
1045
            self.removedItems['NOTE'] = []
1046

    
1047
            appDocData = AppDocData.instance()
1048
            self.resultTreeWidget.setCurrentPID(appDocData.activeDrawing.name)
1049
            ## up to here
1050

    
1051
            self.onClearLog()
1052
            self.dlg = QRecognitionDialog(self, self.path)
1053
            self.dlg.exec_()
1054
            if self.dlg.isAccepted == True:
1055
                '''DO NOTHING'''
1056
        except Exception as ex:
1057
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1058
            self.addMessage.emit(MessageType.Error, message)
1059

    
1060
    '''
1061
        @brief      remove item from tree widget and then remove from scene
1062
        @date       2018.05.25
1063
        @author     Jeongwoo
1064
    '''
1065
    def itemRemoved(self, item):
1066
        try:
1067
            self.resultTreeWidget.itemRemoved(item)
1068

    
1069
            if type(item) is QEngineeringLineNoTextItem:
1070
                self.removedItems['LINE'].append(str(item.uid))
1071
            elif type(item) is QEngineeringInstrumentItem:
1072
                self.removedItems['INST'].append(str(item.uid))
1073
            elif type(item) is QEngineeringEquipmentItem:
1074
                self.removedItems['EQUIP'].append(str(item.uid))
1075
            elif type(item) is QEngineeringNoteItem:
1076
                self.removedItems['NOTE'].append(str(item.uid))
1077

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

    
1083
    '''
1084
        @brief      recognize line
1085
        @author     humkyung
1086
        @date       2018.04.19
1087
        @history    Jeongwoo 2018.04.26 Variable name changed (texts → lineNos)
1088
                                        TextItem type changed (QEngineeringTextItem → QEngineeringLineNoTextItem)
1089
                    humkyung 2018.04.26 remove small objects before recognizing line
1090
                    Jeongwoo 2018.05.02 Show MessageBox when imageviewer doesn't have image
1091
                    Jeongwoo 2018.05.25 Move codes about LineDetector
1092
                    humkyung 2018.06.17 show progress dialog
1093
    '''
1094
    def recognizeLine(self, MainWindow):
1095
        from LineNoTracer import LineNoTracer
1096
        from ConnectAttrDialog import QConnectAttrDialog
1097

    
1098
        if not self.graphicsView.hasImage():
1099
            self.showImageSelectionMessageBox()
1100
            return
1101

    
1102
        try:
1103
            self.dlgConnectAttr = QConnectAttrDialog(self, self.graphicsView)
1104
            self.dlgConnectAttr.exec_()
1105

    
1106
            self.resultTreeWidget.InitLineNoItems()
1107

    
1108
            # construct line no item
1109
            docData = AppDocData.instance()
1110
            for lineno in docData.lineNos:
1111
                item = self.resultTreeWidget.addTreeItem(self.resultTreeWidget.root, lineno)
1112
                connectedItems = lineno.getConnectedItems()
1113
                for connectedItem in connectedItems:
1114
                    if issubclass(type(connectedItem), SymbolSvgItem): 
1115
                        self.resultTreeWidget.addTreeItem(item, connectedItem)
1116
            # up to here
1117
        except Exception as ex:
1118
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1119
            self.addMessage.emit(MessageType.Error, message)
1120

    
1121
    '''
1122
        @history    2018.05.25  Jeongwoo    Moved from MainWindow
1123
                                            SvgItem and TextItem Connect with method in this class
1124
                                            Change method to add GraphicsItem
1125
                    2018.05.28  Jeongwoo    Make QGraphicsItem by symbol, text object. Not xml
1126
                    2018.05.29  Jeongwoo    Change method name and Moved from QRecognitionDialog
1127
                    2018.05.30  Jeongwoo    Add parameters on SymbolSvgItem.__init__() (parentSymbol, childSymbol)
1128
                                            Change Method name and seperate each item
1129
                    humkyung 2018.06.11     display difference between original and recognized image
1130
                    Jeongwoo 2018.06.18     Update Scene after all item added
1131
    '''
1132
    def drawDetectedItems(self, symbolList, textInfoList, otherTextInfoList):
1133
        QApplication.processEvents()
1134
        self.drawDetectedSymbolItem(symbolList)
1135
        QApplication.processEvents()
1136
        self.drawDetectedTextItem(textInfoList)
1137
        QApplication.processEvents()
1138
        self.drawDetectedOtherTextItem(otherTextInfoList)
1139

    
1140
        # Update Scene
1141
        self.graphicsView.scene.update(self.graphicsView.sceneRect())
1142

    
1143
    '''
1144
        @brief      
1145
        @author     humkyung
1146
        @date       2018.08.23
1147
    '''
1148
    def drawDetectedLines(self, lineList, worker):
1149
        area = AppDocData.instance().getArea('Drawing')
1150

    
1151
        lines = []
1152
        for pts in lineList:
1153
            processLine = QEngineeringLineItem(vertices=[(area.x + param[0], area.y + param[1]) for param in pts])
1154
            processLine.area = 'Drawing'
1155
            self.graphicsView.scene.addItem(processLine)
1156
            lines.append(processLine)
1157

    
1158
            if processLine.length() > 100: # TODO: check critical length
1159
                processLine.addFlowArrow()
1160
        
1161
        # re-order process line's start,end according to flow mark
1162
        #worker.arrangeLinePosition(lines, symbols, listWidget)
1163
        # up to here
1164

    
1165
    '''
1166
        history    humkyung 2018.06.09 check length of original and connection point is 2 while parsing
1167
    '''
1168
    def drawDetectedSymbolItem(self, symbolList):
1169
        from GraphicsBoundingBoxItem import QGraphicsBoundingBoxItem
1170
        from SymbolSvgItem import SymbolSvgItem
1171
        import math
1172

    
1173
        try:
1174
            project = AppDocData.instance().getCurrentProject()
1175

    
1176
            searchedMap = []
1177
            for symbol in symbolList:
1178
                pt = [float(x) for x in symbol.getSp()]
1179
                size = [symbol.getWidth(), symbol.getHeight()]
1180
                name = symbol.getName()
1181
                angle = round(math.radians(symbol.getRotatedAngle()), 2)
1182
                _type = symbol.getType()
1183
                origin = [0,0]
1184
                if 2 == len(symbol.getOriginalPoint().split(',')):
1185
                    tokens = symbol.getOriginalPoint().split(',')
1186
                    origin = [pt[0] + float(tokens[0]), pt[1] + float(tokens[1])]
1187
                connPts = []
1188
                if symbol.getConnectionPoint() is not None:
1189
                    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(','))]
1190
                parentSymbol = symbol.getBaseSymbol()
1191
                childSymbol = symbol.getAdditionalSymbol()
1192
                hasInstrumentLabel = symbol.getHasInstrumentLabel()
1193

    
1194
                svgFilePath = os.path.join(project.getSvgFilePath(), _type, name + '.svg')
1195
                if os.path.isfile(svgFilePath):
1196
                    svg = SymbolSvgItem.createItem(_type, svgFilePath)
1197
                    svg.buildItem(name, _type, angle, pt, size, origin, connPts, parentSymbol, childSymbol, hasInstrumentLabel)
1198
                    svg.reCalculationRotatedItem()
1199
                    svg.area = 'Drawing'
1200

    
1201
                    # set owner - 2018.07.20 added by humkyung                   
1202
                    matches = [searched for searched in searchedMap if searched[0] == symbol.owner]
1203
                    if len(matches) == 1:
1204
                        svg.owner = matches[0][1]
1205
                    searchedMap.append((symbol, svg))
1206
                    # up to here
1207

    
1208
                    svg.transfer.onRemoved.connect(self.itemRemoved)
1209
                    self.addSvgItemToScene(svg)
1210
                    
1211
                    # Equipment Item 경우 저장
1212
                    if type(svg) is QEngineeringEquipmentItem:
1213
                        svg.saveEquipData()
1214

    
1215
                    # Instrument Item 경우 저장
1216
                    if type(svg) is QEngineeringInstrumentItem:
1217
                        svg.saveInstData()
1218
                else:
1219
                    item = QGraphicsBoundingBoxItem(pt[0], pt[1], size[0], size[1])
1220
                    item.isSymbol = True
1221
                    item.angle = angle
1222
                    item.setPen(QPen(Qt.red, 5, Qt.SolidLine))
1223
                    self.graphicsView.scene.addItem(item)
1224
            # up to here
1225
        except Exception as ex:
1226
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1227
            self.addMessage.emit(MessageType.Error, message)
1228

    
1229
    '''
1230
        @history    2018.06.08  Jeongwoo    Add parameter on round method
1231
    '''
1232
    def drawDetectedTextItem(self, textInfoList):
1233
        from TextItemFactory import TextItemFactory
1234
        import math
1235

    
1236
        try:
1237
            appDocData = AppDocData.instance()
1238

    
1239
            # parse texts
1240
            for textInfo in textInfoList:
1241
                x = textInfo.getX()
1242
                y = textInfo.getY()
1243
                width = textInfo.getW()
1244
                height = textInfo.getH()
1245
                angle = round(math.radians(textInfo.getAngle()), 2)
1246
                text = textInfo.getText()
1247
                item = TextItemFactory.instance().createTextItem(text)
1248

    
1249
                if item is not None:
1250
                    item.loc = (x, y)
1251
                    item.size = (width, height)
1252
                    item.angle = angle
1253
                    item.setPlainText(text)
1254
                    item.area = 'Drawing'
1255
                    item.transfer.onRemoved.connect(self.itemRemoved)
1256
                    self.addTextItemToScene(item)
1257
                    appDocData.texts.append(item)
1258

    
1259
                    # Line No Text Item 경우 저장
1260
                    if type(item) is QEngineeringLineNoTextItem:
1261
                        item.saveLineData()
1262
        except Exception as ex:
1263
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1264
            self.addMessage.emit(MessageType.Error, message)
1265

    
1266
    '''
1267
        @brief      draw detected texts except which in drawing area
1268
    '''
1269
    def drawDetectedOtherTextItem(self, otherTextInfoList):
1270
        from TextItemFactory import TextItemFactory
1271
        import math
1272

    
1273
        try:
1274
            appDocData = AppDocData.instance()
1275

    
1276
            # parse notes
1277
            for textInfoMap in otherTextInfoList:
1278
                if textInfoMap[0]=='Note':
1279
                    pass
1280

    
1281
                for textInfo in textInfoMap[1]:
1282
                    x = textInfo.getX()
1283
                    y = textInfo.getY()
1284
                    width = textInfo.getW()
1285
                    height = textInfo.getH()
1286
                    angle = round(math.radians(textInfo.getAngle()))
1287
                    text = textInfo.getText()
1288

    
1289
                    if textInfoMap[0] == 'Note':
1290
                        item = QEngineeringNoteItem()
1291
                    else:
1292
                        item = TextItemFactory.instance().createTextItem(text)
1293

    
1294
                    item.loc = (x, y)
1295
                    item.size = (width, height)
1296
                    item.angle = angle
1297
                    item.setPlainText(text)
1298
                    item.area = textInfoMap[0]
1299
                    self.addTextItemToScene(item)
1300
                    appDocData.texts.append(item)
1301

    
1302
                    ## Note Item일 경우 NOTE_DATA_LIST에 추가
1303
                    if textInfoMap[0] == 'Note':
1304
                        item.saveNoteData()
1305
        except Exception as ex:
1306
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1307
            self.addMessage.emit(MessageType.Error, message)
1308

    
1309
    '''
1310
        @brief  draw unknown items 
1311
        @author humkyung
1312
        @date   2018.06.12
1313
        @history    2018.06.14  Jeongwoo    Change method to add unknown item
1314
                    2018.06.18  Jeongwoo    Add connect on unknown item
1315
                                            Add [transfer] for using pyqtSignal
1316
    '''
1317
    def drawUnknownItems(self):
1318
        from QEngineeringFlowArrowItem import QEngineeringFlowArrowItem 
1319
        from EngineeringLineItem import QEngineeringLineItem
1320
        from EngineeringUnknownItem import QEngineeringUnknownItem
1321

    
1322
        try:
1323
            docData = AppDocData.instance()
1324
            project = docData.getCurrentProject()
1325
            windowSize = docData.getSlidingWindowSize()
1326
            thickness = int(windowSize[1])
1327

    
1328
            diffFilePath = os.path.join(project.getTempPath(), "DIFF_" + os.path.basename(self.path))
1329
            if os.path.isfile(diffFilePath):
1330
                imgDiff = cv2.threshold(cv2.cvtColor(cv2.imread(diffFilePath, 1), cv2.COLOR_BGR2GRAY), 127, 255, cv2.THRESH_BINARY)[1]
1331

    
1332
                ## remove line
1333
                lines = [item for item in self.graphicsView.scene.items() if (type(item) is QEngineeringLineItem)]
1334
                for line in lines:
1335
                    line.drawToImage(imgDiff, 255, thickness)
1336
                cv2.imwrite(diffFilePath, imgDiff)
1337
                ## up to here
1338

    
1339
                imgNot = np.ones(imgDiff.shape, np.uint8)
1340
                cv2.bitwise_not(imgDiff, imgNot)
1341
                imgNot = cv2.dilate(imgNot, np.ones((8,8), np.uint8))
1342

    
1343
                diffItems = []
1344

    
1345
                image, contours, hierarchy = cv2.findContours(imgNot, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
1346
                for contour in contours:
1347
                    [x, y, w, h] = cv2.boundingRect(contour)
1348

    
1349
                    # remove too small one
1350
                    if (w < 10 or h < 10): continue
1351

    
1352
                    '''
1353
                    rect = QRectF(x, y, w, h)
1354
                    items = [item for item in diffItems if item.boundingRect().contains(rect)]
1355
                    if len(items) > 0: continue
1356
                    
1357
                    items = [item for item in diffItems if rect.contains(item.boundingRect())]
1358
                    for item in items:
1359
                        diffItems.remove(item)
1360
                    '''
1361

    
1362
                    # create unknown item
1363
                    epsilon = cv2.arcLength(contour, True)*0.001
1364
                    approx = cv2.approxPolyDP(contour, epsilon, True)
1365
                    approx = [pt[0] for pt in approx]
1366
                    item = QEngineeringUnknownItem(approx)
1367
                    item.ara = 'Drawing'
1368
                    diffItems.append(item)
1369
                    # up to here
1370

    
1371
                for item in diffItems:
1372
                    item.transfer.onRemoved.connect(self.itemRemoved)
1373
                    self.addUnknownItemToScene(item)
1374

    
1375
                notFilePath = os.path.join(project.getTempPath(), "NOT_" + os.path.basename(self.path))
1376
                cv2.imwrite(notFilePath, imgNot)
1377
            else:
1378
                message = 'can\'t found {}'.format(diffFilePath)
1379
                self.addMessage.emit(MessageType.Normal, message)
1380
        except Exception as ex:
1381
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1382
            self.addMessage.emit(MessageType.Error, message)
1383

    
1384
    '''
1385
        @brief      load recognition result
1386
        @author     humkyung
1387
        @date       2018.04.??
1388
        @history    humkyung 2018.01.12 parse originalpoint and connectionpoint
1389
                    Jeongwoo 2018.04.17 add QGraphicItem with Rotated text
1390
                    Jeongwoo 2018.04.23 Change to Draw texts on QEngineeringTextItem
1391
                    humkyung 2018.04.23 connect item remove slot to result tree
1392
                    Jeongwoo 2018.04.25 Add if state with QEngineeringNoteItem
1393
                    Jeongwoo 2018.04.26 Change method to create TextItem object with TextItemFactory
1394
                    Jeongwoo 2018.05.03 Change method to draw Svg Item on Scene (svg.addSvgItemToScene)
1395
                    Jeongwoo 2018.05.29 Change method name / Change method to add item / Add Line item
1396
                    Jeongwoo 2018.05.30 Add parameters on SymbolSvgItem.__init__() (parentSymbol, childSymbol) / Change method name / Change XML NODE NAMES
1397
                    Jeongwoo 2018.06.12 Add LineNoTextItem from LINE_NO
1398
                    Jeongwoo 2018.06.14 Add UnknownItem from UNKNOWN
1399
                    Jeongwoo 2018.06.18 Update Scene after all item added
1400
                                        Add connect on unknown item
1401
                                        Add [transfer] for using pyqtSignal
1402
                    kyouho  2018.07.12  Add line property logic
1403
                    humkyung 2018.08.22 show progress while loading xml file
1404
    '''
1405
    def loadRecognitionResultFromXml(self, xmlPath):
1406
        docData = AppDocData.instance()
1407
        from xml.etree.ElementTree import Element, SubElement, dump, ElementTree, parse
1408
        from EngineeringRunItem import QEngineeringRunItem
1409
        from QEngineeringTrimLineNoTextItem import QEngineeringTrimLineNoTextItem
1410

    
1411
        try:
1412
            symbols = []
1413

    
1414
            xml = parse(xmlPath)
1415
            root = xml.getroot()
1416
            
1417
            maxValue = 0
1418
            maxValue = maxValue + len(list(root.iter('SYMBOL')))
1419
            maxValue = maxValue + len(list(root.iter('ATTRIBUTE')))
1420
            maxValue = maxValue + len(list(root.iter('LINE_NO')))
1421
            maxValue = maxValue + len(list(root.iter('LINE')))
1422
            maxValue = maxValue + len(list(root.iter('UNKNOWN')))
1423
            self.progress.setMaximum(maxValue)
1424

    
1425
            for symbol in root.find('SYMBOLS').iter('SYMBOL'):
1426
                item = SymbolSvgItem.fromXml(symbol)
1427
                if item[0] is not None:
1428
                    item[0].transfer.onRemoved.connect(self.itemRemoved)
1429
                    symbols.append(item)
1430
                else:
1431
                    pt = [float(x) for x in symbol.find('LOCATION').text.split(',')]
1432
                    size = [float(x) for x in symbol.find('SIZE').text.split(',')]
1433
                    angle = float(symbol.find('ANGLE').text)
1434
                    item = QGraphicsBoundingBoxItem(pt[0], pt[1], size[0], size[1])
1435
                    item.isSymbol = True
1436
                    item.angle = angle
1437
                    item.setPen(QPen(Qt.red, 5, Qt.SolidLine))
1438
                    self.graphicsView.scene.addItem(item)
1439

    
1440
                self.progress.setValue(self.progress.value() + 1)
1441
                
1442
            QApplication.processEvents()
1443

    
1444
            # set symbol's owner
1445
            childItems = [item for item in symbols if item[1] is not None]
1446
            for item in childItems:
1447
                matches = [param for param in symbols if str(param[0].uid) == item[1]]
1448
                if len(matches) == 1:
1449
                    item[0].owner = matches[0][0]
1450
            # up to here
1451
           
1452
            for item in symbols:
1453
                self.addSvgItemToScene(item[0])
1454

    
1455
            # parse texts
1456
            for text in root.iter('ATTRIBUTE'):
1457
                item = QEngineeringTextItem.fromXml(text)
1458
                if item is not None:
1459
                    uid = text.find('UID')
1460
                    attributeValue = text.find('ATTRIBUTEVALUE')
1461
                    name = text.find('NAME').text
1462
                    item.transfer.onRemoved.connect(self.itemRemoved)
1463
                    self.addTextItemToScene(item)
1464

    
1465
                    if name == 'TEXT':
1466
                        if uid is not None and attributeValue is not None:
1467
                            item.uid = uid.text
1468
                            item.attribute = attributeValue.text
1469
                    elif name == 'NOTE':
1470
                        if uid is not None:
1471
                            item.uid = uid.text
1472

    
1473
                self.progress.setValue(self.progress.value() + 1)
1474
                
1475
            QApplication.processEvents()
1476

    
1477
            for line in root.find('LINEINFOS').iter('LINE'):
1478
                item = QEngineeringLineItem.fromXml(line)
1479
                item.transfer.onRemoved.connect(self.itemRemoved)
1480
                if item: self.addLineItemToScene(item)
1481

    
1482
                self.progress.setValue(self.progress.value() + 1)
1483
                
1484
            QApplication.processEvents()
1485

    
1486
            for unknown in root.iter('UNKNOWN'):
1487
                item = QEngineeringUnknownItem.fromXml(unknown)
1488
                item.transfer.onRemoved.connect(self.itemRemoved)
1489
                if item is not None:
1490
                    item.transfer.onRemoved.connect(self.itemRemoved)
1491
                    self.addUnknownItemToScene(item)
1492

    
1493
                self.progress.setValue(self.progress.value() + 1)
1494
                
1495
            QApplication.processEvents()
1496

    
1497
            for lineNo in root.iter('LINE_NO'):
1498
                location = lineNo.find('LOCATION').text if lineNo.find('LOCATION') is not None else '0,0'
1499
                x = float(location.split(',')[0])
1500
                y = float(location.split(',')[1])
1501
                width = float(lineNo.find('WIDTH').text) if lineNo.find('WIDTH') is not None else 0
1502
                height = float(lineNo.find('HEIGHT').text) if lineNo.find('HEIGHT') is not None else 0
1503
                angle = float(lineNo.find('ANGLE').text) if lineNo.find('ANGLE') is not None else 0
1504
                text = lineNo.find('TEXT').text
1505

    
1506
                item = TextItemFactory.instance().createTextItem(text)
1507
                if item is not None:
1508
                    item.loc = (x, y)
1509
                    item.size = (width, height)
1510
                    item.angle = angle
1511
                    item.setPlainText(text)
1512
                    item.transfer.onRemoved.connect(self.itemRemoved)
1513
                    self.addTextItemToScene(item)
1514

    
1515
                    # attr
1516
                    for userInputAttr in lineNo.iter('USERINPUTATTRIBUTE'):
1517
                        newAttr = UserInputAttribute(userInputAttr.find('TYPEUID').text, userInputAttr.find('TYPEVALUE').text)
1518
                        item._attrs.append(newAttr)
1519
                    for attr in lineNo.iter('ATTRIBUTE'):
1520
                        item._attrs.append((attr.find('NAME').text, attr.find('VALUE').text))
1521

    
1522
                connLine = lineNo.find('CONNLINE')
1523
                if connLine is not None:
1524
                    lineUID = connLine.text
1525
                    connLine = self.graphicsView.findItemByUid(lineUID)
1526
                    if connLine is not None:
1527
                        item.conns.append(connLine)
1528

    
1529
                run = lineNo.find('RUN')
1530
                if run is not None:
1531
                    lineRunItem = QEngineeringRunItem()
1532
                    for child in run:
1533
                        uidElement = child.find('UID')
1534
                        if uidElement is not None:
1535
                            uid = uidElement.text
1536
                            runItem = self.graphicsView.findItemByUid(uid)
1537
                            if runItem is not None:
1538
                                lineRunItem.items.append(runItem)
1539

    
1540
                    item.runs.append(lineRunItem)
1541
                    treeItem = self.resultTreeWidget.addTreeItem(self.resultTreeWidget.root, item)
1542
                    for connectedItem in lineRunItem.items:
1543
                        if issubclass(type(connectedItem), SymbolSvgItem): self.resultTreeWidget.addTreeItem(treeItem, connectedItem)
1544
                    docData.lineNos.append(item)
1545

    
1546
                self.progress.setValue(self.progress.value() + 1)
1547
            QApplication.processEvents()
1548

    
1549
            for trimLineNo in root.iter('TRIM_LINE_NO'):
1550
                item = QEngineeringTrimLineNoTextItem()
1551
                item.uid = trimLineNo.find('UID')
1552

    
1553
                run = trimLineNo.find('RUN')
1554
                if run is not None:
1555
                    lineRunItem = QEngineeringRunItem()
1556
                    for child in run:
1557
                        uidElement = child.find('UID')
1558
                        if uidElement is not None:
1559
                            uid = uidElement.text
1560
                            runItem = self.graphicsView.findItemByUid(uid)
1561
                            if runItem is not None:
1562
                                lineRunItem.items.append(runItem)
1563

    
1564
                    item.runs.append(lineRunItem)
1565
                    treeItem = self.resultTreeWidget.addTreeItem(self.resultTreeWidget.root, item)
1566
                    for connectedItem in lineRunItem.items:
1567
                        if issubclass(type(connectedItem), SymbolSvgItem): self.resultTreeWidget.addTreeItem(treeItem, connectedItem)
1568
                    docData.lineNos.append(item)
1569
            # up to here
1570

    
1571
            # set symbol's connectItem
1572
            from EngineeringConnectorItem import QEngineeringConnectorItem
1573
            connectors = [item for item in self.graphicsView.scene.items() if type(item) == QEngineeringConnectorItem and item.connectedItem is not None]
1574
            for connector in connectors:
1575
                # 처음에는 UID가 connectedItem에 String으로 들어가있기 때문에
1576
                connector.connectedItem = self.graphicsView.findItemByUid(connector.connectedItem)
1577

    
1578
            symbols = [item for item in self.graphicsView.scene.items() if issubclass(type(item), SymbolSvgItem) and len(item.attrs) > 0]
1579
            for symbol in symbols:
1580
                # 처음에는 attrs의 uid가 connectedItem에 String으로 들어가있기 때문에
1581
                for index in range(len(symbol.attrs)):
1582
                    if type(symbol.attrs[index]) is not UserInputAttribute and type(symbol.attrs[index]) is not tuple:
1583
                        symbol.attrs[index] = self.graphicsView.findItemByUid(symbol.attrs[index])
1584
                        
1585
            # Update Scene
1586
            self.graphicsView.scene.update(self.graphicsView.sceneRect())
1587
        except Exception as ex:
1588
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1589
            self.addMessage.emit(MessageType.Error, message)
1590

    
1591
    '''
1592
        @brief      Remove added item on same place and Add GraphicsItem
1593
        @author     Jeongwoo
1594
        @date       2018.05.25
1595
        @history    2018.05.29  Jeongwoo    Moved from QRecognitionDialog
1596
                    2018.06.18  Jeongwoo    Set Z-index
1597
    '''
1598
    def addSvgItemToScene(self, svgItem):
1599
        svgItem.addSvgItemToScene(self.graphicsView.scene)
1600
        
1601
    '''
1602
        @brief      Remove added item on same place and Add GraphicsItem
1603
        @author     Jeongwoo
1604
        @date       2018.05.25
1605
        @history    2018.05.29  Jeongwoo    Moved from QRecognitionDialog
1606
                    2018.06.05  Jeongwoo    Remove Size condition
1607
                    2018.06.18  Jeongwoo    Set Z-index
1608
    '''
1609
    def addTextItemToScene(self, textItem):
1610
        textItem.addTextItemToScene(self.graphicsView.scene)
1611
        
1612
    '''
1613
        @brief      Remove added item on same place and Add GraphicsItem
1614
        @author     Jeongwoo
1615
        @date       2018.05.29
1616
        @history    2018.06.18  Jeongwoo    Set Z-index
1617
    '''
1618
    def addLineItemToScene(self, lineItem):
1619
        lineItem.addLineItemToScene(self.graphicsView.scene)
1620

    
1621
    '''
1622
        @brief      Remove added item on same place and Add Unknown Item
1623
        @author     Jeongwoo
1624
        @date       2018.06.14
1625
        @history    2018.06.18  Jeongwoo    Set Z-index
1626
    '''
1627
    def addUnknownItemToScene(self, unknownItem):
1628
        try:
1629
            unknownItem.addUnknownItemToScene(self.graphicsView.scene)
1630
        except Exception as ex:
1631
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1632
            self.addMessage.emit(MessageType.Error, message)
1633

    
1634
    '''
1635
        @brief      generate output xml file
1636
        @author     humkyung
1637
        @date       2018.04.23
1638
        @history    2018.05.02  Jeongwoo    Show MessageBox when imageviewer doesn't have image
1639
    '''
1640
    def generateOutput(self):
1641
        import XmlGenerator as xg
1642

    
1643
        if not self.graphicsView.hasImage():
1644
            self.showImageSelectionMessageBox()
1645
            return
1646

    
1647
        try:
1648
            appDocData = AppDocData.instance()
1649

    
1650
            ## collect items
1651
            appDocData.lines.clear()
1652
            appDocData.lines = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringLineItem and item.owner is None]
1653

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

    
1657
            appDocData.equipments.clear()
1658
            for item in self.graphicsView.scene.items():
1659
                if type(item) is QEngineeringEquipmentItem:
1660
                    appDocData.equipments.append(item)
1661

    
1662
            appDocData.texts.clear()
1663
            appDocData.texts = [item for item in self.graphicsView.scene.items() if issubclass(type(item), QEngineeringTextItem) and type(item) is not QEngineeringLineNoTextItem]
1664
            ## up to here
1665

    
1666
            appDocData.imgOutput = np.ones((appDocData.imgHeight, appDocData.imgWidth), np.uint8)*255
1667
            xg.writeOutputXml(appDocData.imgName, appDocData.imgWidth, appDocData.imgHeight) # TODO: check
1668
            project = appDocData.getCurrentProject()
1669
            cv2.imwrite(os.path.join(project.getTempPath() , 'OUTPUT.png') , appDocData.imgOutput)
1670
        except Exception as ex:
1671
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1672
            self.addMessage.emit(MessageType.Error, message)
1673

    
1674
    '''
1675
        @brief      resetting attribute at secne
1676
        @author     kyoyho
1677
        @date       2018.08.21
1678
    '''
1679
    def checkAttribute(self):
1680
        try:
1681

    
1682
            docData = AppDocData.instance()
1683
            if not self.graphicsView.hasImage():
1684
                return
1685

    
1686
            # symbol 경우
1687
            items = [item for item in self.graphicsView.scene.items() if issubclass(type(item), SymbolSvgItem)]
1688
            for item in items:
1689
                attrs = item.attrs
1690
                
1691
                removeAttrList = []
1692
                for attr in attrs:
1693
                    if type(attr) is tuple:
1694
                        continue
1695

    
1696
                    if attr is None:
1697
                        removeAttrList.append(attr)
1698
                        continue
1699

    
1700
                    attrInfo = docData.getSymbolAttributeByUID(attr.attribute)
1701
                    if attrInfo is None:
1702
                        removeAttrList.append(attr)
1703
                    # 해당 attribute가 맞는지 확인
1704
                    else:
1705
                        attrType = attrInfo[2]
1706
                        _type = type(attr)
1707
                        if attrType == 'Symbol Item':
1708
                            if not issubclass(_type, SymbolSvgItem):
1709
                                removeAttrList.append(attr)
1710
                        elif attrType == 'Text Item':
1711
                            if _type is not QEngineeringTextItem:
1712
                                removeAttrList.append(attr)
1713
                        elif attrType == 'Int':
1714
                            if _type is not UserInputAttribute and self.isNumber(attr.text):
1715
                                removeAttrList.append(attr)
1716
                        elif attrType == 'String':
1717
                            if _type is not UserInputAttribute:
1718
                                removeAttrList.append(attr)
1719

    
1720
                for attr in removeAttrList:
1721
                    attrs.remove(attr)
1722

    
1723
            # Line No Text Item의 경우
1724
            items = [item for item in self.graphicsView.scene.items() if issubclass(type(item), QEngineeringLineNoTextItem)]
1725
            for item in items:
1726
                attrs = item._attrs
1727
                
1728
                removeAttrList = []
1729
                for attr in attrs:
1730
                    if type(attr) is UserInputAttribute:
1731
                        attrInfo = docData.getLinePropertiesByUID(attr.attribute)
1732
                        if attrInfo is None:
1733
                            removeAttrList.append(attr)
1734

    
1735
                for attr in removeAttrList:
1736
                    attrs.remove(attr)
1737

    
1738
        except Exception as ex:
1739
                message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1740
                self.addMessage.emit(MessageType.Error, message)
1741
    '''
1742
        @brief      Check Number
1743
        @author     kyouho
1744
        @date       2018.08.20
1745
    '''
1746
    def isNumber(self, num):
1747
        p = re.compile('(^[0-9]+$)')
1748
        result = p.match(num)
1749

    
1750
        if result:
1751
            return True
1752
        else:
1753
            return False
1754

    
1755
    '''
1756
        @brief      find overlap Connector
1757
        @author     kyouho
1758
        @date       2018.08.28
1759
    '''
1760
    def findOverlapConnector(self, connectorItem):
1761
        from shapely.geometry import Point
1762
        from EngineeringConnectorItem import QEngineeringConnectorItem
1763
        itemList = []
1764
        
1765
        x = connectorItem.center()[0]
1766
        y = connectorItem.center()[1]
1767

    
1768
        connectors = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringConnectorItem and item != connectorItem]
1769
        for connector in connectors:
1770
            if Point(x, y).distance(Point(connector.center()[0], connector.center()[1])) < 5:
1771
                itemList.append(connector.parent)
1772

    
1773
        return itemList
1774

    
1775
            
1776
if __name__ == '__main__':
1777
    from ProjectDialog import Ui_Dialog
1778
    from App import App 
1779

    
1780
    app = App(sys.argv)
1781
    try:
1782
        dlg = Ui_Dialog()
1783
        selectedProject = dlg.showDialog()
1784
        if selectedProject is not None:
1785
            AppDocData.instance().setCurrentProject(selectedProject)
1786
            app._mainWnd = MainWindow.instance()
1787
            app._mainWnd.show()
1788
            sys.exit(app.exec_())
1789
    except Exception as ex:
1790
        print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
1791
    finally:
1792
        pass