프로젝트

일반

사용자정보

통계
| 개정판:

hytos / DTI_PID / DTI_PID / TextItemFactory.py @ 5062109d

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

1
# coding: utf-8
2
""" This is TextItemFactor module """
3

    
4
from SingletonInstance import SingletonInstance
5
import re
6

    
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

    
20
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Shapes')
21
from EngineeringTextItem import QEngineeringTextItem
22
from EngineeringLineNoTextItem import QEngineeringLineNoTextItem
23
from EngineeringNoteItem import QEngineeringNoteItem
24
from QEngineeringSizeTextItem import QEngineeringSizeTextItem
25
from QEngineeringTagNoTextItem import QEngineeringTagNoTextItem
26
from EngineeringValveOperCodeTextItem import QEngineeringValveOperCodeTextItem
27
from EngineeringReservedWordTextItem import QEngineeringReservedWordTextItem
28
from SpecialItemTypesDialog import SpecialItemTypes
29

    
30

    
31
class TextItemFactory(SingletonInstance):
32
    """ This is TextItemFactor class """
33

    
34
    def __init__(self):
35
        self.delimiter = '"'
36
        self.lineNoDelimiter = '!-!'
37

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

    
47
    def createTextItem(self, textInfo):
48
        from Configs import LineNoConfig, TagNoConfig
49

    
50
        item = None
51

    
52
        try:
53
            text = textInfo.getText()
54
            docData = AppDocData.instance()
55

    
56
            configs = docData.getConfigs('Size', 'Delimiter')
57
            sizeDelimiter = configs[0].value.upper() if 1 == len(configs) else None
58

    
59
            # check is line no
60
            line_no_configs = LineNoConfig.instance()
61
            if line_no_configs:
62
                for line_no_config in line_no_configs:
63
                    result = line_no_config.parse(text)
64
                    if result[0]:
65
                        sizeUnit = line_no_config.unit
66
                        break
67
            else:
68
                result = (False,)
69

    
70
            # check is tag no
71
            tag_no_configs = TagNoConfig.instance(tag=True)
72
            if tag_no_configs:
73
                for tag_no_config in tag_no_configs:
74
                    tagResult = tag_no_config.parse(text)
75
                    if tagResult[0]:
76
                        sizeUnit = tag_no_config.unit
77
                        break
78
            else:
79
                tagResult = (False,)
80

    
81
            if result[0]:
82
                item = QEngineeringLineNoTextItem()
83
                text = ''.join(result[1])
84
                for i in result[2]:
85
                    text = text[:i] + '\n' + text[i:]
86
                item.setPlainText(text)
87

    
88
                # get color option
89
                configs = docData.getConfigs('Line Color', 'Visible Option')
90
                if configs:
91
                    visibleOption = configs[0].value
92
                else:
93
                    visibleOption = 'Random'
94

    
95
                configs = docData.getConfigs('Color Property', 'State')
96
                if configs:
97
                    color_property = configs[0].value
98

    
99
                # set line no color
100
                if visibleOption == 'Random':
101
                    rgb = docData.colors
102
                    item.change_color(QColor(rgb.red, rgb.green, rgb.blue).name())
103
                    # item.setColor(QColor(rgb.red, rgb.green, rgb.blue).name())
104
                else:
105
                    configs = docData.getConfigs('Line No', 'Configuration')
106
                    configs = configs[0].value.split(self.delimiter)
107

    
108
                    values = result[1]
109
                    index = configs.index(color_property)
110
                    if index >= 0:
111
                        value = values[index]
112
                        line_properties = docData.getLinePropertiesByUID(color_property)
113
                        if line_properties[0].Attribute.replace(' ', '') == 'NominalDiameter':
114
                            if sizeUnit == "Inch":
115
                                value = docData.convertInchToMetric(value)
116

    
117
                        configs = docData.getConfigs(color_property, value)
118
                        if configs:
119
                            data = configs[0].value
120
                            rgb = data.split(',')
121
                            item.change_color(QColor(int(rgb[0]), int(rgb[1]), int(rgb[2])).name())
122
                    # up to here
123
                docData.tracerLineNos.append(item)
124
            elif tagResult[0]:
125
                item = QEngineeringTagNoTextItem()
126
                item.setToolTip('TAG NO = {}'.format(text))
127
                item.setPlainText(text)
128
            else:
129
                item = self.create_note_no_text(textInfo)
130
                sizeText = self.isSizeText(text, sizeDelimiter)
131
                if item:
132
                    pass
133
                elif self.is_reserved_word(text):
134
                    item = QEngineeringReservedWordTextItem()
135
                    item.setToolTip('Reserved Word = {}'.format(text))
136
                    item.setPlainText(text)
137
                elif sizeText:
138
                    item = QEngineeringSizeTextItem()
