프로젝트

일반

사용자정보

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

hytos / DTI_PID / DTI_PID / QSymbolEditorDialog.py @ 35d6d96c

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

1
# coding: utf-8
2
from PyQt5 import QtCore, QtGui, QtWidgets
3
from PyQt5.QtWidgets import *
4
from PyQt5.QtGui import *
5
from QtImageViewer import QtImageViewer
6
import os
7
import sqlite3
8
import sys
9
import SG_DbHelper
10
import symbol, SymbolBase
11
import potrace
12

    
13
import UI_SymbolEditor
14
from AppDocData import AppDocData
15

    
16

    
17
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Commands')
18
import CropCommand, HandCommand, ZoomCommand, PenCommand, EraserCommand, AreaEraserCommand, OriginalPointCommand, ConnectionPointCommand
19

    
20

    
21
class QSymbolEditorDialog(QDialog):
22
    FILE_NUMBER = 0
23

    
24
    def __init__(self, parent, image, project):
25
        QDialog.__init__(self, parent)
26

    
27
        self.image = image
28
        self.project = project
29
        self.ui = UI_SymbolEditor.Ui_Dialog()
30
        self.ui.setupUi(self)
31
        self.setupImageViewer()
32
        self.setupTools()
33
        self.initForms()
34
        self.initContents()
35
        self.isAccepted = False
36
        self.dbHelper = SG_DbHelper.SG_DbHelper(self.project.getPath())
37

    
38
    def setupImageViewer(self):
39
        x = self.ui.imageViewContainer.x()
40
        y = self.ui.imageViewContainer.y()
41
        width = self.ui.imageViewContainer.frameGeometry().width()
42
        height = self.ui.imageViewContainer.frameGeometry().height()
43
        self.ui.imageView = QtImageViewer()
44
        self.ui.imageView.setGeometry(QtCore.QRect(0, y, height, height))
45
        self.ui.imageView.aspectRatioMode = QtCore.Qt.KeepAspectRatio
46
        self.ui.imageView.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
47
        self.ui.imageView.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
48
        self.ui.imageView.canZoom = True
49
        self.ui.imageView.canPan = True
50
        image = self.image.copy()
51
        self.imgW = image.width()
52
        self.imgH = image.height()
53
        image = image.scaled(self.imgW, self.imgH)
54
        self.ui.imageView.setImage(image)
55
        self.ui.imageViewerContainerLayout.addWidget(self.ui.imageView)
56

    
57
    def setupTools(self):
58
        self.ui.handButton.clicked.connect(self.handToolClickEvent)
59
        self.ui.penButton.clicked.connect(self.penToolClickEvent)
60
        self.ui.penWidthSpinBox.valueChanged.connect(self.penWidthChangedEvent)
61
        self.ui.eraserButton.clicked.connect(self.eraserToolClickEvent)
62
        self.ui.eraserSpinBox.valueChanged.connect(self.eraserWidthChangedEvent)
63
        self.ui.areaEraserButton.clicked.connect(self.areaEraserToolClickEvent)
64
        self.ui.zoomButton.clicked.connect(self.zoomToolClickEvent)
65
        self.ui.initZoomButton.clicked.connect(self.zoomInitToolClickEvent)
66
        self.ui.guidelineCheckbox.stateChanged.connect(self.guidelineStateChangedEvent)
67

    
68
    def initForms(self):
69
        self.ui.idLineEdit.setValidator(QRegExpValidator(QtCore.QRegExp("^[1-9]\d+$")))
70
        self.ui.thresholdLineEdit.setValidator(QRegExpValidator(QtCore.QRegExp("^[0-9]\d+$"))) # ([0-1]{1}[.])?[0-9]+
71
        self.ui.minMatchPointLineEdit.setValidator(QRegExpValidator(QtCore.QRegExp("^[0-9]\d+$")))
72
        self.initIsOriginDetectComboBoxItems()
73
        self.initOcrOptionComboBoxItems()
74
        self.initDefaultSymbolDirectionComboBoxItems()
75
        self.ui.addAdditionalSymbolButton.clicked.connect(self.addAdditionalSymbol)
76
        self.ui.addOriginalPointButton.clicked.connect(self.addOriginalPoint)
77
        self.ui.addConnectionPointButton.clicked.connect(self.addConnectionPoint)
78
        self.initBaseSymbolComboBoxItems()
79
        self.initAdditionalSymbolComboBoxItems()
80
        
81
    def initContents(self):
82
        self.ui.targetDBLineEdit.setText(self.project.getPath()+'/db/ITI_PID.db')
