프로젝트

일반

사용자정보

통계
| 개정판:

hytos / DTI_PID / DTI_PID / MainWindow.py @ 21fc8683

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

1
# coding: utf-8
2

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

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

    
18
import cv2
19
import numpy as np
20

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

    
26
from PIL import Image
27

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
204
        self.treeWidgetDrawingList.itemDoubleClicked.connect(self.open_selected_drawing)
205
        self.load_drawing_list()
206

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

    
217
    def load_stylesheet(self, file):
218
        """
219
        @brief  load stylesheets
220
        @author humkyung
221
        @date   2018.10.29
222
        """
223

    
224
        QtWidgets.qApp.loadStyleSheet(os.path.join(os.path.dirname(os.path.realpath(__file__)), file))
225

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

    
234
    '''
235
        @brief      Clear TreeWidget and Set Current PID
236
        @author     Jeongwoo
237
        @date       18.04.11
238
        @history    2018.04.26  Jeongwoo    Add Child [SYMBOLS, NOTES] into root item
239
                    2018.05.09  Jeongwoo    Change method to add default tree items
240
                    humkyung 2018.06.10 add tree item for Line No and Unknown Item
241
    '''
242
    def load_drawing_list(self):
243
        """
244
        @brief      load p&id drawing list
245
        @author     humkyung
246
        @date       18.11.02
247
        """
248
        appDocData = AppDocData.instance()
249

    
250
        self.treeWidgetDrawingList.clear()
251
        self.treeWidgetDrawingList.root = QTreeWidgetItem(self.treeWidgetDrawingList, ['P&ID Drawings'])
252
        files = appDocData.getDrawingFileList()
253
        for file in files:
254
            item = QTreeWidgetItem(self.treeWidgetDrawingList.root, [file])
255
            item.setIcon(0, QIcon(':newPrefix/image.png'))
256

    
257
        self.treeWidgetDrawingList.expandItem(self.treeWidgetDrawingList.root)
258
        self.treeWidgetDrawingList.root.sortChildren(0, Qt.AscendingOrder)
259

    
260
    def open_selected_drawing(self, item, column):
261
        """
262
        @brief      open selected p&id drawing
263
        @author     humkyung
264
        @date       18.11.02
265
        """
266
        appDocData = AppDocData.instance()
267
        drawing = os.path.join(appDocData.getCurrentProject().getDrawingFilePath(), item.text(column))
268
        self.onOpenImageDrawing(drawing)
269

    
270
    def onShowDetectSymbol(self):
271
        from DetectSymbolDialog import QDetectSymbolDialog
272

    
273
        dlgDetectSymbol = QDetectSymbolDialog(self)
274
        dlgDetectSymbol.show()
275
        dlgDetectSymbol.exec_()
276
        
277
    '''
278
        @brief      OCR Editor
279
        @author     euisung
280
        @date       2018.10.05
281
        @history    2018.10.16 euisung      no more used, Integrated with oCRTrainingClicked
282
    '''
283
    def oCRTrainingEdidorClicked(self):
284
        from TrainingEditorDialog import QTrainingEditorDialog
285

    
286
        try:
287
            dialog = QTrainingEditorDialog(self)
288
            dialog.exec_()
289
        except Exception as ex:
290
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
291
            self.addMessage.emit(MessageType.Error, message)
292
            
293
        return
294

    
295
    '''
296
        @brief      OCR Training
297
        @author     euisung
298
        @date       2018.09.27
299
        @history    euisung 2018.10.16 TrainingListDialog -> TrainingImageListDialog
300
    '''
301
    def oCRTrainingClicked(self):
302
        from TrainingImageListDialog import QTrainingImageListDialog
303
        #import ctypes
304
        #if not ctypes.windll.shell32.IsUserAnAdmin():
305
        #    reply = QMessageBox.information(self, 'Error', '관리자 권한으로 실행해 주세요.')
306
        #    #return
307
        try:
308
            dialog = QTrainingImageListDialog(self)
309
            dialog.exec_()
310
        except Exception as ex:
311
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
312
            self.addMessage.emit(MessageType.Error, message)
313
            
314
        return
315

    
316
    '''
317
        @brief      show unknownitem's count
318
        @author     kyouho
319
        @date       2018.08.27
320
    '''
321
    def findReplaceTextClicked(self):
322
        if not self.graphicsView.hasImage():
323
            self.showImageSelectionMessageBox()
324
            return
325

    
326
        from TextItemEditDialog import QTextItemEditDialog
327

    
328
        self.dlgTextItemEdit = QTextItemEditDialog(self)
329
        self.dlgTextItemEdit.show()
330
        self.dlgTextItemEdit.exec_()
331

    
332
    '''
333
        @brief      show unknownitem's count
334
        @author     humkyung
335
        @date       2018.08.23
336
        @history    humkyung 2018.08.30 display count of symbol, line, text
337
    '''
338
    def onSceneChanged(self):
339
        items = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringUnknownItem]
340
        if len(items) > 0:
341
            self.labelStatus.setText("<font color='red'>미인식 : {}</font>".format(len(items)))
342
        else:
343
            self.labelStatus.setText("<font color='black'>미인식 : {}</font>".format(len(items)))
344

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

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

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

    
354
    '''
355
        @brief      action save click event
356
        @author     kyouho
357
        @date       2018.08.09
358
        @history    euisung     2018.11.02       add line data list db update
359
    '''
360
    def actionSaveCliked(self):
361
        items = self.graphicsView.scene.items()
362
        for item in items:
363
            if type(item) is QEngineeringLineNoTextItem:
364
                item.saveLineData()
365
            if type(item) is QEngineeringEquipmentItem:
366
                item.saveEquipData()
367
            if type(item) is QEngineeringInstrumentItem:
368
                item.saveInstData()
369
        self.saveToXml(True)
370

    
371
    '''
372
        @brief      save items to xml
373
        @author     kyouho
374
        @date       2018.07.31
375
    '''
376
    def saveToXml(self, alert = True):
377
        import XmlGenerator as xg
378
        from AppDocData import AppDocData
379
        docData = AppDocData.instance()
380
        if docData.imgName is None:
381
            self.showImageSelectionMessageBox()
382
            return
383
        result = xg.writeXmlOnScene(docData.imgName, docData.imgWidth, docData.imgHeight, self.graphicsView.scene)
384
        
385
        if len(self.removedItems['LINE']):
386
            docData.deleteLineDataList_LineNo(self.removedItems['LINE'])
387
            self.removedItems['LINE'] = []
388

    
389
        if len(self.removedItems['EQUIP']):
390
            docData.deleteEquipDataList(self.removedItems['EQUIP'])
