프로젝트

일반

사용자정보

통계
| 개정판:

hytos / DTI_PID / DTI_PID / TextItemFactory.py @ 724bd358

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

1 d0db0878 humkyung
# coding: utf-8
2
""" This is TextItemFactor module """
3 e883edfd humkyung
4 1024ee16 humkyung
from SingletonInstance import SingletonInstance
5 25598176 gaqhf
import re
6 1024ee16 humkyung
7 aa1b6842 김정우
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 18e5ca81 humkyung
from AppDocData import *
18 aa1b6842 김정우
import sys, os
19 1024ee16 humkyung
20 aa1b6842 김정우
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Shapes')
21 c80d49e6 humkyung
from EngineeringTextItem import QEngineeringTextItem
22 baf331db humkyung
from EngineeringLineNoTextItem import QEngineeringLineNoTextItem
23 afabd84e humkyung
from EngineeringNoteItem import QEngineeringNoteItem
24 24015dc6 humkyung
from QEngineeringSizeTextItem import QEngineeringSizeTextItem
25 eca61950 humkyung
from QEngineeringTagNoTextItem import QEngineeringTagNoTextItem
26 a4806b86 humkyung
from EngineeringValveOperCodeTextItem import QEngineeringValveOperCodeTextItem
27 74fc4c98 esham21
from EngineeringReservedWordTextItem import QEngineeringReservedWordTextItem
28 d0db0878 humkyung
from SpecialItemTypesDialog import SpecialItemTypes
29 aa1b6842 김정우
30 1024ee16 humkyung
31
class TextItemFactory(SingletonInstance):
32 8138f238 humkyung
    """ This is TextItemFactor class """
33 1024ee16 humkyung
34 aa1b6842 김정우
    def __init__(self):
35 87aa9c66 gaqhf
        self.delimiter = '"'
36 67f38d89 esham21
        self.lineNoDelimiter = '!-!'
37 aa1b6842 김정우
38 99b4d542 김정우
    '''
39
        @history    2018.04.27  Jeongwoo    Add condition on elif-statement (delimiter != '' and lineNoConfig != '')
40 24015dc6 humkyung
                    humkyung 2018.05.02 create engineering size text item if condition matches
41 8c66ce13 humkyung
                    humkyung 2018.06.19 set line no's color
42 87aa9c66 gaqhf
                    kyouho 2018.07.04 edit for isLineNo method (add parameter)
43 e65b0bf8 humkyung
                    humkyung 2018.08.08 fill linePropertyData and tagSeqNoPattern if given data is None
44 579f5a34 esham21
                    euisung 2018.11.19  now textitemfactory set plain text in createTextItem() for allowables
45 1024ee16 humkyung
    '''
46
47 66a0f7c9 esham21
    def createTextItem(self, textInfo, lineNoConfig=None):
48 14ea3f13 esham21
        from Configs import LineNoConfig, TagNoConfig
49 0d987bb7 esham21
        import csv
50 f118d8a5 humkyung
51 aa1b6842 김정우
        item = None
52 6fad8ffd humkyung
53
        try:
54 cc747b58 esham21
            text = textInfo.getText()
55 24015dc6 humkyung
            docData = AppDocData.instance()
56 49ba3f48 humkyung
57 24015dc6 humkyung
            configs = docData.getConfigs('Size', 'Delimiter')
58 2936baab esham21
            sizeDelimiters = configs[0].value.upper().replace(' ', '').split(',') if 1 == len(configs) else None
59 24015dc6 humkyung
60 e019d322 esham21
            _no_config = None
61 14ea3f13 esham21
            # check is line no
62 49113215 humkyung
            line_no_configs = LineNoConfig.instance()
63
            if line_no_configs:
64 66a0f7c9 esham21
                if not lineNoConfig:
65
                    for line_no_config in line_no_configs:
66
                        result = line_no_config.parse(text)
67
                        if result[0]:
68
                            sizeUnit = line_no_config.unit
69
                            _no_config = line_no_config.value
70
                            break
71
                else:
72
                    matches = [line for line in line_no_configs if lineNoConfig in line.value]
73
                    if matches:
74
                        result = matches[0].parse(text)
75
                        if result[0]:
76
                            sizeUnit = matches[0].unit
77
                            _no_config = matches[0].value
78
                        else:
79
                            for line_no_config in line_no_configs:
80
                                result = line_no_config.parse(text)
81
                                if result[0]:
82
                                    sizeUnit = line_no_config.unit
83
                                    _no_config = line_no_config.value
84
                                    break
85
                    else:
86
                        for line_no_config in line_no_configs:
87
                            result = line_no_config.parse(text)
