프로젝트

일반

사용자정보

통계
| 개정판:

hytos / DTI_PID / DTI_PID / TextItemFactory.py @ c0817882

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

1
"""
2
This is TextItemFactor module
3
"""
4

    
5
from SingletonInstance import SingletonInstane
6
import re
7
try:
8
    from PyQt5.QtCore import *
9
    from PyQt5.QtGui import *
10
    from PyQt5.QtWidgets import *
11
except ImportError:
12
    try:
13
        from PyQt4.QtCore import *
14
        from PyQt4.QtGui import *
15
    except ImportError:
16
        raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.")
17
from AppDocData import *
18
import sys, os
19
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Shapes')
20
from EngineeringTextItem import QEngineeringTextItem
21
from EngineeringLineNoTextItem import QEngineeringLineNoTextItem
22
from EngineeringNoteItem import QEngineeringNoteItem
23
from QEngineeringSizeTextItem import QEngineeringSizeTextItem
24
from QEngineeringTagNoTextItem import QEngineeringTagNoTextItem
25

    
26
class TextItemFactory(SingletonInstane):
27
    """
28
    This is TextItemFactor class
29
    """
30
    def __init__(self):
31
        self.delimiter = '"'
32

    
33
    '''
34
        @history    2018.04.27  Jeongwoo    Add condition on elif-statement (delimiter != '' and lineNoConfig != '')
35
                    humkyung 2018.05.02 create engineering size text item if condition matches
36
                    humkyung 2018.06.19 set line no's color
37
                    kyouho 2018.07.04 edit for isLineNo method (add parameter)
38
                    humkyung 2018.08.08 fill linePropertyData and tagSeqNoPattern if given data is None
39
                    euisung 2018.11.19  now textitemfactory set plain text in createTextItem() for allowables
40
    '''             
41
    def createTextItem(self, textInfo):
42
        import random
43

    
44
        item = None
45

    
46
        try:
47
            text = textInfo.getText()
48
            docData = AppDocData.instance()
49
            configs = docData.getConfigs('Size', 'Delimiter')
50
            sizeDelimiter = configs[0].value.upper() if 1 == len(configs) else None
51

    
52
            result = (False,)
53
            result = self.isLineNo(text)
54

    
55
            if result[0]:
56
                item = QEngineeringLineNoTextItem()
57
                text = ''
58
                for t in result[1]:
59
                    text += t
60
                item.setToolTip(text)
61
                item.setPlainText(text)
62

    
63
                # get color option
64
                configs = docData.getConfigs('Line Color', 'Visible Option')
65
                if configs:
66
                    visibleOption = configs[0].value
67
                else:
68
                    visibleOption = 'Random'
69

    
70
                configs = docData.getConfigs('Color Property', 'State')
71
                if configs:
72
                    color_property = configs[0].value
73

    
74
                # set line no color
75
                if visibleOption == 'Random':
76
                    colorCount = len(docData.colors)
77
                    if colorCount:
78
                        colorIdx = random.randrange(0, colorCount)
79
                        rgb = docData.colors[colorIdx]
80
                        item.setColor(QColor(rgb.red, rgb.green, rgb.blue).name())
81
                else:
82
                    configs = docData.getConfigs('Line No', 'Configuration')
83
                    configs = configs[0].value.split(self.delimiter)
84

    
85
                    values = result[1]
86
                    index = configs.index(color_property)
87
                    if index >= 0:
88
                        value = values[index]
89
                        line_properties = docData.getLinePropertiesByUID(color_property)
90
                        if line_properties[0].Attribute.replace(' ','') == 'NominalDiameter':
91
                            configs = docData.getConfigs('Line No', 'Size Unit')
92
                            if configs and configs[0].value == "Inch":
93
                                value = docData.convertInchToMetric(value)
94

    
95
                        configs = docData.getConfigs(color_property, value)
96
                        if configs:
97
                            data = configs[0].value
98
                            rgb = data.split(',')
99
                            item.setColor(QColor(int(rgb[0]), int(rgb[1]), int(rgb[2])).name())
100
                    # up to here
101
            elif self.isNoteNoText(textInfo):
102
                item = QEngineeringNoteItem()
103
                item.setToolTip(text)
104
                item.setPlainText(text)
105
            elif self.isSizeText(text, sizeDelimiter):
106
                item = QEngineeringSizeTextItem()
107
                item.setToolTip(text)
108
                item.setPlainText(text)
109
            elif self.isTagNoText(text):
110
                item = QEngineeringTagNoTextItem()
111
                item.setToolTip(text)
