프로젝트

일반

사용자정보

통계
| 개정판:

hytos / DTI_PID / DTI_PID / MainWindow.py @ 680b280c

이력 | 보기 | 이력해설 | 다운로드 (76.2 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 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.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
    def onShowDetectSymbol(self):
205
        from DetectSymbolDialog import QDetectSymbolDialog
206

    
207
        dlgDetectSymbol = QDetectSymbolDialog(self)
208
        dlgDetectSymbol.show()
209
        dlgDetectSymbol.exec_()
210
        
211
    '''
212
        @brief      OCR Editor
213
        @author     euisung
214
        @date       2018.10.05
215
        @history    2018.10.16 euisung      no more used, Integrated with oCRTrainingClicked
216
    '''
217
    def oCRTrainingEdidorClicked(self):
218
        from TrainingEditorDialog import QTrainingEditorDialog
219

    
220
        try:
221
            dialog = QTrainingEditorDialog(self)
222
            dialog.exec_()
223
        except Exception as ex:
224
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
225
            self.addMessage.emit(MessageType.Error, message)
226
            
227
        return
228

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

    
238
        try:
239
            dialog = QTrainingImageListDialog(self)
240
            dialog.exec_()
241
        except Exception as ex:
242
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
243
            self.addMessage.emit(MessageType.Error, message)
244
            
245
        return
246

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

    
257
        from TextItemEditDialog import QTextItemEditDialog
258

    
259
        self.dlgTextItemEdit = QTextItemEditDialog(self)
260
        self.dlgTextItemEdit.show()
261
        self.dlgTextItemEdit.exec_()
262

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

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

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

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

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

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

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

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

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

    
323

    
324
        if alert:
325
            resultStr = '[저장 결과]'
326

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

    
337
            QMessageBox.about(self.graphicsView, "알림", resultStr)
338

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

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

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

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

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

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

    
415
                            from PyQt5 import QtGui
416
                            cellItem = QTableWidgetItem('')
417
                            icon = QtGui.QIcon()
418
                            icon.addPixmap(QtGui.QPixmap(":/newPrefix/doubleclick.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
419
                            cellItem.setIcon(icon)
420
                            self.resultPropertyTableWidget.setItem(row, 1, cellItem)
421
                        else:
422
                            self.resultPropertyTableWidget.editItem(cell)
423
                    else:
424
                        self.resultPropertyTableWidget.editItem(cell)
425
            elif items is not None and len(items) == 1 and type(items[0]) is QEngineeringLineNoTextItem:
426
                connCell = self.resultPropertyTableWidget.item(row, 0)
427
                if connCell.text() == 'CONN':
428
                    ## Line No Text Item의 CONN 속성 초기화
429
                    items[0].conns.clear()
430

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

    
443
    def onSuccessSelectAttribute(self, attr):
444
        self.resultPropertyTableWidget.refreshAttr(attr)
445

    
446
    '''
447
        @brief  add message listwidget
448
        @author humkyung
449
        @date   2018.07.31
450
    '''
451
    def onAddMessage(self, messageType, message):
452
        from AppDocData import MessageType
453

    
454
        try:
455
            current = QDateTime.currentDateTime()
456

    
457
            item = QListWidgetItem('{}: {}'.format(current.toString('hh:mm:ss'), message))
458
            if messageType == MessageType.Error:
459
                item.setBackground(Qt.red)
460

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

    
465
    '''
466
        @brief      clear log
467
        @author     humkyung
468
        @date       2018.08.01
469
    '''
470
    def onClearLog(self):
471
        self.listWidgetLog.clear()
472

    
473
    '''
474
        @brief      rotate selected symbol
475
        @author     humkyung
476
        @date       2018.08.15
477
    '''
478
    def onRotate(self, action):
479
        selected = [item for item in self.graphicsView.scene.selectedItems() if issubclass(type(item), SymbolSvgItem)]
480
        if len(selected) == 1:
481
            selected[0].rotateSymbol()
482

    
483
    '''
484
        @brief      Area Zoom
485
        @author     Jeongwoo
486
        @date       2018.06.27
487
        @history    connect command's rejected signal
488
    '''
489
    def onAreaZoom(self, action):
490
        if self.actionZoom.isChecked():
491
            cmd = AreaZoomCommand.AreaZoomCommand(self.graphicsView)
492
            cmd.onRejected.connect(self.onCommandRejected)
493
            self.graphicsView.command = cmd
494

    
495
    '''
496
        @brief      Fit Window
497
        @author     Jeongwoo
498
        @date       2018.06.27
499
        @history    2018.06.27  Jeongwoo    Chnage method to initialize command [Set None → DefaultCommand]
500
    '''
501
    def fitWindow(self, action):
502
        self.graphicsView.useDefaultCommand()
503
        self.graphicsView.zoomImageInit()
504

    
505
    def onConvertPDFToImage(self):
506
        """
507
        @brief      convert to selected pdf to image
508
        @author     humkyung 
509
        @date       2018.07.09
510
        @history    Euisung 2018.10.11 hide shell
511
        """
512
        try: 
513
            filePath = os.path.join(os.path.dirname(os.path.realpath(__file__)) , 'bin64', 'PDF_TO_IMAGE.exe')
514
            subprocess.call(filePath, shell = False)
515
        except Exception as ex:
516
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
517

    
518
    '''
519
        @brief      selection changed
520
        @author     humkyung
521
        @date       2018.06.27
522
        @history    humkung 2018.07.08 call tree widget's findItem
523
    '''
524
    def onSelectionChanged(self):
525
        items = [item for item in self.graphicsView.scene.selectedItems() if issubclass(type(item), SymbolSvgItem) or \
526
            type(item) is QEngineeringLineItem or type(item) is QEngineeringLineNoTextItem or type(item) is QEngineeringNoteItem]
527
        if items:
528
            item = items[-1]
529
            self.resultTreeWidget.findItem(item)
530
            self.resultPropertyTableWidget.showItemProperty(item)
531
        else:
532
            self.resultPropertyTableWidget.showItemProperty(None)
533
        
534
    '''
535
        @brief      Initialize scene and ResultTreeWidget
536
        @author     Jeongwoo
537
        @date       2018.06.14
538
        @history    humkyung 2018.08.16 ask to delete recognized items before remove
539
    '''
540
    def onInitializeScene(self, action):
541
        if not self.graphicsView.hasImage():
542
            self.actionEquipment.setChecked(False)
543
            self.showImageSelectionMessageBox()
544

    
545
            return
546

    
547
        msg = QMessageBox()
548
        msg.setIcon(QMessageBox.Critical)
549
        msg.setText("선택한 인식한 항목들을 삭제하시겠습니까?\n삭제된 항목들은 복구할 수 없습니다.")
550
        msg.setWindowTitle("항목 삭제")
551
        msg.setStandardButtons(QMessageBox.Ok|QMessageBox.Cancel)
552
        if QMessageBox.Ok == msg.exec_():
553
            items = self.graphicsView.scene.items()
554
            for item in items:
555
                if type(item) is not QGraphicsPixmapItem:
556
                    self.graphicsView.scene.removeItem(item)
557

    
558
                    if type(item) is QEngineeringLineNoTextItem:
559
                        self.removedItems['LINE'].append(str(item.uid))
560
                    elif type(item) is QEngineeringInstrumentItem:
561
                        self.removedItems['INST'].append(str(item.uid))
562
                    elif type(item) is QEngineeringEquipmentItem:
563
                        self.removedItems['EQUIP'].append(str(item.uid))
564
                    elif type(item) is QEngineeringNoteItem:
565
                        self.removedItems['NOTE'].append(str(item.uid))
566
                    
567
            if self.path is not None:
568
                baseName = os.path.basename(self.path)
569
                self.resultTreeWidget.setCurrentPID(baseName)
570

    
571
    '''
572
        @brief      Manage Checkable Action statement
573
        @author     Jeongwoo
574
        @date       2018.05.10
575
        @history    2018.06.27  Jeongwoo    Chnage method to initialize command [Set None → DefaultCommand]
576
    '''
577
    def actionGroupTriggered(self, action):
578
        if self.graphicsView.command is not None:
579
            self.graphicsView.useDefaultCommand()
580

    
581
        for _action in self.actionGroup.actions():
582
            _action.setChecked(False)
583

    
584
        action.setChecked(True)
585

    
586
    '''
587
        @brief      Create Equipment
588
        @author     Jeongwoo
589
        @date       18.05.03
590
        @history    2018.05.04  Jeongwoo    Add Parameter on CreateSymbolCommand
591
    '''
592
    def createEquipment(self):
593
        if not self.graphicsView.hasImage():
594
            self.actionEquipment.setChecked(False)
595
            self.showImageSelectionMessageBox()
596
            return
597
        if self.actionEquipment.isChecked():
598
            self.graphicsView.command = CreateSymbolCommand.CreateSymbolCommand(self.graphicsView, self.resultTreeWidget, self.dirTreeWidget)
599
        else:
600
            self.graphicsView.useDefaultCommand()
601

    
602

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

    
619
    '''
620
        @brief      Area OCR
621
        @author     Jeongwoo
622
        @date       18.04.18
623
        @history    2018.05.02  Jeongwoo    Change graphicsView.command by actionOCR checked state
624
                                            Show MessageBox when imageviewer doesn't have image
625
    '''
626
    def onAreaOcr(self):
627
        if not self.graphicsView.hasImage():
628
            self.actionOCR.setChecked(False)
629
            self.showImageSelectionMessageBox()
630
            return
631

    
632
        if self.actionOCR.isChecked():
633
            cmd = AreaOcrCommand.AreaOcrCommand(self.graphicsView)
634
            cmd.onSuccess.connect(self.onRecognizeText)
635
            cmd.onRejected.connect(self.onCommandRejected)
636
            self.graphicsView.command = cmd
637
        else:
638
            self.graphicsView.useDefaultCommand()
639
    
640
    '''
641
        @brief      show text recognition dialog
642
        @author     humkyung
643
        @date       2018.08.08
644
    '''
645
    def onRecognizeText(self, x, y, width, height):
646
        from OcrResultDialog import QOcrResultDialog
647

    
648
        try:
649
            image = self.graphicsView.image().copy(x, y, width, height)
650
            dialog = QOcrResultDialog(self.graphicsView, image, QRectF(x, y, width, height))
651
            (isAccept, textInfoList) = dialog.showDialog()
652
            if isAccept:
653
                if textInfoList is not None and len(textInfoList) > 0:
654
                    docData = AppDocData.instance()
655
                    configs = docData.getConfigs('Line No', 'Delimiter')
656
                    delimiter = configs[0].value if 1 == len(configs) else '-'
657
                    lineNoconfigs = docData.getConfigs('Line No', 'Configuration')
658
                    for textInfo in textInfoList:
659
                        x = textInfo.getX()
660
                        y = textInfo.getY()
661
                        angle = textInfo.getAngle()
662
                        text = textInfo.getText()
663
                        width = textInfo.getW()
664
                        height = textInfo.getH()
665
                        item = TextItemFactory.instance().createTextItem(text)
666
                        if item is not None:
667
                            item.loc = (x, y)
668
                            item.size = (width, height)
669
                            item.angle = angle
670
                            item.setPlainText(text)
671
                            item.setDefaultTextColor(Qt.blue)
672
                            item.addTextItemToScene(self.graphicsView.scene)
673
                            item.transfer.onRemoved.connect(self.itemRemoved)
674
                        else:
675
                            message = 'error occured({}) in {}:{}'.format('텍스트 생성에 실패했습니다.', sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
676
                            self.addMessage.emit(MessageType.Normal, message)
677
                else:
678
                    QMessageBox.about(self.graphicsView, "알림", "텍스트 검출 실패")
679
        except Exception as ex:
680
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
681
            self.addMessage.emit(MessageType.Error, message)
682

    
683
    '''
684
        @brief  area configuration
685
    '''
686
    def areaConfiguration(self):
687
        from ConfigurationAreaDialog import QConfigurationAreaDialog
688

    
689
        self.dlgConfigurationArea = QConfigurationAreaDialog(self)
690
        self.dlgConfigurationArea.show()
691
        self.dlgConfigurationArea.exec_()
692

    
693
    '''
694
        @brief  configuration
695
    '''
696
    def configuration(self):
697
        from ConfigurationDialog import QConfigurationDialog
698

    
699
        self.dlgConfiguration = QConfigurationDialog(self)
700
        self.dlgConfiguration.show()
701
        self.dlgConfiguration.exec_()
702

    
703
    '''
704
        @brief  show nominal diameter dialog 
705
        @author humkyung
706
        @date   2018.06.28
707
    '''
708
    def onShowCodeTable(self):
709
        from CodeTableDialog import QCodeTableDialog
710

    
711
        dlg = QCodeTableDialog(self)
712
        dlg.exec_()
713

    
714
    '''
715
        @brief  show HMB data
716
        @author humkyung
717
        @date   2018.07.11
718
    '''
719
    def onHMBData(self):
720
        from HMBDialog import QHMBDialog
721

    
722
        dlg = QHMBDialog(self)
723
        dlg.show()
724
        dlg.exec_()
725

    
726
    '''
727
        @brief  show line data list 
728
        @author humkyung
729
        @date   2018.05.03
730
    '''
731
    def showItemDataList(self):
732
        from ItemDataExportDialog import QItemDataExportDialog
733

    
734
        self.dlgLineDataList = QItemDataExportDialog(self)
735
        self.dlgLineDataList.exec_()
736

    
737
    '''
738
        @brief  Show Image Selection Guide MessageBox
739
        @author Jeongwoo
740
        @date   2018.05.02
741
    '''
742
    def showImageSelectionMessageBox(self):
743
        QMessageBox.about(self.graphicsView, "알림", "이미지를 선택하신 후 시도해주세요.")
744
        
745
    '''
746
        @brief  change selected lines' type by selected line type
747
        @author humkyung
748
        @date   2018.06.27
749
    '''
750
    def onLineTypeChanged(self, param):
751
        lineType = self.lineComboBox.itemText(param)
752
        selected = [item for item in self.graphicsView.scene.selectedItems() if type(item) is QEngineeringLineItem]
753
        if selected:
754
            for item in selected:
755
                item.lineType = lineType
756

    
757
    '''
758
        @brief      Open image drawing file and then display it
759
        @author     humkyung
760
        @date       2018.??.??
761
        @history    18.04.23 Jeongwoo    Add AppDocData.instance().setCurrentPidSource
762
                    18.04.23 Jeongwoo    Add Store Set Current Pid Image on AppDocData
763
                    18.05.02 Jeongwoo    Add useDefaultCommand()
764
                    humkyung 2018.05.24 load recognition result file if exists
765
                    Jeongwoo 2018.05.29 load data on xml if xml file exist
766
                    humkyung 2018.08.22 clear scene before loading xml file
767
    '''
768
    def onOpenImageDrawing(self, MainWindow):
769
        from Drawing import Drawing
770

    
771
        try:
772
            appDocData = AppDocData.instance()
773
            project = appDocData.getCurrentProject()
774
            
775
            for item in self.graphicsView.scene.items():
776
                self.graphicsView.scene.removeItem(item)
777

    
778
            self.path = self.graphicsView.loadImageFromFile(project.getDrawingFilePath())
779
            if os.path.isfile(self.path):
780
                appDocData.clear()
781
                self.graphicsView.useDefaultCommand()
782

    
783
                appDocData.setImgFilePath(self.path)
784
                appDocData.activeDrawing = Drawing(appDocData.imgName)
785
                appDocData.setCurrentPidSource(Image.open(self.path))
786
                self.resultTreeWidget.setCurrentPID(appDocData.activeDrawing.name)
787

    
788
                self.progress = QProgressDialog("잠시만 기다려주세요", "Cancel", 0, 100, self)
789
                self.progress.setWindowModality(Qt.WindowModal)
790
                self.progress.setAutoReset(True)
791
                self.progress.setAutoClose(True)
792
                self.progress.setMinimum(0)
793
                self.progress.resize(600,100)
794
                self.progress.setWindowTitle("파일 읽는 중...")
795
                self.progress.show()
796

    
797
                ## Load data on xml
798
                try:
799
                    path = os.path.join(appDocData.getCurrentProject().getTempPath(), appDocData.imgName + '.xml')
800
                    if os.path.isfile(path):
801
                        self.loadRecognitionResultFromXml(path)
802
                        self.checkAttribute()
803
                finally:
804
                    self.progress.setValue(self.progress.maximum())
805
                    self.progress.hide()
806
        except Exception as ex:
807
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
808
            self.addMessage.emit(MessageType.Error, message)
809

    
810
        return self.path
811

    
812
    '''
813
        @brief  visible/invisible image drawing
814
        @author humkyung
815
        @date   2018.06.25
816
    '''
817
    def onViewImageDrawing(self, isChecked):
818
        for item in self.graphicsView.scene.items():
819
            if type(item) is QGraphicsPixmapItem:
820
                item.setVisible(isChecked)
821
                break
822

    
823
    '''
824
        @brief  visible/invisible Text 
825
        @author humkyung
826
        @date   2018.06.28
827
    '''
828
    def onViewText(self, isChecked):
829
        selected = [item for item in self.graphicsView.scene.items() if issubclass(type(item), QEngineeringTextItem)]
830
        for item in selected:
831
            item.setVisible(isChecked)
832

    
833
    '''
834
        @brief  visible/invisible Symbol 
835
        @author humkyung
836
        @date   2018.06.28
837
    '''
838
    def onViewSymbol(self, isChecked):
839
        selected = [item for item in self.graphicsView.scene.items() if issubclass(type(item), SymbolSvgItem)]
840
        for item in selected:
841
            item.setVisible(isChecked)
842

    
843
    '''
844
        @brief  visible/invisible Line
845
        @author humkyung
846
        @date   2018.06.28
847
    '''
848
    def onViewLine(self, isChecked):
849
        selected = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringLineItem]
850
        for item in selected:
851
            item.setVisible(isChecked)
852

    
853
    '''
854
        @brief  visible/invisible Unknown 
855
        @author humkyung
856
        @date   2018.06.28
857
    '''
858
    def onViewUnknown(self, isChecked):
859
        selected = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringUnknownItem]
860
        for item in selected:
861
            item.setVisible(isChecked)
862

    
863
    '''
864
        @brief  create a symbol
865
        @history    2018.05.02  Jeongwoo    Change return value of QSymbolEditorDialog (Single variable → Tuple)
866
                                            Add SymbolSvgItem
867
                    2018.05.03  Jeongwoo    Change method to draw Svg Item on Scene (svg.addSvgItemToScene)
868
                                            Change method to make svg and image path
869
                    2018.06.08  Jeongwoo    Add Paramter on SymbolSvgItem.buildItem()
870
    '''
871
    def onCreateSymbolClicked(self):
872
        cmd = FenceCommand.FenceCommand(self.graphicsView)
873
        cmd.onSuccess.connect(self.onAreaSelected)
874
        self.graphicsView.command = cmd
875
        QApplication.setOverrideCursor(Qt.CrossCursor)
876

    
877
    '''
878
        @brief      show SymbolEditorDialog with image selected by user
879
        @author     humkyung
880
        @date       2018.07.20
881
    '''
882
    def onAreaSelected(self, x, y, width, height):
883
        try:
884
            image = self.graphicsView.image()
885
            if image is not None:
886
                symbolEditorDialog = SymbolEditorDialog.QSymbolEditorDialog(self, image.copy(x, y, width, height), AppDocData.instance().getCurrentProject())
887
                (isAccepted, isImmediateInsert, offsetX, offsetY, newSym) = symbolEditorDialog.showDialog()
888
                self.dirTreeWidget.initDirTreeWidget()
889
                if isAccepted:
890
                    if isImmediateInsert:
891
                        svgPath = newSym.getSvgFileFullPath()
892
                        img = cv2.imread(newSym.getImageFileFullPath(), 1)
893
                        w, h = (0, 0)
894
                        if len(img.shape[::-1]) == 2:
895
                            w, h = img.shape[::-1]
896
                        else:
897
                            _chan, w, h = img.shape[::-1]
898
                        svg = SymbolSvgItem(svgPath)
899
                        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)
900

    
901
                        svg.transfer.onRemoved.connect(self.resultTreeWidget.itemRemoved)
902
                        svg.addSvgItemToScene(self.graphicsView.scene)
903
                        for connector in svg.connectors:
904
                            self.graphicsView.scene.addItem(connector)
905
        finally:
906
            self.graphicsView.useDefaultCommand()
907
            QApplication.restoreOverrideCursor()
908
    
909
    '''
910
        @brief      create a line
911
        @author     humkyung
912
        @history    Jeongwoo 2018.05.10 Change method for Checkable action
913
    '''
914
    def onPlaceLine(self):        
915
        if not self.graphicsView.hasImage():
916
            self.actionLine.setChecked(False)
917
            self.showImageSelectionMessageBox()
918
            return
919

    
920
        self.actionLine.setChecked(True)
921
        if not hasattr(self.actionLine, 'tag'):
922
            self.actionLine.tag = PlaceLineCommand.PlaceLineCommand(self.graphicsView)
923
            self.actionLine.tag.onSuccess.connect(self.onLineCreated)
924
            self.actionLine.tag.onRejected.connect(self.onCommandRejected)
925

    
926
        self.graphicsView.command = self.actionLine.tag
927

    
928
    '''
929
        @brief      add created lines to scene
930
        @author     humkyung
931
        @date       2018.07.23
932
    '''
933
    def onLineCreated(self):
934
        from EngineeringConnectorItem import QEngineeringConnectorItem
935

    
936
        try:
937
            count = len(self.actionLine.tag._polyline._vertices)
938
            if count > 1:
939
                items = []
940

    
941
                lineType = self.lineComboBox.currentText()
942
                for index in range(count - 1):
943
                    start = self.actionLine.tag._polyline._vertices[index]
944
                    end  = self.actionLine.tag._polyline._vertices[index + 1]
945
                    
946
                    lineItem = QEngineeringLineItem(vertices=[start, end])
947
                    lineItem.transfer.onRemoved.connect(self.itemRemoved)
948
                    lineItem.lineType = lineType
949
                    if items:
950
                        lineItem.connectIfPossible(items[-1], 5)
951
                    else:
952
                        pt = lineItem.startPoint()
953
                        selected = self.graphicsView.scene.itemAt(QPointF(pt[0], pt[1]), QTransform())
954
                        if selected is not None and type(selected) is QEngineeringConnectorItem:
955
                            lineItem.connectIfPossible(selected.parent, 5)
956
                    
957
                    items.append(lineItem)
958
                    self.graphicsView.scene.addItem(lineItem)
959

    
960
                pt = items[-1].endPoint()
961
                selected = self.graphicsView.scene.itemAt(QPointF(pt[0], pt[1]), QTransform())
962
                if selected is not None and type(selected) is QEngineeringConnectorItem:
963
                    items[-1].connectIfPossible(selected.parent, 5)
964
        finally:
965
            self.graphicsView.scene.removeItem(self.actionLine.tag._polyline)
966
            self.actionLine.tag.reset()
967

    
968
    '''
969
        @brief      refresh scene
970
        @author     humkyung
971
        @date       2018.07.23
972
    '''
973
    def onCommandRejected(self, cmd):
974
        try:
975
            if type(cmd) is PlaceLineCommand.PlaceLineCommand:
976
                self.graphicsView.scene.removeItem(self.actionLine.tag._polyline)
977
                self.graphicsView.scene.update()
978
                self.actionLine.tag.reset()
979

    
980
                self.actionLine.setChecked(False)
981
            elif type(cmd) is AreaZoomCommand.AreaZoomCommand:
982
                self.actionZoom.setChecked(False)
983
            elif type(cmd) is AreaOcrCommand.AreaOcrCommand:
984
                self.actionOCR.setChecked(False)
985
        finally:
986
            self.graphicsView.useDefaultCommand()
987
     
988
    '''
989
        @brief      restore to default command when user press Escape key
990
        @author     humkyung 
991
        @date       2018.08.09
992
    '''
993
    def keyPressEvent(self, event):
994
        try:
995
            if event.key() == Qt.Key_Escape:
996
                checked = self.actionGroup.checkedAction()
997
                if checked:
998
                    checked.setChecked(False)
999
                    self.graphicsView.useDefaultCommand()
1000

    
1001
            QMainWindow.keyPressEvent(self, event)
1002
        except Exception as ex:
1003
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1004
            self.addMessage.emit(MessageType.Error, message)
1005
       
1006
    '''
1007
        @brief      recognize symbol and text
1008
        @author     humkyung
1009
        @date       2018.04.??
1010
        @history    2018.04.16  humkyung    execute line no tracing
1011
                    2018.05.02  Jeongwoo    Show MessageBox when imageviewer doesn't have image
1012
                    2018.05.25  Jeongwoo    Add parameter on QRecognitionDialog.__init__() and Move thread to QRecognitionDialog
1013
                                            Remove codes below if self.dlg.isAccepted == True
1014
                    2018.05.29  Jeongwoo    Remove connects and comments
1015
    '''
1016
    def recognize(self, MainWindow):
1017
        from RecognitionDialog import QRecognitionDialog
1018

    
1019
        if not self.graphicsView.hasImage():
1020
            self.showImageSelectionMessageBox()
1021
            return
1022

    
1023
        try:
1024
            self.removedItems['LINE'] = []
1025
            self.removedItems['EQUIP'] = []
1026
            self.removedItems['INST'] = []
1027
            self.removedItems['NOTE'] = []
1028

    
1029
            appDocData = AppDocData.instance()
1030
            self.resultTreeWidget.setCurrentPID(appDocData.activeDrawing.name)
1031
            ## up to here
1032

    
1033
            self.onClearLog()
1034
            self.dlg = QRecognitionDialog(self, self.path)
1035
            self.dlg.exec_()
1036
            if self.dlg.isAccepted == True:
1037
                '''DO NOTHING'''
1038
        except Exception as ex:
1039
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1040
            self.addMessage.emit(MessageType.Error, message)
1041

    
1042
    '''
1043
        @brief      remove item from tree widget and then remove from scene
1044
        @date       2018.05.25
1045
        @author     Jeongwoo
1046
    '''
1047
    def itemRemoved(self, item):
1048
        try:
1049
            self.resultTreeWidget.itemRemoved(item)
1050

    
1051
            if type(item) is QEngineeringLineNoTextItem:
1052
                self.removedItems['LINE'].append(str(item.uid))
1053
            elif type(item) is QEngineeringInstrumentItem:
1054
                self.removedItems['INST'].append(str(item.uid))
1055
            elif type(item) is QEngineeringEquipmentItem:
1056
                self.removedItems['EQUIP'].append(str(item.uid))
1057
            elif type(item) is QEngineeringNoteItem:
1058
                self.removedItems['NOTE'].append(str(item.uid))
1059

    
1060
            if item.scene() is not None: item.scene().removeItem(item)
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
        @brief      recognize line
1067
        @author     humkyung
1068
        @date       2018.04.19
1069
        @history    Jeongwoo 2018.04.26 Variable name changed (texts → lineNos)
1070
                                        TextItem type changed (QEngineeringTextItem → QEngineeringLineNoTextItem)
1071
                    humkyung 2018.04.26 remove small objects before recognizing line
1072
                    Jeongwoo 2018.05.02 Show MessageBox when imageviewer doesn't have image
1073
                    Jeongwoo 2018.05.25 Move codes about LineDetector
1074
                    humkyung 2018.06.17 show progress dialog
1075
    '''
1076
    def recognizeLine(self, MainWindow):
1077
        from LineNoTracer import LineNoTracer
1078
        from ConnectAttrDialog import QConnectAttrDialog
1079

    
1080
        if not self.graphicsView.hasImage():
1081
            self.showImageSelectionMessageBox()
1082
            return
1083

    
1084
        try:
1085
            self.dlgConnectAttr = QConnectAttrDialog(self, self.graphicsView)
1086
            self.dlgConnectAttr.exec_()
1087

    
1088
            self.resultTreeWidget.InitLineNoItems()
1089

    
1090
            # construct line no item
1091
            docData = AppDocData.instance()
1092
            for lineno in docData.lineNos:
1093
                item = self.resultTreeWidget.addTreeItem(self.resultTreeWidget.root, lineno)
1094
                connectedItems = lineno.getConnectedItems()
1095
                for connectedItem in connectedItems:
1096
                    if issubclass(type(connectedItem), SymbolSvgItem): 
1097
                        self.resultTreeWidget.addTreeItem(item, connectedItem)
1098
            # up to here
1099
        except Exception as ex:
1100
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1101
            self.addMessage.emit(MessageType.Error, message)
1102

    
1103
    '''
1104
        @history    2018.05.25  Jeongwoo    Moved from MainWindow
1105
                                            SvgItem and TextItem Connect with method in this class
1106
                                            Change method to add GraphicsItem
1107
                    2018.05.28  Jeongwoo    Make QGraphicsItem by symbol, text object. Not xml
1108
                    2018.05.29  Jeongwoo    Change method name and Moved from QRecognitionDialog
1109
                    2018.05.30  Jeongwoo    Add parameters on SymbolSvgItem.__init__() (parentSymbol, childSymbol)
1110
                                            Change Method name and seperate each item
1111
                    humkyung 2018.06.11     display difference between original and recognized image
1112
                    Jeongwoo 2018.06.18     Update Scene after all item added
1113
    '''
1114
    def drawDetectedItems(self, symbolList, textInfoList, otherTextInfoList):
1115
        QApplication.processEvents()
1116
        self.drawDetectedSymbolItem(symbolList)
1117
        QApplication.processEvents()
1118
        self.drawDetectedTextItem(textInfoList)
1119
        QApplication.processEvents()
1120
        self.drawDetectedOtherTextItem(otherTextInfoList)
1121

    
1122
        # Update Scene
1123
        self.graphicsView.scene.update(self.graphicsView.sceneRect())
1124

    
1125
    '''
1126
        @brief      
1127
        @author     humkyung
1128
        @date       2018.08.23
1129
    '''
1130
    def drawDetectedLines(self, lineList, worker):
1131
        area = AppDocData.instance().getArea('Drawing')
1132

    
1133
        lines = []
1134
        for pts in lineList:
1135
            processLine = QEngineeringLineItem(vertices=[(area.x + param[0], area.y + param[1]) for param in pts])
1136
            processLine.area = 'Drawing'
1137
            self.graphicsView.scene.addItem(processLine)
1138
            lines.append(processLine)
1139

    
1140
            if processLine.length() > 100: # TODO: check critical length
1141
                processLine.addFlowArrow()
1142
        
1143
        # re-order process line's start,end according to flow mark
1144
        #worker.arrangeLinePosition(lines, symbols, listWidget)
1145
        # up to here
1146

    
1147
    '''
1148
        history    humkyung 2018.06.09 check length of original and connection point is 2 while parsing
1149
    '''
1150
    def drawDetectedSymbolItem(self, symbolList):
1151
        from GraphicsBoundingBoxItem import QGraphicsBoundingBoxItem
1152
        from SymbolSvgItem import SymbolSvgItem
1153
        import math
1154

    
1155
        try:
1156
            project = AppDocData.instance().getCurrentProject()
1157

    
1158
            searchedMap = []
1159
            for symbol in symbolList:
1160
                pt = [float(x) for x in symbol.getSp()]
1161
                size = [symbol.getWidth(), symbol.getHeight()]
1162
                name = symbol.getName()
1163
                angle = round(math.radians(symbol.getRotatedAngle()), 2)
1164
                _type = symbol.getType()
1165
                origin = [0,0]
1166
                if 2 == len(symbol.getOriginalPoint().split(',')):
1167
                    tokens = symbol.getOriginalPoint().split(',')
1168
                    origin = [pt[0] + float(tokens[0]), pt[1] + float(tokens[1])]
1169
                connPts = []
1170
                if symbol.getConnectionPoint() is not None:
1171
                    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(','))]
1172
                parentSymbol = symbol.getBaseSymbol()
1173
                childSymbol = symbol.getAdditionalSymbol()
1174
                hasInstrumentLabel = symbol.getHasInstrumentLabel()
1175

    
1176
                svgFilePath = os.path.join(project.getSvgFilePath(), _type, name + '.svg')
1177
                if os.path.isfile(svgFilePath):
1178
                    svg = SymbolSvgItem.createItem(_type, svgFilePath)
1179
                    svg.buildItem(name, _type, angle, pt, size, origin, connPts, parentSymbol, childSymbol, hasInstrumentLabel)
1180
                    svg.reCalculationRotatedItem()
1181
                    svg.area = 'Drawing'
1182

    
1183
                    # set owner - 2018.07.20 added by humkyung                   
1184
                    matches = [searched for searched in searchedMap if searched[0] == symbol.owner]
1185
                    if len(matches) == 1:
1186
                        svg.owner = matches[0][1]
1187
                    searchedMap.append((symbol, svg))
1188
                    # up to here
1189

    
1190
                    svg.transfer.onRemoved.connect(self.itemRemoved)
1191
                    self.addSvgItemToScene(svg)
1192
                    
1193
                    # Equipment Item 경우 저장
1194
                    if type(svg) is QEngineeringEquipmentItem:
1195
                        svg.saveEquipData()
1196

    
1197
                    # Instrument Item 경우 저장
1198
                    if type(svg) is QEngineeringInstrumentItem:
1199
                        svg.saveInstData()
1200
                else:
1201
                    item = QGraphicsBoundingBoxItem(pt[0], pt[1], size[0], size[1])
1202
                    item.isSymbol = True
1203
                    item.angle = angle
1204
                    item.setPen(QPen(Qt.red, 5, Qt.SolidLine))
1205
                    self.graphicsView.scene.addItem(item)
1206
            # up to here
1207
        except Exception as ex:
1208
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1209
            self.addMessage.emit(MessageType.Error, message)
1210

    
1211
    '''
1212
        @history    2018.06.08  Jeongwoo    Add parameter on round method
1213
    '''
1214
    def drawDetectedTextItem(self, textInfoList):
1215
        from TextItemFactory import TextItemFactory
1216
        import math
1217

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

    
1221
            # parse texts
1222
            for textInfo in textInfoList:
1223
                x = textInfo.getX()
1224
                y = textInfo.getY()
1225
                width = textInfo.getW()
1226
                height = textInfo.getH()
1227
                angle = round(math.radians(textInfo.getAngle()), 2)
1228
                text = textInfo.getText()
1229
                item = TextItemFactory.instance().createTextItem(text)
1230

    
1231
                if item is not None:
1232
                    item.loc = (x, y)
1233
                    item.size = (width, height)
1234
                    item.angle = angle
1235
                    item.setPlainText(text)
1236
                    item.area = 'Drawing'
1237
                    item.transfer.onRemoved.connect(self.itemRemoved)
1238
                    self.addTextItemToScene(item)
1239
                    appDocData.texts.append(item)
1240

    
1241
                    # Line No Text Item 경우 저장
1242
                    if type(item) is QEngineeringLineNoTextItem:
1243
                        item.saveLineData()
1244
        except Exception as ex:
1245
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1246
            self.addMessage.emit(MessageType.Error, message)
1247

    
1248
    '''
1249
        @brief      draw detected texts except which in drawing area
1250
    '''
1251
    def drawDetectedOtherTextItem(self, otherTextInfoList):
1252
        from TextItemFactory import TextItemFactory
1253
        import math
1254

    
1255
        try:
1256
            appDocData = AppDocData.instance()
1257

    
1258
            # parse notes
1259
            for textInfoMap in otherTextInfoList:
1260
                if textInfoMap[0]=='Note':
1261
                    pass
1262

    
1263
                for textInfo in textInfoMap[1]:
1264
                    x = textInfo.getX()
1265
                    y = textInfo.getY()
1266
                    width = textInfo.getW()
1267
                    height = textInfo.getH()
1268
                    angle = round(math.radians(textInfo.getAngle()))
1269
                    text = textInfo.getText()
1270

    
1271
                    item = TextItemFactory.instance().createTextItem(text)
1272

    
1273
                    item.loc = (x, y)
1274
                    item.size = (width, height)
1275
                    item.angle = angle
1276
                    item.setPlainText(text)
1277
                    item.area = textInfoMap[0]
1278
                    self.addTextItemToScene(item)
1279
                    appDocData.texts.append(item)
1280

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

    
1285

    
1286
    '''
1287
        @brief  draw unknown items 
1288
        @author humkyung
1289
        @date   2018.06.12
1290
        @history    2018.06.14  Jeongwoo    Change method to add unknown item
1291
                    2018.06.18  Jeongwoo    Add connect on unknown item
1292
                                            Add [transfer] for using pyqtSignal
1293
    '''
1294
    def drawUnknownItems(self):
1295
        from QEngineeringFlowArrowItem import QEngineeringFlowArrowItem 
1296
        from EngineeringLineItem import QEngineeringLineItem
1297
        from EngineeringUnknownItem import QEngineeringUnknownItem
1298

    
1299
        try:
1300
            docData = AppDocData.instance()
1301
            project = docData.getCurrentProject()
1302
            windowSize = docData.getSlidingWindowSize()
1303
            thickness = int(windowSize[1])
1304

    
1305
            diffFilePath = os.path.join(project.getTempPath(), "DIFF_" + os.path.basename(self.path))
1306
            if os.path.isfile(diffFilePath):
1307
                imgDiff = cv2.threshold(cv2.cvtColor(cv2.imread(diffFilePath, 1), cv2.COLOR_BGR2GRAY), 127, 255, cv2.THRESH_BINARY)[1]
1308

    
1309
                ## remove line
1310
                lines = [item for item in self.graphicsView.scene.items() if (type(item) is QEngineeringLineItem)]
1311
                for line in lines:
1312
                    line.drawToImage(imgDiff, 255, thickness)
1313
                cv2.imwrite(diffFilePath, imgDiff)
1314
                ## up to here
1315

    
1316
                imgNot = np.ones(imgDiff.shape, np.uint8)
1317
                cv2.bitwise_not(imgDiff, imgNot)
1318
                imgNot = cv2.dilate(imgNot, np.ones((8,8), np.uint8))
1319

    
1320
                diffItems = []
1321

    
1322
                image, contours, hierarchy = cv2.findContours(imgNot, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
1323
                for contour in contours:
1324
                    [x, y, w, h] = cv2.boundingRect(contour)
1325

    
1326
                    # remove too small one
1327
                    if (w < 10 or h < 10): continue
1328

    
1329
                    '''
1330
                    rect = QRectF(x, y, w, h)
1331
                    items = [item for item in diffItems if item.boundingRect().contains(rect)]
1332
                    if len(items) > 0: continue
1333
                    
1334
                    items = [item for item in diffItems if rect.contains(item.boundingRect())]
1335
                    for item in items:
1336
                        diffItems.remove(item)
1337
                    '''
1338

    
1339
                    # create unknown item
1340
                    epsilon = cv2.arcLength(contour, True)*0.001
1341
                    approx = cv2.approxPolyDP(contour, epsilon, True)
1342
                    approx = [pt[0] for pt in approx]
1343
                    item = QEngineeringUnknownItem(approx)
1344
                    item.ara = 'Drawing'
1345
                    diffItems.append(item)
1346
                    # up to here
1347

    
1348
                for item in diffItems:
1349
                    item.transfer.onRemoved.connect(self.itemRemoved)
1350
                    self.addUnknownItemToScene(item)
1351

    
1352
                notFilePath = os.path.join(project.getTempPath(), "NOT_" + os.path.basename(self.path))
1353
                cv2.imwrite(notFilePath, imgNot)
1354
            else:
1355
                message = 'can\'t found {}'.format(diffFilePath)
1356
                self.addMessage.emit(MessageType.Normal, message)
1357
        except Exception as ex:
1358
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1359
            self.addMessage.emit(MessageType.Error, message)
1360

    
1361
    '''
1362
        @brief      load recognition result
1363
        @author     humkyung
1364
        @date       2018.04.??
1365
        @history    humkyung 2018.01.12 parse originalpoint and connectionpoint
1366
                    Jeongwoo 2018.04.17 add QGraphicItem with Rotated text
1367
                    Jeongwoo 2018.04.23 Change to Draw texts on QEngineeringTextItem
1368
                    humkyung 2018.04.23 connect item remove slot to result tree
1369
                    Jeongwoo 2018.04.25 Add if state with QEngineeringNoteItem
1370
                    Jeongwoo 2018.04.26 Change method to create TextItem object with TextItemFactory
1371
                    Jeongwoo 2018.05.03 Change method to draw Svg Item on Scene (svg.addSvgItemToScene)
1372
                    Jeongwoo 2018.05.29 Change method name / Change method to add item / Add Line item
1373
                    Jeongwoo 2018.05.30 Add parameters on SymbolSvgItem.__init__() (parentSymbol, childSymbol) / Change method name / Change XML NODE NAMES
1374
                    Jeongwoo 2018.06.12 Add LineNoTextItem from LINE_NO
1375
                    Jeongwoo 2018.06.14 Add UnknownItem from UNKNOWN
1376
                    Jeongwoo 2018.06.18 Update Scene after all item added
1377
                                        Add connect on unknown item
1378
                                        Add [transfer] for using pyqtSignal
1379
                    kyouho  2018.07.12  Add line property logic
1380
                    humkyung 2018.08.22 show progress while loading xml file
1381
    '''
1382
    def loadRecognitionResultFromXml(self, xmlPath):
1383
        docData = AppDocData.instance()
1384
        from xml.etree.ElementTree import Element, SubElement, dump, ElementTree, parse
1385
        from EngineeringRunItem import QEngineeringRunItem
1386
        from QEngineeringTrimLineNoTextItem import QEngineeringTrimLineNoTextItem
1387

    
1388
        try:
1389
            symbols = []
1390

    
1391
            xml = parse(xmlPath)
1392
            root = xml.getroot()
1393
            
1394
            maxValue = 0
1395
            maxValue = maxValue + len(list(root.iter('SYMBOL')))
1396
            maxValue = maxValue + len(list(root.iter('ATTRIBUTE')))
1397
            maxValue = maxValue + len(list(root.iter('LINE_NO')))
1398
            maxValue = maxValue + len(list(root.iter('LINE')))
1399
            maxValue = maxValue + len(list(root.iter('UNKNOWN')))
1400
            self.progress.setMaximum(maxValue)
1401

    
1402
            for symbol in root.find('SYMBOLS').iter('SYMBOL'):
1403
                item = SymbolSvgItem.fromXml(symbol)
1404
                if item[0] is not None:
1405
                    item[0].transfer.onRemoved.connect(self.itemRemoved)
1406
                    symbols.append(item)
1407
                else:
1408
                    pt = [float(x) for x in symbol.find('LOCATION').text.split(',')]
1409
                    size = [float(x) for x in symbol.find('SIZE').text.split(',')]
1410
                    angle = float(symbol.find('ANGLE').text)
1411
                    item = QGraphicsBoundingBoxItem(pt[0], pt[1], size[0], size[1])
1412
                    item.isSymbol = True
1413
                    item.angle = angle
1414
                    item.setPen(QPen(Qt.red, 5, Qt.SolidLine))
1415
                    self.graphicsView.scene.addItem(item)
1416

    
1417
                self.progress.setValue(self.progress.value() + 1)
1418
                
1419
            QApplication.processEvents()
1420

    
1421
            # set symbol's owner
1422
            childItems = [item for item in symbols if item[1] is not None]
1423
            for item in childItems:
1424
                matches = [param for param in symbols if str(param[0].uid) == item[1]]
1425
                if len(matches) == 1:
1426
                    item[0].owner = matches[0][0]
1427
            # up to here
1428
           
1429
            for item in symbols:
1430
                self.addSvgItemToScene(item[0])
1431

    
1432
            # parse texts
1433
            for text in root.iter('ATTRIBUTE'):
1434
                item = QEngineeringTextItem.fromXml(text)
1435
                if item is not None:
1436
                    uid = text.find('UID')
1437
                    attributeValue = text.find('ATTRIBUTEVALUE')
1438
                    name = text.find('NAME').text
1439
                    item.transfer.onRemoved.connect(self.itemRemoved)
1440
                    self.addTextItemToScene(item)
1441

    
1442
                    if name == 'TEXT':
1443
                        if uid is not None and attributeValue is not None:
1444
                            item.uid = uid.text
1445
                            item.attribute = attributeValue.text
1446
                    elif name == 'NOTE':
1447
                        if uid is not None:
1448
                            item.uid = uid.text
1449

    
1450
                self.progress.setValue(self.progress.value() + 1)
1451
                
1452
            QApplication.processEvents()
1453

    
1454
            for line in root.find('LINEINFOS').iter('LINE'):
1455
                item = QEngineeringLineItem.fromXml(line)
1456
                item.transfer.onRemoved.connect(self.itemRemoved)
1457
                if item: self.addLineItemToScene(item)
1458

    
1459
                self.progress.setValue(self.progress.value() + 1)
1460
                
1461
            QApplication.processEvents()
1462

    
1463
            for unknown in root.iter('UNKNOWN'):
1464
                item = QEngineeringUnknownItem.fromXml(unknown)
1465
                item.transfer.onRemoved.connect(self.itemRemoved)
1466
                if item is not None:
1467
                    item.transfer.onRemoved.connect(self.itemRemoved)
1468
                    self.addUnknownItemToScene(item)
1469

    
1470
                self.progress.setValue(self.progress.value() + 1)
1471
                
1472
            QApplication.processEvents()
1473

    
1474
            for lineNo in root.iter('LINE_NO'):
1475
                location = lineNo.find('LOCATION').text if lineNo.find('LOCATION') is not None else '0,0'
1476
                x = float(location.split(',')[0])
1477
                y = float(location.split(',')[1])
1478
                width = float(lineNo.find('WIDTH').text) if lineNo.find('WIDTH') is not None else 0
1479
                height = float(lineNo.find('HEIGHT').text) if lineNo.find('HEIGHT') is not None else 0
1480
                angle = float(lineNo.find('ANGLE').text) if lineNo.find('ANGLE') is not None else 0
1481
                text = lineNo.find('TEXT').text
1482

    
1483
                item = TextItemFactory.instance().createTextItem(text)
1484
                if item is not None:
1485
                    item.loc = (x, y)
1486
                    item.size = (width, height)
1487
                    item.angle = angle
1488
                    item.setPlainText(text)
1489
                    item.transfer.onRemoved.connect(self.itemRemoved)
1490
                    self.addTextItemToScene(item)
1491

    
1492
                    # attr
1493
                    for userInputAttr in lineNo.iter('USERINPUTATTRIBUTE'):
1494
                        newAttr = UserInputAttribute(userInputAttr.find('TYPEUID').text, userInputAttr.find('TYPEVALUE').text)
1495
                        item._attrs.append(newAttr)
1496
                    for attr in lineNo.iter('ATTRIBUTE'):
1497
                        item._attrs.append((attr.find('NAME').text, attr.find('VALUE').text))
1498

    
1499
                connLine = lineNo.find('CONNLINE')
1500
                if connLine is not None:
1501
                    lineUID = connLine.text
1502
                    connLine = self.graphicsView.findItemByUid(lineUID)
1503
                    if connLine is not None:
1504
                        item.conns.append(connLine)
1505

    
1506
                run = lineNo.find('RUN')
1507
                if run is not None:
1508
                    lineRunItem = QEngineeringRunItem()
1509
                    for child in run:
1510
                        uidElement = child.find('UID')
1511
                        if uidElement is not None:
1512
                            uid = uidElement.text
1513
                            runItem = self.graphicsView.findItemByUid(uid)
1514
                            if runItem is not None:
1515
                                lineRunItem.items.append(runItem)
1516

    
1517
                    item.runs.append(lineRunItem)
1518
                    treeItem = self.resultTreeWidget.addTreeItem(self.resultTreeWidget.root, item)
1519
                    for connectedItem in lineRunItem.items:
1520
                        if issubclass(type(connectedItem), SymbolSvgItem): self.resultTreeWidget.addTreeItem(treeItem, connectedItem)
1521
                    docData.lineNos.append(item)
1522

    
1523
                self.progress.setValue(self.progress.value() + 1)
1524
            QApplication.processEvents()
1525

    
1526
            for trimLineNo in root.iter('TRIM_LINE_NO'):
1527
                item = QEngineeringTrimLineNoTextItem()
1528
                item.uid = trimLineNo.find('UID')
1529

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

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

    
1548
            # set symbol's connectItem
1549
            from EngineeringConnectorItem import QEngineeringConnectorItem
1550
            connectors = [item for item in self.graphicsView.scene.items() if type(item) == QEngineeringConnectorItem and item.connectedItem is not None]
1551
            for connector in connectors:
1552
                # 처음에는 UID가 connectedItem에 String으로 들어가있기 때문에
1553
                connector.connectedItem = self.graphicsView.findItemByUid(connector.connectedItem)
1554

    
1555
            symbols = [item for item in self.graphicsView.scene.items() if issubclass(type(item), SymbolSvgItem) and len(item.attrs) > 0]
1556
            for symbol in symbols:
1557
                # 처음에는 attrs의 uid가 connectedItem에 String으로 들어가있기 때문에
1558
                for index in range(len(symbol.attrs)):
1559
                    if type(symbol.attrs[index]) is not UserInputAttribute and type(symbol.attrs[index]) is not tuple:
1560
                        symbol.attrs[index] = self.graphicsView.findItemByUid(symbol.attrs[index])
1561
                        
1562
            # Update Scene
1563
            self.graphicsView.scene.update(self.graphicsView.sceneRect())
1564

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

    
1569
    '''
1570
        @brief      Remove added item on same place and Add GraphicsItem
1571
        @author     Jeongwoo
1572
        @date       2018.05.25
1573
        @history    2018.05.29  Jeongwoo    Moved from QRecognitionDialog
1574
                    2018.06.18  Jeongwoo    Set Z-index
1575
    '''
1576
    def addSvgItemToScene(self, svgItem):
1577
        svgItem.addSvgItemToScene(self.graphicsView.scene)
1578
        
1579
    '''
1580
        @brief      Remove added item on same place and Add GraphicsItem
1581
        @author     Jeongwoo
1582
        @date       2018.05.25
1583
        @history    2018.05.29  Jeongwoo    Moved from QRecognitionDialog
1584
                    2018.06.05  Jeongwoo    Remove Size condition
1585
                    2018.06.18  Jeongwoo    Set Z-index
1586
    '''
1587
    def addTextItemToScene(self, textItem):
1588
        textItem.addTextItemToScene(self.graphicsView.scene)
1589
        
1590
    '''
1591
        @brief      Remove added item on same place and Add GraphicsItem
1592
        @author     Jeongwoo
1593
        @date       2018.05.29
1594
        @history    2018.06.18  Jeongwoo    Set Z-index
1595
    '''
1596
    def addLineItemToScene(self, lineItem):
1597
        lineItem.addLineItemToScene(self.graphicsView.scene)
1598

    
1599
    '''
1600
        @brief      Remove added item on same place and Add Unknown Item
1601
        @author     Jeongwoo
1602
        @date       2018.06.14
1603
        @history    2018.06.18  Jeongwoo    Set Z-index
1604
    '''
1605
    def addUnknownItemToScene(self, unknownItem):
1606
        try:
1607
            unknownItem.addUnknownItemToScene(self.graphicsView.scene)
1608
        except Exception as ex:
1609
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1610
            self.addMessage.emit(MessageType.Error, message)
1611

    
1612
    '''
1613
        @brief      generate output xml file
1614
        @author     humkyung
1615
        @date       2018.04.23
1616
        @history    2018.05.02  Jeongwoo    Show MessageBox when imageviewer doesn't have image
1617
    '''
1618
    def generateOutput(self):
1619
        import XmlGenerator as xg
1620

    
1621
        if not self.graphicsView.hasImage():
1622
            self.showImageSelectionMessageBox()
1623
            return
1624

    
1625
        try:
1626
            appDocData = AppDocData.instance()
1627

    
1628
            ## collect items
1629
            appDocData.lines.clear()
1630
            appDocData.lines = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringLineItem and item.owner is None]
1631

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

    
1635
            appDocData.equipments.clear()
1636
            for item in self.graphicsView.scene.items():
1637
                if type(item) is QEngineeringEquipmentItem:
1638
                    appDocData.equipments.append(item)
1639

    
1640
            appDocData.texts.clear()
1641
            appDocData.texts = [item for item in self.graphicsView.scene.items() if issubclass(type(item), QEngineeringTextItem) and type(item) is not QEngineeringLineNoTextItem]
1642
            ## up to here
1643

    
1644
            appDocData.imgOutput = np.ones((appDocData.imgHeight, appDocData.imgWidth), np.uint8)*255
1645
            xg.writeOutputXml(appDocData.imgName, appDocData.imgWidth, appDocData.imgHeight) # TODO: check
1646
            project = appDocData.getCurrentProject()
1647
            cv2.imwrite(os.path.join(project.getTempPath() , 'OUTPUT.png') , appDocData.imgOutput)
1648
        except Exception as ex:
1649
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1650
            self.addMessage.emit(MessageType.Error, message)
1651

    
1652
    '''
1653
        @brief      resetting attribute at secne
1654
        @author     kyoyho
1655
        @date       2018.08.21
1656
    '''
1657
    def checkAttribute(self):
1658
        try:
1659

    
1660
            docData = AppDocData.instance()
1661
            if not self.graphicsView.hasImage():
1662
                return
1663

    
1664
            # symbol 경우
1665
            items = [item for item in self.graphicsView.scene.items() if issubclass(type(item), SymbolSvgItem)]
1666
            for item in items:
1667
                attrs = item.attrs
1668
                
1669
                removeAttrList = []
1670
                for attr in attrs:
1671
                    if type(attr) is tuple:
1672
                        continue
1673

    
1674
                    if attr is None:
1675
                        removeAttrList.append(attr)
1676
                        continue
1677

    
1678
                    attrInfo = docData.getSymbolAttributeByUID(attr.attribute)
1679
                    if attrInfo is None:
1680
                        removeAttrList.append(attr)
1681
                    # 해당 attribute가 맞는지 확인
1682
                    else:
1683
                        attrType = attrInfo[2]
1684
                        _type = type(attr)
1685
                        if attrType == 'Symbol Item':
1686
                            if not issubclass(_type, SymbolSvgItem):
1687
                                removeAttrList.append(attr)
1688
                        elif attrType == 'Text Item':
1689
                            if _type is not QEngineeringTextItem:
1690
                                removeAttrList.append(attr)
1691
                        elif attrType == 'Int':
1692
                            if _type is not UserInputAttribute and self.isNumber(attr.text):
1693
                                removeAttrList.append(attr)
1694
                        elif attrType == 'String':
1695
                            if _type is not UserInputAttribute:
1696
                                removeAttrList.append(attr)
1697

    
1698
                for attr in removeAttrList:
1699
                    attrs.remove(attr)
1700

    
1701
            # Line No Text Item의 경우
1702
            items = [item for item in self.graphicsView.scene.items() if issubclass(type(item), QEngineeringLineNoTextItem)]
1703
            for item in items:
1704
                attrs = item._attrs
1705
                
1706
                removeAttrList = []
1707
                for attr in attrs:
1708
                    if type(attr) is UserInputAttribute:
1709
                        attrInfo = docData.getLinePropertiesByUID(attr.attribute)
1710
                        if attrInfo is None:
1711
                            removeAttrList.append(attr)
1712

    
1713
                for attr in removeAttrList:
1714
                    attrs.remove(attr)
1715

    
1716
        except Exception as ex:
1717
                message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1718
                self.addMessage.emit(MessageType.Error, message)
1719
    '''
1720
        @brief      Check Number
1721
        @author     kyouho
1722
        @date       2018.08.20
1723
    '''
1724
    def isNumber(self, num):
1725
        p = re.compile('(^[0-9]+$)')
1726
        result = p.match(num)
1727

    
1728
        if result:
1729
            return True
1730
        else:
1731
            return False
1732

    
1733
    '''
1734
        @brief      find overlap Connector
1735
        @author     kyouho
1736
        @date       2018.08.28
1737
    '''
1738
    def findOverlapConnector(self, connectorItem):
1739
        from shapely.geometry import Point
1740
        from EngineeringConnectorItem import QEngineeringConnectorItem
1741
        itemList = []
1742
        
1743
        x = connectorItem.center()[0]
1744
        y = connectorItem.center()[1]
1745

    
1746
        connectors = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringConnectorItem and item != connectorItem]
1747
        for connector in connectors:
1748
            if Point(x, y).distance(Point(connector.center()[0], connector.center()[1])) < 5:
1749
                itemList.append(connector.parent)
1750

    
1751
        return itemList
1752

    
1753
            
1754
if __name__ == '__main__':
1755
    from ProjectDialog import Ui_Dialog
1756
    from App import App 
1757

    
1758
    app = App(sys.argv)
1759
    try:
1760
        dlg = Ui_Dialog()
1761
        selectedProject = dlg.showDialog()
1762
        if selectedProject is not None:
1763
            AppDocData.instance().setCurrentProject(selectedProject)
1764
            app._mainWnd = MainWindow.instance()
1765
            app._mainWnd.show()
1766
            sys.exit(app.exec_())
1767
    except Exception as ex:
1768
        print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
1769
    finally:
1770
        pass
클립보드 이미지 추가 (최대 크기: 500 MB)