88
                            if result[0]:
89
                                sizeUnit = line_no_config.unit
90
                                _no_config = line_no_config.value
91
                                break
92 67f38d89 esham21
            else:
93
                result = (False,)
94 25598176 gaqhf
95 14ea3f13 esham21
            # check is tag no
96
            tag_no_configs = TagNoConfig.instance(tag=True)
97
            if tag_no_configs:
98
                for tag_no_config in tag_no_configs:
99
                    tagResult = tag_no_config.parse(text)
100
                    if tagResult[0]:
101
                        sizeUnit = tag_no_config.unit
102
                        break
103
            else:
104
                tagResult = (False,)
105
106 b73a62df humkyung
            if result[0]:
107 afabd84e humkyung
                item = QEngineeringLineNoTextItem()
108 e019d322 esham21
                item.set_property('Config', self.delimiter.join(list(csv.reader([_no_config], delimiter=self.delimiter, escapechar='^'))[0]))
109 49113215 humkyung
                text = ''.join(result[1])
110 617797e9 esham21
                for i in result[2]:
111
                    text = text[:i] + '\n' + text[i:]
112 579f5a34 esham21
                item.setPlainText(text)
113 25598176 gaqhf
114
                # get color option
115
                configs = docData.getConfigs('Line Color', 'Visible Option')
116
                if configs:
117
                    visibleOption = configs[0].value
118
                else:
119
                    visibleOption = 'Random'
120
121
                configs = docData.getConfigs('Color Property', 'State')
122
                if configs:
123 aa312985 humkyung
                    color_property = configs[0].value
124 25598176 gaqhf
125 aa312985 humkyung
                # set line no color
126 25598176 gaqhf
                if visibleOption == 'Random':
127 fd329e57 esham21
                    rgb = docData.colors
128
                    item.change_color(QColor(rgb.red, rgb.green, rgb.blue).name())
129 25598176 gaqhf
                else:
130 e019d322 esham21
                    #configs = docData.getConfigs('Line No', 'Configuration')
131
                    configs = list(csv.reader([_no_config], delimiter=self.delimiter, escapechar='^'))[0]
132 269a15c8 gaqhf
133 25598176 gaqhf
                    values = result[1]
134 aa312985 humkyung
                    index = configs.index(color_property)
135 fce49e72 gaqhf
                    if index >= 0:
136 25598176 gaqhf
                        value = values[index]
137 aa312985 humkyung
                        line_properties = docData.getLinePropertiesByUID(color_property)
138 1024ee16 humkyung
                        if line_properties[0].Attribute.replace(' ', '') == 'NominalDiameter':
139 67f38d89 esham21
                            if sizeUnit == "Inch":
140 fce49e72 gaqhf
                                value = docData.convertInchToMetric(value)
141 25598176 gaqhf
142 aa312985 humkyung
                        configs = docData.getConfigs(color_property, value)
143 fce49e72 gaqhf
                        if configs:
144
                            data = configs[0].value
145
                            rgb = data.split(',')
146 835465ff humkyung
                            item.change_color(QColor(int(rgb[0]), int(rgb[1]), int(rgb[2])).name())
147 25598176 gaqhf
                    # up to here
148 1171931c esham21
                docData.tracerLineNos.append(item)
149 14ea3f13 esham21
            elif tagResult[0]:
150
                item = QEngineeringTagNoTextItem()
151 6d7f2097 esham21
                text = ''.join(tagResult[1])
152 14ea3f13 esham21
                item.setToolTip('TAG NO = {}'.format(text))
153
                item.setPlainText(text)
154 6fad8ffd humkyung
            else:
155 d6518150 humkyung
                item = self.create_note_no_text(textInfo)
156 2936baab esham21
                for sizeDelimiter in sizeDelimiters:
157
                    sizeTextInfo = self.isSizeText(text, sizeDelimiter)
158
                    if sizeTextInfo:
159
                        break
160 d6518150 humkyung
                if item:
161
                    pass
162 8367115b esham21
                #elif self.is_reserved_word(text):
163
                #    item = QEngineeringReservedWordTextItem()
164
                #    item.setToolTip('Reserved Word = {}'.format(text))
165
                #    item.setPlainText(text)
166 2936baab esham21
                elif sizeTextInfo:
167
                    item = QEngineeringSizeTextItem(mainSubSize=sizeTextInfo[1], sizeDelimiter=sizeTextInfo[2])
168
                    item.setToolTip('SIZE = {}'.format(sizeTextInfo[0]))
169
                    item.setPlainText(sizeTextInfo[0])
170 14ea3f13 esham21
                #elif self.isTagNoText(text):
