프로젝트

일반

사용자정보

통계
| 개정판:

hytos / DTI_PID / DTI_PID / AppDocData.py @ 3c40a466

이력 | 보기 | 이력해설 | 다운로드 (196 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
from QtImageViewerScene import QtImageViewerScene
25

    
26

    
27
class Config:
28
    def __init__(self, section, key, value):
29
        """constructor"""
30
        self.section = section
31
        self.key = key
32
        self.value = value
33

    
34
    '''
35
        @brief  return size value string
36
        @author humkyung
37
        @date   2018.04.24
38
    '''
39
    def sizeValue(self):
40
        return self.inchStr if 'Inch' == self.sizeUnit else self.metricStr
41

    
42

    
43
'''
44
    @brief  Pipe color class
45
'''
46
class Color:
47
    def __init__(self, index, red, green, blue):
48
        self.index = index
49
        self.red = red
50
        self.green = green
51
        self.blue = blue
52

    
53

    
54
'''
55
    @brief      MessageType
56
    @author     humkyung 
57
    @date       2018.07.31
58
'''
59
class MessageType(Enum):
60
    Normal = 1
61
    Error = 2
62
    Check = 3
63

    
64

    
65
class AppDocData(SingletonInstance):
66
    DATABASE = 'ITI_PID.db'
67

    
68
    def __init__(self):
69
        from DisplayColors import DisplayColors
70

    
71
        self._imgFilePath = None
72
        self.imgName = None
73
        self._OCRData = None
74
        self._imgSrc = None
75

    
76
        self._areas = []
77
        self._colors = None
78
        self._lineNoProperties = None
79
        self._lineTypes = None
80
        self._lineTypeConfigs = None
81
        self._activeDrawing = None
82
        #self._hmbTable = None
83
        self._hmbColors = {}
84
        self._hmbData = None
85
        self._arsColors = {}
86
        self._streamLineListModelDatas = []
87
        self._titleBlockProperties = None
88
        self.needReOpening = None
89
        self.SpecBreakUpDownIndicator = []
90
        self.readOnly = False
91

    
92
        # item members are used only recognition except tracerLineNos for trim line no
93
        self.equipments = []
94
        self.lineNos = []
95
        self.lines = []
96
        self.texts = []
97
        self.symbols = []
98
        self.unknowns = []
99
        self.allItems = []
100
        self.tracerLineNos = []
101
        self.lineIndicators = []
102

    
103
        # for cad graphic items to sppid
104
        self.cadGraphics = []
105

    
106
        # caches
107
        self._lineNoPropertiesUID = {}
108
        self._attributeByType = {}
109
        self._connected_items_lists = None
110

    
111
        # caches not need to be clear
112
        self._configs = None
113
        self._symbolType = {}
114
        self._symbolNametList = {}
115
        self._symbolBase = {}
116

    
117
        # for load drawing data from database
118
        self._connecterss = {}
119
        self._associationss = {}
120
        self._attributess = {}
121

    
122
    def clearTempDBData(self):
123
        self._connecterss = {}
124
        self._associationss = {}
125
        self._attributess = {}
126

    
127
    def clearItemList(self, trim):
128
        '''
129
            @brief      clear item list
130
            @author     euisung
131
            @date       2018.11.28
132
        '''
133
        from QEngineeringInstLineNoTextItem import QEngineeringInstLineNoTextItem
134

    
135
        self.equipments.clear()
136
        self.symbols.clear()
137
        self.lineNos.clear()
138
        self.texts.clear()
139
        self.unknowns.clear()
140
        self.allItems.clear()
141
        self.lineIndicators.clear()
142
        if trim:
143
            self.tracerLineNos.clear()
144
            self.lines.clear()
145
            self._connected_items_lists = QEngineeringInstLineNoTextItem()
146

    
147
    '''
148
        @brief      clear
149
        @author     humkyung
150
        @date       2018.09.06
151
    '''
152
    def clear(self, past=None):
153
        from QEngineeringInstLineNoTextItem import QEngineeringInstLineNoTextItem
154

    
155
        if self.activeDrawing and self.activeDrawing.UID and self.activeDrawing.UID != past:
156
            self.clear_occupying_drawing(self.activeDrawing.UID)
157

    
158
        self._imgFilePath = None
159
        self.imgName = None
160
        self._imgSrc = None
161

    
162
        self._areas.clear()
163
        self.equipments.clear()
164
        self.lineNos.clear()
165
        self.lines.clear()
166
        self.texts.clear()
167
        self.symbols.clear()
168
        self.unknowns.clear()
169
        self.allItems.clear()
170
        self.tracerLineNos.clear()
171
        self.cadGraphics.clear()
172
        self.lineIndicators.clear()
173
        self.SpecBreakUpDownIndicator.clear()
174
        #self._colors = None
175
        #self._lineNoProperties = None
176
        self._lineTypeConfigs = None
177
        self._activeDrawing = None
178
        #self._hmbTable = None
179
        self._hmbColors = {}
180
        self._hmbData = None
181
        #self._arsColors = {}
182
        self._streamLineListModelDatas = []
183
        self._titleBlockProperties = None
184

    
185
        #self._configs = None# if not past else self._configs
186
        #self._symbolBase = {}# if not past else self._symbolBase
187
        #self._symbolType = {}# if not past else self._symbolType
188
        #self._lineNoPropertiesUID = {}
189
        self._attributeByType = {}
190
        self._connected_items_lists = QEngineeringInstLineNoTextItem()
191

    
192
        self._connecterss = {}
193
        self._associationss = {}
194
        self._attributess = {}
195

    
196
    def clear_occupying_drawing(self, drawing):
197
        """ clear drawing access """
198
        conn = self.project.database.connect()
199
        with conn:
200
            try:
201
                # Get a cursor object
202
                cursor = conn.cursor()
203
                if drawing:
204
                    sql = "UPDATE Drawings SET [OCCUPIED]=null WHERE [OCCUPIED]='{}' and UID='{}'".format(os.environ['COMPUTERNAME'], drawing)
205
                else:
206
                    sql = "UPDATE Drawings SET [OCCUPIED]=null"
207
                cursor.execute(sql)
208

    
209
                conn.commit()
210
            # Catch the exception
211
            except Exception as ex:
212
                conn.rollback()
213

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

    
218
    def set_occupying_drawing(self, drawing) -> str:
219
        """ set drawing access return true if success"""
220
        with self.project.database.connect() as conn:
221
            try:
222
                # Get a cursor object
223
                cursor = conn.cursor()
224
                sql = f"select OCCUPIED from Drawings where [UID]='{drawing}'"
225
                cursor.execute(sql)
226

    
227
                rows = cursor.fetchall()
228
                if not rows[0]['OCCUPIED'] or rows[0]['OCCUPIED'] == os.environ['COMPUTERNAME']:
229
                    sql = f"UPDATE Drawings SET [OCCUPIED]='{os.environ['COMPUTERNAME']}' WHERE UID='{drawing}'"
230
                    cursor.execute(sql)
231
                    conn.commit()
232
                    return None
233
                else:
234
                    return rows[0]['OCCUPIED']
235

    
236
            # Catch the exception
237
            except Exception as ex:
238
                conn.rollback()
239

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

    
244
                return None
245

    
246
    def winsort(self, data):
247
        """ Windows sort """
248

    
249
        from ctypes import wintypes, windll
250
        from functools import cmp_to_key
251

    
252
        _StrCmpLogicalW = windll.Shlwapi.StrCmpLogicalW
253
        _StrCmpLogicalW.argtypes = [wintypes.LPWSTR, wintypes.LPWSTR]
254
        _StrCmpLogicalW.restype  = wintypes.INT
255

    
256
        cmp_fnc = lambda psz1, psz2: _StrCmpLogicalW(psz1, psz2)
257

    
258
        return sorted(data, key=cmp_to_key(cmp_fnc))
259

    
260
    '''
261
        @brief      Get drawing file list
262
        @author     euisung
263
        @date       2018.09.28
264
    '''
265
    def getDrawingFileList(self):
266
        """ get drawing files which's extension is .png or jpg from drawing folder """
267
        drawingFileList = []
268

    
269
        try:
270
            project = AppDocData.instance().getCurrentProject()
271
            path = project.getDrawingFilePath()
272
            drawingFileList = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f)) and
273
                               (os.path.splitext(f)[1].upper() == '.PNG' or os.path.splitext(f)[1].upper() == '.JPG' or
274
                                os.path.splitext(f)[1].upper() == '.JPEG')]
275
            
276
            drawingFileList = self.winsort(drawingFileList)
277
            #drawingFileList.sort()
278
        except Exception as ex:
279
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
280
                                                      sys.exc_info()[-1].tb_lineno))
281

    
282
        return drawingFileList
283

    
284
    '''
285
        @brief      Get Training file list
286
        @author     euisung
287
        @date       2018.10.16
288
    '''
289
    def getTrainingFileList(self):
290
        try:
291
            project = AppDocData.instance().getCurrentProject()
292
            path = project.getTrainingFilePath()
293
            trainingFileList = os.listdir(path)
294
            trainingFileList.sort()
295
        except Exception as ex:
296
            from App import App
297
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
298
                                                          sys.exc_info()[-1].tb_lineno)
299
            App.mainWnd().addMessage.emit(MessageType.Error, message)
300

    
301
        return trainingFileList
302

    
303
    def getTrainingSymbolFileList(self):
304
        """  Get Symbol Training file list """
305
        try:
306
            project = AppDocData.instance().getCurrentProject()
307
            path = project.getTrainingSymbolFilePath()
308
            symbolTrainingFileList = os.listdir(path)
309
            symbolTrainingFileList.sort()
310
        except Exception as ex:
311
            from App import App
312
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
313
                                                          sys.exc_info()[-1].tb_lineno)
314
            App.mainWnd().addMessage.emit(MessageType.Error, message)
315

    
316
        return symbolTrainingFileList
317

    
318
    '''
319
        @brief      Get DB file path in ProgramData
320
        @author     Jeongwoo
321
        @date       2018.06.27
322
        @history    2018.06.29  Jeongwoo    Change method to get template db path
323
    '''
324
    def getTemplateDbPath(self):
325
        path = os.path.join(os.getenv('ALLUSERSPROFILE'), 'Digital PID')
326
        templateDbPath = os.path.join(path, 'Template.db')
327
        return templateDbPath
328

    
329
    def get_template_symbol_library_path(self):
330
        """return template symbol library path"""
331

    
332
        path = os.path.join(os.getenv('USERPROFILE'), 'Digital PID')
333
        return os.path.join(path, 'SymbolLibrary.syl')
334

    
335
    def getAppDbPath(self):
336
        """
337
        @brief      Get application DB file path in ProgramData
338
        @author     humkyung
339
        @date       2018.10.01
340
        """
341

    
342
        path = os.path.join(os.getenv('USERPROFILE'), 'Digital PID')
343
        app_database = os.path.join(path, 'App.db')
344
        return app_database
345

    
346
    '''
347
        @brief  getter of colors 
348
        @author humkyung
349
        @date   2018.06.18
350
    '''
351
    @property
352
    def colors(self):
353
        import random
354

    
355
        if self._colors is None or self._colors == []:
356
            self._colors = []
357
            with self.project.database.connect() as conn:
358
                try:
359
                    cursor = conn.cursor()
360
                    sql = 'SELECT UID,RED,GREEN,BLUE FROM Colors'
361
                    cursor.execute(sql)
362
                    rows = cursor.fetchall()
363
                    for row in rows:
364
                        self._colors.append(Color(row['UID'], row['RED'], row['GREEN'], row['BLUE']))
365
                # Catch the exception
366
                except Exception as ex:
367
                    from App import App
368
                    message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
369
                                                                  sys.exc_info()[-1].tb_lineno)
370
                    App.mainWnd().addMessage.emit(MessageType.Error, message)
371

    
372
        return self._colors.pop(random.randrange(0, len(self._colors)))
373

    
374
    '''
375
        @brief  setter of colors
376
        @author humkyung
377
        @date   2018.06.18
378
    '''
379
    @colors.setter
380
    def colors(self, value):
381
        self._colors = value
382

    
383
    '''
384
        @brief      set image file path
385
        @author     humkyung
386
        @date       2018.07.30
387
    '''
388
    def setImgFilePath(self, path):
389
        self._imgFilePath = path
390
        self.imgName = os.path.splitext(os.path.basename(self._imgFilePath))[0]
391

    
392
    @staticmethod
393
    def my_imread(file_path):
394
        """ read a file which's name contains unicode string : ref http://devdoftech.co.kr:82/redmine/issues/631 """
395
        import numpy as np
396
        import cv2
397

    
398
        _bytes = None
399
        with open(file_path.encode('utf-8'), 'rb') as stream:
400
            _bytes = bytearray(stream.read())
401

    
402
        numpyArray = np.asarray(_bytes, dtype=np.uint8)
403
        res = cv2.imdecode(numpyArray, cv2.IMREAD_UNCHANGED)
404
        return res
405

    
406
    @property
407
    def imgSrc(self):
408
        """return the image of active drawing"""
409

    
410
        if self.activeDrawing:
411
            return self.activeDrawing.image
412

    
413
        return None
414

    
415
    @imgSrc.setter
416
    def imgSrc(self, value):
417
        """set the image of active drawing with given value"""
418

    
419
        if self.activeDrawing:
420
            self.activeDrawing.image = value
421

    
422
    '''
423
        @brief  getter of line type configs
424
        @author humkyung
425
        @date   2018.06.28
426
    '''
427
    @property
428
    def lineTypeConfigs(self):
429
        from PyQt5.QtCore import Qt
430

    
431
        if self._lineTypeConfigs is None:
432
            self._lineTypeConfigs = []
433

    
434
            styleMap = [('SolidLine', Qt.SolidLine), ('DashLine', Qt.DashLine), ('DotLine', Qt.DotLine),
435
                        ('DashDotLine', Qt.DashDotLine),
436
                        ('DashDotDotLine', Qt.DashDotDotLine), ('CustomDashLine', Qt.CustomDashLine)]
437

    
438
            configs = self.getConfigs('LineTypes')
439
            for config in configs:
440
                color, width, _style, transparent = config.value.split(',')
441
                matches = [param for param in styleMap if param[0] == _style]
442
                style = matches[0][1] if matches else Qt.SolidLine
443
                self._lineTypeConfigs.append((config.key, color, int(width), style, float(transparent)))
444

    
445
        return self._lineTypeConfigs
446

    
447
    '''
448
        @brief  setter of line type configs
449
        @author humkyung
450
        @date   2018.06.28
451
    '''
452
    @lineTypeConfigs.setter
453
    def lineTypeConfigs(self, value):
454
        self._lineTypeConfigs = value
455

    
456
    @property
457
    def drain_size(self):
458
        """ getter of drain_size """
459
        if not hasattr(self, '_drain_size') or not self._drain_size:
460
            configs = self.getConfigs('Drain Size Rule', 'Size')
461
            self._drain_size = configs[0].value if configs else '1"'
462

    
463
        return self._drain_size
464

    
465
    @drain_size.setter
466
    def drain_size(self, value):
467
        """ setter of drain_size """
468
        self._drain_size = value
469

    
470
    '''
471
        @brief      getter of hmb table
472
        @author     humkyung
473
        @date       2018.07.16
474
    '''
475
    '''
476
    @property
477
    def hmbTable(self):
478
        from HMBTable import HMBTable
479

480
        if self._hmbTable is None:
481
            self._hmbTable = HMBTable()
482
            self._hmbTable.load_data()
483

484
        return self._hmbTable
485
    '''
486

    
487
    '''
488
        @brief      setter of hmb table
489
        @author     humkyung
490
        @date       2018.07.16
491
    '''
492
    '''
493
    @hmbTable.setter
494
    def hmbTable(self, value):
495
        self._hmbTable = value
496
    '''
497

    
498
    '''
499
        @brief  get line type config of given line type
500
        @author humkyung
501
        @date   2018.06.28
502
    '''
503
    def getLineTypeConfig(self, lineType):
504
        from PyQt5.QtCore import Qt
505

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

    
509
    def getCurrentPidSource(self):
510
        return self.activeDrawing.currentPidSource
511

    
512
    '''
513
        @brief      Check if exist file name or not
514
        @author     Jeongwoo
515
        @date       2018.05.03
516
    '''
517
    def isExistFileName(self, name):
518
        rows = None
519
        with self.project.database.connect() as conn:
520
            try:
521
                cursor = conn.cursor()
522
                sql = "SELECT * FROM Symbol WHERE name = '" + name + "'"
523
                cursor.execute(sql)
524
                rows = cursor.fetchall()
525
            # Catch the exception
526
            except Exception as ex:
527
                # Roll back any change if something goes wrong
528
                conn.rollback()
529
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
530
                                                          sys.exc_info()[-1].tb_lineno))
531
            finally:
532
                if rows is not None and len(rows) > 0:
533
                    return True
534
                else:
535
                    return False
536

    
537
    '''
538
        @brief      Insert new symbol into Symbol Table, Moved from SG_DbHelper
539
        @author     Jeongwoo
540
        @date       2018.05.03
541
    '''
542
    def insertSymbol(self, symbol):
543
        isAdded = False
544
        with self.project.database.connect() as conn:
545
            try:
546
                sql = self.project.database.to_sql("""
547
                    INSERT INTO Symbol(name, SymbolType_UID, threshold, minMatchPoint, isDetectOrigin, rotationCount, ocrOption, isContainChild, originalPoint, connectionPoint, baseSymbol, additionalSymbol, isExceptDetect, hasInstrumentLabel, width, height, flip, TextArea) 
548
                    VALUES(?, (select UID from SymbolType where Type=?), ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);
549
                """)
550

    
551
                cursor = conn.cursor()
552
                query = (symbol.getName(), symbol.getType(), symbol.getThreshold()
553
                         , symbol.getMinMatchCount(), symbol.getIsDetectOnOrigin(), symbol.getRotationCount()
554
                         , symbol.getOcrOption(), symbol.getIsContainChild()
555
                         , symbol.getOriginalPoint(), symbol.getConnectionPoint()
556
                         , symbol.getBaseSymbol(), symbol.getAdditionalSymbol(), symbol.getIsExceptDetect(),
557
                         symbol.getHasInstrumentLabel()
558
                         , symbol.width, symbol.height, symbol.detectFlip, symbol.text_area_str)
559
                cursor.execute(sql, query)
560
                conn.commit()
561
                isAdded = True
562
            # Catch the exception
563
            except Exception as ex:
564
                # Roll back any change if something goes wrong
565
                conn.rollback()
566

    
567
                from App import App
568
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
569
                                                              sys.exc_info()[-1].tb_lineno)
570
                App.mainWnd().addMessage.emit(MessageType.Error, message)
571
            finally:
572
                return (isAdded, symbol.getType(), symbol.getName(), symbol.getPath())
573

    
574
    '''
575
        @brief      Update symbol in Symbol Table, Moved from SG_DbHelper
576
        @author     Jeongwoo
577
        @date       2018.05.03
578
    '''
579
    def updateSymbol(self, symbol):
580
        isUpdated = False
581

    
582
        with self.project.database.connect() as conn:
583
            try:
584
                sql = self.project.database.to_sql("""
585
                    UPDATE Symbol
586
                    SET
587
                        name = ?, SymbolType_UID=(select UID from SymbolType where Type=?), threshold=?, 
588
                        minMatchPoint=?, isDetectOrigin=?, rotationCount=?, ocrOption=?, isContainChild=?, 
589
                        originalPoint=?, connectionPoint=?, baseSymbol=?, additionalSymbol=?, isExceptDetect=?, 
590
                        hasInstrumentLabel=?, width=?, height=?, flip=?, TextArea=? WHERE uid = ?
591
                """)
592

    
593
                cursor = conn.cursor()
594
                query = (symbol.getName(), symbol.getType(), symbol.getThreshold()
595
                         , symbol.getMinMatchCount(), symbol.getIsDetectOnOrigin(), symbol.getRotationCount()
596
                         , symbol.getOcrOption(), symbol.getIsContainChild()
597
                         , symbol.getOriginalPoint(), symbol.getConnectionPoint()
598
                         , symbol.getBaseSymbol(), symbol.getAdditionalSymbol(), symbol.getIsExceptDetect(),
599
                         symbol.getHasInstrumentLabel(), symbol.width, symbol.height, symbol.detectFlip, symbol.text_area_str,
600
                         symbol.getUid())
601
                cursor.execute(sql, query)
602
                conn.commit()
603
                isUpdated = True
604
            # Catch the exception
605
            except Exception as ex:
606
                # Roll back any change if something goes wrong
607
                conn.rollback()
608

    
609
                from App import App
610
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
611
                                                              sys.exc_info()[-1].tb_lineno)
612
                App.mainWnd().addMessage.emit(MessageType.Error, message)
613
            finally:
614
                self._symbolBase = {}
615
                return (isUpdated, symbol.getType(), symbol.getName(), symbol.getPath())
616

    
617
    def getSymbolPreset(self):
618
        """ get symbol preset """
619
        presets = []
620
        with self.project.database.connect() as conn:
621
            try:
622
                cursor = conn.cursor()
623
                sql = 'SELECT [UID], [Find], [Target], [Action], [Condition] FROM SymbolPreset'
624
                cursor.execute(sql)
625
                rows = cursor.fetchall()
626
                for row in rows:
627
                    presets.append([row['Find'], row['Target'], row['Action'], row['Condition']])
628
            # Catch the exception
629
            except Exception as ex:
630
                from App import App
631
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
632
                                                                sys.exc_info()[-1].tb_lineno)
633
                App.mainWnd().addMessage.emit(MessageType.Error, message)
634

    
635
                return []
636

    
637
        return presets
638

    
639
    def saveSymbolPreset(self, presets):
640
        """ save symbol preset """
641
        import uuid
642

    
643
        conn = self.project.database.connect()
644
        with conn:
645
            try:
646
                # Get a cursor object
647
                cursor = conn.cursor()
648

    
649
                sql = "delete from SymbolPreset"
650
                cursor.execute(sql)
651

    
652
                for preset in presets:
653
                    sql = self.project.database.to_sql("insert into [SymbolPreset]([UID], [Find], [Target], [Action], [Condition]) values(?,?,?,?,?)")
654
                    param = (str(uuid.uuid4()), preset[0], preset[1], preset[2], preset[3])
655
                    cursor.execute(sql, param)
656
                conn.commit()
657

    
658
            except Exception as ex:
659
                # Roll back any change if something goes wrong
660
                conn.rollback()
661
                from App import App
662
                from AppDocData import MessageType
663
                message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
664
                                                                sys.exc_info()[-1].tb_lineno)
665
                App.mainWnd().addMessage.emit(MessageType.Error, message)
666
        