391
            self.removedItems['EQUIP'] = []
392

    
393
        if len(self.removedItems['INST']):
394
            docData.deleteInstDataList(self.removedItems['INST'])
395
            self.removedItems['INST'] = []
396

    
397
        if len(self.removedItems['NOTE']):
398
            docData.deleteNoteDataList(self.removedItems['NOTE'])
399
            self.removedItems['NOTE'] = []
400

    
401

    
402
        if alert:
403
            resultStr = '[저장 결과]'
404

    
405
            for item in result.items():
406
                itemName = str(item[0])
407
                itemSuccessCount = str(item[1][0])
408
                itemFailUidList = item[1][1]
409
                resultStr += "\r\n" + itemName + " Save Count : " + itemSuccessCount
410
                if len(itemFailUidList) > 0:
411
                    resultStr += "\r\n" + itemName + " Error List(UID)"
412
                    for uid in itemFailUidList:
413
                        resultStr += "\r\n" + uid
414

    
415
            QMessageBox.about(self.graphicsView, "알림", resultStr)
416

    
417
    '''
418
        @brief      refresh resultPropertyTableWidget
419
        @author     kyouho
420
        @date       2018.07.19
421
    '''
422
    def refreshResultPropertyTableWidget(self):
423
        items = self.graphicsView.scene.selectedItems()
424
        if len(items) == 1:
425
            self.resultPropertyTableWidget.onSymbolClicked(items[0])
426
    
427
    '''
428
        @brief      resultPropertyTableWidget Cell Click Event
429
        @author     kyouho
430
        @date       2018.08.23
431
    '''
432
    def cellClickedEvent(self, row, column):
433
        item = self.graphicsView.scene.selectedItems()
434
        if len(item) != 1:
435
            return
436
        item = item[0]
437

    
438
        cell = self.resultPropertyTableWidget.item(row, column)
439
        for valueCell, uid in self.resultPropertyTableWidget.attrValueList:
440
            if valueCell == cell and issubclass(type(item), SymbolSvgItem):
441
                for attr in item.attrs:
442
                    if attr.attribute == uid and (issubclass(type(attr), SymbolSvgItem) or type(attr) is QEngineeringTextItem):
443
                        prevItem = item
444
                        currentItem = attr
445

    
446
                        rect = currentItem.sceneBoundingRect()
447
                        self.graphicsView.centerOn(rect.center())
448
                        self.graphicsView.zoomImage(True, QMouseEvent(QEvent.MouseButtonPress, self.graphicsView.mapFromScene(QPointF(rect.left(), rect.top())), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier), 3)
449
                        prevItem.setSelected(True)
450

    
451
                        currentItem.setHightlight()
452
                    elif (issubclass(type(attr), SymbolSvgItem) or type(attr) is QEngineeringTextItem):
453
                        attr.unsetHightlight()
454

    
455

    
456
    '''
457
        @brief  add message listwidget
458
        @author humkyung
459
        @date   2018.07.31
460
    '''
461
    def onAddMessage(self, messageType, message):
462
        from AppDocData import MessageType
463

    
464
        try:
465
            current = QDateTime.currentDateTime()
466

    
467
            item = QListWidgetItem('{}: {}'.format(current.toString('hh:mm:ss'), message))
468
            if messageType == MessageType.Error:
469
                item.setBackground(Qt.red)
470

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

    
475
    '''
476
        @brief      clear log
477
        @author     humkyung
478
        @date       2018.08.01
479
    '''
480
    def onClearLog(self):
481
        self.listWidgetLog.clear()
482

    
483
    '''
484
        @brief      rotate selected symbol
485
        @author     humkyung
486
        @date       2018.08.15
487
    '''
488
    def onRotate(self, action):
489
        selected = [item for item in self.graphicsView.scene.selectedItems() if issubclass(type(item), SymbolSvgItem)]
490
        if len(selected) == 1:
491
            selected[0].rotateSymbol()
492

    
493
    '''
494
        @brief      Area Zoom
495
        @author     Jeongwoo
496
        @date       2018.06.27
497
        @history    connect command's rejected signal
498
    '''
499
    def onAreaZoom(self, action):
500
        if self.actionZoom.isChecked():
501
            cmd = AreaZoomCommand.AreaZoomCommand(self.graphicsView)
502
            cmd.onRejected.connect(self.onCommandRejected)
503
            self.graphicsView.command = cmd
504

    
505
    '''
506
        @brief      Fit Window
507
        @author     Jeongwoo
508
        @date       2018.06.27
509
        @history    2018.06.27  Jeongwoo    Chnage method to initialize command [Set None → DefaultCommand]
510
    '''
511
    def fitWindow(self, action):
512
        self.graphicsView.useDefaultCommand()
513
        self.graphicsView.zoomImageInit()
514

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

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

    
555
            return
556

    
557
        msg = QMessageBox()
558
        msg.setIcon(QMessageBox.Critical)
559
        msg.setText("선택한 인식한 항목들을 삭제하시겠습니까?\n삭제된 항목들은 복구할 수 없습니다.")
560
        msg.setWindowTitle("항목 삭제")
561
        msg.setStandardButtons(QMessageBox.Ok|QMessageBox.Cancel)
562
        if QMessageBox.Ok == msg.exec_():
563
            items = self.graphicsView.scene.items()
564
            for item in items:
565
                if type(item) is not QGraphicsPixmapItem:
566
                    self.graphicsView.scene.removeItem(item)
567

    
568
                    if type(item) is QEngineeringLineNoTextItem:
569
                        self.removedItems['LINE'].append(str(item.uid))
570
                    elif type(item) is QEngineeringInstrumentItem:
571
                        self.removedItems['INST'].append(str(item.uid))
572
                    elif type(item) is QEngineeringEquipmentItem:
573
                        self.removedItems['EQUIP'].append(str(item.uid))
574
                    elif type(item) is QEngineeringNoteItem:
575
                        self.removedItems['NOTE'].append(str(item.uid))
576
                    
577
            if self.path is not None:
578
                baseName = os.path.basename(self.path)
579
                self.resultTreeWidget.setCurrentPID(baseName)
580

    
581
    '''
582
        @brief      Manage Checkable Action statement
583
        @author     Jeongwoo
584
        @date       2018.05.10
585
        @history    2018.06.27  Jeongwoo    Chnage method to initialize command [Set None → DefaultCommand]
586
    '''
587
    def actionGroupTriggered(self, action):
588
        if self.graphicsView.command is not None:
589
            self.graphicsView.useDefaultCommand()
590

    
591
        for _action in self.actionGroup.actions():
592
            _action.setChecked(False)
