프로젝트

일반

사용자정보

개정판 02e3cc34

ID02e3cc34537a0d746fe487d4baf466140ededbb2
상위 39ef99cf
하위 b3f4bf37, 1024ee16

백흠경이(가) 약 5년 전에 추가함

issue #643: 텍스트 찾기 및 변경 다이얼로그 수정

Change-Id: I029e43e411cfd39b4b80c36038afe6a434728e4a

차이점 보기:

DTI_PID/DTI_PID/AppDocData.py
483 483

  
484 484
    def isExistFileName(self, name):
485 485
        rows = None
486
        conn = self.project.database.connect()
487
        with conn:
486
        with self.project.database.connect() as conn:
488 487
            try:
489 488
                cursor = conn.cursor()
490 489
                sql = "SELECT * FROM Symbol WHERE name = '" + name + "'"
......
510 509

  
511 510
    def insertSymbol(self, symbol):
512 511
        isAdded = False
513
        conn = self.project.database.connect()
514
        with conn:
512
        with self.project.database.connect() as conn:
515 513
            try:
516 514
                sql = self.project.database.to_sql("""
517 515
                    INSERT INTO Symbol(name, SymbolType_UID, threshold, minMatchPoint, isDetectOrigin, rotationCount, ocrOption, isContainChild, originalPoint, connectionPoint, baseSymbol, additionalSymbol, isExceptDetect, hasInstrumentLabel, width, height, flip) 
......
550 548
    def updateSymbol(self, symbol):
551 549
        isUpdated = False
552 550

  
553
        conn = self.project.database.connect()
554
        with conn:
551
        with self.project.database.connect() as conn:
555 552
            try:
556 553
                sql = self.project.database.to_sql("""
557 554
                    UPDATE Symbol
......
596 593
    def getTargetSymbolList(self):
597 594
        targetSymbolList = []
598 595

  
599
        conn = self.project.database.connect()
600
        with conn:
596
        with self.project.database.connect() as conn:
601 597
            cursor = conn.cursor()
602 598
            sql = """SELECT a.UID,a.Name,b.Type,a.Threshold,a.MinMatchPoint,a.IsDetectOrigin,a.RotationCount,a.OCROption,a.IsContainChild,a.OriginalPoint,a.ConnectionPoint,
603 599
                    a.BaseSymbol,a.AdditionalSymbol,a.IsExceptDetect,a.HasInstrumentLabel,a.flip FROM Symbol a inner join SymbolType b on a.SymbolType_UID=b.UID WHERE a.IsExceptDetect = 0 order by width * height desc"""
......
607 603
                for row in rows:
608 604
                    sym = symbol.SymbolBase(row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9],
609 605
                                            row[10], row[11], row[12], row[13], row[14], row[0],
610
                                            detectFlip=row[15])  ## uid is last item
606
                                            detectFlip=row[15])  # uid is last item
611 607
                    targetSymbolList.append(sym)
612 608
            except Exception as ex:
613 609
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
......
615 611

  
616 612
        return targetSymbolList
617 613

  
618
    '''
619
        @brief  build application database
620
        @author humkyung
621
        @date   2018.04.20
622
    '''
623

  
624 614
    def buildAppDatabase(self):
625
        try:
626
            path = os.path.join(os.getenv('ALLUSERSPROFILE'), 'Digital PID')
627
            appDatabaseFilePath = os.path.join(path, 'App.db')
615
        """build application database"""
616
        path = os.path.join(os.getenv('ALLUSERSPROFILE'), 'Digital PID')
617
        appDatabaseFilePath = os.path.join(path, 'App.db')
628 618

  
629
            # Creates or opens a file called mydb with a SQLite3 DB
630
            conn = sqlite3.connect(appDatabaseFilePath)
631
            # Get a cursor object
632
            cursor = conn.cursor()
619
        # Creates or opens a file called mydb with a SQLite3 DB
620
        with sqlite3.connect(appDatabaseFilePath) as conn:
621
            try:
622
                # Get a cursor object
623
                cursor = conn.cursor()
633 624

  
634
            sqlFiles = ['App.Configuration.sql', 'App.Styles.sql']
635
            for sqlFile in sqlFiles:
636
                filePath = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'Scripts', sqlFile)
637
                try:
638
                    file = QFile(filePath)
639
                    file.open(QFile.ReadOnly)
640
                    sql = file.readAll()
641
                    sql = str(sql, encoding='utf8')
642
                    cursor.executescript(sql)
643
                finally:
644
                    file.close()
645
            conn.commit()
646
        # Catch the exception
647
        except Exception as ex:
648
            # Roll back any change if something goes wrong
649
            conn.rollback()
650
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
651
                                                      sys.exc_info()[-1].tb_lineno))
652
        finally:
653
            # Close the db connection
654
            conn.close()
625
                sqlFiles = ['App.Configuration.sql', 'App.Styles.sql']
626
                for sqlFile in sqlFiles:
627
                    filePath = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'Scripts', sqlFile)
628
                    try:
629
                        file = QFile(filePath)
630
                        file.open(QFile.ReadOnly)
631
                        sql = file.readAll()
632
                        sql = str(sql, encoding='utf8')
633
                        cursor.executescript(sql)
634
                    finally:
635
                        file.close()
636
                conn.commit()
637
            # Catch the exception
638
            except Exception as ex:
639
                # Roll back any change if something goes wrong
640
                conn.rollback()
641
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
642
                                                          sys.exc_info()[-1].tb_lineno))
655 643

  
656 644
        # expiration date is 2019-11-9-23-59-59 : e52SoJJRdZ-apJuhlFWtnFWC
657 645
        # configs = [Config('app', 'error origin point', '51,72'), Config('app', 'expiration', 'e52SoJJRdZ-apJuhlFWtnFWC')]
......
660 648
        if not configs:
661 649
            configs = self.getAppConfigs('app', 'license')
662 650
            if configs and 'DOFTECH' in configs[0].value:
663
                configs = [Config('app', 'error origin point', '51,72')]
664 651
                self.deleteAppConfigs('app', 'mode')
652
                configs = None
665 653
            else:
666
                configs = [Config('app', 'mode', 'advanced'), Config('app', 'error origin point', '51,72')]
654
                configs = [Config('app', 'mode', 'advanced')]
667 655
        else:
668
            configs = [Config('app', 'error origin point', '51,72')]
669
        self.saveAppConfigs(configs)
656
            configs = None
657

  
658
        if configs:
659
            self.saveAppConfigs(configs)
670 660

  
671 661
    '''
672 662
        @brief  load app style
DTI_PID/DTI_PID/Commands/SaveWorkCommand.py
46 46
                            titleBlockItems.append(item)
47 47
            '''
48 48

  
49
            db_items = [item for item in items if issubclass(type(item), QEngineeringAbstractItem) and type(
50
                item) is not QGraphicsBoundingBoxItem and type(item) is not QEngineeringErrorItem and type(
51
                item) is not QEngineeringLineNoTextItem]
49
            db_items = [item for item in items if issubclass(type(item), QEngineeringAbstractItem) and
50
                        type(item) is not QGraphicsBoundingBoxItem and
51
                        type(item) is not QEngineeringErrorItem and
52
                        type(item) is not QEngineeringLineNoTextItem]
52 53
            db_items.extend([item for item in items if type(item) is QEngineeringLineNoTextItem])
53 54
            db_items.extend([line for line in appDocData.tracerLineNos if type(line) is QEngineeringTrimLineNoTextItem])
54
            #db_items.extend(titleBlockItems)
55

  
55 56
            appDocData.saveToDatabase(db_items, self.show_progress)
56 57

  
57 58
            self.resultStr = SaveWorkCommand.save_to_xml()
DTI_PID/DTI_PID/MainWindow.py
119 119
        _translate = QCoreApplication.translate
120 120
        version = QCoreApplication.applicationVersion()
121 121
        # set title
122
        self.setWindowTitle(_translate(f"{App.NAME}({version}) - {project.name}",
123
                                       f"{App.NAME}({version}) - {project.name}"))
122
        self.setWindowTitle(self.title)
124 123

  
125 124
        self.lineComboBox = QComboBox(self.toolBar)
126 125
        for condition in LineTypeConditions.items():
......
320 319
        self.tableWidgetInconsistency.keyPressEvent = self.inconsistencyTableKeyPressEvent
321 320
        self.tableWidgetInconsistency.setSortingEnabled(True)
322 321

  
322
    @property
323
    def title(self) -> str:
324
        """return window title"""
325

  
326
        from App import App
327

  
328
        app_doc_data = AppDocData.instance()
329
        project = app_doc_data.getCurrentProject()
330
        version = QCoreApplication.applicationVersion()
331
        title = f"{App.NAME}({version}) - {project.name}:" \
332
                f"{app_doc_data.activeDrawing.name if app_doc_data.activeDrawing else ''}"
333

  
334
        return title
335

  
323 336
    def eventFilter(self, source, event):
324 337
        """display mouse position of graphics view"""
325
        if (event.type() == QEvent.MouseMove):
338
        if event.type() == QEvent.MouseMove:
326 339
            pos = self.graphicsView.mapToScene(event.pos())
327 340
            self._label_mouse.setText('mouse pos : ({},{})'.format(round(pos.x()), round(pos.y())))
328 341

  
......
440 453
            action.setChecked(False)
441 454

  
442 455
    def load_language(self, file):
443
        """
444
        load language file and then apply selected language 
445
        """
456
        """load language file and then apply selected language"""
446 457
        try:
447 458
            qm_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'translate', '{0}.qm'.format(file))
448 459
            QtWidgets.qApp.load_language(qm_file)
......
568 579
                                                           sys.exc_info()[-1].tb_lineno)
569 580
            self.addMessage.emit(MessageType.Error, message)
570 581

  
571
    '''
572
        @brief      show unknownitem's count
573
        @author     kyouho
574
        @date       2018.08.27
575
    '''
576

  
577 582
    def findReplaceTextClicked(self):
583
        """pop up find and replace dialog"""
578 584
        if not self.graphicsView.hasImage():
579 585
            self.showImageSelectionMessageBox()
580 586
            return
