프로젝트

일반

사용자정보

통계
| 개정판:

hytos / DTI_PID / DTI_PID / SymbolEditorDialog.py @ 62762fec

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

1
# coding: utf-8
2

    
3
from PyQt5 import QtCore, QtGui, QtWidgets
4
from PyQt5.QtCore import pyqtSlot, QRectF
5
from PyQt5.QtWidgets import *
6
from PyQt5.QtGui import *
7
from QtImageViewer import QtImageViewer
8
import os
9
import sqlite3
10
import sys
11
import symbol, SymbolBase
12
import potrace
13
import numpy as np
14
import cv2
15

    
16
import SymbolEditor_UI
17
from AppDocData import * 
18

    
19
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Commands')
20
import CropCommand, HandCommand, ZoomCommand, PenCommand, EraserCommand, AreaEraserCommand, OriginalPointCommand, ConnectionPointCommand, AreaZoomCommand, FitImageCommand, RemoveTextCommand, RotateImageCommand, FlipImageCommand
21

    
22

    
23
class QSymbolEditorDialog(QDialog):
24
    """ This is symbol editor dialog """
25

    
26
    FILE_NUMBER = 0
27

    
28
    '''
29
        @history    2018.05.02  Jeongwoo    Add variables (self.offsetX, self.offsetY, self.newSym)
30
                    2018.05.03  Jeongwoo    Remove parameter in SG_DbHelper()
31
                                            Remove self.dbHelper variable
32
                    2018.07.03  Yecheol     Rename File, Is Instrument Label added
33
    '''
34
    def __init__(self, parent, image, project, selectedSymbol = None):
35
        QDialog.__init__(self, parent)
36

    
37
        try:
38
            self.setWindowFlag(Qt.WindowMinMaxButtonsHint)
39
            self.image = image
40
            self.selectedSymbol = selectedSymbol
41
            self.project = project
42
            self.ui = SymbolEditor_UI.Ui_Dialog()
43
            self.ui.setupUi(self)
44
            self.ui.tableWidgetConnList.setColumnCount(3)
45
            self.ui.tableWidgetConnList.setHorizontalHeaderLabels([self.tr('위치'), self.tr('방향'), self.tr('심볼')])
46
            self.ui.tableWidgetConnList.horizontalHeaderItem(0).setSizeHint(QSize(25, 25))
47
            self.ui.tableWidgetConnList.itemPressed.connect(self.onConnPtPressed)
48

    
49
            self.setupImageViewer()
50
            self.setupTools()
51
            self.initForms()
52
            self.initContents()
53
            self.isAccepted = False
54
            self.offsetX = 0
55
            self.offsetY = 0
56
            self.newSym = None
57

    
58
            self.setWindowTitle(self.tr('심볼 편집기'))
59
            if self.selectedSymbol is None:
60
                self.ui.checkBoxChange.setEnabled(False)
61
                self.ui.pushButtonChange.setEnabled(False)
62
        except Exception as ex:
63
            from App import App
64

    
65
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
66
            App.mainWnd().addMessage.emit(MessageType.Error, message)
67

    
68
    def changeSymbolInfo(self):
69
        ''' 
70
            @brief      change base and additional symbol info for already created on drawing
71
            @author     euisung
72
            @date       2019.04.23
73
        '''
74
        from App import App
75
        from SymbolSvgItem import SymbolSvgItem
76

    
77
        mainScene = App.mainWnd().graphicsView
78
        if not mainScene.hasImage():
79
            return
80
        symbols = [item for item in mainScene.items() if issubclass(type(item), SymbolSvgItem) and item.name == self.selectedSymbol.getName()]
81
        newBase = self.ui.baseSymbolComboBox.currentText()
82
        newAddition = self.makeAdditionalSymbolListString()
83
        newType = self.ui.typeComboBox.currentText()
84
        for symbol in symbols:
85
            symbol.type = newType
86
            symbol.parentSymbol = newBase
87
            symbol.childSymbol = newAddition
88

    
89

    
90
    ''' 
91
        @brief      hilight pressed connector item
92
        @author     humkyung
93
        @date       2018.08.31
94
    '''
95
    def onConnPtPressed(self, item):
96
        data = item.data(Qt.UserRole)
97
        if data is not None:
98
            for row in range(self.ui.tableWidgetConnList.rowCount()):
99
                item = self.ui.tableWidgetConnList.item(row, 0)
100
                item.data(Qt.UserRole).hoverLeaveEvent(None)
101

    
102
            data.hoverEnterEvent(None)
103

    
104
    def convertQImageToMat(self, incomingImage):
105
        '''  Converts a QImage into an opencv MAT format  '''
106

    
107
        try:
108
            incomingImage = incomingImage.convertToFormat(QImage.Format_RGBA8888)
109

    
110
            width = incomingImage.width()
111
            height = incomingImage.height()
112

    
113
            ptr = incomingImage.bits()
114
            ptr.setsize(incomingImage.byteCount())
115
            arr = np.array(ptr).reshape(height, width, 4)  #  Copies the data
116
            return arr
117
        except Exception as ex:
118
            from App import App
119

    
120
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
121
            App.mainWnd().addMessage.emit(MessageType.Error, message)
122

    
123
    '''
124
        @brief  Set up QtImageViewer and QImage
125
        @history    2018.05.02  Jeongwoo    Connect imageviewer and QSymbolEditorDialog
126
    '''
127
    def setupImageViewer(self):
128
        from MainWindow import MainWindow
129

    
130
        x = self.ui.imageViewContainer.x()
131
        y = self.ui.imageViewContainer.y()
132
        width = self.ui.imageViewContainer.frameGeometry().width()
133
        height = self.ui.imageViewContainer.frameGeometry().height()
