프로젝트

일반

사용자정보

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

hytos / DTI_PID / DTI_PID / AppDocData.py @ acc6b10d

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

1
# coding: utf-8
2
""" This is document data(SDI) class """
3

    
4
import sys
5
import os
6
import sqlite3
7
import datetime
8
from enum import Enum
9
from PIL import PngImagePlugin, JpegImagePlugin
10
from PIL import Image
11
from PIL.ImageQt import ImageQt
12

    
13
try:
14
    from PyQt5.QtCore import *
15
    from PyQt5.QtGui import *
16
    from PyQt5 import QtWidgets
17
except ImportError:
18
    from PyQt4.QtCore import *
19
    from PyQt4.QtGui import *
20

    
21
from SingletonInstance import SingletonInstance
22
import symbol
23
from NominalPipeSize import NominalPipeSize
24

    
25

    
26
class Config:
27
    def __init__(self, section, key, value):
28
        self.section = section
29
        self.key = key
30
        self.value = value
31

    
32
    '''
33
        @brief  return size value string
34
        @author humkyung
35
        @date   2018.04.24
36
    '''
37

    
38
    def sizeValue(self):
39
        return self.inchStr if 'Inch' == self.sizeUnit else self.metricStr
40

    
41

    
42
'''
43
    @brief  Pipe color class
44
'''
45

    
46

    
47
class Color:
48
    def __init__(self, index, red, green, blue):
49
        self.index = index
50
        self.red = red
51
        self.green = green
52
        self.blue = blue
53

    
54

    
55
'''
56
    @brief      MessageType
57
    @author     humkyung 
58
    @date       2018.07.31
59
'''
60

    
61

    
62
class MessageType(Enum):
63
    Normal = 1
64
    Error = 2
65
    Check = 3
66

    
67

    
68
class AppDocData(SingletonInstance):
69
    DATABASE = 'ITI_PID.db'
70

    
71
    def __init__(self):
72
        from DisplayColors import DisplayColors
73

    
74
        self._imgFilePath = None
75
        self.imgName = None
76
        self._OCRData = None
77
        self._imgSrc = None
78

    
79
        self._areas = []
80
        self.equipments = []
81
        self.lineNos = []
82
        self.lines = []
83
        self.texts = []
84
        self.symbols = []
85
        self.unknowns = []
86
        self.allItems = []
87
        self.tracerLineNos = []
88
        self.lineIndicators = []
89
        self._colors = None
90
        self._lineNoProperties = None
91
        self._lineTypes = None
92
        self._lineTypeConfigs = None
93
        self._activeDrawing = None
94
        self._hmbTable = None
95
        self._titleBlockProperties = None
96
        self.needReOpening = None
97

    
98
        # caches
99
        self._configs = None
100
        self._symbolBase = {}
101
        self._symbolType = {}
102
        self._lineNoPropertiesUID = {}
103
        self._attributeByType = {}
104

    
105
        # for load drawing data from database
106
        self._connecterss = {}
107
        self._associationss = {}
108
        self._attributess = {}
109

    
110
    def clearTempDBData(self):
111
        self._connecterss = {}
112
        self._associationss = {}
113
        self._attributess = {}
114

    
115
    def clearItemList(self, trim):
116
        '''
117
            @brief      clear item list
118
            @author     euisung
119
            @date       2018.11.28
120
        '''
121
        self.equipments.clear()
122
        self.symbols.clear()
123
        self.lineNos.clear()
124
        self.texts.clear()
125
        self.unknowns.clear()
126
        self.allItems.clear()
127
        self.lineIndicators.clear()
128
        if trim:
129
            self.tracerLineNos.clear()
130
            self.lines.clear()
131

    
132
    '''
133
        @brief      clear
134
        @author     humkyung
135
        @date       2018.09.06
136
    '''
137

    
138
    def clear(self):
139
        if self.activeDrawing and self.activeDrawing.UID:
140
            self.clear_occupying_drawing(self.activeDrawing.UID)
141

    
142
        self._imgFilePath = None
143
        self.imgName = None
144
        self._imgSrc = None
145

    
146
        self._areas.clear()
147
        self.equipments.clear()
148
        self.lineNos.clear()
149
        self.lines.clear()
150
        self.texts.clear()
151
        self.symbols.clear()
152
        self.unknowns.clear()
153
        self.allItems.clear()
154
        self.tracerLineNos.clear()
155
        self.lineIndicators.clear()
156
        self._colors = None
157
        self._lineNoProperties = None
158
        self._lineTypeConfigs = None
159
        self._activeDrawing = None
160
        self._hmbTable = None
161
        self._titleBlockProperties = None
162

    
163
        self._configs = None
164
        self._symbolBase = {}
165
        self._symbolType = {}
166
        self._lineNoPropertiesUID = {}
167
        self._attributeByType = {}
168

    
169
        self._connecterss = {}
170
        self._associationss = {}
171
        self._attributess = {}
172

    
173
    def clear_occupying_drawing(self, drawing):
174
        """ clear drawing access """
175
        conn = self.project.database.connect()
176
        with conn:
177
            try:
178
                # Get a cursor object
179
                cursor = conn.cursor()
180
                if drawing:
181
                    sql = "UPDATE Drawings SET [OCCUPIED]=null WHERE [OCCUPIED]='{}' and UID='{}'".format(os.environ['COMPUTERNAME'], drawing)
182
                else:
183
                    sql = "UPDATE Drawings SET [OCCUPIED]=null"
184
                cursor.execute(sql)
185

    
186
                conn.commit()
187
            # Catch the exception
188
            except Exception as ex:
189
                conn.rollback()
190

    
191
                from App import App 
192
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
193
                App.mainWnd().addMessage.emit(MessageType.Error, message)
194

    
195
    def set_occupying_drawing(self, drawing):
196
        """ set drawing access return true if success"""
197
        conn = self.project.database.connect()
198
        with conn:
199
            try:
200
                # Get a cursor object
201
                cursor = conn.cursor()
202
                sql = "select OCCUPIED from Drawings where [UID]='{}'".format(drawing)
203
                cursor.execute(sql)
204

    
205
                rows = cursor.fetchall()
206
                if not rows[0][0] or rows[0][0] == os.environ['COMPUTERNAME']:
207
                    sql = "UPDATE Drawings SET [OCCUPIED]='{}' WHERE UID='{}'".format(os.environ['COMPUTERNAME'], drawing)
208
                    cursor.execute(sql)
209
                    conn.commit()
210
                    return True
211
                else:
212
                    return False
213

    
214
            # Catch the exception
215
            except Exception as ex:
216
                conn.rollback()
217

    
218
                from App import App 
219
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
220
                App.mainWnd().addMessage.emit(MessageType.Error, message)
221

    
222
                return False
223

    
224
    '''
225
        @brief      Get drawing file list
226
        @author     euisung
227
        @date       2018.09.28
228
    '''
229

    
230
    def getDrawingFileList(self):
231
        """ get drawing files which's extension is .png or jpg from drawing folder """
232
        drawingFileList = []
233

    
234
        try:
235
            project = AppDocData.instance().getCurrentProject()
236
            path = project.getDrawingFilePath()
237
            drawingFileList = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f)) and
238
                               (os.path.splitext(f)[1].upper() == '.PNG' or os.path.splitext(f)[1].upper() == '.JPG' or
239
                                os.path.splitext(f)[1].upper() == '.JPEG')]
240
            drawingFileList.sort()
241
        except Exception as ex:
242
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
243
                                                      sys.exc_info()[-1].tb_lineno))
244

    
245
        return drawingFileList
246

    
247
    '''
248
        @brief      Get Training file list
249
        @author     euisung
250
        @date       2018.10.16
251
    '''
252

    
253
    def getTrainingFileList(self):
254
        try:
255
            project = AppDocData.instance().getCurrentProject()
256
            path = project.getTrainingFilePath()
257
            trainingFileList = os.listdir(path)
258
            trainingFileList.sort()
259
        except Exception as ex:
260
            from App import App
261
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
262
                                                          sys.exc_info()[-1].tb_lineno)
263
            App.mainWnd().addMessage.emit(MessageType.Error, message)
264

    
265
        return trainingFileList
266

    
267
    def getTrainingSymbolFileList(self):
268
        """  Get Symbol Training file list """
269
        try:
270
            project = AppDocData.instance().getCurrentProject()
271
            path = project.getTrainingSymbolFilePath()
272
            symbolTrainingFileList = os.listdir(path)
273
            symbolTrainingFileList.sort()
274
        except Exception as ex:
275
            from App import App
276
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
277
                                                          sys.exc_info()[-1].tb_lineno)
278
            App.mainWnd().addMessage.emit(MessageType.Error, message)
279

    
280
        return symbolTrainingFileList
281

    
282
    '''
283
        @brief      Get DB file path in ProgramData
284
        @author     Jeongwoo
285
        @date       2018.06.27
286
        @history    2018.06.29  Jeongwoo    Change method to get template db path
287
    '''
288

    
289
    def getTemplateDbPath(self):
290
        path = os.path.join(os.getenv('ALLUSERSPROFILE'), 'Digital PID')
291
        templateDbPath = os.path.join(path, 'Template.db')
292
        return templateDbPath
293

    
294
    def get_template_symbol_library_path(self):
295
        """return template symbol library path"""
296

    
297
        path = os.path.join(os.getenv('ALLUSERSPROFILE'), 'Digital PID')
298
        return os.path.join(path, 'SymbolLibrary.syl')
299

    
300
    def getAppDbPath(self):
301
        """
302
        @brief      Get application DB file path in ProgramData
303
        @author     humkyung
304
        @date       2018.10.01
305
        """
306

    
307
        path = os.path.join(os.getenv('ALLUSERSPROFILE'), 'Digital PID')
308
        app_database = os.path.join(path, 'App.db')
309
        return app_database
310

    
311
    '''
312
        @brief  getter of colors 
313
        @author humkyung
314
        @date   2018.06.18
315
    '''
316

    
317
    @property
318
    def colors(self):
319
        import random
320

    
321
        if self._colors is None or self._colors == []:
322
            self._colors = []
323
            with self.project.database.connect() as conn:
324
                try:
325
                    cursor = conn.cursor()
326
                    sql = 'SELECT UID,RED,GREEN,BLUE FROM Colors'
327
                    cursor.execute(sql)
328
                    rows = cursor.fetchall()
329
                    for row in rows:
330
                        self._colors.append(Color(int(row[0]), int(row[1]), int(row[2]), int(row[3])))
331
                # Catch the exception
332
                except Exception as ex:
333
                    from App import App
334
                    message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
335
                                                                  sys.exc_info()[-1].tb_lineno)
336
                    App.mainWnd().addMessage.emit(MessageType.Error, message)
337

    
338
        return self._colors.pop(random.randrange(0, len(self._colors)))
339

    
340
    '''
341
        @brief  setter of colors
342
        @author humkyung
343
        @date   2018.06.18
344
    '''
345

    
346
    @colors.setter
347
    def colors(self, value):
348
        self._colors = value
349

    
350
    '''
351
        @brief      set image file path
352
        @author     humkyung
353
        @date       2018.07.30
354
    '''
355

    
356
    def setImgFilePath(self, path):
357
        self._imgFilePath = path
358
        self.imgName = os.path.splitext(os.path.basename(self._imgFilePath))[0]
359

    
360
    @staticmethod
361
    def my_imread(file_path):
362
        """ read a file which's name contains unicode string : ref http://devdoftech.co.kr:82/redmine/issues/631 """
363
        import numpy as np
364
        import cv2
365

    
366
        _bytes = None
367
        with open(file_path.encode('utf-8'), 'rb') as stream:
368
            _bytes = bytearray(stream.read())
369

    
370
        numpyArray = np.asarray(_bytes, dtype=np.uint8)
371
        res = cv2.imdecode(numpyArray, cv2.IMREAD_UNCHANGED)
372
        return res
373

    
374
    @property
375
    def imgSrc(self):
376
        """return the image of active drawing"""
377

    
378
        if self.activeDrawing:
379
            return self.activeDrawing.image
380

    
381
        return None
382

    
383
    @imgSrc.setter
384
    def imgSrc(self, value):
385
        """set the image of active drawing with given value"""
386

    
387
        if self.activeDrawing:
388
            self.activeDrawing.image = value
389

    
390
    '''
391
        @brief  getter of line type configs
392
        @author humkyung
393
        @date   2018.06.28
394
    '''
395

    
396
    @property
397
    def lineTypeConfigs(self):
398
        from PyQt5.QtCore import Qt
399

    
400
        if self._lineTypeConfigs is None:
401
            self._lineTypeConfigs = []
402

    
403
            styleMap = [('SolidLine', Qt.SolidLine), ('DashLine', Qt.DashLine), ('DotLine', Qt.DotLine),
404
                        ('DashDotLine', Qt.DashDotLine),
405
                        ('DashDotDotLine', Qt.DashDotDotLine), ('CustomDashLine', Qt.CustomDashLine)]
406

    
407
            configs = self.getConfigs('LineTypes')
408
            for config in configs:
409
                color, width, _style, transparent = config.value.split(',')
410
                matches = [param for param in styleMap if param[0] == _style]
411
                style = matches[0][1] if matches else Qt.SolidLine
412
                self._lineTypeConfigs.append((config.key, color, int(width), style, float(transparent)))
413

    
414
        return self._lineTypeConfigs
415

    
416
    '''
417
        @brief  setter of line type configs
418
        @author humkyung
419
        @date   2018.06.28
420
    '''
421

    
422
    @lineTypeConfigs.setter
423
    def lineTypeConfigs(self, value):
424
        self._lineTypeConfigs = value
425

    
426
    @property
427
    def drain_size(self):
428
        """ getter of drain_size """
429
        if not hasattr(self, '_drain_size') or not self._drain_size:
430
            configs = self.getConfigs('Drain Size Rule', 'Size')
431
            self._drain_size = configs[0].value if configs else '1"'
432

    
433
        return self._drain_size
434

    
435
    @drain_size.setter
436
    def drain_size(self, value):
437
        """ setter of drain_size """
438
        self._drain_size = value
439

    
440
    '''
441
        @brief      getter of hmb table
442
        @author     humkyung
443
        @date       2018.07.16
444
    '''
445

    
446
    @property
447
    def hmbTable(self):
448
        from HMBTable import HMBTable
449

    
450
        if self._hmbTable is None:
451
            self._hmbTable = HMBTable()
452
            self._hmbTable.loadData()
453

    
454
        return self._hmbTable
455

    
456
    '''
457
        @brief      setter of hmb table
458
        @author     humkyung
459
        @date       2018.07.16
460
    '''
461

    
462
    @hmbTable.setter
463
    def hmbTable(self, value):
464
        self._hmbTable = value
465

    
466
    '''
467
        @brief  get line type config of given line type
468
        @author humkyung
469
        @date   2018.06.28
470
    '''
471

    
472
    def getLineTypeConfig(self, lineType):
473
        from PyQt5.QtCore import Qt
474

    
475
        matches = [config for config in self.lineTypeConfigs if config[0] == lineType]
476
        return matches[0] if matches else (lineType, '#0000FF', 5, Qt.SolidLine, 50)
477

    
478
    def getCurrentPidSource(self):
479
        return self.activeDrawing.currentPidSource
480

    
481
    '''
482
        @brief      Check if exist file name or not
483
        @author     Jeongwoo
484
        @date       2018.05.03
485
    '''
486

    
487
    def isExistFileName(self, name):
488
        rows = None
489
        with self.project.database.connect() as conn:
490
            try:
491
                cursor = conn.cursor()
492
                sql = "SELECT * FROM Symbol WHERE name = '" + name + "'"
493
                cursor.execute(sql)
494
                rows = cursor.fetchall()
495
            # Catch the exception
496
            except Exception as ex:
497
                # Roll back any change if something goes wrong
498
                conn.rollback()
499
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
500
                                                          sys.exc_info()[-1].tb_lineno))
501
            finally:
502
                if rows is not None and len(rows) > 0:
503
                    return True
504
                else:
505
                    return False
506

    
507
    '''
508
        @brief      Insert new symbol into Symbol Table, Moved from SG_DbHelper
509
        @author     Jeongwoo
510
        @date       2018.05.03
511
    '''
512

    
513
    def insertSymbol(self, symbol):
514
        isAdded = False
515
        with self.project.database.connect() as conn:
516
            try:
517
                sql = self.project.database.to_sql("""
518
                    INSERT INTO Symbol(name, SymbolType_UID, threshold, minMatchPoint, isDetectOrigin, rotationCount, ocrOption, isContainChild, originalPoint, connectionPoint, baseSymbol, additionalSymbol, isExceptDetect, hasInstrumentLabel, width, height, flip) 
519
                    VALUES(?, (select UID from SymbolType where Type=?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
520
                """)
521

    
522
                cursor = conn.cursor()
523
                query = (symbol.getName(), symbol.getType(), symbol.getThreshold()
524
                         , symbol.getMinMatchCount(), symbol.getIsDetectOnOrigin(), symbol.getRotationCount()
525
                         , symbol.getOcrOption(), symbol.getIsContainChild()
526
                         , symbol.getOriginalPoint(), symbol.getConnectionPoint()
527
                         , symbol.getBaseSymbol(), symbol.getAdditionalSymbol(), symbol.getIsExceptDetect(),
528
                         symbol.getHasInstrumentLabel()
529
                         , symbol.width, symbol.height, symbol.detectFlip)
530
                cursor.execute(sql, query)
531
                conn.commit()
532
                isAdded = True
