프로젝트

일반

사용자정보

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

hytos / DTI_PID / DTI_PID / AppDocData.py @ 18a45d2e

이력 | 보기 | 이력해설 | 다운로드 (151 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 = ?, minMatchPoint = ?, isDetectOrigin = ?,
560
                        rotationCount = ?, ocrOption = ?, isContainChild = ?, originalPoint = ?, connectionPoint = ?,
561
                        baseSymbol = ?, additionalSymbol = ?, isExceptDetect = ?, hasInstrumentLabel = ?, width = ?, height = ?, flip = ?, text_area = ?,
562
                    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.getText_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.text_area\
603
                        b.UID FROM Symbol a inner join SymbolType b on a.SymbolType_UID=b.UID WHERE a.IsExceptDetect = 0 order by width * height desc"""
604
            try:
605
                cursor.execute(sql)
606
                rows = cursor.fetchall()
607
                for row in rows:
608
                    sym = symbol.SymbolBase(row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9],
609
                                            row[10], row[11], row[12], row[13], row[14], row[0], iType=row[17],
610
                                            detectFlip=row[15], text_area=row[16])  # uid is last item
611
                    targetSymbolList.append(sym)
612
            except Exception as ex:
613
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
614
                                                          sys.exc_info()[-1].tb_lineno))
615

    
616
        return targetSymbolList
617

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

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

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

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

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

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

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

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

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

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

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

    
699
        return style
700

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

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

    
710
        try:
711
            self.buildAppDatabase()
712

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

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

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

    
736
        return styles
737

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

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

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

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

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

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

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

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

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

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

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

    
830
        return prjDatabaseFilePath
831

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

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

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

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

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

    
891
        self._titleBlockProperties = None
892

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

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

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

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

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

    
926
        return res
927

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

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

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

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

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

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

    
967
        return res
968

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

    
972
        from SymbolAttr import SymbolAttr
973

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

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

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

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

    
1000
        return res
1001

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

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

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

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

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

    
1040
        return res
1041

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

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

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

    
1071
        return res
1072

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

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

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

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

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

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

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

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

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

    
1163
        projectList = []
1164

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

    
1187
        return projectList
1188

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

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

    
1208
        return res
1209

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

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

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

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

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

    
1243
        return res
1244

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

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

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

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

    
1274
        return self._areas
1275

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

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

    
1288
        return None
1289

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

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

    
1302
                    sql = "select * from configuration"
1303

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

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

    
1318
        return res
1319

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

    
1327
        res = []
1328

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

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

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

    
1353
        return res
1354

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

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

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

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

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

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

    
1410
    def saveAppConfigs(self, configs):
1411
        """
1412
        @brief      save application configurations
1413
        @author     humkyung
1414
        @date       2018.10.01
1415
        """
1416

    
1417
        # Creates or opens a file called mydb with a SQLite3 DB
1418
        dbPath = self.getAppDbPath()
1419
        conn = sqlite3.connect(dbPath)
1420
        with conn:
1421
            try:
1422
                # Get a cursor object
1423
                cursor = conn.cursor()
1424

    
1425
                for config in configs:
1426
                    value = config.value
1427
                    if type(value) is str and "'" in value:
1428
                        value = value.replace("'", "''")
1429

    
1430
                    sql = "insert or replace into configuration values(?,?,?)"
1431
                    param = (config.section, config.key, value)
1432

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

    
1442
    '''
1443
        @brief  delete configurations
1444
        @author humkyung
1445
        @date   2018.06.29
1446
    '''
1447

    
1448
    def deleteConfigs(self, section, key=None):
1449
        conn = self.project.database.connect()
1450
        with conn:
1451
            try:
1452
                # Get a cursor object
1453
                cursor = conn.cursor()
1454

    
1455
                if key is not None:
1456
                    sql = "delete from configuration where section='{}' and key='{}'".format(section, key)
1457
                else:
1458
                    sql = "delete from configuration where section='{}'".format(section)
1459
                cursor.execute(sql)
1460

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

    
1469
    def deleteAppConfigs(self, section, key=None):
1470
        """
1471
        @brief  delete application configurations
1472
        @author humkyung
1473
        @date   2018.11.01
1474
        """
1475

    
1476
        # Creates or opens a file called mydb with a SQLite3 DB
1477
        dbPath = self.getAppDbPath()
1478
        conn = sqlite3.connect(dbPath)
1479
        with conn:
1480
            try:
1481
                # Get a cursor object
1482
                cursor = conn.cursor()
1483

    
1484
                if key is not None:
1485
                    sql = "delete from configuration where section='{}' and key='{}'".format(section, key)
1486
                else:
1487
                    sql = "delete from configuration where section='{}'".format(section)
1488
                cursor.execute(sql)
1489

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

    
1498
    '''
1499
        @brief      set area list
1500
        @history    humkyung 2018.05.18 round area coordinate and dimension before saving
1501
        @history    euisung  2018.11.20 add self._area reset process
1502
    '''
1503

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

    
1515
        # Creates or opens a file called mydb with a SQLite3 DB
1516
        conn = self.project.database.connect()
1517
        with conn:
1518
            try:
1519
                # Get a cursor object
1520
                cursor = conn.cursor()
1521

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

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

    
1543
    def getSymbolNameList(self):
1544
        """ get symbol name list """
1545
        symbolNametList = []
1546

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

    
1560
        return symbolNametList
1561

    
1562
    '''
1563
        @brief      get symbol name list by symbol Type
1564
        @author     Jeongwoo
1565
        @date       18.04.06
1566
        @history    .
1567
    '''
1568

    
1569
    def getSymbolNameListByType(self, type):
1570
        symbolNametList = []
1571

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

    
1587
        return symbolNametList
1588

    
1589
    '''
1590
        @brief  delete added symbol data
1591
    '''
1592

    
1593
    def deleteSymbol(self, fileName):
1594
        ret = False
1595

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

    
1614
    '''
1615
        @brief  get symbol name
1616
        @history    18.04.24    Jeongwoo    Add isExceptDetect Field
1617
    '''
1618

    
1619
    def getSymbolByQuery(self, fieldName, param):
1620
        ret = None
1621

    
1622
        if fieldName in self._symbolBase:
1623
            if param in self._symbolBase[fieldName]:
1624
                ret = self._symbolBase[fieldName][param]
1625
                return ret
1626
        else:
1627
            self._symbolBase[fieldName] = {}
1628

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

    
1650
        return ret
1651

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

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

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

    
1686
        return ret
1687

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

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

    
1702
        conn = self.project.database.connect()
1703
        with conn:
1704
            try:
1705
                # Get a cursor object
1706
                cursor = conn.cursor()
1707

    
1708
                sql = "select UID,Code,Metric,Inch,InchStr,AllowableInchStr,MetricStr,AllowableMetricStr from NominalDiameter ORDER BY {} DESC".format(
1709
                    orderStr)
1710
                cursor.execute(sql)
1711
                rows = cursor.fetchall()
1712
                for row in rows:
1713
                    pipeSize = NominalPipeSize(row[0], row[1], float(row[2]) if row[2] else None,
1714
                                               float(row[3]) if row[3] else None, row[4], row[5], row[6], row[7])
1715
                    pipeSize.sizeUnit = sizeUnit
1716
                    if forCheckLineNumber:
1717
                        if sizeUnit == 'Inch' and pipeSize.inchStr:
1718
                            res.append(pipeSize.inchStr)
1719
                        elif sizeUnit == 'Metric' and pipeSize.metricStr:
1720
                            res.append(pipeSize.metricStr)
1721
                    else:
1722
                        res.append(pipeSize)
1723
            # Catch the exception
1724
            except Exception as ex:
1725
                from App import App
1726
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1727
                                                              sys.exc_info()[-1].tb_lineno)
1728
                App.mainWnd().addMessage.emit(MessageType.Error, message)
1729

    
1730
        return res
1731

    
1732
    '''
1733
        @brief      insert NominalDiameter table
1734
        @author     kyouho
1735
        @date       2018.07.16
1736
    '''
1737

    
1738
    def insertNomialPipeSize(self, pipeSizes):
1739
        conn = self.project.database.connect()
1740
        with conn:
1741
            try:
1742
                # Get a cursor object
1743
                cursor = conn.cursor()
1744
                for pipeSize in pipeSizes:
1745
                    sql = pipeSize.toSql()
1746
                    if type(sql) is list and len(sql) == 1:
1747
                        cursor.execute(self.project.database.to_sql(sql[0][0]), sql[0][1])
1748

    
1749
                conn.commit()
1750
            # Catch the exception
1751
            except Exception as ex:
1752
                # Roll back any change if something goes wrong
1753
                conn.rollback()
1754

    
1755
                from App import App
1756
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1757
                                                              sys.exc_info()[-1].tb_lineno)
1758
                App.mainWnd().addMessage.emit(MessageType.Error, message)
1759

    
1760
    '''
1761
        @brief      delete NominalDiameter table
1762
        @author     kyouho
1763
        @date       2018.07.16
1764
    '''
1765

    
1766
    def deleteNomialPipeSize(self):
1767
        conn = self.project.database.connect()
1768
        with conn:
1769
            cursor = conn.cursor()
1770
            sql = "DELETE FROM NominalDiameter"
1771
            try:
1772
                cursor.execute(sql)
1773
                conn.commit()
1774
            except Exception as ex:
1775
                conn.rollback()
1776
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1777
                                                          sys.exc_info()[-1].tb_lineno))
1778

    
1779
    '''
1780
        @brief      convert inch to metric
1781
        @author     kyouho
1782
        @date       2018.07.09
1783
    '''
1784

    
1785
    def convertInchToMetric(self, inch):
1786
        result = ''
1787
        conn = self.project.database.connect()
1788
        with conn:
1789
            try:
1790
                # Get a cursor object
1791
                cursor = conn.cursor()
1792

    
1793
                sql = "select MetricStr from NominalDiameter WHERE InchStr = ?"
1794
                param = (inch,)
1795
                cursor.execute(sql, param)
1796
                rows = cursor.fetchall()
1797

    
1798
                if rows:
1799
                    result = rows[0][0]
1800
                # Catch the exception
1801
            except Exception as ex:
1802
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1803
                                                          sys.exc_info()[-1].tb_lineno))
1804

    
1805
        return result
1806

    
1807
    '''
1808
        @brief      get Color MaxUID
1809
        @author     kyouho
1810
        @date       2018.07.03
1811
    '''
1812

    
1813
    def getMaxColorUID(self):
1814
        result = 0
1815

    
1816
        conn = self.project.database.connect()
1817
        with conn:
1818
            try:
1819
                # Get a cursor object
1820
                cursor = conn.cursor()
1821

    
1822
                sql = "select MAX(UID) from Colors"
1823
                cursor.execute(sql)
1824
                rows = cursor.fetchall()
1825

    
1826
                result = rows[0][0]
1827
                # Catch the exception
1828
            except Exception as ex:
1829
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1830
                                                          sys.exc_info()[-1].tb_lineno))
1831

    
1832
        return result
1833

    
1834
    '''
1835
        @brief      insert Color property
1836
        @author     kyouho
1837
        @date       2018.07.09
1838
    '''
1839

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

    
1857
    '''
1858
        @brief      delete Color property
1859
        @author     kyouho
1860
        @date       2018.07.09
1861
    '''
1862

    
1863
    def deletePropertyColor(self, property):
1864
        conn = self.project.database.connect()
1865
        with conn:
1866
            try:
1867
                # Get a cursor object
1868
                cursor = conn.cursor()
1869

    
1870
                sql = "DELETE FROM Colors WHERE PROPERTY = '{}'".format(property)
1871
                cursor.execute(sql)
1872
                conn.commit()
1873
                # Catch the exception
1874
            except Exception as ex:
1875
                # Roll back any change if something goes wrong
1876
                conn.rollback()
1877
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1878
                                                          sys.exc_info()[-1].tb_lineno))
1879

    
1880
    '''
1881
        @brief      get Fluid Code
1882
        @author     kyouho
1883
        @date       2018.07.03
1884
        @history    kyouho 2018.07.04 kyouho 2018.07.04 forCheckLineNumber get only code
1885
    '''
1886

    
1887
    def getFluidCodeData(self, forCheckLineNumber=False):
1888
        from FluidCodeData import FluidCodeData
1889
        result = []
1890

    
1891
        conn = self.project.database.connect()
1892
        with conn:
1893
            try:
1894
                # Get a cursor object
1895
                cursor = conn.cursor()
1896

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

    
1911
        return result
1912

    
1913
    '''
1914
        @brief      get Symbol Attribute
1915
        @author     kyouho
1916
        @date       2018.07.18
1917
    '''
1918

    
1919
    def checkAttribute(self, attr):
1920
        conn = self.project.database.connect()
1921
        with conn:
1922
            try:
1923
                # Get a cursor object
1924
                cursor = conn.cursor()
1925

    
1926
                sql = 'select UID from SymbolAttribute where UID = ?'
1927
                param = (attr,)
1928
                cursor.execute(sql, param)
1929
                rows = cursor.fetchall()
1930
                if len(rows):
1931
                    return True
1932
                else:
1933
                    return False
1934
                # Catch the exception
1935
            except Exception as ex:
1936
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1937
                                                          sys.exc_info()[-1].tb_lineno))
1938

    
1939
        return False
1940

    
1941
    def read_drawing_shape(self, drawing):
1942
        """read drawing shape"""
1943

    
1944
        res = None
1945

    
1946
        with self.project.database.connect() as conn:
1947
            try:
1948
                # Get a cursor object
1949
                cursor = conn.cursor()
1950

    
1951
                sql = f"select Image from Drawings where UID='{drawing}'"
1952
                cursor.execute(sql)
1953
                records = cursor.fetchall()
1954
                for record in records:
1955
                    res = record[0]
1956
                    break
1957

    
1958
            # Catch the exception
1959
            except Exception as ex:
1960
                from App import App
1961
                # Roll back any change if something goes wrong
1962
                conn.rollback()
1963

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

    
1968
        return res
1969

    
1970
    def read_symbol_shape(self, symbol_name):
1971
        """read symbol shape(image and svg)"""
1972

    
1973
        
1974
        res = (None, None)
1975

    
1976
        # need to test on mssql
1977
        return res
1978

    
1979
        with self.project.database.connect() as conn:
1980
            try:
1981
                # Get a cursor object
1982
                cursor = conn.cursor()
1983

    
1984
                sql = f"select Image, Svg from Symbol where Name='{symbol_name}'"
1985
                cursor.execute(sql)
1986
                records = cursor.fetchall()
1987
                for record in records:
1988
                    res = (record[0], record[1])
1989
                    break
1990

    
1991
            # Catch the exception
1992
            except Exception as ex:
1993
                from App import App
1994
                # Roll back any change if something goes wrong
1995
                conn.rollback()
1996

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

    
2001
        return res
2002

    
2003

    
2004
    def update_symbol_shape(self, symbol_name, image_file, svg_file, image_display_file):
2005
        """update symbol shape"""
2006

    
2007
        # need to test on mssql
2008
        return
2009

    
2010
        with self.project.database.connect() as conn:
2011
            try:
2012
                # Get a cursor object
2013
                cursor = conn.cursor()
2014

    
2015
                cols = []
2016
                params = []
2017

    
2018
                image_blob_data = None
2019
                if image_file and os.path.isfile(image_file):
2020
                    with open(image_file, 'rb') as file:
2021
                        image_blob_data = file.read()
2022
                    cols.append('Image=?')
2023
                    params.append(image_blob_data)
2024

    
2025
                svg_blob_data = None
2026
                if svg_file and os.path.isfile(svg_file):
2027
                    with open(svg_file, 'rb') as file:
2028
                        svg_blob_data = file.read()
2029
                    cols.append('Svg=?')
2030
                    params.append(svg_blob_data)
2031

    
2032
                image_display_blob_data = None
2033
                if image_file and image_display_file and os.path.isfile(image_display_file):
2034
                    with open(image_file, 'rb') as file:
2035
                        image_display_blob_data = file.read()
2036
                    cols.append('Image_display=?')
2037
                    params.append(image_display_blob_data)
2038

    
2039
                sql = f"update Symbol set {','.join(cols)} where Name='{symbol_name}'"
2040
                # Convert data into tuple format
2041
                cursor.execute(self.project.database.to_sql(sql), tuple(params))
2042
                conn.commit()
2043

    
2044
            # Catch the exception
2045
            except Exception as ex:
2046
                from App import App
2047
                # Roll back any change if something goes wrong
2048
                conn.rollback()
2049

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

    
2054
    def getCustomTables(self):
2055
        ''' get custom code tables '''
2056

    
2057
        import uuid
2058
        from CodeTables import CodeTable
2059

    
2060
        with self.project.database.connect() as conn:
2061
            try:
2062
                result = []
2063

    
2064
                # Get a cursor object
2065
                cursor = conn.cursor()
2066

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

    
2084
        return result
2085

    
2086
    '''
2087
        @brief      get Symbol Attribute
2088
        @author     kyouho
2089
        @date       2018.07.18
2090
        @history    humkyung 2018.10.13 load expression
2091
    '''
2092
    def getSymbolAttribute(self, _type):
2093
        import uuid
2094
        from SymbolAttr import SymbolAttr
2095
        from CodeTables import CodeTable
2096

    
2097
        result = []
2098

    
2099
        if self._attributeByType and _type in self._attributeByType:
2100
            new_attr_without_any_binding_data = []
2101
            for attr_old in self._attributeByType[_type]:
2102
                attr = SymbolAttr()
2103
                attr.UID = attr_old.UID
2104
                attr.Attribute = attr_old.Attribute
2105
                attr.DisplayAttribute = attr_old.DisplayAttribute
2106
                attr.AttributeType = attr_old.AttributeType
2107
                attr.AttrAt = attr_old.AttrAt
2108
                attr.Expression = attr_old.Expression
2109
                attr.Target = attr_old.Target
2110
                attr.IsProp = attr_old.IsProp
2111
                attr.Codes = attr_old.Codes
2112
                new_attr_without_any_binding_data.append(attr)
2113
            self._attributeByType[_type] = new_attr_without_any_binding_data
2114

    
2115
            return self._attributeByType[_type]
2116

    
2117
        with self.project.database.connect() as conn:
2118
            try:
2119
                # Get a cursor object
2120
                cursor = conn.cursor()
2121

    
2122
                sql = self.project.database.to_sql(
2123
                    '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]')
2124
                param = (_type,)
2125
                cursor.execute(sql, param)
2126
                rows = cursor.fetchall()
2127
                for row in rows:
2128
                    attr = SymbolAttr()
2129
                    attr.UID = uuid.UUID(row[0])
2130
                    attr.Attribute = row[1]
2131
                    attr.DisplayAttribute = row[2]
2132
                    attr.AttributeType = row[3]
2133
                    attr.AttrAt = row[4]
2134
                    attr.Expression = row[5]
2135
                    attr.Target = row[7]
2136
                    attr.IsProp = row[8]
2137
                    attr.Codes = CodeTable.instance('SymbolAttributeCodeTable', symbol_attribute_uid=row[0])
2138
                    result.append(attr)
2139
            # Catch the exception
2140
            except Exception as ex:
2141
                from App import App
2142
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2143
                                                              sys.exc_info()[-1].tb_lineno)
2144
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2145

    
2146
        self._attributeByType[_type] = result
2147
        return result
2148

    
2149
    '''
2150
        @brief      get Symbol Attribute by UID
2151
        @author     kyouho
2152
        @date       2018.08.17
2153
        @history    humkyung 2018.10.13 load expression
2154
    '''
2155

    
2156
    def getSymbolAttributeByUID(self, UID):
2157
        from SymbolAttr import SymbolAttr
2158

    
2159
        res = None
2160

    
2161
        conn = self.project.database.connect()
2162
        with conn:
2163
            try:
2164
                # Get a cursor object
2165
                cursor = conn.cursor()
2166

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

    
2188
        return res
2189

    
2190
    '''
2191
        @brief      save symbol attributes
2192
        @author     humkyung
2193
        @date       2018.08.14
2194
        @history    humkyung 2018.10.13 save expression
2195
    '''
2196
    def saveSymbolAttributes(self, type, attrs, type_str):
2197
        from CodeTables import CodeTable
2198

    
2199
        with self.project.database.connect() as conn:
2200
            try:
2201
                # Get a cursor object
2202
                cursor = conn.cursor()
2203

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

    
2222
                # update symbol attribute
2223
                sql = self.project.database.to_sql('delete from SymbolAttribute where SymbolType_UID = ?')
2224
                param = (type,)
2225
                cursor.execute(sql, param)
2226

    
2227
                for attr in attrs:
2228
                    sql = self.project.database.to_sql(
2229
                        'insert into SymbolAttribute(UID, SymbolType_UID, Attribute, DisplayAttribute, AttributeType, '
2230
                        'AttrAt, Expression, Target, [index], [Property]) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)')
2231
                    attr.insert(1, type)
2232
                    cursor.execute(sql, tuple(attr[:-1]))
2233
                # up to here
2234

    
2235
                # update symbol attribute code table data
2236
                for attr in attrs:
2237
                    if attr[-1]:
2238
                        for code in attr[-1]:
2239
                            sql = self.project.database.to_sql( \
2240
                                "insert into SymbolAttributeCodeTable(UID, Code, Description, Allowables, SymbolAttribute_UID) VALUES(?,?,?,?,?)")
2241
                            param = (code[0], code[1], code[2], ','.join(code[3]), attr[0])
2242
                            cursor.execute(sql, param)
2243
                # up to here
2244

    
2245
                conn.commit()
2246

    
2247
                if hasattr(self, '_equipment_attributes'):
2248
                    del self._equipment_attributes
2249

    
2250
                if hasattr(self, '_valve_attributes'):
2251
                    del self._valve_attributes
2252

    
2253
                if hasattr(self, '_inst_attributes'):
2254
                    del self._inst_attributes
2255

    
2256
                if hasattr(self, '_note_attributes'):
2257
                    del self._note_attributes
2258
            # Catch the exception
2259
            except Exception as ex:
2260
                # Roll back any change if something goes wrong
2261
                conn.rollback()
2262

    
2263
                from App import App
2264
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2265
                                                              sys.exc_info()[-1].tb_lineno)
2266
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2267

    
2268
            self._attributeByType = {}
2269
            CodeTable.clearTables()
2270

    
2271
    def saveCustomCodes(self, tables):
2272
        ''' save custom code tables and codes '''
2273

    
2274
        from CodeTables import CodeTable
2275

    
2276
        conn = self.project.database.connect()
2277
        with conn:
2278
            try:
2279
                # Get a cursor object
2280
                cursor = conn.cursor()
2281

    
2282
                # delete custom codes and tables
2283
                sql = "delete from CustomCodes"
2284
                cursor.execute(sql)
2285

    
2286
                sql = "delete from CustomTables"
2287
                cursor.execute(sql)
2288
                # up to here
2289

    
2290
                # update symbol attribute code table data
2291
                for table in tables:
2292
                    sql = self.project.database.to_sql("insert into CustomTables (UID, Name, Description) VALUES(?,?,?)")
2293
                    param = (table[0], table[1], table[2])
2294
                    cursor.execute(sql, param)
2295

    
2296
                    for code in table[3]:
2297
                        sql = self.project.database.to_sql( \
2298
                            "insert into CustomCodes(UID, Code, Description, Allowables, Table_UID) VALUES(?,?,?,?,?)")
2299
                        param = (code[0], code[1], code[2], ','.join(code[3]), table[0])
2300
                        cursor.execute(sql, param)
2301
                # up to here
2302

    
2303
                conn.commit()
2304

    
2305
            # Catch the exception
2306
            except Exception as ex:
2307
                # Roll back any change if something goes wrong
2308
                conn.rollback()
2309

    
2310
                from App import App
2311
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2312
                                                              sys.exc_info()[-1].tb_lineno)
2313
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2314

    
2315
            CodeTable.clearTables()
2316

    
2317
    '''
2318
        @brief      save symbol attributes
2319
        @author     humkyung
2320
        @date       2018.08.14
2321
    '''
2322
    def saveLineAttributes(self, attrs):
2323
        conn = self.project.database.connect()
2324
        with conn:
2325
            try:
2326
                # Get a cursor object
2327
                cursor = conn.cursor()
2328

    
2329
                sql = 'delete from LineProperties'
2330
                cursor.execute(sql)
2331

    
2332
                for attr in attrs:
2333
                    sql = self.project.database.to_sql(
2334
                        'insert into LineProperties(UID, Name, DisplayName, Type, LimitNumber, [index]) values(?, ?, ?, ?, ?, ?)')
2335
                    cursor.execute(sql, tuple(attr))
2336

    
2337
                conn.commit()
2338

    
2339
                self._lineNoProperties = None
2340
                self._lineNoPropertiesUID = {}
2341
            # Catch the exception
2342
            except Exception as ex:
2343
                # Roll back any change if something goes wrong
2344
                conn.rollback()
2345

    
2346
                from App import App
2347
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2348
                                                              sys.exc_info()[-1].tb_lineno)
2349
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2350

    
2351
    '''
2352
        @brief      get symbol type id
2353
        @author     kyouho
2354
        @date       2018.08.17
2355
    '''
2356

    
2357
    def getSymbolTypeId(self, symbolType):
2358
        result = []
2359

    
2360
        conn = self.project.database.connect()
2361
        with conn:
2362
            try:
2363
                # Get a cursor object
2364
                cursor = conn.cursor()
2365

    
2366
                sql = self.project.database.to_sql('select UID from SymbolType where Type = ?')
2367
                param = (symbolType,)
2368
                cursor.execute(sql, param)
2369
                rows = cursor.fetchall()
2370

    
2371
                if len(rows):
2372
                    result = rows[0][0]
2373
                else:
2374
                    result = -1
2375
                # Catch the exception
2376
            except Exception as ex:
2377
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2378
                                                          sys.exc_info()[-1].tb_lineno))
2379

    
2380
        return result
2381

    
2382
    '''
2383
        @brief      get Code Table Data
2384
        @author     kyouho
2385
        @date       2018.07.10
2386
    '''
2387

    
2388
    def getCodeTable(self, property, forCheckLineNumber=False, symbol_attribute_uid=None, custom_table_uid=None, custom=False):
2389
        result = []
2390
        conn = self.project.database.connect()
2391
        with conn:
2392
            try:
2393
                # Get a cursor object
2394
                cursor = conn.cursor()
2395

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

    
2437
        return result
2438

    
2439
    def get_components(self, drawing):
2440
        """ get components in given drawing """
2441

    
2442
        with self.project.database.connect() as conn:
2443
            try:
2444
                # Get a cursor object
2445
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
2446

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

    
2459
    def get_opcs(self):
2460
        """ get opc in project """
2461
        with self.project.database.connect() as conn:
2462
            try:
2463
                # Get a cursor object
2464
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
2465

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

    
2480
    def get_opc_relations(self):
2481
        """ get opc relations """
2482
        conn = self.project.database.connect()
2483
        with conn:
2484
            try:
2485
                # Get a cursor object
2486
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
2487

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

    
2504
    def save_opc_relations(self, opcs):
2505
        """ save opc relations """
2506
        conn = self.project.database.connect()
2507
        with conn:
2508
            try:
2509
                # Get a cursor object
2510
                cursor = conn.cursor()
2511
                sql = 'delete from OPCRelations'
2512
                cursor.execute(sql)
2513

    
2514
                for opc in opcs:
2515
                    sql = 'insert into OPCRelations(From_Drawings_UID,From_LineNo_UID,From_OPC_UID,To_Drawings_UID,To_LineNo_UID,To_OPC_UID) \
2516
                        values({},{},{},{},{},{})'.format(
2517
                        "(select UID from Drawings where Name='{}')".format(opc[0]),
2518
                        "'{}'".format(opc[1]) if opc[1] else 'null',
2519
                        "'{}'".format(opc[2]) if opc[2] else 'null',
2520
                        "(select UID from Drawings where Name='{}')".format(opc[3]) if opc[3] else 'null',
2521
                        "'{}'".format(opc[4]) if opc[4] else 'null',
2522
                        "'{}'".format(opc[5]) if opc[5] else 'null')
2523
                    cursor.execute(sql)
2524

    
2525
                conn.commit()
2526
            # Catch the exception
2527
            except Exception as ex:
2528
                conn.rollback()
2529

    
2530
                from App import App
2531
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2532
                                                              sys.exc_info()[-1].tb_lineno)
2533
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2534

    
2535
    def get_component_connectors(self, component):
2536
        """ get connectors of given component """
2537
        if self._connecterss and component in self._connecterss:
2538
            return self._connecterss[component]
2539

    
2540
        conn = self.project.database.connect()
2541
        with conn:
2542
            try:
2543
                # Get a cursor object
2544
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
2545

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

    
2550
                pre = ''
2551
                rows = cursor.fetchall()
2552
                for row in rows:
2553
                    if pre != row['Components_UID']:
2554
                        if pre != '':
2555
                            self._connecterss[pre] = compo
2556
                        pre = row['Components_UID']
2557
                        compo = []
2558
                        compo.append(row)
2559
                        if row is rows[-1]:
2560
                            self._connecterss[row['Components_UID']] = compo
2561
                    else:
2562
                        compo.append(row)
2563
                        if row is rows[-1]:
2564
                            self._connecterss[row['Components_UID']] = compo
2565

    
2566
                return self._connecterss[component] if component in self._connecterss else []
2567
                # Catch the exception
2568
            except Exception as ex:
2569
                from App import App
2570
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2571
                                                              sys.exc_info()[-1].tb_lineno)
2572
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2573

    
2574
    def get_component_associations(self, component):
2575
        """ get associations of given component """
2576
        if self._associationss and component in self._associationss:
2577
            return self._associationss[component]
2578
        elif self._associationss:
2579
            return []
2580

    
2581
        conn = self.project.database.connect()
2582
        with conn:
2583
            try:
2584
                # Get a cursor object
2585
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
2586

    
2587
                # sql = "select * from Associations where Components_UID='{}'".format(component)
2588
                sql = "select a.* from Associations a \
2589
                            join Components b on a.Components_UID=b.[UID] where Drawings_UID='{}' order by Components_UID".format(
2590
                    self.activeDrawing.UID)
2591
                cursor.execute(sql)
2592

    
2593
                pre = ''
2594
                rows = cursor.fetchall()
2595
                for row in rows:
2596
                    if pre != row['Components_UID']:
2597
                        if pre != '':
2598
                            self._associationss[pre] = compo
2599
                        pre = row['Components_UID']
2600
                        compo = []
2601
                        compo.append(row)
2602
                        if row is rows[-1]:
2603
                            self._associationss[row['Components_UID']] = compo
2604
                    else:
2605
                        compo.append(row)
2606
                        if row is rows[-1]:
2607
                            self._associationss[row['Components_UID']] = compo
2608

    
2609
                return self._associationss[component] if component in self._associationss else []
2610
                # Catch the exception
2611
            except Exception as ex:
2612
                from App import App
2613
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2614
                                                              sys.exc_info()[-1].tb_lineno)
2615
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2616

    
2617
    def get_component_attributes(self, component):
2618
        """ get attributes of given component """
2619
        if self._attributess and component in self._attributess:
2620
            return self._attributess[component]
2621
        elif self._attributess:
2622
            return []
2623

    
2624
        conn = self.project.database.connect()
2625
        with conn:
2626
            try:
2627
                # Get a cursor object
2628
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
2629

    
2630
                sql = "select a.*, b.* from Attributes a \
2631
                            join SymbolAttribute b on a.SymbolAttribute_UID=b.UID \
2632
                            join Components c on a.Components_UID=c.UID \
2633
                        where Drawings_UID='{}' order by a.Components_UID, b.[index]".format(self.activeDrawing.UID)
2634
                cursor.execute(sql)
2635

    
2636
                pre = ''
2637
                rows = cursor.fetchall()
2638
                for row in rows:
2639
                    if pre != row['Components_UID']:
2640
                        if pre != '':
2641
                            self._attributess[pre] = compo
2642
                        pre = row['Components_UID']
2643
                        compo = []
2644
                        compo.append(row)
2645
                        if row is rows[-1]:
2646
                            self._attributess[row['Components_UID']] = compo
2647
                    else:
2648
                        compo.append(row)
2649
                        if row is rows[-1]:
2650
                            self._attributess[row['Components_UID']] = compo
2651

    
2652
                return self._attributess[component] if component in self._attributess else []
2653
                # Catch the exception
2654
            except Exception as ex:
2655
                from App import App
2656
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2657
                                                              sys.exc_info()[-1].tb_lineno)
2658
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2659

    
2660
    def get_pipe_runs(self, component):
2661
        """ get line runs of given component """
2662
        conn = self.project.database.connect()
2663
        with conn:
2664
            try:
2665
                # Get a cursor object
2666
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
2667

    
2668
                sql = "select * from PipeRuns where Owner='{}' order by [Index]".format(component)
2669
                cursor.execute(sql)
2670
                return cursor.fetchall()
2671
                # Catch the exception
2672
            except Exception as ex:
2673
                from App import App
2674
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2675
                                                              sys.exc_info()[-1].tb_lineno)
2676
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2677

    
2678
    def get_pipe_run_items(self, pipe_run):
2679
        """ get line run items of given pipe run """
2680
        conn = self.project.database.connect()
2681
        with conn:
2682
            try:
2683
                # Get a cursor object
2684
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
2685

    
2686
                sql = "select * from PipeRunItems where PipeRuns_UID='{}' order by [Index]".format(pipe_run)
2687
                cursor.execute(sql)
2688
                return cursor.fetchall()
2689
                # Catch the exception
2690
            except Exception as ex:
2691
                from App import App
2692
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2693
                                                              sys.exc_info()[-1].tb_lineno)
2694
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2695

    
2696
    '''
2697
        @brief      get special item types from database
2698
        @author     humkyung
2699
        @date       2019.08.10
2700
    '''
2701

    
2702
    def get_special_item_types(self):
2703
        conn = self.project.database.connect()
2704
        with conn:
2705
            try:
2706
                # Get a cursor object
2707
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
2708

    
2709
                sql = 'select UID, Code, Type, Allowables from SpecialItemTypes order by Code DESC'
2710
                cursor.execute(sql)
2711
                return cursor.fetchall()
2712
                # Catch the exception
2713
            except Exception as ex:
2714
                from App import App
2715
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2716
                                                              sys.exc_info()[-1].tb_lineno)
2717
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2718

    
2719
    '''
2720
        @brief      save special item types
2721
        @author     humkyung
2722
        @date       2019.08.10
2723
    '''
2724

    
2725
    def save_special_item_types(self, datas):
2726
        import uuid
2727

    
2728
        conn = self.project.database.connect()
2729
        with conn:
2730
            try:
2731
                # Get a cursor object
2732
                cursor = conn.cursor()
2733

    
2734
                for data in datas:
2735
                    uid, code, _type, allowables = data[0], data[1], data[2], data[3]
2736
                    if not uid:
2737
                        sql = self.project.database.to_sql(
2738
                            'insert into SpecialItemTypes(UID, Code, Type, Allowables) values(?, ?, ?, ?)')
2739
                        param = (str(uuid.uuid4()), data[1], data[2], data[3])
2740
                    elif uid == '-1':
2741
                        sql = self.project.database.to_sql('delete from SpecialItemTypes where uid=?')
2742
                        param = (data[-1],)
2743
                    else:
2744
                        sql = self.project.database.to_sql(
2745
                            'update SpecialItemTypes SET Code=?, Type=?, Allowables=? WHERE UID = ?')
2746
                        param = (data[1], data[2], data[3], data[0])
2747
                    cursor.execute(sql, param)
2748

    
2749
                conn.commit()
2750
            # Catch the exception
2751
            except Exception as ex:
2752
                # Roll back any change if something goes wrong
2753
                conn.rollback()
2754

    
2755
                from App import App
2756
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2757
                                                              sys.exc_info()[-1].tb_lineno)
2758
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2759

    
2760
    def get_special_items(self, drawings=None):
2761
        """ get special items from database """
2762
        result = []
2763

    
2764
        conn = self.project.database.connect()
2765
        with conn:
2766
            try:
2767
                # get a cursor object
2768
                cursor = conn.cursor()
2769

    
2770
                sql = 'select distinct (select Value from Components where UID=D.Owner) as "Line No",C.Code from Components A \
2771
                    left join Drawings B on A.Drawings_UID=B.UID \
2772
                    left join SpecialItemTypes C on A.SpecialItemTypes_UID=C.UID \
2773
                    left join Components D on A.Connected=D.UID \
2774
                    where A.SpecialItemTypes_UID is not null'
2775
                if drawings is not None:
2776
                    doc_names = "','".join(drawings)
2777
                    sql += f" and A.Drawings_UID in (select UID from Drawings where Name in ('{doc_names}'))"
2778
                sql += ' order by "Line No"'
2779
                cursor.execute(sql)
2780

    
2781
                return cursor.fetchall()
2782
            # catch the exception
2783
            except Exception as ex:
2784
                from App import App
2785
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2786
                                                              sys.exc_info()[-1].tb_lineno)
2787
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2788

    
2789
        return None
2790

    
2791
    '''
2792
        @brief      Set Common Code Data
2793
        @author     kyouho
2794
        @date       2018.07.12
2795
    '''
2796

    
2797
    def saveCommonCodeData(self, tableName, datas):
2798
        import uuid
2799

    
2800
        conn = self.project.database.connect()
2801
        with conn:
2802
            try:
2803
                # Get a cursor object
2804
                cursor = conn.cursor()
2805

    
2806
                for data in datas:
2807
                    uid, code, description, allowables = data[0], data[1], data[2], data[3]
2808
                    if not uid:
2809
                        sql = self.project.database.to_sql(
2810
                            "insert into {}(UID, CODE, DESCRIPTION, ALLOWABLES) values(?, ?, ?, ?)".format(tableName))
2811
                        param = (str(uuid.uuid4()), data[1], data[2], data[3])
2812
                    elif uid == '-1':
2813
                        sql = self.project.database.to_sql('delete from {} where uid=?'.format(tableName))
2814
                        param = (data[-1],)
2815
                    else:
2816
                        sql = self.project.database.to_sql(
2817
                            "update {} SET CODE=?, DESCRIPTION=?, ALLOWABLES=? WHERE UID = ?".format(tableName))
2818
                        param = (data[1], data[2], data[3], data[0])
2819
                    cursor.execute(sql, param)
2820

    
2821
                conn.commit()
2822
            # Catch the exception
2823
            except Exception as ex:
2824
                # Roll back any change if something goes wrong
2825
                conn.rollback()
2826

    
2827
                from App import App
2828
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2829
                                                              sys.exc_info()[-1].tb_lineno)
2830
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2831

    
2832
    '''
2833
        @brief      Set Common Code Data
2834
        @author     kyouho
2835
        @date       2018.07.12
2836
    '''
2837

    
2838
    def deleteCommonCodeData(self, datas):
2839
        try:
2840
            conn = self.project.database.connect()
2841
            with conn:
2842
                # Get a cursor object
2843
                cursor = conn.cursor()
2844

    
2845
                for data in datas:
2846
                    uid = data[0]
2847
                    tableName = data[1]
2848

    
2849
                    if uid:
2850
                        sql = "delete from {} where UID = ?".format(tableName)
2851
                        param = (uid,)
2852
                        cursor.execute(sql, param)
2853

    
2854
                    cursor.execute(sql, param)
2855

    
2856
                conn.commit()
2857

    
2858
        # Catch the exception
2859
        except Exception as ex:
2860
            # Roll back any change if something goes wrong
2861
            conn.rollback()
2862
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2863
                                                      sys.exc_info()[-1].tb_lineno))
2864

    
2865
    '''
2866
        @brief      delete data list
2867
        @author     kyouho
2868
        @date       2018.08.16
2869
    '''
2870

    
2871
    def deleteDataList(self, tableName, UID):
2872
        conn = self.project.database.connect()
2873
        with conn:
2874
            try:
2875
                # Get a cursor object
2876
                cursor = conn.cursor()
2877
                sql = 'delete from {} where UID = {}'.format(tableName, UID)
2878
                cursor.execute(sql)
2879
                conn.commit()
2880

    
2881
            # Catch the exception
2882
            except Exception as ex:
2883
                # Roll back any change if something goes wrong
2884
                conn.rollback()
2885
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2886
                                                          sys.exc_info()[-1].tb_lineno))
2887

    
2888
    def get_document_name_list(self):
2889
        """ get document name list """
2890
        result = []
2891

    
2892
        conn = self.project.database.connect()
2893
        with conn:
2894
            try:
2895
                # Get a cursor object
2896
                cursor = conn.cursor()
2897

    
2898
                sql = "select distinct B.Name as 'Drawing_Name' from Components A join Drawings B on A.Drawings_UID=B.UID"
2899
                cursor.execute(sql)
2900

    
2901
                rows = cursor.fetchall()
2902
                for row in rows:
2903
                    result.append(row[0])
2904

    
2905
                result.sort()
2906
            # Catch the exception
2907
            except Exception as ex:
2908
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2909
                                                          sys.exc_info()[-1].tb_lineno))
2910

    
2911
        return result
2912

    
2913
    '''
2914
        @brief      get line documentName list
2915
        @author     kyouho
2916
        @date       2018.08.13
2917
    '''
2918

    
2919
    def getLineDocumentNameList(self):
2920
        result = []
2921

    
2922
        conn = self.project.database.connect()
2923
        with conn:
2924
            try:
2925
                # Get a cursor object
2926
                cursor = conn.cursor()
2927

    
2928
                sql = 'select DISTINCT(PNID_NO) from LINE_DATA_LIST'
2929

    
2930
                cursor.execute(sql)
2931
                rows = cursor.fetchall()
2932
                for row in rows:
2933
                    result.append(row[0])
2934
            # Catch the exception
2935
            except Exception as ex:
2936
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2937
                                                          sys.exc_info()[-1].tb_lineno))
2938

    
2939
        return result
2940

    
2941
    '''
2942
        @brief      get line data list
2943
        @author     kyouho
2944
        @date       2018.08.13
2945
    '''
2946

    
2947
    def get_line_data_list(self, drawings=None):
2948
        result = []
2949

    
2950
        with self.project.database.connect() as conn:
2951
            try:
2952
                # Get a cursor object
2953
                cursor = conn.cursor()
2954

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

    
2974
            # catch the exception
2975
            except Exception as ex:
2976
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2977
                                                          sys.exc_info()[-1].tb_lineno))
2978

    
2979
        return result
2980

    
2981
    def get_equipment_data_list(self, drawings=None):
2982
        """ get equipment data list """
2983

    
2984
        result = []
2985

    
2986
        with self.project.database.connect() as conn:
2987
            try:
2988
                # Get a cursor object
2989
                cursor = conn.cursor()
2990

    
2991
                sql = "select A.UID,B.NAME,C.SymbolType_UID,D.Type from Components A join Drawings B on A.Drawings_UID=B.UID\
2992
                        join Symbol C on A.Symbol_UID=C.UID\
2993
                        join SymbolType D on C.SymbolType_UID=D.UID\
2994
                        where D.Category in ('Equipment','Equipment Components')"
2995

    
2996
                if drawings is not None:
2997
                    doc_names = "','".join(drawings)
2998
                    sql += f" and A.Drawings_UID in (select UID from Drawings where Name in ('{doc_names}'))"
2999

    
3000
                cursor.execute(sql)
3001
                comps = [(row[0], row[1], row[2], row[3]) for row in cursor.fetchall()]
3002
                for comp in comps:
3003
                    sql = f"select distinct B.Attribute,A.Value from Attributes A left join SymbolAttribute B on " \
3004
                          f"A.SymbolAttribute_UID=B.UID where A.Components_UID='{comp[0]}'"
3005
                    cursor.execute(sql)
3006
                    attrs = cursor.fetchall()
3007
                    data = []
3008
                    for attr in attrs:
3009
                        data.append([attr[0], attr[1]])
3010
                    if data:
3011
                        data.insert(0, ['Type', comp[3]])
3012
                        data.insert(0, ['Drawing Name', comp[1]])
3013
                        data.insert(0, ['UID', comp[0]])
3014
                        result.append(data)
3015

    
3016
            # catch the exception
3017
            except Exception as ex:
3018
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3019
                                                           sys.exc_info()[-1].tb_lineno))
3020

    
3021
        return result
3022

    
3023
    '''
3024
        @brief      set line data list
3025
        @author     kyouho
3026
        @date       2018.08.13
3027
    '''
3028

    
3029
    def setLineDataList(self, dataLists):
3030
        conn = self.project.database.connect()
3031
        with conn:
3032
            try:
3033
                # Get a cursor object
3034
                cursor = conn.cursor()
3035

    
3036
                for data in dataLists:
3037
                    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(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
3038
                    param = tuple(data)
3039
                    cursor.execute(sql, param)
3040

    
3041
                conn.commit()
3042

    
3043
            # Catch the exception
3044
            except Exception as ex:
3045
                # Roll back any change if something goes wrong
3046
                conn.rollback()
3047
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3048
                                                          sys.exc_info()[-1].tb_lineno))
3049

    
3050
    '''
3051
        @brief      delete line data list
3052
        @author     kyouho
3053
        @date       2018.08.13
3054
    '''
3055
    def deleteLineDataList(self, removeUID):
3056
        conn = self.project.database.connect()
3057
        with conn:
3058
            try:
3059
                # Get a cursor object
3060
                cursor = conn.cursor()
3061

    
3062
                for uid in removeUID:
3063
                    sql = "delete from LINE_DATA_LIST where uid = '{}'".format(uid)
3064
                    cursor.execute(sql)
3065

    
3066
                conn.commit()
3067

    
3068
            # Catch the exception
3069
            except Exception as ex:
3070
                # Roll back any change if something goes wrong
3071
                conn.rollback()
3072
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3073
                                                          sys.exc_info()[-1].tb_lineno))
3074

    
3075
    '''
3076
        @brief      delete line data list
3077
        @author     kyouho
3078
        @date       2018.08.13
3079
    '''
3080

    
3081
    def deleteLineDataList_LineNo(self, removeUID):
3082
        conn = self.project.database.connect()
3083
        with conn:
3084
            try:
3085
                # Get a cursor object
3086
                cursor = conn.cursor()
3087

    
3088
                for uid in removeUID:
3089
                    sql = "delete from LINE_DATA_LIST where LINE_NO = ?"
3090
                    param = (uid,)
3091
                    cursor.execute(sql, param)
3092

    
3093
                conn.commit()
3094

    
3095
            # Catch the exception
3096
            except Exception as ex:
3097
                # Roll back any change if something goes wrong
3098
                conn.rollback()
3099
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3100
                                                          sys.exc_info()[-1].tb_lineno))
3101

    
3102
    '''
3103
        @brief      delete equip data list
3104
        @author     kyouho
3105
        @date       2018.08.14
3106
    '''
3107

    
3108
    def deleteEquipDataList(self, removeUID):
3109
        conn = self.project.database.connect()
3110
        with conn:
3111
            try:
3112
                # Get a cursor object
3113
                cursor = conn.cursor()
3114

    
3115
                for uid in removeUID:
3116
                    sql = "delete from EQUIPMENT_DATA_LIST where uid = '{}'".format(uid)
3117
                    cursor.execute(sql)
3118

    
3119
                conn.commit()
3120

    
3121
            # Catch the exception
3122
            except Exception as ex:
3123
                # Roll back any change if something goes wrong
3124
                conn.rollback()
3125
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3126
                                                          sys.exc_info()[-1].tb_lineno))
3127

    
3128
    '''
3129
        @brief      delete inst data list
3130
        @author     kyouho
3131
        @date       2018.08.14
3132
    '''
3133

    
3134
    def deleteInstDataList(self, removeUID):
3135
        conn = self.project.database.connect()
3136
        with conn:
3137
            try:
3138
                # Get a cursor object
3139
                cursor = conn.cursor()
3140

    
3141
                for uid in removeUID:
3142
                    sql = "delete from INSTRUMENT_DATA_LIST where uid = '{}'".format(uid)
3143
                    cursor.execute(sql)
3144

    
3145
                conn.commit()
3146

    
3147
            # Catch the exception
3148
            except Exception as ex:
3149
                # Roll back any change if something goes wrong
3150
                conn.rollback()
3151
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3152
                                                          sys.exc_info()[-1].tb_lineno))
3153

    
3154
    '''
3155
        @brief      delete note data list
3156
        @author     kyouho
3157
        @date       2018.10.10
3158
    '''
3159

    
3160
    def deleteNoteDataList(self, removeUID):
3161
        conn = self.project.database.connect()
3162
        with conn:
3163
            try:
3164
                # Get a cursor object
3165
                cursor = conn.cursor()
3166

    
3167
                for uid in removeUID:
3168
                    sql = "delete from NOTE_DATA_LIST where uid = '{}'".format(uid)
3169
                    cursor.execute(sql)
3170

    
3171
                conn.commit()
3172

    
3173
            # Catch the exception
3174
            except Exception as ex:
3175
                # Roll back any change if something goes wrong
3176
                conn.rollback()
3177
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3178
                                                          sys.exc_info()[-1].tb_lineno))
3179

    
3180
    def get_valve_attributes(self):
3181
        """ return valve attributes """
3182

    
3183
        from SymbolAttr import SymbolAttr
3184

    
3185
        res = None
3186
        if not hasattr(self, '_valve_attributes'):
3187
            self._valve_attributes = []
3188

    
3189
            conn = self.project.database.connect()
3190
            with conn:
3191
                try:
3192
                    # Get a cursor object
3193
                    cursor = conn.cursor()
3194

    
3195
                    sql = "select distinct A.Attribute from SymbolAttribute A join SymbolType B on A.SymbolType_UID=B.UID " \
3196
                          "where B.Category = 'Piping'"
3197
                    cursor.execute(sql)
3198
                    rows = cursor.fetchall()
3199
                    for row in rows:
3200
                        attr = SymbolAttr()
3201
                        attr.Attribute = row[0]
3202
                        self._valve_attributes.append(attr)
3203

    
3204
                    res = self._valve_attributes
3205
                # Catch the exception
3206
                except Exception as ex:
3207
                    print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3208
                                                               sys.exc_info()[-1].tb_lineno))
3209
        else:
3210
            res = self._valve_attributes
3211

    
3212
        return res
3213

    
3214
    def get_valve_data_list(self, drawings=None):
3215
        """get valve data list"""
3216

    
3217
        result = []
3218
        conn = self.project.database.connect()
3219
        with conn:
3220
            try:
3221
                # Get a cursor object
3222
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
3223

    
3224
                sql = "select a.UID,D.Name,E.Name as 'Drawing Name',C.Attribute,B.Value from Components a " \
3225
                      "join Attributes B on a.UID=B.Components_UID " \
3226
                      "join SymbolAttribute C on B.SymbolAttribute_UID=C.UID " \
3227
                      "join Symbol D on a.Symbol_UID=D.UID " \
3228
                      "join Drawings E on a.Drawings_UID=E.UID " \
3229
                      "where a.Symbol_UID in (select UID from Symbol where SymbolType_UID in " \
3230
                      "(select UID from SymbolType where Category in ('Piping')))"
3231
                if drawings is not None:
3232
                    doc_names = "','".join(drawings)
3233
                    sql += f" and A.Drawings_UID in (select UID from Drawings where Name in ('{doc_names}'))"
3234

    
3235
                cursor.execute(sql)
3236
                rows = cursor.fetchall()
3237
                for row in rows:
3238
                    matches = [res for res in result if res['UID'] == row['UID']]
3239
                    if matches:
3240
                        matches[0][row['Attribute']] = row['Value']
3241
                    else:
3242
                        data = {'UID': row['UID'], 'ITEM_NO': row['Name'], 'Drawing Name': row['Drawing Name'],
3243
                                row['Attribute']: row['Value']}
3244
                        result.append(data)
3245

    
3246
            # Catch the exception
3247
            except Exception as ex:
3248
                from App import App
3249
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3250
                                                              sys.exc_info()[-1].tb_lineno)
3251
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3252

    
3253
        return result
3254

    
3255
    def get_instrument_attributes(self):
3256
        """ return valve attributes """
3257

    
3258
        from SymbolAttr import SymbolAttr
3259

    
3260
        res = None
3261
        if not hasattr(self, '_inst_attributes'):
3262
            self._inst_attributes = []
3263

    
3264
            with self.project.database.connect() as conn:
3265
                try:
3266
                    # Get a cursor object
3267
                    cursor = conn.cursor()
3268

    
3269
                    sql = "select distinct A.Attribute from SymbolAttribute A join SymbolType B on A.SymbolType_UID=B.UID " \
3270
                          "where B.Category = 'Instrumentation'"
3271
                    cursor.execute(sql)
3272
                    rows = cursor.fetchall()
3273
                    for row in rows:
3274
                        attr = SymbolAttr()
3275
                        attr.Attribute = row[0]
3276
                        self._inst_attributes.append(attr)
3277

    
3278
                    res = self._inst_attributes
3279
                # Catch the exception
3280
                except Exception as ex:
3281
                    print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3282
                                                               sys.exc_info()[-1].tb_lineno))
3283
        else:
3284
            res = self._inst_attributes
3285

    
3286
        return res
3287

    
3288
    '''
3289
        @brief      get instrument data list
3290
        @author     kyouho
3291
        @date       2018.08.14
3292
    '''
3293

    
3294
    def get_instrument_data_list(self, drawings=None):
3295
        result = []
3296
        conn = self.project.database.connect()
3297
        with conn:
3298
            try:
3299
                # Get a cursor object
3300
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
3301

    
3302
                sql = "select a.UID,D.Name,E.Name as 'Drawing Name',C.Attribute,B.Value from Components a " \
3303
                      "join Attributes B on a.UID=B.Components_UID " \
3304
                      "join SymbolAttribute C on B.SymbolAttribute_UID=C.UID " \
3305
                      "join Symbol D on a.Symbol_UID=D.UID " \
3306
                      "join Drawings E on a.Drawings_UID=E.UID " \
3307
                      "where a.Symbol_UID in (select UID from Symbol where SymbolType_UID in " \
3308
                      "(select UID from SymbolType where Category in ('Instrumentation')))"
3309
                if drawings is not None:
3310
                    doc_names = "','".join(drawings)
3311
                    sql += f" and A.Drawings_UID in (select UID from Drawings where Name in ('{doc_names}'))"
3312

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

    
3330
        return result
3331

    
3332
    def get_note_attributes(self):
3333
        """ return note attributes """
3334

    
3335
        from SymbolAttr import SymbolAttr
3336

    
3337
        res = None
3338
        if not hasattr(self, '_note_attributes'):
3339
            self._note_attributes = []
3340

    
3341
            conn = self.project.database.connect()
3342
            with conn:
3343
                try:
3344
                    # Get a cursor object
3345
                    cursor = conn.cursor()
3346

    
3347
                    sql = "select distinct A.Attribute from SymbolAttribute A join SymbolType B on A.SymbolType_UID=B.UID " \
3348
                          "where B.Category='General' and B.Type='Notes'"
3349
                    cursor.execute(sql)
3350
                    rows = cursor.fetchall()
3351
                    for row in rows:
3352
                        attr = SymbolAttr()
3353
                        attr.Attribute = row[0]
3354
                        self._note_attributes.append(attr)
3355

    
3356
                    res = self._note_attributes
3357
                # Catch the exception
3358
                except Exception as ex:
3359
                    print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3360
                                                               sys.exc_info()[-1].tb_lineno))
3361
        else:
3362
            res = self._note_attributes
3363

    
3364
        return res
3365

    
3366
    def get_note_data_list(self, drawings=None):
3367
        """ get note data list """
3368
        result = []
3369

    
3370
        conn = self.project.database.connect()
3371
        with conn:
3372
            try:
3373
                # Get a cursor object
3374
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
3375

    
3376
                sql = "select a.UID,D.Name,E.Name as 'Drawing Name',C.Attribute,B.Value from Components a " \
3377
                      "join Attributes B on a.UID=B.Components_UID " \
3378
                      "join SymbolAttribute C on B.SymbolAttribute_UID=C.UID " \
3379
                      "join Symbol D on a.Symbol_UID=D.UID " \
3380
                      "join Drawings E on a.Drawings_UID=E.UID " \
3381
                      "where a.Symbol_UID in (select UID from Symbol where SymbolType_UID in " \
3382
                      "(select UID from SymbolType where Category='General' and Type='Notes'))"
3383
                if drawings is not None:
3384
                    doc_names = "','".join(drawings)
3385
                    sql += f" and A.Drawings_UID in (select UID from Drawings where Name in ('{doc_names}'))"
3386

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

    
3404
        return result
3405

    
3406
    def saveToDatabase(self, items, show_progress=None):
3407
        """ save given items to database """
3408
        # delete all datas of current drawing
3409
        drawing_name = self.activeDrawing.name
3410
        drawing_uid = self.activeDrawing.UID
3411

    
3412
        queries = {'first':[], 'second':[]}
3413
        for item in items:
3414
            if hasattr(item, 'toSql_return_separately'):
3415
                sql, sqlLater = item.toSql_return_separately()
3416
                queries['first'].append(sql)
3417
                queries['second'].append(sqlLater)
3418
            else:
3419
                queries['first'].append(item.toSql())
3420

    
3421
        with self.project.database.connect() as conn:
3422
            try:
3423
                # Get a cursor object
3424
                cursor = conn.cursor()
3425
                if self.project.database.db_type == 'SQLite':
3426
                    cursor.execute('begin')
3427

    
3428
                sql = "delete from LINE_DATA_LIST where PNID_NO = '{}'".format(drawing_name)
3429
                cursor.execute(sql)
3430
                sql = "delete from TitleBlockValues where Drawings_UID = '{}'".format(drawing_uid)
3431
                cursor.execute(sql)
3432

    
3433
                # delete LineNoAttributes
3434
                sql = f"delete from LineNoAttributes where Components_UID in " \
3435
                      f"(select UID from Components where Drawings_UID='{drawing_uid}')"
3436
                cursor.execute(sql)
3437

    
3438
                # delete Attributes
3439
                sql = f"delete from Attributes where Components_UID in " \
3440
                      f"(select UID from Components where Drawings_UID='{drawing_uid}')"
3441
                cursor.execute(sql)
3442

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

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

    
3453
                # delete PipeRunItems
3454
                sql = f"delete from PipeRunItems where PipeRuns_UID in " \
3455
                      f"(select UID from PipeRuns where Drawings_UID='{drawing_uid}')"
3456
                cursor.execute(sql)
3457

    
3458
                # delete PipeRuns
3459
                sql = f"delete from PipeRuns where Drawings_UID='{drawing_uid}'"
3460
                cursor.execute(sql)
3461

    
3462
                # delete Components 
3463
                sql = "delete from Components where Drawings_UID='{}'".format(drawing_uid)
3464
                cursor.execute(sql)
3465

    
3466
                progress = 0
3467
                length = len(queries['first']) + len(queries['second'])
3468
                for sql in queries['first']:
3469
                    if type(sql) is list:
3470
                        for item in sql:
3471
                            if item is not None and 2 == len(item):
3472
                                cursor.executemany(self.project.database.to_sql(item[0]), item[1])
3473
                    else:
3474
                        if sql is not None and 2 == len(sql):
3475
                            cursor.executemany(self.project.database.to_sql(sql[0]), sql[1])
3476

    
3477
                    if show_progress:
3478
                        show_progress.emit(int((progress / length)*100))
3479
                    progress += 1
3480

    
3481
                for sql in queries['second']:
3482
                    if type(sql) is list:
3483
                        for item in sql:
3484
                            if item is not None and 2 == len(item):
3485
                                cursor.executemany(self.project.database.to_sql(item[0]), item[1])
3486
                    else:
3487
                        if sql is not None and 2 == len(sql):
3488
                            cursor.executemany(self.project.database.to_sql(sql[0]), sql[1])
3489

    
3490
                    if show_progress:
3491
                        show_progress.emit(int((progress / length)*100))
3492
                    progress += 1
3493

    
3494
                if show_progress:
3495
                    show_progress.emit(99)
3496

    
3497
                if self.project.database.db_type == 'SQLite':
3498
                    cursor.execute('commit')
3499
                else:
3500
                    conn.commit()
3501
            # Catch the exception
3502
            except Exception as ex:
3503
                # Roll back any change if something goes wrong
3504
                conn.rollback()
3505

    
3506
                from App import App
3507
                message = 'error occurred({}\\n{}) in {}:{}'.format(repr(ex), sql,
3508
                                                                    sys.exc_info()[-1].tb_frame.f_code.co_filename,
3509
                                                                    sys.exc_info()[-1].tb_lineno)
3510
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3511

    
3512
    '''
3513
        @brief      set equipment data list
3514
        @author     humkyung
3515
        @date       2018.05.03
3516
    '''
3517

    
3518
    def setEquipmentDataList(self, dataList):
3519
        conn = self.project.database.connect()
3520
        with conn:
3521
            try:
3522
                # Get a cursor object
3523
                cursor = conn.cursor()
3524

    
3525
                for data in dataList:
3526
                    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(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
3527
                    param = tuple(data)
3528
                    cursor.execute(self.project.database.to_sql(sql), param)
3529
                conn.commit()
3530
            # Catch the exception
3531
            except Exception as ex:
3532
                # Roll back any change if something goes wrong
3533
                conn.rollback()
3534

    
3535
                from App import App
3536
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3537
                                                              sys.exc_info()[-1].tb_lineno)
3538
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3539

    
3540
    '''
3541
        @brief      set instrumnet data list
3542
        @author     kyoyho
3543
        @date       2018.08.14
3544
    '''
3545

    
3546
    def setInstrumentDataList(self, dataList):
3547
        conn = self.project.database.connect()
3548
        with conn:
3549
            try:
3550
                # Get a cursor object
3551
                cursor = conn.cursor()
3552

    
3553
                for data in dataList:
3554
                    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(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
3555
                    param = tuple(data)
3556
                    cursor.execute(sql, param)
3557
                conn.commit()
3558

    
3559
            # Catch the exception
3560
            except Exception as ex:
3561
                # Roll back any change if something goes wrong
3562
                conn.rollback()
3563

    
3564
                from App import App
3565
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3566
                                                              sys.exc_info()[-1].tb_lineno)
3567
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3568

    
3569
    def getDrawings(self):
3570
        """ get drawings """
3571
        from Drawing import Drawing
3572

    
3573
        res = []
3574

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

    
3589
        return res
3590

    
3591
    def saveDrawings(self, drawings):
3592
        """save given drawings"""
3593

    
3594
        import uuid
3595

    
3596
        with self.project.database.connect() as conn:
3597
            try:
3598
                # Get a cursor object
3599
                cursor = conn.cursor() if self.project.database.db_type == 'SQLite' else conn.cursor(as_dict=True)
3600
                if self.project.database.db_type == 'SQLite':
3601
                    cursor.execute('begin')
3602

    
3603
                for drawing in drawings:
3604
                    if drawing.UID is None:
3605
                        # get image data
3606
                        image_blob_data = None
3607
                        #file_path = os.path.join(self.project.getDrawingFilePath(), drawing.name)
3608
                        #if drawing.name and os.path.isfile(file_path):
3609
                        #    with open(file_path.encode('utf-8'), 'rb') as file:
3610
                        #        image_blob_data = file.read()
3611
                        # up to here
3612

    
3613
                        sql = self.project.database.to_sql(
3614
                            'insert into Drawings(UID, [NAME], [DATETIME], [Image]) values(?, ?, ?, ?)')
3615
                        param = tuple([str(uuid.uuid4()), drawing.name, '', image_blob_data])
3616
                        drawing.UID = param[0]
3617
                    else:
3618
                        sql = self.project.database.to_sql("update Drawings set [NAME]=?,[DATETIME]=? where UID=?")
3619
                        param = (drawing.name, drawing.datetime, str(drawing.UID))
3620
                        #param = (drawing.name, drawing.datetime, image_blob_data, str(drawing.UID))
3621

    
3622
                    cursor.execute(sql, param)
3623

    
3624
                if self.project.database.db_type == 'SQLite':
3625
                    cursor.execute('commit')
3626
                else:
3627
                    conn.commit()
3628
            # Catch the exception
3629
            except Exception as ex:
3630
                # Roll back any change if something goes wrong
3631
                conn.rollback()
3632

    
3633
                from App import App
3634
                message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
3635
                                                              sys.exc_info()[-1].tb_lineno)
3636
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3637

    
3638
    '''
3639
        @brief  get IsOriginDetect ComboBox Items
3640
    '''
3641

    
3642
    def getIsOriginDetectComboBoxItems(self):
3643
        return [("원본 도면", 0), ("텍스트 제거 도면", 1)]
3644

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

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

    
3652
    '''
3653
        @brief      Return Symbol Type Items
3654
        @author     Jeongwoo
3655
        @date       18.04.20
3656
        @history    18.05.08    Jeongwoo type index changed
3657
    '''
3658

    
3659
    def getSymbolTypeList(self):
3660
        symbolTypeList = []
3661

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

    
3676
        return symbolTypeList
3677

    
3678
    '''
3679
        @brief      Get Symbol Category by Symbol Type
3680
        @author     Jeongwoo
3681
        @date       2018.05.09
3682
    '''
3683

    
3684
    def getSymbolCategoryByType(self, type):
3685
        category = None
3686
        if type in self._symbolType:
3687
            return self._symbolType[type]
3688

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

    
3702
        return category
3703

    
3704
    '''
3705
        @brief      Check Symbol Type is included in 'Equipment' Category
3706
        @author     Jeongwoo
3707
        @date       2018.05.09
3708
    '''
3709

    
3710
    def isEquipmentType(self, type):
3711
        category = self.getSymbolCategoryByType(type)
3712
        return category is not None and category == 'Equipment'
3713

    
3714
    '''
3715
        @brief      Return Symbol Type Items with "None"
3716
        @author     Jeongwoo
3717
        @date       18.04.06
3718
        @history    Seperate SymbolTypeList and "None"
3719
    '''
3720

    
3721
    def getSymbolTypeComboBoxItems(self):
3722
        symbolTypeList = [symbol_type for symbol_type in self.getSymbolTypeList() if symbol_type[1]]
3723
        symbolTypeList.insert(0, ('None', 'None', 'None'))
3724

    
3725
        return symbolTypeList
3726

    
3727
    '''
3728
        @brief  get Base Symbol ComboBox Items
3729
    '''
3730

    
3731
    def getBaseSymbolComboBoxItems(self, type=None):
3732
        bsymbolNameList = self.getSymbolNameListByType(type)
3733
        bsymbolNameList.sort()
3734
        bsymbolNameList.insert(0, "None")
3735
        return bsymbolNameList
3736

    
3737
    '''
3738
        @brief  get Additional Symbol ComboBox Items
3739
    '''
3740

    
3741
    def getAdditionalSymbolComboBoxItems(self):
3742
        asymbolNameList = self.getSymbolNameList()
3743
        asymbolNameList.sort()
3744
        asymbolNameList.insert(0, "None")
3745
        return asymbolNameList
3746

    
3747
    '''
3748
        @brief  get Additional Symbol's default direction ComboBox Items
3749
    '''
3750

    
3751
    def getDefaultSymbolDirectionComboBoxItems(self):
3752
        return [("UP", 0), ("DOWN", 2), ("LEFT", 3), ("RIGHT", 1)]
3753

    
3754
    '''
3755
        @brief  getter of activeDrawing
3756
        @author humkyung
3757
        @date   2018.07.07
3758
    '''
3759

    
3760
    @property
3761
    def activeDrawing(self):
3762
        return self._activeDrawing
3763

    
3764
    '''
3765
        @brief  setter of activeDrawing
3766
        @author humkyung
3767
        @date   2018.07.07
3768
    '''
3769

    
3770
    @activeDrawing.setter
3771
    def activeDrawing(self, value):
3772
        if self._activeDrawing:
3773
            del self._activeDrawing
3774

    
3775
        self._activeDrawing = value
3776

    
3777
    def getColNames(self, table):
3778
        """ return column names of given table and attribute names if tabe is VALVE_DATA_LIST or EQUIPMET_DATA_LIST """
3779
        res = None
3780

    
3781
        conn = self.project.database.connect()
3782
        with conn:
3783
            try:
3784
                cursor = conn.cursor()
3785
                cursor.execute('select * from {}'.format(table))
3786
                res = [col_name[0] for col_name in cursor.description]
3787

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

    
3801
        return res
3802

    
3803
    '''
3804
        @brief  getter of OCRData
3805
        @author humkyung
3806
        @date   2018.11.19
3807
    '''
3808

    
3809
    @property
3810
    def OCRData(self):
3811
        if self._OCRData is None:
3812
            configs = self.getConfigs('Text Recognition', 'OCR Data')
3813
            self._OCRData = configs[0].value if 1 == len(configs) else 'eng'
3814

    
3815
        return self._OCRData
3816

    
3817
    '''
3818
        @brief  setter of OCRData
3819
        @author humkyung
3820
        @date   2018.11.19
3821
    '''
3822

    
3823
    @OCRData.setter
3824
    def OCRData(self, value):
3825
        self._OCRData = value
3826

    
3827

    
3828
if __name__ == '__main__':
3829
    from AppDocData import AppDocData
3830

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