593

    
594
        action.setChecked(True)
595

    
596
    '''
597
        @brief      Create Equipment
598
        @author     Jeongwoo
599
        @date       18.05.03
600
        @history    2018.05.04  Jeongwoo    Add Parameter on CreateSymbolCommand
601
    '''
602
    def createEquipment(self):
603
        if not self.graphicsView.hasImage():
604
            self.actionEquipment.setChecked(False)
605
            self.showImageSelectionMessageBox()
606
            return
607
        if self.actionEquipment.isChecked():
608
            self.graphicsView.command = CreateSymbolCommand.CreateSymbolCommand(self.graphicsView, self.resultTreeWidget, self.dirTreeWidget)
609
        else:
610
            self.graphicsView.useDefaultCommand()
611

    
612

    
613
    '''
614
        @brief      Create Nozzle
615
        @author     Jeongwoo
616
        @date       2018.05.03
617
        @history    2018.05.04  Jeongwoo    Add Parameter on CreateSymbolCommand
618
    '''
619
    def createNozzle(self):
620
        if not self.graphicsView.hasImage():
621
            self.actionNozzle.setChecked(False)
622
            self.showImageSelectionMessageBox()
623
            return
624
        if self.actionNozzle.isChecked():
625
            self.graphicsView.command = CreateSymbolCommand.CreateSymbolCommand(self.graphicsView, self.resultTreeWidget, self.dirTreeWidget)
626
        else:
627
            self.graphicsView.useDefaultCommand()
628

    
629
    '''
630
        @brief      Area OCR
631
        @author     Jeongwoo
632
        @date       18.04.18
633
        @history    2018.05.02  Jeongwoo    Change graphicsView.command by actionOCR checked state
634
                                            Show MessageBox when imageviewer doesn't have image
635
    '''
636
    def onAreaOcr(self):
637
        if not self.graphicsView.hasImage():
638
            self.actionOCR.setChecked(False)
639
            self.showImageSelectionMessageBox()
640
            return
641

    
642
        if self.actionOCR.isChecked():
643
            cmd = AreaOcrCommand.AreaOcrCommand(self.graphicsView)
644
            cmd.onSuccess.connect(self.onRecognizeText)
645
            cmd.onRejected.connect(self.onCommandRejected)
646
            self.graphicsView.command = cmd
647
        else:
648
            self.graphicsView.useDefaultCommand()
649
    
650
    '''
651
        @brief      show text recognition dialog
652
        @author     humkyung
653
        @date       2018.08.08
654
    '''
655
    def onRecognizeText(self, x, y, width, height):
656
        from OcrResultDialog import QOcrResultDialog
657

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

    
693
    '''
694
        @brief  area configuration
695
    '''
696
    def areaConfiguration(self):
697
        from ConfigurationAreaDialog import QConfigurationAreaDialog
698

    
699
        self.dlgConfigurationArea = QConfigurationAreaDialog(self)
700
        self.dlgConfigurationArea.show()
701
        self.dlgConfigurationArea.exec_()
702

    
703
    '''
704
        @brief  configuration
705
    '''
706
    def configuration(self):
707
        from ConfigurationDialog import QConfigurationDialog
708

    
709
        self.dlgConfiguration = QConfigurationDialog(self)
710
        self.dlgConfiguration.show()
711
        self.dlgConfiguration.exec_()
712

    
713
    '''
714
        @brief  show nominal diameter dialog 
715
        @author humkyung
716
        @date   2018.06.28
717
    '''
718
    def onShowCodeTable(self):
719
        from CodeTableDialog import QCodeTableDialog
720

    
721
        dlg = QCodeTableDialog(self)
722
        dlg.exec_()
723

    
724
    '''
725
        @brief  show HMB data
726
        @author humkyung
727
        @date   2018.07.11
728
    '''
729
    def onHMBData(self):
730
        from HMBDialog import QHMBDialog
731

    
732
        dlg = QHMBDialog(self)
733
        dlg.show()
734
        dlg.exec_()
735

    
736
    '''
737
        @brief  show line data list 
738
        @author humkyung
739
        @date   2018.05.03
740
    '''
741
    def showItemDataList(self):
742
        from ItemDataExportDialog import QItemDataExportDialog
743

    
744
        self.dlgLineDataList = QItemDataExportDialog(self)
745
        self.dlgLineDataList.exec_()
746

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

    
767
    '''
768
        @brief      Open image drawing file and then display it
769
        @author     humkyung
770
        @date       2018.??.??
771
        @history    18.04.23 Jeongwoo    Add AppDocData.instance().setCurrentPidSource
772
                    18.04.23 Jeongwoo    Add Store Set Current Pid Image on AppDocData
773
                    18.05.02 Jeongwoo    Add useDefaultCommand()
774
                    humkyung 2018.05.24 load recognition result file if exists
775
                    Jeongwoo 2018.05.29 load data on xml if xml file exist
776
                    humkyung 2018.08.22 clear scene before loading xml file
777
    '''
778
    def onOpenImageDrawing(self, path=None):
779
        from Drawing import Drawing
780

    
781
        try:
782
            appDocData = AppDocData.instance()
783
            project = appDocData.getCurrentProject()
784
            
785
            for item in self.graphicsView.scene.items():
786
                self.graphicsView.scene.removeItem(item)
787

    
788
            self.path = self.graphicsView.loadImageFromFile(project.getDrawingFilePath(), path)
789
            if os.path.isfile(self.path):
790
                appDocData.clear()
791
                self.graphicsView.useDefaultCommand()
792

    
793
                appDocData.setImgFilePath(self.path)
794
                appDocData.activeDrawing = Drawing(appDocData.imgName)
795
                appDocData.setCurrentPidSource(Image.open(self.path))
796
                self.resultTreeWidget.setCurrentPID(appDocData.activeDrawing.name)
797

    
798
                self.progress = QProgressDialog("잠시만 기다려주세요", "Cancel", 0, 100, self)
799
                self.progress.setWindowModality(Qt.WindowModal)
800
                self.progress.setAutoReset(True)
801
                self.progress.setAutoClose(True)
802
                self.progress.setMinimum(0)
803
                self.progress.resize(600,100)
804
                self.progress.setWindowTitle("파일 읽는 중...")
805
                self.progress.show()
806

    
807
                ## Load data on xml
808
                try:
809
                    path = os.path.join(appDocData.getCurrentProject().getTempPath(), appDocData.imgName + '.xml')
810
                    if os.path.isfile(path):
811
                        self.loadRecognitionResultFromXml(path)
812
                        self.checkAttribute()
813
                finally:
814
                    self.progress.setValue(self.progress.maximum())