134
        self.ui.imageView = QtImageViewer(MainWindow.instance())
135
        self.ui.imageView.guidesEnabled = True
136
        self.ui.imageView.setGeometry(QtCore.QRect(0, y, height, height))
137
        self.ui.imageView.aspectRatioMode = QtCore.Qt.KeepAspectRatio
138
        self.ui.imageView.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
139
        self.ui.imageView.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
140
        self.ui.imageView.canZoom = True
141
        self.ui.imageView.canPan = True
142
        image = self.image.copy()
143
        self.imgW = image.width()
144
        self.imgH = image.height()
145
        image = image.scaled(self.imgW, self.imgH)
146
        self.ui.imageView.setImage(image)
147
        self.ui.imageViewerContainerLayout.addWidget(self.ui.imageView)
148
        self.ui.imageView.startPointChanged.connect(self.offsetChanged)
149

    
150
    '''
151
        @brief  Set up Hand, Crop, ETC Tools
152
        @history    2018.05.03  Jeongwoo    Add connection for removeTextButton
153
                    2018.06.11  Jeongwoo    Add connection for rotation and flip
154
    '''
155
    def setupTools(self):
156
        self.ui.handButton.clicked.connect(self.handToolClickEvent)
157
        self.ui.cropButton.clicked.connect(self.cropToolClickEvent)
158
        self.ui.penButton.clicked.connect(self.penToolClickEvent)
159
        self.ui.penWidthSpinBox.valueChanged.connect(self.penWidthChangedEvent)
160
        self.ui.eraserButton.clicked.connect(self.eraserToolClickEvent)
161
        self.ui.eraserSpinBox.valueChanged.connect(self.eraserWidthChangedEvent)
162
        self.ui.areaEraserButton.clicked.connect(self.areaEraserToolClickEvent)
163
        self.ui.fitImageButton.clicked.connect(self.fitImageToolClickEvent)
164
        self.ui.zoomButton.clicked.connect(self.zoomToolClickEvent)
165
        self.ui.areaZoomButton.clicked.connect(self.areaZoomToolClickEvent)
166
        self.ui.initZoomButton.clicked.connect(self.zoomInitToolClickEvent)
167
        self.ui.guidelineCheckbox.stateChanged.connect(self.guidelineStateChangedEvent)
168
        self.ui.removeTextButton.clicked.connect(self.removeTextClickEvent)
169
        self.ui.rotateLeftButton.clicked.connect(self.rotateLeftClickEvent)
170
        self.ui.rotateRightButton.clicked.connect(self.rotateRightClickEvent)
171
        self.ui.flipHorizontalButton.clicked.connect(self.flipHorizontalClickEvent)
172
        self.ui.flipVerticalButton.clicked.connect(self.flipVerticalClickEvent)
173
        self.ui.pushButtonDelConnPt.clicked.connect(self.onDeleteConnPt)
174
        self.ui.pushButtonChange.clicked.connect(self.changeSymbolInfo)
175

    
176
    '''
177
        @brief  Init Forms with type and default values
178
    '''
179
    def initForms(self):
180
        self.ui.thresholdLineEdit.setValidator(QRegExpValidator(QtCore.QRegExp("^[0-9]\d+$"))) # ([0-1]{1}[.])?[0-9]+
181
        self.ui.minMatchPointLineEdit.setValidator(QRegExpValidator(QtCore.QRegExp("^[0-9]\d+$")))
182
        self.initDefaultSymbolDirectionComboBoxItems()
183
        self.ui.addAdditionalSymbolButton.clicked.connect(self.addAdditionalSymbolEvent)
184
        self.ui.addOriginalPointButton.clicked.connect(self.addOriginalPoint)
185
        self.ui.addConnectionPointButton.clicked.connect(self.addConnectionPoint)
186
        self.initSymbolTypeComboBoxItems()
187
        self.initBaseSymbolComboBoxItems(None)
188
        self.initAdditionalSymbolComboBoxItems()
189
        self.ui.guidelineCheckbox.setChecked(True)
190

    
191
        ''' add symbol gradients to combobox '''
192
        configs = AppDocData.instance().getConfigs('Symbol Gradients')
193
        if configs is not None:
194
            for config in configs:
195
                self.ui.comboBoxNormalColor.addItem(config.key, config.value)
196
                self.ui.comboBoxHoverColor.addItem(config.key, config.value)
197

    
198
            nomalIndex = self.ui.comboBoxNormalColor.findText('Blue', Qt.MatchExactly)
199
            if nomalIndex is not -1:
200
                self.ui.comboBoxNormalColor.setCurrentIndex(nomalIndex)
201
            hoberIndex = self.ui.comboBoxNormalColor.findText('Red', Qt.MatchExactly)
202
            if hoberIndex is not -1:
203
                self.ui.comboBoxHoverColor.setCurrentIndex(hoberIndex)
204

    
205
    '''
206
        @brief      Init Symbol Type ComboBox Items
207
        @author     Jeongwoo
208
        @date       2018.04.06
209
    '''
210
    def initSymbolTypeComboBoxItems(self):
211
        for item in AppDocData.instance().getSymbolTypeComboBoxItems():
212
            self.ui.typeComboBox.addItem(item[2])
213
        self.ui.typeComboBox.currentTextChanged.connect(self.symbolTypeTextChagedEvent)
214

    
215
    def symbolTypeTextChagedEvent(self, value):
216
        self.initBaseSymbolComboBoxItems(value)
217
        
218
    '''
219
        @brief  Set data on forms, For modifying symbol
220
        @history    2018.05.02  Jeongwoo    When modifying symbol, Make immediateInsertCheckBox disable
221
                    2018.07.04  Yecheol     Remove is Symbol ID(idLineEdit)
222
    '''