112
                item.setPlainText(text)
113
            else:
114
                item = QEngineeringTextItem()
115
                item.setToolTip(text)
116
                item.setPlainText(text)
117
        except Exception as ex:
118
            from App import App
119

    
120
            message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
121
            App.mainWnd().addMessage.emit(MessageType.Error, message)
122

    
123
        return item
124
    
125
    '''
126
        @brief  check if given text is possible to be line no
127
        @author humkyung
128
        @date   2018.04.20
129
        @history 2018.04.26 Jeongwoo Moved here from QEngineeringTextItem
130
                 2018.04.30 Jeongwoo lineNoConfig None Check
131
                 kyouho 2018.07.04 edit logic
132
                 2018.11.15 add allowable
133
    '''
134
    def isLineNo(self, text):
135
        try:
136
            docData = AppDocData.instance()
137
            # delimiter
138
            configs = docData.getConfigs('Line No', 'Delimiter')
139
            delimiter = configs[0].value if 1 == len(configs) else '-'
140
            # line config
141
            configs = docData.getConfigs('Line No', 'Configuration')
142
            if configs and configs[0].value:
143
                lineNoConfig = configs[0].value.split(self.delimiter)
144

    
145
                res = []
146

    
147
                if lineNoConfig is None or len(lineNoConfig) == 0:
148
                    return (False,)
149
            
150
                tokens = text.split(delimiter)
151
                patternText = configs[0].value.replace(self.delimiter, '').split(self.delimiter)
152
                #Line Number에 Delimiter가 있을 수 있음
153
                if configs[0].value != 'None' and len(tokens) >= len(patternText):
154
                    loopText = text.replace(' ','')
155
                    
156
                    for propertyName in lineNoConfig:
157
                        isStartWord = False
158
                        loopList = []
159

    
160
                        lineProp = docData.getLinePropertiesByUID(propertyName)
161
                        # Line property인 경우
162
                        if lineProp:
163
                            lineType = lineProp[0].AttributeType
164
                            if lineType == 'Code Table':
165
                                tableName = lineProp[0].Attribute
166
                                if tableName == 'NominalDiameter':
167
                                    loopListOri = docData.getCodeTable(tableName, True)
168
                                    for loop in loopListOri:
169
                                        loopList.append((loop, loop))
170
                                else:
171
                                    allAllows = docData.getCodeTable(tableName)
172
                                    for index in range(len(allAllows)):
173
                                        loopList.append((allAllows[index][1], allAllows[index][1]))
174
                                        if allAllows[index][3] != '' and allAllows[index][3] != None:
175
                                            allows = allAllows[index][3].split(',')
176
                                            for allow in allows:
177
                                                loopList.append((allow, allAllows[index][1]))
178

    
179
                                isStartWord = True
180

    
181
                            elif lineType == 'Int':
182
                                length = lineProp[0].Length
183
                                loopList.append((length, True))
184

    
185
                            elif lineType == 'String':
186
                                length = lineProp[0].Length
187
                                loopList.append((length, False))
188

    
189
                        # 못찾은 경우 (ex. delimiter)
190
                        else:
191
                            if propertyName:
192
                                loopList.append((propertyName, propertyName))
193
                                isStartWord = True
194
                            else:
195
                                return (False,)
196
                        
197
                        find = False
198
                        for loop in loopList:
199
                            if isStartWord:
200
                                result = self.isStartWithWord(loopText, loop)
201
                            else:
202
                                result = self.isLimitWord(loopText, loop)
203
                            if result[0]:
204
                                loopText = result[1]
205
                                res.append(result[2])
206
                                find = True
207
                                break
208
                        if not find:
209
                            return (False,)
210

    
211
                    if loopText == '':
212
                        return (True, res)
213
                    else:
214
                        return (False,)
215

    
216
            return (False,)
217
        except Exception as ex:
218
            from App import App
219

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

    
223
            return (False,)
224

    
225
    '''
226
        @brief      Check Text startwith word
227
        @author     kyouho
228
        @date       2018.07.04
229
    '''
230
    def isStartWithWord(self, text, word):
231
        sliceText = text[0:len(word[0])]
232
        if sliceText == word[0]:
233
            return (True, text[len(sliceText):len(text)], word[1])
234
        else:
235
            return (False,)
236

    
237

    
238
    '''
239
        @brief      Check Text startwith number
240
        @author     kyouho
241
        @date       2018.07.05
242
    '''
243
    def isStartWithNumber(self, text):
244
        sliceText = text[0:1]
245
        num = ''