815
                    self.progress.hide()
816
        except Exception as ex:
817
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
818
            self.addMessage.emit(MessageType.Error, message)
819

    
820
        return self.path
821

    
822
    '''
823
        @brief  visible/invisible image drawing
824
        @author humkyung
825
        @date   2018.06.25
826
    '''
827
    def onViewImageDrawing(self, isChecked):
828
        for item in self.graphicsView.scene.items():
829
            if type(item) is QGraphicsPixmapItem:
830
                item.setVisible(isChecked)
831
                break
832

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

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

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

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

    
873
    '''
874
        @brief  create a symbol
875
        @history    2018.05.02  Jeongwoo    Change return value of QSymbolEditorDialog (Single variable → Tuple)
876
                                            Add SymbolSvgItem
877
                    2018.05.03  Jeongwoo    Change method to draw Svg Item on Scene (svg.addSvgItemToScene)
878
                                            Change method to make svg and image path
879
                    2018.06.08  Jeongwoo    Add Paramter on SymbolSvgItem.buildItem()
880
    '''
881
    def onCreateSymbolClicked(self):
882
        cmd = FenceCommand.FenceCommand(self.graphicsView)
883
        cmd.onSuccess.connect(self.onAreaSelected)
884
        self.graphicsView.command = cmd
885
        QApplication.setOverrideCursor(Qt.CrossCursor)
886

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

    
911
                        svg.transfer.onRemoved.connect(self.resultTreeWidget.itemRemoved)
912
                        svg.addSvgItemToScene(self.graphicsView.scene)
913
                        for connector in svg.connectors:
914
                            self.graphicsView.scene.addItem(connector)
915
        finally:
916
            self.graphicsView.useDefaultCommand()
917
            QApplication.restoreOverrideCursor()
918
    
919
    '''
920
        @brief      create a line
921
        @author     humkyung
922
        @history    Jeongwoo 2018.05.10 Change method for Checkable action
923
    '''
924
    def onPlaceLine(self):        
925
        if not self.graphicsView.hasImage():
926
            self.actionLine.setChecked(False)
927
            self.showImageSelectionMessageBox()
928
            return
929

    
930
        self.actionLine.setChecked(True)
931
        if not hasattr(self.actionLine, 'tag'):
932
            self.actionLine.tag = PlaceLineCommand.PlaceLineCommand(self.graphicsView)
933
            self.actionLine.tag.onSuccess.connect(self.onLineCreated)
934
            self.actionLine.tag.onRejected.connect(self.onCommandRejected)
935

    
936
        self.graphicsView.command = self.actionLine.tag
937

    
938
    '''
939
        @brief      add created lines to scene
940
        @author     humkyung
941
        @date       2018.07.23
942
    '''
943
    def onLineCreated(self):
944
        from EngineeringConnectorItem import QEngineeringConnectorItem
945

    
946
        try:
947
            count = len(self.actionLine.tag._polyline._vertices)
948
            if count > 1:
949
                items = []
950

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

    
970
                pt = items[-1].endPoint()
971
                selected = self.graphicsView.scene.itemAt(QPointF(pt[0], pt[1]), QTransform())
972
                if selected is not None and type(selected) is QEngineeringConnectorItem:
973
                    items[-1].connectIfPossible(selected.parent, 5)
974
        finally:
975
            self.graphicsView.scene.removeItem(self.actionLine.tag._polyline)
976
            self.actionLine.tag.reset()
977

    
978
    '''
979
        @brief      refresh scene
980
        @author     humkyung
981
        @date       2018.07.23
982
    '''
983
    def onCommandRejected(self, cmd):
984
        try:
985
            if type(cmd) is PlaceLineCommand.PlaceLineCommand:
986
                self.graphicsView.scene.removeItem(self.actionLine.tag._polyline)
987
                self.graphicsView.scene.update()
988
                self.actionLine.tag.reset()
989

    
990
                self.actionLine.setChecked(False)
991
            elif type(cmd) is AreaZoomCommand.AreaZoomCommand:
992
                self.actionZoom.setChecked(False)
993
            elif type(cmd) is AreaOcrCommand.AreaOcrCommand:
994
                self.actionOCR.setChecked(False)
995
        finally:
996
            self.graphicsView.useDefaultCommand()
997
     
998
    '''
999
        @brief      restore to default command when user press Escape key
1000
        @author     humkyung 
1001
        @date       2018.08.09
1002
    '''
1003
    def keyPressEvent(self, event):
1004
        try:
1005
            if event.key() == Qt.Key_Escape:
1006
                checked = self.actionGroup.checkedAction()
1007
                if checked:
1008
                    checked.setChecked(False)
1009
                    self.graphicsView.useDefaultCommand()
1010

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

    
1029
        if not self.graphicsView.hasImage():
1030
            self.showImageSelectionMessageBox()
1031
            return
1032

    
1033
        try:
1034
            self.removedItems['LINE'] = []
1035
            self.removedItems['EQUIP'] = []
1036
            self.removedItems['INST'] = []
1037
            self.removedItems['NOTE'] = []
1038

    
1039
            appDocData = AppDocData.instance()
1040
            self.resultTreeWidget.setCurrentPID(appDocData.activeDrawing.name)
1041
            ## up to here
1042

    
1043
            self.onClearLog()
1044
            self.dlg = QRecognitionDialog(self, self.path)
1045
            self.dlg.exec_()
1046
            if self.dlg.isAccepted == True:
1047
                '''DO NOTHING'''
1048
        except Exception as ex:
1049
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1050
            self.addMessage.emit(MessageType.Error, message)
1051

    
1052
    '''
1053
        @brief      remove item from tree widget and then remove from scene
1054
        @date       2018.05.25
1055
        @author     Jeongwoo
1056
    '''
1057
    def itemRemoved(self, item):
1058
        try:
1059
            self.resultTreeWidget.itemRemoved(item)
1060

    
1061
            if type(item) is QEngineeringLineNoTextItem:
1062
                self.removedItems['LINE'].append(str(item.uid))
1063
            elif type(item) is QEngineeringInstrumentItem:
1064
                self.removedItems['INST'].append(str(item.uid))
1065
            elif type(item) is QEngineeringEquipmentItem:
1066
                self.removedItems['EQUIP'].append(str(item.uid))
1067
            elif type(item) is QEngineeringNoteItem:
1068
                self.removedItems['NOTE'].append(str(item.uid))
1069

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

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

    
1090
        if not self.graphicsView.hasImage():
1091
            self.showImageSelectionMessageBox()
1092
            return
1093

    
1094
        try:
1095
            self.dlgConnectAttr = QConnectAttrDialog(self, self.graphicsView)
1096
            self.dlgConnectAttr.exec_()
1097

    
1098
            self.resultTreeWidget.InitLineNoItems()
1099

    
1100
            # construct line no item
1101
            docData = AppDocData.instance()
1102
            for lineno in docData.lineNos:
1103
                item = self.resultTreeWidget.addTreeItem(self.resultTreeWidget.root, lineno)
1104
                connectedItems = lineno.getConnectedItems()
1105
                for connectedItem in connectedItems:
1106
                    if issubclass(type(connectedItem), SymbolSvgItem): 
1107
                        self.resultTreeWidget.addTreeItem(item, connectedItem)
1108
            # up to here
1109
        except Exception as ex:
1110
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1111
            self.addMessage.emit(MessageType.Error, message)
1112

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

    
1132
        # Update Scene
1133
        self.graphicsView.scene.update(self.graphicsView.sceneRect())
1134

    
1135
    '''
1136
        @brief      
1137
        @author     humkyung
1138
        @date       2018.08.23
1139
    '''
1140
    def drawDetectedLines(self, lineList, worker):
1141
        area = AppDocData.instance().getArea('Drawing')
1142

    
1143
        lines = []
1144
        for pts in lineList:
1145
            processLine = QEngineeringLineItem(vertices=[(area.x + param[0], area.y + param[1]) for param in pts])
1146
            processLine.area = 'Drawing'
1147
            self.graphicsView.scene.addItem(processLine)
1148
            lines.append(processLine)
1149

    
1150
            if processLine.length() > 100: # TODO: check critical length
1151
                processLine.addFlowArrow()
1152
        
1153
        # re-order process line's start,end according to flow mark
1154
        #worker.arrangeLinePosition(lines, symbols, listWidget)
1155
        # up to here
1156

    
1157
    '''
1158
        history    humkyung 2018.06.09 check length of original and connection point is 2 while parsing
1159
    '''
1160
    def drawDetectedSymbolItem(self, symbolList):
1161
        from GraphicsBoundingBoxItem import QGraphicsBoundingBoxItem
1162
        from SymbolSvgItem import SymbolSvgItem
1163
        import math
1164

    
1165
        try:
1166
            project = AppDocData.instance().getCurrentProject()
1167

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

    
1186
                svgFilePath = os.path.join(project.getSvgFilePath(), _type, name + '.svg')
1187
                if os.path.isfile(svgFilePath):
1188
                    svg = SymbolSvgItem.createItem(_type, svgFilePath)
1189
                    svg.buildItem(name, _type, angle, pt, size, origin, connPts, parentSymbol, childSymbol, hasInstrumentLabel)
1190
                    svg.reCalculationRotatedItem()
1191
                    svg.area = 'Drawing'
1192

    
1193
                    # set owner - 2018.07.20 added by humkyung                   
1194
                    matches = [searched for searched in searchedMap if searched[0] == symbol.owner]
1195
                    if len(matches) == 1:
1196
                        svg.owner = matches[0][1]
1197
                    searchedMap.append((symbol, svg))
1198
                    # up to here
1199

    
1200
                    svg.transfer.onRemoved.connect(self.itemRemoved)
1201
                    self.addSvgItemToScene(svg)
1202
                    
1203
                    # Equipment Item 경우 저장
1204
                    if type(svg) is QEngineeringEquipmentItem:
1205
                        svg.saveEquipData()
1206

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

    
1221
    '''
1222
        @history    2018.06.08  Jeongwoo    Add parameter on round method
1223
    '''
1224
    def drawDetectedTextItem(self, textInfoList):
1225
        from TextItemFactory import TextItemFactory
1226
        import math
1227

    
1228
        try:
1229
            appDocData = AppDocData.instance()
1230

    
1231
            # parse texts
1232
            for textInfo in textInfoList:
1233
                x = textInfo.getX()
1234
                y = textInfo.getY()
1235
                width = textInfo.getW()
1236
                height = textInfo.getH()
1237
                angle = round(math.radians(textInfo.getAngle()), 2)
1238
                text = textInfo.getText()
1239
                item = TextItemFactory.instance().createTextItem(text)
1240

    
1241
                if item is not None:
1242
                    item.loc = (x, y)
1243
                    item.size = (width, height)
1244
                    item.angle = angle
1245
                    item.setPlainText(text)
1246
                    item.area = 'Drawing'
1247
                    item.transfer.onRemoved.connect(self.itemRemoved)
1248
                    self.addTextItemToScene(item)
1249
                    appDocData.texts.append(item)
1250

    
1251
                    # Line No Text Item 경우 저장
1252
                    if type(item) is QEngineeringLineNoTextItem:
1253
                        item.saveLineData()
1254
                    #sung
1255
                    #if type(item) is QEngineeringNoteItem:
1256
                    #    item.saveNoteData()
1257
        except Exception as ex:
1258
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1259
            self.addMessage.emit(MessageType.Error, message)
1260

    
1261
    '''
1262
        @brief      draw detected texts except which in drawing area
1263
    '''
1264
    def drawDetectedOtherTextItem(self, otherTextInfoList):
1265
        from TextItemFactory import TextItemFactory
1266
        import math
1267

    
1268
        try:
1269
            appDocData = AppDocData.instance()
1270

    
1271
            # parse notes
1272
            for textInfoMap in otherTextInfoList:
1273
                if textInfoMap[0]=='Note':
1274
                    pass
1275

    
1276
                for textInfo in textInfoMap[1]:
1277
                    x = textInfo.getX()
1278
                    y = textInfo.getY()
1279
                    width = textInfo.getW()
1280
                    height = textInfo.getH()
1281
                    angle = round(math.radians(textInfo.getAngle()))
1282
                    text = textInfo.getText()
1283

    
1284
                    item = TextItemFactory.instance().createTextItem(text)
1285

    
1286
                    item.loc = (x, y)
1287
                    item.size = (width, height)
1288
                    item.angle = angle
1289
                    item.setPlainText(text)
1290
                    item.area = textInfoMap[0]
1291
                    self.addTextItemToScene(item)
1292
                    appDocData.texts.append(item)
1293

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

    
1298

    
1299
    '''
1300
        @brief  draw unknown items 
1301
        @author humkyung
1302
        @date   2018.06.12
1303
        @history    2018.06.14  Jeongwoo    Change method to add unknown item
1304
                    2018.06.18  Jeongwoo    Add connect on unknown item
1305
                                            Add [transfer] for using pyqtSignal
1306
    '''
1307
    def drawUnknownItems(self):
1308
        from QEngineeringFlowArrowItem import QEngineeringFlowArrowItem 