223
    def initContents(self):
224
        try:
225
            if self.selectedSymbol is not None:
226
                self.ui.immediateInsertCheckBox.setDisabled(True)
227

    
228
                self.ui.nameLineEdit.setText(self.selectedSymbol.getName())
229
                self.ui.thresholdLineEdit.setText(str(int(self.selectedSymbol.getThreshold() * 100)))
230
                self.ui.minMatchPointLineEdit.setText(str(self.selectedSymbol.getMinMatchCount()))
231
                self.ui.rotationCountSpinBox.setValue(self.selectedSymbol.getRotationCount())
232
                self.ui.isContainChildCheckBox.setChecked(True if self.selectedSymbol.getIsContainChild() else False)
233
                self.ui.typeComboBox.setCurrentIndex(self.ui.typeComboBox.findText(self.selectedSymbol.getType()))
234
                self.ui.baseSymbolComboBox.setCurrentIndex(self.ui.baseSymbolComboBox.findText(self.selectedSymbol.getBaseSymbol()))
235
                self.ui.isExceptDetectCheckBox.setChecked(True if self.selectedSymbol.getIsExceptDetect() else False)
236
                self.ui.makeFlipCheckBox.setChecked(True if self.selectedSymbol.getDetectFlip() else False)
237
                
238
                self.ui.hasInstrumentLabelCheckBox.setChecked(True if self.selectedSymbol.getHasInstrumentLabel() else False)
239

    
240
                additionalSymbol = self.selectedSymbol.getAdditionalSymbol()
241
                if additionalSymbol is not None and len(additionalSymbol) > 0:
242
                    splitAdditionalSymbolList = additionalSymbol.split("/")
243
                    for symString in splitAdditionalSymbolList:
244
                        splitSymString = symString.split(",")
245
                        self.addAdditionalSymbol(splitSymString[0], splitSymString[1])
246

    
247
                originalPoint = self.selectedSymbol.getOriginalPoint()
248
                self.ui.originalPointLineEdit.setText(originalPoint)
249
                OriginalPointCommand.OriginalPointCommand.drawCircle(self.ui.imageView, originalPoint.split(",")[0], originalPoint.split(",")[1])
250
                self.ui.imageView.isOriginalPointSelected = True
251

    
252
                connectionPoint = self.selectedSymbol.getConnectionPoint()
253
                if connectionPoint is not None and len(connectionPoint) > 0:
254
                    splitConnectionPointList = connectionPoint.split("/")
255
                    symbol_indecies = [str(idx) for idx in range(self.ui.additionalSymbolListWidget.count()+1)]
256

    
257
                    self.ui.tableWidgetConnList.setRowCount(len(splitConnectionPointList))
258
                    row = 0
259
                    for conString in splitConnectionPointList: # conString : x,y
260
                        direction = 'AUTO'
261
                        symbol_idx = '0'
262
                        tokens = conString.split(',')
263
                        if len(tokens) == 4:
264
                            direction = tokens[0]
265
                            x = tokens[1]
266
                            y = tokens[2]
267
                            symbol_idx = tokens[3]
268
                        if len(tokens) == 3:
269
                            direction = tokens[0]
270
                            x = tokens[1]
271
                            y = tokens[2]
272
                        elif len(tokens) == 2:
273
                            x = tokens[0]
274
                            y = tokens[1]
275

    
276
                        conn = ConnectionPointCommand.ConnectionPointCommand.drawCircle(self.ui.imageView, x, y)
277

    
278
                        item = QTableWidgetItem('{},{}'.format(x, y))
279
                        item.setFlags(Qt.ItemIsEnabled)
280
                        item.setData(Qt.UserRole, conn)
281
                        self.ui.tableWidgetConnList.setItem(row, 0, item)
282

    
283
                        directionComboBox = QComboBox(self.ui.tableWidgetConnList)
284
                        directionComboBox.addItems(['AUTO', 'LEFT', 'RIGHT', 'UP', 'DOWN'])
285
                        directionComboBox.setCurrentText(direction)
286
                        self.ui.tableWidgetConnList.setCellWidget(row, 1, directionComboBox)
287

    
288
                        # add symbol index combobox - 2019.01.04 added by humkyung
289
                        symbol_idx_combobox = QComboBox(self.ui.tableWidgetConnList)
290
                        symbol_idx_combobox.addItems(symbol_indecies)
291
                        if symbol_idx in symbol_indecies:
292
                            symbol_idx_combobox.setCurrentText(symbol_idx)
293
                        else:
294
                            symbol_idx_combobox.setCurrentText('0')
295
                        self.ui.tableWidgetConnList.setCellWidget(row, 2, symbol_idx_combobox)
296
                        # up to here
297

    
298
                        row = row + 1
299

    
300
                        self.ui.tableWidgetConnList.resizeColumnsToContents()
301
            else:
302
                self.ui.minMatchPointLineEdit.setText('0')
303
        except Exception as ex:
304
            from App import App
305

    
306
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
307
            App.mainWnd().addMessage.emit(MessageType.Error, message)
308

    
309
    '''
310
        @brief  Init ComboBox Items For Direction of DB Field [additionalSymbol]
311
    '''
312
    def initDefaultSymbolDirectionComboBoxItems(self):
313
        for item in AppDocData.instance().getDefaultSymbolDirectionComboBoxItems():
314
            self.ui.defaultSymbolDirectionComboBox.addItem(item[0], item[1]) # 0 : text / 1 : data(integer)
315
        
316
    '''
317
        @brief  Init ComboBox Items For DB Field [baseSymbol]
318
    '''
319
    def initBaseSymbolComboBoxItems(self, type):