667

    
668
    def getTargetSymbolList(self, all=False):
669
        """get symbol list to be detected except isExceptDetect field is unset"""
670
        targetSymbolList = []
671

    
672
        with self.project.database.connect() as conn:
673
            cursor = conn.cursor()
674
            if not all:
675
                sql = """SELECT a.UID,a.Name,b.Type,a.Threshold,a.MinMatchPoint,a.IsDetectOrigin,a.RotationCount,
676
                a.OCROption,a.IsContainChild,a.OriginalPoint,a.ConnectionPoint,a.BaseSymbol,a.AdditionalSymbol,a.Width,a.Height,
677
                a.IsExceptDetect,a.HasInstrumentLabel,a.flip,a.TextArea,b.UID as DB_UID FROM Symbol a inner join SymbolType b on 
678
                a.SymbolType_UID=b.UID WHERE a.IsExceptDetect = 0 order by width * height desc"""
679
            else:
680
                sql = """SELECT a.UID,a.Name,b.Type,a.Threshold,a.MinMatchPoint,a.IsDetectOrigin,a.RotationCount,
681
                a.OCROption,a.IsContainChild,a.OriginalPoint,a.ConnectionPoint,a.BaseSymbol,a.AdditionalSymbol,a.Width,a.Height,
682
                a.IsExceptDetect,a.HasInstrumentLabel,a.flip,a.TextArea,b.UID as DB_UID FROM Symbol a inner join SymbolType b on 
683
                a.SymbolType_UID=b.UID WHERE a.[SymbolType_UID] != -1 order by width * height desc"""
684
            try:
685
                cursor.execute(sql)
686
                rows = cursor.fetchall()
687
                for row in rows:
688
                    sym = symbol.SymbolBase(row['Name'], row['Type'], row['Threshold'],
689
                                                row['MinMatchPoint'], row['IsDetectOrigin'],
690
                                                row['RotationCount'], row['OCROption'],
691
                                                row['IsContainChild'], row['OriginalPoint'],
692
                                                row['ConnectionPoint'], row['BaseSymbol'],
693
                                                row['AdditionalSymbol'], row['IsExceptDetect'],
694
                                                row['HasInstrumentLabel'], row['UID'],
695
                                                iType=row['DB_UID'], width=row['Width'], height=row['Height'],
696
                                                detectFlip=row['flip'], text_area=row['TextArea'])
697
                    targetSymbolList.append(sym)
698
            except Exception as ex:
699
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
700
                                                          sys.exc_info()[-1].tb_lineno))
701

    
702
        return targetSymbolList
703

    
704
    def get_favorite_libraries(self):
705
        res = []
706

    
707
        with self.project.database.connect() as conn:
708
            cursor = conn.cursor()
709
            sql = f"select UID,Symbol_UID from Libraries where [User]='{os.environ['COMPUTERNAME'].upper()}'"
710
            try:
711
                cursor.execute(sql)
712
                return cursor.fetchall()
713
            except Exception as ex:
714
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
715
                                                          sys.exc_info()[-1].tb_lineno))
716

    
717
        return None
718

    
719
    def buildAppDatabase(self):
720
        """build application database"""
721
        path = os.path.join(os.getenv('USERPROFILE'), 'Digital PID')
722
        appDatabaseFilePath = os.path.join(path, 'App.db')
723

    
724
        # Creates or opens a file called mydb with a SQLite3 DB
725
        with sqlite3.connect(appDatabaseFilePath) as conn:
726
            try:
727
                # Get a cursor object
728
                cursor = conn.cursor()
729

    
730
                sqlFiles = ['App.Configuration.sql', 'App.Styles.sql']
731
                for sqlFile in sqlFiles:
732
                    filePath = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'Scripts', sqlFile)
733
                    try:
734
                        file = QFile(filePath)
735
                        file.open(QFile.ReadOnly)
736
                        sql = file.readAll()
737
                        sql = str(sql, encoding='utf8')
738
                        cursor.executescript(sql)
739
                    finally:
740
                        file.close()
741
                conn.commit()
742
            # Catch the exception
743
            except Exception as ex:
744
                # Roll back any change if something goes wrong
745
                conn.rollback()
746
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
747
                                                          sys.exc_info()[-1].tb_lineno))
748

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

    
752
        configs = self.getAppConfigs('app', 'license')
753
        if configs and len(configs[0].value.split('.')) == 3:
754
            pass
755
        else:
756
            configs = self.getAppConfigs('app', 'expiration')
757
            if not configs:
758
                configs = self.getAppConfigs('app', 'license')
759
                if configs and 'DOFTECH' in configs[0].value:
760
                    self.deleteAppConfigs('app', 'mode')
761
                    configs = None
762
                else:
763
                    configs = [Config('app', 'mode', 'advanced')]
764
            else:
765
                configs = None
766

    
767
            if configs:
768
                self.saveAppConfigs(configs)
769

    
770
    '''
771
        @brief  load app style
772
        @author humkyung
773
        @date   2018.04.20
774
    '''
775
    def loadAppStyle(self):
776
        style = 'Fusion'
777

    
778
        path = os.path.join(os.getenv('USERPROFILE'), 'Digital PID')
779
        if not os.path.exists(path): os.makedirs(path)
780

    
781
        self.buildAppDatabase()
782
        try:
783
            appDatabaseFilePath = os.path.join(path, 'App.db')
784
            # Creates or opens a file called mydb with a SQLite3 DB
785
            conn = sqlite3.connect(appDatabaseFilePath)
786
            # Get a cursor object
787
            cursor = conn.cursor()
788

    
789
            sql = "select Value from Configuration where Section='App' and Key='Style'"
790
            cursor.execute(sql)
791
            rows = cursor.fetchall()
792
            style = rows[0][0] if 1 == len(rows) else 'Fusion'
793
        # Catch the exception
794
        except Exception as ex:
795
            # Roll back any change if something goes wrong
796
            conn.rollback()
797
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
798
                                                      sys.exc_info()[-1].tb_lineno))
799
        finally:
800
            # Close the db connection
801
            conn.close()
802

    
803
        return style
804

    
805
    '''
806
        @brief  load app styles and then return a list
807
        @author humkyung
808
        @date   2018.04.20
809
    '''
810
    def loadAppStyles(self):
811
        styles = []
812

    
813
        try:
814
            self.buildAppDatabase()
815

    
816
            path = os.path.join(os.getenv('USERPROFILE'), 'Digital PID')
817
            appDatabaseFilePath = os.path.join(path, 'App.db')
818

    
819
            # Creates or opens a file called mydb with a SQLite3 DB
820
            conn = sqlite3.connect(appDatabaseFilePath)
821
            # Get a cursor object
822
            cursor = conn.cursor()
823

    
824
            sql = 'select UID,Value from Styles'
825
            cursor.execute(sql)
826
            rows = cursor.fetchall()
827
            for row in rows: styles.append(row[1])
828
            if 0 == len(rows): rows.append('fusion')
829
        # Catch the exception
830
        except Exception as ex:
831
            # Roll back any change if something goes wrong
832
            conn.rollback()
833
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
834
                                                      sys.exc_info()[-1].tb_lineno))
835
        finally:
836
            # Close the db connection
837
            conn.close()
838

    
839
        return styles
840

    
841
    '''
842
        @brief  Set current Project
843
        @history    2018.06.27  Jeongwoo    If DB file is not, copy DB file from ProgramData
844
    '''
845
    def setCurrentProject(self, project):
846
        self.project = project
847
        project.make_sub_directories()
848
        try:
849
            # save size unit
850
            #self.saveConfigs([Config('Project', 'Unit', project.prj_unit)])
851

    
852
            if self.project.database.db_type == 'SQLite':
853
                # Creates or opens a file called mydb with a SQLite3 DB
854
                db_path = self.project.database.file_path
855

    
856
                if not os.path.isfile(db_path):
857
                    templatePath = self.getTemplateDbPath()
858
                    templateFile = QFile(templatePath)
859
                    templateFile.copy(db_path)
860

    
861
                try:
862
                    conn = self.project.database.connect()
863
                    with conn:
864
                        # Get a cursor object
865
                        cursor = conn.cursor()
866

    
867
                        fileNames = os.listdir(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'Scripts'))
868
                        for fileName in fileNames:
869
                            if fileName.endswith(".sql") and ('SQLite_Project' == os.path.splitext(fileName)[0].split('.')[0]):
870
                                try:
871
                                    file = QFile(
872
                                        os.path.join(os.path.dirname(os.path.realpath(__file__)), 'Scripts', fileName))
873
                                    file.open(QFile.ReadOnly)
874
                                    sql = file.readAll()
875
                                    sql = str(sql, encoding='utf8')
876
                                    cursor.executescript(sql)
877
                                finally:
878
                                    file.close()
879
                        conn.commit()
880
                except Exception as ex:
881
                    print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
882
                                                              sys.exc_info()[-1].tb_lineno))
883
        # Catch the exception
884
        except Exception as ex:
885
            # Roll back any change if something goes wrong
886
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
887
                                                      sys.exc_info()[-1].tb_lineno))
888
        finally:
889
            pass
890

    
891
    '''
892
        @brief  Get current Project
893
    '''
894
    def getCurrentProject(self):
895
        return self.project
896

    
897
    '''
898
        @brief      return project database path
899
        @history    humkyung 2018.04.19 return Project.db in Program Data folder instead of PROJECT_DB_PATH variable
900
    '''
901
    def getPrjDatabasePath(self):
902
        path = os.path.join(os.getenv('USERPROFILE'), 'Digital PID')
903
        if not os.path.exists(path): os.makedirs(path)
904

    
905
        prjDatabaseFilePath = os.path.join(path, 'Project.db')
906
        try:
907
            # Creates or opens a file called mydb with a SQLite3 DB
908
            conn = sqlite3.connect(prjDatabaseFilePath)
909
            # Get a cursor object
910
            cursor = conn.cursor()
911

    
912
            filePath = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'Scripts', 'Project.Projects.sql')
913
            try:
914
                file = QFile(filePath)
915
                file.open(QFile.ReadOnly)
916
                sql = file.readAll()
917
                sql = str(sql, encoding='utf8')
918
                cursor.executescript(sql)
919
            finally:
920
                file.close()
921
            conn.commit()
922
        # Catch the exception
923
        except Exception as ex:
924
            # Roll back any change if something goes wrong
925
            conn.rollback()
926
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
927
                                                      sys.exc_info()[-1].tb_lineno))
928
        finally:
929
            # Close the db connection
930
            conn.close()
931

    
932
        return prjDatabaseFilePath
933

    
934
    def getErrorItemSvgPath(self):
935
        '''
936
            @brief  return error item svg path
937
            @author euisung
938
            @date   2019.04.02
939
        '''
940
        return os.path.join(os.getenv('USERPROFILE'), 'Digital PID', 'Explode.svg')
941

    
942
    def updateTitleBlockProperties(self, titleBlockProps):
943
        '''
944
            @brief  update title block properties
945
            @author euisung
946
            @date   2018.11.09
947
        '''
948
        try:
949
            originTitleBlockProps = self.getTitleBlockProperties()
950
            deletedTitleBlockProps = []
951
            for originTitleBlockProp in originTitleBlockProps:
952
                for titleBlockProp in titleBlockProps:
953
                    # uid compare for determine delete props
954
                    if originTitleBlockProp[0] == titleBlockProp[0]:
955
                        break
956
                deletedTitleBlockProps.append(originTitleBlockProp[0])
957

    
958
            # Creates or opens a file called mydb with a SQLite3 DB
959
            conn = self.project.database.connect()
960
            with conn:
961
                try:
962
                    # Get a cursor object
963
                    cursor = conn.cursor()
964

    
965
                    for deletedTitleBlockProp in deletedTitleBlockProps:
966
                        sql = "delete from TitleBlockValues where TitleBlockProperties_UID='{}'".format(deletedTitleBlockProp)
967
                        cursor.execute(sql)
968
                        sql = "delete from TitleBlockProperties where UID='{}'".format(deletedTitleBlockProp)
969
                        cursor.execute(sql)
970

    
971
                    for titleBlockProp in titleBlockProps:
972
                        sql = self.project.database.to_sql("insert into [TitleBlockProperties]([UID], [NAME], [AREA], [TEXT]) values(?,?,?,?)")
973
                        param = (titleBlockProp[0], titleBlockProp[1], titleBlockProp[2], titleBlockProp[3])  # uid, name, area, text
974
                        cursor.execute(sql, param)
975
                    conn.commit()
976
                    # Catch the exception
977
                except Exception as ex:
978
                    # Roll back any change if something goes wrong
979
                    conn.rollback()
980
                    from App import App
981
                    from AppDocData import MessageType
982
                    message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
983
                                                                   sys.exc_info()[-1].tb_lineno)
984
                    App.mainWnd().addMessage.emit(MessageType.Error, message)
985
        # Catch the exception
986
        except Exception as ex:
987
            from App import App
988
            from AppDocData import MessageType
989
            message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
990
                                                           sys.exc_info()[-1].tb_lineno)
991
            App.mainWnd().addMessage.emit(MessageType.Error, message)
992

    
993
        self._titleBlockProperties = None
994

    
995
    def getTitleBlockProperties(self):
996
        """"return title block properties"""
997

    
998
        res = None
999
        if self._titleBlockProperties is None:
1000
            self._titleBlockProperties = []
1001

    
1002
            with self.project.database.connect() as conn:
1003
                try:
1004
                    # Get a cursor object
1005
                    cursor = conn.cursor()
1006

    
1007
                    sql = "select UID, Name, AREA, [TEXT] from TitleBlockProperties"
1008
                    cursor.execute(sql)
1009
                    rows = cursor.fetchall()
1010
                    for row in rows:
1011
                        attr = []
1012
                        attr.append(row['UID'])  # uid
1013
                        attr.append(row['Name'])  # name
1014
                        attr.append(row['AREA'])  # area
1015
                        attr.append(row['TEXT'])  # text
1016
                        self._titleBlockProperties.append(attr)
1017

    
1018
                    res = self._titleBlockProperties
1019
                # Catch the exception
1020
                except Exception as ex:
1021
                    print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1022
                                                              sys.exc_info()[-1].tb_lineno))
1023
        else:
1024
            res = self._titleBlockProperties
1025

    
1026
        return res
1027

    
1028
    def clearLineNoProperties(self):
1029
        self._lineNoProperties = None
1030
        self._lineNoPropertiesUID = {}
1031

    
1032
    def getLineProperties(self):
1033
        """return line no properties"""
1034
        from SymbolAttr import SymbolAttr
1035

    
1036
        res = None
1037
        if self._lineNoProperties is None:
1038
            self._lineNoProperties = []
1039

    
1040
            with self.project.database.connect() as conn:
1041
                try:
1042
                    # Get a cursor object
1043
                    cursor = conn.cursor()
1044

    
1045
                    sql = "select UID, Name, DisplayName, Type, LimitNumber, [index] from LineProperties " \
1046
                          "order by [index]"
1047
                    cursor.execute(sql)
1048
                    rows = cursor.fetchall()
1049
                    for row in rows:
1050
                        attr = SymbolAttr()
1051
                        attr.UID = row['UID']
1052
                        attr.Attribute = row['Name']
1053
                        attr.DisplayAttribute = row['DisplayName']
1054
                        attr.AttributeType = row['Type']
1055
                        attr.Length = row['LimitNumber']
1056
                        attr.IsProp = 5
1057
                        attr.Index = -1
1058
                        self._lineNoProperties.append(attr)
1059

    
1060
                    res = self._lineNoProperties
1061

    
1062
                    # update cache
1063
                    if res:
1064
                        for _prop in res:
1065
                            if str(_prop.UID) not in self._lineNoPropertiesUID:
1066
                                self._lineNoPropertiesUID[str(_prop.UID)] = [_prop]
1067
                # Catch the exception
1068
                except Exception as ex:
1069
                    print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1070
                                                              sys.exc_info()[-1].tb_lineno))
1071
        else:
1072
            res = self._lineNoProperties
1073

    
1074
        return res
1075

    
1076
    def get_equipment_attributes(self):
1077
        """ return equipment attributes """
1078

    
1079
        from SymbolAttr import SymbolAttr
1080

    
1081
        res = None
1082
        if not hasattr(self, '_equipment_attributes'):
1083
            self._equipment_attributes = []
1084

    
1085
            with self.project.database.connect() as conn:
1086
                try:
1087
                    # Get a cursor object
1088
                    cursor = conn.cursor()
1089

    
1090
                    sql = "select distinct A.Attribute from SymbolAttribute A join SymbolType B on " \
1091
                          "A.SymbolType_UID=B.UID where B.Category in ('Equipment')"#,'Equipment Components')"
1092
                    cursor.execute(sql)
1093
                    rows = cursor.fetchall()
1094
                    for row in rows:
1095
                        attr = SymbolAttr()
1096
                        attr.Attribute = row['Attribute']
1097
                        self._equipment_attributes.append(attr)
1098

    
1099
                    res = self._equipment_attributes
1100
                # Catch the exception
1101
                except Exception as ex:
1102
                    print('error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
1103
                                                               sys.exc_info()[-1].tb_lineno))
1104
        else:
1105
            res = self._equipment_attributes
1106

    
1107
        return res
1108

    
1109
    '''
1110
        @brief  return line properties
1111
        @author humkyung
1112
        @date   2018.04.09
1113
    '''
1114
    def getLinePropertiesByUID(self, UID):
1115
        from SymbolAttr import SymbolAttr
1116

    
1117
        res = []
1118
        if UID in self._lineNoPropertiesUID:
1119
            res = self._lineNoPropertiesUID[UID]
1120
            return res
1121

    
1122
        with self.project.database.connect() as conn:
1123
            try:
1124
                # Get a cursor object
1125
                cursor = conn.cursor()
1126

    
1127
                sql = f"select UID, Name, DisplayName, Type, LimitNumber, [index] from LineProperties where " \
1128
                      f"uid = '{UID}'"
1129
                cursor.execute(sql)
1130
                rows = cursor.fetchall()
1131
                for row in rows:
1132
                    attr = SymbolAttr()
1133
                    attr.UID = row['UID']
1134
                    attr.Attribute = row['Name']
1135
                    attr.DisplayAttribute = row['DisplayName']
1136
                    attr.AttributeType = row['Type']
1137
                    attr.Length = row['LimitNumber']
1138
                    attr.IsProp = 5
1139
                    attr.Index = -1
1140
                    res.append(attr)
1141
                self._lineNoPropertiesUID[UID] = res
1142
            # Catch the exception
1143
            except Exception as ex:
1144
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1145
                                                          sys.exc_info()[-1].tb_lineno))
1146

    
1147
        return res
1148

    
1149
    '''
1150
        @brief  return line types 
1151
        @author humkyung
1152
        @date   2018.06.27
1153
    '''
1154
    def getLineTypes(self):
1155
        from LineTypeConditions import LineTypeConditions
1156

    
1157
        res = []
1158
        conn = self.project.database.connect()
1159
        with conn:
1160
            try:
1161
                cursor = conn.cursor()
1162
                sql = "select UID,Name,Type1,Conditions1,Type2,Conditions2 from LineTypes order by Name"
1163
                cursor.execute(sql)
1164
                rows = cursor.fetchall()
1165
                for row in rows:
1166
                    line_type = LineTypeConditions(row['UID'], row['Name'])
1167
                    line_type._conditions[0][0] = row['Type1']
1168
                    line_type._conditions[0][1] = row['Conditions1']
1169
                    line_type._conditions[1][0] = row['Type2']
1170
                    line_type._conditions[1][1] = row['Conditions2']
1171
                    res.append(line_type)
1172
            # Catch the exception
1173
            except Exception as ex:
1174
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1175
                                                          sys.exc_info()[-1].tb_lineno))
1176

    
1177
        return res
1178

    
1179
    '''
1180
        @brief      Insert New Project Info
1181
        @author     Jeongwoo
1182
        @date       2018.04.06
1183
        @history    humkyung 2018.04.19 use getPrjDatabasePath function instead of PROJECT_DB_PATH variable
1184
    '''
1185
    def insertProjectInfo(self, desc, prj_unit, dir):
1186
        prjDatabaseFilePath = self.getPrjDatabasePath()
1187
        conn = sqlite3.connect(prjDatabaseFilePath)
1188
        with conn:
1189
            try:
1190
                folderName = dir.split('/')[-1]
1191
                if folderName:
1192
                    nowDate = datetime.datetime.now().strftime('%Y.%m.%d %H:%M')
1193
                    sql = "insert or replace into Projects(Name, [Desc], [Unit], Path, CreatedDate, UpdatedDate) values(?, ?, ?, ?, ?, ?)"
1194
                    param = (folderName, desc, prj_unit, dir, nowDate, nowDate)
1195

    
1196
                    cursor = conn.cursor()
1197
                    cursor.execute(sql, param)
1198
                    conn.commit()
1199
                else:
1200
                    print("Empty folder name")
1201
            except Exception as ex:
1202
                # Roll back any change if something goes wrong
1203
                conn.rollback()
1204
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1205
                                                          sys.exc_info()[-1].tb_lineno))
1206

    
1207
    def removeProjectInfo(self, targetProject):
1208
        '''
1209
        @brief      Remove Project Info
1210
        @author     Euisung
1211
        @date       2019.01.28
1212
        '''
1213
        prjDatabaseFilePath = self.getPrjDatabasePath()
1214
        conn = sqlite3.connect(prjDatabaseFilePath)
1215
        with conn:
1216
            try:
1217
                sql = "delete from Projects where Id = '{}'".format(targetProject.id)
1218
                cur = conn.cursor()
1219
                cur.execute(sql)
1220
                conn.commit()
1221
            except Exception as ex:
1222
                # Roll back any change if something goes wrong
1223
                conn.rollback()
1224
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1225
                                                          sys.exc_info()[-1].tb_lineno))
1226

    
1227
    '''
1228
        @brief      update project
1229
        @author     Jeongwoo
1230
        @date       2018.04.06
1231
        @history    humkyung 2018.04.19 use getPrjDatabasePath function instead of PROJECT_DB_PATH variable
1232
    '''
1233
    def updateProjectUpdatedDate(self, project):
1234
        prjDatabaseFilePath = self.getPrjDatabasePath()
1235
        conn = sqlite3.connect(prjDatabaseFilePath)
1236
        with conn:
1237
            try:
1238
                nowDate = datetime.datetime.now().strftime('%Y.%m.%d %H:%M')
1239
                sql = '''
1240
                    UPDATE Projects
1241
                    SET UpdatedDate = ?,[Desc]=?,[Unit]=? 
1242
                    WHERE Id = ?
1243
                '''
1244
                cur = conn.cursor()
1245
                cur.execute(sql, (nowDate, project.desc, project.prj_unit, project.getId()))