1309
        from EngineeringLineItem import QEngineeringLineItem
1310
        from EngineeringUnknownItem import QEngineeringUnknownItem
1311

    
1312
        try:
1313
            docData = AppDocData.instance()
1314
            project = docData.getCurrentProject()
1315
            windowSize = docData.getSlidingWindowSize()
1316
            thickness = int(windowSize[1])
1317

    
1318
            diffFilePath = os.path.join(project.getTempPath(), "DIFF_" + os.path.basename(self.path))
1319
            if os.path.isfile(diffFilePath):
1320
                imgDiff = cv2.threshold(cv2.cvtColor(cv2.imread(diffFilePath, 1), cv2.COLOR_BGR2GRAY), 127, 255, cv2.THRESH_BINARY)[1]
1321

    
1322
                ## remove line
1323
                lines = [item for item in self.graphicsView.scene.items() if (type(item) is QEngineeringLineItem)]
1324
                for line in lines:
1325
                    line.drawToImage(imgDiff, 255, thickness)
1326
                cv2.imwrite(diffFilePath, imgDiff)
1327
                ## up to here
1328

    
1329
                imgNot = np.ones(imgDiff.shape, np.uint8)
1330
                cv2.bitwise_not(imgDiff, imgNot)
1331
                imgNot = cv2.dilate(imgNot, np.ones((8,8), np.uint8))
1332

    
1333
                diffItems = []