83
        #self.ui.isOriginDetectComboBox
84
        #self.ui.ocrOptionComboBox
85
        #self.ui.baseSymbolComboBox
86
        #self.initBaseSymbolComboBoxItems()
87
        #self.ui.defaultSymbolDirectionComboBox
88
        #self.ui.additionalSymbolComboBox
89

    
90
    def initIsOriginDetectComboBoxItems(self):
91
        self.ui.isOriginDetectComboBox.addItem("원본 도면", 0)
92
        self.ui.isOriginDetectComboBox.addItem("텍스트 제거 도면", 1)
93

    
94
    def initOcrOptionComboBoxItems(self):
95
        self.ui.ocrOptionComboBox.addItem("OCR 미적용", 0)
96
        self.ui.ocrOptionComboBox.addItem("일반 심볼", 1)
97
        self.ui.ocrOptionComboBox.addItem("Instrument 계통", 2)
98

    
99
    def initDefaultSymbolDirectionComboBoxItems(self):
100
        self.ui.defaultSymbolDirectionComboBox.addItem("", 0)
101
        self.ui.defaultSymbolDirectionComboBox.addItem("", 2)
102
        self.ui.defaultSymbolDirectionComboBox.addItem("", 3)
103
        self.ui.defaultSymbolDirectionComboBox.addItem("", 1)
104

    
105
    def initBaseSymbolComboBoxItems(self):
106
        symbolNameList = AppDocData.instance().getSymbolNameList()
107
        symbolNameList.insert(0, "None")
108
        for name in symbolNameList:
109
            self.ui.baseSymbolComboBox.addItem(name)
110

    
111
    def initAdditionalSymbolComboBoxItems(self):
112
        symbolNameList = AppDocData.instance().getSymbolNameList()
113
        symbolNameList.insert(0, "None")
114
        for name in symbolNameList:
115
            self.ui.additionalSymbolComboBox.addItem(name)
116

    
117
    def removeConnectionPointCircles(self, circlePointList):
118
        for circlePoint in circlePointList:
119
            self.removeConnectionPointCircle(circlePoint)
120

    
121
    def removeConnectionPointCircle(self, circlePoint):
122
        self.ui.imageView.scene.removeItem(self.ui.imageView.scene.itemAt(QtCore.QPointF(int(circlePoint.x()), int(circlePoint.y())), QTransform()))
123

    
124
    def showDialog(self):
125
        self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.WindowContextHelpButtonHint)
126
        self.show()
127
        self.exec_()
128
        return self.isAccepted
129

    
130
    def makeFileName(self, originName, newName):
131
        imageFolderDir = self.project.getPath() + "\\image"
132
        imageDir = imageFolderDir + "\\" + newName + ".png"
133
        svgFolderDir = self.project.getPath() + "\\svg"
134
        svgDir = svgFolderDir + "\\" + newName + ".svg"
135
        if (os.path.exists(imageDir)) or (self.dbHelper.isExistFileName(imageDir) or (os.path.exists(svgDir))):
136
            self.FILE_NUMBER = self.FILE_NUMBER + 1
137
            imgName = originName + "({})".format(self.FILE_NUMBER)
138
            return self.makeFileName(originName, imgName)
139
        else:
140
            return newName
141

    
142
    def makeSymbolData(self):
143
        symId = self.ui.idLineEdit.text()
144
        name = self.ui.nameLineEdit.text()
145
        type = self.ui.typeLineEdit.text()
146
        self.FILE_NUMBER = 0
147
        fileName = self.makeFileName(name, name)
148
        path = self.project.getPath() + "\\image\\" + fileName + ".png"
149
        threshold = self.ui.thresholdLineEdit.text()
150
        minMatchPoint = self.ui.minMatchPointLineEdit.text()
151
        isDetectOnOrigin = self.ui.isOriginDetectComboBox.currentData()
152
        rotationCount = self.ui.rotationCountSpinBox.value()
153
        ocrOption = self.ui.ocrOptionComboBox.currentData()
154
        isContainChild = 1 if self.ui.isContainChildCheckBox.isChecked() else 0
155
        originalPoint = self.ui.originalPointLineEdit.text()
156
        connectionPoint = self.makeConnectionPointListString()
157
        ### 기초심볼추가
158
        baseSymbol = self.ui.baseSymbolComboBox.currentText()
159
        ### 부가심볼추가
160
        additionalSymbol = self.makeAdditionalSymbolListString()
161

    
162
        convertedThreshold = int(threshold) / 100.0