320
        self.ui.baseSymbolComboBox.clear()
321
        for item in AppDocData.instance().getBaseSymbolComboBoxItems(type):
322
            self.ui.baseSymbolComboBox.addItem(item)
323
            
324
    '''
325
        @brief  Init ComboBox Items For symbolName of DB Field [additionalSymbol]
326
    '''
327
    def initAdditionalSymbolComboBoxItems(self):
328
        for name in AppDocData.instance().getAdditionalSymbolComboBoxItems():
329
            self.ui.additionalSymbolComboBox.addItem(name)
330
    
331
    '''
332
        @brief  remove ConnectionPoint Circles (Using for loop)
333
    '''
334
    def removeConnectionPointCircles(self, circlePointList):
335
        for circlePoint in circlePointList:
336
            self.removeConnectionPointCircle(circlePoint)
337
            
338
    '''
339
        @brief      remove each ConnectionPoint Circle
340
        @history    2018.06.12  Jeongwoo    Add conditions for selecting ellipse item
341
    '''
342
    def removeConnectionPointCircle(self, circlePoint):
343
        from EngineeringConnectorItem import QEngineeringConnectorItem
344

    
345
        imageWidth = self.ui.imageView.image().width()
346
        imageHeight = self.ui.imageView.image().height()
347
        items = [item for item in self.ui.imageView.scene.items(QRectF(float(circlePoint.x())-0.5, float(circlePoint.y())-0.5, 1, 1)) \
348
            if type(item) is QEngineeringConnectorItem]
349
        for item in items:
350
            self.ui.imageView.scene.removeItem(item)
351
        
352
    '''^
353
        @brief  Display this QDialog
354
        @history    2018.05.02  Jeongwoo    Change return value (Single variable → Tuple)
355
    '''
356
    def showDialog(self):
357
        self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowContextHelpButtonHint)
358
        self.exec_()
359
        return (self.isAccepted, self.ui.immediateInsertCheckBox.isChecked(), self.offsetX, self.offsetY, self.newSym)
360
    
361
    '''
362
        @brief  Using input [Name], make file name
363
                If the [Name] exists, add number like [FILE_NAME(1), FILE_NAME(2), ...]
364
                Recursive function
365
        @history    2018.05.02  Jeongwoo    Change isExistFileName's parameter (Dir → newName)
366
                    2018.05.03  Jeongwoo    Change self.dbHelper to AppDocData
367
    '''
368
    def makeFileName(self, type, originName, newName):
369
        imageFolderDir = self.project.getImageFilePath()
370
        imageDir = os.path.join(imageFolderDir, type, newName + '.png')
371
        svgFolderDir = self.project.getSvgFilePath()
372
        svgDir = os.path.join(svgFolderDir, type, newName + '.svg')
373
        if (os.path.exists(imageDir)) or (AppDocData.instance().isExistFileName(newName) or (os.path.exists(svgDir))):
374
            self.FILE_NUMBER = self.FILE_NUMBER + 1
375
            imgName = originName + "({})".format(self.FILE_NUMBER)
376
            return self.makeFileName(type, originName, imgName)
377
        else:
378
            return newName
379
        
380
    '''
381
        @brief  Make symbol object for saving on DB
382
        @history    2018.05.02  Jeongwoo    newSym object changed self.newSym
383
    '''
384
    def makeSymbolData(self, width, height):
385
        uid = -1
386
        if self.selectedSymbol is not None:
387
            uid = self.selectedSymbol.getUid()
388
        #symId = self.ui.idLineEdit.text()
389
        name = self.ui.nameLineEdit.text()
390
        type = self.ui.typeComboBox.currentText() #Empty
391
        self.FILE_NUMBER = 0
392
        lastName = ""
393
        if self.selectedSymbol is not None:
394
            lastName = self.selectedSymbol.getName()
395
        fileName = ""
396
        if name == lastName:
397
            fileName = name
398
        else:
399
            fileName = self.makeFileName(type, name, name)
400
        threshold = self.ui.thresholdLineEdit.text()
401
        minMatchPoint = self.ui.minMatchPointLineEdit.text()
402
        rotationCount = self.ui.rotationCountSpinBox.value()
403
        ocrOption = 0
404
        isContainChild = 1 if self.ui.isContainChildCheckBox.isChecked() else 0
405
        originalPoint = self.ui.originalPointLineEdit.text()
406
        connectionPoint = self.makeConnectionPointListString()
407
        baseSymbol = self.ui.baseSymbolComboBox.currentText()
408
        additionalSymbol = self.makeAdditionalSymbolListString()
409
        isExceptDetect = 1 if self.ui.isExceptDetectCheckBox.isChecked() else 0
410

    
411
        hasInstrumentLabel = 1 if self.ui.hasInstrumentLabelCheckBox.isChecked() else 0
412

    
413
        detectFlip = 1 if self.ui.makeFlipCheckBox.isChecked() else 0
414

    
415
        convertedThreshold = int(threshold) / 100.0
416

    
417
        imageWidth = width
418
        iamgeHeight = height
419

    
420
        self.newSym = symbol.SymbolBase(fileName, type, convertedThreshold, int(minMatchPoint), True, 
421
                        rotationCount, ocrOption, isContainChild, originalPoint, connectionPoint, baseSymbol, additionalSymbol, isExceptDetect, hasInstrumentLabel, uid, imageWidth, iamgeHeight, detectFlip=detectFlip)
422

    
423
        return self.newSym
424
    
425
    '''
426
        @brief  Make AdditionalSymbol String
427
                [AdditionalSymbolString = DIRECTION,SYMBOL_NAME/DIRECTION,SYMBOL_NAME/...]
428
    '''