171
                #    item = QEngineeringTagNoTextItem()
172
                #    item.setToolTip('TAG NO = {}'.format(text))
173
                #    item.setPlainText(text)
174 8367115b esham21
                #elif self.is_valve_operation_code(text):
175
                #    item = QEngineeringValveOperCodeTextItem()
176
                #    item.setToolTip('Valve Operation Code = {}'.format(text))
177
                #    item.setPlainText(text)
178 d6518150 humkyung
                else:
179 3a04bc04 esham21
                    text = self.fix_dictionary_word(text)
180 d6518150 humkyung
                    item = QEngineeringTextItem()
181
                    item.setToolTip(text)
182
                    item.setPlainText(text)
183 d0db0878 humkyung
                    item.special_item_type = SpecialItemTypes.instance().find_match_exactly(item)
184 f7987e0e esham21
                #docData.texts.append(item)
185 6fad8ffd humkyung
        except Exception as ex:
186 1024ee16 humkyung
            from App import App
187 c5e51d41 esham21
            from AppDocData import MessageType
188 e65b0bf8 humkyung
189 1024ee16 humkyung
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
190
                                                           sys.exc_info()[-1].tb_lineno)
191 e65b0bf8 humkyung
            App.mainWnd().addMessage.emit(MessageType.Error, message)
192 6fad8ffd humkyung
193 aa1b6842 김정우
        return item
194 1024ee16 humkyung
195 aa1b6842 김정우
    '''
196 c71687d5 gaqhf
        @brief      Check Text startwith word
197 87aa9c66 gaqhf
        @author     kyouho
198
        @date       2018.07.04
199
    '''
200 1024ee16 humkyung
201 c71687d5 gaqhf
    def isStartWithWord(self, text, word):
202 579f5a34 esham21
        sliceText = text[0:len(word[0])]
203
        if sliceText == word[0]:
204
            return (True, text[len(sliceText):len(text)], word[1])
205 87aa9c66 gaqhf
        else:
206
            return (False,)
207
208
    '''
209 c71687d5 gaqhf
        @brief      Check Text startwith number
210
        @author     kyouho
211
        @date       2018.07.05
212
    '''
213 1024ee16 humkyung
214 c71687d5 gaqhf
    def isStartWithNumber(self, text):
215
        sliceText = text[0:1]
216 d2a401b0 gaqhf
        num = ''
217 c71687d5 gaqhf
        if self.isNumber(sliceText):
218
            text = text[1:len(text)]
219 1024ee16 humkyung
            num += text
220 c71687d5 gaqhf
            while len(text) > 0:
221
                sliceText = text[0:1]
222 1024ee16 humkyung
223 c71687d5 gaqhf
                if self.isNumber(sliceText):
224
                    text = text[1:len(text)]
225 d2a401b0 gaqhf
                    num += text
226 c71687d5 gaqhf
                else:
227
                    break
228 1024ee16 humkyung
229 d2a401b0 gaqhf
            return (True, text, num)
230 c71687d5 gaqhf
        else:
231
            return (False,)
232
233
    '''
234
        @brief      Check Number
235
        @author     kyouho
236
        @date       2018.07.05
237 25598176 gaqhf
        @history    kyouho 2018.07.09   add Refular Expression
238 c71687d5 gaqhf
    '''
239 1024ee16 humkyung
240 c71687d5 gaqhf
    def isNumber(self, num):
241 7278d3e3 gaqhf
        p = re.compile('(^[0-9]+$)')
242 510a03fb gaqhf
        result = p.match(num)
243
244
        if result:
245 c71687d5 gaqhf
            return True
246 510a03fb gaqhf
        else:
247 c71687d5 gaqhf
            return False
248
249 ccb8b051 gaqhf
    '''
250
        @brief      Check Number
251
        @author     kyouho
252
        @date       2018.07.05
253
    '''
254 1024ee16 humkyung
255 ccb8b051 gaqhf
    def isTagSeqNo(self, text, pattern):
256
        try:
257
            if pattern is not None:
258
                attr = text
259
                result = eval(pattern)
260
                if self.isNumber(result):
261
                    sliceText = text[0:len(result)]
262
                    return (True, text[len(sliceText):len(text)], sliceText)
263
                else:
264
                    return (False,)
265
            else:
266
                return (False,)
267
        except Exception as ex:
268 1024ee16 humkyung
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
269
                                                       sys.exc_info()[-1].tb_lineno))
270
271 269a15c8 gaqhf
    '''
272
        @brief      Check Number
273
        @author     kyouho
274
        @date       2018.07.05
275
    '''