163

    
164
        newSym = symbol.SymbolBase(int(symId), fileName, type, path, convertedThreshold, int(minMatchPoint), isDetectOnOrigin
165
                                   , rotationCount, ocrOption, isContainChild, originalPoint, connectionPoint, baseSymbol, additionalSymbol)
166

    
167
        return newSym
168

    
169
    def makeAdditionalSymbolListString(self):
170
        ret = ""
171
        listItems = []
172
        for index in range(self.ui.additionalSymbolListWidget.count()):
173
            listItems.append(self.ui.additionalSymbolListWidget.item(index))
174
        if listItems is not None:
175
            for index in range(len(listItems)):
176
                item = listItems[index]
177
                text = item.text()
178
                if index != 0:
179
                    ret = ret + "/"
180
                ret = ret + text
181
        return ret
182

    
183
    def makeConnectionPointListString(self):
184
        ret = ""
185
        listItems = []
186
        for index in range(self.ui.connectionPointList.count()):
187
            listItems.append(self.ui.connectionPointList.item(index))
188
        if listItems is not None:
189
            for index in range(len(listItems)):
190
                item = listItems[index]
191
                text = item.text()
192
                if index != 0:
193
                    ret = ret + "/"
194
                ret = ret + text
195
        return ret
196

    
197
    def accept(self):
198
        print("save")
199

    
200
        isValid, exceptionMsg = self.isValidSymbolInfo()
201
        if isValid:
202
            print("valid symbol info")
203
            isAdded, fileName, imagePath = self.dbHelper.insertSymbol(self.makeSymbolData())
204

    
205
            if isAdded:
206
                image = self.ui.imageView.image()
207
                if image is not None:
208
                    image.save(imagePath, 'PNG')
209
                    potrace.convertImageToSvg(imagePath, self.project.getPath()+"\\svg\\" + fileName + ".svg")
210
                    self.isAccepted = True
211
            else:
212
                QMessageBox.about(self.ui.buttonBox, "알림", "심볼 저장 과정 중 문제가 발생했습니다.")
213
            QDialog.accept(self)
214
        else:
215
            print("invalid symbol info")
216
            QMessageBox.about(self.ui.buttonBox, "알림", exceptionMsg)
217

    
218
    def cancel(self):
219
        print("cancel")
220
        self.isAccepted = Flase
221
        QDialog.cancel(self)
222

    
223
    def keyPressEvent(self, event):
224
        if event.key() == QtCore.Qt.Key_Delete:
225
            selectedItems = self.ui.connectionPointList.selectedItems()
226
            if selectedItems is not None:
227
                for item in selectedItems:
228
                    text = item.text()
229
                    x = int(text.split(",")[0])
230
                    y = int(text.split(",")[1])
231
                    self.removeConnectionPointCircle(QtCore.QPointF(x, y))
232
                    self.ui.connectionPointList.takeItem(self.ui.connectionPointList.row(item))
233

    
234
    def handToolClickEvent(self, event):
235
        print("hand tool clicked")
236
        self.ui.imageView.command = HandCommand.HandCommand(self.ui.imageView)
237

    
238
    def zoomInitToolClickEvent(self, event):
239
        print("zoom init tool clicked")
240
        self.ui.imageView.command = None
241
        self.ui.imageView.zoomImageInit()
242

    
243
    def zoomToolClickEvent(self, event):
244
        print("zoom tool clicked")
245
        self.ui.imageView.command = ZoomCommand.ZoomCommand(self.ui.imageView)
246

    
247
    def penToolClickEvent(self, event):
248
        print("Pen")
249
        width = self.ui.toolWidget.findChild(QSpinBox, 'penWidthSpinBox').value()
250
        self.ui.imageView.command = PenCommand.PenCommand(self.ui.imageView)
251
        self.ui.imageView.command.width = width
252

    
253
    def penWidthChangedEvent(self, value):
254
        print("Pen Width " + str(value))
255
        if self.ui.imageView.command is not None and type(self.ui.imageView.command) is PenCommand.PenCommand:
256
            self.ui.imageView.command.width = value
257

    
258
    def eraserToolClickEvent(self, event):
259
        print("eraser")
260
        width = self.ui.toolWidget.findChild(QSpinBox, 'eraserSpinBox').value()
261
        self.ui.imageView.command = EraserCommand.EraserCommand(self.ui.imageView)
262
        self.ui.imageView.command.width = width
263

    
264
    def eraserWidthChangedEvent(self, value):
265
        print("eraser " + str(value))