139
                    item.setToolTip('SIZE = {}'.format(sizeText))
140
                    item.setPlainText(sizeText)
141
                #elif self.isTagNoText(text):
142
                #    item = QEngineeringTagNoTextItem()
143
                #    item.setToolTip('TAG NO = {}'.format(text))
144
                #    item.setPlainText(text)
145
                elif self.is_valve_operation_code(text):
146
                    item = QEngineeringValveOperCodeTextItem()
147
                    item.setToolTip('Valve Operation Code = {}'.format(text))
148
                    item.setPlainText(text)
149
                else:
150
                    text = self.fix_dictionary_word(text)
151
                    item = QEngineeringTextItem()
152
                    item.setToolTip(text)
153
                    item.setPlainText(text)
154
                    item.special_item_type = SpecialItemTypes.instance().find_match_exactly(item)
155
                #docData.texts.append(item)
156
        except Exception as ex:
157
            from App import App
158
            from AppDocData import MessageType
159

    
160
            message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
161
                                                           sys.exc_info()[-1].tb_lineno)
162
            App.mainWnd().addMessage.emit(MessageType.Error, message)
163

    
164
        return item
165

    
166
    '''
167
        @brief      Check Text startwith word
168
        @author     kyouho
169
        @date       2018.07.04
170
    '''
171

    
172
    def isStartWithWord(self, text, word):
173
        sliceText = text[0:len(word[0])]
174
        if sliceText == word[0]:
175
            return (True, text[len(sliceText):len(text)], word[1])
176
        else:
177
            return (False,)
178

    
179
    '''
180
        @brief      Check Text startwith number
181
        @author     kyouho
182
        @date       2018.07.05
183
    '''
184

    
185
    def isStartWithNumber(self, text):
186
        sliceText = text[0:1]
187
        num = ''
188
        if self.isNumber(sliceText):
189
            text = text[1:len(text)]
190
            num += text
191
            while len(text) > 0:
192
                sliceText = text[0:1]
193

    
194
                if self.isNumber(sliceText):
195
                    text = text[1:len(text)]
196
                    num += text
197
                else:
198
                    break
199

    
200
            return (True, text, num)
201
        else:
202
            return (False,)
203

    
204
    '''
205
        @brief      Check Number
206
        @author     kyouho
207
        @date       2018.07.05
208
        @history    kyouho 2018.07.09   add Refular Expression
209
    '''
210

    
211
    def isNumber(self, num):
212
        p = re.compile('(^[0-9]+$)')
213
        result = p.match(num)
214

    
215
        if result:
216
            return True
217
        else:
218
            return False
219

    
220
    '''
221
        @brief      Check Number
222
        @author     kyouho
223
        @date       2018.07.05
224
    '''
225

    
226
    def isTagSeqNo(self, text, pattern):
227
        try:
228
            if pattern is not None:
229
                attr = text
230
                result = eval(pattern)
231
                if self.isNumber(result):
232
                    sliceText = text[0:len(result)]
233
                    return (True, text[len(sliceText):len(text)], sliceText)
234
                else:
235
                    return (False,)
236
            else:
237
                return (False,)
238
        except Exception as ex:
239
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
240
                                                       sys.exc_info()[-1].tb_lineno))
241

    
242
    '''
243
        @brief      Check Number
244
        @author     kyouho
245
        @date       2018.07.05
246
    '''
247

    
248
    def isLimitWord(self, text, pattern):
249
        try:
250
            if pattern is not None:
251
                attr = text
252
                length = pattern[0]
253
                isNumber = pattern[1]
254

    
255
                if length:  # Length가 있으면 Length만큼 문자열을 가져와 길이를 검사한다.
256
                    result = eval('attr[:' + str(length) + ']')
257
                    if int(length) != len(result):
258
                        return (False,)
259
                elif isNumber:
260
                    match = re.search(re.compile('^[0-9]+'), attr)
261
                    if match:
262
                        result = match.group(match.start())
263
                    else:
264
                        return (False,)
265
                else:
266
                    result = attr
267

    
268
                if isNumber:
269
                    if self.isNumber(result):
270
                        sliceText = text[0:len(result)]
271
                        return (True, text[len(sliceText):len(text)], sliceText)
272
                    else:
273
                        return (False,)
274
                else:
275
                    sliceText = text[0:len(result)]
276
                    return (True, text[len(sliceText):len(text)], sliceText)
277
            else:
278
                return (False,)
279
        except Exception as ex:
280
            print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
281
                                                       sys.exc_info()[-1].tb_lineno))
282

    
283
    '''
284
        @brief      Check if given text is Note No Text (ex : NOTE 1, NOTE 2, ...)
285
        @author     Jeongwoo
286
        @date       2018.04.26
287
        @history    2018.05.16  Jeongwoo    Modify Validator flag
288
    '''