276 1024ee16 humkyung
277 269a15c8 gaqhf
    def isLimitWord(self, text, pattern):
278
        try:
279
            if pattern is not None:
280
                attr = text
281
                length = pattern[0]
282
                isNumber = pattern[1]
283
284 acf92f86 humkyung
                if length:  # Length가 있으면 Length만큼 문자열을 가져와 길이를 검사한다.
285
                    result = eval('attr[:' + str(length) + ']')
286
                    if int(length) != len(result):
287 1024ee16 humkyung
                        return (False,)
288 acf92f86 humkyung
                elif isNumber:
289
                    match = re.search(re.compile('^[0-9]+'), attr)
290
                    if match:
291 1024ee16 humkyung
                        result = match.group(match.start())
292 acf92f86 humkyung
                    else:
293
                        return (False,)
294
                else:
295
                    result = attr
296 269a15c8 gaqhf
297
                if isNumber:
298
                    if self.isNumber(result):
299
                        sliceText = text[0:len(result)]
300
                        return (True, text[len(sliceText):len(text)], sliceText)
301
                    else:
302
                        return (False,)
303
                else:
304
                    sliceText = text[0:len(result)]
305
                    return (True, text[len(sliceText):len(text)], sliceText)
306
            else:
307
                return (False,)
308
        except Exception as ex:
309 1024ee16 humkyung
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
310
                                                       sys.exc_info()[-1].tb_lineno))
311 c71687d5 gaqhf
312
    '''
313 aa1b6842 김정우
        @brief      Check if given text is Note No Text (ex : NOTE 1, NOTE 2, ...)
314
        @author     Jeongwoo
315
        @date       2018.04.26
316 73a9aa93 김정우
        @history    2018.05.16  Jeongwoo    Modify Validator flag
317 aa1b6842 김정우
    '''
318 1024ee16 humkyung
319 d6518150 humkyung
    def create_note_no_text(self, textInfo):
320
        item = None
321
322 e883edfd humkyung
        appDocData = AppDocData.instance()
323 be3e0c2d humkyung
        configs = appDocData.getConfigs('Note No Tag Rule', 'Note No Expression')
324 b73a62df humkyung
        if 1 == len(configs) and configs[0].value:
325 be3e0c2d humkyung
            expression = configs[0].value
326 cc747b58 esham21
            match = re.search(re.compile(expression), textInfo.getText())
327 f48febb9 esham21
328 d6518150 humkyung
            if match:
329
                configs = appDocData.getConfigs('Note No Tag Rule', 'Note No Symbol Name')
330
                if 1 == len(configs) and configs[0].value:
331
                    symbol_names = configs[0].value.split(',')
332 e0cb1584 esham21
                    for symbol in appDocData.symbols:
333 1024ee16 humkyung
                        if symbol.name in symbol_names and symbol.includes(
334
                                textInfo.center) and '"' not in textInfo.getText():
335 7765b508 humkyung
                            item = QEngineeringNoteItem(symbol=symbol)
336 25bc4adc esham21
                            item.owner = symbol
337 08115fb1 esham21
                            symbol.add_assoc_item(item, 0)
338 d6518150 humkyung
                            break
339
                else:
340
                    item = QEngineeringNoteItem()
341
342
                if item:
343
                    item.setToolTip(textInfo.getText())
344
                    item.setPlainText(textInfo.getText())
345
346
        return item
347 24015dc6 humkyung
348
    '''
349
        @brief  check if given text is size text
350
        @author humkyung
351
        @date   2018.05.02
352
    '''
353 1024ee16 humkyung
354 859d4c52 esham21
    def isSizeText(self, text, delimiter='X'):
355 fbc85e2d humkyung
        from NominalPipeSize import NominalPipeSizeTable
356
357 d03fbb91 esham21
        try:
358
            sizeUnit = None
359
            configs = AppDocData.instance().getConfigs('Project', 'Unit')
360
            sizeUnit = configs[0].value if 1 == len(configs) else 'Imperial'
361
362
            pipe_sizes = NominalPipeSizeTable.instance().pipe_sizes
363
364
            text = text.replace("'", '"').replace(' ', '').upper()
365
366
            if delimiter != '/' and delimiter in text:
367
                if len([_text for _text in text.split(delimiter.upper()) if len(_text) > 0]) < 2:
368
                    return False
369
                if text.count(delimiter) != 1:
370
                    return False
371
372
            first, second = None, None
373
            # for imperial
374
            if sizeUnit == 'Imperial' and text.find('"') is not -1 and delimiter == '/':
375
                first = text[:text.find('"') + 1]