1246

    
1247
                if project.database.host and project.database.port:
1248
                    _host = project.database.host + ':' + project.database.port
1249
                else:
1250
                    _host = None
1251
                sql = 'insert or replace into DBSettings(Projects_UID, DBTypes_UID, Host, User, Password, FilePath) values(?,(select UID from DBTypes where Name=?),?,?,?,?)'
1252
                cur = conn.cursor()
1253
                cur.execute(sql, (
1254
                    project.getId(), project.database.db_type, _host, project.database.user,
1255
                    project.database.password, project.database.file_path))
1256
                conn.commit()
1257
            except Exception as ex:
1258
                # Roll back any change if something goes wrong
1259
                conn.rollback()
1260
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1261
                                                          sys.exc_info()[-1].tb_lineno))
1262

    
1263
    '''
1264
        @brief  get project list from database
1265
        @history    humkyung 2018.04.18 add only project which's project exists
1266
    '''
1267
    def getProjectList(self):
1268
        from Project import Project
1269

    
1270
        projectList = []
1271

    
1272
        conn = sqlite3.connect(self.getPrjDatabasePath())
1273
        with conn:
1274
            conn.row_factory = sqlite3.Row
1275
            cursor = conn.cursor()
1276
            sql = "select a.Id,a.Name,a.[Desc],a.[Unit],a.Path,a.CreatedDate,a.UpdatedDate,\
1277
                (select \
1278
                CASE \
1279
                WHEN b.DBTypes_UID is NULL THEN 'SQLite' \
1280
                ELSE (select Name from DBTypes where UID=b.DBTypes_UID) \
1281
                END \
1282
                ) DBType,b.Host,b.User,b.Password \
1283
                from projects a left join dbsettings b on a.Id=b.Projects_UID order by strftime(a.UpdatedDate) desc"
1284
            try:
1285
                cursor.execute(sql)
1286
                rows = cursor.fetchall()
1287
                for row in rows:
1288
                    if os.path.isdir(row['Path']):  # check if folder exists
1289
                        projectList.append(Project(row))
1290
            except Exception as ex:
1291
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1292
                                                          sys.exc_info()[-1].tb_lineno))
1293

    
1294
        return projectList
1295

    
1296
    '''
1297
        @brief  get sliding window size
1298
        @author humkyung
1299
    '''
1300
    def getSlidingWindowSize(self):
1301
        res = [25, 20]
1302
        try:
1303
            configs = self.getConfigs('Sliding Window')
1304
            for config in configs:
1305
                if config.key == 'Width':
1306
                    res[0] = int(config.value)
1307
                elif config.key == 'Height':
1308
                    res[1] = int(config.value)
1309
        # Catch the exception
1310
        except Exception as ex:
1311
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1312
                                                      sys.exc_info()[-1].tb_lineno))
1313

    
1314
        return res
1315

    
1316
    '''
1317
        @brief  get line no configuration
1318
        @author humkyung
1319
        @date   2018.04.16
1320
    '''
1321
    def getLineNoConfiguration(self):
1322
        res = None
1323

    
1324
        conn = self.project.database.connect()
1325
        with conn:
1326
            try:
1327
                # Get a cursor object
1328
                cursor = conn.cursor()
1329

    
1330
                delimiter = None
1331
                sql = "select * from configuration where section='Line No' and key='Delimiter"
1332
                cursor.execute(sql)
1333
                rows = cursor.fetchall()
1334
                if len(rows) == 1:
1335
                    delimiter = rows[0][2]
1336

    
1337
                if delimiter is not None:
1338
                    sql = "select * from configuration where section='Line No' and key='Configuration'"
1339
                    cursor.execute(sql)
1340
                    rows = cursor.fetchall()
1341
                    if len(rows) == 1:
1342
                        res = rows[0][2].split(delimiter)
1343
            # Catch the exception
1344
            except Exception as ex:
1345
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1346
                                                          sys.exc_info()[-1].tb_lineno))
1347

    
1348
        return res
1349

    
1350
    '''
1351
        @brief  get area list
1352
        @author humkyung
1353
        @history    euisung     2018.11.20 (0,0),(0,0) process add
1354
    '''
1355
    def getAreaList(self, size=False):
1356
        from Area import Area
1357

    
1358
        if len(self._areas) == 0:
1359
            conn = self.project.database.connect()
1360
            with conn:
1361
                try:
1362
                    # Get a cursor object
1363
                    cursor = conn.cursor()
1364

    
1365
                    sql = "select * from configuration where section='Area'"
1366
                    cursor.execute(sql)
1367
                    rows = cursor.fetchall()
1368
                    for row in rows:
1369
                        name = row['Key']
1370
                        area = Area(name)
1371
                        area.parse(row['Value'])
1372
                        self._areas.append(area)
1373
                # Catch the exception
1374
                except Exception as ex:
1375
                    print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1376
                                                              sys.exc_info()[-1].tb_lineno))
1377

    
1378
        return self._areas if size else [area for area in self._areas if area.name != 'Size']
1379

    
1380
    '''
1381
        @brief  get area of given name
1382
        @author humkyung
1383
        @date   2018.04.07
1384
    '''
1385
    def getArea(self, name):
1386
        areas = self.getAreaList(size=True)
1387
        matches = [area for area in areas if area.name == name]
1388
        if 1 == len(matches) and matches[0].height is not 0 and matches[0].width is not 0:
1389
            return matches[0]
1390

    
1391
        return None
1392

    
1393
    def getConfigs(self, section, key=None):
1394
        """ get configurations from database """
1395
        res = []
1396

    
1397
        if self._configs is None:
1398
            self._configs = []
1399
            with self.project.database.connect() as conn:
1400
                try:
1401
                    # Get a cursor object
1402
                    cursor = conn.cursor()
1403

    
1404
                    sql = "select * from configuration"
1405

    
1406
                    cursor.execute(sql)
1407
                    rows = cursor.fetchall()
1408
                    for row in rows:
1409
                        self._configs.append(Config(row['Section'], row['Key'], row['Value']))
1410
                # Catch the exception
1411
                except Exception as ex:
1412
                    print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1413
                                                              sys.exc_info()[-1].tb_lineno))
1414

    
1415
        if key is not None:
1416
            return [con for con in self._configs if con.section == section and con.key == key]
1417
        else:
1418
            return [con for con in self._configs if con.section == section]
1419

    
1420
    def getAppConfigs(self, section, key=None):
1421
        """get application configurations"""
1422

    
1423
        res = []
1424

    
1425
        # Creates or opens a file called mydb with a SQLite3 DB
1426
        dbPath = self.getAppDbPath()
1427
        with sqlite3.connect(dbPath) as conn:
1428
            try:
1429
                # Get a cursor object
1430
                cursor = conn.cursor()
1431

    
1432
                if key is not None:
1433
                    sql = "select * from configuration where section=? and key=?"
1434
                    param = (section, key)
1435
                else:
1436
                    sql = "select * from configuration where section=?"
1437
                    param = (section,)
1438

    
1439
                cursor.execute(sql, param)
1440
                rows = cursor.fetchall()
1441
                for row in rows:
1442
                    res.append(Config(row[0], row[1], row[2]))
1443
            # Catch the exception
1444
            except Exception as ex:
1445
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1446
                                                          sys.exc_info()[-1].tb_lineno))
1447

    
1448
        return res
1449

    
1450
    '''
1451
        @brief      save configurations
1452
        @author     humkyung
1453
        @date       2018.04.16
1454
        @history    humkyung 2018.07.03 replace ' with " if value has '
1455
                    kyouho 2018.07.09 change query method
1456
    '''
1457
    def saveConfigs(self, configs):
1458
        from LineTypeConditions import LineTypeConditions
1459

    
1460
        with self.project.database.connect() as conn:
1461
            try:
1462
                # Get a cursor object
1463
                cursor = conn.cursor()
1464
                if self.project.database.db_type == 'SQLite':
1465
                    cursor.execute('begin')
1466

    
1467
                for config in configs:
1468
                    if type(config) is Config:
1469
                        value = config.value
1470
                        #if type(value) is str and "'" in value:
1471
                        #    value = value.replace("'", "''")
1472

    
1473
                        sql = self.project.database.to_sql(
1474
                            "insert into configuration(Section,[Key],Value) select ?,?,? where not exists(select 1 from configuration where Section=? and [Key]=?)")
1475
                        param = (config.section, config.key, str(value), config.section, config.key)
1476
                        cursor.execute(sql, param)
1477
                        sql = self.project.database.to_sql(
1478
                            "update configuration set Value=? where Section=? and [Key]=?")
1479
                        param = (str(value), config.section, config.key)
1480
                        cursor.execute(sql, param)
1481
                    elif hasattr(config, 'toSql'):
1482
                        sql = config.toSql()
1483
                        if type(sql) is list:
1484
                            for item in sql:
1485
                                if item is not None and 2 == len(item):
1486
                                    cursor.execute(self.project.database.to_sql(item[0]), item[1])
1487
                        else:
1488
                            if sql is not None and 2 == len(sql):
1489
                                cursor.execute(self.project.database.to_sql(sql[0]), sql[1])
1490
                self._configs = None  # reset config table
1491
                LineTypeConditions.CONDITIONS = None
1492

    
1493
                if self.project.database.db_type == 'SQLite':
1494
                    cursor.execute('commit')
1495
                else:
1496
                    conn.commit()
1497
            # Catch the exception
1498
            except Exception as ex:
1499
                # Roll back any change if something goes wrong
1500
                conn.rollback()
1501

    
1502
                from App import App
1503
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1504
                                                              sys.exc_info()[-1].tb_lineno)
1505
                App.mainWnd().addMessage.emit(MessageType.Error, message)
1506

    
1507
    def saveAppConfigs(self, configs):
1508
        """save application configurations"""
1509

    
1510
        # Creates or opens a file called mydb with a SQLite3 DB
1511
        dbPath = self.getAppDbPath()
1512
        with sqlite3.connect(dbPath) as conn:
1513
            try:
1514
                # Get a cursor object
1515
                cursor = conn.cursor()
1516

    
1517
                for config in configs:
1518
                    value = config.value
1519
                    if type(value) is str and "'" in value:
1520
                        value = value.replace("'", "''")
1521

    
1522
                    sql = "insert or replace into configuration values(?,?,?)"
1523
                    param = (config.section, config.key, value)
1524

    
1525
                    cursor.execute(sql, param)
1526
                conn.commit()
1527
            # Catch the exception
1528
            except Exception as ex:
1529
                # Roll back any change if something goes wrong
1530
                conn.rollback()
1531
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1532
                                                          sys.exc_info()[-1].tb_lineno))
1533

    
1534
    def updateProjectUnit(self, unit):
1535
        """save project configurations"""
1536

    
1537
        # Creates or opens a file called mydb with a SQLite3 DB
1538
        dbPath = self.getPrjDatabasePath()
1539
        with sqlite3.connect(dbPath) as conn:
1540
            try:
1541
                # Get a cursor object
1542
                cursor = conn.cursor()
1543

    
1544
                sql = "update Projects set [Unit]=? where [Id]=?"
1545
                param = (unit, self.project.getId())
1546

    
1547
                cursor.execute(sql, param)
1548
                conn.commit()
1549
            # Catch the exception
1550
            except Exception as ex:
1551
                # Roll back any change if something goes wrong
1552
                conn.rollback()
1553
                
1554
                from App import App
1555
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1556
                                                              sys.exc_info()[-1].tb_lineno)
1557
                App.mainWnd().addMessage.emit(MessageType.Error, message)
1558

    
1559
    def deleteConfigs(self, section, key=None):
1560
        """
1561
        delete configurations by using section and key
1562
        :param section:
1563
        :param key:
1564
        :return: None
1565
        """
1566
        with self.project.database.connect() as conn:
1567
            try:
1568
                # Get a cursor object
1569
                cursor = conn.cursor()
1570

    
1571
                if key is not None:
1572
                    sql = "delete from configuration where section='{}' and [key]='{}'".format(section, key)
1573
                else:
1574
                    sql = "delete from configuration where section='{}'".format(section)
1575
                cursor.execute(sql)
1576

    
1577
                conn.commit()
1578
            # Catch the exception
1579
            except Exception as ex:
1580
                # Roll back any change if something goes wrong
1581
                conn.rollback()
1582

    
1583
                message = f'error occurred({ex}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:' \
1584
                          f'{sys.exc_info()[-1].tb_lineno}'
1585
                print(message)
1586

    
1587
    def deleteAppConfigs(self, section, key=None):
1588
        """
1589
        @brief  delete application configurations
1590
        @author humkyung
1591
        @date   2018.11.01
1592
        """
1593

    
1594
        # Creates or opens a file called mydb with a SQLite3 DB
1595
        dbPath = self.getAppDbPath()
1596
        conn = sqlite3.connect(dbPath)
1597
        with conn:
1598
            try:
1599
                # Get a cursor object
1600
                cursor = conn.cursor()
1601

    
1602
                if key is not None:
1603
                    sql = "delete from configuration where section='{}' and key='{}'".format(section, key)
1604
                else:
1605
                    sql = "delete from configuration where section='{}'".format(section)
1606
                cursor.execute(sql)
1607

    
1608
                conn.commit()
1609
            # Catch the exception
1610
            except Exception as ex:
1611
                # Roll back any change if something goes wrong
1612
                conn.rollback()
1613
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1614
                                                          sys.exc_info()[-1].tb_lineno))
1615

    
1616
    '''
1617
        @brief      set area list
1618
        @history    humkyung 2018.05.18 round area coordinate and dimension before saving
1619
        @history    euisung  2018.11.20 add self._area reset process
1620
    '''
1621
    def setAreaList(self, areas):
1622
        for area in areas:
1623
            matches = [x for x in self._areas if x.name == area.name]
1624
            if 1 == len(matches):
1625
                matches[0].x = area.x
1626
                matches[0].y = area.y
1627
                matches[0].width = area.width
1628
                matches[0].height = area.height
1629
            elif 0 == len(matches):
1630
                self._areas.append(area)
1631

    
1632
        # Creates or opens a file called mydb with a SQLite3 DB
1633
        conn = self.project.database.connect()
1634
        with conn:
1635
            try:
1636
                # Get a cursor object
1637
                cursor = conn.cursor()
1638

    
1639
                for area in self._areas:
1640
                    sql = "insert into configuration select 'Area','{}','({},{}),({},{})' where not exists(select 1 from configuration where Section='Area' and [Key]='{}')".format(
1641
                        area.name, round(area.x), round(area.y), round(area.width), round(area.height), area.name)
1642
                    cursor.execute(sql)
1643
                    sql = "update configuration set Value='({},{}),({},{})' where Section='Area' and [Key]='{}'".format(
1644
                        round(area.x), round(area.y), round(area.width), round(area.height), area.name)
1645
                    cursor.execute(sql)
1646
                conn.commit()
1647
            # Catch the exception
1648
            except Exception as ex:
1649
                # Roll back any change if something goes wrong
1650
                conn.rollback()
1651

    
1652
                from App import App
1653
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1654
                                                              sys.exc_info()[-1].tb_lineno)
1655
                App.mainWnd().addMessage.emit(MessageType.Error, message)
1656
            finally:
1657
                # Close the db connection
1658
                self._areas = []
1659

    
1660
    def getSymbolNameList(self):
1661
        """ get symbol name list """
1662
        symbolNametList = []
1663

    
1664
        conn = self.project.database.connect()
1665
        with conn:
1666
            cursor = conn.cursor()
1667
            sql = 'SELECT * FROM SymbolName'
1668
            try:
1669
                cursor.execute(sql)
1670
                rows = cursor.fetchall()
1671
                for row in rows:
1672
                    symbolNametList.append(row['Name'])  # Name String
1673
            except Exception as ex:
1674
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1675
                                                          sys.exc_info()[-1].tb_lineno))
1676

    
1677
        return symbolNametList
1678

    
1679
    '''
1680
        @brief      get symbol name list by symbol Type
1681
        @author     Jeongwoo
1682
        @date       18.04.06
1683
        @history    .
1684
    '''
1685
    def getSymbolNameListByType(self, type):
1686
        symbolNametList = []
1687
        if type in self._symbolNametList:
1688
            return self._symbolNametList[type]
1689

    
1690
        conn = self.project.database.connect()
1691
        with conn:
1692
            cursor = conn.cursor()
1693
            sql = ''
1694
            if type is not None:
1695
                sql = self.project.database.to_sql('SELECT * FROM SymbolName WHERE [Type]=?')
1696
                try:
1697
                    cursor.execute(sql, (type,))
1698
                    rows = cursor.fetchall()
1699
                    for row in rows:
1700
                        symbolNametList.append(row['Name'])  # Name String
1701
                    self._symbolNametList[type] = symbolNametList
1702
                except Exception as ex:
1703
                    print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1704
                                                              sys.exc_info()[-1].tb_lineno))
1705

    
1706
        return symbolNametList
1707

    
1708
    '''
1709
        @brief  delete added symbol data
1710
    '''
1711
    def deleteSymbol(self, fileName):
1712
        ret = False
1713

    
1714
        conn = self.project.database.connect()
1715
        with conn:
1716
            try:
1717
                cursor = conn.cursor()
1718
                sql = self.project.database.to_sql("DELETE FROM Symbol WHERE name = ?")
1719
                try:
1720
                    cursor.execute(sql, (fileName,))
1721
                    conn.commit()
1722
                    ret = True
1723
                except Exception as ex:
1724
                    conn.rollback()
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
                    ret = False
1730
            finally:
1731
                self._symbolBase = {}
1732
                return (ret, fileName)
1733

    
1734
    def getDuplicatedAttrs(self, param):
1735
        """ get duplicated attributes """
1736

    
1737
        res = []
1738
        
1739
        with self.project.database.connect() as conn:
1740
            cursor = conn.cursor()
1741
            sql = self.project.database.to_sql(f"SELECT t.Value, c.UID, d.Name FROM "
1742
                                               f"(SELECT a.[Value] FROM Attributes a GROUP BY a.[value] HAVING COUNT(a.[value]) > 1) t "
1743
                                               f"INNER JOIN Attributes a ON a.Value=t.value "
1744
                                               f"INNER JOIN SymbolAttribute b ON a.SymbolAttribute_UID=b.UID "
1745
                                               f"INNER JOIN Components c ON a.Components_UID=c.UID "
1746
                                               f"INNER JOIN Drawings d ON c.Drawings_UID=d.UID "
1747
                                               f"WHERE b.Attribute=? AND t.value != '' AND t.value != 'None' AND t.value IS NOT null")
1748
            try:
1749
                cursor.execute(sql, (param,))
1750
                rows = cursor.fetchall()
1751
                for row in rows:
1752
                    res.append([row['Name'], row['UID'], row['Value']])
1753

    
1754
                res = sorted(res, key=lambda pram: param[2])
1755
                return res
1756

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

    
1763
    '''
1764
        @brief  get symbol name
1765
        @history    18.04.24    Jeongwoo    Add isExceptDetect Field
1766
    '''
1767
    def getSymbolByQuery(self, fieldName, param):
1768
        ret = None
1769

    
1770
        if fieldName in self._symbolBase:
1771
            if param in self._symbolBase[fieldName]:
1772
                ret = self._symbolBase[fieldName][param]
1773
                return ret
1774
        else:
1775
            self._symbolBase[fieldName] = {}
1776

    
1777
        with self.project.database.connect() as conn:
1778
            cursor = conn.cursor()
1779
            sql = self.project.database.to_sql(f"SELECT a.UID as UID,a.Name,b.Type,a.Threshold,a.MinMatchPoint,"
1780
                                               f"a.IsDetectOrigin,a.RotationCount,a.OCROption,a.IsContainChild,"
1781
                                               f"a.OriginalPoint,a.ConnectionPoint,a.BaseSymbol,a.AdditionalSymbol,"
1782
                                               f"a.IsExceptDetect,a.HasInstrumentLabel,a.flip,a.TextArea,b.UID as DB_UID FROM "
1783
                                               f"Symbol a inner join SymbolType b on a.SymbolType_UID=b.UID WHERE "
1784
                                               f"a.{fieldName}=?")
1785
            try:
1786
                cursor.execute(sql, (param,))
1787
                rows = cursor.fetchall()
1788
                if rows is not None and len(rows) > 0:
1789
                    symbolTuple = rows[0]
1790
                    ret = symbol.SymbolBase(symbolTuple['Name'], symbolTuple['Type'], symbolTuple['Threshold']
1791
                                            , symbolTuple['MinMatchPoint'], symbolTuple['IsDetectOrigin'],
1792
                                            symbolTuple['RotationCount'], symbolTuple['OCROption'],
1793
                                            symbolTuple['IsContainChild'], symbolTuple['OriginalPoint'],
1794
                                            symbolTuple['ConnectionPoint'], symbolTuple['BaseSymbol'],
1795
                                            symbolTuple['AdditionalSymbol'], symbolTuple['IsExceptDetect'],
1796
                                            symbolTuple['HasInstrumentLabel'], symbolTuple['UID'],
1797
                                            iType=symbolTuple['DB_UID'], detectFlip=symbolTuple['flip'],
1798
                                            text_area=symbolTuple['TextArea'])
1799
                    self._symbolBase[fieldName][param] = ret
1800
            except Exception as ex:
1801
                from App import App
1802
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1803
                                                              sys.exc_info()[-1].tb_lineno)
1804
                App.mainWnd().addMessage.emit(MessageType.Error, message)
1805

    
1806
        return ret
1807

    
1808
    '''
1809
        @brief  get symbol name list
1810
        @history    18.04.24    Jeongwoo    Add isExceptDetect Field
1811
    '''
1812
    def getSymbolListByType(self, field_name=None, param=None):
1813
        ret = []
1814

    
1815
        with self.project.database.connect() as conn:
1816
            cursor = conn.cursor()
1817
            if field_name is not None and param is not None:
1818
                sql = """SELECT a.UID,a.Name,b.Type,a.Threshold,a.MinMatchPoint,a.IsDetectOrigin,a.RotationCount,
1819
                a.OCROption,a.IsContainChild,a.OriginalPoint,a.ConnectionPoint,a.BaseSymbol,a.AdditionalSymbol,
1820
                a.IsExceptDetect,a.HasInstrumentLabel,a.flip,a.TextArea,b.UID as DB_UID FROM Symbol a 
1821
                inner join SymbolType b on a.SymbolType_UID=b.UID WHERE 
1822
                SymbolType_UID = (select UID from SymbolType where {}={})""".format(
1823
                    field_name, self.project.database.place_holder)
1824
            else:
1825
                sql = """SELECT a.UID,a.Name,b.Type,a.Threshold,a.MinMatchPoint,a.IsDetectOrigin,a.RotationCount, 
1826
                a.OCROption,a.IsContainChild,a.OriginalPoint,a.ConnectionPoint,a.BaseSymbol,a.AdditionalSymbol,
1827
                a.IsExceptDetect,a.HasInstrumentLabel,a.flip,a.TextArea,b.UID as DB_UID FROM Symbol a 
1828
                inner join SymbolType b on a.SymbolType_UID=b.UID"""
1829
            try:
1830
                cursor.execute(sql, (param,)) if param is not None else cursor.execute(sql)
1831
                rows = cursor.fetchall()
1832
                if rows is not None and len(rows) > 0:
1833
                    for symbolTuple in rows:
1834
                        sym = symbol.SymbolBase(symbolTuple['Name'], symbolTuple['Type'], symbolTuple['Threshold'],
1835
                                                symbolTuple['MinMatchPoint'], symbolTuple['IsDetectOrigin'],
1836
                                                symbolTuple['RotationCount'], symbolTuple['OCROption'],
1837
                                                symbolTuple['IsContainChild'], symbolTuple['OriginalPoint'],
1838
                                                symbolTuple['ConnectionPoint'], symbolTuple['BaseSymbol'],
1839
                                                symbolTuple['AdditionalSymbol'], symbolTuple['IsExceptDetect'],
1840
                                                symbolTuple['HasInstrumentLabel'], symbolTuple['UID'],
1841
                                                iType=symbolTuple['DB_UID'],
1842
                                                detectFlip=symbolTuple['flip'], text_area=symbolTuple['TextArea'])
1843
                        ret.append(sym)
1844

    
1845
                # update cache
1846
                if ret:
1847
                    if 'UID' not in self._symbolBase:
1848
                        self._symbolBase['UID'] = {}
1849
                    if 'name' not in self._symbolBase:
1850
                        self._symbolBase['name'] = {}
1851

    
1852
                    for _symbol in ret:
1853
                        if _symbol.uid not in self._symbolBase['UID']:
1854
                            self._symbolBase['UID'][_symbol.uid] = _symbol
1855
                        if _symbol.sName not in self._symbolBase['name']:
1856
                            self._symbolBase['name'][_symbol.sName] = _symbol
1857
            except Exception as ex:
1858
                from App import App
1859
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1860
                                                              sys.exc_info()[-1].tb_lineno)
1861
                App.mainWnd().addMessage.emit(MessageType.Error, message)
1862

    
1863
        return ret
1864

    
1865
    '''
1866
        @brief      get NominalDiameter
1867
        @author     humkyung
1868
        @date       2018.04.20
1869
        @history    humkyung 2018.04.24 read MetricStr column and set size unit
1870
                    kyouho 2018.07.04 forCheckLineNumber get only inch or metric
1871
                    kyouho 2018.07.16 edit query order by code
1872
    '''
1873
    def getNomialPipeSizeData(self, forCheckLineNumber=False, orderStr="MetricStr"):
1874
        res = []
1875
        configs = self.getConfigs('Line No', 'Size Unit')
1876
        sizeUnit = configs[0].value if 1 == len(configs) else 'Metric'
1877

    
1878
        conn = self.project.database.connect()
1879
        with conn:
1880
            try:
1881
                # Get a cursor object
1882
                cursor = conn.cursor()
1883

    
1884
                sql = f"select UID,Code,Metric,Inch,InchStr,AllowableInchStr,MetricStr,AllowableMetricStr from " \
1885
                      f"NominalDiameter ORDER BY {orderStr} DESC"
1886
                cursor.execute(sql)
1887
                rows = cursor.fetchall()
1888
                for row in rows:
1889
                    pipeSize = NominalPipeSize(row['UID'], row['Code'], float(row['Metric']) if row['Metric'] else None,
1890
                                               float(row['Inch']) if row['Inch'] else None, row['InchStr'],
1891
                                               row['AllowableInchStr'], row['MetricStr'], row['AllowableMetricStr'])
1892
                    pipeSize.sizeUnit = sizeUnit
1893
                    if forCheckLineNumber:
1894
                        if sizeUnit == 'Inch' and pipeSize.inchStr:
1895
                            res.append(pipeSize.inchStr)
1896
                        elif sizeUnit == 'Metric' and pipeSize.metricStr:
1897
                            res.append(pipeSize.metricStr)
1898
                    else:
1899
                        res.append(pipeSize)
1900

    
1901
                if 'Inch' in sizeUnit:
1902
                    res = sorted(res, key=lambda param:len(param.inchStr), reverse=True)
1903
                else:
1904
                    res = sorted(res, key=lambda param:len(param.metricStr), reverse=True)
1905
            # Catch the exception
1906
            except Exception as ex:
1907
                from App import App
1908
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1909
                                                              sys.exc_info()[-1].tb_lineno)
1910
                App.mainWnd().addMessage.emit(MessageType.Error, message)
1911

    
1912
        return res
1913

    
1914
    '''
1915
        @brief      insert NominalDiameter table
1916
        @author     kyouho
1917
        @date       2018.07.16
1918
    '''
1919
    def insertNomialPipeSize(self, pipeSizes):
1920
        conn = self.project.database.connect()
1921
        with conn:
1922
            try:
1923
                # Get a cursor object
1924
                cursor = conn.cursor()
1925
                for pipeSize in pipeSizes:
1926
                    sql = pipeSize.toSql()
1927
                    if type(sql) is list and len(sql) == 1:
1928
                        cursor.execute(self.project.database.to_sql(sql[0][0]), sql[0][1])
1929

    
1930
                conn.commit()
1931
            # Catch the exception
1932
            except Exception as ex:
1933
                # Roll back any change if something goes wrong
1934
                conn.rollback()
1935

    
1936
                from App import App
1937
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1938
                                                              sys.exc_info()[-1].tb_lineno)
1939
                App.mainWnd().addMessage.emit(MessageType.Error, message)
1940

    
1941
    '''
1942
        @brief      delete NominalDiameter table
1943
        @author     kyouho
1944
        @date       2018.07.16
1945
    '''
1946
    def deleteNomialPipeSize(self):
1947
        conn = self.project.database.connect()
1948
        with conn:
1949
            cursor = conn.cursor()
1950
            sql = "DELETE FROM NominalDiameter"
1951
            try:
1952
                cursor.execute(sql)
1953
                conn.commit()
1954
            except Exception as ex:
1955
                conn.rollback()
1956
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1957
                                                          sys.exc_info()[-1].tb_lineno))
1958

    
1959
    '''
1960
        @brief      convert inch to metric
1961
        @author     kyouho
1962
        @date       2018.07.09
1963
    '''
1964
    def convertInchToMetric(self, inch):
1965
        result = ''
1966
        conn = self.project.database.connect()
1967
        with conn:
1968
            try:
1969
                # Get a cursor object
1970
                cursor = conn.cursor()
1971

    
1972
                sql = "select MetricStr from NominalDiameter WHERE InchStr = ?"
1973
                param = (inch,)
1974
                cursor.execute(sql, param)
1975
                rows = cursor.fetchall()
1976

    
1977
                if rows:
1978
                    result = rows[0][0]
1979
                # Catch the exception
1980
            except Exception as ex:
1981
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
1982
                                                          sys.exc_info()[-1].tb_lineno))
1983

    
1984
        return result
1985

    
1986
    '''
1987
        @brief      get Color MaxUID
1988
        @author     kyouho
1989
        @date       2018.07.03
1990
    '''
1991
    def getMaxColorUID(self):
1992
        result = 0
1993

    
1994
        conn = self.project.database.connect()
1995
        with conn:
1996
            try:
1997
                # Get a cursor object
1998
                cursor = conn.cursor()
1999

    
2000
                sql = "select MAX(UID) from Colors"
2001
                cursor.execute(sql)
2002
                rows = cursor.fetchall()
2003

    
2004
                result = rows[0][0]
2005
                # Catch the exception
2006
            except Exception as ex:
2007
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2008
                                                          sys.exc_info()[-1].tb_lineno))
2009

    
2010
        return result
2011

    
2012
    '''
2013
        @brief      insert Color property
2014
        @author     kyouho
2015
        @date       2018.07.09
2016
    '''
2017
    def setPropertyColor(self, _color):
2018
        conn = self.project.database.connect()
2019
        with conn:
2020
            try:
2021
                # Get a cursor object
2022
                cursor = conn.cursor()
2023
                sql = "INSERT INTO Colors(UID, RED, GREEN, BLUE, PROPERTY, VALUE) VALUES(?,?,?,?,?,?)"
2024
                param = (_color.index, _color.red, _color.green, _color.blue, _color._property, _color.value)
2025
                cursor.execute(sql, param)
2026
                conn.commit()
2027
            # Catch the exception
2028
            except Exception as ex:
2029
                # Roll back any change if something goes wrong
2030
                conn.rollback()
2031
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2032
                                                          sys.exc_info()[-1].tb_lineno))
2033

    
2034
    '''
2035
        @brief      delete Color property
2036
        @author     kyouho
2037
        @date       2018.07.09
2038
    '''
2039
    def deletePropertyColor(self, property):
2040
        conn = self.project.database.connect()
2041
        with conn:
2042
            try:
2043
                # Get a cursor object
2044
                cursor = conn.cursor()
2045

    
2046
                sql = "DELETE FROM Colors WHERE PROPERTY = '{}'".format(property)
2047
                cursor.execute(sql)
2048
                conn.commit()
2049
                # Catch the exception
2050
            except Exception as ex:
2051
                # Roll back any change if something goes wrong
2052
                conn.rollback()
2053
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2054
                                                          sys.exc_info()[-1].tb_lineno))
2055

    
2056
    '''
2057
        @brief      get Fluid Code
2058
        @author     kyouho
2059
        @date       2018.07.03
2060
        @history    kyouho 2018.07.04 kyouho 2018.07.04 forCheckLineNumber get only code
2061
    '''
2062
    def getFluidCodeData(self, forCheckLineNumber=False):
2063
        from FluidCodeData import FluidCodeData
2064
        result = []
2065

    
2066
        conn = self.project.database.connect()
2067
        with conn:
2068
            try:
2069
                # Get a cursor object
2070
                cursor = conn.cursor()
2071

    
2072
                sql = 'select uid, code, description from FluidCode order by length(code) DESC'
2073
                cursor.execute(sql)
2074
                rows = cursor.fetchall()
2075
                for row in rows:
2076
                    data = FluidCodeData(row[0], row[1], row[2])
2077
                    if forCheckLineNumber:
2078
                        result.append(data.code)
2079
                    else:
2080
                        result.append(data)
2081
                # Catch the exception
2082
            except Exception as ex:
2083
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2084
                                                          sys.exc_info()[-1].tb_lineno))
2085

    
2086
        return result
2087

    
2088
    '''
2089
        @brief      get Symbol Attribute
2090
        @author     kyouho
2091
        @date       2018.07.18
2092
    '''
2093
    def checkAttribute(self, attr):
2094
        conn = self.project.database.connect()
2095
        with conn:
2096
            try:
2097
                # Get a cursor object
2098
                cursor = conn.cursor()
2099

    
2100
                sql = 'select UID from SymbolAttribute where UID = ?'
2101
                param = (attr,)
2102
                cursor.execute(sql, param)
2103
                rows = cursor.fetchall()
2104
                if len(rows):
2105
                    return True
2106
                else:
2107
                    return False
2108
                # Catch the exception
2109
            except Exception as ex:
2110
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2111
                                                          sys.exc_info()[-1].tb_lineno))
2112

    
2113
        return False
2114

    
2115
    def read_drawing_shape(self, drawing):
2116
        """read drawing shape"""
2117

    
2118
        res = None
2119

    
2120
        with self.project.database.connect() as conn:
2121
            try:
2122
                # Get a cursor object
2123
                cursor = conn.cursor()
2124

    
2125
                sql = f"select Image from Drawings where UID='{drawing}'"
2126
                cursor.execute(sql)
2127
                records = cursor.fetchall()
2128
                for record in records:
2129
                    res = record[0]
2130
                    break
2131

    
2132
            # Catch the exception
2133
            except Exception as ex:
2134
                from App import App
2135
                # Roll back any change if something goes wrong
2136
                conn.rollback()
2137

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

    
2142
        return res
2143

    
2144
    def read_symbol_shape(self, symbol_name):
2145
        """read symbol shape(image and svg)"""
2146
        
2147
        res = (None, None)
2148

    
2149
        # need to test on mssql
2150
        return res
2151

    
2152
        with self.project.database.connect() as conn:
2153
            try:
2154
                # Get a cursor object
2155
                cursor = conn.cursor()
2156

    
2157
                sql = f"select Image, Svg from Symbol where Name='{symbol_name}'"
2158
                cursor.execute(sql)
2159
                records = cursor.fetchall()
2160
                for record in records:
2161
                    res = (record[0], record[1])
2162
                    break
2163

    
2164
            # Catch the exception
2165
            except Exception as ex:
2166
                from App import App
2167
                # Roll back any change if something goes wrong
2168
                conn.rollback()
2169

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

    
2174
        return res
2175

    
2176

    
2177
    def update_symbol_shape(self, symbol_name, image_file, svg_file, image_display_file):
2178
        """update symbol shape"""
2179

    
2180
        # need to test on mssql
2181
        return
2182

    
2183
        with self.project.database.connect() as conn:
2184
            try:
2185
                # Get a cursor object
2186
                cursor = conn.cursor()
2187

    
2188
                cols = []
2189
                params = []
2190

    
2191
                image_blob_data = None
2192
                if image_file and os.path.isfile(image_file):
2193
                    with open(image_file, 'rb') as file:
2194
                        image_blob_data = file.read()
2195
                    cols.append('Image=?')
2196
                    params.append(image_blob_data)
2197

    
2198
                svg_blob_data = None
2199
                if svg_file and os.path.isfile(svg_file):
2200
                    with open(svg_file, 'rb') as file:
2201
                        svg_blob_data = file.read()
2202
                    cols.append('Svg=?')
2203
                    params.append(svg_blob_data)
2204

    
2205
                image_display_blob_data = None
2206
                if image_file and image_display_file and os.path.isfile(image_display_file):
2207
                    with open(image_file, 'rb') as file:
2208
                        image_display_blob_data = file.read()
2209
                    cols.append('Image_display=?')
2210
                    params.append(image_display_blob_data)
2211

    
2212
                sql = f"update Symbol set {','.join(cols)} where Name='{symbol_name}'"
2213
                # Convert data into tuple format
2214
                cursor.execute(self.project.database.to_sql(sql), tuple(params))
2215
                conn.commit()
2216

    
2217
            # Catch the exception
2218
            except Exception as ex:
2219
                from App import App
2220
                # Roll back any change if something goes wrong
2221
                conn.rollback()
2222

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

    
2227
    def getReplaceTables(self):
2228
        ''' get replace(inst) code tables '''
2229

    
2230
        import uuid
2231
        from CodeTables import CodeTable
2232

    
2233
        with self.project.database.connect() as conn:
2234
            try:
2235
                result = []
2236

    
2237
                # Get a cursor object
2238
                cursor = conn.cursor()
2239

    
2240
                sql = self.project.database.to_sql('select UID, Name, Description from InstTables')
2241
                cursor.execute(sql)
2242
                rows = cursor.fetchall()
2243
                for row in rows:
2244
                    table = []
2245
                    table.append(uuid.UUID(row['UID']))
2246
                    table.append(row['Name'])
2247
                    table.append(row['Description'])
2248
                    table.append(CodeTable.instance('InstCodes', inst_table_uid=row['UID']))
2249
                    result.append(table)
2250
            # Catch the exception
2251
            except Exception as ex:
2252
                from App import App
2253
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2254
                                                              sys.exc_info()[-1].tb_lineno)
2255
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2256

    
2257
        return result
2258

    
2259
    def getCustomTables(self):
2260
        ''' get custom code tables '''
2261

    
2262
        import uuid
2263
        from CodeTables import CodeTable
2264

    
2265
        with self.project.database.connect() as conn:
2266
            try:
2267
                result = []
2268

    
2269
                # Get a cursor object
2270
                cursor = conn.cursor()
2271

    
2272
                sql = self.project.database.to_sql('select UID, Name, Description from CustomTables')
2273
                cursor.execute(sql)
2274
                rows = cursor.fetchall()
2275
                for row in rows:
2276
                    table = []
2277
                    table.append(uuid.UUID(row['UID']))
2278
                    table.append(row['Name'])
2279
                    table.append(row['Description'])
2280
                    table.append(CodeTable.instance('CustomCodes', custom_table_uid=row['UID']))
2281
                    result.append(table)
2282
            # Catch the exception
2283
            except Exception as ex:
2284
                from App import App
2285
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2286
                                                              sys.exc_info()[-1].tb_lineno)
2287
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2288

    
2289
        return result
2290

    
2291
    def loadSymbolAttributeCodeTables(self):
2292
        ''' load symbol attribute code tables '''
2293

    
2294
        try:
2295
            types = self.getSymbolTypeList()
2296

    
2297
            for _type in types:
2298
                self.getSymbolAttribute(_type[2])
2299

    
2300
        except Exception as ex:
2301
            from App import App
2302
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2303
                                                            sys.exc_info()[-1].tb_lineno)
2304
            App.mainWnd().addMessage.emit(MessageType.Error, message)
2305

    
2306
    '''
2307
        @brief      get Symbol Attribute
2308
        @author     kyouho
2309
        @date       2018.07.18
2310
        @history    humkyung 2018.10.13 load expression
2311
    '''
2312
    def getSymbolAttribute(self, _type):
2313
        import uuid
2314
        from SymbolAttr import SymbolAttr
2315
        from CodeTables import CodeTable
2316

    
2317
        result = []
2318

    
2319
        if self._attributeByType and _type in self._attributeByType:
2320
            new_attr_without_any_binding_data = []
2321
            for attr_old in self._attributeByType[_type]:
2322
                attr = SymbolAttr()
2323
                attr.UID = attr_old.UID
2324
                attr.Attribute = attr_old.Attribute
2325
                attr.DisplayAttribute = attr_old.DisplayAttribute
2326
                attr.AttributeType = attr_old.AttributeType
2327
                attr.AttrAt = attr_old.AttrAt
2328
                attr.Expression = attr_old.Expression
2329
                attr.Target = attr_old.Target
2330
                attr.IsProp = attr_old.IsProp
2331
                attr.Codes = attr_old.Codes
2332
                attr.Index = attr_old.Index
2333
                new_attr_without_any_binding_data.append(attr)
2334
            self._attributeByType[_type] = new_attr_without_any_binding_data
2335

    
2336
            return self._attributeByType[_type]
2337

    
2338
        with self.project.database.connect() as conn:
2339
            try:
2340
                # Get a cursor object
2341
                cursor = conn.cursor()
2342

    
2343
                sql = self.project.database.to_sql(
2344
                    'select a.UID, a.Attribute, a.DisplayAttribute, a.AttributeType, a.[AttrAt], a.[Expression], '
2345
                    'a.[index], a.[Target], a.[Property], a.[index] from SymbolAttribute a inner join SymbolType t '
2346
                    'on a.SymbolType_UID = t.UID and t.type = ? order by a.[index]')
2347
                param = (_type,)
2348
                cursor.execute(sql, param)
2349
                rows = cursor.fetchall()
2350
                for row in rows:
2351
                    attr = SymbolAttr()
2352
                    attr.UID = uuid.UUID(row['UID'].replace('\n', ""))
2353
                    attr.Attribute = row['Attribute']
2354
                    attr.DisplayAttribute = row['DisplayAttribute']
2355
                    attr.AttributeType = row['AttributeType']
2356
                    attr.AttrAt = row['AttrAt']
2357
                    attr.Expression = row['Expression']
2358
                    attr.Target = row['Target']
2359
                    attr.IsProp = row['Property']
2360
                    attr.Index = row['index']
2361
                    attr.Codes = CodeTable.instance('SymbolAttributeCodeTable', symbol_attribute_uid=row['UID'])
2362
                    result.append(attr)
2363
            # Catch the exception
2364
            except Exception as ex:
2365
                from App import App
2366
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2367
                                                              sys.exc_info()[-1].tb_lineno)
2368
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2369

    
2370
        self._attributeByType[_type] = result
2371
        return result
2372

    
2373
    '''
2374
        @brief      get Symbol Attribute by UID
2375
        @author     kyouho
2376
        @date       2018.08.17
2377
        @history    humkyung 2018.10.13 load expression
2378
    '''
2379
    def getSymbolAttributeByUID(self, UID):
2380
        from SymbolAttr import SymbolAttr
2381

    
2382
        res = None
2383

    
2384
        with self.project.database.connect() as conn:
2385
            try:
2386
                # Get a cursor object
2387
                cursor = conn.cursor()
2388

    
2389
                sql = f"select Attribute, DisplayAttribute, AttributeType, AttrAt, Expression, Target, Property, [index] from " \
2390
                      f"SymbolAttribute where uid = '{UID}'"
2391
                cursor.execute(sql)
2392
                rows = cursor.fetchall()
2393
                if len(rows):
2394
                    res = SymbolAttr()
2395
                    res.UID = UID
2396
                    res.Attribute = rows[0]['Attribute']
2397
                    res.DisplayAttribute = rows[0]['DisplayAttribute']
2398
                    res.AttributeType = rows[0]['AttributeType']
2399
                    res.AttrAt = rows[0]['AttrAt']
2400
                    res.Expression = rows[0]['Expression']
2401
                    res.Target = rows[0]['Target']
2402
                    res.IsProp = rows[0]['Property']
2403
                    res.Index = rows[0]['index']
2404
                # Catch the exception
2405
            except Exception as ex:
2406
                from App import App
2407
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2408
                                                              sys.exc_info()[-1].tb_lineno)
2409
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2410

    
2411
        return res
2412

    
2413
    '''
2414
        @brief      save symbol attributes
2415
        @author     humkyung
2416
        @date       2018.08.14
2417
        @history    humkyung 2018.10.13 save expression
2418
    '''
2419
    def saveSymbolAttributes(self, type, attrs, type_str):
2420
        from CodeTables import CodeTable
2421

    
2422
        with self.project.database.connect() as conn:
2423
            try:
2424
                # Get a cursor object
2425
                cursor = conn.cursor()
2426

    
2427
                # delete symbol attribute code table data
2428
                origin_attrs = self.getSymbolAttribute(type_str)
2429
                for origin_attr in origin_attrs:
2430
                    '''
2431
                    # delete symbol attribute code table data for deleted symbol attribute, and backup not edited attribute code table data
2432
                    remain = False
2433
                    for attr in attrs:
2434
                        if str(origin_attr.UID) == attr[0]:
2435
                            remain = True
2436
                            break
2437
                    if remain and attr[-1] and type(attr[-1][0][3]) is list: # this means not edited and need backup
2438
                        attr[-1] = self.getCodeTable('SymbolAttributeCodeTable', forCheckLineNumber=False, symbol_attribute_uid=origin_attr.UID)
2439
                    '''