266
        if self.ui.imageView.command is not None and type(self.ui.imageView.command) is EraserCommand.EraserCommand:
267
            self.ui.imageView.command.width = value
268

    
269
    def areaEraserToolClickEvent(self, event):
270
        print("area eraser")
271
        self.ui.imageView.command = AreaEraserCommand.AreaEraserCommand(self.ui.imageView)
272

    
273
    def guidelineStateChangedEvent(self, value):
274
        if self.ui.guidelineCheckbox.isChecked():
275
            self.ui.imageView.showGuideline(True)
276
        else:
277
            self.ui.imageView.showGuideline(False)
278

    
279
    def addAdditionalSymbol(self, event):
280
        print("addAdditionalSymbol")
281
        additionalSymbolIndex = self.ui.additionalSymbolComboBox.currentIndex()
282
        if additionalSymbolIndex != 0:
283
            print("Symbol Selected")
284
            direction = self.ui.defaultSymbolDirectionComboBox.currentText()
285
            symbolName = self.ui.additionalSymbolComboBox.currentText()
286
            text = "{},{}".format(direction, symbolName)
287

    
288
            if self.isAlreadyAdded(text):
289
                QMessageBox.about(self.ui.buttonBox, "알림", "이미 추가된 아이템입니다.")
290
            else:
291
                self.ui.additionalSymbolListWidget.addItem(text)
292

    
293
    def isAlreadyAdded(self, text):
294
        for index in range(self.ui.additionalSymbolListWidget.count()):
295
            item = self.ui.additionalSymbolListWidget.item(index)
296
            if item.text() == text:
297
                return True
298
        return False
299

    
300
    def addOriginalPoint(self, event):
301
        print("addOriginalPoint")
302
        self.ui.imageView.command = OriginalPointCommand.OriginalPointCommand(self.ui.imageView, self.ui.originalPointLineEdit)
303

    
304
    def addConnectionPoint(self, event):
305
        print("addConnectionPoint")
306
        self.ui.imageView.command = ConnectionPointCommand.ConnectionPointCommand(self.ui.imageView, self.ui.connectionPointLineEdit, self.ui.connectionPointList)
307

    
308
    def isValidSymbolInfo(self):
309
        print("isValid")
310
        EXCEPTION_MSG_FORMAT = "{} 입력을 확인해주세요."
311
        EXCEPTION_MSG_DUPLICATED_FORMAT = "이미 저장된 {} 값입니다."
312
        infoTitle = ""
313

    
314
        idText = self.ui.idLineEdit.text()
315
        id = int(idText) if idText else -1
316
        if (id == -1 or id < 100):
317
            infoTitle = self.ui.idLabel.text()
318
            return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
319

    
320
        if self.dbHelper.isExistData('symId', id):
321
            infoTitle = self.ui.idLabel.text()
322
            return (False, EXCEPTION_MSG_DUPLICATED_FORMAT.format(infoTitle))
323

    
324
        if not self.ui.nameLineEdit.text():
325
            infoTitle = self.ui.nameLabel.text()
326
            return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
327

    
328
        #if not self.ui.typeLineEdit.text():
329
        #    infoTitle = self.ui.typeLabel.text()
330
        #    return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
331

    
332
        thresholdText = self.ui.thresholdLineEdit.text()
333
        threshold = float(thresholdText) if thresholdText else -1
334
        if not(threshold >= 0 and threshold <= 100):
335
            infoTitle = self.ui.thresholdLabel.text()
336
            return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
337
            
338
        minMatchPointText = self.ui.minMatchPointLineEdit.text()
339
        minMatchPoint = float(minMatchPointText) if minMatchPointText else -1
340
        if not(minMatchPoint >= 0):
341
            infoTitle = self.ui.minMatchPointLabel.text()
342
            return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
343

    
344
        if self.ui.baseSymbolComboBox.currentIndex() == 0: #default value(None) index
345
            infoTitle = self.ui.baseSymbolLabel.text()
346
            return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
347

    
348
        #Additional Symbol is Nullable
349

    
350
        if not self.ui.originalPointLineEdit.text() or self.ui.imageView.isOriginalPointSelected == False:
351
            infoTitle = self.ui.originalPointLabel.text()
352
            return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
353

    
354
        if not (self.ui.connectionPointList.count() > 0):
355
            infoTitle = self.ui.connectionPointLabel.text()
356
            return (False, EXCEPTION_MSG_FORMAT.format(infoTitle))
357
            
358
        return True, None
클립보드 이미지 추가 (최대 크기: 500 MB)