533
            # Catch the exception
534
            except Exception as ex:
535
                # Roll back any change if something goes wrong
536
                conn.rollback()
537

    
538
                from App import App
539
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
540
                                                              sys.exc_info()[-1].tb_lineno)
541
                App.mainWnd().addMessage.emit(MessageType.Error, message)
542
            finally:
543
                return (isAdded, symbol.getType(), symbol.getName(), symbol.getPath())
544

    
545
    '''
546
        @brief      Update symbol in Symbol Table, Moved from SG_DbHelper
547
        @author     Jeongwoo
548
        @date       2018.05.03
549
    '''
550

    
551
    def updateSymbol(self, symbol):
552
        isUpdated = False
553

    
554
        with self.project.database.connect() as conn:
555
            try:
556
                sql = self.project.database.to_sql("""
557
                    UPDATE Symbol
558
                    SET
559
                        name = ?, SymbolType_UID=(select UID from SymbolType where Type=?), threshold=?, 
560
                        minMatchPoint=?, isDetectOrigin=?, rotationCount=?, ocrOption=?, isContainChild=?, 
561
                        originalPoint=?, connectionPoint=?, baseSymbol=?, additionalSymbol=?, isExceptDetect=?, 
562
                        hasInstrumentLabel=?, width=?, height=?, flip=?, TextArea=? WHERE uid = ?
563
                """)
564

    
565
                cursor = conn.cursor()
566
                query = (symbol.getName(), symbol.getType(), symbol.getThreshold()
567
                         , symbol.getMinMatchCount(), symbol.getIsDetectOnOrigin(), symbol.getRotationCount()
568
                         , symbol.getOcrOption(), symbol.getIsContainChild()
569
                         , symbol.getOriginalPoint(), symbol.getConnectionPoint()
570
                         , symbol.getBaseSymbol(), symbol.getAdditionalSymbol(), symbol.getIsExceptDetect(),
571
                         symbol.getHasInstrumentLabel(), symbol.width, symbol.height, symbol.detectFlip, symbol.text_area_str,
572
                         symbol.getUid())
573
                cursor.execute(sql, query)
574
                conn.commit()
575
                isUpdated = True
576
            # Catch the exception
577
            except Exception as ex:
578
                # Roll back any change if something goes wrong
579
                conn.rollback()
580

    
581
                from App import App
582
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
583
                                                              sys.exc_info()[-1].tb_lineno)
584
                App.mainWnd().addMessage.emit(MessageType.Error, message)
585
            finally:
586
                self._symbolBase = {}
587
                return (isUpdated, symbol.getType(), symbol.getName(), symbol.getPath())
588

    
589
    '''
590
        @brief      Get Detecting Target Symbol List (Field 'isExceptDetect' == False(0))
591
        @author     Jeongwoo
592
        @date       18.04.24
593
        @history    humkyung 2018.06.28 select symbol order by threshold descending
594
    '''
595

    
596
    def getTargetSymbolList(self):
597
        targetSymbolList = []
598

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

    
617
        return targetSymbolList
618

    
619
    def buildAppDatabase(self):
620
        """build application database"""
621
        path = os.path.join(os.getenv('ALLUSERSPROFILE'), 'Digital PID')
622
        appDatabaseFilePath = os.path.join(path, 'App.db')
623

    
624
        # Creates or opens a file called mydb with a SQLite3 DB
625
        with sqlite3.connect(appDatabaseFilePath) as conn:
626
            try:
627
                # Get a cursor object
628
                cursor = conn.cursor()
629

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

    
649
        # expiration date is 2019-11-9-23-59-59 : e52SoJJRdZ-apJuhlFWtnFWC
650
        # configs = [Config('app', 'error origin point', '51,72'), Config('app', 'expiration', 'e52SoJJRdZ-apJuhlFWtnFWC')]
651

    
652
        configs = self.getAppConfigs('app', 'expiration')
653
        if not configs:
654
            configs = self.getAppConfigs('app', 'license')
655
            if configs and 'DOFTECH' in configs[0].value:
656
                self.deleteAppConfigs('app', 'mode')
657
                configs = None
658
            else:
659
                configs = [Config('app', 'mode', 'advanced')]
660
        else:
661
            configs = None
662

    
663
        if configs:
664
            self.saveAppConfigs(configs)
665

    
666
    '''
667
        @brief  load app style
668
        @author humkyung
669
        @date   2018.04.20
670
    '''
671

    
672
    def loadAppStyle(self):
673
        style = 'Fusion'
674

    
675
        path = os.path.join(os.getenv('ALLUSERSPROFILE'), 'Digital PID')
676
        if not os.path.exists(path): os.makedirs(path)
677

    
678
        self.buildAppDatabase()
679
        try:
680
            appDatabaseFilePath = os.path.join(path, 'App.db')
681
            # Creates or opens a file called mydb with a SQLite3 DB
682
            conn = sqlite3.connect(appDatabaseFilePath)
683
            # Get a cursor object
684
            cursor = conn.cursor()
685

    
686
            sql = "select Value from Configuration where Section='App' and Key='Style'"
687
            cursor.execute(sql)
688
            rows = cursor.fetchall()
689
            style = rows[0][0] if 1 == len(rows) else 'Fusion'
690
        # Catch the exception
691
        except Exception as ex:
692
            # Roll back any change if something goes wrong
693
            conn.rollback()
694
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
695
                                                      sys.exc_info()[-1].tb_lineno))
696
        finally:
697
            # Close the db connection
698
            conn.close()
699

    
700
        return style
701

    
702
    '''
703
        @brief  load app styles and then return a list
704
        @author humkyung
705
        @date   2018.04.20
706
    '''
707

    
708
    def loadAppStyles(self):
709
        styles = []
710

    
711
        try:
712
            self.buildAppDatabase()
713

    
714
            path = os.path.join(os.getenv('ALLUSERSPROFILE'), 'Digital PID')
715
            appDatabaseFilePath = os.path.join(path, 'App.db')
716

    
717
            # Creates or opens a file called mydb with a SQLite3 DB
718
            conn = sqlite3.connect(appDatabaseFilePath)
719
            # Get a cursor object
720
            cursor = conn.cursor()
721

    
722
            sql = 'select UID,Value from Styles'
723
            cursor.execute(sql)
724
            rows = cursor.fetchall()
725
            for row in rows: styles.append(row[1])
726
            if 0 == len(rows): rows.append('fusion')
727
        # Catch the exception
728
        except Exception as ex:
729
            # Roll back any change if something goes wrong
730
            conn.rollback()
731
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
732
                                                      sys.exc_info()[-1].tb_lineno))
733
        finally:
734
            # Close the db connection
735
            conn.close()
736

    
737
        return styles
738

    
739
    '''
740
        @brief  Set current Project
741
        @history    2018.06.27  Jeongwoo    If DB file is not, copy DB file from ProgramData
742
    '''
743

    
744
    def setCurrentProject(self, project):
745
        self.project = project
746
        project.make_sub_directories()
747
        try:
748
            if self.project.database.db_type == 'SQLite':
749
                # Creates or opens a file called mydb with a SQLite3 DB
750
                db_path = self.project.database.file_path
751

    
752
                if not os.path.isfile(db_path):
753
                    templatePath = self.getTemplateDbPath()
754
                    templateFile = QFile(templatePath)
755
                    templateFile.copy(db_path)
756

    
757
                try:
758
                    conn = self.project.database.connect()
759
                    with conn:
760
                        # Get a cursor object
761
                        cursor = conn.cursor()
762

    
763
                        fileNames = os.listdir(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'Scripts'))
764
                        for fileName in fileNames:
765
                            if fileName.endswith(".sql") and ('SQLite_Project' == os.path.splitext(fileName)[0].split('.')[0]):
766
                                try:
767
                                    file = QFile(
768
                                        os.path.join(os.path.dirname(os.path.realpath(__file__)), 'Scripts', fileName))
769
                                    file.open(QFile.ReadOnly)
770
                                    sql = file.readAll()
771
                                    sql = str(sql, encoding='utf8')
772
                                    cursor.executescript(sql)
773
                                finally:
774
                                    file.close()
775
                        conn.commit()
776
                        self.saveConfigs([Config('Project', 'Unit', project.prj_unit)])
777
                except Exception as ex:
778
                    print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
779
                                                              sys.exc_info()[-1].tb_lineno))
780
        # Catch the exception
781
        except Exception as ex:
782
            # Roll back any change if something goes wrong
783
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
784
                                                      sys.exc_info()[-1].tb_lineno))
785
        finally:
786
            pass
787

    
788
    '''
789
        @brief  Get current Project
790
    '''
791

    
792
    def getCurrentProject(self):
793
        return self.project
794

    
795
    '''
796
        @brief      return project database path
797
        @history    humkyung 2018.04.19 return Project.db in Program Data folder instead of PROJECT_DB_PATH variable
798
    '''
799

    
800
    def getPrjDatabasePath(self):
801
        path = os.path.join(os.getenv('ALLUSERSPROFILE'), 'Digital PID')
802
        if not os.path.exists(path): os.makedirs(path)
803

    
804
        prjDatabaseFilePath = os.path.join(path, 'Project.db')
805
        try:
806
            # Creates or opens a file called mydb with a SQLite3 DB
807
            conn = sqlite3.connect(prjDatabaseFilePath)
808
            # Get a cursor object
809
            cursor = conn.cursor()
810

    
811
            filePath = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'Scripts', 'Project.Projects.sql')
812
            try:
813
                file = QFile(filePath)
814
                file.open(QFile.ReadOnly)
815
                sql = file.readAll()
816
                sql = str(sql, encoding='utf8')
817
                cursor.executescript(sql)
818
            finally:
819
                file.close()
820
            conn.commit()
821
        # Catch the exception
822
        except Exception as ex:
823
            # Roll back any change if something goes wrong
824
            conn.rollback()
825
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
826
                                                      sys.exc_info()[-1].tb_lineno))
827
        finally:
828
            # Close the db connection
829
            conn.close()
830

    
831
        return prjDatabaseFilePath
832

    
833
    def getErrorItemSvgPath(self):
834
        '''
835
            @brief  return error item svg path
836
            @author euisung
837
            @date   2019.04.02
838
        '''
839
        return os.path.join(os.getenv('ALLUSERSPROFILE'), 'Digital PID', 'Explode.svg')
840

    
841
    def updateTitleBlockProperties(self, titleBlockProps):
842
        '''
843
            @brief  update title block properties
844
            @author euisung
845
            @date   2018.11.09
846
        '''
847
        try:
848
            originTitleBlockProps = self.getTitleBlockProperties()
849
            deletedTitleBlockProps = []
850
            for originTitleBlockProp in originTitleBlockProps:
851
                for titleBlockProp in titleBlockProps:
852
                    # uid compare for determine delete props
853
                    if originTitleBlockProp[0] == titleBlockProp[0]:
854
                        break
855
                deletedTitleBlockProps.append(originTitleBlockProp[0])
856

    
857
            # Creates or opens a file called mydb with a SQLite3 DB
858
            conn = self.project.database.connect()
859
            with conn:
860
                try:
861
                    # Get a cursor object
862
                    cursor = conn.cursor()
863

    
864
                    for deletedTitleBlockProp in deletedTitleBlockProps:
865
                        sql = "delete from TitleBlockValues where TitleBlockProperties_UID='{}'".format(deletedTitleBlockProp)
866
                        cursor.execute(sql)
867
                        sql = "delete from TitleBlockProperties where UID='{}'".format(deletedTitleBlockProp)
868
                        cursor.execute(sql)
869

    
870
                    for titleBlockProp in titleBlockProps:
871
                        sql = self.project.database.to_sql("insert into [TitleBlockProperties]([UID], [NAME], [AREA], [TEXT]) values(?,?,?,?)")
872
                        param = (titleBlockProp[0], titleBlockProp[1], titleBlockProp[2], titleBlockProp[3])  # uid, name, area, text
873
                        cursor.execute(sql, param)
874
                    conn.commit()
875
                    # Catch the exception
876
                except Exception as ex:
877
                    # Roll back any change if something goes wrong
878
                    conn.rollback()
879
                    from App import App
880
                    from AppDocData import MessageType
881
                    message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
882
                                                                   sys.exc_info()[-1].tb_lineno)
883
                    App.mainWnd().addMessage.emit(MessageType.Error, message)
884
        # Catch the exception
885
        except Exception as ex:
886
            from App import App
887
            from AppDocData import MessageType
888
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
889
                                                           sys.exc_info()[-1].tb_lineno)
890
            App.mainWnd().addMessage.emit(MessageType.Error, message)
891

    
892
        self._titleBlockProperties = None
893

    
894
    def getTitleBlockProperties(self):
895
        """"return title block properties"""
896

    
897
        res = None
898
        if self._titleBlockProperties is None:
899
            self._titleBlockProperties = []
900

    
901
            # Creates or opens a file called mydb with a SQLite3 DB
902
            conn = self.project.database.connect()
903
            with conn:
904
                try:
905
                    # Get a cursor object
906
                    cursor = conn.cursor()
907

    
908
                    sql = "select UID, Name, AREA, [TEXT] from TitleBlockProperties"
909
                    cursor.execute(sql)
910
                    rows = cursor.fetchall()
911
                    for row in rows:
912
                        attr = []
913
                        attr.append(row[0])  # uid
914
                        attr.append(row[1])  # name
915
                        attr.append(row[2])  # area
916
                        attr.append(row[3])  # text
917
                        self._titleBlockProperties.append(attr)
918

    
919
                    res = self._titleBlockProperties
920
                # Catch the exception
921
                except Exception as ex:
922
                    print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
923
                                                              sys.exc_info()[-1].tb_lineno))
924
        else:
925
            res = self._titleBlockProperties
926

    
927
        return res
928

    
929
    def clearLineNoProperties(self):
930
        self._lineNoProperties = None
931
        self._lineNoPropertiesUID = {}
932

    
933
    def getLineProperties(self):
934
        """return line no properties"""
935
        from SymbolAttr import SymbolAttr
936

    
937
        res = None
938
        if self._lineNoProperties is None:
939
            self._lineNoProperties = []
940

    
941
            with self.project.database.connect() as conn:
942
                try:
943
                    # Get a cursor object
944
                    cursor = conn.cursor()
945

    
946
                    sql = "select UID, Name, DisplayName, Type, LimitNumber, [index] from LineProperties " \
947
                          "order by [index]"
948
                    cursor.execute(sql)
949
                    rows = cursor.fetchall()
950
                    for row in rows:
951
                        attr = SymbolAttr()
952
                        attr.UID = row[0]
953
                        attr.Attribute = row[1]
954
                        attr.DisplayAttribute = row[2]
955
                        attr.AttributeType = row[3]
956
                        attr.Length = row[4]
957
                        attr.IsProp = 5
958
                        self._lineNoProperties.append(attr)
959

    
960
                    res = self._lineNoProperties
961
                # Catch the exception
962
                except Exception as ex:
963
                    print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
964
                                                              sys.exc_info()[-1].tb_lineno))
965
        else:
966
            res = self._lineNoProperties
967

    
968
        return res
969

    
970
    def get_equipment_attributes(self):
971
        """ return equipment attributes """
972

    
973
        from SymbolAttr import SymbolAttr
974

    
975
        res = None
976
        if not hasattr(self, '_equipment_attributes'):
977
            self._equipment_attributes = []
978

    
979
            with self.project.database.connect() as conn:
980
                try:
981
                    # Get a cursor object
982
                    cursor = conn.cursor()
983

    
984
                    sql = "select distinct A.Attribute from SymbolAttribute A join SymbolType B on " \
985
                          "A.SymbolType_UID=B.UID where B.Category = 'Equipment'"
986
                    cursor.execute(sql)
987
                    rows = cursor.fetchall()
988
                    for row in rows:
989
                        attr = SymbolAttr()
990
                        attr.Attribute = row[0]
991
                        self._equipment_attributes.append(attr)
992

    
993
                    res = self._equipment_attributes
994
                # Catch the exception
995
                except Exception as ex:
996
                    print('error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
997
                                                               sys.exc_info()[-1].tb_lineno))
998
        else:
999
            res = self._equipment_attributes
1000

    
1001
        return res
1002

    
1003
    '''
1004
        @brief  return line properties
1005
        @author humkyung
1006
        @date   2018.04.09
1007
    '''
1008

    
1009
    def getLinePropertiesByUID(self, UID):
1010
        from SymbolAttr import SymbolAttr
1011

    
1012
        res = []
1013
        if UID in self._lineNoPropertiesUID:
1014
            res = self._lineNoPropertiesUID[UID]
1015
            return res
1016

    
1017
        with self.project.database.connect() as conn:
1018
            try:
1019
                # Get a cursor object
1020
                cursor = conn.cursor()
1021

    
1022
                sql = f"select UID, Name, DisplayName, Type, LimitNumber, [index] from LineProperties where " \
1023
                      f"uid = '{UID}'"
1024
                cursor.execute(sql)
1025
                rows = cursor.fetchall()
1026
                for row in rows:
1027
                    attr = SymbolAttr()
1028
                    attr.UID = row[0]
1029
                    attr.Attribute = row[1]
1030
                    attr.DisplayAttribute = row[2]
1031
                    attr.AttributeType = row[3]
1032
                    attr.Length = row[4]
1033
                    attr.IsProp = 5
1034
                    res.append(attr)
1035
                self._lineNoPropertiesUID[UID] = res
1036
            # Catch the exception
1037
            except Exception as ex:
1038
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1039
                                                          sys.exc_info()[-1].tb_lineno))