......
632 638
            '''
633 639

  
634 640
            # unknown item is not saved now for performance
635
            db_items = [item for item in items if issubclass(type(item), QEngineeringAbstractItem) and type(
636
                item) is not QGraphicsBoundingBoxItem and type(item) is not QEngineeringErrorItem and type(
637
                item) is not QEngineeringLineNoTextItem and type(item) is not QEngineeringUnknownItem]
641
            db_items = [item for item in items if issubclass(type(item), QEngineeringAbstractItem) and
642
                        type(item) is not QGraphicsBoundingBoxItem and
643
                        type(item) is not QEngineeringErrorItem and
644
                        type(item) is not QEngineeringLineNoTextItem and
645
                        type(item) is not QEngineeringUnknownItem]
638 646
            db_items.extend([item for item in items if type(item) is QEngineeringLineNoTextItem])
639 647
            db_items.extend([line for line in appDocData.tracerLineNos if type(line) is QEngineeringTrimLineNoTextItem])
640 648
            #db_items.extend(titleBlockItems)
......
1357 1365
                        # self.progress.hide()
1358 1366

  
1359 1367
                self.changeViewCheckedState(True)
1368
                self.setWindowTitle(self.title)
1360 1369
        except Exception as ex:
1361 1370
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1362 1371
                                                           sys.exc_info()[-1].tb_lineno)
DTI_PID/DTI_PID/OcrResultDialog.py
15 15
from App import App
16 16
from AppDocData import *
17 17

  
18

  
18 19
class QOcrResultDialog(QDialog):
19
    def __init__(self, parent, qimage, boundingBox, isModify = False, text = None):
20
    def __init__(self, parent, qimage, boundingBox, isModify=False, text=None):
20 21
        QDialog.__init__(self, parent)
21 22
        self.textInfoList = []
22 23

  
......
26 27
        self.originImageHeight = qimage.height()
27 28
        self.boundingBox = boundingBox
28 29

  
29
        self.angle = 0 # angle is degree
30
        self.angle = 0  # angle is degree
30 31

  
31 32
        self.ui = OcrResultDialog_UI.Ui_Dialog()
32 33
        self.ui.setupUi(self)
33
        
34

  
34 35
        appDocData = AppDocData.instance()
35 36
        configs = appDocData.getAppConfigs('app', 'mode')
36 37
        if configs and 1 == len(configs) and 'advanced' == configs[0].value:
......
42 43
        self.imgH = qimage.height()
43 44
        self.image = self.image.scaled(self.imgW, self.imgH)
44 45
        self.graphicsView = QtImageViewer.QtImageViewer(App.mainWnd())
45
        self.graphicsView.useDefaultCommand() ##### USE DEFAULT COMMAND
46
        self.graphicsView.useDefaultCommand()  ##### USE DEFAULT COMMAND
46 47
        self.graphicsView.setImage(self.image)
47 48
        self.ui.horizontalLayoutGraphicsView.addWidget(self.graphicsView)
48
        
49
        self.ui.counterClockPushButton_2.clicked.connect(lambda : self.rotateImage(True))
50
        self.ui.clockPushButton_2.clicked.connect(lambda : self.rotateImage(False))
49

  
50
        self.ui.counterClockPushButton_2.clicked.connect(lambda: self.rotateImage(True))
51
        self.ui.clockPushButton_2.clicked.connect(lambda: self.rotateImage(False))
51 52
        self.ui.redetectPushButton_2.clicked.connect(self.detectText)
52 53
        self.ui.pushButtonMakeTrainingImage.clicked.connect(self.pushButtonMakeTrainingImageClicked)
53 54

  
......
77 78
        @date       2018.10.16
78 79
        @history    euisung     2018.11.02       add notice push
79 80
    '''
81

  
80 82
    def pushButtonMakeTrainingImageClicked(self):
81 83
        import uuid
82 84
        uid = str(uuid.uuid4()) + '.png'
......
87 89
        self.image.save(trainingImgPath)
88 90
        QMessageBox.about(self, self.tr("INFO"), self.tr('Successfully saved.'))
89 91
        QDialog.reject(self)
90
        
92

  
91 93
    def rotateImage(self, isCounterClock):
92 94
        for item in self.graphicsView.scene.items():
93 95
            self.graphicsView.scene.removeItem(item)
......
101 103
            '''Clock'''
102 104
            self.angle = (self.angle - 270) % 360
103 105
            transform.rotate(90)
104
        #print(str(360 - self.angle))
106
        # print(str(360 - self.angle))
105 107
        self.image = self.image.transformed(transform)
106 108
        self.graphicsView.setImage(self.image)
107 109
        self.textInfoList = []
......
112 114
                 2018.11.08 euisung     add white char list check process on db
113 115
                 2018.11.22 euisung     OCR lang apply fixed
114 116
    '''
117

  
115 118
    def detectText(self):
116 119
        try:
117 120
            buffer = QBuffer()
......
119 122
            self.image.save(buffer, "PNG")
120 123
            pyImage = Image.open(io.BytesIO(buffer.data()))
121 124
            img = np.array(pyImage)
122
            
123
            #self.image.save('c:\\temp\\a.png')
125

  
126
            # self.image.save('c:\\temp\\a.png')
124 127

  
125 128
            docData = AppDocData.instance()
126
            
129

  
127 130
            '''
128 131
            # get ocr data of area which has the text
129 132
            pt = self.boundingBox.center()
......
135 138

  
136 139
            whiteCharList = docData.getConfigs('Text Recognition', 'White Character List')
137 140
            if len(whiteCharList) is 0:
138
                self.textInfoList = TOCR.getTextInfo(img, (round(self.boundingBox.x()), round(self.boundingBox.y())), 0, language=ocr_data)
141
                self.textInfoList = TOCR.getTextInfo(img, (round(self.boundingBox.x()), round(self.boundingBox.y())), 0,
142
                                                     language=ocr_data)
139 143
            else:
140
                self.textInfoList = TOCR.getTextInfo(img, (round(self.boundingBox.x()), round(self.boundingBox.y())), 0, language=ocr_data, conf = whiteCharList[0].value)
144
                self.textInfoList = TOCR.getTextInfo(img, (round(self.boundingBox.x()), round(self.boundingBox.y())), 0,
145
                                                     language=ocr_data, conf=whiteCharList[0].value)
141 146

  
142 147
            if self.textInfoList is not None and len(self.textInfoList) > 0:
143 148
                self.ui.detectResultTextEdit.setText(self.getPlainText(self.textInfoList))
144 149
                for textInfo in self.textInfoList:
145
                    self.graphicsView.scene.addRect(textInfo.getX()-int(self.boundingBox.x()), textInfo.getY()-int(self.boundingBox.y()), textInfo.getW(), textInfo.getH(), QPen(Qt.red, 1, Qt.SolidLine))
150
                    self.graphicsView.scene.addRect(textInfo.getX() - int(self.boundingBox.x()),
151
                                                    textInfo.getY() - int(self.boundingBox.y()), textInfo.getW(),
152
                                                    textInfo.getH(), QPen(Qt.red, 1, Qt.SolidLine))
146 153
            else:
147 154
                self.ui.detectResultTextEdit.setText("Not Found")
148 155
        except Exception as ex:
149
            from App import App 
150
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
156
            from App import App
157
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
158
                                                           sys.exc_info()[-1].tb_lineno)
151 159
            App.mainWnd().addMessage.emit(MessageType.Error, message)
152 160

  
153 161
    def getPlainText(self, textInfoList):
......
166 174
        @history    18.04.20    Jeongwoo    Calculate Start Point Coordinates by rotated angle