376
                second = text[text.find('"') + 1:].replace(delimiter.upper(), '',
377
                                            1).strip() if delimiter is not None else text[text.find('"') + 1:].strip()
378
            elif sizeUnit == 'Imperial':
379
                first = text.split(delimiter.upper())[0]
380
                second = text.split(delimiter.upper())[1] if len(text.split(delimiter.upper())) == 2 else None
381
            # for metric
382 859d4c52 esham21
            else:
383 d03fbb91 esham21
                split_text = text.strip().split(delimiter.upper())
384
                if len(split_text) > 2:
385
                    return False
386
                first = split_text[0]
387
                second = split_text[1] if len(split_text) is 2 else None
388
389
            tokens = [first, second] if second is not None and len(second) is not 0 else [first]
390
            index = 0
391
            for token in tokens:
392
                matches = [(sizeData.find(token, sizeUnit) if sizeUnit else sizeData.find(token)) for sizeData in pipe_sizes
393
                        if (sizeData.find(token, sizeUnit) if sizeUnit else sizeData.find(token))]
394
                if matches:
395
                    tokens[index] = matches[0]
396
                else:
397
                    return False
398
                index += 1
399 1024ee16 humkyung
400 d03fbb91 esham21
            if len(tokens) == 2:
401
                if self.inch_to_number(tokens[0]) < self.inch_to_number(tokens[1]):
402
                    tokens[0], tokens[1] = tokens[1], tokens[0]
403
            return [delimiter.join(tokens), tokens, delimiter]
404
        except Exception as ex:
405
            from App import App
406
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
407
                                                              sys.exc_info()[-1].tb_lineno)
408
            App.mainWnd().addMessage.emit(MessageType.Error, message)
409
            return False
410 1024ee16 humkyung
411 5062109d esham21
    def inch_to_number(self, inch_str):
412 d03fbb91 esham21
        try:
413
            app_doc_data = AppDocData.instance()
414
            configs = app_doc_data.getConfigs('Size', 'Symbol')
415
            size_symbols = configs[0].value.replace(' ', '').split(',') if 1 == len(configs) else ['"']
416
417 7c35c986 esham21
            inchs = str(inch_str)
418 d03fbb91 esham21
            for symbol in size_symbols:
419 7c35c986 esham21
                inchs = inchs.replace(symbol, '')
420 724bd358 esham21
            inchs = inchs.lstrip('0').replace(' ', '-').replace('"', '').split('-')
421 d03fbb91 esham21
422
            number = 0
423
            for inch in inchs:
424
                if '/' not in inch:
425
                    number += float(inch)
426
                else:
427
                    fraction = inch.split('/')
428
                    number += float(fraction[0]) / float(fraction[1])
429
        except Exception as ex:
430
            from App import App
431 d39b9d01 esham21
            from AppDocData import MessageType
432 d03fbb91 esham21
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
433 d39b9d01 esham21
                                                            sys.exc_info()[-1].tb_lineno)
434 d03fbb91 esham21
            App.mainWnd().addMessage.emit(MessageType.Error, message)
435
436
            return 0
437 5062109d esham21
438
        return number
439
440 eca61950 humkyung
    '''
441
        @brief  check if given text is tag no
442
        @author humkyung
443
        @date   2018.05.03
444
    '''
445 1024ee16 humkyung
446 eca61950 humkyung
    def isTagNoText(self, text):
447 04271a49 humkyung
        from CodeTables import CodeTable
448
449 b048d967 esham21
        found = CodeTable.instance('EqpTagNames').find_match_exactly(text)
450 04271a49 humkyung
451
        return True if found else False
452 a4806b86 humkyung
453
    def is_valve_operation_code(self, text):
454
        """
455
        check if given text is valve operation code
456
        """
457
        from CodeTables import CodeTable
458
459 b048d967 esham21
        found = CodeTable.instance('ValveOperCodes').find_match_exactly(text)
460 a4806b86 humkyung
461
        return True if found else False
462 74fc4c98 esham21
463 3a04bc04 esham21
    def fix_dictionary_word(self, text):
464
        """ fix if given text is in dictionary """
465
        from CodeTables import CodeTable
466
467
        found = CodeTable.instance('Dictionary').find_match_exactly(text)
468
469
        return found if found else text
470
471 ff77e799 humkyung
    def is_reserved_word(self, text):
472
        """ check if given text is reserved words """
473 74fc4c98 esham21
        from CodeTables import CodeTable
474
475 b048d967 esham21
        found = CodeTable.instance('ReservedWords').find_match_exactly(text)
476 74fc4c98 esham21
477
        return True if found else False
클립보드 이미지 추가 (최대 크기: 500 MB)