1040

    
1041
        return res
1042

    
1043
    '''
1044
        @brief  return line types 
1045
        @author humkyung
1046
        @date   2018.06.27
1047
    '''
1048

    
1049
    def getLineTypes(self):
1050
        from LineTypeConditions import LineTypeConditions
1051

    
1052
        res = []
1053
        conn = self.project.database.connect()
1054
        with conn:
1055
            try:
1056
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
1057
                sql = "select UID,Name,Type1,Conditions1,Type2,Conditions2 from LineTypes order by Name"
1058
                cursor.execute(sql)
1059
                rows = cursor.fetchall()
1060
                for row in rows:
1061
                    line_type = LineTypeConditions(row['UID'], row['Name'])
1062
                    line_type._conditions[0][0] = row['Type1']
1063
                    line_type._conditions[0][1] = row['Conditions1']
1064
                    line_type._conditions[1][0] = row['Type2']
1065
                    line_type._conditions[1][1] = row['Conditions2']
1066
                    res.append(line_type)
1067
            # Catch the exception
1068
            except Exception as ex:
1069
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1070
                                                          sys.exc_info()[-1].tb_lineno))
1071

    
1072
        return res
1073

    
1074
    '''
1075
        @brief      Insert New Project Info
1076
        @author     Jeongwoo
1077
        @date       2018.04.06
1078
        @history    humkyung 2018.04.19 use getPrjDatabasePath function instead of PROJECT_DB_PATH variable
1079
    '''
1080

    
1081
    def insertProjectInfo(self, desc, prj_unit, dir):
1082
        prjDatabaseFilePath = self.getPrjDatabasePath()
1083
        conn = sqlite3.connect(prjDatabaseFilePath)
1084
        with conn:
1085
            try:
1086
                folderName = dir.split('/')[-1]
1087
                if folderName:
1088
                    nowDate = datetime.datetime.now().strftime('%Y.%m.%d %H:%M')
1089
                    sql = "insert or replace into Projects(Name, [Desc], [Unit], Path, CreatedDate, UpdatedDate) values(?, ?, ?, ?, ?, ?)"
1090
                    param = (folderName, desc, prj_unit, dir, nowDate, nowDate)
1091

    
1092
                    cursor = conn.cursor()
1093
                    cursor.execute(sql, param)
1094
                    conn.commit()
1095
                else:
1096
                    print("Empty folder name")
1097
            except Exception as ex:
1098
                # Roll back any change if something goes wrong
1099
                conn.rollback()
1100
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1101
                                                          sys.exc_info()[-1].tb_lineno))
1102

    
1103
    def removeProjectInfo(self, targetProject):
1104
        '''
1105
        @brief      Remove Project Info
1106
        @author     Euisung
1107
        @date       2019.01.28
1108
        '''
1109
        prjDatabaseFilePath = self.getPrjDatabasePath()
1110
        conn = sqlite3.connect(prjDatabaseFilePath)
1111
        with conn:
1112
            try:
1113
                sql = "delete from Projects where Id = '{}'".format(targetProject.id)
1114
                cur = conn.cursor()
1115
                cur.execute(sql)
1116
                conn.commit()
1117
            except Exception as ex:
1118
                # Roll back any change if something goes wrong
1119
                conn.rollback()
1120
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1121
                                                          sys.exc_info()[-1].tb_lineno))
1122

    
1123
    '''
1124
        @brief      update project
1125
        @author     Jeongwoo
1126
        @date       2018.04.06
1127
        @history    humkyung 2018.04.19 use getPrjDatabasePath function instead of PROJECT_DB_PATH variable
1128
    '''
1129

    
1130
    def updateProjectUpdatedDate(self, project):
1131
        prjDatabaseFilePath = self.getPrjDatabasePath()
1132
        conn = sqlite3.connect(prjDatabaseFilePath)
1133
        with conn:
1134
            try:
1135
                nowDate = datetime.datetime.now().strftime('%Y.%m.%d %H:%M')
1136
                sql = '''
1137
                    UPDATE Projects
1138
                    SET UpdatedDate = ?,[Desc]=?,[Unit]=? 
1139
                    WHERE Id = ?
1140
                '''
1141
                cur = conn.cursor()
1142
                cur.execute(sql, (nowDate, project.desc, project.prj_unit, project.getId()))
1143

    
1144
                sql = 'insert or replace into DBSettings(Projects_UID, DBTypes_UID, Host, User, Password, FilePath) values(?,(select UID from DBTypes where Name=?),?,?,?,?)'
1145
                cur = conn.cursor()
1146
                cur.execute(sql, (
1147
                    project.getId(), project.database.db_type, project.database.host, project.database.user,
1148
                    project.database.password, project.database.file_path))
1149
                conn.commit()
1150
            except Exception as ex:
1151
                # Roll back any change if something goes wrong
1152
                conn.rollback()
1153
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1154
                                                          sys.exc_info()[-1].tb_lineno))
1155

    
1156
    '''
1157
        @brief  get project list from database
1158
        @history    humkyung 2018.04.18 add only project which's project exists
1159
    '''
1160

    
1161
    def getProjectList(self):
1162
        from Project import Project
1163

    
1164
        projectList = []
1165

    
1166
        conn = sqlite3.connect(self.getPrjDatabasePath())
1167
        with conn:
1168
            conn.row_factory = sqlite3.Row
1169
            cursor = conn.cursor()
1170
            sql = "select a.Id,a.Name,a.[Desc],a.[Unit],a.Path,a.CreatedDate,a.UpdatedDate,\
1171
                (select \
1172
                CASE \
1173
                WHEN b.DBTypes_UID is NULL THEN 'SQLite' \
1174
                ELSE (select Name from DBTypes where UID=b.DBTypes_UID) \
1175
                END \
1176
                ) DBType,b.Host,b.User,b.Password \
1177
                from projects a left join dbsettings b on a.Id=b.Projects_UID order by strftime(a.UpdatedDate) desc"
1178
            try:
1179
                cursor.execute(sql)
1180
                rows = cursor.fetchall()
1181
                for row in rows:
1182
                    if os.path.isdir(row['Path']):  # check if folder exists
1183
                        projectList.append(Project(row))
1184
            except Exception as ex:
1185
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1186
                                                          sys.exc_info()[-1].tb_lineno))
1187

    
1188
        return projectList
1189

    
1190
    '''
1191
        @brief  get sliding window size
1192
        @author humkyung
1193
    '''
1194

    
1195
    def getSlidingWindowSize(self):
1196
        res = [25, 20]
1197
        try:
1198
            configs = self.getConfigs('Sliding Window')
1199
            for config in configs:
1200
                if config.key == 'Width':
1201
                    res[0] = int(config.value)
1202
                elif config.key == 'Height':
1203
                    res[1] = int(config.value)
1204
        # Catch the exception
1205
        except Exception as ex:
1206
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1207
                                                      sys.exc_info()[-1].tb_lineno))
1208

    
1209
        return res
1210

    
1211
    '''
1212
        @brief  get line no configuration
1213
        @author humkyung
1214
        @date   2018.04.16
1215
    '''
1216

    
1217
    def getLineNoConfiguration(self):
1218
        res = None
1219

    
1220
        conn = self.project.database.connect()
1221
        with conn:
1222
            try:
1223
                # Get a cursor object
1224
                cursor = conn.cursor()
1225

    
1226
                delimiter = None
1227
                sql = "select * from configuration where section='Line No' and key='Delimiter"
1228
                cursor.execute(sql)
1229
                rows = cursor.fetchall()
1230
                if len(rows) == 1:
1231
                    delimiter = rows[0][2]
1232

    
1233
                if delimiter is not None:
1234
                    sql = "select * from configuration where section='Line No' and key='Configuration'"
1235
                    cursor.execute(sql)
1236
                    rows = cursor.fetchall()
1237
                    if len(rows) == 1:
1238
                        res = rows[0][2].split(delimiter)
1239
            # Catch the exception
1240
            except Exception as ex:
1241
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1242
                                                          sys.exc_info()[-1].tb_lineno))
1243

    
1244
        return res
1245

    
1246
    '''
1247
        @brief  get area list
1248
        @author humkyung
1249
        @history    euisung     2018.11.20 (0,0),(0,0) process add
1250
    '''
1251

    
1252
    def getAreaList(self):
1253
        from Area import Area
1254

    
1255
        if len(self._areas) == 0:
1256
            conn = self.project.database.connect()
1257
            with conn:
1258
                try:
1259
                    # Get a cursor object
1260
                    cursor = conn.cursor()
1261

    
1262
                    sql = "select * from configuration where section='Area'"
1263
                    cursor.execute(sql)
1264
                    rows = cursor.fetchall()
1265
                    for row in rows:
1266
                        name = row[1]
1267
                        area = Area(name)
1268
                        area.parse(row[2])
1269
                        self._areas.append(area)
1270
                # Catch the exception
1271
                except Exception as ex:
1272
                    print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1273
                                                              sys.exc_info()[-1].tb_lineno))
1274

    
1275
        return self._areas
1276

    
1277
    '''
1278
        @brief  get area of given name
1279
        @author humkyung
1280
        @date   2018.04.07
1281
    '''
1282

    
1283
    def getArea(self, name):
1284
        areas = self.getAreaList()
1285
        matches = [area for area in areas if area.name == name]
1286
        if 1 == len(matches) and matches[0].height is not 0 and matches[0].width is not 0:
1287
            return matches[0]
1288

    
1289
        return None
1290

    
1291
    def getConfigs(self, section, key=None):
1292
        """ get configurations from database """
1293
        res = []
1294

    
1295
        if self._configs is None:
1296
            self._configs = []
1297
            conn = self.project.database.connect()
1298
            with conn:
1299
                try:
1300
                    # Get a cursor object
1301
                    cursor = conn.cursor()
1302

    
1303
                    sql = "select * from configuration"
1304

    
1305
                    cursor.execute(sql)
1306
                    rows = cursor.fetchall()
1307
                    for row in rows:
1308
                        self._configs.append(Config(row[0], row[1], row[2]))
1309
                # Catch the exception
1310
                except Exception as ex:
1311
                    print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1312
                                                              sys.exc_info()[-1].tb_lineno))
1313

    
1314
        if key is not None:
1315
            return [con for con in self._configs if con.section == section and con.key == key]
1316
        else:
1317
            return [con for con in self._configs if con.section == section]
1318

    
1319
        return res
1320

    
1321
    def getAppConfigs(self, section, key=None):
1322
        """
1323
            @brief  get application configurations
1324
            @author humkyung
1325
            @date   2018.11.01
1326
        """
1327

    
1328
        res = []
1329

    
1330
        # Creates or opens a file called mydb with a SQLite3 DB
1331
        dbPath = self.getAppDbPath()
1332
        conn = sqlite3.connect(dbPath)
1333
        with conn:
1334
            try:
1335
                # Get a cursor object
1336
                cursor = conn.cursor()
1337

    
1338
                if key is not None:
1339
                    sql = "select * from configuration where section=? and key=?"
1340
                    param = (section, key)
1341
                else:
1342
                    sql = "select * from configuration where section=?"
1343
                    param = (section,)
1344

    
1345
                cursor.execute(sql, param)
1346
                rows = cursor.fetchall()
1347
                for row in rows:
1348
                    res.append(Config(row[0], row[1], row[2]))
1349
            # Catch the exception
1350
            except Exception as ex:
1351
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1352
                                                          sys.exc_info()[-1].tb_lineno))
1353

    
1354
        return res
1355

    
1356
    '''
1357
        @brief      save configurations
1358
        @author     humkyung
1359
        @date       2018.04.16
1360
        @history    humkyung 2018.07.03 replace ' with " if value has '
1361
                    kyouho 2018.07.09 change query method
1362
    '''
1363

    
1364
    def saveConfigs(self, configs):
1365
        with self.project.database.connect() as conn:
1366
            try:
1367
                # Get a cursor object
1368
                cursor = conn.cursor()
1369
                if self.project.database.db_type == 'SQLite':
1370
                    cursor.execute('begin')
1371

    
1372
                for config in configs:
1373
                    if type(config) is Config:
1374
                        value = config.value
1375
                        if type(value) is str and "'" in value:
1376
                            value = value.replace("'", "''")
1377

    
1378
                        sql = self.project.database.to_sql(
1379
                            "insert into configuration(Section,[Key],Value) select ?,?,? where not exists(select 1 from configuration where Section=? and [Key]=?)")
1380
                        param = (config.section, config.key, str(value), config.section, config.key)
1381
                        cursor.execute(sql, param)
1382
                        sql = self.project.database.to_sql(
1383
                            "update configuration set Value=? where Section=? and [Key]=?")
1384
                        param = (str(value), config.section, config.key)
1385
                        cursor.execute(sql, param)
1386
                    elif hasattr(config, 'toSql'):
1387
                        sql = config.toSql()
1388
                        if type(sql) is list:
1389
                            for item in sql:
1390
                                if item is not None and 2 == len(item):
1391
                                    cursor.execute(self.project.database.to_sql(item[0]), item[1])
1392
                        else:
1393
                            if sql is not None and 2 == len(sql):
1394
                                cursor.execute(self.project.database.to_sql(sql[0]), sql[1])
1395
                self._configs = None  # reset config table
1396

    
1397
                if self.project.database.db_type == 'SQLite':
1398
                    cursor.execute('commit')
1399
                else:
1400
                    conn.commit()
1401
            # Catch the exception
1402
            except Exception as ex:
1403
                # Roll back any change if something goes wrong
1404
                conn.rollback()
1405

    
1406
                from App import App
1407
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1408
                                                              sys.exc_info()[-1].tb_lineno)
1409
                App.mainWnd().addMessage.emit(MessageType.Error, message)
1410

    
1411
    def saveAppConfigs(self, configs):
1412
        """save application configurations"""
1413

    
1414
        # Creates or opens a file called mydb with a SQLite3 DB
1415
        dbPath = self.getAppDbPath()
1416
        with sqlite3.connect(dbPath) as conn:
1417
            try:
1418
                # Get a cursor object
1419
                cursor = conn.cursor()
1420

    
1421
                for config in configs:
1422
                    value = config.value
1423
                    if type(value) is str and "'" in value:
1424
                        value = value.replace("'", "''")
1425

    
1426
                    sql = "insert or replace into configuration values(?,?,?)"
1427
                    param = (config.section, config.key, value)
1428

    
1429
                    cursor.execute(sql, param)
1430
                conn.commit()
1431
            # Catch the exception
1432
            except Exception as ex:
1433
                # Roll back any change if something goes wrong
1434
                conn.rollback()
1435
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1436
                                                          sys.exc_info()[-1].tb_lineno))
1437

    
1438
    '''
1439
        @brief  delete configurations
1440
        @author humkyung
1441
        @date   2018.06.29
1442
    '''
1443

    
1444
    def deleteConfigs(self, section, key=None):
1445
        conn = self.project.database.connect()
1446
        with conn:
1447
            try:
1448
                # Get a cursor object
1449
                cursor = conn.cursor()
1450

    
1451
                if key is not None:
1452
                    sql = "delete from configuration where section='{}' and key='{}'".format(section, key)
1453
                else:
1454
                    sql = "delete from configuration where section='{}'".format(section)
1455
                cursor.execute(sql)
1456

    
1457
                conn.commit()
1458
            # Catch the exception
1459
            except Exception as ex:
1460
                # Roll back any change if something goes wrong
1461
                conn.rollback()
1462
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1463
                                                          sys.exc_info()[-1].tb_lineno))
1464

    
1465
    def deleteAppConfigs(self, section, key=None):
1466
        """
1467
        @brief  delete application configurations
1468
        @author humkyung
1469
        @date   2018.11.01
1470
        """
1471

    
1472
        # Creates or opens a file called mydb with a SQLite3 DB
1473
        dbPath = self.getAppDbPath()
1474
        conn = sqlite3.connect(dbPath)
1475
        with conn:
1476
            try:
1477
                # Get a cursor object
1478
                cursor = conn.cursor()
1479

    
1480
                if key is not None:
1481
                    sql = "delete from configuration where section='{}' and key='{}'".format(section, key)
1482
                else:
1483
                    sql = "delete from configuration where section='{}'".format(section)
1484
                cursor.execute(sql)
1485

    
1486
                conn.commit()
1487
            # Catch the exception
1488
            except Exception as ex:
1489
                # Roll back any change if something goes wrong
1490
                conn.rollback()
1491
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1492
                                                          sys.exc_info()[-1].tb_lineno))
1493

    
1494
    '''
1495
        @brief      set area list
1496
        @history    humkyung 2018.05.18 round area coordinate and dimension before saving
1497
        @history    euisung  2018.11.20 add self._area reset process
1498
    '''
1499

    
1500
    def setAreaList(self, areas):
1501
        for area in areas:
1502
            matches = [x for x in self._areas if x.name == area.name]
1503
            if 1 == len(matches):
1504
                matches[0].x = area.x
1505
                matches[0].y = area.y
1506
                matches[0].width = area.width
1507
                matches[0].height = area.height
1508
            elif 0 == len(matches):
1509
                self._areas.append(area)
1510

    
1511
        # Creates or opens a file called mydb with a SQLite3 DB
1512
        conn = self.project.database.connect()
1513
        with conn:
1514
            try:
1515
                # Get a cursor object
1516
                cursor = conn.cursor()
1517

    
1518
                for area in self._areas:
1519
                    sql = "insert into configuration select 'Area','{}','({},{}),({},{})' where not exists(select 1 from configuration where Section='Area' and [Key]='{}')".format(
1520
                        area.name, round(area.x), round(area.y), round(area.width), round(area.height), area.name)