167 175
                    18.04.26    Jeongwoo    Scene.itemAt(textX - boundBox.x(), textY - boundBox.y())
168 176
    '''
177

  
169 178
    def accept(self):
170 179
        from TextInfo import TextInfo
171 180
        self.isAccepted = True
......
184 193

  
185 194
            if not len(self.textInfoList) > 0:
186 195
                import cv2
187
                #QMessageBox.about(self.ui.ocrDialogButtonBox, "알림", "텍스트 검출을 하신 후 다시 시도해주세요.")
188
                
196
                # QMessageBox.about(self.ui.ocrDialogButtonBox, "알림", "텍스트 검출을 하신 후 다시 시도해주세요.")
197

  
189 198
                buffer = QBuffer()
190 199
                buffer.open(QBuffer.ReadWrite)
191 200
                self.image.save(buffer, "PNG")
......
195 204
                img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
196 205
                imgNot = np.ones(img.shape, np.uint8)
197 206
                cv2.bitwise_not(img, imgNot)
198
                imgNot = cv2.dilate(imgNot, np.ones((8,8), np.uint8))
207
                imgNot = cv2.dilate(imgNot, np.ones((8, 8), np.uint8))
199 208

  
200 209
                contours, hierarchy = cv2.findContours(imgNot, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
201
                minX, minY, maxX, maxY = sys.maxsize, sys.maxsize, 0 ,0
210
                minX, minY, maxX, maxY = sys.maxsize, sys.maxsize, 0, 0
202 211
                if len(contours) is 0:
203 212
                    minX, minY, maxX, maxY = self.boundingBox.x(), self.boundingBox.y(), self.boundingBox.x() + self.image.width(), self.boundingBox.y() + self.image.height()
204 213
                else:
205 214
                    minX, minY, maxX, maxY = sys.maxsize, sys.maxsize, 0, 0
206 215
                    for cnt in contours:
207 216
                        x, y, w, h = cv2.boundingRect(cnt)
208
                        minX = min(x ,minX)
217
                        minX = min(x, minX)
209 218
                        minY = min(y, minY)
210 219
                        maxX = max(x + w, maxX)
211 220
                        maxY = max(y + h, maxY)
212 221
                    minX, minY, maxX, maxY = minX + self.boundingBox.x(), minY + self.boundingBox.y(), maxX + self.boundingBox.x(), maxY + self.boundingBox.y()
213
                
222

  
214 223
                self.textInfoList.append(TextInfo(text, minX, minY, maxX - minX, maxY - minY, 0))
215 224

  
216 225
            if not isSplit:
217 226
                minX, minY, maxX, maxY = sys.maxsize, sys.maxsize, 0, 0
218 227
                for textInfo in self.textInfoList:
219
                    x, y, w, h = textInfo.getX() ,textInfo.getY(), textInfo.getW(), textInfo.getH()
220
                    minX = min(x ,minX)
228
                    x, y, w, h = textInfo.getX(), textInfo.getY(), textInfo.getW(), textInfo.getH()
229
                    minX = min(x, minX)
221 230
                    minY = min(y, minY)
222 231
                    maxX = max(x + w, maxX)
223 232
                    maxY = max(y + h, maxY)
224
                
233

  
225 234
                self.textInfoList = [TextInfo(text, minX, minY, maxX - minX, maxY - minY, 0)]
226 235

  
227 236
            if len(self.textInfoList) > 0:
228 237
                for index in range(len(splitText)):
229 238
                    textInfo = self.textInfoList[index]
230
                    item = self.graphicsView.scene.itemAt(QPointF(float(textInfo.getX() - int(self.boundingBox.x())), float(textInfo.getY()-int(self.boundingBox.y()))), QTransform())
239
                    item = self.graphicsView.scene.itemAt(QPointF(float(textInfo.getX() - int(self.boundingBox.x())),
240
                                                                  float(textInfo.getY() - int(self.boundingBox.y()))),
241
                                                          QTransform())
231 242
                    if item is not None:
232 243
                        ## Transform rectangle for calculate start point
233 244
                        imgTransform = QTransform()
234 245
                        if self.angle == 90 or self.angle == 270:
235
                            imgTransform.translate(self.image.height()*0.5, self.image.width()*0.5)
246
                            imgTransform.translate(self.image.height() * 0.5, self.image.width() * 0.5)
236 247
                        elif self.angle == 0 or self.angle == 360:
237
                            imgTransform.translate(self.image.width()*0.5, self.image.height()*0.5)
248
                            imgTransform.translate(self.image.width() * 0.5, self.image.height() * 0.5)
238 249
                        imgTransform.rotate(-abs(self.angle))
239
                        imgTransform.translate(-self.image.width()*0.5, -self.image.height()*0.5)
240
                        rect = QRect(textInfo.getX() - int(self.boundingBox.x()), textInfo.getY() - int(self.boundingBox.y()), textInfo.getW(), textInfo.getH())
250
                        imgTransform.translate(-self.image.width() * 0.5, -self.image.height() * 0.5)
251
                        rect = QRect(textInfo.getX() - int(self.boundingBox.x()),
252
                                     textInfo.getY() - int(self.boundingBox.y()), textInfo.getW(), textInfo.getH())
241 253
                        rect = imgTransform.mapRect(rect)
242 254
                        ## up to here
243 255
                        textInfo.setX(rect.x() + int(self.boundingBox.x()))
244 256
                        textInfo.setY(rect.y() + int(self.boundingBox.y()))
245 257
                        textInfo.setText(splitText[index])
246 258
                        radian = round(math.radians(abs(self.angle)), 2)
247
                        textInfo.setAngle(radian) # 360 degree == 6.28319 radian
259
                        textInfo.setAngle(radian)  # 360 degree == 6.28319 radian
248 260
                        if radian == 1.57 or radian == 4.71:
249 261
                            width = textInfo.getW()
250 262
                            height = textInfo.getH()
251
                            textInfo.setW(height) ## SWAP
252
                            textInfo.setH(width) ## SWAP
263
                            textInfo.setW(height)  ## SWAP
264
                            textInfo.setH(width)  ## SWAP
253 265
                self.textInfoList = self.textInfoList[:len(splitText)]
254 266

  
255 267
                QDialog.accept(self)
256 268

  
257 269
        except Exception as ex:
258
            from App import App 
259
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
270
            from App import App
271
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
272
                                                           sys.exc_info()[-1].tb_lineno)
260 273
            App.mainWnd().addMessage.emit(MessageType.Error, message)
261 274

  
262 275
    def reject(self):
......
267 280
    '''