1334

    
1335
                image, contours, hierarchy = cv2.findContours(imgNot, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
1336
                for contour in contours:
1337
                    [x, y, w, h] = cv2.boundingRect(contour)
1338

    
1339
                    # remove too small one
1340
                    if (w < 10 or h < 10): continue
1341

    
1342
                    '''
1343
                    rect = QRectF(x, y, w, h)
1344
                    items = [item for item in diffItems if item.boundingRect().contains(rect)]
1345
                    if len(items) > 0: continue
1346
                    
1347
                    items = [item for item in diffItems if rect.contains(item.boundingRect())]
1348
                    for item in items:
1349
                        diffItems.remove(item)
1350
                    '''
1351

    
1352
                    # create unknown item
1353
                    epsilon = cv2.arcLength(contour, True)*0.001
1354
                    approx = cv2.approxPolyDP(contour, epsilon, True)
1355
                    approx = [pt[0] for pt in approx]
1356
                    item = QEngineeringUnknownItem(approx)
1357
                    item.ara = 'Drawing'
1358
                    diffItems.append(item)
1359
                    # up to here
1360

    
1361
                for item in diffItems:
1362
                    item.transfer.onRemoved.connect(self.itemRemoved)
1363
                    self.addUnknownItemToScene(item)
1364

    
1365
                notFilePath = os.path.join(project.getTempPath(), "NOT_" + os.path.basename(self.path))
1366
                cv2.imwrite(notFilePath, imgNot)
1367
            else:
1368
                message = 'can\'t found {}'.format(diffFilePath)
1369
                self.addMessage.emit(MessageType.Normal, message)
1370
        except Exception as ex:
1371
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1372
            self.addMessage.emit(MessageType.Error, message)
1373

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

    
1401
        try:
1402
            symbols = []
1403

    
1404
            xml = parse(xmlPath)
1405
            root = xml.getroot()
1406
            
1407
            maxValue = 0
1408
            maxValue = maxValue + len(list(root.iter('SYMBOL')))
1409
            maxValue = maxValue + len(list(root.iter('ATTRIBUTE')))
1410
            maxValue = maxValue + len(list(root.iter('LINE_NO')))
1411
            maxValue = maxValue + len(list(root.iter('LINE')))
1412
            maxValue = maxValue + len(list(root.iter('UNKNOWN')))
1413
            self.progress.setMaximum(maxValue)
1414

    
1415
            for symbol in root.find('SYMBOLS').iter('SYMBOL'):
1416
                item = SymbolSvgItem.fromXml(symbol)
1417
                if item[0] is not None:
1418
                    item[0].transfer.onRemoved.connect(self.itemRemoved)
1419
                    symbols.append(item)
1420
                else:
1421
                    pt = [float(x) for x in symbol.find('LOCATION').text.split(',')]
1422
                    size = [float(x) for x in symbol.find('SIZE').text.split(',')]
1423
                    angle = float(symbol.find('ANGLE').text)
1424
                    item = QGraphicsBoundingBoxItem(pt[0], pt[1], size[0], size[1])
1425
                    item.isSymbol = True
1426
                    item.angle = angle
1427
                    item.setPen(QPen(Qt.red, 5, Qt.SolidLine))
1428
                    self.graphicsView.scene.addItem(item)
1429

    
1430
                self.progress.setValue(self.progress.value() + 1)
1431
                
1432
            QApplication.processEvents()
1433

    
1434
            # set symbol's owner
1435
            childItems = [item for item in symbols if item[1] is not None]
1436
            for item in childItems:
1437
                matches = [param for param in symbols if str(param[0].uid) == item[1]]
1438
                if len(matches) == 1:
1439
                    item[0].owner = matches[0][0]
1440
            # up to here
1441
           
1442
            for item in symbols:
1443
                self.addSvgItemToScene(item[0])
1444

    
1445
            # parse texts
1446
            for text in root.iter('ATTRIBUTE'):
1447
                item = QEngineeringTextItem.fromXml(text)
1448
                if item is not None:
1449
                    uid = text.find('UID')
1450
                    attributeValue = text.find('ATTRIBUTEVALUE')
1451
                    name = text.find('NAME').text
1452
                    item.transfer.onRemoved.connect(self.itemRemoved)
1453
                    self.addTextItemToScene(item)
1454

    
1455
                    if name == 'TEXT':
1456
                        if uid is not None and attributeValue is not None:
1457
                            item.uid = uid.text
1458
                            item.attribute = attributeValue.text
1459
                    elif name == 'NOTE':
1460
                        if uid is not None:
1461
                            item.uid = uid.text
1462

    
1463
                self.progress.setValue(self.progress.value() + 1)
1464
                
1465
            QApplication.processEvents()
1466

    
1467
            for line in root.find('LINEINFOS').iter('LINE'):
1468
                item = QEngineeringLineItem.fromXml(line)
1469
                item.transfer.onRemoved.connect(self.itemRemoved)
1470
                if item: self.addLineItemToScene(item)
1471

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

    
1476
            for unknown in root.iter('UNKNOWN'):
1477
                item = QEngineeringUnknownItem.fromXml(unknown)
1478
                item.transfer.onRemoved.connect(self.itemRemoved)
1479
                if item is not None:
1480
                    item.transfer.onRemoved.connect(self.itemRemoved)
1481
                    self.addUnknownItemToScene(item)
1482

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

    
1487
            for lineNo in root.iter('LINE_NO'):
1488
                location = lineNo.find('LOCATION').text if lineNo.find('LOCATION') is not None else '0,0'
1489
                x = float(location.split(',')[0])
1490
                y = float(location.split(',')[1])
1491
                width = float(lineNo.find('WIDTH').text) if lineNo.find('WIDTH') is not None else 0
1492
                height = float(lineNo.find('HEIGHT').text) if lineNo.find('HEIGHT') is not None else 0
1493
                angle = float(lineNo.find('ANGLE').text) if lineNo.find('ANGLE') is not None else 0
1494
                text = lineNo.find('TEXT').text
1495

    
1496
                item = TextItemFactory.instance().createTextItem(text)
1497
                if item is not None:
1498
                    item.loc = (x, y)
1499
                    item.size = (width, height)
1500
                    item.angle = angle
1501
                    item.setPlainText(text)
1502
                    item.transfer.onRemoved.connect(self.itemRemoved)
1503
                    self.addTextItemToScene(item)
1504

    
1505
                    # attr
1506
                    for userInputAttr in lineNo.iter('USERINPUTATTRIBUTE'):
1507
                        newAttr = UserInputAttribute(userInputAttr.find('TYPEUID').text, userInputAttr.find('TYPEVALUE').text)
1508
                        item.attrs.append(newAttr)
1509
                    for attr in lineNo.iter('ATTRIBUTE'):
1510
                        item.attrs[docData.getLinePropertiesByUID(attr.find('UID').text)[0]] = attr.find('VALUE').text
1511

    
1512
                connLine = lineNo.find('CONNLINE')
1513
                if connLine is not None:
1514
                    lineUID = connLine.text
1515
                    connLine = self.graphicsView.findItemByUid(lineUID)
1516
                    if connLine is not None:
1517
                        item.conns.append(connLine)
1518

    
1519
                run = lineNo.find('RUN')
1520
                if run is not None:
1521
                    lineRunItem = QEngineeringRunItem()
1522
                    for child in run:
1523
                        uidElement = child.find('UID')
1524
                        if uidElement is not None:
1525
                            uid = uidElement.text
1526
                            runItem = self.graphicsView.findItemByUid(uid)
1527
                            if runItem is not None:
1528
                                lineRunItem.items.append(runItem)
1529

    
1530
                    item.runs.append(lineRunItem)
1531
                    treeItem = self.resultTreeWidget.addTreeItem(self.resultTreeWidget.root, item)
1532
                    for connectedItem in lineRunItem.items:
1533
                        if issubclass(type(connectedItem), SymbolSvgItem): self.resultTreeWidget.addTreeItem(treeItem, connectedItem)
1534
                    docData.lineNos.append(item)
1535

    
1536
                self.progress.setValue(self.progress.value() + 1)
1537
            QApplication.processEvents()
1538

    
1539
            for trimLineNo in root.iter('TRIM_LINE_NO'):
1540
                item = QEngineeringTrimLineNoTextItem()
1541
                item.uid = trimLineNo.find('UID')
1542

    
1543
                run = trimLineNo.find('RUN')
1544
                if run is not None:
1545
                    lineRunItem = QEngineeringRunItem()
1546
                    for child in run:
1547
                        uidElement = child.find('UID')
1548
                        if uidElement is not None:
1549
                            uid = uidElement.text
1550
                            runItem = self.graphicsView.findItemByUid(uid)
1551
                            if runItem is not None:
1552
                                lineRunItem.items.append(runItem)
1553

    
1554
                    item.runs.append(lineRunItem)
1555
                    treeItem = self.resultTreeWidget.addTreeItem(self.resultTreeWidget.root, item)
1556
                    for connectedItem in lineRunItem.items:
1557
                        if issubclass(type(connectedItem), SymbolSvgItem): self.resultTreeWidget.addTreeItem(treeItem, connectedItem)
1558
                    docData.lineNos.append(item)
1559
            # up to here
1560

    
1561
            # set symbol's connectItem
1562
            from EngineeringConnectorItem import QEngineeringConnectorItem
1563
            connectors = [item for item in self.graphicsView.scene.items() if type(item) == QEngineeringConnectorItem and item.connectedItem is not None]
1564
            for connector in connectors:
1565
                # 처음에는 UID가 connectedItem에 String으로 들어가있기 때문에
1566
                connector.connectedItem = self.graphicsView.findItemByUid(connector.connectedItem)
1567

    
1568
            symbols = [item for item in self.graphicsView.scene.items() if issubclass(type(item), SymbolSvgItem) and len(item.attrs) > 0]
1569
            for symbol in symbols:
1570
                # 처음에는 attrs의 uid가 connectedItem에 String으로 들어가있기 때문에
1571
                for index in range(len(symbol.attrs)):
1572
                    if type(symbol.attrs[index]) is not UserInputAttribute and type(symbol.attrs[index]) is not tuple:
1573
                        symbol.attrs[index] = self.graphicsView.findItemByUid(symbol.attrs[index])
1574
                        
1575
            # Update Scene
1576
            self.graphicsView.scene.update(self.graphicsView.sceneRect())
1577

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

    
1582
    '''
1583
        @brief      Remove added item on same place and Add GraphicsItem
1584
        @author     Jeongwoo
1585
        @date       2018.05.25
1586
        @history    2018.05.29  Jeongwoo    Moved from QRecognitionDialog
1587
                    2018.06.18  Jeongwoo    Set Z-index
1588
    '''
1589
    def addSvgItemToScene(self, svgItem):
1590
        svgItem.addSvgItemToScene(self.graphicsView.scene)
1591
        
1592
    '''
1593
        @brief      Remove added item on same place and Add GraphicsItem
1594
        @author     Jeongwoo
1595
        @date       2018.05.25
1596
        @history    2018.05.29  Jeongwoo    Moved from QRecognitionDialog
1597
                    2018.06.05  Jeongwoo    Remove Size condition
1598
                    2018.06.18  Jeongwoo    Set Z-index
1599
    '''
1600
    def addTextItemToScene(self, textItem):
1601
        textItem.addTextItemToScene(self.graphicsView.scene)
1602
        
1603
    '''
1604
        @brief      Remove added item on same place and Add GraphicsItem
1605
        @author     Jeongwoo
1606
        @date       2018.05.29
1607
        @history    2018.06.18  Jeongwoo    Set Z-index
1608
    '''
1609
    def addLineItemToScene(self, lineItem):
1610
        lineItem.addLineItemToScene(self.graphicsView.scene)
1611

    
1612
    '''
1613
        @brief      Remove added item on same place and Add Unknown Item
1614
        @author     Jeongwoo
1615
        @date       2018.06.14
1616
        @history    2018.06.18  Jeongwoo    Set Z-index
1617
    '''
1618
    def addUnknownItemToScene(self, unknownItem):
1619
        try:
1620
            unknownItem.addUnknownItemToScene(self.graphicsView.scene)
1621
        except Exception as ex:
1622
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1623
            self.addMessage.emit(MessageType.Error, message)
1624

    
1625
    '''
1626
        @brief      generate output xml file
1627
        @author     humkyung
1628
        @date       2018.04.23
1629
        @history    2018.05.02  Jeongwoo    Show MessageBox when imageviewer doesn't have image
1630
    '''
1631
    def generateOutput(self):
1632
        import XmlGenerator as xg
1633

    
1634
        if not self.graphicsView.hasImage():
1635
            self.showImageSelectionMessageBox()
1636
            return
1637

    
1638
        try:
1639
            appDocData = AppDocData.instance()
1640

    
1641
            ## collect items
1642
            appDocData.lines.clear()
1643
            appDocData.lines = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringLineItem and item.owner is None]