1521
                    cursor.execute(sql)
1522
                    sql = "update configuration set Value='({},{}),({},{})' where Section='Area' and [Key]='{}'".format(
1523
                        round(area.x), round(area.y), round(area.width), round(area.height), area.name)
1524
                    cursor.execute(sql)
1525
                conn.commit()
1526
            # Catch the exception
1527
            except Exception as ex:
1528
                # Roll back any change if something goes wrong
1529
                conn.rollback()
1530

    
1531
                from App import App
1532
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1533
                                                              sys.exc_info()[-1].tb_lineno)
1534
                App.mainWnd().addMessage.emit(MessageType.Error, message)
1535
            finally:
1536
                # Close the db connection
1537
                self._areas = []
1538

    
1539
    def getSymbolNameList(self):
1540
        """ get symbol name list """
1541
        symbolNametList = []
1542

    
1543
        conn = self.project.database.connect()
1544
        with conn:
1545
            cursor = conn.cursor()
1546
            sql = 'SELECT * FROM SymbolName'
1547
            try:
1548
                cursor.execute(sql)
1549
                rows = cursor.fetchall()
1550
                for row in rows:
1551
                    symbolNametList.append(row[4])  # Name String
1552
            except Exception as ex:
1553
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1554
                                                          sys.exc_info()[-1].tb_lineno))
1555

    
1556
        return symbolNametList
1557

    
1558
    '''
1559
        @brief      get symbol name list by symbol Type
1560
        @author     Jeongwoo
1561
        @date       18.04.06
1562
        @history    .
1563
    '''
1564

    
1565
    def getSymbolNameListByType(self, type):
1566
        symbolNametList = []
1567

    
1568
        conn = self.project.database.connect()
1569
        with conn:
1570
            cursor = conn.cursor()
1571
            sql = ''
1572
            if type is not None:
1573
                sql = self.project.database.to_sql('SELECT * FROM SymbolName WHERE [Type]=?')
1574
                try:
1575
                    cursor.execute(sql, (type,))
1576
                    rows = cursor.fetchall()
1577
                    for row in rows:
1578
                        symbolNametList.append(row[4])  # Name String
1579
                except Exception as ex:
1580
                    print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1581
                                                              sys.exc_info()[-1].tb_lineno))
1582

    
1583
        return symbolNametList
1584

    
1585
    '''
1586
        @brief  delete added symbol data
1587
    '''
1588

    
1589
    def deleteSymbol(self, fileName):
1590
        ret = False
1591

    
1592
        conn = self.project.database.connect()
1593
        with conn:
1594
            try:
1595
                cursor = conn.cursor()
1596
                sql = self.project.database.to_sql("DELETE FROM Symbol WHERE name = ?")
1597
                try:
1598
                    cursor.execute(sql, (fileName,))
1599
                    conn.commit()
1600
                    ret = True
1601
                except Exception as ex:
1602
                    conn.rollback()
1603
                    print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1604
                                                              sys.exc_info()[-1].tb_lineno))
1605
                    ret = False
1606
            finally:
1607
                self._symbolBase = {}
1608
                return (ret, fileName)
1609

    
1610
    '''
1611
        @brief  get symbol name
1612
        @history    18.04.24    Jeongwoo    Add isExceptDetect Field
1613
    '''
1614

    
1615
    def getSymbolByQuery(self, fieldName, param):
1616
        ret = None
1617

    
1618
        if fieldName in self._symbolBase:
1619
            if param in self._symbolBase[fieldName]:
1620
                ret = self._symbolBase[fieldName][param]
1621
                return ret
1622
        else:
1623
            self._symbolBase[fieldName] = {}
1624

    
1625
        with self.project.database.connect() as conn:
1626
            cursor = conn.cursor()
1627
            sql = self.project.database.to_sql(f"SELECT a.UID,a.Name,b.Type,a.Threshold,a.MinMatchPoint,"
1628
                                               f"a.IsDetectOrigin,a.RotationCount,a.OCROption,a.IsContainChild,"
1629
                                               f"a.OriginalPoint,a.ConnectionPoint,a.BaseSymbol,a.AdditionalSymbol,"
1630
                                               f"a.IsExceptDetect,a.HasInstrumentLabel,a.flip,a.TextArea,b.UID FROM "
1631
                                               f"Symbol a inner join SymbolType b on a.SymbolType_UID=b.UID WHERE "
1632
                                               f"a.{fieldName}=?")
1633
            try:
1634
                cursor.execute(sql, (param,))
1635
                rows = cursor.fetchall()
1636
                if rows is not None and len(rows) > 0:
1637
                    symbolTuple = rows[0]
1638
                    ret = symbol.SymbolBase(symbolTuple[1], symbolTuple[2], symbolTuple[3]
1639
                                            , symbolTuple[4], symbolTuple[5], symbolTuple[6], symbolTuple[7],
1640
                                            symbolTuple[8]
1641
                                            , symbolTuple[9], symbolTuple[10], symbolTuple[11], symbolTuple[12],
1642
                                            symbolTuple[13], symbolTuple[14], symbolTuple[0], iType=symbolTuple[17],
1643
                                            detectFlip=symbolTuple[15], text_area=symbolTuple[16])  ## uid is last item
1644
                    self._symbolBase[fieldName][param] = ret
1645
            except Exception as ex:
1646
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1647
                                                          sys.exc_info()[-1].tb_lineno))
1648

    
1649
        return ret
1650

    
1651
    '''
1652
        @brief  get symbol name list
1653
        @history    18.04.24    Jeongwoo    Add isExceptDetect Field
1654
    '''
1655

    
1656
    def getSymbolListByType(self, field_name=None, param=None):
1657
        ret = []
1658

    
1659
        with self.project.database.connect() as conn:
1660
            cursor = conn.cursor()
1661
            if field_name is not None and param is not None:
1662
                sql = """SELECT a.UID,a.Name,b.Type,a.Threshold,a.MinMatchPoint,a.IsDetectOrigin,a.RotationCount,
1663
                a.OCROption,a.IsContainChild,a.OriginalPoint,a.ConnectionPoint,a.BaseSymbol,a.AdditionalSymbol,
1664
                a.IsExceptDetect,a.HasInstrumentLabel,a.flip,a.TextArea,b.UID FROM Symbol a 
1665
                inner join SymbolType b on a.SymbolType_UID=b.UID WHERE 
1666
                SymbolType_UID = (select UID from SymbolType where {}={})""".format(
1667
                    field_name, self.project.database.place_holder)
1668
            else:
1669
                sql = """SELECT a.UID,a.Name,b.Type,a.Threshold,a.MinMatchPoint,a.IsDetectOrigin,a.RotationCount, 
1670
                a.OCROption,a.IsContainChild,a.OriginalPoint,a.ConnectionPoint,a.BaseSymbol,a.AdditionalSymbol,
1671
                a.IsExceptDetect,a.HasInstrumentLabel,a.flip FROM Symbol a 
1672
                inner join SymbolType b on a.SymbolType_UID=b.UID"""
1673
            try:
1674
                cursor.execute(sql, (param,)) if param is not None else cursor.execute(sql)
1675
                rows = cursor.fetchall()
1676
                if rows is not None and len(rows) > 0:
1677
                    for symbolTuple in rows:
1678
                        sym = symbol.SymbolBase(symbolTuple[1], symbolTuple[2], symbolTuple[3], symbolTuple[4]
1679
                                                , symbolTuple[5], symbolTuple[6], symbolTuple[7], symbolTuple[8],
1680
                                                symbolTuple[9]
1681
                                                , symbolTuple[10], symbolTuple[11], symbolTuple[12], symbolTuple[13],
1682
                                                symbolTuple[14], symbolTuple[0], iType=symbolTuple[17],
1683
                                                detectFlip=symbolTuple[15], text_area=symbolTuple[16])  ## uid is last item
1684
                        ret.append(sym)
1685
            except Exception as ex:
1686
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1687
                                                          sys.exc_info()[-1].tb_lineno))
1688

    
1689
        return ret
1690

    
1691
    '''
1692
        @brief      get NominalDiameter
1693
        @author     humkyung
1694
        @date       2018.04.20
1695
        @history    humkyung 2018.04.24 read MetricStr column and set size unit
1696
                    kyouho 2018.07.04 forCheckLineNumber get only inch or metric
1697
                    kyouho 2018.07.16 edit query order by code
1698
    '''
1699

    
1700
    def getNomialPipeSizeData(self, forCheckLineNumber=False, orderStr="MetricStr"):
1701
        res = []
1702
        configs = self.getConfigs('Line No', 'Size Unit')
1703
        sizeUnit = configs[0].value if 1 == len(configs) else 'Metric'
1704

    
1705
        conn = self.project.database.connect()
1706
        with conn:
1707
            try:
1708
                # Get a cursor object
1709
                cursor = conn.cursor()
1710

    
1711
                sql = "select UID,Code,Metric,Inch,InchStr,AllowableInchStr,MetricStr,AllowableMetricStr from NominalDiameter ORDER BY {} DESC".format(
1712
                    orderStr)
1713
                cursor.execute(sql)
1714
                rows = cursor.fetchall()
1715
                for row in rows:
1716
                    pipeSize = NominalPipeSize(row[0], row[1], float(row[2]) if row[2] else None,
1717
                                               float(row[3]) if row[3] else None, row[4], row[5], row[6], row[7])
1718
                    pipeSize.sizeUnit = sizeUnit
1719
                    if forCheckLineNumber:
1720
                        if sizeUnit == 'Inch' and pipeSize.inchStr:
1721
                            res.append(pipeSize.inchStr)
1722
                        elif sizeUnit == 'Metric' and pipeSize.metricStr:
1723
                            res.append(pipeSize.metricStr)
1724
                    else:
1725
                        res.append(pipeSize)
1726

    
1727
                if 'Inch' in sizeUnit:
1728
                    res = sorted(res, key=lambda param:len(param.inchStr), reverse=True)
1729
                else:
1730
                    res = sorted(res, key=lambda param:len(param.metricStr), reverse=True)
1731
            # Catch the exception
1732
            except Exception as ex:
1733
                from App import App
1734
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1735
                                                              sys.exc_info()[-1].tb_lineno)
1736
                App.mainWnd().addMessage.emit(MessageType.Error, message)
1737

    
1738
        return res
1739

    
1740
    '''
1741
        @brief      insert NominalDiameter table
1742
        @author     kyouho
1743
        @date       2018.07.16
1744
    '''
1745

    
1746
    def insertNomialPipeSize(self, pipeSizes):
1747
        conn = self.project.database.connect()
1748
        with conn:
1749
            try:
1750
                # Get a cursor object
1751
                cursor = conn.cursor()
1752
                for pipeSize in pipeSizes:
1753
                    sql = pipeSize.toSql()
1754
                    if type(sql) is list and len(sql) == 1:
1755
                        cursor.execute(self.project.database.to_sql(sql[0][0]), sql[0][1])
1756

    
1757
                conn.commit()
1758
            # Catch the exception
1759
            except Exception as ex:
1760
                # Roll back any change if something goes wrong
1761
                conn.rollback()
1762

    
1763
                from App import App
1764
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1765
                                                              sys.exc_info()[-1].tb_lineno)
1766
                App.mainWnd().addMessage.emit(MessageType.Error, message)
1767

    
1768
    '''
1769
        @brief      delete NominalDiameter table
1770
        @author     kyouho
1771
        @date       2018.07.16
1772
    '''
1773

    
1774
    def deleteNomialPipeSize(self):
1775
        conn = self.project.database.connect()
1776
        with conn:
1777
            cursor = conn.cursor()
1778
            sql = "DELETE FROM NominalDiameter"
1779
            try:
1780
                cursor.execute(sql)
1781
                conn.commit()
1782
            except Exception as ex:
1783
                conn.rollback()
1784
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1785
                                                          sys.exc_info()[-1].tb_lineno))
1786

    
1787
    '''
1788
        @brief      convert inch to metric
1789
        @author     kyouho
1790
        @date       2018.07.09
1791
    '''
1792

    
1793
    def convertInchToMetric(self, inch):
1794
        result = ''
1795
        conn = self.project.database.connect()
1796
        with conn:
1797
            try:
1798
                # Get a cursor object
1799
                cursor = conn.cursor()
1800

    
1801
                sql = "select MetricStr from NominalDiameter WHERE InchStr = ?"
1802
                param = (inch,)
1803
                cursor.execute(sql, param)
1804
                rows = cursor.fetchall()
1805

    
1806
                if rows:
1807
                    result = rows[0][0]
1808
                # Catch the exception
1809
            except Exception as ex:
1810
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1811
                                                          sys.exc_info()[-1].tb_lineno))
1812

    
1813
        return result
1814

    
1815
    '''
1816
        @brief      get Color MaxUID
1817
        @author     kyouho
1818
        @date       2018.07.03
1819
    '''
1820

    
1821
    def getMaxColorUID(self):
1822
        result = 0
1823

    
1824
        conn = self.project.database.connect()
1825
        with conn:
1826
            try:
1827
                # Get a cursor object
1828
                cursor = conn.cursor()
1829

    
1830
                sql = "select MAX(UID) from Colors"
1831
                cursor.execute(sql)
1832
                rows = cursor.fetchall()
1833

    
1834
                result = rows[0][0]
1835
                # Catch the exception
1836
            except Exception as ex:
1837
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1838
                                                          sys.exc_info()[-1].tb_lineno))
1839

    
1840
        return result
1841

    
1842
    '''
1843
        @brief      insert Color property
1844
        @author     kyouho
1845
        @date       2018.07.09
1846
    '''
1847

    
1848
    def setPropertyColor(self, _color):
1849
        conn = self.project.database.connect()
1850
        with conn:
1851
            try:
1852
                # Get a cursor object
1853
                cursor = conn.cursor()
1854
                sql = "INSERT INTO Colors(UID, RED, GREEN, BLUE, PROPERTY, VALUE) VALUES(?,?,?,?,?,?)"
1855
                param = (_color.index, _color.red, _color.green, _color.blue, _color._property, _color.value)
1856
                cursor.execute(sql, param)
1857
                conn.commit()
1858
            # Catch the exception
1859
            except Exception as ex:
1860
                # Roll back any change if something goes wrong
1861
                conn.rollback()
1862
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1863
                                                          sys.exc_info()[-1].tb_lineno))
1864

    
1865
    '''
1866
        @brief      delete Color property
1867
        @author     kyouho
1868
        @date       2018.07.09
1869
    '''
1870

    
1871
    def deletePropertyColor(self, property):
1872
        conn = self.project.database.connect()
1873
        with conn:
1874
            try:
1875
                # Get a cursor object
1876
                cursor = conn.cursor()
1877

    
1878
                sql = "DELETE FROM Colors WHERE PROPERTY = '{}'".format(property)
1879
                cursor.execute(sql)
1880
                conn.commit()
1881
                # Catch the exception
1882
            except Exception as ex:
1883
                # Roll back any change if something goes wrong
1884
                conn.rollback()
1885
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1886
                                                          sys.exc_info()[-1].tb_lineno))
1887

    
1888
    '''
1889
        @brief      get Fluid Code
1890
        @author     kyouho
1891
        @date       2018.07.03
1892
        @history    kyouho 2018.07.04 kyouho 2018.07.04 forCheckLineNumber get only code
1893
    '''
1894

    
1895
    def getFluidCodeData(self, forCheckLineNumber=False):
1896
        from FluidCodeData import FluidCodeData
1897
        result = []
1898

    
1899
        conn = self.project.database.connect()
1900
        with conn:
1901
            try:
1902
                # Get a cursor object
1903
                cursor = conn.cursor()
1904

    
1905
                sql = 'select uid, code, description from FluidCode order by length(code) DESC'
1906
                cursor.execute(sql)
1907
                rows = cursor.fetchall()
1908
                for row in rows:
1909
                    data = FluidCodeData(row[0], row[1], row[2])
1910
                    if forCheckLineNumber:
1911
                        result.append(data.code)
1912
                    else:
1913
                        result.append(data)
1914
                # Catch the exception
1915
            except Exception as ex:
1916
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1917
                                                          sys.exc_info()[-1].tb_lineno))
1918

    
1919
        return result
1920

    
1921
    '''
1922
        @brief      get Symbol Attribute
1923
        @author     kyouho
1924
        @date       2018.07.18
1925
    '''
1926

    
1927
    def checkAttribute(self, attr):
1928
        conn = self.project.database.connect()
1929
        with conn:
1930
            try:
1931
                # Get a cursor object
1932
                cursor = conn.cursor()
1933

    
1934
                sql = 'select UID from SymbolAttribute where UID = ?'
1935
                param = (attr,)
1936
                cursor.execute(sql, param)
1937
                rows = cursor.fetchall()
1938
                if len(rows):
1939
                    return True
1940
                else:
1941
                    return False
1942
                # Catch the exception
1943
            except Exception as ex:
1944
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1945
                                                          sys.exc_info()[-1].tb_lineno))
1946

    
1947
        return False
1948

    
1949
    def read_drawing_shape(self, drawing):
1950
        """read drawing shape"""
1951

    
1952
        res = None
1953

    
1954
        with self.project.database.connect() as conn:
1955
            try:
1956
                # Get a cursor object
1957
                cursor = conn.cursor()
1958

    
1959
                sql = f"select Image from Drawings where UID='{drawing}'"
1960
                cursor.execute(sql)
1961
                records = cursor.fetchall()