429
    def makeAdditionalSymbolListString(self):
430
        ret = ""
431
        listItems = []
432
        for index in range(self.ui.additionalSymbolListWidget.count()):
433
            listItems.append(self.ui.additionalSymbolListWidget.item(index))
434
        if listItems is not None:
435
            for index in range(len(listItems)):
436
                item = listItems[index]
437
                text = item.text()
438
                if index != 0:
439
                    ret = ret + "/"
440
                ret = ret + text
441

    
442
        return ret
443
    
444
    '''
445
        @brief  Make ConnectionPoint String
446
                [ConnectionPointString = U,x1,y1/D,x2,y2/...]
447
    '''
448
    def makeConnectionPointListString(self):
449
        res = ""
450

    
451
        connPtStringList = []
452
        for row in range(self.ui.tableWidgetConnList.rowCount()):
453
            direction = self.ui.tableWidgetConnList.cellWidget(row, 1).currentText()
454
            symbol_idx = self.ui.tableWidgetConnList.cellWidget(row, 2).currentText()
455

    
456
            connPtString = '{},{},{}'.format(direction, self.ui.tableWidgetConnList.item(row, 0).text(), symbol_idx)
457
            connPtStringList.append(connPtString)
458

    
459
        res = '/'.join(connPtStringList)
460

    
461
        return res
462
    
463
    '''
464
        @brief  Called when Save Button Clicked
465
                Validation Check → Make Symbol Data → Insert Symbol Data into DB → Save png and svg files
466
        @history    2018.05.03  Jeongwoo    Change parameters on method 'deleteImageAndSvg'
467
                                            Change self.dbHelper to AppDocData
468
    '''
469
    def accept(self):
470
        isValid, exceptionMsg = self.isValidSymbolInfo()
471
        if isValid:
472
            if self.selectedSymbol is None:
473
                isSuccess, fileType, fileName, imagePath = AppDocData.instance().insertSymbol(self.makeSymbolData(self.ui.imageView.image().width(), self.ui.imageView.image().height()))
474
            else:
475
                isSuccess, fileType, fileName, imagePath = AppDocData.instance().updateSymbol(self.makeSymbolData(self.ui.imageView.image().width(), self.ui.imageView.image().height()))
476

    
477
            if isSuccess:
478
                try:
479
                    image = self.ui.imageView.image()
480
                    #imageFlip = self.ui.imageView.image().mirrored(horizontal = True, vertical = False)
481
                    if image is not None:
482
                        if self.selectedSymbol is not None:
483
                            self.deleteImageAndSvg(self.selectedSymbol.getImageFileFullPath(), self.selectedSymbol.getSvgFileFullPath())
484
                        imageLocation = os.path.join(self.project.getImageFilePath(), fileType)
485
                        if not os.path.exists(imageLocation):
486
                            os.makedirs(imageLocation) 
487
                            
488
                        image.save(imagePath, 'PNG')
489
                        #if self.ui.makeFlipCheckBox.isChecked():
490
                        #    imageFlip.save(imagePath + '_Flip', 'PNG')
491

    
492
                        svgLocation = os.path.join(self.project.getSvgFilePath(), fileType)
493
                        if not os.path.exists(svgLocation):
494
                            os.makedirs(svgLocation)
495

    
496
                        normal_color = self.ui.comboBoxNormalColor.itemData(self.ui.comboBoxNormalColor.currentIndex())
497
                        hover_color = self.ui.comboBoxHoverColor.itemData(self.ui.comboBoxHoverColor.currentIndex())
498
                        potrace.convertImageToSvg(imagePath, os.path.join(svgLocation, fileName + ".svg"), normalColor=normal_color, hoverColor=hover_color)
499
                        #if self.ui.makeFlipCheckBox.isChecked():
500
                        #    potrace.convertImageToSvg(imagePath + '_Flip', os.path.join(svgLocation + "/" + fileName + "_Flip.svg"), normalColor=normal_color, hoverColor=hover_color)
501
                        self.isAccepted = True
502
                        if self.ui.checkBoxChange.isChecked():
503
                            self.changeSymbolInfo()
504
                        QDialog.accept(self)
505
                except:
506
                    if self.selectedSymbol is None:
507
                        self.resetInsertSymbol(imagePath, fileName)
508
                    else:
509
                        self.resetUpdateSymbol(imagePath, fileName) ### update roll back 으로 변경해야함
510
                    self.isAccepted = False
511
                    QMessageBox.about(self.ui.buttonBox, "알림", "심볼 저장 과정 중 문제가 발생했습니다.")
512
            else:
513
                QMessageBox.about(self.ui.buttonBox, "알림", "심볼 저장 과정 중 문제가 발생했습니다.")
514
        else:
515
            print("invalid symbol info")
516
            QMessageBox.about(self.ui.buttonBox, "알림", exceptionMsg)
517
            
518
    '''
519
        @brief  Called When Close Button Clicked
520
    '''
521
    def reject(self):
522
        self.isAccepted = False
523
        QDialog.reject(self)
524

    
525
    '''
526
        @history    2018.05.03  Jeongwoo    Change Parameters (imagePath, type, name → imagePath, svgPath)
527
    '''
528
    def deleteImageAndSvg(self, imagePath, svgPath):
529
        if os.path.exists(imagePath):
530
            os.remove(imagePath)
531

    
532
        if os.path.exists(svgPath):
533
            os.remove(svgPath)
534
        
535
    '''
536
        @brief  Called When error occured while saving png and svg files
537
                Delete png, svg files and record from DB
538
        @history    2018.05.03  Jeongwoo    Change Parameters and fileName variable
539
    '''
540
    def resetInsertSymbol(self, imagePath, svgPath):