1644

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

    
1648
            appDocData.equipments.clear()
1649
            for item in self.graphicsView.scene.items():
1650
                if type(item) is QEngineeringEquipmentItem:
1651
                    appDocData.equipments.append(item)
1652

    
1653
            appDocData.texts.clear()
1654
            appDocData.texts = [item for item in self.graphicsView.scene.items() if issubclass(type(item), QEngineeringTextItem) and type(item) is not QEngineeringLineNoTextItem]
1655
            ## up to here
1656

    
1657
            appDocData.imgOutput = np.ones((appDocData.imgHeight, appDocData.imgWidth), np.uint8)*255
1658
            xg.writeOutputXml(appDocData.imgName, appDocData.imgWidth, appDocData.imgHeight) # TODO: check
1659
            project = appDocData.getCurrentProject()
1660
            cv2.imwrite(os.path.join(project.getTempPath() , 'OUTPUT.png') , appDocData.imgOutput)
1661
        except Exception as ex:
1662
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1663
            self.addMessage.emit(MessageType.Error, message)
1664

    
1665
    '''
1666
        @brief      resetting attribute at secne
1667
        @author     kyoyho
1668
        @date       2018.08.21
1669
    '''
1670
    def checkAttribute(self):
1671
        try:
1672

    
1673
            docData = AppDocData.instance()
1674
            if not self.graphicsView.hasImage():
1675
                return
1676

    
1677
            # symbol 경우
1678
            items = [item for item in self.graphicsView.scene.items() if issubclass(type(item), SymbolSvgItem)]
1679
            for item in items:
1680
                attrs = item.attrs
1681
                
1682
                removeAttrList = []
1683
                for attr in attrs:
1684
                    if type(attr) is tuple:
1685
                        continue
1686

    
1687
                    if attr is None:
1688
                        removeAttrList.append(attr)
1689
                        continue
1690

    
1691
                    attrInfo = docData.getSymbolAttributeByUID(attr.attribute)
1692
                    if attrInfo is None:
1693
                        removeAttrList.append(attr)
1694
                    # 해당 attribute가 맞는지 확인
1695
                    else:
1696
                        attrType = attrInfo[2]
1697
                        _type = type(attr)
1698
                        if attrType == 'Symbol Item':
1699
                            if not issubclass(_type, SymbolSvgItem):
1700
                                removeAttrList.append(attr)
1701
                        elif attrType == 'Text Item':
1702
                            if _type is not QEngineeringTextItem:
1703
                                removeAttrList.append(attr)
1704
                        elif attrType == 'Int':
1705
                            if _type is not UserInputAttribute and self.isNumber(attr.text):
1706
                                removeAttrList.append(attr)
1707
                        elif attrType == 'String':
1708
                            if _type is not UserInputAttribute:
1709
                                removeAttrList.append(attr)
1710

    
1711
                for attr in removeAttrList:
1712
                    attrs.remove(attr)
1713

    
1714
            # Line No Text Item의 경우
1715
            items = [item for item in self.graphicsView.scene.items() if issubclass(type(item), QEngineeringLineNoTextItem)]
1716
            for item in items:
1717
                attrs = item.attrs
1718
                
1719
                removeAttrList = []
1720
                for attr in attrs:
1721
                    if type(attr) is UserInputAttribute:
1722
                        attrInfo = docData.getLinePropertiesByUID(attr.attribute)
1723
                        if attrInfo is None:
1724
                            removeAttrList.append(attr)
1725

    
1726
                for attr in removeAttrList:
1727
                    attrs.remove(attr)
1728

    
1729
        except Exception as ex:
1730
                message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
1731
                self.addMessage.emit(MessageType.Error, message)
1732
    '''
1733
        @brief      Check Number
1734
        @author     kyouho
1735
        @date       2018.08.20
1736
    '''
1737
    def isNumber(self, num):
1738
        p = re.compile('(^[0-9]+$)')
1739
        result = p.match(num)
1740

    
1741
        if result:
1742
            return True
1743
        else:
1744
            return False
1745

    
1746
    '''
1747
        @brief      find overlap Connector
1748
        @author     kyouho
1749
        @date       2018.08.28
1750
    '''
1751
    def findOverlapConnector(self, connectorItem):
1752
        from shapely.geometry import Point
1753
        from EngineeringConnectorItem import QEngineeringConnectorItem
1754
        itemList = []
1755
        
1756
        x = connectorItem.center()[0]
1757
        y = connectorItem.center()[1]
1758

    
1759
        connectors = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringConnectorItem and item != connectorItem]
1760
        for connector in connectors:
1761
            if Point(x, y).distance(Point(connector.center()[0], connector.center()[1])) < 5:
1762
                itemList.append(connector.parent)
1763

    
1764
        return itemList
1765

    
1766
            
1767
if __name__ == '__main__':
1768
    from ProjectDialog import Ui_Dialog
1769
    from App import App 
1770

    
1771
    app = App(sys.argv)
1772
    try:
1773
        dlg = Ui_Dialog()
1774
        selectedProject = dlg.showDialog()
1775
        if selectedProject is not None:
1776
            AppDocData.instance().setCurrentProject(selectedProject)
1777
            app._mainWnd = MainWindow.instance()
1778
            app._mainWnd.show()
1779
            sys.exit(app.exec_())
1780
    except Exception as ex:
1781
        print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
1782
    finally:
1783
        pass