1962
                for record in records:
1963
                    res = record[0]
1964
                    break
1965

    
1966
            # Catch the exception
1967
            except Exception as ex:
1968
                from App import App
1969
                # Roll back any change if something goes wrong
1970
                conn.rollback()
1971

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

    
1976
        return res
1977

    
1978
    def read_symbol_shape(self, symbol_name):
1979
        """read symbol shape(image and svg)"""
1980

    
1981
        
1982
        res = (None, None)
1983

    
1984
        # need to test on mssql
1985
        return res
1986

    
1987
        with self.project.database.connect() as conn:
1988
            try:
1989
                # Get a cursor object
1990
                cursor = conn.cursor()
1991

    
1992
                sql = f"select Image, Svg from Symbol where Name='{symbol_name}'"
1993
                cursor.execute(sql)
1994
                records = cursor.fetchall()
1995
                for record in records:
1996
                    res = (record[0], record[1])
1997
                    break
1998

    
1999
            # Catch the exception
2000
            except Exception as ex:
2001
                from App import App
2002
                # Roll back any change if something goes wrong
2003
                conn.rollback()
2004

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

    
2009
        return res
2010

    
2011

    
2012
    def update_symbol_shape(self, symbol_name, image_file, svg_file, image_display_file):
2013
        """update symbol shape"""
2014

    
2015
        # need to test on mssql
2016
        return
2017

    
2018
        with self.project.database.connect() as conn:
2019
            try:
2020
                # Get a cursor object
2021
                cursor = conn.cursor()
2022

    
2023
                cols = []
2024
                params = []
2025

    
2026
                image_blob_data = None
2027
                if image_file and os.path.isfile(image_file):
2028
                    with open(image_file, 'rb') as file:
2029
                        image_blob_data = file.read()
2030
                    cols.append('Image=?')
2031
                    params.append(image_blob_data)
2032

    
2033
                svg_blob_data = None
2034
                if svg_file and os.path.isfile(svg_file):
2035
                    with open(svg_file, 'rb') as file:
2036
                        svg_blob_data = file.read()
2037
                    cols.append('Svg=?')
2038
                    params.append(svg_blob_data)
2039

    
2040
                image_display_blob_data = None
2041
                if image_file and image_display_file and os.path.isfile(image_display_file):
2042
                    with open(image_file, 'rb') as file:
2043
                        image_display_blob_data = file.read()
2044
                    cols.append('Image_display=?')
2045
                    params.append(image_display_blob_data)
2046

    
2047
                sql = f"update Symbol set {','.join(cols)} where Name='{symbol_name}'"
2048
                # Convert data into tuple format
2049
                cursor.execute(self.project.database.to_sql(sql), tuple(params))
2050
                conn.commit()
2051

    
2052
            # Catch the exception
2053
            except Exception as ex:
2054
                from App import App
2055
                # Roll back any change if something goes wrong
2056
                conn.rollback()
2057

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

    
2062
    def getCustomTables(self):
2063
        ''' get custom code tables '''
2064

    
2065
        import uuid
2066
        from CodeTables import CodeTable
2067

    
2068
        with self.project.database.connect() as conn:
2069
            try:
2070
                result = []
2071

    
2072
                # Get a cursor object
2073
                cursor = conn.cursor()
2074

    
2075
                sql = self.project.database.to_sql('select UID, Name, Description from CustomTables')
2076
                cursor.execute(sql)
2077
                rows = cursor.fetchall()
2078
                for row in rows:
2079
                    table = []
2080
                    table.append(uuid.UUID(row[0]))
2081
                    table.append(row[1])
2082
                    table.append(row[2])
2083
                    table.append(CodeTable.instance('CustomCodes', custom_table_uid=row[0]))
2084
                    result.append(table)
2085
            # Catch the exception
2086
            except Exception as ex:
2087
                from App import App
2088
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2089
                                                              sys.exc_info()[-1].tb_lineno)
2090
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2091

    
2092
        return result
2093

    
2094
    '''
2095
        @brief      get Symbol Attribute
2096
        @author     kyouho
2097
        @date       2018.07.18
2098
        @history    humkyung 2018.10.13 load expression
2099
    '''
2100
    def getSymbolAttribute(self, _type):
2101
        import uuid
2102
        from SymbolAttr import SymbolAttr
2103
        from CodeTables import CodeTable
2104

    
2105
        result = []
2106

    
2107
        if self._attributeByType and _type in self._attributeByType:
2108
            new_attr_without_any_binding_data = []
2109
            for attr_old in self._attributeByType[_type]:
2110
                attr = SymbolAttr()
2111
                attr.UID = attr_old.UID
2112
                attr.Attribute = attr_old.Attribute
2113
                attr.DisplayAttribute = attr_old.DisplayAttribute
2114
                attr.AttributeType = attr_old.AttributeType
2115
                attr.AttrAt = attr_old.AttrAt
2116
                attr.Expression = attr_old.Expression
2117
                attr.Target = attr_old.Target
2118
                attr.IsProp = attr_old.IsProp
2119
                attr.Codes = attr_old.Codes
2120
                new_attr_without_any_binding_data.append(attr)
2121
            self._attributeByType[_type] = new_attr_without_any_binding_data
2122

    
2123
            return self._attributeByType[_type]
2124

    
2125
        with self.project.database.connect() as conn:
2126
            try:
2127
                # Get a cursor object
2128
                cursor = conn.cursor()
2129

    
2130
                sql = self.project.database.to_sql(
2131
                    'select a.UID, a.Attribute, a.DisplayAttribute, a.AttributeType, a.[AttrAt], a.[Expression], a.[index], a.[Target], a.[Property] from SymbolAttribute a inner join SymbolType t on a.SymbolType_UID = t.UID and t.type = ? order by a.[index]')
2132
                param = (_type,)
2133
                cursor.execute(sql, param)
2134
                rows = cursor.fetchall()
2135
                for row in rows:
2136
                    attr = SymbolAttr()
2137
                    attr.UID = uuid.UUID(row[0])
2138
                    attr.Attribute = row[1]
2139
                    attr.DisplayAttribute = row[2]
2140
                    attr.AttributeType = row[3]
2141
                    attr.AttrAt = row[4]
2142
                    attr.Expression = row[5]
2143
                    attr.Target = row[7]
2144
                    attr.IsProp = row[8]
2145
                    attr.Codes = CodeTable.instance('SymbolAttributeCodeTable', symbol_attribute_uid=row[0])
2146
                    result.append(attr)
2147
            # Catch the exception
2148
            except Exception as ex:
2149
                from App import App
2150
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2151
                                                              sys.exc_info()[-1].tb_lineno)
2152
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2153

    
2154
        self._attributeByType[_type] = result
2155
        return result
2156

    
2157
    '''
2158
        @brief      get Symbol Attribute by UID
2159
        @author     kyouho
2160
        @date       2018.08.17
2161
        @history    humkyung 2018.10.13 load expression
2162
    '''
2163

    
2164
    def getSymbolAttributeByUID(self, UID):
2165
        from SymbolAttr import SymbolAttr
2166

    
2167
        res = None
2168

    
2169
        conn = self.project.database.connect()
2170
        with conn:
2171
            try:
2172
                # Get a cursor object
2173
                cursor = conn.cursor()
2174

    
2175
                sql = 'select Attribute, DisplayAttribute, AttributeType, AttrAt, Expression, Target, Property from SymbolAttribute where uid = "{}"'.format(
2176
                    UID)
2177
                cursor.execute(sql)
2178
                rows = cursor.fetchall()
2179
                if len(rows):
2180
                    res = SymbolAttr()
2181
                    res.UID = UID
2182
                    res.Attribute = rows[0][0]
2183
                    res.DisplayAttribute = rows[0][1]
2184
                    res.AttributeType = rows[0][2]
2185
                    res.AttrAt = rows[0][3]
2186
                    res.Expression = rows[0][4]
2187
                    res.Target = rows[0][5]
2188
                    res.IsProp = row[0][6]
2189
                # Catch the exception
2190
            except Exception as ex:
2191
                from App import App
2192
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2193
                                                              sys.exc_info()[-1].tb_lineno)
2194
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2195

    
2196
        return res
2197

    
2198
    '''
2199
        @brief      save symbol attributes
2200
        @author     humkyung
2201
        @date       2018.08.14
2202
        @history    humkyung 2018.10.13 save expression
2203
    '''
2204
    def saveSymbolAttributes(self, type, attrs, type_str):
2205
        from CodeTables import CodeTable
2206

    
2207
        with self.project.database.connect() as conn:
2208
            try:
2209
                # Get a cursor object
2210
                cursor = conn.cursor()
2211

    
2212
                # delete symbol attribute code table data
2213
                origin_attrs = self.getSymbolAttribute(type_str)
2214
                for origin_attr in origin_attrs:
2215
                    '''
2216
                    # delete symbol attribute code table data for deleted symbol attribute, and backup not edited attribute code table data
2217
                    remain = False
2218
                    for attr in attrs:
2219
                        if str(origin_attr.UID) == attr[0]:
2220
                            remain = True
2221
                            break
2222
                    if remain and attr[-1] and type(attr[-1][0][3]) is list: # this means not edited and need backup
2223
                        attr[-1] = self.getCodeTable('SymbolAttributeCodeTable', forCheckLineNumber=False, symbol_attribute_uid=origin_attr.UID)
2224
                    '''
2225
                    
2226
                    sql = "delete from SymbolAttributeCodeTable where SymbolAttribute_UID = '{}'".format(origin_attr.UID)
2227
                    cursor.execute(sql)
2228
                # up to here
2229

    
2230
                # update symbol attribute
2231
                sql = self.project.database.to_sql('delete from SymbolAttribute where SymbolType_UID = ?')
2232
                param = (type,)
2233
                cursor.execute(sql, param)
2234

    
2235
                for attr in attrs:
2236
                    sql = self.project.database.to_sql(
2237
                        'insert into SymbolAttribute(UID, SymbolType_UID, Attribute, DisplayAttribute, AttributeType, '
2238
                        'AttrAt, Expression, Target, [index], [Property]) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)')
2239
                    attr.insert(1, type)
2240
                    cursor.execute(sql, tuple(attr[:-1]))
2241
                # up to here
2242

    
2243
                # update symbol attribute code table data
2244
                for attr in attrs:
2245
                    if attr[-1]:
2246
                        for code in attr[-1]:
2247
                            sql = self.project.database.to_sql( \
2248
                                "insert into SymbolAttributeCodeTable(UID, Code, Description, Allowables, SymbolAttribute_UID) VALUES(?,?,?,?,?)")
2249
                            param = (code[0], code[1], code[2], ','.join(code[3]), attr[0])
2250
                            cursor.execute(sql, param)
2251
                # up to here
2252

    
2253
                conn.commit()
2254

    
2255
                if hasattr(self, '_equipment_attributes'):
2256
                    del self._equipment_attributes
2257

    
2258
                if hasattr(self, '_valve_attributes'):
2259
                    del self._valve_attributes
2260

    
2261
                if hasattr(self, '_inst_attributes'):
2262
                    del self._inst_attributes
2263

    
2264
                if hasattr(self, '_note_attributes'):
2265
                    del self._note_attributes
2266
            # Catch the exception
2267
            except Exception as ex:
2268
                # Roll back any change if something goes wrong
2269
                conn.rollback()
2270

    
2271
                from App import App
2272
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2273
                                                              sys.exc_info()[-1].tb_lineno)
2274
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2275

    
2276
            self._attributeByType = {}
2277
            CodeTable.clearTables()
2278

    
2279
    def saveCustomCodes(self, tables):
2280
        ''' save custom code tables and codes '''
2281

    
2282
        from CodeTables import CodeTable
2283

    
2284
        conn = self.project.database.connect()
2285
        with conn:
2286
            try:
2287
                # Get a cursor object
2288
                cursor = conn.cursor()
2289

    
2290
                # delete custom codes and tables
2291
                sql = "delete from CustomCodes"
2292
                cursor.execute(sql)
2293

    
2294
                sql = "delete from CustomTables"
2295
                cursor.execute(sql)
2296
                # up to here
2297

    
2298
                # update symbol attribute code table data
2299
                for table in tables:
2300
                    sql = self.project.database.to_sql("insert into CustomTables (UID, Name, Description) VALUES(?,?,?)")
2301
                    param = (table[0], table[1], table[2])
2302
                    cursor.execute(sql, param)
2303

    
2304
                    for code in table[3]:
2305
                        sql = self.project.database.to_sql( \
2306
                            "insert into CustomCodes(UID, Code, Description, Allowables, Table_UID) VALUES(?,?,?,?,?)")
2307
                        param = (code[0], code[1], code[2], ','.join(code[3]), table[0])
2308
                        cursor.execute(sql, param)
2309
                # up to here
2310

    
2311
                conn.commit()
2312

    
2313
            # Catch the exception
2314
            except Exception as ex:
2315
                # Roll back any change if something goes wrong
2316
                conn.rollback()
2317

    
2318
                from App import App
2319
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2320
                                                              sys.exc_info()[-1].tb_lineno)
2321
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2322

    
2323
            CodeTable.clearTables()
2324

    
2325
    '''
2326
        @brief      save symbol attributes
2327
        @author     humkyung
2328
        @date       2018.08.14
2329
    '''
2330
    def saveLineAttributes(self, attrs):
2331
        conn = self.project.database.connect()
2332
        with conn:
2333
            try:
2334
                # Get a cursor object
2335
                cursor = conn.cursor()
2336

    
2337
                sql = 'delete from LineProperties'
2338
                cursor.execute(sql)
2339

    
2340
                for attr in attrs:
2341
                    sql = self.project.database.to_sql(
2342
                        'insert into LineProperties(UID, Name, DisplayName, Type, LimitNumber, [index]) values(?, ?, ?, ?, ?, ?)')
2343
                    cursor.execute(sql, tuple(attr))
2344

    
2345
                conn.commit()
2346

    
2347
                self._lineNoProperties = None
2348
                self._lineNoPropertiesUID = {}
2349
            # Catch the exception
2350
            except Exception as ex:
2351
                # Roll back any change if something goes wrong
2352
                conn.rollback()
2353

    
2354
                from App import App
2355
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2356
                                                              sys.exc_info()[-1].tb_lineno)
2357
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2358

    
2359
    '''
2360
        @brief      get symbol type id
2361
        @author     kyouho
2362
        @date       2018.08.17
2363
    '''
2364

    
2365
    def getSymbolTypeId(self, symbolType):
2366
        result = []
2367

    
2368
        conn = self.project.database.connect()
2369
        with conn:
2370
            try:
2371
                # Get a cursor object
2372
                cursor = conn.cursor()
2373

    
2374
                sql = self.project.database.to_sql('select UID from SymbolType where Type = ?')
2375
                param = (symbolType,)
2376
                cursor.execute(sql, param)
2377
                rows = cursor.fetchall()
2378

    
2379
                if len(rows):
2380
                    result = rows[0][0]
2381
                else:
2382
                    result = -1
2383
                # Catch the exception
2384
            except Exception as ex:
2385
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2386
                                                          sys.exc_info()[-1].tb_lineno))
2387

    
2388
        return result
2389

    
2390
    '''
2391
        @brief      get Code Table Data
2392
        @author     kyouho
2393
        @date       2018.07.10
2394
    '''
2395

    
2396
    def getCodeTable(self, property, forCheckLineNumber=False, symbol_attribute_uid=None, custom_table_uid=None, custom=False):
2397
        result = []
2398
        conn = self.project.database.connect()
2399
        with conn:
2400
            try:
2401
                # Get a cursor object
2402
                cursor = conn.cursor()
2403

    
2404
                if property.upper().replace(' ', '') == "NOMINALDIAMETER" and forCheckLineNumber:
2405
                    sql = 'select InchStr, MetricStr from [{}] order by Metric ASC'.format(property)
2406
                    cursor.execute(sql)
2407
                    rows = cursor.fetchall()
2408
                    for index in range(2):
2409
                        for row in rows:
2410
                            if row[index] != '' and result.count(row[index].replace("'", '"')) == 0:
2411
                                result.append(row[index].replace("'", '"'))
2412
                else:
2413
                    """
2414
                    sql = "select name from sqlite_master where type='table'"# AND name={}".format(property)
2415
                    cursor.execute(sql)
2416
                    rows = cursor.fetchall()
2417
                    if property.upper() in [name[0].upper() for name in rows]:
2418
                    """
2419
                    if not symbol_attribute_uid and not custom_table_uid and not custom:
2420
                        sql = 'select uid, code, description, Allowables from [{}] order by code DESC'.format(property)
2421
                    elif symbol_attribute_uid and not custom_table_uid:
2422
                        sql = "select uid, code, description, Allowables from [{}] where SymbolAttribute_UID='{}' order by code DESC".format(property, symbol_attribute_uid)
2423
                    elif not symbol_attribute_uid and custom_table_uid:
2424
                        sql = "select uid, code, description, Allowables from [{}] where Table_UID='{}' order by code DESC".format(property, custom_table_uid)
2425
                    elif custom:
2426
                        sql = "select uid, code, description, Allowables from CustomCodes \
2427
                                    where table_uid = (select uid from CustomTables where upper(name) like upper('{}'))".format(property)
2428
                    cursor.execute(sql)
2429
                    rows = cursor.fetchall()
2430
                    for row in rows:
2431
                        if forCheckLineNumber:
2432
                            data = row[1]
2433
                        else:
2434
                            data = (row[0], row[1], row[2], row[3])
2435
                        result.append(data)