541
        self.deleteImageAndSvg(imagePath, svgPath)
542

    
543
        fileName = os.path.basename(imagePath.replace('.png', ''))
544
        AppDocData.instance().deleteSymbol(fileName)
545

    
546
    '''
547
        @history    2018.05.03  Jeongwoo    Change Parameters
548
                                            Change self.dbHelper to AppDocData
549
    '''
550
    def resetUpdateSymbol(self, imagePath, svgPath):
551
        self.deleteImageAndSvg(imagePath, svgPath)
552

    
553
        AppDocData.instance().updateSymbol(self.selectedSymbol)
554

    
555
    '''
556
        @history    2018.06.12  Jeongwoo    coords type changed (int → float)
557
    '''
558
    def keyPressEvent(self, event):
559
        if event.key() == QtCore.Qt.Key_Delete:
560
            if self.ui.tableWidgetConnList.hasFocus():
561
                model = self.ui.tableWidgetConnList.model()
562

    
563
                item = self.ui.tableWidgetConnList.currentItem()
564
                if item is not None:
565
                    item = self.ui.tableWidgetConnList.item(item.row(), 0)
566
                    data = item.data(Qt.UserRole)
567
                    if data is not None:
568
                        self.ui.imageView.scene.removeItem(data)
569
                        model.removeRow(item.row())
570
            elif self.ui.additionalSymbolListWidget.hasFocus():
571
                selectedItems = self.ui.additionalSymbolListWidget.selectedItems()
572
                if selectedItems is not None:
573
                    for item in selectedItems:
574
                        self.ui.additionalSymbolListWidget.takeItem(self.ui.additionalSymbolListWidget.row(item))
575
                        
576
    '''
577
        @brief  Hand Tool Button Clicked
578
    '''
579
    def handToolClickEvent(self, event):
580
        self.ui.imageView.command = HandCommand.HandCommand(self.ui.imageView)
581
        
582
    '''
583
        @brief  Crop Tool Button Clicked
584
        @history    2018.06.11  Jeongwoo    init original/connection points and guide line refresh
585
    '''
586
    def cropToolClickEvent(self, event):
587
        self.initOriginalAndConnectionPoint()
588
        self.ui.imageView.command = CropCommand.CropCommand(self.ui.imageView)
589
        self.guidelineStateChangedEvent(None)
590
                         
591
    '''
592
        @brief  Zoom Init Tool Button Clicked
593
    '''
594
    def zoomInitToolClickEvent(self, event):
595
        self.ui.imageView.command = None
596
        self.ui.imageView.zoomImageInit()
597

    
598
    '''
599
        @brief  Area Zoom Tool Button Clicked
600
    '''
601
    def areaZoomToolClickEvent(self, event):
602
        self.ui.imageView.command = AreaZoomCommand.AreaZoomCommand(self.ui.imageView)
603
                         
604
    '''
605
        @brief  Zoom Tool Button Clicked
606
    '''
607
    def zoomToolClickEvent(self, event):
608
        self.ui.imageView.command = ZoomCommand.ZoomCommand(self.ui.imageView)
609
                         
610
    '''
611
        @brief  Pen Tool Button Clicked
612
    '''
613
    def penToolClickEvent(self, event):
614
        width = self.ui.toolWidget.findChild(QSpinBox, 'penWidthSpinBox').value()
615
        self.ui.imageView.command = PenCommand.PenCommand(self.ui.imageView)
616
        self.ui.imageView.command.width = width
617
                         
618
    '''
619
        @brief  Pen Width Value Changed
620
    '''
621
    def penWidthChangedEvent(self, value):
622
        if self.ui.imageView.command is not None and type(self.ui.imageView.command) is PenCommand.PenCommand:
623
            self.ui.imageView.command.width = value
624
                 
625
    '''
626
        @brief  Eraser Tool Button Clicked
627
    '''
628
    def eraserToolClickEvent(self, event):
629
        width = self.ui.toolWidget.findChild(QSpinBox, 'eraserSpinBox').value()
630
        self.ui.imageView.command = EraserCommand.EraserCommand(self.ui.imageView)
631
        self.ui.imageView.command.width = width
632
                         
633
    '''
634
        @brief  Eraser Width Value Changed
635
    '''
636
    def eraserWidthChangedEvent(self, value):
637
        if self.ui.imageView.command is not None and type(self.ui.imageView.command) is EraserCommand.EraserCommand:
638
            self.ui.imageView.command.width = value
639
                             
640
    '''
641
        @brief  Area Eraser Tool Button Clicked
642
    '''
643
    def areaEraserToolClickEvent(self, event):
644
        self.ui.imageView.command = AreaEraserCommand.AreaEraserCommand(self.ui.imageView)
645
                             
646
    '''
647
        @brief      Fit Image Tool Button Clicked
648
        @history    2018.05.02  Jeongwoo    Method name changed(getAdjust → getOffset)
649
                                            Emit offsets to startPointChanged
650
                    2018.06.11  Jeongwoo    init original/connection points
651
    '''
652
    def fitImageToolClickEvent(self, event):
653
        self.initOriginalAndConnectionPoint()
654
        self.ui.imageView.command = FitImageCommand.FitImageCommand(self.ui.imageView)
655
        adjustX, adjustY = self.ui.imageView.command.getOffset()
656
        self.ui.imageView.startPointChanged.emit(adjustX, adjustY)
657
                         
658
    '''
659
        @brief  Guideline Check State Changed
660
    '''
661
    def guidelineStateChangedEvent(self, value):
662
        if self.ui.guidelineCheckbox.isChecked():
663
            self.ui.imageView.showGuideline(None, True)
664
        else:
665
            self.ui.imageView.showGuideline(None, False)