246
        if self.isNumber(sliceText):
247
            text = text[1:len(text)]
248
            num += text 
249
            while len(text) > 0:
250
                sliceText = text[0:1]
251
                
252
                if self.isNumber(sliceText):
253
                    text = text[1:len(text)]
254
                    num += text
255
                else:
256
                    break
257
            
258
            return (True, text, num)
259
        else:
260
            return (False,)
261

    
262

    
263
    '''
264
        @brief      Check Number
265
        @author     kyouho
266
        @date       2018.07.05
267
        @history    kyouho 2018.07.09   add Refular Expression
268
    '''
269
    def isNumber(self, num):
270
        p = re.compile('(^[0-9]+$)')
271
        result = p.match(num)
272

    
273
        if result:
274
            return True
275
        else:
276
            return False
277

    
278
    '''
279
        @brief      Check Number
280
        @author     kyouho
281
        @date       2018.07.05
282
    '''
283
    def isTagSeqNo(self, text, pattern):
284
        try:
285
            if pattern is not None:
286
                attr = text
287
                result = eval(pattern)
288
                if self.isNumber(result):
289
                    sliceText = text[0:len(result)]
290
                    return (True, text[len(sliceText):len(text)], sliceText)
291
                else:
292
                    return (False,)
293
            else:
294
                return (False,)
295
        except Exception as ex:
296
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))       
297
            
298
    '''
299
        @brief      Check Number
300
        @author     kyouho
301
        @date       2018.07.05
302
    '''
303
    def isLimitWord(self, text, pattern):
304
        try:
305
            if pattern is not None:
306
                attr = text
307
                length = pattern[0]
308
                isNumber = pattern[1]
309

    
310
                if length:  # Length가 있으면 Length만큼 문자열을 가져와 길이를 검사한다.
311
                    result = eval('attr[:' + str(length) + ']')
312
                    if int(length) != len(result):
313
                        return(False,)
314
                elif isNumber:
315
                    match = re.search(re.compile('^[0-9]+'), attr)
316
                    if match:
317
                        result = match.group(match.start()) 
318
                    else:
319
                        return (False,)
320
                else:
321
                    result = attr
322

    
323
                if isNumber:
324
                    if self.isNumber(result):
325
                        sliceText = text[0:len(result)]
326
                        return (True, text[len(sliceText):len(text)], sliceText)
327
                    else:
328
                        return (False,)
329
                else:
330
                    sliceText = text[0:len(result)]
331
                    return (True, text[len(sliceText):len(text)], sliceText)
332
            else:
333
                return (False,)
334
        except Exception as ex:
335
            print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))       
336

    
337
    '''
338
        @brief      Check if given text is Note No Text (ex : NOTE 1, NOTE 2, ...)
339
        @author     Jeongwoo
340
        @date       2018.04.26
341
        @history    2018.05.16  Jeongwoo    Modify Validator flag
342
    '''
343
    def isNoteNoText(self, textInfo):
344
        appDocData = AppDocData.instance()
345
        configs = appDocData.getConfigs('Note No Tag Rule', 'Note No Expression')
346
        if 1 == len(configs) and configs[0].value:
347
            expression = configs[0].value
348
            match = re.search(re.compile(expression), textInfo.getText())
349

    
350
            configs = appDocData.getConfigs('Note No Tag Rule', 'Note No Symbol Name')
351
            if match and 1 == len(configs) and configs[0].value: 
352
                for symbol in appDocData.symbols:
353
                    if symbol.name == configs[0].value and symbol.isContains(textInfo):
354
                        return True
355
            else:
356
                return (True if match else False)
357
        
358
        return False
359

    
360
    '''
361
        @brief  check if given text is size text
362
        @author humkyung
363
        @date   2018.05.02
364
    '''
365
    def isSizeText(self, text, delimiter=None):
366
        docData = AppDocData.instance()
367
        sizeDataList = docData.getNomialPipeSizeData()
368

    
369
        tokens = text.upper().split(delimiter) if delimiter is not None else [text]
370
        for token in tokens:
371
            matches = [sizeData for sizeData in sizeDataList if sizeData.sizeValue() == token]
372
            if not matches: return False
373
        
374
        return True
375
    
376
    '''
377
        @brief  check if given text is tag no
378
        @author humkyung
379
        @date   2018.05.03
380
    '''
381
    def isTagNoText(self, text):
382
        docData = AppDocData.instance()
383
        dataList = docData.getEquipmentDataList()
384
        matches = [data for data in dataList if data['ITEM_NO'] == text]
385
        return (len(matches) > 0)