268 281
        @brief  Display this QDialog
269 282
    '''
283

  
270 284
    def showDialog(self):
271
        #self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
285
        # self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
272 286
        self.exec_()
273 287
        return (self.isAccepted, self.textInfoList)
DTI_PID/DTI_PID/Shapes/EngineeringLineItem.py
92 92
                    index = index + 1
93 93

  
94 94
                self.update_arrow()
95

  
96
                tooltip = '<b>{}</b><br>({},{})-({},{})'.format(str(self.uid), vertices[0][0], vertices[0][1],
97
                                                                vertices[1][0], vertices[1][1])
98
                self.setToolTip(tooltip)
95
                self.setToolTip(self.tooltip)
99 96
        except Exception as ex:
100 97
            from App import App
101 98
            from AppDocData import MessageType
......
109 106
        return str(self.uid)
110 107

  
111 108
    @property
109
    def tooltip(self):
110
        """return tooltip string"""
111

  
112
        start = self.connectors[0].center()
113
        end = self.connectors[1].center()
114
        tooltip = f"<b>TYPE=LINE</b><br>UID={str(self.uid)}<br>POS=({start[0]},{start[1]})-({end[0]},{end[1]})"
115

  
116
        return tooltip
117

  
118
    @property
112 119
    def properties(self):
113 120
        """ getter of flow mark """
114 121
        import uuid
......
1397 1404
            item = QEngineeringLineItem(vertices=[startPoint, endPoint], uid=uid)
1398 1405
            item.setVisible(False)
1399 1406
            item.lineType = node.find('TYPE').text if node.find('TYPE') is not None else 'Secondary'
1400
            ## assign area
1407
            # assign area
1401 1408
            if node.find('AREA') is None:
1402 1409
                appDocData = AppDocData.instance()
1403 1410
                for area in appDocData.getAreaList():
......
1406 1413
                        break
1407 1414
            else:
1408 1415
                item.area = node.find('AREA').text
1409
            ## up to here
1416
            # up to here
1410 1417

  
1411 1418
            thicknessNode = node.find('THICKNESS')
1412 1419
            item.thickness = int(
......
1728 1735
        self.setLine(start[0], start[1], end[0], end[1])
1729 1736
        self.update()
1730 1737

  
1731
        tooltip = '<b>{}</b><br>({},{})-({},{})'.format(str(self.uid), start[0], start[1], end[0], end[1])
1732
        self.setToolTip(tooltip)
1733

  
1738
        self.setToolTip(self.tooltip)
1734 1739
        self.update_arrow()
1735 1740

  
1736 1741
        self.scene().contents_changed.emit()
DTI_PID/DTI_PID/TextItemEditDialog.py
14 14
from SymbolSvgItem import SymbolSvgItem
15 15
from EngineeringLineItem import QEngineeringLineItem
16 16

  
17

  
17 18
class QTextItemEditDialog(QDialog):
18 19
    """ This is text item edit dialog class """
19 20

  
......
24 25
        self.ui = TextItemEdit_UI.Ui_TextItemEditDialog()
25 26
        self.ui.setupUi(self)
26 27

  
27
        self.ui.pushButtonFindText.clicked.connect(self.findTextClicked)
28
        self.ui.pushButtonFindText.clicked.connect(self.find_text)
28 29
        self.ui.pushButtonReplaceText.clicked.connect(self.replaceTextClicked)
29 30
        self.ui.checkBoxUID.stateChanged.connect(self.checkBoxChanged)
30 31

  
31
        self.prevText = ''
32
        self.textItems = []
33
        self.listIndex = 0
34

  
35 32
        self.ui.lineEditFindText.setFocus()
36 33

  
37
    '''
38
        @brief      find text click event
39
        @author     kyouho
40
        @date       2018.08.27
41
    '''
42
    def findTextClicked(self):
43
        self.findText()
44
    
45 34
    def is_valid_uuid(self, text, version=4):
46 35
        """ Check if uuid_to_test is a valid UUID. """
47 36
        import uuid
48 37

  
49 38
        try:
50
            uuid_obj = uuid.UUID(text)#, version=version)
39
            uuid_obj = uuid.UUID(text)  # , version=version)
51 40
        except:
52 41
            return False
53 42

  
54 43
        return str(uuid_obj) == text
55 44

  
56 45
    def checkBoxChanged(self, checkState):
57
        self.listIndex = 0
58
        self.prevText = ''
59 46
        if checkState is int(Qt.Checked):
60 47
            self.ui.pushButtonReplaceText.setEnabled(False)
61 48
            self.ui.lineEditReplaceText.setEnabled(False)
......
63 50
            self.ui.pushButtonReplaceText.setEnabled(True)
64 51
            self.ui.lineEditReplaceText.setEnabled(True)
65 52

  
66
    '''
67
        @brief      find text
68
        @author     kyouho
69
        @date       2018.08.27