289

    
290
    def create_note_no_text(self, textInfo):
291
        item = None
292

    
293
        appDocData = AppDocData.instance()
294
        configs = appDocData.getConfigs('Note No Tag Rule', 'Note No Expression')
295
        if 1 == len(configs) and configs[0].value:
296
            expression = configs[0].value
297
            match = re.search(re.compile(expression), textInfo.getText())
298

    
299
            if match:
300
                configs = appDocData.getConfigs('Note No Tag Rule', 'Note No Symbol Name')
301
                if 1 == len(configs) and configs[0].value:
302
                    symbol_names = configs[0].value.split(',')
303
                    for symbol in appDocData.symbols:
304
                        if symbol.name in symbol_names and symbol.includes(
305
                                textInfo.center) and '"' not in textInfo.getText():
306
                            item = QEngineeringNoteItem(symbol=symbol)
307
                            item.owner = symbol
308
                            symbol.add_assoc_item(item, 0)
309
                            break
310
                else:
311
                    item = QEngineeringNoteItem()
312

    
313
                if item:
314
                    item.setToolTip(textInfo.getText())
315
                    item.setPlainText(textInfo.getText())
316

    
317
        return item
318

    
319
    '''
320
        @brief  check if given text is size text
321
        @author humkyung
322
        @date   2018.05.02
323
    '''
324

    
325
    def isSizeText(self, text, delimiter='X'):
326
        from NominalPipeSize import NominalPipeSizeTable
327

    
328
        sizeUnit = None
329
        configs = AppDocData.instance().getConfigs('Project', 'Unit')
330
        sizeUnit = configs[0].value if 1 == len(configs) else None
331

    
332
        pipe_sizes = NominalPipeSizeTable.instance().pipe_sizes
333

    
334
        text = text.replace("'", '"').replace(' ', '').upper()
335

    
336
        first, second = None, None
337
        # for imperial
338
        if text.find('"') is not -1:
339
            first = text[:text.find('"') + 1]
340
            second = text[text.find('"') + 1:].replace(delimiter.upper(), '',
341
                                                       1).strip() if delimiter is not None else text[text.find(
342
                '"') + 1:].strip()
343
        # for metric
344
        else:
345
            split_text = text.strip().split(delimiter.upper())
346
            if len(split_text) > 2:
347
                return False
348
            first = split_text[0]
349
            second = split_text[1] if len(split_text) is 2 else None
350

    
351
        tokens = [first, second] if second is not None and len(second) is not 0 else [first]
352
        index = 0
353
        for token in tokens:
354
            matches = [(sizeData.find(token, sizeUnit) if sizeUnit else sizeData.find(token)) for sizeData in pipe_sizes
355
                       if (sizeData.find(token, sizeUnit) if sizeUnit else sizeData.find(token))]
356
            if matches:
357
                tokens[index] = matches[0]
358
            else:
359
                return False
360
            index += 1
361

    
362
        if len(tokens) == 2:
363
            if self.inch_to_number(tokens[0]) < self.inch_to_number(tokens[1]):
364
                tokens[0], tokens[1] = tokens[1], tokens[0]
365
        return delimiter.join(tokens)
366

    
367
    def inch_to_number(self, inch_str):
368
        inchs = inch_str.replace('"', '').split('-')
369
        number = 0
370
        for inch in inchs:
371
            if '/' not in inch:
372
                number += float(inch)
373
            else:
374
                fraction = inch.split('/')
375
                number += float(fraction[0]) / float(fraction[1])
376

    
377
        return number
378

    
379
    '''
380
        @brief  check if given text is tag no
381
        @author humkyung
382
        @date   2018.05.03
383
    '''
384

    
385
    def isTagNoText(self, text):
386
        from CodeTables import CodeTable
387

    
388
        found = CodeTable.instance('EqpTagNames').find_match_exactly(text)
389

    
390
        return True if found else False
391

    
392
    def is_valve_operation_code(self, text):
393
        """
394
        check if given text is valve operation code
395
        """
396
        from CodeTables import CodeTable
397

    
398
        found = CodeTable.instance('ValveOperCodes').find_match_exactly(text)
399

    
400
        return True if found else False
401

    
402
    def fix_dictionary_word(self, text):
403
        """ fix if given text is in dictionary """
404
        from CodeTables import CodeTable
405

    
406
        found = CodeTable.instance('Dictionary').find_match_exactly(text)
407

    
408
        return found if found else text
409

    
410
    def is_reserved_word(self, text):
411
        """ check if given text is reserved words """
412
        from CodeTables import CodeTable
413

    
414
        found = CodeTable.instance('ReservedWords').find_match_exactly(text)
415

    
416
        return True if found else False
클립보드 이미지 추가 (최대 크기: 500 MB)