개정판 1024ee16
issue 1221: hide template sheet
Change-Id: Ie57e16ffc6b3bd202cd879dfcd8d8fa8ff19daa0
DTI_PID/DTI_PID/AppDocData.py | ||
---|---|---|
18 | 18 |
from PyQt4.QtCore import * |
19 | 19 |
from PyQt4.QtGui import * |
20 | 20 |
|
21 |
from SingletonInstance import SingletonInstane |
|
21 |
from SingletonInstance import SingletonInstance
|
|
22 | 22 |
import symbol |
23 | 23 |
from NominalPipeSize import NominalPipeSize |
24 | 24 |
|
... | ... | |
64 | 64 |
Error = 2 |
65 | 65 |
|
66 | 66 |
|
67 |
class AppDocData(SingletonInstane): |
|
67 |
class AppDocData(SingletonInstance):
|
|
68 | 68 |
DATABASE = 'ITI_PID.db' |
69 | 69 |
|
70 | 70 |
def __init__(self): |
... | ... | |
975 | 975 |
if not hasattr(self, '_equipment_attributes'): |
976 | 976 |
self._equipment_attributes = [] |
977 | 977 |
|
978 |
conn = self.project.database.connect() |
|
979 |
with conn: |
|
978 |
with self.project.database.connect() as conn: |
|
980 | 979 |
try: |
981 | 980 |
# Get a cursor object |
982 | 981 |
cursor = conn.cursor() |
983 | 982 |
|
984 |
sql = "select distinct A.UID,A.Attribute from SymbolAttribute A join SymbolType B on A.SymbolType_UID=B.UID " \
|
|
985 |
"where B.Category = 'Equipment'" |
|
983 |
sql = "select distinct A.Attribute from SymbolAttribute A join SymbolType B on " \
|
|
984 |
"A.SymbolType_UID=B.UID where B.Category = 'Equipment'"
|
|
986 | 985 |
cursor.execute(sql) |
987 | 986 |
rows = cursor.fetchall() |
988 | 987 |
for row in rows: |
989 | 988 |
attr = SymbolAttr() |
990 |
attr.UID = row[0] |
|
991 |
attr.Attribute = row[1] |
|
989 |
attr.Attribute = row[0] |
|
992 | 990 |
self._equipment_attributes.append(attr) |
993 | 991 |
|
994 | 992 |
res = self._equipment_attributes |
995 | 993 |
# Catch the exception |
996 | 994 |
except Exception as ex: |
997 |
print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename,
|
|
995 |
print('error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename,
|
|
998 | 996 |
sys.exc_info()[-1].tb_lineno)) |
999 | 997 |
else: |
1000 | 998 |
res = self._equipment_attributes |
... | ... | |
2882 | 2880 |
|
2883 | 2881 |
result = [] |
2884 | 2882 |
|
2885 |
conn = self.project.database.connect() |
|
2886 |
with conn: |
|
2883 |
with self.project.database.connect() as conn: |
|
2887 | 2884 |
try: |
2888 | 2885 |
# Get a cursor object |
2889 | 2886 |
cursor = conn.cursor() |
... | ... | |
2900 | 2897 |
cursor.execute(sql) |
2901 | 2898 |
comps = [(row[0], row[1], row[2], row[3]) for row in cursor.fetchall()] |
2902 | 2899 |
for comp in comps: |
2903 |
sql = f"select B.Attribute,A.Value from Attributes A left join SymbolAttribute B on A.SymbolAttribute_UID=B.UID " \
|
|
2904 |
f"where A.Components_UID='{comp[0]}'" |
|
2900 |
sql = f"select distinct B.Attribute,A.Value from Attributes A left join SymbolAttribute B on " \
|
|
2901 |
f"A.SymbolAttribute_UID=B.UID where A.Components_UID='{comp[0]}'"
|
|
2905 | 2902 |
cursor.execute(sql) |
2906 | 2903 |
attrs = cursor.fetchall() |
2907 | 2904 |
data = [] |
DTI_PID/DTI_PID/DisplayColors.py | ||
---|---|---|
7 | 7 |
from enum import Enum |
8 | 8 |
from AppDocData import AppDocData |
9 | 9 |
from AppDocData import Config |
10 |
from SingletonInstance import SingletonInstane |
|
10 |
from SingletonInstance import SingletonInstance |
|
11 |
|
|
11 | 12 |
|
12 | 13 |
class DisplayOptions(Enum): |
13 | 14 |
""" This is display options class """ |
14 | 15 |
DisplayByLineNo = 1 |
15 | 16 |
DisplayByLineType = 2 |
16 | 17 |
|
17 |
class DisplayColors(SingletonInstane): |
|
18 |
|
|
19 |
class DisplayColors(SingletonInstance): |
|
18 | 20 |
""" |
19 | 21 |
This is display colors class |
20 | 22 |
""" |
... | ... | |
38 | 40 |
app_doc_data = AppDocData.instance() |
39 | 41 |
configs = app_doc_data.getAppConfigs('app', 'display_option') |
40 | 42 |
if configs: |
41 |
self.option = DisplayOptions.DisplayByLineNo if configs[0].value == str(DisplayOptions.DisplayByLineNo) else DisplayOptions.DisplayByLineType |
|
43 |
self.option = DisplayOptions.DisplayByLineNo if configs[0].value == str( |
|
44 |
DisplayOptions.DisplayByLineNo) else DisplayOptions.DisplayByLineType |
|
42 | 45 |
|
43 | 46 |
def save_data(self): |
44 | 47 |
""" save display option to database """ |
... | ... | |
47 | 50 |
configs.append(Config('app', 'display_option', str(self._option))) |
48 | 51 |
AppDocData.instance().saveAppConfigs(configs) |
49 | 52 |
except Exception as ex: |
50 |
from App import App
|
|
53 |
from App import App |
|
51 | 54 |
from AppDocData import MessageType |
52 | 55 |
|
53 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
|
54 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
|
56 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
|
57 |
sys.exc_info()[-1].tb_lineno) |
|
58 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
DTI_PID/DTI_PID/EqpDatasheetExportDialog.py | ||
---|---|---|
83 | 83 |
if matches: |
84 | 84 |
row[col].value = matches[0][1] |
85 | 85 |
|
86 |
# hide template sheet |
|
87 |
if equipments: |
|
88 |
sheet = book.get_sheet_by_name(f"{_type}(1)") |
|
89 |
if sheet: |
|
90 |
book.active = sheet |
|
91 |
book.get_sheet_by_name('Datasheet').sheet_state = 'hidden' |
|
92 |
# up to here |
|
93 |
|
|
86 | 94 |
options = QFileDialog.Options() |
87 | 95 |
options |= QFileDialog.DontUseNativeDialog |
88 | 96 |
file_name = QFileDialog.getSaveFileName(self, f"{_type} xlsx file", app_doc_data.project.path, |
89 |
"xlsx files(*.xlsx)", options=options) |
|
97 |
"xlsx files(*.xlsx)", options=options)
|
|
90 | 98 |
save_file_name = None |
91 | 99 |
if file_name[0]: |
92 | 100 |
file_name, ext = os.path.splitext(file_name[0]) |
DTI_PID/DTI_PID/HMBTable.py | ||
---|---|---|
3 | 3 |
import os |
4 | 4 |
import sys |
5 | 5 |
import sqlite3 |
6 |
from SingletonInstance import SingletonInstane |
|
6 |
from SingletonInstance import SingletonInstance
|
|
7 | 7 |
|
8 | 8 |
''' |
9 | 9 |
@brief HMB data |
DTI_PID/DTI_PID/ItemDataExportDialog.py | ||
---|---|---|
487 | 487 |
|
488 | 488 |
row += 1 |
489 | 489 |
|
490 |
''' |
|
491 |
@brief setting equip data |
|
492 |
@author kyouho |
|
493 |
@date 2018.08.14 |
|
494 |
''' |
|
495 |
|
|
496 | 490 |
def set_equipment_data(self): |
491 |
"""fill equipment data""" |
|
497 | 492 |
try: |
498 | 493 |
equipTable = self.ui.tableWidgetEquipmentDataList |
499 | 494 |
app_doc_data = AppDocData.instance() |
DTI_PID/DTI_PID/MainWindow.py | ||
---|---|---|
29 | 29 |
|
30 | 30 |
import MainWindow_UI |
31 | 31 |
import QtImageViewer |
32 |
from SingletonInstance import SingletonInstane |
|
32 |
from SingletonInstance import SingletonInstance
|
|
33 | 33 |
|
34 | 34 |
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Shapes') |
35 | 35 |
from EngineeringAbstractItem import QEngineeringAbstractItem |
... | ... | |
68 | 68 |
import uuid |
69 | 69 |
|
70 | 70 |
|
71 |
class MainWindow(QMainWindow, MainWindow_UI.Ui_MainWindow, SingletonInstane): |
|
71 |
class MainWindow(QMainWindow, MainWindow_UI.Ui_MainWindow, SingletonInstance):
|
|
72 | 72 |
""" This is MainWindow class """ |
73 | 73 |
addMessage = pyqtSignal(Enum, str) |
74 | 74 |
|
DTI_PID/DTI_PID/NominalPipeSize.py | ||
---|---|---|
1 | 1 |
# coding: utf-8 |
2 | 2 |
""" This is NominalPipeSize module """ |
3 | 3 |
|
4 |
from SingletonInstance import SingletonInstane |
|
4 |
from SingletonInstance import SingletonInstance
|
|
5 | 5 |
|
6 | 6 |
|
7 |
class NominalPipeSizeTable(SingletonInstane): |
|
7 |
class NominalPipeSizeTable(SingletonInstance):
|
|
8 | 8 |
""" This is nominal pipe size table class """ |
9 | 9 |
|
10 | 10 |
def __init__(self): |
DTI_PID/DTI_PID/QtImageViewerScene.py | ||
---|---|---|
3 | 3 |
|
4 | 4 |
import sys |
5 | 5 |
import os.path |
6 |
from SingletonInstance import SingletonInstance |
|
7 |
|
|
6 | 8 |
try: |
7 | 9 |
from PyQt5.QtCore import * |
8 | 10 |
from PyQt5.QtGui import * |
... | ... | |
13 | 15 |
from PyQt4.QtGui import * |
14 | 16 |
except ImportError: |
15 | 17 |
raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.") |
16 |
|
|
18 |
|
|
17 | 19 |
__author__ = "humkyung <humkyung.doftech.co.kr>" |
18 | 20 |
__version__ = '1.0.0' |
19 | 21 |
|
20 | 22 |
|
21 |
class QtImageViewerScene(QGraphicsScene): |
|
23 |
class QtImageViewerScene(QGraphicsScene, SingletonInstance):
|
|
22 | 24 |
""" This is image viewer scene class """ |
23 | 25 |
contents_changed = pyqtSignal() |
24 | 26 |
|
... | ... | |
34 | 36 |
def removeItem(self, item): |
35 | 37 |
""" remove given item from scene """ |
36 | 38 |
QGraphicsScene.removeItem(self, item) |
37 |
self.contents_changed.emit() |
|
39 |
self.contents_changed.emit() |
DTI_PID/DTI_PID/SingletonInstance.py | ||
---|---|---|
1 | 1 |
# coding: utf-8 |
2 | 2 |
|
3 |
class SingletonInstane: |
|
3 |
class SingletonInstance:
|
|
4 | 4 |
__instance = None |
5 | 5 |
|
6 | 6 |
@classmethod |
... | ... | |
12 | 12 |
if not cls.__instance: |
13 | 13 |
cls.__instance = cls(*args, **kargs) |
14 | 14 |
cls.instance = cls.__getInstance |
15 |
return cls.__instance |
|
15 |
return cls.__instance |
DTI_PID/DTI_PID/TextItemFactory.py | ||
---|---|---|
1 | 1 |
# coding: utf-8 |
2 | 2 |
""" This is TextItemFactor module """ |
3 | 3 |
|
4 |
from SingletonInstance import SingletonInstane |
|
4 |
from SingletonInstance import SingletonInstance
|
|
5 | 5 |
import re |
6 |
|
|
6 | 7 |
try: |
7 | 8 |
from PyQt5.QtCore import * |
8 | 9 |
from PyQt5.QtGui import * |
... | ... | |
15 | 16 |
raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.") |
16 | 17 |
from AppDocData import * |
17 | 18 |
import sys, os |
19 |
|
|
18 | 20 |
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Shapes') |
19 | 21 |
from EngineeringTextItem import QEngineeringTextItem |
20 | 22 |
from EngineeringLineNoTextItem import QEngineeringLineNoTextItem |
... | ... | |
25 | 27 |
from EngineeringReservedWordTextItem import QEngineeringReservedWordTextItem |
26 | 28 |
from SpecialItemTypesDialog import SpecialItemTypes |
27 | 29 |
|
28 |
class TextItemFactory(SingletonInstane): |
|
30 |
|
|
31 |
class TextItemFactory(SingletonInstance): |
|
29 | 32 |
""" This is TextItemFactor class """ |
33 |
|
|
30 | 34 |
def __init__(self): |
31 | 35 |
self.delimiter = '"' |
32 | 36 |
self.lineNoDelimiter = '!-!' |
... | ... | |
38 | 42 |
kyouho 2018.07.04 edit for isLineNo method (add parameter) |
39 | 43 |
humkyung 2018.08.08 fill linePropertyData and tagSeqNoPattern if given data is None |
40 | 44 |
euisung 2018.11.19 now textitemfactory set plain text in createTextItem() for allowables |
41 |
''' |
|
45 |
''' |
|
46 |
|
|
42 | 47 |
def createTextItem(self, textInfo): |
43 | 48 |
from Configs import LineNoConfig |
44 | 49 |
|
... | ... | |
92 | 97 |
if visibleOption == 'Random': |
93 | 98 |
rgb = docData.colors |
94 | 99 |
item.change_color(QColor(rgb.red, rgb.green, rgb.blue).name()) |
95 |
#item.setColor(QColor(rgb.red, rgb.green, rgb.blue).name()) |
|
100 |
# item.setColor(QColor(rgb.red, rgb.green, rgb.blue).name())
|
|
96 | 101 |
else: |
97 | 102 |
configs = docData.getConfigs('Line No', 'Configuration') |
98 | 103 |
configs = configs[0].value.split(self.delimiter) |
... | ... | |
102 | 107 |
if index >= 0: |
103 | 108 |
value = values[index] |
104 | 109 |
line_properties = docData.getLinePropertiesByUID(color_property) |
105 |
if line_properties[0].Attribute.replace(' ','') == 'NominalDiameter': |
|
110 |
if line_properties[0].Attribute.replace(' ', '') == 'NominalDiameter':
|
|
106 | 111 |
if sizeUnit == "Inch": |
107 | 112 |
value = docData.convertInchToMetric(value) |
108 | 113 |
|
... | ... | |
142 | 147 |
item.special_item_type = SpecialItemTypes.instance().find_match_exactly(item) |
143 | 148 |
docData.texts.append(item) |
144 | 149 |
except Exception as ex: |
145 |
from App import App
|
|
150 |
from App import App |
|
146 | 151 |
from AppDocData import MessageType |
147 | 152 |
|
148 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
|
153 |
message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
|
154 |
sys.exc_info()[-1].tb_lineno) |
|
149 | 155 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
150 | 156 |
|
151 | 157 |
return item |
152 |
|
|
158 |
|
|
153 | 159 |
''' |
154 | 160 |
@brief Check Text startwith word |
155 | 161 |
@author kyouho |
156 | 162 |
@date 2018.07.04 |
157 | 163 |
''' |
164 |
|
|
158 | 165 |
def isStartWithWord(self, text, word): |
159 | 166 |
sliceText = text[0:len(word[0])] |
160 | 167 |
if sliceText == word[0]: |
... | ... | |
162 | 169 |
else: |
163 | 170 |
return (False,) |
164 | 171 |
|
165 |
|
|
166 | 172 |
''' |
167 | 173 |
@brief Check Text startwith number |
168 | 174 |
@author kyouho |
169 | 175 |
@date 2018.07.05 |
170 | 176 |
''' |
177 |
|
|
171 | 178 |
def isStartWithNumber(self, text): |
172 | 179 |
sliceText = text[0:1] |
173 | 180 |
num = '' |
174 | 181 |
if self.isNumber(sliceText): |
175 | 182 |
text = text[1:len(text)] |
176 |
num += text
|
|
183 |
num += text |
|
177 | 184 |
while len(text) > 0: |
178 | 185 |
sliceText = text[0:1] |
179 |
|
|
186 |
|
|
180 | 187 |
if self.isNumber(sliceText): |
181 | 188 |
text = text[1:len(text)] |
182 | 189 |
num += text |
183 | 190 |
else: |
184 | 191 |
break |
185 |
|
|
192 |
|
|
186 | 193 |
return (True, text, num) |
187 | 194 |
else: |
188 | 195 |
return (False,) |
... | ... | |
193 | 200 |
@date 2018.07.05 |
194 | 201 |
@history kyouho 2018.07.09 add Refular Expression |
195 | 202 |
''' |
203 |
|
|
196 | 204 |
def isNumber(self, num): |
197 | 205 |
p = re.compile('(^[0-9]+$)') |
198 | 206 |
result = p.match(num) |
... | ... | |
207 | 215 |
@author kyouho |
208 | 216 |
@date 2018.07.05 |
209 | 217 |
''' |
218 |
|
|
210 | 219 |
def isTagSeqNo(self, text, pattern): |
211 | 220 |
try: |
212 | 221 |
if pattern is not None: |
... | ... | |
220 | 229 |
else: |
221 | 230 |
return (False,) |
222 | 231 |
except Exception as ex: |
223 |
print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
224 |
|
|
232 |
print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
|
233 |
sys.exc_info()[-1].tb_lineno)) |
|
234 |
|
|
225 | 235 |
''' |
226 | 236 |
@brief Check Number |
227 | 237 |
@author kyouho |
228 | 238 |
@date 2018.07.05 |
229 | 239 |
''' |
240 |
|
|
230 | 241 |
def isLimitWord(self, text, pattern): |
231 | 242 |
try: |
232 | 243 |
if pattern is not None: |
... | ... | |
237 | 248 |
if length: # Length가 있으면 Length만큼 문자열을 가져와 길이를 검사한다. |
238 | 249 |
result = eval('attr[:' + str(length) + ']') |
239 | 250 |
if int(length) != len(result): |
240 |
return(False,) |
|
251 |
return (False,)
|
|
241 | 252 |
elif isNumber: |
242 | 253 |
match = re.search(re.compile('^[0-9]+'), attr) |
243 | 254 |
if match: |
244 |
result = match.group(match.start())
|
|
255 |
result = match.group(match.start()) |
|
245 | 256 |
else: |
246 | 257 |
return (False,) |
247 | 258 |
else: |
... | ... | |
259 | 270 |
else: |
260 | 271 |
return (False,) |
261 | 272 |
except Exception as ex: |
262 |
print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
273 |
print('error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
|
274 |
sys.exc_info()[-1].tb_lineno)) |
|
263 | 275 |
|
264 | 276 |
''' |
265 | 277 |
@brief Check if given text is Note No Text (ex : NOTE 1, NOTE 2, ...) |
... | ... | |
267 | 279 |
@date 2018.04.26 |
268 | 280 |
@history 2018.05.16 Jeongwoo Modify Validator flag |
269 | 281 |
''' |
282 |
|
|
270 | 283 |
def create_note_no_text(self, textInfo): |
271 | 284 |
item = None |
272 | 285 |
|
... | ... | |
281 | 294 |
if 1 == len(configs) and configs[0].value: |
282 | 295 |
symbol_names = configs[0].value.split(',') |
283 | 296 |
for symbol in appDocData.symbols: |
284 |
if symbol.name in symbol_names and symbol.includes(textInfo.center) and '"' not in textInfo.getText(): |
|
297 |
if symbol.name in symbol_names and symbol.includes( |
|
298 |
textInfo.center) and '"' not in textInfo.getText(): |
|
285 | 299 |
item = QEngineeringNoteItem(symbol=symbol) |
286 | 300 |
item.owner = symbol |
287 | 301 |
symbol.add_assoc_item(item, 0) |
... | ... | |
300 | 314 |
@author humkyung |
301 | 315 |
@date 2018.05.02 |
302 | 316 |
''' |
317 |
|
|
303 | 318 |
def isSizeText(self, text, delimiter='X'): |
304 | 319 |
from NominalPipeSize import NominalPipeSizeTable |
305 | 320 |
|
... | ... | |
315 | 330 |
# for imperial |
316 | 331 |
if text.find('"') is not -1: |
317 | 332 |
first = text[:text.find('"') + 1] |
318 |
second = text[text.find('"') + 1:].replace(delimiter.upper(), '', 1).strip() if delimiter is not None else text[text.find('"') + 1:].strip() |
|
333 |
second = text[text.find('"') + 1:].replace(delimiter.upper(), '', |
|
334 |
1).strip() if delimiter is not None else text[text.find( |
|
335 |
'"') + 1:].strip() |
|
319 | 336 |
# for metric |
320 | 337 |
else: |
321 | 338 |
split_text = text.strip().split(delimiter.upper()) |
... | ... | |
327 | 344 |
tokens = [first, second] if second is not None and len(second) is not 0 else [first] |
328 | 345 |
index = 0 |
329 | 346 |
for token in tokens: |
330 |
matches = [(sizeData.find(token, sizeUnit) if sizeUnit else sizeData.find(token)) for sizeData in pipe_sizes if (sizeData.find(token, sizeUnit) if sizeUnit else sizeData.find(token))] |
|
347 |
matches = [(sizeData.find(token, sizeUnit) if sizeUnit else sizeData.find(token)) for sizeData in pipe_sizes |
|
348 |
if (sizeData.find(token, sizeUnit) if sizeUnit else sizeData.find(token))] |
|
331 | 349 |
if matches: |
332 | 350 |
tokens[index] = matches[0] |
333 | 351 |
else: |
334 | 352 |
return False |
335 | 353 |
index += 1 |
336 |
|
|
354 |
|
|
337 | 355 |
return delimiter.join(tokens) |
338 |
|
|
356 |
|
|
339 | 357 |
''' |
340 | 358 |
@brief check if given text is tag no |
341 | 359 |
@author humkyung |
342 | 360 |
@date 2018.05.03 |
343 | 361 |
''' |
362 |
|
|
344 | 363 |
def isTagNoText(self, text): |
345 | 364 |
from CodeTables import CodeTable |
346 | 365 |
|
내보내기 Unified diff