2440
                    
2441
                    sql = "delete from SymbolAttributeCodeTable where SymbolAttribute_UID = '{}'".format(origin_attr.UID)
2442
                    cursor.execute(sql)
2443
                # up to here
2444

    
2445
                # update symbol attribute
2446
                sql = self.project.database.to_sql('delete from SymbolAttribute where SymbolType_UID = ?')
2447
                param = (type,)
2448
                cursor.execute(sql, param)
2449

    
2450
                for attr in attrs:
2451
                    sql = self.project.database.to_sql(
2452
                        'insert into SymbolAttribute(UID, SymbolType_UID, Attribute, DisplayAttribute, AttributeType, '
2453
                        'AttrAt, Expression, Target, [index], [Property]) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)')
2454
                    attr.insert(1, type)
2455
                    cursor.execute(sql, tuple(attr[:-1]))
2456
                # up to here
2457

    
2458
                # update symbol attribute code table data
2459
                for attr in attrs:
2460
                    if attr[-1]:
2461
                        for code in attr[-1]:
2462
                            sql = self.project.database.to_sql( \
2463
                                "insert into SymbolAttributeCodeTable(UID, Code, Description, Allowables, "
2464
                                "SymbolAttribute_UID) VALUES(?,?,?,?,?)")
2465
                            param = (code[0], code[1], code[2], ','.join(code[3]), attr[0])
2466
                            cursor.execute(sql, param)
2467
                # up to here
2468

    
2469
                conn.commit()
2470

    
2471
                if hasattr(self, '_equipment_attributes'):
2472
                    del self._equipment_attributes
2473

    
2474
                if hasattr(self, '_valve_attributes'):
2475
                    del self._valve_attributes
2476

    
2477
                if hasattr(self, '_inst_attributes'):
2478
                    del self._inst_attributes
2479

    
2480
                if hasattr(self, '_note_attributes'):
2481
                    del self._note_attributes
2482
            # Catch the exception
2483
            except Exception as ex:
2484
                # Roll back any change if something goes wrong
2485
                conn.rollback()
2486

    
2487
                from App import App
2488
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2489
                                                              sys.exc_info()[-1].tb_lineno)
2490
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2491

    
2492
            self._attributeByType = {}
2493
            CodeTable.clearTables()
2494

    
2495
    def save_hmb_data(self, hmb_list: list):
2496
        import uuid
2497

    
2498
        app_doc_data = AppDocData.instance()
2499
        with app_doc_data.project.database.connect() as conn:
2500
            try:
2501
                cursor = conn.cursor()
2502
                sql = 'delete from HMB_VALUE'
2503
                cursor.execute(sql)
2504
                sql = 'delete from HMB_LIST'
2505
                cursor.execute(sql)
2506
                sql = 'delete from Stream_No'
2507
                cursor.execute(sql)
2508

    
2509
                list_uids = []
2510
                if hmb_list and hmb_list[0].datas:
2511
                    """save hmb data catalog""" 
2512
                    for data in hmb_list[0].datas[0]:
2513
                        sql = f"insert into HMB_LIST(UID, Name, Unit, [index], [Type]) values(?,?,?,?,?)"
2514
                        sql = self.project.database.to_sql(sql)
2515
                        list_uid = str(uuid.uuid4())
2516
                        params = (list_uid, data.name, data.unit, data.index, data.phase)
2517
                        list_uids.append(list_uid)
2518
                        cursor.execute(sql, params)
2519

    
2520
                for hmb in hmb_list:
2521
                    """stream no save"""
2522
                    sql = f'insert into Stream_No(UID, Stream_No, [From], [To]) values(?,?,?,?)'
2523
                    sql = self.project.database.to_sql(sql)
2524
                    hmb.uid = hmb.uid if hmb.uid else str(uuid.uuid4())
2525
                    params = (str(hmb.uid), hmb.stream_no, hmb.hfrom, hmb.hto)
2526
                    cursor.execute(sql, params)
2527

    
2528
                    """save hmb data value"""
2529
                    params = []
2530
                    sql = f"insert into HMB_Value(UID, HMB_LIST_UID, Stream_No_UID, Value, [Case]) values(?,?,?,?,?)"
2531
                    sql = self.project.database.to_sql(sql)
2532
                    for data_case in hmb.datas:
2533
                        index = 0
2534
                        for data in data_case:
2535
                            params.append((str(uuid.uuid4()), list_uids[index], hmb.uid, data.value, data.case))
2536
                            index = index + 1
2537
                    cursor.executemany(sql, tuple(params))
2538

    
2539
                conn.commit()
2540
                self._hmbData = None
2541
                        
2542
            except Exception as ex:
2543
                # Roll back any change if something goes wrong
2544
                conn.rollback()
2545

    
2546
                from App import App
2547
                message = f"error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:" \
2548
                          f"{sys.exc_info()[-1].tb_lineno}"
2549
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2550

    
2551
    def get_hmb_data(self, file_path: str):
2552
        """get hmb data from pap database if file_path is given otherwise get hmb data from id2 database"""
2553

    
2554
        from HMBTable import HMBData
2555

    
2556
        if not file_path:
2557
            if self._hmbData is None:
2558
                app_doc_data = AppDocData.instance()
2559
                with app_doc_data.project.database.connect() as conn:
2560
                    try:
2561
                        cursor = conn.cursor()
2562
                        sql = f"SELECT v.Value, v.[Case], r.Name, r.Unit, r.[index], r.[Type], s.Stream_No, s.[From], s.[To], s.UID FROM " \
2563
                                f"HMB_VALUE v " \
2564
                                f"INNER JOIN HMB_LIST r ON v.HMB_LIST_UID=r.UID " \
2565
                                f"INNER JOIN Stream_No s ON v.Stream_No_UID=s.UID " \
2566
                                f"ORDER BY s.stream_no"
2567
                        cursor.execute(sql)
2568
                        rows = cursor.fetchall()
2569

    
2570
                        hmbs = HMBData.from_row(rows)
2571
                        self._hmbData = hmbs
2572
                        return self._hmbData
2573
                    except Exception as ex:
2574
                        # Roll back any change if something goes wrong
2575
                        conn.rollback()
2576

    
2577
                        from App import App
2578
                        message = f"error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:" \
2579
                                f"{sys.exc_info()[-1].tb_lineno}"
2580
                        App.mainWnd().addMessage.emit(MessageType.Error, message)
2581
            else:
2582
                return self._hmbData
2583
        else:
2584
            with sqlite3.connect(file_path) as conn:
2585
                try:
2586
                    conn.row_factory = sqlite3.Row
2587
                    cursor = conn.cursor()
2588
                    sql = 'select * from HMB_condition'
2589
                    cursor.execute(sql)
2590
                    rows = cursor.fetchall()
2591
                    return rows
2592
                except Exception as ex:
2593
                    # Roll back any change if something goes wrong
2594
                    conn.rollback()
2595

    
2596
                    from App import App
2597
                    message = f"error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:" \
2598
                              f"{sys.exc_info()[-1].tb_lineno}"
2599
                    App.mainWnd().addMessage.emit(MessageType.Error, message)
2600

    
2601
        return None
2602

    
2603
    def get_hmb_attributes(self):
2604
        """get hmb attributes"""
2605
        from SymbolAttr import SymbolAttr
2606

    
2607
        attrs = []
2608
        with self.project.database.connect() as conn:
2609
            try:
2610
                # Get a cursor object
2611
                cursor = conn.cursor()
2612

    
2613
                sql = f"select * from SymbolAttribute where SymbolType_UID = " \
2614
                      f"(select UID from SymbolType where Type='HMB') order by [index]"
2615
                sql = self.project.database.to_sql(sql)
2616
                cursor.execute(sql)
2617
                rows = cursor.fetchall()
2618
                for row in rows:
2619
                    attr = SymbolAttr(row['UID'])
2620
                    attr.Attribute = row['Attribute']
2621
                    attr.DisplayAttribute = row['DisplayAttribute']
2622
                    attr.AttributeType = row['AttributeType']
2623
                    attr.AttrAt = row['AttrAt']
2624
                    attr.Expression = row['Expression']
2625
                    attr.Target = row['Target']
2626
                    attr.IsProp = row['Property']
2627
                    attr.Index = row['index']
2628

    
2629
                    attrs.append(attr)
2630

    
2631
            # Catch the exception
2632
            except Exception as ex:
2633
                # Roll back any change if something goes wrong
2634
                conn.rollback()
2635

    
2636
                from App import App
2637
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2638
                                                               sys.exc_info()[-1].tb_lineno)
2639
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2640

    
2641
        return attrs
2642

    
2643
    def save_hmb_model(self, model: QStandardItemModel):
2644
        """ no more used """
2645
        """save hmb model to database"""
2646

    
2647
        with self.project.database.connect() as conn:
2648
            try:
2649
                # get a cursor object
2650
                cursor = conn.cursor()
2651

    
2652
                # delete hmb table
2653
                sql = 'delete from HMB'
2654
                sql = self.project.database.to_sql(sql)
2655
                cursor.execute(sql)
2656
                # up to here
2657

    
2658
                for row in range(model.rowCount()):
2659
                    params = []
2660
                    for col in range(model.columnCount()):
2661
                        data = model.data(model.index(row, col))
2662
                        params.append(data)
2663

    
2664
                    values = ['?' for col in range(model.columnCount())]
2665
                    sql = f"insert into HMB values({','.join(values)})"
2666
                    cursor.execute(sql, params)
2667

    
2668
                conn.commit()
2669
            except Exception as ex:
2670
                # Roll back any change if something goes wrong
2671
                conn.rollback()
2672

    
2673
                from App import App
2674
                message = f"error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:" \
2675
                          f"{sys.exc_info()[-1].tb_lineno}"
2676
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2677

    
2678
    def save_hmb_attributes(self, attrs):
2679
        """save hmb attributes"""
2680
        from CodeTables import CodeTable
2681

    
2682
        with self.project.database.connect() as conn:
2683
            try:
2684
                # Get a cursor object
2685
                cursor = conn.cursor()
2686

    
2687
                # delete hmb attributes
2688
                sql = f"delete from SymbolAttribute where SymbolType_UID = (select UID from SymbolType where Type='HMB')"
2689
                sql = self.project.database.to_sql(sql)
2690
                cursor.execute(sql)
2691
                # up to here
2692

    
2693
                for idx, attr in enumerate(attrs):
2694
                    sql = self.project.database.to_sql(
2695
                        'insert into SymbolAttribute(UID, SymbolType_UID, Attribute, DisplayAttribute, AttributeType, '
2696
                        'AttrAt, Expression, Target, [index], [Property]) values(?, '
2697
                        '(select uid from SymbolType where Type=\'HMB\'), ?, ?, ?, ?, ?, ?, ?, ?)')
2698
                    params = (str(attr.UID), attr.Attribute, attr.Attribute, 'String', attr.AttrAt,
2699
                              attr.Expression if attr.Expression else None, attr.Target, idx, attr.IsProp)
2700

    
2701
                    cursor.execute(sql, params)
2702
                # up to here
2703

    
2704
                conn.commit()
2705

    
2706
            # Catch the exception
2707
            except Exception as ex:
2708
                # Roll back any change if something goes wrong
2709
                conn.rollback()
2710

    
2711
                from App import App
2712
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2713
                                                               sys.exc_info()[-1].tb_lineno)
2714
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2715

    
2716
    @staticmethod
2717
    def save_stream_line_data(stream_line_list: list):
2718
        """ save stream line from to """
2719
        import uuid
2720

    
2721
        app_doc_data = AppDocData.instance()
2722
        with app_doc_data.project.database.connect() as conn:
2723
            try:
2724
                cursor = conn.cursor()
2725
                """delete stream line which has stream number is given data"""
2726
                sql = "delete from HMB_From_To where Stream_No=?"
2727
                sql = app_doc_data.project.database.to_sql(sql)
2728
                params = (stream_line_list[0],)
2729
                cursor.execute(sql, params)
2730
                """up to here"""
2731

    
2732
                for stream_line in stream_line_list[1]:
2733
                    sql = f"insert into HMB_From_To(UID,[Drawing_UID],[From_Component_UID],[To_Component_UID],[Stream_No],[Case]) values" \
2734
                          f"(?,?,?,?,?,?)"
2735
                    sql = app_doc_data.project.database.to_sql(sql)
2736
                    params = (str(uuid.uuid4()), stream_line[0], stream_line[1], stream_line[2], stream_line[3], stream_line[4])
2737
                    cursor.execute(sql, params)
2738

    
2739
                conn.commit()
2740
            except Exception as ex:
2741
                # Roll back any change if something goes wrong
2742
                conn.rollback()
2743

    
2744
                from App import App
2745
                message = f"error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:" \
2746
                          f"{sys.exc_info()[-1].tb_lineno}"
2747
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2748

    
2749
    def get_stream_line_list_data(self, drawing_names=None):
2750
        """ get stream line list data from """
2751
        with self.project.database.connect() as conn:
2752
            try:
2753
                # Get a cursor object
2754
                cursor = conn.cursor()
2755

    
2756
                if drawing_names is None:
2757
                    doc_names = self.activeDrawing.name
2758
                else:
2759
                    doc_names = "','".join(drawing_names)
2760

    
2761
                sql = f"select S.PnIDNumber, S.Tag_Seq_No, S.PipingMaterialsClass, S.InsulationPurpose, S.FluidCode, " \
2762
                      f"S.UnitNumber, S.NominalDiameter, S.[From], S.[To], S.Stream_No, S.[Case], S.[Index], D.Name from Stream_Line_List S " \
2763
                      f"join Drawings D on S.Drawing_UID=D.UID " \
2764
                      f"where S.Drawing_UID in (select UID from Drawings where Name in ('{doc_names}'))"
2765
                sql = self.project.database.to_sql(sql)
2766
                cursor.execute(sql)
2767
                rows = cursor.fetchall()
2768

    
2769
                datas = []
2770
                for row in rows:
2771
                    data = {}
2772
                    data['PnIDNumber'] = row['PnIDNumber']
2773
                    data['Tag Seq No'] = row['Tag_Seq_No']
2774
                    data['PipingMaterialsClass'] = row['PipingMaterialsClass']
2775
                    data['InsulationPurpose'] = row['InsulationPurpose']
2776
                    data['FluidCode'] = row['FluidCode']
2777
                    data['UnitNumber'] = row['UnitNumber']
2778
                    data['NominalDiameter'] = row['NominalDiameter']
2779
                    data['FROM'] = row['From']
2780
                    data['TO'] = row['To']
2781
                    data['Stream No'] = row['Stream_No']
2782
                    data['Case'] = row['Case'] if row['Case'] else ''
2783
                    data['index'] = row['Index']
2784
                    data['Drawing Name'] = row['Name']
2785
                    
2786
                    datas.append(data)
2787

    
2788
                return datas
2789

    
2790
            # Catch the exception
2791
            except Exception as ex:
2792
                # Roll back any change if something goes wrong
2793
                conn.rollback()
2794

    
2795
                from App import App
2796
                message = f"error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:" \
2797
                          f"{sys.exc_info()[-1].tb_lineno}"
2798
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2799

    
2800
    def get_stream_from_to(self, stream_no: str = None, drawing_uid: str = None) -> list:
2801
        """ get stream lines related to hmb """
2802

    
2803
        with self.project.database.connect() as conn:
2804
            try:
2805
                # Get a cursor object
2806
                cursor = conn.cursor()
2807

    
2808
                if stream_no:
2809
                    sql = f"select h.Drawing_UID, h.From_Component_UID, h.To_Component_UID, d.Name, h.[Case] from HMB_From_To h " \
2810
                          f"inner join Drawings d on d.UID=h.Drawing_UID " \
2811
                          f"where Stream_No = ?"
2812
                    params = (stream_no,)
2813
                else:
2814
                    sql = f"select h.From_Component_UID, h.To_Component_UID, s.Stream_No, h.[Case] from HMB_From_To h " \
2815
                          f"inner join Stream_No s on s.Stream_No=h.Stream_No " \
2816
                          f"where Drawing_UID = ?"
2817
                    params = (drawing_uid,)
2818
                sql = self.project.database.to_sql(sql)
2819
                cursor.execute(sql, params)
2820
                return cursor.fetchall()
2821
            # Catch the exception
2822
            except Exception as ex:
2823
                # Roll back any change if something goes wrong
2824
                conn.rollback()
2825

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

    
2831

    
2832
    def saveCustomCodes(self, tables):
2833
        ''' save custom code tables and codes '''
2834

    
2835
        from CodeTables import CodeTable
2836

    
2837
        conn = self.project.database.connect()
2838
        with conn:
2839
            try:
2840
                # Get a cursor object
2841
                cursor = conn.cursor()
2842

    
2843
                # delete custom codes and tables
2844
                sql = "delete from CustomCodes"
2845
                cursor.execute(sql)
2846

    
2847
                sql = "delete from CustomTables"
2848
                cursor.execute(sql)
2849
                # up to here
2850

    
2851
                # update symbol attribute code table data
2852
                for table in tables:
2853
                    sql = self.project.database.to_sql("insert into CustomTables (UID, Name, Description) VALUES(?,?,?)")
2854
                    param = (table[0], table[1], table[2])
2855
                    cursor.execute(sql, param)
2856

    
2857
                    for code in table[3]:
2858
                        sql = self.project.database.to_sql( \
2859
                            "insert into CustomCodes(UID, Code, Description, Allowables, Table_UID) VALUES(?,?,?,?,?)")
2860
                        param = (code[0], code[1], code[2], ','.join(code[3]), table[0])
2861
                        cursor.execute(sql, param)
2862
                # up to here
2863

    
2864
                conn.commit()
2865

    
2866
            # Catch the exception
2867
            except Exception as ex:
2868
                # Roll back any change if something goes wrong
2869
                conn.rollback()
2870

    
2871
                from App import App
2872
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2873
                                                              sys.exc_info()[-1].tb_lineno)
2874
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2875

    
2876
            CodeTable.clearTables()
2877

    
2878
    def saveReplaceCodes(self, tables):
2879
        ''' save repalce(inst) code tables and codes '''
2880

    
2881
        from CodeTables import CodeTable
2882

    
2883
        conn = self.project.database.connect()
2884
        with conn:
2885
            try:
2886
                # Get a cursor object
2887
                cursor = conn.cursor()
2888

    
2889
                # delete custom codes and tables
2890
                sql = "delete from InstCodes"
2891
                cursor.execute(sql)
2892

    
2893
                sql = "delete from InstTables"
2894
                cursor.execute(sql)
2895
                # up to here
2896

    
2897
                # update symbol attribute code table data
2898
                for table in tables:
2899
                    sql = self.project.database.to_sql("insert into InstTables (UID, Name, Description) VALUES(?,?,?)")
2900
                    param = (table[0], table[1], table[2])
2901
                    cursor.execute(sql, param)
2902

    
2903
                    for code in table[3]:
2904
                        sql = self.project.database.to_sql( \
2905
                            "insert into InstCodes(UID, Code, Symbols, Attribute, NewCode, Expression, Priority, Table_UID) VALUES(?,?,?,?,?,?,?,?)")
2906
                        param = (code[0], ','.join(code[1]), ','.join(code[2]), ','.join(code[3]), code[4], code[5], code[6], table[0])
2907
                        cursor.execute(sql, param)
2908
                # up to here
2909

    
2910
                conn.commit()
2911

    
2912
            # Catch the exception
2913
            except Exception as ex:
2914
                # Roll back any change if something goes wrong
2915
                conn.rollback()
2916

    
2917
                from App import App
2918
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2919
                                                              sys.exc_info()[-1].tb_lineno)
2920
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2921

    
2922
            CodeTable.clearTables()
2923

    
2924
    '''
2925
        @brief      save symbol attributes
2926
        @author     humkyung
2927
        @date       2018.08.14
2928
    '''
2929
    def saveLineAttributes(self, attrs):
2930
        with self.project.database.connect() as conn:
2931
            try:
2932
                # Get a cursor object
2933
                cursor = conn.cursor()
2934

    
2935
                sql = 'delete from LineProperties'
2936
                cursor.execute(sql)
2937

    
2938
                for attr in attrs:
2939
                    sql = self.project.database.to_sql(
2940
                        'insert into LineProperties(UID, Name, DisplayName, Type, LimitNumber, [index]) values(?, ?, ?, ?, ?, ?)')
2941
                    cursor.execute(sql, tuple(attr))
2942

    
2943
                conn.commit()
2944

    
2945
                self._lineNoProperties = None
2946
                self._lineNoPropertiesUID = {}
2947
            # Catch the exception
2948
            except Exception as ex:
2949
                # Roll back any change if something goes wrong
2950
                conn.rollback()
2951

    
2952
                from App import App
2953
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2954
                                                              sys.exc_info()[-1].tb_lineno)
2955
                App.mainWnd().addMessage.emit(MessageType.Error, message)
2956

    
2957
    '''
2958
        @brief      get symbol type id
2959
        @author     kyouho
2960
        @date       2018.08.17
2961
    '''
2962
    def getSymbolTypeId(self, symbolType):
2963
        result = []
2964

    
2965
        with self.project.database.connect() as conn:
2966
            try:
2967
                # Get a cursor object
2968
                cursor = conn.cursor()
2969

    
2970
                sql = self.project.database.to_sql('select UID from SymbolType where Type = ?')
2971
                param = (symbolType,)
2972
                cursor.execute(sql, param)
2973
                rows = cursor.fetchall()
2974

    
2975
                if len(rows):
2976
                    result = rows[0]['UID']
2977
                else:
2978
                    result = -1
2979
                # Catch the exception
2980
            except Exception as ex:
2981
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
2982
                                                          sys.exc_info()[-1].tb_lineno))
2983

    
2984
        return result
2985

    
2986
    '''
2987
        @brief      get Code Table Data
2988
        @author     kyouho
2989
        @date       2018.07.10
2990
    '''
2991
    def getCodeTable(self, property, forCheckLineNumber=False, symbol_attribute_uid=None, custom_table_uid=None, custom=False, \
2992
                                                    inst_table_uid=None, inst=False):
2993
        result = []
2994
        with self.project.database.connect() as conn:
2995
            try:
2996
                # Get a cursor object
2997
                cursor = conn.cursor()
2998

    
2999
                if property.upper().replace(' ', '') == "NOMINALDIAMETER" and forCheckLineNumber:
3000
                    cols = ['InchStr', 'MetricStr']
3001
                    sql = f"select {cols[0]}, {cols[1]} from [{property}] order by Metric ASC"
3002
                    cursor.execute(sql)
3003
                    rows = cursor.fetchall()