666
                             
667
    '''
668
        @brief  Add AdditionalSymbol String on ListWidget Listener
669
    '''
670
    def addAdditionalSymbolEvent(self, event):
671
        additionalSymbolIndex = self.ui.additionalSymbolComboBox.currentIndex()
672
        if additionalSymbolIndex != 0:
673
            parent_index = self.ui.spinBoxParent.value()
674
            direction = self.ui.defaultSymbolDirectionComboBox.currentText()
675
            symbolName = self.ui.additionalSymbolComboBox.currentText()
676
            self.addAdditionalSymbol(parent_index, direction, symbolName)
677
                    
678
    '''
679
        @brief  Add AdditionalSymbol String on ListWidget
680
    '''
681
    def addAdditionalSymbol(self, parent_index, direction, symbolName):
682
        text = "{},{},{}".format(parent_index, direction, symbolName)
683

    
684
        if self.isAlreadyAdded(text):
685
            QMessageBox.about(self.ui.buttonBox, self.tr("알림"), self.tr("이미 추가된 아이템입니다."))
686
        else:
687
            self.ui.additionalSymbolListWidget.addItem(text)
688
                                 
689
    '''
690
        @brief  Check the text is already added
691
    '''
692
    def isAlreadyAdded(self, text):
693
        for index in range(self.ui.additionalSymbolListWidget.count()):
694
            item = self.ui.additionalSymbolListWidget.item(index)
695
            if item.text() == text:
696
                return True
697
        return False
698
                     
699
    '''
700
        @brief      update scene when command is success
701
        @author     humkyung
702
        @date       2018.08.28
703
    '''
704
    def onCommandSuccess(self, pt):
705
        from EngineeringConnectorItem import QEngineeringConnectorItem
706

    
707
        self.ui.imageView.scene.invalidate()
708
        if type(pt) is QEngineeringConnectorItem:
709
            rows = self.ui.tableWidgetConnList.rowCount()
710
            self.ui.tableWidgetConnList.setRowCount(rows + 1)
711

    
712
            item = QTableWidgetItem('{},{}'.format(pt.center()[0], pt.center()[1]))
713
            item.setData(Qt.UserRole, pt)
714
            item.setFlags(Qt.ItemIsEnabled)
715
            self.ui.tableWidgetConnList.setItem(rows, 0, item)
716

    
717
            directionComboBox = QComboBox(self.ui.tableWidgetConnList)
718
            directionComboBox.addItems(['AUTO', 'LEFT', 'RIGHT', 'UP', 'DOWN'])
719
            directionComboBox.setCurrentText('AUTO')
720
            self.ui.tableWidgetConnList.setCellWidget(rows, 1, directionComboBox)
721

    
722
            # add symbol index combobox - 2019.01.07 added by humkyung
723
            symbol_indecies = [str(idx) for idx in range(self.ui.additionalSymbolListWidget.count()+1)]
724
            symbol_idx_combobox = QComboBox(self.ui.tableWidgetConnList)
725
            symbol_idx_combobox.addItems(symbol_indecies)
726
            symbol_idx_combobox.setCurrentText('0')
727
            self.ui.tableWidgetConnList.setCellWidget(rows, 2, symbol_idx_combobox)
728
            # up to here
729

    
730
    '''
731
        @brief  Original Point Tool Button Clicked
732
    '''
733
    def addOriginalPoint(self, event):
734
        cmd = OriginalPointCommand.OriginalPointCommand(self.ui.imageView, self.ui.originalPointLineEdit)
735
        cmd.onSuccess.connect(self.onCommandSuccess)
736
        self.ui.imageView.command = cmd
737
            
738
    '''
739
        @brief  Connection Point Tool Button Clicked
740
    '''
741
    def addConnectionPoint(self, event):
742
        cmd = ConnectionPointCommand.ConnectionPointCommand(self.ui.imageView, self.ui.connectionPointLineEdit)
743
        cmd.onSuccess.connect(self.onCommandSuccess)
744
        self.ui.imageView.command = cmd
745

    
746
    '''
747
        @brief      delete current item from tableWidgetConnList
748
        @author     humkyung
749
        @date       2018.08.31
750
    '''
751
    def onDeleteConnPt(self):
752
        try:
753
            model = self.ui.tableWidgetConnList.model()
754

    
755
            item = self.ui.tableWidgetConnList.currentItem()
756
            if item is not None:
757
                item = self.ui.tableWidgetConnList.item(item.row(), 0)
758
                data = item.data(Qt.UserRole)
759
                if data is not None:
760
                    self.ui.imageView.scene.removeItem(data)
761
                    model.removeRow(item.row())
762
        except Exception as ex:
763
            from App import App
764
            from AppDocData import MessageType
765

    
766
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
767
            App.mainWnd().addMessage.emit(MessageType.Error, message)
768

    
769
    '''
770
        @brief  Remove Text Tool Button Clicked
771
        @author Jeongwoo
772
        @date   2018.05.03
773
        @history    2018.05.09  Jeongwoo    Remove comment and activate RemoveTextCommand
774
    '''
775
    def removeTextClickEvent(self, event):
776
        self.ui.imageView.command = RemoveTextCommand.RemoveTextCommand(self.ui.imageView)
777

    
778
    '''
779
        @brief      Init Original/Connection points
780
        @author     Jeongwoo
781
        @date       2018.06.11
782
    '''
783
    def initOriginalAndConnectionPoint(self):
784
        self.ui.originalPointLineEdit.setText('')
785
        self.ui.tableWidgetConnList.setRowCount(0)
786
        #self.ui.connectionPointList.clear()
787
        
788
    '''
789
        @brief      Rotate image clockwise
790
        @author     Jeongwoo
791
        @date       2018.06.11
792
    '''