70
    '''
71
    def findText(self):
53
    def find_text(self):
54
        """find user input text"""
55

  
56
        self.ui.tableViewResult.setModel(None)
57

  
72 58
        text = self.ui.lineEditFindText.text()
73 59
        if not text: return
74 60

  
61
        text_items = []
75 62
        if int(self.ui.checkBoxUID.checkState()) is int(Qt.Checked):
76
            self.textItems = [item for item in self.mainWindow.graphicsView.scene.items() if hasattr(item, 'uid') and str(item.uid).count(text)]
63
            text_items = [item for item in self.mainWindow.graphicsView.scene.items()
64
                              if hasattr(item, 'uid') and str(item.uid).count(text)]
77 65
        else:
78
            self.textItems = [item for item in self.mainWindow.graphicsView.scene.items() if issubclass(type(item), QEngineeringTextItem) and item.text().count(text)]
79
        
80
        if not self.textItems:
66
            text_items = [item for item in self.mainWindow.graphicsView.scene.items()
67
                              if issubclass(type(item), QEngineeringTextItem) and item.text().count(text)]
68

  
69
        if not text_items:
81 70
            QMessageBox.about(self, self.tr("Notice"), self.tr('Nothing Found.'))
82 71
            return
83
        if self.prevText != text:
84
            self.prevText = text
85
            self.listIndex = 0
86
            item = self.textItems[self.listIndex]
87
            self.selectTextItem(item)
88
            self.listIndex += 1
89
        elif self.textItems and self.listIndex == len(self.textItems):
90
            self.listIndex = 0
91
            QMessageBox.about(self, self.tr("Notice"), self.tr('Last Item Found.'))
92
        elif self.textItems:
93
            item = self.textItems[self.listIndex]
94
            self.selectTextItem(item)
95
            self.listIndex += 1
96 72

  
97
    '''
98
        @brief      replace text
99
        @author     kyouho
100
        @date       2018.08.27
101
    '''
73
        model = QStandardItemModel(len(text_items), 1)
74
        model.setHorizontalHeaderLabels(['UID'])
75
        for row in range(len(text_items)):
76
            item = QStandardItem(str(text_items[row]))
77
            item.setData(text_items[row])
78
            model.setItem(row, 0, item)
79
        self.ui.tableViewResult.setModel(model)
80
        self.ui.tableViewResult.selectionModel().selectionChanged.connect(self.selection_changed)
81
        self.selectTextItem(text_items[0])
82

  
102 83
    def replaceTextClicked(self):
103
        text = self.ui.lineEditFindText.text()
104
        if self.prevText != text:
105
            self.findText()
106
            self.listIndex = 0
107

  
108
        if self.textItems:
109
            item = self.textItems[self.listIndex]
110
            replace = self.ui.lineEditReplaceText.text()
111
            ## 기존 item이 replace가 전부 완료시 다음 item 선택
112
            if not item.text().count(text):
113
                self.textItems.remove(item)
114
                self.listIndex -= 1
115
                self.findText()
116

  
117
            if self.textItems:
118
                item = self.textItems[self.listIndex]
119
                if text == replace:
120
                    return
121
                item.setPlainText(item.text().replace(text, replace))
122
                #print(item.text())
84
        """replace text"""
85
        self.find_text()
86

  
87
        replace = self.ui.lineEditReplaceText.text()
88
        model = self.ui.tableViewResult.model()
89
        if replace and model.rowCount():
90
            messages = []
91
            for row in range(model.rowCount()):
92
                item = self.ui.tableViewResult.model().item(row, 0)
93
                data = item.data()
94
                if data and data.text() != replace:
95
                    text = data.text()
96
                    messages.append(f"replaced: {text} --> {replace}")
97
                    data.setPlainText(text.replace(text, replace))
98

  
99
            if messages:
100
                QMessageBox.information(self, self.tr('Information'), '\r\n'.join(messages))
123 101

  
124 102
    '''
125 103
        @brief      key press event
126 104
        @author     kyouho 
127 105
        @date       2018.08.27
128 106
    '''
107

  
129 108
    def selectTextItem(self, item):
130 109
        rect = item.sceneBoundingRect()
131 110
        self.mainWindow.graphicsView.centerOn(rect.center())
132
        self.mainWindow.graphicsView.zoomImage(True, QMouseEvent(QEvent.MouseButtonPress, self.mainWindow.graphicsView.mapFromScene(QPointF(rect.left(), rect.top())), Qt.LeftButton, Qt.LeftButton, Qt.NoModifier), 3)
111
        self.mainWindow.graphicsView.zoomImage(True, QMouseEvent(QEvent.MouseButtonPress,
112
                                                                 self.mainWindow.graphicsView.mapFromScene(
113
                                                                     QPointF(rect.left(), rect.top())), Qt.LeftButton,
114
                                                                 Qt.LeftButton, Qt.NoModifier), 3)
133 115
        item.setSelected(True)
134 116

  
135 117
    def replaceTextItem(self, item):
136 118
        pass
137 119

  
138

  
139
    '''
140
        @brief      key press event
141
        @author     kyouho 
142
        @date       2018.08.27