3004
                    for index in range(2):
3005
                        for row in rows:
3006
                            if row[cols[index]] != '' and result.count(row[cols[index]].replace("'", '"')) == 0:
3007
                                result.append(row[cols[index]].replace("'", '"'))
3008
                else:
3009
                    """
3010
                    sql = "select name from sqlite_master where type='table'"# AND name={}".format(property)
3011
                    cursor.execute(sql)
3012
                    rows = cursor.fetchall()
3013
                    if property.upper() in [name[0].upper() for name in rows]:
3014
                    """
3015
                    if not symbol_attribute_uid and not custom_table_uid and not custom and not inst_table_uid and not inst:
3016
                        sql = 'select uid, code, description, Allowables from [{}] order by code DESC'.format(property)
3017
                    elif symbol_attribute_uid and not custom_table_uid and not inst_table_uid and not inst:
3018
                        sql = "select uid, code, description, Allowables from [{}] where SymbolAttribute_UID='{}' " \
3019
                              "order by code DESC".format(property, symbol_attribute_uid)
3020
                    elif not symbol_attribute_uid and custom_table_uid and not inst_table_uid:
3021
                        sql = "select uid, code, description, Allowables from [{}] where Table_UID='{}' " \
3022
                              "order by code DESC".format(property, custom_table_uid)
3023
                    elif not symbol_attribute_uid and not custom_table_uid and inst_table_uid:
3024
                        sql = "select uid, code, symbols, attribute, newcode, expression, priority from [{}] where Table_UID='{}' " \
3025
                              "order by code DESC".format(property, inst_table_uid)
3026
                    elif custom:
3027
                        sql = "select uid, code, description, Allowables from CustomCodes \
3028
                                    where table_uid = (select uid from CustomTables where upper(name) like upper('{}'))".format(property)
3029
                    elif inst:
3030
                        sql = "select uid, code, symbols, attribute, newcode, expression, priority from InstCodes \
3031
                                    where table_uid = (select uid from InstTables where upper(name) like upper('{}'))".format(property)
3032
                    cursor.execute(sql)
3033
                    rows = cursor.fetchall()
3034
                    if not inst:
3035
                        for row in rows:
3036
                            if forCheckLineNumber:
3037
                                data = row['code']
3038
                            else:
3039
                                data = (row['uid'], row['code'], row['description'], row['Allowables'])
3040
                            result.append(data)
3041
                        # else:
3042
                        #    result = None
3043
                    else:
3044
                        for row in rows:
3045
                            data = (row['uid'], row['code'], row['symbols'], row['attribute'], row['newcode'], row['expression'], row['priority'])
3046
                            result.append(data)
3047
            # Catch the exception
3048
            except Exception as ex:
3049
                from App import App
3050
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3051
                                                              sys.exc_info()[-1].tb_lineno)
3052
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3053

    
3054
        return result
3055

    
3056
    def get_components(self, drawing):
3057
        """ get components in given drawing """
3058

    
3059
        with self.project.database.connect() as conn:
3060
            try:
3061
                # Get a cursor object
3062
                cursor = conn.cursor()
3063

    
3064
                sql = "select a.*,b.Name,b.SymbolType_UID,b.[Type],b.OriginalPoint,b.ConnectionPoint,b.BaseSymbol," \
3065
                      "b.AdditionalSymbol,b.HasInstrumentLabel,b.Flip as DetectFlip from Components a " \
3066
                      "join Symbol b on a.Symbol_UID=b.UID where a.Drawings_UID='{}'".format(drawing)
3067
                cursor.execute(sql)
3068
                return cursor.fetchall()
3069
                # Catch the exception
3070
            except Exception as ex:
3071
                from App import App
3072
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3073
                                                              sys.exc_info()[-1].tb_lineno)
3074
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3075

    
3076
    def check_runs(self):
3077
        """ check run item duplication """
3078

    
3079
        with self.project.database.connect() as conn:
3080
            try:
3081
                # Get a cursor object
3082
                cursor = conn.cursor()
3083

    
3084
                sql = "select [Components_UID], count([Components_UID]) as count from [PipeRunItems] " \
3085
                      "group by [Components_UID] having count([Components_UID]) > 1"
3086

    
3087
                cursor.execute(sql)
3088

    
3089
                rows = cursor.fetchall()
3090

    
3091
                items = []
3092
                if rows:
3093
                    for row in rows:
3094
                        sql = "select c.[UID], d.[Name] from [Components] c inner join [Drawings] d on c.Drawings_UID=d.[UID]" \
3095
                              "where c.[UID]='" + row["Components_UID"] + "'"
3096
                        cursor.execute(sql)
3097

    
3098
                        _rows = cursor.fetchall()
3099
                        if _rows:
3100
                            items = items + _rows
3101

    
3102
                return items
3103
                # Catch the exception
3104
            except Exception as ex:
3105
                from App import App
3106
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3107
                                                              sys.exc_info()[-1].tb_lineno)
3108
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3109

    
3110
    def get_opcs(self):
3111
        """ get opc in project """
3112
        configs = self.getConfigs('PSN', 'Symbols')
3113
        target = configs[0].value if configs else 'ALL'
3114

    
3115
        with self.project.database.connect() as conn:
3116
            try:
3117
                # Get a cursor object
3118
                cursor = conn.cursor()
3119

    
3120
                '''
3121
                if target == "ALL" or target == '':
3122
                    sql = "select (select Name from Drawings where UID=a.Drawings_UID) as Drawing," \
3123
                        "(select Value from Components where UID=a.Owner) as [Line No]," \
3124
                        "(select Name from Symbol where a.Symbol_UID=UID) as Symbol," \
3125
                        "(select stuff((select ',' + convert(NVARCHAR(10),[index]) from [Points] where Connected = a.UID for XML PAth('')),1,1,'')) as [Count]," \
3126
                        "UID as OPC from Components a " \
3127
                        "where Symbol_UID in (select UID from Symbol where SymbolType_UID in " \
3128
                        "(select UID from SymbolType where Type='Instrument OPC''s' or Type='Piping OPC''s'))"
3129
                else:
3130
                    sql = "select (select Name from Drawings where UID=a.Drawings_UID) as Drawing," \
3131
                        "(select Value from Components where UID=a.Owner) as [Line No]," \
3132
                        "(select Name from Symbol where a.Symbol_UID=UID) as Symbol," \
3133
                        "(select stuff((select ',' + convert(NVARCHAR(10),[index]) from [Points] where Connected = a.UID for XML PAth('')),1,1,'')) as [Count]," \
3134
                        "UID as OPC from Components a " \
3135
                        "where Symbol_UID in (" + target + ")"
3136
                '''
3137
                if target == "ALL" or target == '':
3138
                    sql = "select (select Name from Drawings where UID=a.Drawings_UID) as Drawing," \
3139
                        "(select Value from Components where UID=a.Owner) as [Line No]," \
3140
                        "(select Name from Symbol where a.Symbol_UID=UID) as Symbol," \
3141
                        "(select Count(1) from [Points] where Connected = a.UID) as [Count]," \
3142
                        "(select [Index] from [PipeRunItems] where Components_UID = a.UID) as [Index]," \
3143
                        "UID as OPC from Components a " \
3144
                        "where Symbol_UID in (select UID from Symbol where SymbolType_UID in " \
3145
                        "(select UID from SymbolType where Type='Instrument OPC''s' or Type='Piping OPC''s'))"
3146
                else:
3147
                    sql = "select (select Name from Drawings where UID=a.Drawings_UID) as Drawing," \
3148
                        "(select Value from Components where UID=a.Owner) as [Line No]," \
3149
                        "(select Name from Symbol where a.Symbol_UID=UID) as Symbol," \
3150
                        "(select Count(1) from [Points] where Connected = a.UID) as [Count]," \
3151
                        "(select [Index] from [PipeRunItems] where Components_UID = a.UID) as [Index]," \
3152
                        "UID as OPC from Components a " \
3153
                        "where Symbol_UID in (" + target + ")"
3154

    
3155
                cursor.execute(sql)
3156

    
3157
                rows = cursor.fetchall()
3158

    
3159
                opcs = []
3160
                if self.project.database.db_type == 'SQLite':
3161
                    for row in rows:
3162
                        #count = str(len(row["Count"].split(',')))
3163
                        opcs.append({ "Drawing":row["Drawing"], "Line No":row["Line No"], "Symbol":row["Symbol"], "Count":row["Count"], "OPC":row["OPC"], "Index": row["Index"]})
3164
                else:
3165
                    opcs = rows
3166

    
3167
                for opc in opcs:
3168
                    opc['Index'] = 0 if opc['Index'] == 1 else 1 # 0 : start with opc, 1 : end with opc
3169

    
3170
                return opcs
3171
                # Catch the exception
3172
            except Exception as ex:
3173
                from App import App
3174
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3175
                                                              sys.exc_info()[-1].tb_lineno)
3176
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3177

    
3178
    def get_opc_relations(self):
3179
        """ get opc relations """
3180
        conn = self.project.database.connect()
3181
        with conn:
3182
            try:
3183
                # Get a cursor object
3184
                cursor = conn.cursor()
3185

    
3186
                sql = "select (select Name from Drawings where UID=a.From_Drawings_UID) as From_Drawing,\
3187
                a.From_LineNo_UID as From_LineNo,\
3188
                a.From_OPC_UID,\
3189
                (select Name from Drawings where UID=a.To_Drawings_UID) as To_Drawing,\
3190
                a.To_LineNo_UID as To_LineNo,\
3191
                a.To_OPC_UID \
3192
                from OPCRelations a"
3193
                cursor.execute(sql)
3194
                return cursor.fetchall()
3195
                # Catch the exception
3196
            except Exception as ex:
3197
                from App import App
3198
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3199
                                                              sys.exc_info()[-1].tb_lineno)
3200
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3201

    
3202
    def save_opc_relations(self, opcs):
3203
        """ save opc relations """
3204
        conn = self.project.database.connect()
3205
        with conn:
3206
            try:
3207
                # Get a cursor object
3208
                cursor = conn.cursor()
3209
                sql = 'delete from OPCRelations'
3210
                cursor.execute(sql)
3211

    
3212
                for opc in opcs:
3213
                    sql = 'insert into OPCRelations(From_Drawings_UID,From_LineNo_UID,From_OPC_UID,To_Drawings_UID,To_LineNo_UID,To_OPC_UID) \
3214
                        values({},{},{},{},{},{})'.format(
3215
                        "(select UID from Drawings where Name='{}')".format(opc[0]),
3216
                        "'{}'".format(opc[1]) if opc[1] else 'null',
3217
                        "'{}'".format(opc[2]) if opc[2] else 'null',
3218
                        "(select UID from Drawings where Name='{}')".format(opc[3]) if opc[3] else 'null',
3219
                        "'{}'".format(opc[4]) if opc[4] else 'null',
3220
                        "'{}'".format(opc[5]) if opc[5] else 'null')
3221
                    cursor.execute(sql)
3222

    
3223
                conn.commit()
3224
            # Catch the exception
3225
            except Exception as ex:
3226
                conn.rollback()
3227

    
3228
                from App import App
3229
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3230
                                                              sys.exc_info()[-1].tb_lineno)
3231
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3232

    
3233
    def get_component_connectors(self, component):
3234
        """ get connectors of given component """
3235
        if self._connecterss and component in self._connecterss:
3236
            return self._connecterss[component]
3237

    
3238
        conn = self.project.database.connect()
3239
        with conn:
3240
            try:
3241
                # Get a cursor object
3242
                cursor = conn.cursor()
3243

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

    
3248
                pre = ''
3249
                rows = cursor.fetchall()
3250
                for row in rows:
3251
                    if pre != row['Components_UID']:
3252
                        if pre != '':
3253
                            self._connecterss[pre] = compo
3254
                        pre = row['Components_UID']
3255
                        compo = []
3256
                        compo.append(row)
3257
                        if row is rows[-1]:
3258
                            self._connecterss[row['Components_UID']] = compo
3259
                    else:
3260
                        compo.append(row)
3261
                        if row is rows[-1]:
3262
                            self._connecterss[row['Components_UID']] = compo
3263

    
3264
                return self._connecterss[component] if component in self._connecterss else []
3265
                # Catch the exception
3266
            except Exception as ex:
3267
                from App import App
3268
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3269
                                                              sys.exc_info()[-1].tb_lineno)
3270
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3271

    
3272
    def get_component_associations(self, component):
3273
        """ get associations of given component """
3274
        if self._associationss and component in self._associationss:
3275
            return self._associationss[component]
3276
        elif self._associationss:
3277
            return []
3278

    
3279
        conn = self.project.database.connect()
3280
        with conn:
3281
            try:
3282
                # Get a cursor object
3283
                cursor = conn.cursor()
3284

    
3285
                # sql = "select * from Associations where Components_UID='{}'".format(component)
3286
                sql = "select a.* from Associations a \
3287
                            join Components b on a.Components_UID=b.[UID] where Drawings_UID='{}' order by Components_UID".format(
3288
                    self.activeDrawing.UID)
3289
                cursor.execute(sql)
3290

    
3291
                pre = ''
3292
                rows = cursor.fetchall()
3293
                for row in rows:
3294
                    if pre != row['Components_UID']:
3295
                        if pre != '':
3296
                            self._associationss[pre] = compo
3297
                        pre = row['Components_UID']
3298
                        compo = []
3299
                        compo.append(row)
3300
                        if row is rows[-1]:
3301
                            self._associationss[row['Components_UID']] = compo
3302
                    else:
3303
                        compo.append(row)
3304
                        if row is rows[-1]:
3305
                            self._associationss[row['Components_UID']] = compo
3306

    
3307
                return self._associationss[component] if component in self._associationss else []
3308
                # Catch the exception
3309
            except Exception as ex:
3310
                from App import App
3311
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3312
                                                              sys.exc_info()[-1].tb_lineno)
3313
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3314

    
3315
    def get_component_attributes(self, component):
3316
        """ get attributes of given component """
3317
        if self._attributess and component in self._attributess:
3318
            return self._attributess[component]
3319
        elif self._attributess:
3320
            return []
3321

    
3322
        conn = self.project.database.connect()
3323
        with conn:
3324
            try:
3325
                # Get a cursor object
3326
                cursor = conn.cursor()
3327

    
3328
                sql = "select a.*, b.* from Attributes a \
3329
                            join SymbolAttribute b on a.SymbolAttribute_UID=b.UID \
3330
                            join Components c on a.Components_UID=c.UID \
3331
                        where Drawings_UID='{}' order by a.Components_UID, b.[index]".format(self.activeDrawing.UID)
3332
                cursor.execute(sql)
3333

    
3334
                pre = ''
3335
                rows = cursor.fetchall()
3336
                for row in rows:
3337
                    if pre != row['Components_UID']:
3338
                        if pre != '':
3339
                            self._attributess[pre] = compo
3340
                        pre = row['Components_UID']
3341
                        compo = []
3342
                        compo.append(row)
3343
                        if row is rows[-1]:
3344
                            self._attributess[row['Components_UID']] = compo
3345
                    else:
3346
                        compo.append(row)
3347
                        if row is rows[-1]:
3348
                            self._attributess[row['Components_UID']] = compo
3349

    
3350
                return self._attributess[component] if component in self._attributess else []
3351
                # Catch the exception
3352
            except Exception as ex:
3353
                from App import App
3354
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3355
                                                              sys.exc_info()[-1].tb_lineno)
3356
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3357

    
3358
    def get_pipe_runs(self, component):
3359
        """ get line runs of given component """
3360
        conn = self.project.database.connect()
3361
        with conn:
3362
            try:
3363
                # Get a cursor object
3364
                cursor = conn.cursor()
3365

    
3366
                sql = "select * from PipeRuns where Owner='{}' order by [Index]".format(component)
3367
                cursor.execute(sql)
3368
                return cursor.fetchall()
3369
                # Catch the exception
3370
            except Exception as ex:
3371
                from App import App
3372
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3373
                                                              sys.exc_info()[-1].tb_lineno)
3374
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3375

    
3376
    def get_pipe_run_items(self, pipe_run):
3377
        """ get line run items of given pipe run """
3378
        conn = self.project.database.connect()
3379
        with conn:
3380
            try:
3381
                # Get a cursor object
3382
                cursor = conn.cursor()
3383

    
3384
                sql = "select * from PipeRunItems where PipeRuns_UID='{}' order by [Index]".format(pipe_run)
3385
                cursor.execute(sql)
3386
                return cursor.fetchall()
3387
                # Catch the exception
3388
            except Exception as ex:
3389
                from App import App
3390
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3391
                                                              sys.exc_info()[-1].tb_lineno)
3392
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3393

    
3394
    '''
3395
        @brief      get special item types from database
3396
        @author     humkyung
3397
        @date       2019.08.10
3398
    '''
3399
    def get_special_item_types(self):
3400
        conn = self.project.database.connect()
3401
        with conn:
3402
            try:
3403
                # Get a cursor object
3404
                cursor = conn.cursor()
3405

    
3406
                sql = 'select UID, Code, Type, Allowables from SpecialItemTypes order by Code DESC'
3407
                cursor.execute(sql)
3408
                return cursor.fetchall()
3409
                # Catch the exception
3410
            except Exception as ex:
3411
                from App import App
3412
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3413
                                                              sys.exc_info()[-1].tb_lineno)
3414
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3415

    
3416
    '''
3417
        @brief      save special item types
3418
        @author     humkyung
3419
        @date       2019.08.10
3420
    '''
3421
    def save_special_item_types(self, datas):
3422
        import uuid
3423

    
3424
        conn = self.project.database.connect()
3425
        with conn:
3426
            try:
3427
                # Get a cursor object
3428
                cursor = conn.cursor()
3429

    
3430
                for data in datas:
3431
                    uid, code, _type, allowables = data[0], data[1], data[2], data[3]
3432
                    if not uid:
3433
                        sql = self.project.database.to_sql(
3434
                            'insert into SpecialItemTypes(UID, Code, Type, Allowables) values(?, ?, ?, ?)')
3435
                        param = (str(uuid.uuid4()), data[1], data[2], data[3])
3436
                    elif uid == '-1':
3437
                        sql = self.project.database.to_sql('delete from SpecialItemTypes where uid=?')
3438
                        param = (data[-1],)
3439
                    else:
3440
                        sql = self.project.database.to_sql(
3441
                            'update SpecialItemTypes SET Code=?, Type=?, Allowables=? WHERE UID = ?')
3442
                        param = (data[1], data[2], data[3], data[0])
3443
                    cursor.execute(sql, param)
3444

    
3445
                conn.commit()
3446
            # Catch the exception
3447
            except Exception as ex:
3448
                # Roll back any change if something goes wrong
3449
                conn.rollback()
3450

    
3451
                from App import App
3452
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3453
                                                              sys.exc_info()[-1].tb_lineno)
3454
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3455

    
3456
    def get_special_items(self, drawings=None):
3457
        """ get special items from database """
3458
        result = []
3459

    
3460
        conn = self.project.database.connect()
3461
        with conn:
3462
            try:
3463
                # get a cursor object
3464
                cursor = conn.cursor()
3465

    
3466
                sql = 'select distinct (select Value from Components where UID=D.Owner) as "Line No",C.Code from Components A \
3467
                    left join Drawings B on A.Drawings_UID=B.UID \
3468
                    left join SpecialItemTypes C on A.SpecialItemTypes_UID=C.UID \
3469
                    left join Components D on A.Connected=D.UID \
3470
                    where A.SpecialItemTypes_UID is not null'
3471
                if drawings is not None:
3472
                    doc_names = "','".join(drawings)
3473
                    sql += f" and A.Drawings_UID in (select UID from Drawings where Name in ('{doc_names}'))"
3474
                sql += ' order by "Line No"'
3475
                cursor.execute(sql)
3476

    
3477
                return cursor.fetchall()
3478
            # catch the exception
3479
            except Exception as ex:
3480
                from App import App
3481
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3482
                                                              sys.exc_info()[-1].tb_lineno)
3483
                App.mainWnd().addMessage.emit(MessageType.Error, message)
3484

    
3485
        return None
3486

    
3487
    '''
3488
        @brief      Set Common Code Data
3489
        @author     kyouho
3490
        @date       2018.07.12
3491
    '''
3492
    def saveCommonCodeData(self, tableName, datas):
3493
        import uuid
3494

    
3495
        conn = self.project.database.connect()
3496
        with conn:
3497
            try:
3498
                # Get a cursor object
3499
                cursor = conn.cursor()
3500

    
3501
                sql = self.project.database.to_sql('delete from {}'.format(tableName))
3502
                cursor.execute(sql)
3503

    
3504
                for data in datas:
3505
                    '''
3506
                    uid, code, description, allowables = data[0], data[1], data[2], data[3]
3507
                    if not uid:
3508
                        sql = self.project.database.to_sql(
3509
                            "insert into {}(UID, CODE, DESCRIPTION, ALLOWABLES) values(?, ?, ?, ?)".format(tableName))
3510
                        param = (str(uuid.uuid4()), data[1], data[2], data[3])
3511
                    elif uid == '-1':
3512
                        sql = self.project.database.to_sql('delete from {} where uid=?'.format(tableName))
3513
                        param = (data[-1],)
3514
                    else:
3515
                        sql = self.project.database.to_sql(
3516
                            "update {} SET CODE=?, DESCRIPTION=?, ALLOWABLES=? WHERE UID = ?".format(tableName))
3517
                        param = (data[1], data[2], data[3], data[0])
3518
                    cursor.execute(sql, param)
3519
                    '''
3520
                    if data[0]:
3521
                        uid = data[0]
3522
                    else:
3523
                        uid = str(uuid.uuid4())
3524
                    sql = self.project.database.to_sql(
3525
                        "insert into {}(UID, CODE, DESCRIPTION, ALLOWABLES) values(?, ?, ?, ?)".format(tableName))
3526
                    param = (uid, data[1], data[2], data[3])
3527
                    cursor.execute(sql, param)
3528

    
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
    def selectView(self):
3541
        """ get document name list """
3542
        result = []
3543

    
3544
        with self.project.database.connect() as conn:
3545
            try:
3546
                # Get a cursor object
3547
                cursor = conn.cursor()
3548

    
3549
                sql = "select * from T_PSN_VIEW"
3550
                cursor.execute(sql)
3551

    
3552
                rows = cursor.fetchall()
3553
                for row in rows:
3554
                    result.append(row['OID'])
3555

    
3556
                result.sort()
3557
            # Catch the exception
3558
            except Exception as ex:
3559
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3560
                                                          sys.exc_info()[-1].tb_lineno))
3561

    
3562
        return result
3563

    
3564
    '''
3565
        @brief      Set Common Code Data
3566
        @author     kyouho
3567
        @date       2018.07.12
3568
    '''