793
    def rotateLeftClickEvent(self, event):
794
        self.initOriginalAndConnectionPoint()
795
        self.ui.imageView.command = RotateImageCommand.RotateImageCommand(self.ui.imageView, True)
796
        self.guidelineStateChangedEvent(None)
797
        
798
    '''
799
        @brief      Rotate image counter-clockwise
800
        @author     Jeongwoo
801
        @date       2018.06.11
802
    '''
803
    def rotateRightClickEvent(self, event):
804
        self.initOriginalAndConnectionPoint()
805
        self.ui.imageView.command = RotateImageCommand.RotateImageCommand(self.ui.imageView)
806
        self.guidelineStateChangedEvent(None)
807
        
808
    '''
809
        @brief      Flip image left and right
810
        @author     Jeongwoo
811
        @date       2018.06.11
812
    '''
813
    def flipHorizontalClickEvent(self, event):
814
        self.initOriginalAndConnectionPoint()
815
        self.ui.imageView.command = FlipImageCommand.FlipImageCommand(self.ui.imageView, horizontal = True, vertical = False)
816
        self.guidelineStateChangedEvent(None)
817
        
818
    '''
819
        @brief      Flip image up and down
820
        @author     Jeongwoo
821
        @date       2018.06.11
822
    '''
823
    def flipVerticalClickEvent(self, event):
824
        self.initOriginalAndConnectionPoint()
825
        self.ui.imageView.command = FlipImageCommand.FlipImageCommand(self.ui.imageView, horizontal = False, vertical = True)
826
        self.guidelineStateChangedEvent(None)
827

    
828
    def adjustOriginalPoint(self, adjustX, adjustY):
829
        originalPoint = self.ui.originalPointLineEdit.text()
830
        if originalPoint and self.ui.imageView.isOriginalPointSelected:
831
            x = float(originalPoint.split(",")[0])
832
            y = float(originalPoint.split(",")[1])
833
            OriginalPointCommand.OriginalPointCommand.removeCircle(self.ui.imageView, x, y)
834
            x = x - adjustX
835
            y = y - adjustY
836
            self.ui.originalPointLineEdit.setText(str(x)+","+str(y))
837
            OriginalPointCommand.OriginalPointCommand.drawCircle(self.ui.imageView, x, y)
838

    
839
    def adjustConnectionPoint(self, adjustX, adjustY):
840
        itemCount = self.ui.connectionPointList.count()
841
        for index in range(itemCount):
842
            item = self.ui.connectionPointList.item(index)
843
            text = item.text()
844
            x = float(text.split(",")[0])
845
            y = float(text.split(",")[1])
846
            self.removeConnectionPointCircle(QtCore.QPointF(x, y))
847
            x = x - adjustX
848
            y = y - adjustY
849
            item.setText(str(x)+","+str(y))
850
            ConnectionPointCommand.ConnectionPointCommand.drawCircle(self.ui.imageView, x, y)
851
                         
852
    '''
853
        @brief  Validation Check
854
        @return (isValid, errorMsg)
855
        @history    2018.05.03  Jeongwoo    Change self.dbHelper to AppDocData
856
    '''
857
    def isValidSymbolInfo(self):
858
        EXCEPTION_MSG_FORMAT = "{} 입력을 확인해주세요."
859
        EXCEPTION_MSG_DUPLICATED_FORMAT = "이미 저장된 {} 값입니다."
860
        infoTitle = ""
861

    
862
        if not self.ui.nameLineEdit.text():
863
            infoTitle = self.ui.nameLabel.text()
864
            return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
865

    
866
        thresholdText = self.ui.thresholdLineEdit.text()
867
        threshold = float(thresholdText) if thresholdText else -1
868
        if not(threshold >= 0 and threshold <= 100):
869
            infoTitle = self.ui.thresholdLabel.text()
870
            return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
871
            
872
        minMatchPointText = self.ui.minMatchPointLineEdit.text()
873
        minMatchPoint = float(minMatchPointText) if minMatchPointText else -1
874
        if not(minMatchPoint >= 0):
875
            infoTitle = self.ui.minMatchPointLabel.text()
876
            return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
877

    
878
        if self.ui.typeComboBox.currentIndex() == 0:
879
            infoTitle = self.ui.typeLabel.text()
880
            return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
881

    
882
        if self.ui.baseSymbolComboBox.currentIndex() == 0: #default value(None) index
883
            infoTitle = self.ui.baseSymbolLabel.text()
884
            return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
885

    
886
        #Additional Symbol is Nullable
887

    
888
        if not self.ui.originalPointLineEdit.text() or self.ui.imageView.isOriginalPointSelected == False:
889
            infoTitle = self.ui.originalPointLabel.text()
890
            return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
891

    
892
        #if not (self.ui.tableWidgetConnList.rowCount() > 0):
893
        #    infoTitle = self.ui.connectionPointLabel.text()
894
        #    return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
895
            
896
        return True, None
897

    
898
    '''
899
        @brief  Slot for change offsets
900
        @author Jeongwoo
901
        @date   2018.05.02
902
        @history    2018.06.11  Jeongwoo    Add refresh guideline
903
    '''
904
    @pyqtSlot(float, float)
905
    def offsetChanged(self, oX, oY):
906
        #print('offsetX : ' + str(self.offsetX) + '->' + str(self.offsetX+oX))
907
        #print('offsetY : ' + str(self.offsetY) + '->' + str(self.offsetY+oY))
908
        self.offsetX = self.offsetX + oX
909
        self.offsetY = self.offsetY + oY
910
        self.guidelineStateChangedEvent(None)
클립보드 이미지 추가 (최대 크기: 500 MB)