2436
                    # else:
2437
                    #    result = None
2438
            # Catch the exception
2439
            except Exception as ex:
2440
                from App import App
2441
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2442
                                                              sys.exc_info()[-1].tb_lineno)
2443
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2444

    
2445
        return result
2446

    
2447
    def get_components(self, drawing):
2448
        """ get components in given drawing """
2449

    
2450
        with self.project.database.connect() as conn:
2451
            try:
2452
                # Get a cursor object
2453
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
2454

    
2455
                sql = "select a.*,b.Name,b.SymbolType_UID,b.[Type],b.OriginalPoint,b.ConnectionPoint,b.BaseSymbol," \
2456
                      "b.AdditionalSymbol,b.HasInstrumentLabel,b.Flip as DetectFlip from Components a " \
2457
                      "join Symbol b on a.Symbol_UID=b.UID where a.Drawings_UID='{}'".format(drawing)
2458
                cursor.execute(sql)
2459
                return cursor.fetchall()
2460
                # Catch the exception
2461
            except Exception as ex:
2462
                from App import App
2463
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2464
                                                              sys.exc_info()[-1].tb_lineno)
2465
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2466

    
2467
    def get_opcs(self):
2468
        """ get opc in project """
2469
        with self.project.database.connect() as conn:
2470
            try:
2471
                # Get a cursor object
2472
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
2473

    
2474
                sql = "select (select Name from Drawings where UID=a.Drawings_UID) as Drawing," \
2475
                      "(select Value from Components where UID=a.Owner) as [Line No]," \
2476
                      "UID as OPC from Components a " \
2477
                      "where Symbol_UID in (select UID from Symbol where SymbolType_UID in " \
2478
                      "(select UID from SymbolType where Type='Instrument OPC''s' or Type='Piping OPC''s'))"
2479
                cursor.execute(sql)
2480
                return cursor.fetchall()
2481
                # Catch the exception
2482
            except Exception as ex:
2483
                from App import App
2484
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2485
                                                              sys.exc_info()[-1].tb_lineno)
2486
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2487

    
2488
    def get_opc_relations(self):
2489
        """ get opc relations """
2490
        conn = self.project.database.connect()
2491
        with conn:
2492
            try:
2493
                # Get a cursor object
2494
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
2495

    
2496
                sql = "select (select Name from Drawings where UID=a.From_Drawings_UID) as From_Drawing,\
2497
                a.From_LineNo_UID as From_LineNo,\
2498
                a.From_OPC_UID,\
2499
                (select Name from Drawings where UID=a.To_Drawings_UID) as To_Drawing,\
2500
                a.To_LineNo_UID as To_LineNo,\
2501
                a.To_OPC_UID \
2502
                from OPCRelations a"
2503
                cursor.execute(sql)
2504
                return cursor.fetchall()
2505
                # Catch the exception
2506
            except Exception as ex:
2507
                from App import App
2508
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2509
                                                              sys.exc_info()[-1].tb_lineno)
2510
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2511

    
2512
    def save_opc_relations(self, opcs):
2513
        """ save opc relations """
2514
        conn = self.project.database.connect()
2515
        with conn:
2516
            try:
2517
                # Get a cursor object
2518
                cursor = conn.cursor()
2519
                sql = 'delete from OPCRelations'
2520
                cursor.execute(sql)
2521

    
2522
                for opc in opcs:
2523
                    sql = 'insert into OPCRelations(From_Drawings_UID,From_LineNo_UID,From_OPC_UID,To_Drawings_UID,To_LineNo_UID,To_OPC_UID) \
2524
                        values({},{},{},{},{},{})'.format(
2525
                        "(select UID from Drawings where Name='{}')".format(opc[0]),
2526
                        "'{}'".format(opc[1]) if opc[1] else 'null',
2527
                        "'{}'".format(opc[2]) if opc[2] else 'null',
2528
                        "(select UID from Drawings where Name='{}')".format(opc[3]) if opc[3] else 'null',
2529
                        "'{}'".format(opc[4]) if opc[4] else 'null',
2530
                        "'{}'".format(opc[5]) if opc[5] else 'null')
2531
                    cursor.execute(sql)
2532

    
2533
                conn.commit()
2534
            # Catch the exception
2535
            except Exception as ex:
2536
                conn.rollback()
2537

    
2538
                from App import App
2539
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2540
                                                              sys.exc_info()[-1].tb_lineno)
2541
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2542

    
2543
    def get_component_connectors(self, component):
2544
        """ get connectors of given component """
2545
        if self._connecterss and component in self._connecterss:
2546
            return self._connecterss[component]
2547

    
2548
        conn = self.project.database.connect()
2549
        with conn:
2550
            try:
2551
                # Get a cursor object
2552
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
2553

    
2554
                sql = f"select a.* from Points a join Components b on a.Components_UID=b.[UID] where Drawings_UID=" \
2555
                      f"'{self.activeDrawing.UID}' order by Components_UID, [Index]"
2556
                cursor.execute(sql)
2557

    
2558
                pre = ''
2559
                rows = cursor.fetchall()
2560
                for row in rows:
2561
                    if pre != row['Components_UID']:
2562
                        if pre != '':
2563
                            self._connecterss[pre] = compo
2564
                        pre = row['Components_UID']
2565
                        compo = []
2566
                        compo.append(row)
2567
                        if row is rows[-1]:
2568
                            self._connecterss[row['Components_UID']] = compo
2569
                    else:
2570
                        compo.append(row)
2571
                        if row is rows[-1]:
2572
                            self._connecterss[row['Components_UID']] = compo
2573

    
2574
                return self._connecterss[component] if component in self._connecterss else []
2575
                # Catch the exception
2576
            except Exception as ex:
2577
                from App import App
2578
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2579
                                                              sys.exc_info()[-1].tb_lineno)
2580
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2581

    
2582
    def get_component_associations(self, component):
2583
        """ get associations of given component """
2584
        if self._associationss and component in self._associationss:
2585
            return self._associationss[component]
2586
        elif self._associationss:
2587
            return []
2588

    
2589
        conn = self.project.database.connect()
2590
        with conn:
2591
            try:
2592
                # Get a cursor object
2593
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
2594

    
2595
                # sql = "select * from Associations where Components_UID='{}'".format(component)
2596
                sql = "select a.* from Associations a \
2597
                            join Components b on a.Components_UID=b.[UID] where Drawings_UID='{}' order by Components_UID".format(
2598
                    self.activeDrawing.UID)
2599
                cursor.execute(sql)
2600

    
2601
                pre = ''
2602
                rows = cursor.fetchall()
2603
                for row in rows:
2604
                    if pre != row['Components_UID']:
2605
                        if pre != '':
2606
                            self._associationss[pre] = compo
2607
                        pre = row['Components_UID']
2608
                        compo = []
2609
                        compo.append(row)
2610
                        if row is rows[-1]:
2611
                            self._associationss[row['Components_UID']] = compo
2612
                    else:
2613
                        compo.append(row)
2614
                        if row is rows[-1]:
2615
                            self._associationss[row['Components_UID']] = compo
2616

    
2617
                return self._associationss[component] if component in self._associationss else []
2618
                # Catch the exception
2619
            except Exception as ex:
2620
                from App import App
2621
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2622
                                                              sys.exc_info()[-1].tb_lineno)
2623
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2624

    
2625
    def get_component_attributes(self, component):
2626
        """ get attributes of given component """
2627
        if self._attributess and component in self._attributess:
2628
            return self._attributess[component]
2629
        elif self._attributess:
2630
            return []
2631

    
2632
        conn = self.project.database.connect()
2633
        with conn:
2634
            try:
2635
                # Get a cursor object
2636
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
2637

    
2638
                sql = "select a.*, b.* from Attributes a \
2639
                            join SymbolAttribute b on a.SymbolAttribute_UID=b.UID \
2640
                            join Components c on a.Components_UID=c.UID \
2641
                        where Drawings_UID='{}' order by a.Components_UID, b.[index]".format(self.activeDrawing.UID)
2642
                cursor.execute(sql)
2643

    
2644
                pre = ''
2645
                rows = cursor.fetchall()
2646
                for row in rows:
2647
                    if pre != row['Components_UID']:
2648
                        if pre != '':
2649
                            self._attributess[pre] = compo
2650
                        pre = row['Components_UID']
2651
                        compo = []
2652
                        compo.append(row)
2653
                        if row is rows[-1]:
2654
                            self._attributess[row['Components_UID']] = compo
2655
                    else:
2656
                        compo.append(row)
2657
                        if row is rows[-1]:
2658
                            self._attributess[row['Components_UID']] = compo
2659

    
2660
                return self._attributess[component] if component in self._attributess else []
2661
                # Catch the exception
2662
            except Exception as ex:
2663
                from App import App
2664
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2665
                                                              sys.exc_info()[-1].tb_lineno)
2666
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2667

    
2668
    def get_pipe_runs(self, component):
2669
        """ get line runs of given component """
2670
        conn = self.project.database.connect()
2671
        with conn:
2672
            try:
2673
                # Get a cursor object
2674
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
2675

    
2676
                sql = "select * from PipeRuns where Owner='{}' order by [Index]".format(component)
2677
                cursor.execute(sql)
2678
                return cursor.fetchall()
2679
                # Catch the exception
2680
            except Exception as ex:
2681
                from App import App
2682
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2683
                                                              sys.exc_info()[-1].tb_lineno)
2684
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2685

    
2686
    def get_pipe_run_items(self, pipe_run):
2687
        """ get line run items of given pipe run """
2688
        conn = self.project.database.connect()
2689
        with conn:
2690
            try:
2691
                # Get a cursor object
2692
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
2693

    
2694
                sql = "select * from PipeRunItems where PipeRuns_UID='{}' order by [Index]".format(pipe_run)
2695
                cursor.execute(sql)
2696
                return cursor.fetchall()
2697
                # Catch the exception
2698
            except Exception as ex:
2699
                from App import App
2700
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2701
                                                              sys.exc_info()[-1].tb_lineno)
2702
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2703

    
2704
    '''
2705
        @brief      get special item types from database
2706
        @author     humkyung
2707
        @date       2019.08.10
2708
    '''
2709

    
2710
    def get_special_item_types(self):
2711
        conn = self.project.database.connect()
2712
        with conn:
2713
            try:
2714
                # Get a cursor object
2715
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
2716

    
2717
                sql = 'select UID, Code, Type, Allowables from SpecialItemTypes order by Code DESC'
2718
                cursor.execute(sql)
2719
                return cursor.fetchall()
2720
                # Catch the exception
2721
            except Exception as ex:
2722
                from App import App
2723
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2724
                                                              sys.exc_info()[-1].tb_lineno)
2725
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2726

    
2727
    '''
2728
        @brief      save special item types
2729
        @author     humkyung
2730
        @date       2019.08.10
2731
    '''
2732

    
2733
    def save_special_item_types(self, datas):
2734
        import uuid
2735

    
2736
        conn = self.project.database.connect()
2737
        with conn:
2738
            try:
2739
                # Get a cursor object
2740
                cursor = conn.cursor()
2741

    
2742
                for data in datas:
2743
                    uid, code, _type, allowables = data[0], data[1], data[2], data[3]
2744
                    if not uid:
2745
                        sql = self.project.database.to_sql(
2746
                            'insert into SpecialItemTypes(UID, Code, Type, Allowables) values(?, ?, ?, ?)')
2747
                        param = (str(uuid.uuid4()), data[1], data[2], data[3])
2748
                    elif uid == '-1':
2749
                        sql = self.project.database.to_sql('delete from SpecialItemTypes where uid=?')
2750
                        param = (data[-1],)
2751
                    else:
2752
                        sql = self.project.database.to_sql(
2753
                            'update SpecialItemTypes SET Code=?, Type=?, Allowables=? WHERE UID = ?')
2754
                        param = (data[1], data[2], data[3], data[0])
2755
                    cursor.execute(sql, param)
2756

    
2757
                conn.commit()
2758
            # Catch the exception
2759
            except Exception as ex:
2760
                # Roll back any change if something goes wrong
2761
                conn.rollback()
2762

    
2763
                from App import App
2764
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2765
                                                              sys.exc_info()[-1].tb_lineno)
2766
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2767

    
2768
    def get_special_items(self, drawings=None):
2769
        """ get special items from database """
2770
        result = []
2771

    
2772
        conn = self.project.database.connect()
2773
        with conn:
2774
            try:
2775
                # get a cursor object
2776
                cursor = conn.cursor()
2777

    
2778
                sql = 'select distinct (select Value from Components where UID=D.Owner) as "Line No",C.Code from Components A \
2779
                    left join Drawings B on A.Drawings_UID=B.UID \
2780
                    left join SpecialItemTypes C on A.SpecialItemTypes_UID=C.UID \
2781
                    left join Components D on A.Connected=D.UID \
2782
                    where A.SpecialItemTypes_UID is not null'
2783
                if drawings is not None:
2784
                    doc_names = "','".join(drawings)
2785
                    sql += f" and A.Drawings_UID in (select UID from Drawings where Name in ('{doc_names}'))"
2786
                sql += ' order by "Line No"'
2787
                cursor.execute(sql)
2788

    
2789
                return cursor.fetchall()
2790
            # catch the exception
2791
            except Exception as ex:
2792
                from App import App
2793
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2794
                                                              sys.exc_info()[-1].tb_lineno)
2795
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2796

    
2797
        return None
2798

    
2799
    '''
2800
        @brief      Set Common Code Data
2801
        @author     kyouho
2802
        @date       2018.07.12
2803
    '''
2804

    
2805
    def saveCommonCodeData(self, tableName, datas):
2806
        import uuid
2807

    
2808
        conn = self.project.database.connect()
2809
        with conn:
2810
            try:
2811
                # Get a cursor object
2812
                cursor = conn.cursor()
2813

    
2814
                for data in datas:
2815
                    uid, code, description, allowables = data[0], data[1], data[2], data[3]
2816
                    if not uid:
2817
                        sql = self.project.database.to_sql(
2818
                            "insert into {}(UID, CODE, DESCRIPTION, ALLOWABLES) values(?, ?, ?, ?)".format(tableName))
2819
                        param = (str(uuid.uuid4()), data[1], data[2], data[3])
2820
                    elif uid == '-1':
2821
                        sql = self.project.database.to_sql('delete from {} where uid=?'.format(tableName))
2822
                        param = (data[-1],)
2823
                    else:
2824
                        sql = self.project.database.to_sql(
2825
                            "update {} SET CODE=?, DESCRIPTION=?, ALLOWABLES=? WHERE UID = ?".format(tableName))
2826
                        param = (data[1], data[2], data[3], data[0])
2827
                    cursor.execute(sql, param)
2828

    
2829
                conn.commit()
2830
            # Catch the exception
2831
            except Exception as ex:
2832
                # Roll back any change if something goes wrong
2833
                conn.rollback()
2834

    
2835
                from App import App
2836
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2837
                                                              sys.exc_info()[-1].tb_lineno)
2838
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2839

    
2840
    '''
2841
        @brief      Set Common Code Data
2842
        @author     kyouho
2843
        @date       2018.07.12
2844
    '''
2845

    
2846
    def deleteCommonCodeData(self, datas):
2847
        try:
2848
            conn = self.project.database.connect()
2849
            with conn:
2850
                # Get a cursor object
2851
                cursor = conn.cursor()
2852

    
2853
                for data in datas:
2854
                    uid = data[0]
2855
                    tableName = data[1]
2856

    
2857
                    if uid:
2858
                        sql = "delete from {} where UID = ?".format(tableName)
2859
                        param = (uid,)
2860
                        cursor.execute(sql, param)
2861

    
2862
                    cursor.execute(sql, param)
2863

    
2864
                conn.commit()
2865

    
2866
        # Catch the exception
2867
        except Exception as ex:
2868
            # Roll back any change if something goes wrong
2869
            conn.rollback()
2870
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2871
                                                      sys.exc_info()[-1].tb_lineno))
2872

    
2873
    '''
2874
        @brief      delete data list
2875
        @author     kyouho
2876
        @date       2018.08.16
2877
    '''
2878

    
2879
    def deleteDataList(self, tableName, UID):
2880
        conn = self.project.database.connect()
2881
        with conn:
2882
            try:
2883
                # Get a cursor object
2884
                cursor = conn.cursor()
2885
                sql = 'delete from {} where UID = {}'.format(tableName, UID)
2886
                cursor.execute(sql)
2887
                conn.commit()
2888

    
2889
            # Catch the exception
2890
            except Exception as ex:
2891
                # Roll back any change if something goes wrong
2892
                conn.rollback()
2893
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2894
                                                          sys.exc_info()[-1].tb_lineno))
2895

    
2896
    def get_document_name_list(self):
2897
        """ get document name list """
2898
        result = []
2899

    
2900
        conn = self.project.database.connect()
2901
        with conn:
2902
            try:
2903
                # Get a cursor object
2904
                cursor = conn.cursor()
2905

    
2906
                sql = "select distinct B.Name as 'Drawing_Name' from Components A join Drawings B on A.Drawings_UID=B.UID"
2907
                cursor.execute(sql)
2908

    
2909
                rows = cursor.fetchall()
2910
                for row in rows:
2911
                    result.append(row[0])
2912

    
2913
                result.sort()
2914
            # Catch the exception
2915
            except Exception as ex:
2916
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2917
                                                          sys.exc_info()[-1].tb_lineno))
2918

    
2919
        return result
2920

    
2921
    '''
2922
        @brief      get line documentName list
2923
        @author     kyouho
2924
        @date       2018.08.13
2925
    '''