3569
    def deleteCommonCodeData(self, datas):
3570
        try:
3571
            conn = self.project.database.connect()
3572
            with conn:
3573
                # Get a cursor object
3574
                cursor = conn.cursor()
3575

    
3576
                for data in datas:
3577
                    uid = data[0]
3578
                    tableName = data[1]
3579

    
3580
                    if uid:
3581
                        sql = "delete from {} where UID = ?".format(tableName)
3582
                        param = (uid,)
3583
                        cursor.execute(sql, param)
3584

    
3585
                    cursor.execute(sql, param)
3586

    
3587
                conn.commit()
3588

    
3589
        # Catch the exception
3590
        except Exception as ex:
3591
            # Roll back any change if something goes wrong
3592
            conn.rollback()
3593
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3594
                                                      sys.exc_info()[-1].tb_lineno))
3595

    
3596
    '''
3597
        @brief      delete data list
3598
        @author     kyouho
3599
        @date       2018.08.16
3600
    '''
3601
    def deleteDataList(self, tableName, UID):
3602
        conn = self.project.database.connect()
3603
        with conn:
3604
            try:
3605
                # Get a cursor object
3606
                cursor = conn.cursor()
3607
                sql = 'delete from {} where UID = {}'.format(tableName, UID)
3608
                cursor.execute(sql)
3609
                conn.commit()
3610

    
3611
            # Catch the exception
3612
            except Exception as ex:
3613
                # Roll back any change if something goes wrong
3614
                conn.rollback()
3615
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3616
                                                          sys.exc_info()[-1].tb_lineno))
3617

    
3618
    def get_document_name_list(self):
3619
        """ get document name list """
3620
        result = []
3621

    
3622
        with self.project.database.connect() as conn:
3623
            try:
3624
                # Get a cursor object
3625
                cursor = conn.cursor()
3626

    
3627
                sql = "select distinct B.Name as 'Drawing_Name' from Components A join Drawings B on " \
3628
                      "A.Drawings_UID=B.UID"
3629
                cursor.execute(sql)
3630

    
3631
                rows = cursor.fetchall()
3632
                for row in rows:
3633
                    result.append(row['Drawing_Name'])
3634

    
3635
                result.sort()
3636
            # Catch the exception
3637
            except Exception as ex:
3638
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3639
                                                          sys.exc_info()[-1].tb_lineno))
3640

    
3641
        return result
3642

    
3643
    '''
3644
        @brief      get line documentName list
3645
        @author     kyouho
3646
        @date       2018.08.13
3647
    '''
3648
    def getLineDocumentNameList(self):
3649
        result = []
3650

    
3651
        conn = self.project.database.connect()
3652
        with conn:
3653
            try:
3654
                # Get a cursor object
3655
                cursor = conn.cursor()
3656

    
3657
                sql = 'select DISTINCT(PNID_NO) from LINE_DATA_LIST'
3658

    
3659
                cursor.execute(sql)
3660
                rows = cursor.fetchall()
3661
                for row in rows:
3662
                    result.append(row[0])
3663
            # Catch the exception
3664
            except Exception as ex:
3665
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3666
                                                          sys.exc_info()[-1].tb_lineno))
3667

    
3668
        return result
3669

    
3670
    '''
3671
        @brief      get line data list
3672
        @author     kyouho
3673
        @date       2018.08.13
3674
    '''
3675
    def get_line_data_list(self, drawings=None):
3676
        result = []
3677

    
3678
        with self.project.database.connect() as conn:
3679
            try:
3680
                # Get a cursor object
3681
                cursor = conn.cursor()
3682

    
3683
                '''
3684
                sql = 'select A.UID,B.Name,A.Value as [Line No] from Components A left join Drawings B on A.Drawings_UID=B.UID'
3685
                if drawings is not None:
3686
                    doc_names = "','".join(drawings)
3687
                    sql += f" where A.Symbol_UID=1 and Drawings_UID in (select UID from Drawings where Name in ('{doc_names}'))"
3688
                cursor.execute(sql)
3689
                comps = [(row['UID'], row['Name'], row['Line No']) for row in cursor.fetchall()]
3690
                for comp in comps:
3691
                    sql = f"select b.Name,a.Value from LineNoAttributes a left join LineProperties b " \
3692
                          f"on a.LineProperties_UID=b.UID where a.Components_UID='{comp[0]}'"
3693
                    cursor.execute(sql)
3694
                    attrs = cursor.fetchall()
3695
                    data = []
3696
                    for attr in attrs:
3697
                        data.append([attr['Name'], attr['Value']])
3698
                    if data:
3699
                        data.insert(0, ['Drawing Name', comp[1]])
3700
                        data.insert(0, ['UID', comp[0]])
3701
                        data.insert(0, ['Line No', comp[2]])
3702
                        result.append(data)
3703
                '''
3704

    
3705
                sql = 'select A.UID,B.Name,A.Value as [Line No],D.[Name] as AttrN,C.[Value] as [AttrV] from Components A left join Drawings B on A.Drawings_UID=B.UID \
3706
                        left join LineNoAttributes C on A.[UID]=C.Components_UID left join LineProperties D on C.LineProperties_UID=D.UID'
3707
                if drawings is not None:
3708
                    doc_names = "','".join(drawings)
3709
                    sql += f" where A.Symbol_UID=1 and Drawings_UID in (select UID from Drawings where Name in ('{doc_names}'))"
3710
                cursor.execute(sql)
3711

    
3712
                comps = [[row['UID'], row['Name'], row['Line No'], row['AttrN'], row['AttrV']] for row in cursor.fetchall()]
3713
                lineNos = {}
3714

    
3715
                for comp in comps:
3716
                    if comp[0] not in lineNos:
3717
                        lineNos[comp[0]] = [['Line No', comp[2]], ['UID', comp[0]], ['Drawing Name', comp[1]]]
3718
                    lineNos[comp[0]].append([comp[3], comp[4]])
3719

    
3720
                result = list(lineNos.values())
3721

    
3722
            # catch the exception
3723
            except Exception as ex:
3724
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3725
                                                          sys.exc_info()[-1].tb_lineno))
3726

    
3727
        return result
3728

    
3729
    def get_equipment_data_list(self, drawings=None):
3730
        """ get equipment data list """
3731

    
3732
        result = []
3733

    
3734
        with self.project.database.connect() as conn:
3735
            try:
3736
                # Get a cursor object
3737
                cursor = conn.cursor()
3738

    
3739
                sql = "select A.UID,B.NAME,C.SymbolType_UID,D.Type,C.NAME as symbol from Components A join Drawings B on A.Drawings_UID=B.UID\
3740
                        join Symbol C on A.Symbol_UID=C.UID\
3741
                        join SymbolType D on C.SymbolType_UID=D.UID\
3742
                        where D.Category in ('Equipment')"#,'Equipment Components')"
3743

    
3744
                if drawings is not None:
3745
                    doc_names = "','".join(drawings)
3746
                    sql += f" and A.Drawings_UID in (select UID from Drawings where Name in ('{doc_names}'))"
3747

    
3748
                cursor.execute(sql)
3749
                comps = [(row['UID'], row['NAME'], row['SymbolType_UID'], row['Type'], row['symbol']) for row in cursor.fetchall()]
3750
                for comp in comps:
3751
                    sql = f"select distinct B.Attribute,A.Value from Attributes A left join SymbolAttribute B on " \
3752
                          f"A.SymbolAttribute_UID=B.UID where A.Components_UID='{comp[0]}'"
3753
                    cursor.execute(sql)
3754
                    attrs = cursor.fetchall()
3755
                    data = []
3756
                    for attr in attrs:
3757
                        data.append([attr['Attribute'], attr['Value']])
3758
                    if data:
3759
                        data.insert(0, ['Type', comp[3]])
3760
                        data.insert(0, ['Drawing Name', comp[1]])
3761
                        data.insert(0, ['ITEM_NO', comp[4]])
3762
                        data.insert(0, ['UID', comp[0]])
3763
                        result.append(data)
3764

    
3765
            # catch the exception
3766
            except Exception as ex:
3767
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3768
                                                           sys.exc_info()[-1].tb_lineno))
3769

    
3770
        return result
3771

    
3772
    '''
3773
        @brief      set line data list
3774
        @author     kyouho
3775
        @date       2018.08.13
3776
    '''
3777
    def setLineDataList(self, dataLists):
3778
        conn = self.project.database.connect()
3779
        with conn:
3780
            try:
3781
                # Get a cursor object
3782
                cursor = conn.cursor()
3783

    
3784
                for data in dataLists:
3785
                    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(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
3786
                    param = tuple(data)
3787
                    cursor.execute(sql, param)
3788

    
3789
                conn.commit()
3790

    
3791
            # Catch the exception
3792
            except Exception as ex:
3793
                # Roll back any change if something goes wrong
3794
                conn.rollback()
3795
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3796
                                                          sys.exc_info()[-1].tb_lineno))
3797

    
3798
    '''
3799
        @brief      delete line data list
3800
        @author     kyouho
3801
        @date       2018.08.13
3802
    '''
3803
    def deleteLineDataList(self, removeUID):
3804
        conn = self.project.database.connect()
3805
        with conn:
3806
            try:
3807
                # Get a cursor object
3808
                cursor = conn.cursor()
3809

    
3810
                for uid in removeUID:
3811
                    sql = "delete from LINE_DATA_LIST where uid = '{}'".format(uid)
3812
                    cursor.execute(sql)
3813

    
3814
                conn.commit()
3815

    
3816
            # Catch the exception
3817
            except Exception as ex:
3818
                # Roll back any change if something goes wrong
3819
                conn.rollback()
3820
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3821
                                                          sys.exc_info()[-1].tb_lineno))
3822

    
3823
    '''
3824
        @brief      delete line data list
3825
        @author     kyouho
3826
        @date       2018.08.13
3827
    '''
3828
    def deleteLineDataList_LineNo(self, removeUID):
3829
        conn = self.project.database.connect()
3830
        with conn:
3831
            try:
3832
                # Get a cursor object
3833
                cursor = conn.cursor()
3834

    
3835
                for uid in removeUID:
3836
                    sql = "delete from LINE_DATA_LIST where LINE_NO = ?"
3837
                    param = (uid,)
3838
                    cursor.execute(sql, param)
3839

    
3840
                conn.commit()
3841

    
3842
            # Catch the exception
3843
            except Exception as ex:
3844
                # Roll back any change if something goes wrong
3845
                conn.rollback()
3846
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3847
                                                          sys.exc_info()[-1].tb_lineno))
3848

    
3849
    '''
3850
        @brief      delete equip data list
3851
        @author     kyouho
3852
        @date       2018.08.14
3853
    '''
3854
    def deleteEquipDataList(self, removeUID):
3855
        conn = self.project.database.connect()
3856
        with conn:
3857
            try:
3858
                # Get a cursor object
3859
                cursor = conn.cursor()
3860

    
3861
                for uid in removeUID:
3862
                    sql = "delete from EQUIPMENT_DATA_LIST where uid = '{}'".format(uid)
3863
                    cursor.execute(sql)
3864

    
3865
                conn.commit()
3866

    
3867
            # Catch the exception
3868
            except Exception as ex:
3869
                # Roll back any change if something goes wrong
3870
                conn.rollback()
3871
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3872
                                                          sys.exc_info()[-1].tb_lineno))
3873

    
3874
    '''
3875
        @brief      delete inst data list
3876
        @author     kyouho
3877
        @date       2018.08.14
3878
    '''
3879
    def deleteInstDataList(self, removeUID):
3880
        conn = self.project.database.connect()
3881
        with conn:
3882
            try:
3883
                # Get a cursor object
3884
                cursor = conn.cursor()
3885

    
3886
                for uid in removeUID:
3887
                    sql = "delete from INSTRUMENT_DATA_LIST where uid = '{}'".format(uid)
3888
                    cursor.execute(sql)
3889

    
3890
                conn.commit()
3891

    
3892
            # Catch the exception
3893
            except Exception as ex:
3894
                # Roll back any change if something goes wrong
3895
                conn.rollback()
3896
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3897
                                                          sys.exc_info()[-1].tb_lineno))
3898

    
3899
    '''
3900
        @brief      delete note data list
3901
        @author     kyouho
3902
        @date       2018.10.10
3903
    '''
3904
    def deleteNoteDataList(self, removeUID):
3905
        conn = self.project.database.connect()
3906
        with conn:
3907
            try:
3908
                # Get a cursor object
3909
                cursor = conn.cursor()
3910

    
3911
                for uid in removeUID:
3912
                    sql = "delete from NOTE_DATA_LIST where uid = '{}'".format(uid)
3913
                    cursor.execute(sql)
3914

    
3915
                conn.commit()
3916

    
3917
            # Catch the exception
3918
            except Exception as ex:
3919
                # Roll back any change if something goes wrong
3920
                conn.rollback()
3921
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3922
                                                          sys.exc_info()[-1].tb_lineno))
3923

    
3924
    def get_valve_attributes(self):
3925
        """ return valve attributes """
3926

    
3927
        from SymbolAttr import SymbolAttr
3928

    
3929
        res = None
3930
        if not hasattr(self, '_valve_attributes'):
3931
            self._valve_attributes = []
3932

    
3933
            with self.project.database.connect() as conn:
3934
                try:
3935
                    # Get a cursor object
3936
                    cursor = conn.cursor()
3937

    
3938
                    sql = "select distinct A.Attribute from SymbolAttribute A join SymbolType B on " \
3939
                          "A.SymbolType_UID=B.UID where B.Category = 'Piping'"
3940
                    cursor.execute(sql)
3941
                    rows = cursor.fetchall()
3942
                    for row in rows:
3943
                        attr = SymbolAttr()
3944
                        attr.Attribute = row['Attribute']
3945
                        self._valve_attributes.append(attr)
3946

    
3947
                    res = self._valve_attributes
3948
                # Catch the exception
3949
                except Exception as ex:
3950
                    print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
3951
                                                               sys.exc_info()[-1].tb_lineno))
3952
        else:
3953
            res = self._valve_attributes
3954

    
3955
        return res
3956

    
3957
    def get_valve_data_list(self, drawings=None):
3958
        """get valve data list"""
3959

    
3960
        result = []
3961
        conn = self.project.database.connect()
3962
        with conn:
3963
            try:
3964
                # Get a cursor object
3965
                cursor = conn.cursor()
3966

    
3967
                sql = "select a.UID,D.Name,E.Name as 'Drawing Name',C.Attribute,B.Value,a.[Owner] from Components a " \
3968
                      "join Attributes B on a.UID=B.Components_UID " \
3969
                      "join SymbolAttribute C on B.SymbolAttribute_UID=C.UID " \
3970
                      "join Symbol D on a.Symbol_UID=D.UID " \
3971
                      "join Drawings E on a.Drawings_UID=E.UID " \
3972
                      "where a.Symbol_UID in (select UID from Symbol where SymbolType_UID in " \
3973
                      "(select UID from SymbolType where Category in ('Piping')))"
3974
                if drawings is not None:
3975
                    doc_names = "','".join(drawings)
3976
                    sql += f" and A.Drawings_UID in (select UID from Drawings where Name in ('{doc_names}'))"
3977

    
3978
                cursor.execute(sql)
3979
                rows = cursor.fetchall()
3980
                '''
3981
                for row in rows:
3982
                    matches = [res for res in result if res['UID'] == row['UID']]
3983
                    if matches:
3984
                        matches[0][row['Attribute']] = row['Value']
3985
                    else:
3986
                        data = {'UID': row['UID'], 'ITEM_NO': row['Name'], 'Drawing Name': row['Drawing Name'],
3987
                                'Owner': row['Owner'], row['Attribute']: row['Value']}
3988
                        result.append(data)
3989

3990
                '''
3991
                valves = {}
3992

    
3993
                for row in rows:
3994
                    if row['UID'] not in valves:
3995
                        valves[row['UID']] = {'UID': row['UID'], 'ITEM_NO': row['Name'], 'Drawing Name': row['Drawing Name'],
3996
                                'Owner': row['Owner']}
3997
                    valves[row['UID']][row['Attribute']] = row['Value']
3998

    
3999
                result = list(valves.values())
4000

    
4001
            # Catch the exception
4002
            except Exception as ex:
4003
                from App import App
4004
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
4005
                                                              sys.exc_info()[-1].tb_lineno)
4006
                App.mainWnd().addMessage.emit(MessageType.Error, message)
4007

    
4008
        return result
4009

    
4010
    def get_instrument_attributes(self):
4011
        """ return valve attributes """
4012

    
4013
        from SymbolAttr import SymbolAttr
4014

    
4015
        res = None
4016
        if not hasattr(self, '_inst_attributes'):
4017
            self._inst_attributes = []
4018

    
4019
            with self.project.database.connect() as conn:
4020
                try:
4021
                    # Get a cursor object
4022
                    cursor = conn.cursor()
4023

    
4024
                    sql = "select distinct A.Attribute from SymbolAttribute A join SymbolType B on " \
4025
                          "A.SymbolType_UID=B.UID where B.Category = 'Instrumentation'"
4026
                    cursor.execute(sql)
4027
                    rows = cursor.fetchall()
4028
                    for row in rows:
4029
                        attr = SymbolAttr()
4030
                        attr.Attribute = row['Attribute']
4031
                        self._inst_attributes.append(attr)
4032

    
4033
                    res = self._inst_attributes
4034
                # Catch the exception
4035
                except Exception as ex:
4036
                    print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
4037
                                                               sys.exc_info()[-1].tb_lineno))
4038
        else:
4039
            res = self._inst_attributes
4040

    
4041
        return res
4042

    
4043
    '''
4044
        @brief      get instrument data list
4045
        @author     kyouho
4046
        @date       2018.08.14
4047
    '''
4048
    def get_instrument_data_list(self, drawings=None):
4049
        result = []
4050
        conn = self.project.database.connect()
4051
        with conn:
4052
            try:
4053
                # Get a cursor object
4054
                cursor = conn.cursor()
4055

    
4056
                sql = "select a.UID,D.Name,E.Name as 'Drawing Name',C.Attribute,B.Value,a.Symbol_UID,a.[Owner] from Components a " \
4057
                      "join Attributes B on a.UID=B.Components_UID " \
4058
                      "join SymbolAttribute C on B.SymbolAttribute_UID=C.UID " \
4059
                      "join Symbol D on a.Symbol_UID=D.UID " \
4060
                      "join Drawings E on a.Drawings_UID=E.UID " \
4061
                      "where a.Symbol_UID in (select UID from Symbol where SymbolType_UID in " \
4062
                      "(select UID from SymbolType where Category in ('Instrumentation')))"
4063
                if drawings is not None:
4064
                    doc_names = "','".join(drawings)
4065
                    sql += f" and A.Drawings_UID in (select UID from Drawings where Name in ('{doc_names}'))"
4066

    
4067
                cursor.execute(sql)
4068
                rows = cursor.fetchall()
4069
                '''
4070
                for row in rows:
4071
                    matches = [res for res in result if res['UID'] == row['UID']]
4072
                    if matches:
4073
                        matches[0][row['Attribute']] = row['Value']
4074
                    else:
4075
                        data = {'UID': row['UID'], 'ITEM_NO': row['Name'], 'Drawing Name': row['Drawing Name'], 'Owner': row['Owner'], 
4076
                                'Symbol_UID': int(row['Symbol_UID']), row['Attribute']: row['Value']}
4077
                        result.append(data)
4078
                '''
4079
                insts = {}
4080

    
4081
                for row in rows:
4082
                    if row['UID'] not in insts:
4083
                        insts[row['UID']] = {'UID': row['UID'], 'ITEM_NO': row['Name'], 'Drawing Name': row['Drawing Name'], 'Owner': row['Owner'], 
4084
                                'Symbol_UID': int(row['Symbol_UID'])}
4085
                    insts[row['UID']][row['Attribute']] = row['Value']
4086

    
4087
                result = list(insts.values())
4088
            # Catch the exception
4089
            except Exception as ex:
4090
                from App import App
4091
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
4092
                                                              sys.exc_info()[-1].tb_lineno)
4093
                App.mainWnd().addMessage.emit(MessageType.Error, message)
4094

    
4095
        return result
4096

    
4097
    def get_note_attributes(self):
4098
        """ return note attributes """
4099

    
4100
        from SymbolAttr import SymbolAttr
4101

    
4102
        res = None
4103
        if not hasattr(self, '_note_attributes'):
4104
            self._note_attributes = []
4105

    
4106
            with self.project.database.connect() as conn:
4107
                try:
4108
                    # Get a cursor object
4109
                    cursor = conn.cursor()
4110

    
4111
                    sql = "select distinct A.Attribute from SymbolAttribute A join SymbolType B on " \
4112
                          "A.SymbolType_UID=B.UID where B.Category='General' and B.Type='Notes'"
4113
                    cursor.execute(sql)
4114
                    rows = cursor.fetchall()
4115
                    for row in rows:
4116
                        attr = SymbolAttr()
4117
                        attr.Attribute = row['Attribute']
4118
                        self._note_attributes.append(attr)
4119

    
4120
                    res = self._note_attributes
4121
                # Catch the exception
4122
                except Exception as ex:
4123
                    print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
4124
                                                               sys.exc_info()[-1].tb_lineno))
4125
        else:
4126
            res = self._note_attributes
4127

    
4128
        return res
4129

    
4130
    def get_note_data_list(self, drawings=None):
4131
        """ get note data list """
4132
        result = []
4133

    
4134
        conn = self.project.database.connect()
4135
        with conn:
4136
            try:
4137
                # Get a cursor object
4138
                cursor = conn.cursor()
4139

    
4140
                sql = "select a.UID,D.Name,E.Name as 'Drawing Name',C.Attribute,B.Value from Components a " \
4141
                      "join Attributes B on a.UID=B.Components_UID " \
4142
                      "join SymbolAttribute C on B.SymbolAttribute_UID=C.UID " \
4143
                      "join Symbol D on a.Symbol_UID=D.UID " \
4144
                      "join Drawings E on a.Drawings_UID=E.UID " \
4145
                      "where a.Symbol_UID in (select UID from Symbol where SymbolType_UID in " \
4146
                      "(select UID from SymbolType where Category='General' and Type='Notes'))"
4147
                if drawings is not None:
4148
                    doc_names = "','".join(drawings)
4149
                    sql += f" and A.Drawings_UID in (select UID from Drawings where Name in ('{doc_names}'))"
4150

    
4151
                cursor.execute(sql)
4152
                rows = cursor.fetchall()
4153
                for row in rows:
4154
                    matches = [res for res in result if res['UID'] == row['UID']]
4155
                    if matches:
4156
                        matches[0][row['Attribute']] = row['Value']
4157
                    else:
4158
                        data = {'UID': row['UID'], 'ITEM_NO': row['Name'], 'Drawing Name': row['Drawing Name'],
4159
                                row['Attribute']: row['Value']}
4160
                        result.append(data)
4161
            # Catch the exception
4162
            except Exception as ex:
4163
                from App import App
4164
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
4165
                                                              sys.exc_info()[-1].tb_lineno)
4166
                App.mainWnd().addMessage.emit(MessageType.Error, message)
4167

    
4168
        return result
4169

    
4170
    def saveToDatabase(self, items, rect: QRectF, show_progress=None):
4171
        """ save given items to database """
4172
        import uuid
4173

    
4174
        # delete all datas of current drawing
4175
        drawing_name = self.activeDrawing.name
4176
        drawing_uid = self.activeDrawing.UID
4177

    
4178
        queries = {'first': [], 'second': []}
4179
        for item in items:
4180
            if hasattr(item, 'toSql_return_separately'):
4181
                sql, sqlLater = item.toSql_return_separately()
4182
                queries['first'].append(sql)
4183
                queries['second'].append(sqlLater)
4184
            else:
4185
                queries['first'].append(item.toSql())
4186

    
4187
        with self.project.database.connect() as conn:
4188
            try:
4189
                # Get a cursor object
4190
                cursor = conn.cursor()
4191
                if self.project.database.db_type == 'SQLite':
4192
                    cursor.execute('begin')
4193

    
4194
                sql = "delete from LINE_DATA_LIST where PNID_NO = '{}'".format(drawing_name)
4195
                cursor.execute(sql)
4196
                sql = "delete from TitleBlockValues where Drawings_UID = '{}'".format(drawing_uid)
4197
                cursor.execute(sql)
4198

    
4199
                # delete LineNoAttributes
4200
                sql = f"delete from LineNoAttributes where Components_UID in " \
4201
                      f"(select UID from Components where Drawings_UID='{drawing_uid}')"
4202
                cursor.execute(sql)
4203

    
4204
                # delete Attributes
4205
                sql = f"delete from Attributes where Components_UID in " \
4206
                      f"(select UID from Components where Drawings_UID='{drawing_uid}')"
4207
                cursor.execute(sql)
4208

    
4209
                # delete Associations
4210
                sql = f"delete from Associations where Components_UID in " \
4211
                      f"(select UID from Components where Drawings_UID='{drawing_uid}')"
4212
                cursor.execute(sql)
4213

    
4214
                # delete Points
4215
                sql = f"delete from Points where Components_UID in " \
4216
                      f"(select UID from Components where Drawings_UID='{drawing_uid}')"
4217
                cursor.execute(sql)
4218

    
4219
                # delete PipeRunItems
4220
                sql = f"delete from PipeRunItems where PipeRuns_UID in " \
4221
                      f"(select UID from PipeRuns where Drawings_UID='{drawing_uid}')"
4222
                cursor.execute(sql)
4223

    
4224
                # delete PipeRuns
4225
                sql = f"delete from PipeRuns where Drawings_UID='{drawing_uid}'"
4226
                cursor.execute(sql)
4227

    
4228
                # delete Components 
4229
                sql = "delete from Components where Drawings_UID='{}'".format(drawing_uid)
4230
                cursor.execute(sql)
4231

    
4232
                # delete Stream Line List
4233
                sql = "delete from Stream_Line_List where Drawing_UID='{}'".format(drawing_uid)
4234
                cursor.execute(sql)
4235

    
4236
                progress = 0
4237
                length = len(queries['first']) + len(queries['second'])
4238
                for sql in queries['first']:
4239
                    if type(sql) is list:
4240
                        for item in sql:
4241
                            if item is not None and 2 == len(item):
4242
                                cursor.executemany(self.project.database.to_sql(item[0]), item[1])
4243
                    else:
4244
                        if sql is not None and 2 == len(sql):
4245
                            cursor.executemany(self.project.database.to_sql(sql[0]), sql[1])
4246

    
4247
                    if show_progress:
4248
                        show_progress.emit(int((progress / length)*100))
4249
                    progress += 1
4250

    
4251
                for sql in queries['second']:
4252
                    if type(sql) is list:
4253
                        for item in sql:
4254
                            if item is not None and 2 == len(item):
4255
                                cursor.executemany(self.project.database.to_sql(item[0]), item[1])
4256
                    else:
4257
                        if sql is not None and 2 == len(sql):
4258
                            cursor.executemany(self.project.database.to_sql(sql[0]), sql[1])
4259

    
4260
                    if show_progress:
4261
                        show_progress.emit(int((progress / length)*100))
4262
                    progress += 1
4263

    
4264
                # save Stream No Line List
4265
                index = 1
4266
                for model_data in self._streamLineListModelDatas:
4267
                    sql = f"insert into Stream_Line_List (UID, Drawing_UID, PnIDNumber, Tag_Seq_No, PipingMaterialsClass, InsulationPurpose, FluidCode, " \
4268
                          f"UnitNumber, NominalDiameter, [From], [To], Stream_No, [Case], [Index]) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
4269
                    sql = self.project.database.to_sql(sql)
4270
                    params = (str(uuid.uuid4()), drawing_uid, model_data['PnIDNumber'], model_data['Tag Seq No'], model_data['PipingMaterialsClass'], model_data['InsulationPurpose'], \
4271
                              model_data['FluidCode'], model_data['UnitNumber'], model_data['NominalDiameter'], model_data['FROM'], model_data['TO'], model_data['Stream No'], model_data['Case'], index)
4272
                    cursor.execute(sql, params)
4273
                    index += 1
4274

    
4275
                if show_progress:
4276
                    show_progress.emit(99)
4277

    
4278
                if self.project.database.db_type == 'SQLite':
4279
                    cursor.execute('commit')
4280
                else:
4281
                    conn.commit()
4282
            # Catch the exception
4283
            except Exception as ex:
4284
                # Roll back any change if something goes wrong
4285
                conn.rollback()
4286

    
4287
                from App import App
4288
                message = 'error occurred({}\\n{}) in {}:{}'.format(repr(ex), sql,
4289
                                                                    sys.exc_info()[-1].tb_frame.f_code.co_filename,
4290
                                                                    sys.exc_info()[-1].tb_lineno)
4291
                App.mainWnd().addMessage.emit(MessageType.Error, message)
4292

    
4293
        if rect:
4294
            self.activeDrawing.view_rect = rect
4295
            self.update_view_region(self.activeDrawing)
4296

    
4297
    def update_view_region(self, drawing):
4298
        """update view region"""
4299
        with self.project.database.connect() as conn:
4300
            try:
4301
                # Get a cursor object
4302
                cursor = conn.cursor()
4303

    
4304
                # check if there is view region
4305
                sql = f"select Drawings_UID from Views where Drawings_UID=?"
4306
                params = (drawing.UID,)
4307
                cursor.execute(self.project.database.to_sql(sql), params)
4308
                rows = cursor.fetchall()
4309
                if rows:
4310
                    sql = f"update Views set X=?,Y=?,Width=?,Height=? where Drawings_UID=?"
4311
                    params = (drawing.view_rect.x(), drawing.view_rect.y(),
4312
                              drawing.view_rect.width(), drawing.view_rect.height(), drawing.UID)
4313
                else:
4314
                    sql = f"insert into Views(Drawings_UID,X,Y,Width,Height) values(?,?,?,?,?)"
4315
                    params = (drawing.UID, drawing.view_rect.x(), drawing.view_rect.y(),
4316
                              drawing.view_rect.width(), drawing.view_rect.height())
4317

    
4318
                sql = self.project.database.to_sql(sql)
4319
                cursor.execute(sql, params)
4320
                conn.commit()
4321
            # Catch the exception
4322
            except Exception as ex:
4323

    
4324
                from App import App
4325
                message = 'error occurred({}\\n{}) in {}:{}'.format(repr(ex), sql,
4326
                                                                    sys.exc_info()[-1].tb_frame.f_code.co_filename,
4327
                                                                    sys.exc_info()[-1].tb_lineno)
4328
                App.mainWnd().addMessage.emit(MessageType.Error, message)
4329

    
4330
    '''
4331
        @brief      set equipment data list
4332
        @author     humkyung
4333
        @date       2018.05.03
4334
    '''
4335
    def setEquipmentDataList(self, dataList):
4336
        conn = self.project.database.connect()
4337
        with conn:
4338
            try:
4339
                # Get a cursor object
4340
                cursor = conn.cursor()
4341

    
4342
                for data in dataList:
4343
                    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(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
4344
                    param = tuple(data)
4345
                    cursor.execute(self.project.database.to_sql(sql), param)
4346
                conn.commit()
4347
            # Catch the exception
4348
            except Exception as ex:
4349
                # Roll back any change if something goes wrong
4350
                conn.rollback()
4351

    
4352
                from App import App
4353
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
4354
                                                              sys.exc_info()[-1].tb_lineno)
4355
                App.mainWnd().addMessage.emit(MessageType.Error, message)
4356

    
4357
    '''
4358
        @brief      set instrumnet data list
4359
        @author     kyoyho
4360
        @date       2018.08.14
4361
    '''
4362
    def setInstrumentDataList(self, dataList):
4363
        conn = self.project.database.connect()
4364
        with conn:
4365
            try:
4366
                # Get a cursor object
4367
                cursor = conn.cursor()
4368

    
4369
                for data in dataList:
4370
                    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(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
4371
                    param = tuple(data)
4372
                    cursor.execute(sql, param)
4373
                conn.commit()
4374

    
4375
            # Catch the exception
4376
            except Exception as ex:
4377
                # Roll back any change if something goes wrong
4378
                conn.rollback()
4379

    
4380
                from App import App
4381
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
4382
                                                              sys.exc_info()[-1].tb_lineno)
4383
                App.mainWnd().addMessage.emit(MessageType.Error, message)
4384

    
4385
    def getDrawings(self):
4386
        """ get drawings """
4387
        from Drawing import Drawing
4388

    
4389
        res = []
4390

    
4391
        with self.project.database.connect() as conn:
4392
            try:
4393
                cursor = conn.cursor()
4394
                if self.project.database.db_type == 'SQLite':
4395
                    sql = 'select UID, [NAME], [DATETIME], IFNULL(B.[X], 0) as X, IFNULL(B.[Y], 0) as Y, ' \
4396
                          'IFNULL(B.[Width], 0) as Width, IFNULL(B.[Height], 0) as Height from Drawings A ' \
4397
                          'left join Views B on A.UID = B.Drawings_UID'
4398
                else:
4399
                    sql = 'select UID, [NAME], [DATETIME], ISNULL(B.[X], 0) as X, ISNULL(B.[Y], 0) as Y, ' \
4400
                          'ISNULL(B.[Width], 0) as Width, ISNULL(B.[Height], 0) as Height from Drawings A ' \
4401
                          'left join Views B on A.UID = B.Drawings_UID'
4402

    
4403
                cursor.execute(self.project.database.to_sql(sql))
4404
                for row in cursor.fetchall():
4405
                    rect = QRectF(float(row['X']), float(row['Y']), float(row['Width']), float(row['Height']))
4406
                    res.append(Drawing(row['UID'], row['NAME'], row['DATETIME'], rect))
4407
            # Catch the exception
4408
            except Exception as ex:
4409
                from App import App
4410
                message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
4411
                                                              sys.exc_info()[-1].tb_lineno)
4412
                App.mainWnd().addMessage.emit(MessageType.Error, message)
4413

    
4414
        return res
4415

    
4416
    def saveDrawings(self, drawings):
4417
        """save given drawings"""
4418

    
4419
        import uuid
4420

    
4421
        if not drawings:
4422
            return
4423

    
4424
        with self.project.database.connect() as conn:
4425
            try:
4426
                # Get a cursor object
4427
                cursor = conn.cursor()
4428
                if self.project.database.db_type == 'SQLite':
4429
                    cursor.execute('begin')
4430

    
4431
                for drawing in drawings:
4432
                    if drawing.UID is None:
4433
                        # get image data
4434
                        image_blob_data = None
4435
                        #file_path = os.path.join(self.project.getDrawingFilePath(), drawing.name)
4436
                        #if drawing.name and os.path.isfile(file_path):
4437
                        #    with open(file_path.encode('utf-8'), 'rb') as file:
4438
                        #        image_blob_data = file.read()
4439
                        # up to here
4440

    
4441
                        sql = self.project.database.to_sql(
4442
                            'insert into Drawings(UID, [NAME], [DATETIME], [Image]) values(?, ?, ?, ?)')
4443
                        param = tuple([str(uuid.uuid4()), drawing.name, '', image_blob_data])
4444
                        drawing.UID = param[0]
4445
                    else:
4446
                        sql = self.project.database.to_sql("update Drawings set [NAME]=?,[DATETIME]=? where UID=?")
4447
                        param = (drawing.name, drawing.datetime, str(drawing.UID))
4448
                        #param = (drawing.name, drawing.datetime, image_blob_data, str(drawing.UID))
4449

    
4450
                    cursor.execute(sql, param)
4451

    
4452
                if self.project.database.db_type == 'SQLite':
4453
                    cursor.execute('commit')
4454
                else:
4455
                    conn.commit()
4456
            # Catch the exception
4457
            except Exception as ex:
4458
                # Roll back any change if something goes wrong
4459
                conn.rollback()
4460

    
4461
                from App import App
4462
                message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
4463
                                                              sys.exc_info()[-1].tb_lineno)
4464
                App.mainWnd().addMessage.emit(MessageType.Error, message)
4465

    
4466
    '''
4467
        @brief  get IsOriginDetect ComboBox Items
4468
    '''
4469
    def getIsOriginDetectComboBoxItems(self):
4470
        return [("원본 도면", 0), ("텍스트 제거 도면", 1)]
4471

    
4472
    '''
4473
        @brief  get IsOriginDetect ComboBox Items
4474
    '''
4475
    def getOcrOptionComboBoxItems(self):
4476
        return [("OCR 미적용", 0), ("일반 심볼", 1), ("Instrument 계통", 2)]
4477

    
4478
    '''
4479
        @brief      Return Symbol Type Items
4480
        @author     Jeongwoo
4481
        @date       18.04.20
4482
        @history    18.05.08    Jeongwoo type index changed
4483
    '''
4484
    def getSymbolTypeList(self):
4485
        symbolTypeList = []
4486

    
4487
        with self.project.database.connect() as conn:
4488
            cursor = conn.cursor()
4489
            sql = 'SELECT * FROM SymbolType ORDER BY Type ASC'
4490
            try:
4491
                cursor.execute(sql)
4492
                rows = cursor.fetchall()
4493
                for row in rows:
4494
                    symbolTypeList.append((row['UID'], row['Category'], row['Type']))  # UID, category, type
4495
            except Exception as ex:
4496
                from App import App
4497
                message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
4498
                                                              sys.exc_info()[-1].tb_lineno)
4499
                App.mainWnd().addMessage.emit(MessageType.Error, message)
4500

    
4501
        return symbolTypeList
4502

    
4503
    def getSymbolCategoryByType(self, type: str):
4504
        """get symbol category by using symbol type"""
4505
        category = None
4506
        if type in self._symbolType:
4507
            return self._symbolType[type]
4508

    
4509
        with self.project.database.connect() as conn:
4510
            try:
4511
                cursor = conn.cursor()
4512
                sql = self.project.database.to_sql('SELECT Category FROM SymbolType WHERE [Type] = ?')
4513
                cursor.execute(sql, (type,))
4514
                rows = cursor.fetchall()
4515
                if rows is not None and len(rows) > 0:
4516
                    category = rows[0]['Category']
4517
                    self._symbolType[type] = category
4518
            except Exception as ex:
4519
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
4520
                                                          sys.exc_info()[-1].tb_lineno))
4521

    
4522
        return category
4523

    
4524
    '''
4525
        @brief      Check Symbol Type is included in 'Equipment' Category
4526
        @author     Jeongwoo
4527
        @date       2018.05.09
4528
    '''
4529
    def isEquipmentType(self, type):
4530
        category = self.getSymbolCategoryByType(type)
4531
        return category is not None and category == 'Equipment'
4532

    
4533
    '''
4534
        @brief      Return Symbol Type Items with "None"
4535
        @author     Jeongwoo
4536
        @date       18.04.06
4537
        @history    Seperate SymbolTypeList and "None"
4538
    '''
4539
    def getSymbolTypeComboBoxItems(self):
4540
        symbolTypeList = [symbol_type for symbol_type in self.getSymbolTypeList() if symbol_type[1]]
4541
        symbolTypeList.insert(0, ('None', 'None', 'None'))
4542

    
4543
        return symbolTypeList
4544

    
4545
    '''
4546
        @brief  get Base Symbol ComboBox Items
4547
    '''
4548
    def getBaseSymbolComboBoxItems(self, type=None):
4549
        bsymbolNameList = self.getSymbolNameListByType(type)
4550
        bsymbolNameList = bsymbolNameList.copy()
4551
        bsymbolNameList.sort()
4552
        bsymbolNameList.insert(0, "None")
4553
        return bsymbolNameList
4554

    
4555
    '''
4556
        @brief  get Additional Symbol ComboBox Items
4557
    '''
4558
    def getAdditionalSymbolComboBoxItems(self):
4559
        asymbolNameList = self.getSymbolNameList()
4560
        asymbolNameList.sort()
4561
        asymbolNameList.insert(0, "None")
4562
        return asymbolNameList
4563

    
4564
    '''
4565
        @brief  get Additional Symbol's default direction ComboBox Items
4566
    '''
4567
    def getDefaultSymbolDirectionComboBoxItems(self):
4568
        return [("UP", 0), ("DOWN", 2), ("LEFT", 3), ("RIGHT", 1)]
4569

    
4570
    '''
4571
        @brief  getter of activeDrawing
4572
        @author humkyung
4573
        @date   2018.07.07
4574
    '''
4575
    @property
4576
    def activeDrawing(self):
4577
        return self._activeDrawing
4578

    
4579
    '''
4580
        @brief  setter of activeDrawing
4581
        @author humkyung
4582
        @date   2018.07.07
4583
    '''
4584
    @activeDrawing.setter
4585
    def activeDrawing(self, value):
4586
        if self._activeDrawing:
4587
            del self._activeDrawing
4588

    
4589
        self._activeDrawing = value
4590

    
4591
    def getColNames(self, table):
4592
        """ return column names of given table and attribute names if tabe is VALVE_DATA_LIST or EQUIPMET_DATA_LIST """
4593
        res = None
4594

    
4595
        conn = self.project.database.connect()
4596
        with conn:
4597
            try:
4598
                cursor = conn.cursor()
4599
                cursor.execute('select * from {}'.format(table))
4600
                res = [col_name[0] for col_name in cursor.description]
4601

    
4602
                if table == 'EQUIPMET_DATA_LIST' or table == 'VALVE_DATA_LIST':
4603
                    sql = 'select distinct c.Attribute from {} a left join Attributes b on a.uid=b.Components_UID ' \
4604
                          'left join SymbolAttribute c on b.SymbolAttribute_UID=c.UID where c.Attribute is not NULL'.format(
4605
                        table)
4606
                    cursor.execute(sql)
4607
                    rows = cursor.fetchall()
4608
                    for row in rows:
4609
                        res.append(row['Attribute'])
4610
            # Catch the exception
4611
            except Exception as ex:
4612
                print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
4613
                                                          sys.exc_info()[-1].tb_lineno))
4614

    
4615
        return res
4616

    
4617

    
4618
    def get_ext_apps(self):
4619
        """get external application information from App.db"""
4620

    
4621
        path = os.path.join(os.getenv('USERPROFILE'), 'Digital PID')
4622
        app_database_path = os.path.join(path, 'App.db')
4623
        with sqlite3.connect(app_database_path) as conn:
4624
            try:
4625
                conn.row_factory = sqlite3.Row
4626
                cursor = conn.cursor()
4627
                sql = 'select * from ExtApps'
4628
                cursor.execute(sql)
4629
                rows = cursor.fetchall()
4630
                return rows
4631
            except Exception as ex:
4632
                # Roll back any change if something goes wrong
4633
                conn.rollback()
4634

    
4635
                from App import App
4636
                message = f"error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:" \
4637
                          f"{sys.exc_info()[-1].tb_lineno}"
4638
                App.mainWnd().addMessage.emit(MessageType.Error, message)
4639

    
4640
        return None
4641

    
4642
    def set_ext_apps(self, model:QStandardItemModel) -> None:
4643
        """ save ext apps to database """
4644

    
4645
        path = os.path.join(os.getenv('USERPROFILE'), 'Digital PID')
4646
        app_database_path = os.path.join(path, 'App.db')
4647
        with sqlite3.connect(app_database_path) as conn:
4648
            try:
4649
                # Get a cursor object
4650
                cursor = conn.cursor()
4651

    
4652
                names = ','.join([f"'{model.item(row, 0).text()}'" for row in range(model.rowCount())])
4653
                sql = f"delete from ExtApps where [Name] not in (?)"
4654
                cursor.execute(sql, (names, ))
4655

    
4656
                for row in range(model.rowCount()):
4657
                    param = (model.item(row, 0).text(), model.item(row, 1).text(), model.item(row, 2).text())
4658

    
4659
                    sql = "insert into ExtApps([Name], Executable, Argument) select ?,?,? where not exists" \
4660
                          "(select [Name] from ExtApps where [Name]=?)"
4661
                    cursor.execute(sql, (param[0], param[1], param[2], param[0]))
4662

    
4663
                    sql = f"update ExtApps set Executable=?, Argument=? where [Name]=?"
4664
                    cursor.execute(sql, (param[1], param[2], param[0]))
4665

    
4666
                conn.commit()
4667
            # Catch the exception
4668
            except Exception as ex:
4669
                conn.rollback()
4670

    
4671
                from App import App
4672
                message = f'error occurred({ex}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:' \
4673
                          f'{sys.exc_info()[-1].tb_lineno}'
4674
                App.mainWnd().addMessage.emit(MessageType.Error, message)
4675

    
4676
        return None
4677

    
4678
    '''
4679
        @brief  getter of OCRData
4680
        @author humkyung
4681
        @date   2018.11.19
4682
    '''
4683
    @property
4684
    def OCRData(self):
4685
        if self._OCRData is None:
4686
            configs = self.getConfigs('Text Recognition', 'OCR Data')
4687
            self._OCRData = configs[0].value if 1 == len(configs) else 'eng'
4688

    
4689
        return self._OCRData
4690

    
4691
    '''
4692
        @brief  setter of OCRData
4693
        @author humkyung
4694
        @date   2018.11.19
4695
    '''
4696
    @OCRData.setter
4697
    def OCRData(self, value):
4698
        self._OCRData = value
4699

    
4700

    
4701
if __name__ == '__main__':
4702
    from AppDocData import AppDocData
4703

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