143
    '''
144 120
    def keyPressEvent(self, event):
121
        """key press event"""
145 122
        if event.key() == Qt.Key_Return:
146 123
            if self.ui.lineEditFindText.hasFocus():
147
                self.findText()
124
                self.find_text()
148 125
            elif self.ui.lineEditReplaceText.hasFocus():
149
                self.replaceTextClicked()
126
                self.replaceTextClicked()
127
        elif event.key() == Qt.Key_Escape:
128
            self.reject()
129

  
130
    def selection_changed(self, selection):
131
        """row selection is changed"""
132

  
133
        try:
134
            if selection.indexes():
135
                row = selection.indexes()[0].row()
136
                item = self.ui.tableViewResult.model().item(row, 0)
137
                data = item.data()
138
                self.selectTextItem(data)
139
        except Exception as ex:
140
            from App import App
141
            from AppDocData import MessageType
142

  
143
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
144
                                                           sys.exc_info()[-1].tb_lineno)
145
            App.mainWnd().addMessage.emit(MessageType.Error, message)
146

  
147
    def reject(self):
148
        """close a dialog"""
149
        QDialog.reject(self)
DTI_PID/DTI_PID/TextItemEdit_UI.py
1 1
# -*- coding: utf-8 -*-
2 2

  
3
# Form implementation generated from reading ui file './UI/TextItemEdit.ui'
3
# Form implementation generated from reading ui file '.\UI\TextItemEdit.ui'
4 4
#
5
# Created by: PyQt5 UI code generator 5.11.3
5
# Created by: PyQt5 UI code generator 5.13.0
6 6
#
7 7
# WARNING! All changes made in this file will be lost!
8 8

  
9

  
9 10
from PyQt5 import QtCore, QtGui, QtWidgets
10 11

  
12

  
11 13
class Ui_TextItemEditDialog(object):
12 14
    def setupUi(self, TextItemEditDialog):
13 15
        TextItemEditDialog.setObjectName("TextItemEditDialog")
14
        TextItemEditDialog.resize(307, 99)
16
        TextItemEditDialog.resize(421, 220)
15 17
        self.gridLayout = QtWidgets.QGridLayout(TextItemEditDialog)
16 18
        self.gridLayout.setObjectName("gridLayout")
17
        self.pushButtonReplaceText = QtWidgets.QPushButton(TextItemEditDialog)
18
        self.pushButtonReplaceText.setObjectName("pushButtonReplaceText")
19
        self.gridLayout.addWidget(self.pushButtonReplaceText, 2, 3, 1, 1)
20
        self.buttonBox = QtWidgets.QDialogButtonBox(TextItemEditDialog)
21
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
22
        self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Close)
23
        self.buttonBox.setObjectName("buttonBox")
24
        self.gridLayout.addWidget(self.buttonBox, 4, 2, 1, 2)
19
        self.gridLayout_2 = QtWidgets.QGridLayout()
20
        self.gridLayout_2.setObjectName("gridLayout_2")
25 21
        self.pushButtonFindText = QtWidgets.QPushButton(TextItemEditDialog)
26 22
        self.pushButtonFindText.setDefault(True)
27 23
        self.pushButtonFindText.setObjectName("pushButtonFindText")
28
        self.gridLayout.addWidget(self.pushButtonFindText, 1, 3, 1, 1)
29
        self.lineEditFindText = QtWidgets.QLineEdit(TextItemEditDialog)
30
        self.lineEditFindText.setObjectName("lineEditFindText")
31
        self.gridLayout.addWidget(self.lineEditFindText, 1, 1, 1, 2)
24
        self.gridLayout_2.addWidget(self.pushButtonFindText, 0, 2, 1, 1)
25
        self.pushButtonReplaceText = QtWidgets.QPushButton(TextItemEditDialog)
26
        self.pushButtonReplaceText.setObjectName("pushButtonReplaceText")
27
        self.gridLayout_2.addWidget(self.pushButtonReplaceText, 1, 2, 1, 1)
28
        self.label_2 = QtWidgets.QLabel(TextItemEditDialog)
29
        self.label_2.setObjectName("label_2")
30
        self.gridLayout_2.addWidget(self.label_2, 0, 0, 1, 1)
32 31
        self.label = QtWidgets.QLabel(TextItemEditDialog)
33 32
        self.label.setObjectName("label")
34
        self.gridLayout.addWidget(self.label, 2, 0, 1, 1)
33
        self.gridLayout_2.addWidget(self.label, 1, 0, 1, 1)
34
        self.lineEditFindText = QtWidgets.QLineEdit(TextItemEditDialog)
35
        self.lineEditFindText.setObjectName("lineEditFindText")
36
        self.gridLayout_2.addWidget(self.lineEditFindText, 0, 1, 1, 1)
35 37
        self.lineEditReplaceText = QtWidgets.QLineEdit(TextItemEditDialog)
36 38
        self.lineEditReplaceText.setObjectName("lineEditReplaceText")
37
        self.gridLayout.addWidget(self.lineEditReplaceText, 2, 1, 1, 2)
38
        self.label_2 = QtWidgets.QLabel(TextItemEditDialog)
39
        self.label_2.setObjectName("label_2")
40
        self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1)
39
        self.gridLayout_2.addWidget(self.lineEditReplaceText, 1, 1, 1, 1)
40
        self.tableViewResult = QtWidgets.QTableView(TextItemEditDialog)
41
        self.tableViewResult.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
42
        self.tableViewResult.setObjectName("tableViewResult")
43
        self.tableViewResult.horizontalHeader().setStretchLastSection(True)
44
        self.gridLayout_2.addWidget(self.tableViewResult, 2, 0, 1, 3)
45
        self.gridLayout.addLayout(self.gridLayout_2, 0, 0, 1, 1)
46
        self.horizontalLayout = QtWidgets.QHBoxLayout()
47
        self.horizontalLayout.setObjectName("horizontalLayout")
41 48
        self.checkBoxUID = QtWidgets.QCheckBox(TextItemEditDialog)
42 49
        self.checkBoxUID.setFocusPolicy(QtCore.Qt.NoFocus)
43 50
        self.checkBoxUID.setObjectName("checkBoxUID")
44
        self.gridLayout.addWidget(self.checkBoxUID, 4, 0, 1, 1)
51
        self.horizontalLayout.addWidget(self.checkBoxUID)
52
        self.buttonBox = QtWidgets.QDialogButtonBox(TextItemEditDialog)
53
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
54
        self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Close)
55
        self.buttonBox.setObjectName("buttonBox")
56
        self.horizontalLayout.addWidget(self.buttonBox)
57
        self.gridLayout.addLayout(self.horizontalLayout, 2, 0, 1, 1)
45 58

  
46 59
        self.retranslateUi(TextItemEditDialog)
47 60
        self.buttonBox.accepted.connect(TextItemEditDialog.accept)
......
51 64
    def retranslateUi(self, TextItemEditDialog):
52 65
        _translate = QtCore.QCoreApplication.translate
53 66
        TextItemEditDialog.setWindowTitle(_translate("TextItemEditDialog", "Text Find / Replace"))
54
        self.pushButtonReplaceText.setText(_translate("TextItemEditDialog", "Replace"))
55 67
        self.pushButtonFindText.setText(_translate("TextItemEditDialog", "→"))
56
        self.label.setText(_translate("TextItemEditDialog", "Replace"))
68
        self.pushButtonReplaceText.setText(_translate("TextItemEditDialog", "Replace"))
57 69
        self.label_2.setText(_translate("TextItemEditDialog", "Text"))
70
        self.label.setText(_translate("TextItemEditDialog", "Replace"))
58 71
        self.checkBoxUID.setText(_translate("TextItemEditDialog", "UID"))
59

  
60

  
61
if __name__ == "__main__":
62
    import sys
63
    app = QtWidgets.QApplication(sys.argv)
64
    TextItemEditDialog = QtWidgets.QDialog()
65
    ui = Ui_TextItemEditDialog()
66
    ui.setupUi(TextItemEditDialog)
67
    TextItemEditDialog.show()
68
    sys.exit(app.exec_())
69

  
DTI_PID/DTI_PID/UI/TextItemEdit.ui
6 6
   <rect>
7 7
    <x>0</x>
8 8
    <y>0</y>
9
    <width>307</width>
10
    <height>99</height>
9
    <width>421</width>
10
    <height>220</height>
11 11
   </rect>
12 12
  </property>
13 13
  <property name="windowTitle">
14 14
   <string>Text Find / Replace</string>
15 15
  </property>
16
  <property name="sizeGripEnabled">
17
   <bool>true</bool>
18
  </property>
19
  <property name="modal">
20
   <bool>false</bool>
21
  </property>
16 22
  <layout class="QGridLayout" name="gridLayout">
17
   <item row="2" column="3">
18
    <widget class="QPushButton" name="pushButtonReplaceText">
19
     <property name="text">
20
      <string>Replace</string>
21
     </property>
22
    </widget>
23
   </item>
24
   <item row="4" column="2" colspan="2">
25
    <widget class="QDialogButtonBox" name="buttonBox">
26
     <property name="orientation">
27
      <enum>Qt::Horizontal</enum>
28
     </property>
29
     <property name="standardButtons">
30
      <set>QDialogButtonBox::Close</set>
31
     </property>
32
    </widget>
33
   </item>
34
   <item row="1" column="3">
35
    <widget class="QPushButton" name="pushButtonFindText">
36
     <property name="text">
37
      <string>→</string>
38
     </property>
39
     <property name="default">
40
      <bool>true</bool>
41
     </property>
42
    </widget>
43
   </item>
44
   <item row="1" column="1" colspan="2">
45
    <widget class="QLineEdit" name="lineEditFindText"/>
23
   <item row="0" column="0">
24
    <layout class="QGridLayout" name="gridLayout_2">
25
     <item row="0" column="2">
26
      <widget class="QPushButton" name="pushButtonFindText">
27
       <property name="text">
28
        <string>→</string>
29
       </property>
30
       <property name="default">
31
        <bool>true</bool>
32
       </property>
33
      </widget>
34
     </item>
35
     <item row="1" column="2">
36
      <widget class="QPushButton" name="pushButtonReplaceText">
37
       <property name="text">
38
        <string>Replace</string>
39
       </property>
40
      </widget>
41
     </item>
42
     <item row="0" column="0">
43
      <widget class="QLabel" name="label_2">
44
       <property name="text">
45
        <string>Text</string>
46
       </property>
47
      </widget>
48
     </item>
49
     <item row="1" column="0">
50
      <widget class="QLabel" name="label">
51
       <property name="text">
52
        <string>Replace</string>
53
       </property>
54
      </widget>
55
     </item>
56
     <item row="0" column="1">
57
      <widget class="QLineEdit" name="lineEditFindText"/>
58
     </item>
59
     <item row="1" column="1">
60
      <widget class="QLineEdit" name="lineEditReplaceText"/>
61
     </item>
62
     <item row="2" column="0" colspan="3">
63
      <widget class="QTableView" name="tableViewResult">
64
       <property name="selectionBehavior">
65
        <enum>QAbstractItemView::SelectRows</enum>
66
       </property>
67
       <attribute name="horizontalHeaderStretchLastSection">
68
        <bool>true</bool>
69
       </attribute>
70
      </widget>
71
     </item>
72
    </layout>
46 73
   </item>
47 74
   <item row="2" column="0">
48
    <widget class="QLabel" name="label">
49
     <property name="text">
50
      <string>Replace</string>
51
     </property>
52
    </widget>
53
   </item>
54
   <item row="2" column="1" colspan="2">
55
    <widget class="QLineEdit" name="lineEditReplaceText"/>
56
   </item>
57
   <item row="1" column="0">
58
    <widget class="QLabel" name="label_2">
59
     <property name="text">
60
      <string>Text</string>
61
     </property>
62
    </widget>
63
   </item>
64
   <item row="4" column="0">
65
    <widget class="QCheckBox" name="checkBoxUID">
66
     <property name="focusPolicy">
67
      <enum>Qt::NoFocus</enum>
68
     </property>
69
     <property name="text">
70
      <string>UID</string>
71
     </property>
72
    </widget>
75
    <layout class="QHBoxLayout" name="horizontalLayout">
76
     <item>
77
      <widget class="QCheckBox" name="checkBoxUID">
78
       <property name="focusPolicy">
79
        <enum>Qt::NoFocus</enum>
80
       </property>
81
       <property name="text">
82
        <string>UID</string>
83
       </property>
84
      </widget>
85
     </item>
86
     <item>
87
      <widget class="QDialogButtonBox" name="buttonBox">
88
       <property name="orientation">
89
        <enum>Qt::Horizontal</enum>
90
       </property>
91
       <property name="standardButtons">
92
        <set>QDialogButtonBox::Close</set>
93
       </property>
94
      </widget>
95
     </item>
96
    </layout>
73 97
   </item>
74 98
  </layout>
75 99
 </widget>

내보내기 Unified diff

클립보드 이미지 추가 (최대 크기: 500 MB)