2926

    
2927
    def getLineDocumentNameList(self):
2928
        result = []
2929

    
2930
        conn = self.project.database.connect()
2931
        with conn:
2932
            try:
2933
                # Get a cursor object
2934
                cursor = conn.cursor()
2935

    
2936
                sql = 'select DISTINCT(PNID_NO) from LINE_DATA_LIST'
2937

    
2938
                cursor.execute(sql)
2939
                rows = cursor.fetchall()
2940
                for row in rows:
2941
                    result.append(row[0])
2942
            # Catch the exception
2943
            except Exception as ex:
2944
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2945
                                                          sys.exc_info()[-1].tb_lineno))
2946

    
2947
        return result
2948

    
2949
    '''
2950
        @brief      get line data list
2951
        @author     kyouho
2952
        @date       2018.08.13
2953
    '''
2954

    
2955
    def get_line_data_list(self, drawings=None):
2956
        result = []
2957

    
2958
        with self.project.database.connect() as conn:
2959
            try:
2960
                # Get a cursor object
2961
                cursor = conn.cursor()
2962

    
2963
                sql = 'select A.UID,B.Name from Components A left join Drawings B on A.Drawings_UID=B.UID'
2964
                if drawings is not None:
2965
                    doc_names = "','".join(drawings)
2966
                    sql += f" where Drawings_UID in (select UID from Drawings where Name in ('{doc_names}'))"
2967
                cursor.execute(sql)
2968
                comps = [(row[0], row[1]) for row in cursor.fetchall()]
2969
                for comp in comps:
2970
                    sql = f"select b.Name,a.Value from LineNoAttributes a left join LineProperties b " \
2971
                          f"on a.LineProperties_UID=b.UID where a.Components_UID='{comp[0]}'"
2972
                    cursor.execute(sql)
2973
                    attrs = cursor.fetchall()
2974
                    data = []
2975
                    for attr in attrs:
2976
                        data.append([attr[0], attr[1]])
2977
                    if data:
2978
                        data.insert(0, ['Drawing Name', comp[1]])
2979
                        data.insert(0, ['UID', comp[0]])
2980
                        result.append(data)
2981

    
2982
            # catch the exception
2983
            except Exception as ex:
2984
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2985
                                                          sys.exc_info()[-1].tb_lineno))
2986

    
2987
        return result
2988

    
2989
    def get_equipment_data_list(self, drawings=None):
2990
        """ get equipment data list """
2991

    
2992
        result = []
2993

    
2994
        with self.project.database.connect() as conn:
2995
            try:
2996
                # Get a cursor object
2997
                cursor = conn.cursor()
2998

    
2999
                sql = "select A.UID,B.NAME,C.SymbolType_UID,D.Type from Components A join Drawings B on A.Drawings_UID=B.UID\
3000
                        join Symbol C on A.Symbol_UID=C.UID\
3001
                        join SymbolType D on C.SymbolType_UID=D.UID\
3002
                        where D.Category in ('Equipment','Equipment Components')"
3003

    
3004
                if drawings is not None:
3005
                    doc_names = "','".join(drawings)
3006
                    sql += f" and A.Drawings_UID in (select UID from Drawings where Name in ('{doc_names}'))"
3007

    
3008
                cursor.execute(sql)
3009
                comps = [(row[0], row[1], row[2], row[3]) for row in cursor.fetchall()]
3010
                for comp in comps:
3011
                    sql = f"select distinct B.Attribute,A.Value from Attributes A left join SymbolAttribute B on " \
3012
                          f"A.SymbolAttribute_UID=B.UID where A.Components_UID='{comp[0]}'"
3013
                    cursor.execute(sql)
3014
                    attrs = cursor.fetchall()
3015
                    data = []
3016
                    for attr in attrs:
3017
                        data.append([attr[0], attr[1]])
3018
                    if data:
3019
                        data.insert(0, ['Type', comp[3]])
3020
                        data.insert(0, ['Drawing Name', comp[1]])
3021
                        data.insert(0, ['UID', comp[0]])
3022
                        result.append(data)
3023

    
3024
            # catch the exception
3025
            except Exception as ex:
3026
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3027
                                                           sys.exc_info()[-1].tb_lineno))
3028

    
3029
        return result
3030

    
3031
    '''
3032
        @brief      set line data list
3033
        @author     kyouho
3034
        @date       2018.08.13
3035
    '''
3036

    
3037
    def setLineDataList(self, dataLists):
3038
        conn = self.project.database.connect()
3039
        with conn:
3040
            try:
3041
                # Get a cursor object
3042
                cursor = conn.cursor()
3043

    
3044
                for data in dataLists:
3045
                    sql = "insert into LINE_DATA_LIST(UID, LINE_SIZE, LINE_SYMBOL, LINE_NO, LINE_CLASS, LINE_ROUTING_FROM, LINE_ROUTING_TO, SERVICE_FLUID, SERVICE_DENSITY, SERVICE_STATE, OPERATION_CONDITION_TEMP, OPERATION_CONDITION_PRESS, DESIGN_CONDITION_TEMP, DESIGN_CONDITION_PRESS, TEST_CONDITION_TEMP, TEST_CONDITION_PRESS, INSUL_CODE, PAINT_CODE, NDE_CODE, PWHT, PNID_NO) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
3046
                    param = tuple(data)
3047
                    cursor.execute(sql, param)
3048

    
3049
                conn.commit()
3050

    
3051
            # Catch the exception
3052
            except Exception as ex:
3053
                # Roll back any change if something goes wrong
3054
                conn.rollback()
3055
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3056
                                                          sys.exc_info()[-1].tb_lineno))
3057

    
3058
    '''
3059
        @brief      delete line data list
3060
        @author     kyouho
3061
        @date       2018.08.13
3062
    '''
3063
    def deleteLineDataList(self, removeUID):
3064
        conn = self.project.database.connect()
3065
        with conn:
3066
            try:
3067
                # Get a cursor object
3068
                cursor = conn.cursor()
3069

    
3070
                for uid in removeUID:
3071
                    sql = "delete from LINE_DATA_LIST where uid = '{}'".format(uid)
3072
                    cursor.execute(sql)
3073

    
3074
                conn.commit()
3075

    
3076
            # Catch the exception
3077
            except Exception as ex:
3078
                # Roll back any change if something goes wrong
3079
                conn.rollback()
3080
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3081
                                                          sys.exc_info()[-1].tb_lineno))
3082

    
3083
    '''
3084
        @brief      delete line data list
3085
        @author     kyouho
3086
        @date       2018.08.13
3087
    '''
3088

    
3089
    def deleteLineDataList_LineNo(self, removeUID):
3090
        conn = self.project.database.connect()
3091
        with conn:
3092
            try:
3093
                # Get a cursor object
3094
                cursor = conn.cursor()
3095

    
3096
                for uid in removeUID:
3097
                    sql = "delete from LINE_DATA_LIST where LINE_NO = ?"
3098
                    param = (uid,)
3099
                    cursor.execute(sql, param)
3100

    
3101
                conn.commit()
3102

    
3103
            # Catch the exception
3104
            except Exception as ex:
3105
                # Roll back any change if something goes wrong
3106
                conn.rollback()
3107
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3108
                                                          sys.exc_info()[-1].tb_lineno))
3109

    
3110
    '''
3111
        @brief      delete equip data list
3112
        @author     kyouho
3113
        @date       2018.08.14
3114
    '''
3115

    
3116
    def deleteEquipDataList(self, removeUID):
3117
        conn = self.project.database.connect()
3118
        with conn:
3119
            try:
3120
                # Get a cursor object
3121
                cursor = conn.cursor()
3122

    
3123
                for uid in removeUID:
3124
                    sql = "delete from EQUIPMENT_DATA_LIST where uid = '{}'".format(uid)
3125
                    cursor.execute(sql)
3126

    
3127
                conn.commit()
3128

    
3129
            # Catch the exception
3130
            except Exception as ex:
3131
                # Roll back any change if something goes wrong
3132
                conn.rollback()
3133
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3134
                                                          sys.exc_info()[-1].tb_lineno))
3135

    
3136
    '''
3137
        @brief      delete inst data list
3138
        @author     kyouho
3139
        @date       2018.08.14
3140
    '''
3141

    
3142
    def deleteInstDataList(self, removeUID):
3143
        conn = self.project.database.connect()
3144
        with conn:
3145
            try:
3146
                # Get a cursor object
3147
                cursor = conn.cursor()
3148

    
3149
                for uid in removeUID:
3150
                    sql = "delete from INSTRUMENT_DATA_LIST where uid = '{}'".format(uid)
3151
                    cursor.execute(sql)
3152

    
3153
                conn.commit()
3154

    
3155
            # Catch the exception
3156
            except Exception as ex:
3157
                # Roll back any change if something goes wrong
3158
                conn.rollback()
3159
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3160
                                                          sys.exc_info()[-1].tb_lineno))
3161

    
3162
    '''
3163
        @brief      delete note data list
3164
        @author     kyouho
3165
        @date       2018.10.10
3166
    '''
3167

    
3168
    def deleteNoteDataList(self, removeUID):
3169
        conn = self.project.database.connect()
3170
        with conn:
3171
            try:
3172
                # Get a cursor object
3173
                cursor = conn.cursor()
3174

    
3175
                for uid in removeUID:
3176
                    sql = "delete from NOTE_DATA_LIST where uid = '{}'".format(uid)
3177
                    cursor.execute(sql)
3178

    
3179
                conn.commit()
3180

    
3181
            # Catch the exception
3182
            except Exception as ex:
3183
                # Roll back any change if something goes wrong
3184
                conn.rollback()
3185
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3186
                                                          sys.exc_info()[-1].tb_lineno))
3187

    
3188
    def get_valve_attributes(self):
3189
        """ return valve attributes """
3190

    
3191
        from SymbolAttr import SymbolAttr
3192

    
3193
        res = None
3194
        if not hasattr(self, '_valve_attributes'):
3195
            self._valve_attributes = []
3196

    
3197
            conn = self.project.database.connect()
3198
            with conn:
3199
                try:
3200
                    # Get a cursor object
3201
                    cursor = conn.cursor()
3202

    
3203
                    sql = "select distinct A.Attribute from SymbolAttribute A join SymbolType B on A.SymbolType_UID=B.UID " \
3204
                          "where B.Category = 'Piping'"
3205
                    cursor.execute(sql)
3206
                    rows = cursor.fetchall()
3207
                    for row in rows:
3208
                        attr = SymbolAttr()
3209
                        attr.Attribute = row[0]
3210
                        self._valve_attributes.append(attr)
3211

    
3212
                    res = self._valve_attributes
3213
                # Catch the exception
3214
                except Exception as ex:
3215
                    print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3216
                                                               sys.exc_info()[-1].tb_lineno))
3217
        else:
3218
            res = self._valve_attributes
3219

    
3220
        return res
3221

    
3222
    def get_valve_data_list(self, drawings=None):
3223
        """get valve data list"""
3224

    
3225
        result = []
3226
        conn = self.project.database.connect()
3227
        with conn:
3228
            try:
3229
                # Get a cursor object
3230
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
3231

    
3232
                sql = "select a.UID,D.Name,E.Name as 'Drawing Name',C.Attribute,B.Value from Components a " \
3233
                      "join Attributes B on a.UID=B.Components_UID " \
3234
                      "join SymbolAttribute C on B.SymbolAttribute_UID=C.UID " \
3235
                      "join Symbol D on a.Symbol_UID=D.UID " \
3236
                      "join Drawings E on a.Drawings_UID=E.UID " \
3237
                      "where a.Symbol_UID in (select UID from Symbol where SymbolType_UID in " \
3238
                      "(select UID from SymbolType where Category in ('Piping')))"
3239
                if drawings is not None:
3240
                    doc_names = "','".join(drawings)
3241
                    sql += f" and A.Drawings_UID in (select UID from Drawings where Name in ('{doc_names}'))"
3242

    
3243
                cursor.execute(sql)
3244
                rows = cursor.fetchall()
3245
                for row in rows:
3246
                    matches = [res for res in result if res['UID'] == row['UID']]
3247
                    if matches:
3248
                        matches[0][row['Attribute']] = row['Value']
3249
                    else:
3250
                        data = {'UID': row['UID'], 'ITEM_NO': row['Name'], 'Drawing Name': row['Drawing Name'],
3251
                                row['Attribute']: row['Value']}
3252
                        result.append(data)
3253

    
3254
            # Catch the exception
3255
            except Exception as ex:
3256
                from App import App
3257
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3258
                                                              sys.exc_info()[-1].tb_lineno)
3259
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3260

    
3261
        return result
3262

    
3263
    def get_instrument_attributes(self):
3264
        """ return valve attributes """
3265

    
3266
        from SymbolAttr import SymbolAttr
3267

    
3268
        res = None
3269
        if not hasattr(self, '_inst_attributes'):
3270
            self._inst_attributes = []
3271

    
3272
            with self.project.database.connect() as conn:
3273
                try:
3274
                    # Get a cursor object
3275
                    cursor = conn.cursor()
3276

    
3277
                    sql = "select distinct A.Attribute from SymbolAttribute A join SymbolType B on A.SymbolType_UID=B.UID " \
3278
                          "where B.Category = 'Instrumentation'"
3279
                    cursor.execute(sql)
3280
                    rows = cursor.fetchall()
3281
                    for row in rows:
3282
                        attr = SymbolAttr()
3283
                        attr.Attribute = row[0]
3284
                        self._inst_attributes.append(attr)
3285

    
3286
                    res = self._inst_attributes
3287
                # Catch the exception
3288
                except Exception as ex:
3289
                    print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3290
                                                               sys.exc_info()[-1].tb_lineno))
3291
        else:
3292
            res = self._inst_attributes
3293

    
3294
        return res
3295

    
3296
    '''
3297
        @brief      get instrument data list
3298
        @author     kyouho
3299
        @date       2018.08.14
3300
    '''
3301

    
3302
    def get_instrument_data_list(self, drawings=None):
3303
        result = []
3304
        conn = self.project.database.connect()
3305
        with conn:
3306
            try:
3307
                # Get a cursor object
3308
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
3309

    
3310
                sql = "select a.UID,D.Name,E.Name as 'Drawing Name',C.Attribute,B.Value from Components a " \
3311
                      "join Attributes B on a.UID=B.Components_UID " \
3312
                      "join SymbolAttribute C on B.SymbolAttribute_UID=C.UID " \
3313
                      "join Symbol D on a.Symbol_UID=D.UID " \
3314
                      "join Drawings E on a.Drawings_UID=E.UID " \
3315
                      "where a.Symbol_UID in (select UID from Symbol where SymbolType_UID in " \
3316
                      "(select UID from SymbolType where Category in ('Instrumentation')))"
3317
                if drawings is not None:
3318
                    doc_names = "','".join(drawings)
3319
                    sql += f" and A.Drawings_UID in (select UID from Drawings where Name in ('{doc_names}'))"
3320

    
3321
                cursor.execute(sql)
3322
                rows = cursor.fetchall()
3323
                for row in rows:
3324
                    matches = [res for res in result if res['UID'] == row['UID']]
3325
                    if matches:
3326
                        matches[0][row['Attribute']] = row['Value']
3327
                    else:
3328
                        data = {'UID': row['UID'], 'ITEM_NO': row['Name'], 'Drawing Name': row['Drawing Name'],
3329
                                row['Attribute']: row['Value']}
3330
                        result.append(data)
3331
            # Catch the exception
3332
            except Exception as ex:
3333
                from App import App
3334
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3335
                                                              sys.exc_info()[-1].tb_lineno)
3336
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3337

    
3338
        return result
3339

    
3340
    def get_note_attributes(self):
3341
        """ return note attributes """
3342

    
3343
        from SymbolAttr import SymbolAttr
3344

    
3345
        res = None
3346
        if not hasattr(self, '_note_attributes'):
3347
            self._note_attributes = []
3348

    
3349
            conn = self.project.database.connect()
3350
            with conn:
3351
                try:
3352
                    # Get a cursor object
3353
                    cursor = conn.cursor()
3354

    
3355
                    sql = "select distinct A.Attribute from SymbolAttribute A join SymbolType B on A.SymbolType_UID=B.UID " \
3356
                          "where B.Category='General' and B.Type='Notes'"
3357
                    cursor.execute(sql)
3358
                    rows = cursor.fetchall()
3359
                    for row in rows:
3360
                        attr = SymbolAttr()
3361
                        attr.Attribute = row[0]
3362
                        self._note_attributes.append(attr)
3363

    
3364
                    res = self._note_attributes
3365
                # Catch the exception
3366
                except Exception as ex:
3367
                    print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3368
                                                               sys.exc_info()[-1].tb_lineno))
3369
        else:
3370
            res = self._note_attributes
3371

    
3372
        return res
3373

    
3374
    def get_note_data_list(self, drawings=None):
3375
        """ get note data list """
3376
        result = []
3377

    
3378
        conn = self.project.database.connect()
3379
        with conn:
3380
            try:
3381
                # Get a cursor object
3382
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
3383

    
3384
                sql = "select a.UID,D.Name,E.Name as 'Drawing Name',C.Attribute,B.Value from Components a " \
3385
                      "join Attributes B on a.UID=B.Components_UID " \
3386
                      "join SymbolAttribute C on B.SymbolAttribute_UID=C.UID " \
3387
                      "join Symbol D on a.Symbol_UID=D.UID " \
3388
                      "join Drawings E on a.Drawings_UID=E.UID " \
3389
                      "where a.Symbol_UID in (select UID from Symbol where SymbolType_UID in " \
3390
                      "(select UID from SymbolType where Category='General' and Type='Notes'))"
3391
                if drawings is not None:
3392
                    doc_names = "','".join(drawings)
3393
                    sql += f" and A.Drawings_UID in (select UID from Drawings where Name in ('{doc_names}'))"
3394

    
3395
                cursor.execute(sql)
3396
                rows = cursor.fetchall()
3397
                for row in rows:
3398
                    matches = [res for res in result if res['UID'] == row['UID']]
3399
                    if matches:
3400
                        matches[0][row['Attribute']] = row['Value']
3401
                    else:
3402
                        data = {'UID': row['UID'], 'ITEM_NO': row['Name'], 'Drawing Name': row['Drawing Name'],
3403
                                row['Attribute']: row['Value']}
3404
                        result.append(data)
3405
            # Catch the exception
3406
            except Exception as ex:
3407
                from App import App
3408
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3409
                                                              sys.exc_info()[-1].tb_lineno)
3410
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3411

    
3412
        return result
3413

    
3414
    def saveToDatabase(self, items, show_progress=None):
3415
        """ save given items to database """
3416
        # delete all datas of current drawing
3417
        drawing_name = self.activeDrawing.name
3418
        drawing_uid = self.activeDrawing.UID
3419

    
3420
        queries = {'first':[], 'second':[]}
3421
        for item in items:
3422
            if hasattr(item, 'toSql_return_separately'):
3423
                sql, sqlLater = item.toSql_return_separately()
3424
                queries['first'].append(sql)
3425
                queries['second'].append(sqlLater)
3426
            else:
3427
                queries['first'].append(item.toSql())
3428

    
3429
        with self.project.database.connect() as conn:
3430
            try:
3431
                # Get a cursor object
3432
                cursor = conn.cursor()
3433
                if self.project.database.db_type == 'SQLite':
3434
                    cursor.execute('begin')
3435

    
3436
                sql = "delete from LINE_DATA_LIST where PNID_NO = '{}'".format(drawing_name)
3437
                cursor.execute(sql)
3438
                sql = "delete from TitleBlockValues where Drawings_UID = '{}'".format(drawing_uid)
3439
                cursor.execute(sql)
3440

    
3441
                # delete LineNoAttributes
3442
                sql = f"delete from LineNoAttributes where Components_UID in " \
3443
                      f"(select UID from Components where Drawings_UID='{drawing_uid}')"
3444
                cursor.execute(sql)
3445

    
3446
                # delete Attributes
3447
                sql = f"delete from Attributes where Components_UID in " \
3448
                      f"(select UID from Components where Drawings_UID='{drawing_uid}')"
3449
                cursor.execute(sql)
3450

    
3451
                # delete Associations
3452
                sql = f"delete from Associations where Components_UID in " \
3453
                      f"(select UID from Components where Drawings_UID='{drawing_uid}')"
3454
                cursor.execute(sql)
3455

    
3456
                # delete Points
3457
                sql = f"delete from Points where Components_UID in " \
3458
                      f"(select UID from Components where Drawings_UID='{drawing_uid}')"
3459
                cursor.execute(sql)
3460

    
3461
                # delete PipeRunItems
3462
                sql = f"delete from PipeRunItems where PipeRuns_UID in " \
3463
                      f"(select UID from PipeRuns where Drawings_UID='{drawing_uid}')"
3464
                cursor.execute(sql)
3465

    
3466
                # delete PipeRuns
3467
                sql = f"delete from PipeRuns where Drawings_UID='{drawing_uid}'"
3468
                cursor.execute(sql)
3469

    
3470
                # delete Components 
3471
                sql = "delete from Components where Drawings_UID='{}'".format(drawing_uid)
3472
                cursor.execute(sql)
3473

    
3474
                progress = 0
3475
                length = len(queries['first']) + len(queries['second'])
3476
                for sql in queries['first']:
3477
                    if type(sql) is list:
3478
                        for item in sql:
3479
                            if item is not None and 2 == len(item):
3480
                                cursor.executemany(self.project.database.to_sql(item[0]), item[1])
3481
                    else:
3482
                        if sql is not None and 2 == len(sql):
3483
                            cursor.executemany(self.project.database.to_sql(sql[0]), sql[1])
3484

    
3485
                    if show_progress:
3486
                        show_progress.emit(int((progress / length)*100))
3487
                    progress += 1
3488

    
3489
                for sql in queries['second']:
3490
                    if type(sql) is list:
3491
                        for item in sql:
3492
                            if item is not None and 2 == len(item):
3493
                                cursor.executemany(self.project.database.to_sql(item[0]), item[1])
3494
                    else:
3495
                        if sql is not None and 2 == len(sql):
3496
                            cursor.executemany(self.project.database.to_sql(sql[0]), sql[1])
3497

    
3498
                    if show_progress:
3499
                        show_progress.emit(int((progress / length)*100))
3500
                    progress += 1
3501

    
3502
                if show_progress:
3503
                    show_progress.emit(99)
3504

    
3505
                if self.project.database.db_type == 'SQLite':
3506
                    cursor.execute('commit')
3507
                else:
3508
                    conn.commit()
3509
            # Catch the exception
3510
            except Exception as ex:
3511
                # Roll back any change if something goes wrong
3512
                conn.rollback()
3513

    
3514
                from App import App
3515
                message = 'error occurred({}\\n{}) in {}:{}'.format(repr(ex), sql,
3516
                                                                    sys.exc_info()[-1].tb_frame.f_code.co_filename,
3517
                                                                    sys.exc_info()[-1].tb_lineno)
3518
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3519

    
3520
    '''
3521
        @brief      set equipment data list
3522
        @author     humkyung
3523
        @date       2018.05.03
3524
    '''
3525

    
3526
    def setEquipmentDataList(self, dataList):
3527
        conn = self.project.database.connect()
3528
        with conn:
3529
            try:
3530
                # Get a cursor object
3531
                cursor = conn.cursor()
3532

    
3533
                for data in dataList:
3534
                    sql = "insert into EQUIPMENT_DATA_LIST(UID, ITEM_NO, SERVICE, NO_REQ, FLUID, DESC_OF_PART, OPERATION_CONDITION_TEMP, OPERATION_CONDITION_PRESS, DESIGN_CONDITION_TEMP, DESIGN_CONDITION_PRESS, MATERIAL, WEIGHT, POWER, INSULATION, PNID_NO, REV) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
3535
                    param = tuple(data)
3536
                    cursor.execute(self.project.database.to_sql(sql), param)
3537
                conn.commit()
3538
            # Catch the exception
3539
            except Exception as ex:
3540
                # Roll back any change if something goes wrong
3541
                conn.rollback()
3542

    
3543
                from App import App
3544
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3545
                                                              sys.exc_info()[-1].tb_lineno)
3546
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3547

    
3548
    '''
3549
        @brief      set instrumnet data list
3550
        @author     kyoyho
3551
        @date       2018.08.14
3552
    '''
3553

    
3554
    def setInstrumentDataList(self, dataList):
3555
        conn = self.project.database.connect()
3556
        with conn:
3557
            try:
3558
                # Get a cursor object
3559
                cursor = conn.cursor()
3560

    
3561
                for data in dataList:
3562
                    sql = "insert into INSTRUMENT_DATA_LIST(UID, ITEM_NO, SERVICE, FLOW_RATE, PRESSURE, TEMPERATURE, TPYE, RANGE, NOR_LEVEL_MM, NOR_LEVEL_PERCENT, DEL_PRESS, SHUT_OFF, LOCATION, PNID_NO, REV) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
3563
                    param = tuple(data)
3564
                    cursor.execute(sql, param)
3565
                conn.commit()
3566

    
3567
            # Catch the exception
3568
            except Exception as ex:
3569
                # Roll back any change if something goes wrong
3570
                conn.rollback()
3571

    
3572
                from App import App
3573
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3574
                                                              sys.exc_info()[-1].tb_lineno)
3575
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3576

    
3577
    def getDrawings(self):
3578
        """ get drawings """
3579
        from Drawing import Drawing
3580

    
3581
        res = []
3582

    
3583
        with self.project.database.connect() as conn:
3584
            try:
3585
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
3586
                sql = 'select UID,[NAME],[DATETIME] from Drawings'
3587
                cursor.execute(sql)
3588
                for row in cursor.fetchall():
3589
                    res.append(Drawing(row['UID'], row['NAME'], row['DATETIME']))
3590
            # Catch the exception
3591
            except Exception as ex:
3592
                from App import App
3593
                message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
3594
                                                              sys.exc_info()[-1].tb_lineno)
3595
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3596

    
3597
        return res
3598

    
3599
    def saveDrawings(self, drawings):
3600
        """save given drawings"""
3601

    
3602
        import uuid
3603

    
3604
        with self.project.database.connect() as conn:
3605
            try:
3606
                # Get a cursor object
3607
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
3608
                if self.project.database.db_type == 'SQLite':
3609
                    cursor.execute('begin')
3610

    
3611
                for drawing in drawings:
3612
                    if drawing.UID is None:
3613
                        # get image data
3614
                        image_blob_data = None
3615
                        #file_path = os.path.join(self.project.getDrawingFilePath(), drawing.name)
3616
                        #if drawing.name and os.path.isfile(file_path):
3617
                        #    with open(file_path.encode('utf-8'), 'rb') as file:
3618
                        #        image_blob_data = file.read()
3619
                        # up to here
3620

    
3621
                        sql = self.project.database.to_sql(
3622
                            'insert into Drawings(UID, [NAME], [DATETIME], [Image]) values(?, ?, ?, ?)')
3623
                        param = tuple([str(uuid.uuid4()), drawing.name, '', image_blob_data])
3624
                        drawing.UID = param[0]
3625
                    else:
3626
                        sql = self.project.database.to_sql("update Drawings set [NAME]=?,[DATETIME]=? where UID=?")
3627
                        param = (drawing.name, drawing.datetime, str(drawing.UID))
3628
                        #param = (drawing.name, drawing.datetime, image_blob_data, str(drawing.UID))
3629

    
3630
                    cursor.execute(sql, param)
3631

    
3632
                if self.project.database.db_type == 'SQLite':
3633
                    cursor.execute('commit')
3634
                else:
3635
                    conn.commit()
3636
            # Catch the exception
3637
            except Exception as ex:
3638
                # Roll back any change if something goes wrong
3639
                conn.rollback()
3640

    
3641
                from App import App
3642
                message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
3643
                                                              sys.exc_info()[-1].tb_lineno)
3644
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3645

    
3646
    '''
3647
        @brief  get IsOriginDetect ComboBox Items
3648
    '''
3649

    
3650
    def getIsOriginDetectComboBoxItems(self):
3651
        return [("원본 도면", 0), ("텍스트 제거 도면", 1)]
3652

    
3653
    '''
3654
        @brief  get IsOriginDetect ComboBox Items
3655
    '''
3656

    
3657
    def getOcrOptionComboBoxItems(self):
3658
        return [("OCR 미적용", 0), ("일반 심볼", 1), ("Instrument 계통", 2)]
3659

    
3660
    '''
3661
        @brief      Return Symbol Type Items
3662
        @author     Jeongwoo
3663
        @date       18.04.20
3664
        @history    18.05.08    Jeongwoo type index changed
3665
    '''
3666

    
3667
    def getSymbolTypeList(self):
3668
        symbolTypeList = []
3669

    
3670
        with self.project.database.connect() as conn:
3671
            cursor = conn.cursor()
3672
            sql = 'SELECT * FROM SymbolType ORDER BY Type ASC'
3673
            try:
3674
                cursor.execute(sql)
3675
                rows = cursor.fetchall()
3676
                for row in rows:
3677
                    symbolTypeList.append((row[0], row[1], row[2]))  # UID, category, type
3678
            except Exception as ex:
3679
                from App import App
3680
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3681
                                                              sys.exc_info()[-1].tb_lineno)
3682
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3683

    
3684
        return symbolTypeList
3685

    
3686
    '''
3687
        @brief      Get Symbol Category by Symbol Type
3688
        @author     Jeongwoo
3689
        @date       2018.05.09
3690
    '''
3691

    
3692
    def getSymbolCategoryByType(self, type):
3693
        category = None
3694
        if type in self._symbolType:
3695
            return self._symbolType[type]
3696

    
3697
        with self.project.database.connect() as conn:
3698
            try:
3699
                cursor = conn.cursor()
3700
                sql = self.project.database.to_sql('SELECT Category FROM SymbolType WHERE [Type] = ?')
3701
                cursor.execute(sql, (type,))
3702
                rows = cursor.fetchall()
3703
                if rows is not None and len(rows) > 0:
3704
                    category = rows[0][0]
3705
                    self._symbolType[type] = category
3706
            except Exception as ex:
3707
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3708
                                                          sys.exc_info()[-1].tb_lineno))
3709

    
3710
        return category
3711

    
3712
    '''
3713
        @brief      Check Symbol Type is included in 'Equipment' Category
3714
        @author     Jeongwoo
3715
        @date       2018.05.09
3716
    '''
3717

    
3718
    def isEquipmentType(self, type):
3719
        category = self.getSymbolCategoryByType(type)
3720
        return category is not None and category == 'Equipment'
3721

    
3722
    '''
3723
        @brief      Return Symbol Type Items with "None"
3724
        @author     Jeongwoo
3725
        @date       18.04.06
3726
        @history    Seperate SymbolTypeList and "None"
3727
    '''
3728

    
3729
    def getSymbolTypeComboBoxItems(self):
3730
        symbolTypeList = [symbol_type for symbol_type in self.getSymbolTypeList() if symbol_type[1]]
3731
        symbolTypeList.insert(0, ('None', 'None', 'None'))
3732

    
3733
        return symbolTypeList
3734

    
3735
    '''
3736
        @brief  get Base Symbol ComboBox Items
3737
    '''
3738

    
3739
    def getBaseSymbolComboBoxItems(self, type=None):
3740
        bsymbolNameList = self.getSymbolNameListByType(type)
3741
        bsymbolNameList.sort()
3742
        bsymbolNameList.insert(0, "None")
3743
        return bsymbolNameList
3744

    
3745
    '''
3746
        @brief  get Additional Symbol ComboBox Items
3747
    '''
3748

    
3749
    def getAdditionalSymbolComboBoxItems(self):
3750
        asymbolNameList = self.getSymbolNameList()
3751
        asymbolNameList.sort()
3752
        asymbolNameList.insert(0, "None")
3753
        return asymbolNameList
3754

    
3755
    '''
3756
        @brief  get Additional Symbol's default direction ComboBox Items
3757
    '''
3758

    
3759
    def getDefaultSymbolDirectionComboBoxItems(self):
3760
        return [("UP", 0), ("DOWN", 2), ("LEFT", 3), ("RIGHT", 1)]
3761

    
3762
    '''
3763
        @brief  getter of activeDrawing
3764
        @author humkyung
3765
        @date   2018.07.07
3766
    '''
3767

    
3768
    @property
3769
    def activeDrawing(self):
3770
        return self._activeDrawing
3771

    
3772
    '''
3773
        @brief  setter of activeDrawing
3774
        @author humkyung
3775
        @date   2018.07.07
3776
    '''
3777

    
3778
    @activeDrawing.setter
3779
    def activeDrawing(self, value):
3780
        if self._activeDrawing:
3781
            del self._activeDrawing
3782

    
3783
        self._activeDrawing = value
3784

    
3785
    def getColNames(self, table):
3786
        """ return column names of given table and attribute names if tabe is VALVE_DATA_LIST or EQUIPMET_DATA_LIST """
3787
        res = None
3788

    
3789
        conn = self.project.database.connect()
3790
        with conn:
3791
            try:
3792
                cursor = conn.cursor()
3793
                cursor.execute('select * from {}'.format(table))
3794
                res = [col_name[0] for col_name in cursor.description]
3795

    
3796
                if table == 'EQUIPMET_DATA_LIST' or table == 'VALVE_DATA_LIST':
3797
                    sql = 'select distinct c.Attribute from {} a left join Attributes b on a.uid=b.Components_UID ' \
3798
                          'left join SymbolAttribute c on b.SymbolAttribute_UID=c.UID where c.Attribute is not NULL'.format(
3799
                        table)
3800
                    cursor.execute(sql)
3801
                    rows = cursor.fetchall()
3802
                    for row in rows:
3803
                        res.append(row[0])
3804
            # Catch the exception
3805
            except Exception as ex:
3806
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3807
                                                          sys.exc_info()[-1].tb_lineno))
3808

    
3809
        return res
3810

    
3811
    '''
3812
        @brief  getter of OCRData
3813
        @author humkyung
3814
        @date   2018.11.19
3815
    '''
3816

    
3817
    @property
3818
    def OCRData(self):
3819
        if self._OCRData is None:
3820
            configs = self.getConfigs('Text Recognition', 'OCR Data')
3821
            self._OCRData = configs[0].value if 1 == len(configs) else 'eng'
3822

    
3823
        return self._OCRData
3824

    
3825
    '''
3826
        @brief  setter of OCRData
3827
        @author humkyung
3828
        @date   2018.11.19
3829
    '''
3830

    
3831
    @OCRData.setter
3832
    def OCRData(self, value):
3833
        self._OCRData = value
3834

    
3835

    
3836
if __name__ == '__main__':
3837
    from AppDocData import AppDocData
3838

    
3839
    instance = AppDocData.instance()
클립보드 이미지 추가 (최대 크기: 500 MB)