hytos / DTI_PID / DTI_PID / SymbolTreeWidget.py @ db2dcb47
이력 | 보기 | 이력해설 | 다운로드 (14.9 KB)
1 | d0db0878 | humkyung | # coding: utf-8
|
---|---|---|---|
2 | """ This is Symbol Tree Widget module """
|
||
3 | |||
4 | d52b3462 | 김정우 | try:
|
5 | from PyQt5.QtCore import * |
||
6 | from PyQt5.QtGui import * |
||
7 | from PyQt5.QtWidgets import * |
||
8 | except ImportError: |
||
9 | try:
|
||
10 | from PyQt4.QtCore import * |
||
11 | from PyQt4.QtGui import * |
||
12 | except ImportError: |
||
13 | raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.") |
||
14 | 6a2a7457 | humkyung | from AppDocData import * |
15 | d52b3462 | 김정우 | import os |
16 | 4f0ae2af | humkyung | import sys |
17 | 936111d1 | 김정우 | import SymbolBase |
18 | import symbol |
||
19 | dc05dcb9 | humkyung | import SymbolEditorDialog |
20 | 8df40630 | 김정우 | import QSymbolDisplayDialog |
21 | d52b3462 | 김정우 | |
22 | b1a510c6 | humkyung | |
23 | b929957d | humkyung | class QSymbolTreeWidget(QTreeWidget): |
24 | b1a510c6 | humkyung | # Add signal
|
25 | 936111d1 | 김정우 | singleClicked = pyqtSignal(SymbolBase.SymbolBase) |
26 | b929957d | humkyung | TREE_DATA_ROLE = Qt.UserRole |
27 | 936111d1 | 김정우 | |
28 | d52b3462 | 김정우 | def __init__(self): |
29 | QTreeWidget.__init__(self)
|
||
30 | b1a510c6 | humkyung | self.setIconSize(QSize(32, 32)) |
31 | |||
32 | self.setDragEnabled(True) # enable drag |
||
33 | d52b3462 | 김정우 | self.initDirTreeWidget()
|
34 | 936111d1 | 김정우 | self.isDoubleClicked = False |
35 | d52b3462 | 김정우 | self.itemDoubleClicked.connect(self.itemDoubleClickEvent) |
36 | e85bb909 | 김정우 | self.setContextMenuPolicy(Qt.CustomContextMenu)
|
37 | self.customContextMenuRequested.connect(self.openContextMenu) |
||
38 | b929957d | humkyung | self.currentItemChanged.connect(self.onCurrentItemChanged) |
39 | b1a510c6 | humkyung | |
40 | 2894ed79 | 김정우 | '''
|
41 | @brief Show Context Menu
|
||
42 | @author Jeongwoo
|
||
43 | @date 18.04.??
|
||
44 | 6a2a7457 | humkyung | @history Jeongwoo 2018.04.23 Symbol object Null Check when show context menu
|
45 | humkyung 2018.08.14 add menu for symbol type
|
||
46 | 2894ed79 | 김정우 | '''
|
47 | b1a510c6 | humkyung | |
48 | e85bb909 | 김정우 | def openContextMenu(self, position): |
49 | indexes = self.selectedIndexes()
|
||
50 | itemPosition = self.mapTo(self, position) |
||
51 | item = self.itemAt(itemPosition)
|
||
52 | 6a2a7457 | humkyung | data = item.data(0, self.TREE_DATA_ROLE) |
53 | 8701ed58 | esham21 | |
54 | advanced = False
|
||
55 | app_doc_data = AppDocData.instance() |
||
56 | configs = app_doc_data.getAppConfigs('app', 'mode') |
||
57 | if configs and 1 == len(configs) and 'advanced' == configs[0].value: |
||
58 | advanced = True
|
||
59 | |||
60 | b0034990 | humkyung | if data is not None and type(data) is symbol.SymbolBase: |
61 | 6a2a7457 | humkyung | sym = self.getSymbolByItemName(item, 0) |
62 | text = item.text(0)
|
||
63 | if len(indexes) > 0: |
||
64 | level = 0
|
||
65 | index = indexes[0]
|
||
66 | while index.parent().isValid():
|
||
67 | index = index.parent() |
||
68 | level += 1
|
||
69 | if sym is not None: |
||
70 | menu = QMenu() |
||
71 | 8701ed58 | esham21 | if advanced:
|
72 | editSymbolAction = QAction(self.tr("Edit Symbol")) |
||
73 | editSymbolAction.triggered.connect(lambda: self.editSymbolActionClickEvent(item, 0)) |
||
74 | menu.addAction(editSymbolAction) |
||
75 | 02519509 | humkyung | editDisplaySymbolAction = QAction(self.tr("Edit Symbol for Display")) |
76 | 8701ed58 | esham21 | editDisplaySymbolAction.triggered.connect(lambda: self.editDisplaySymbolActionClickEvent(item, 0)) |
77 | menu.addAction(editDisplaySymbolAction) |
||
78 | 6a2a7457 | humkyung | displaySymbolAction = QAction(self.tr("Display Symbol")) |
79 | 61a7cd2d | esham21 | displaySymbolAction.triggered.connect(lambda: self.displaySymbolActionClickEvent(item, 0)) |
80 | 6a2a7457 | humkyung | menu.addAction(displaySymbolAction) |
81 | 8701ed58 | esham21 | if advanced:
|
82 | deleteSymbolAction = QAction(self.tr("Delete Symbol")) |
||
83 | deleteSymbolAction.triggered.connect(lambda: self.deleteSymbolActionClickEvent(sym.getType(), text)) |
||
84 | menu.addAction(deleteSymbolAction) |
||
85 | 6a2a7457 | humkyung | menu.exec_(self.viewport().mapToGlobal(position))
|
86 | else:
|
||
87 | 8701ed58 | esham21 | if advanced:
|
88 | menu = QMenu() |
||
89 | editAttrAction = QAction(self.tr("Edit Attribute")) |
||
90 | editAttrAction.triggered.connect(lambda: self.onEditAttrClicked(item, 0)) |
||
91 | menu.addAction(editAttrAction) |
||
92 | menu.exec_(self.viewport().mapToGlobal(position))
|
||
93 | e85bb909 | 김정우 | |
94 | def editSymbolActionClickEvent(self, item, columNo): |
||
95 | self.showSymbolEditorDialog(item, columNo)
|
||
96 | |||
97 | 61a7cd2d | esham21 | def editDisplaySymbolActionClickEvent(self, item, columNo): |
98 | self.showSymbolEditorDialog(item, columNo, True) |
||
99 | |||
100 | 6a2a7457 | humkyung | '''
|
101 | @brief popup attribute editor dialog
|
||
102 | @author humkyung
|
||
103 | @date 2018.08.13
|
||
104 | '''
|
||
105 | b1a510c6 | humkyung | |
106 | 6a2a7457 | humkyung | def onEditAttrClicked(self, item, columnNo): |
107 | b0034990 | humkyung | from SymbolAttrEditorDialog import QSymbolAttrEditorDialog |
108 | 6a2a7457 | humkyung | |
109 | try:
|
||
110 | b1a510c6 | humkyung | data = item.data(0, self.TREE_DATA_ROLE) |
111 | b0034990 | humkyung | |
112 | b1a510c6 | humkyung | dlg = QSymbolAttrEditorDialog(self, data)
|
113 | e89f871b | esham21 | dlg.show() |
114 | b1a510c6 | humkyung | dlg.exec_() |
115 | 6a2a7457 | humkyung | except Exception as ex: |
116 | from App import App |
||
117 | |||
118 | b1a510c6 | humkyung | message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
119 | sys.exc_info()[-1].tb_lineno)
|
||
120 | 6a2a7457 | humkyung | App.mainWnd().addMessage.emit(MessageType.Error, message) |
121 | |||
122 | 61a7cd2d | esham21 | def displaySymbolActionClickEvent(self, item, columnNo): |
123 | # project = AppDocData.instance().getCurrentProject()
|
||
124 | # image = QImage(os.path.join(project.getImageFilePath(), itemType, itemName, "PNG")) #itemName includes ".png"
|
||
125 | try:
|
||
126 | sym = self.getSymbolByItemName(item, columnNo)
|
||
127 | if sym is not None: |
||
128 | bceea84f | esham21 | # origin symbol image
|
129 | 61a7cd2d | esham21 | path = sym.getPath() |
130 | image = QImage(path, "PNG")
|
||
131 | bceea84f | esham21 | # symbol image for display
|
132 | path = os.path.splitext(path) |
||
133 | path = path[0] + '_display' + path[1] |
||
134 | image2 = QImage(path, "PNG") if os.path.exists(path) else None |
||
135 | dialog = QSymbolDisplayDialog.QSymbolDisplayDialog(image, image2) |
||
136 | 61a7cd2d | esham21 | dialog.showDialog() |
137 | else:
|
||
138 | QMessageBox.about(self, self.tr('Error'), self.tr('Error occurs during loading symbol data.')) |
||
139 | except Exception as ex: |
||
140 | from App import App |
||
141 | from AppDocData import MessageType |
||
142 | |||
143 | b1a510c6 | humkyung | message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
144 | sys.exc_info()[-1].tb_lineno)
|
||
145 | 61a7cd2d | esham21 | App.mainWnd().addMessage.emit(MessageType.Error, message) |
146 | e85bb909 | 김정우 | |
147 | cb51acb2 | 김정우 | def deleteSymbolActionClickEvent(self, itemType, itemName): |
148 | 100ba941 | 김정우 | msg = QMessageBox() |
149 | msg.setIcon(QMessageBox.Critical) |
||
150 | d88d6f39 | esham21 | msg.setText(self.tr('Are you sure you want to delete selected symbol?\nData can not be restored!')) |
151 | msg.setWindowTitle(self.tr('Delete symbol')) |
||
152 | b1a510c6 | humkyung | msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) |
153 | 100ba941 | 김정우 | result = msg.exec_() |
154 | cb51acb2 | 김정우 | self.handleDeleteSymbolAction(result, itemType, itemName)
|
155 | 100ba941 | 김정우 | |
156 | d9cbc4d3 | 김정우 | '''
|
157 | @history 2018.05.03 Jeongwoo Modify file path with ".png" and ".svg"
|
||
158 | Use project object when making svgPath
|
||
159 | '''
|
||
160 | b1a510c6 | humkyung | |
161 | cb51acb2 | 김정우 | def handleDeleteSymbolAction(self, result, itemType, itemName): |
162 | 100ba941 | 김정우 | if result == QMessageBox.Ok:
|
163 | project = AppDocData.instance().getCurrentProject() |
||
164 | b1a510c6 | humkyung | imagePath = os.path.join(project.getImageFilePath(), itemType, |
165 | itemName + '.png') # itemName DOESN'T includes ".png" |
||
166 | 100ba941 | 김정우 | if os.path.exists(imagePath):
|
167 | os.remove(imagePath) |
||
168 | |||
169 | 25e0cacb | Gyusu | svgPath = os.path.join(project.getSvgFilePath(), itemType, itemName + '.svg')
|
170 | 100ba941 | 김정우 | if os.path.exists(svgPath):
|
171 | os.remove(svgPath) |
||
172 | |||
173 | d9cbc4d3 | 김정우 | AppDocData.instance().deleteSymbol(itemName) |
174 | bcdd2a76 | 김정우 | self.initDirTreeWidget()
|
175 | 100ba941 | 김정우 | else:
|
176 | pass
|
||
177 | 000faa4d | 김정우 | |
178 | 3828d206 | 김정우 | '''
|
179 | @history 2018.05.02 Jeongwoo Change return value of QSymbolEditorDialog (Single variable → Tuple)
|
||
180 | '''
|
||
181 | b1a510c6 | humkyung | |
182 | 000faa4d | 김정우 | def initDirTreeWidget(self): |
183 | project = AppDocData.instance().getCurrentProject() |
||
184 | if project is not None: |
||
185 | d52b3462 | 김정우 | self.clear()
|
186 | 000faa4d | 김정우 | projectPath = project.getPath().replace("\\", "/") |
187 | cb51acb2 | 김정우 | self.makeChildDir()
|
188 | b1a510c6 | humkyung | self.load_symbol_info()
|
189 | cb51acb2 | 김정우 | self.expandAll()
|
190 | d52b3462 | 김정우 | |
191 | ed2b4ab0 | 김정우 | '''
|
192 | @brief Load Symbol Info and add TreeItem with DB
|
||
193 | @author Jeongwoo
|
||
194 | @date 18.04.20
|
||
195 | 65f1308c | humkyung | @history Jeongwoo 2018.05.03 Get Svg File Path by SymbolBase.getSvgFileFullPath()
|
196 | humkyung 2018.07.30 sort child items
|
||
197 | ed2b4ab0 | 김정우 | '''
|
198 | b1a510c6 | humkyung | |
199 | def load_symbol_info(self): |
||
200 | b0034990 | humkyung | try:
|
201 | b1a510c6 | humkyung | app_doc_data = AppDocData.instance() |
202 | |||
203 | 02519509 | humkyung | symbolTypeList = app_doc_data.getSymbolTypeList() |
204 | b0034990 | humkyung | for symbolType in symbolTypeList: |
205 | d0db0878 | humkyung | if not symbolType[1]: continue # skip if category is empty |
206 | b0034990 | humkyung | parent = QTreeWidgetItem(self, [symbolType[2]]) |
207 | parent.setData(0, self.TREE_DATA_ROLE, symbolType) |
||
208 | 02519509 | humkyung | symbolList = app_doc_data.getSymbolListByType('UID', symbolType[0]) |
209 | b0034990 | humkyung | for symbol in symbolList: |
210 | symbolItem = QTreeWidgetItem(parent, [symbol.getName()]) |
||
211 | symbolItem.setData(0, self.TREE_DATA_ROLE, symbol) |
||
212 | b1a510c6 | humkyung | |
213 | _, svg = app_doc_data.read_symbol_shape(symbol.sName) |
||
214 | if svg:
|
||
215 | db2dcb47 | humkyung | symbol.pixmap = QPixmap() |
216 | a1723c66 | humkyung | symbol.pixmap.loadFromData(svg if isinstance(svg, bytes) else svg.encode()) |
217 | icon = QIcon(symbol.pixmap) |
||
218 | b1a510c6 | humkyung | symbolItem.setIcon(0, icon)
|
219 | symbolItem.svgFilePath = None # save svg file path |
||
220 | else:
|
||
221 | svgPath = symbol.getSvgFileFullPath() |
||
222 | db2dcb47 | humkyung | symbol.pixmap = QPixmap(svgPath) |
223 | icon = QIcon(symbol.pixmap) |
||
224 | b1a510c6 | humkyung | symbolItem.setIcon(0, icon)
|
225 | symbolItem.svgFilePath = svgPath # save svg file path
|
||
226 | ed2b4ab0 | 김정우 | |
227 | b0034990 | humkyung | parent.sortChildren(0, Qt.AscendingOrder)
|
228 | except Exception as ex: |
||
229 | from App import App |
||
230 | |||
231 | b1a510c6 | humkyung | message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename, |
232 | sys.exc_info()[-1].tb_lineno)
|
||
233 | b0034990 | humkyung | App.mainWnd().addMessage.emit(MessageType.Error, message) |
234 | cdbc7e7f | 김정우 | |
235 | 9b09db27 | 김정우 | '''
|
236 | @brief Make Directory
|
||
237 | @author Jeongwoo
|
||
238 | @date 18.04.??
|
||
239 | @history 18.04.12 Jeongwoo Add output, temp Directory
|
||
240 | '''
|
||
241 | b1a510c6 | humkyung | |
242 | cb51acb2 | 김정우 | def makeChildDir(self): |
243 | project = AppDocData.instance().getCurrentProject() |
||
244 | dbDir = project.getDbFilePath() |
||
245 | d52b3462 | 김정우 | if not os.path.exists(dbDir): |
246 | os.makedirs(dbDir) |
||
247 | cb51acb2 | 김정우 | imgDir = project.getImageFilePath() |
248 | d52b3462 | 김정우 | if not os.path.exists(imgDir): |
249 | os.makedirs(imgDir) |
||
250 | cb51acb2 | 김정우 | svgDir = project.getSvgFilePath() |
251 | d52b3462 | 김정우 | if not os.path.exists(svgDir): |
252 | os.makedirs(svgDir) |
||
253 | 9b09db27 | 김정우 | outputDir = project.getOutputPath() |
254 | if not os.path.exists(outputDir): |
||
255 | os.makedirs(outputDir) |
||
256 | tempDir = project.getTempPath() |
||
257 | if not os.path.exists(tempDir): |
||
258 | os.makedirs(tempDir) |
||
259 | d52b3462 | 김정우 | |
260 | b1a510c6 | humkyung | def showSymbolEditorDialog(self, item, columnNo, display=False): |
261 | e2ae85c2 | humkyung | """pop up symbol editor dialog"""
|
262 | |||
263 | 4f0ae2af | humkyung | try:
|
264 | sym = self.getSymbolByItemName(item, columnNo)
|
||
265 | 61a7cd2d | esham21 | if sym and display: |
266 | # for symbol image for display
|
||
267 | path = os.path.splitext(sym.getPath()) |
||
268 | path = path[0] + '_display' + path[1] |
||
269 | if os.path.exists(path):
|
||
270 | image = QImage(path, "PNG")
|
||
271 | else:
|
||
272 | path = sym.getPath() |
||
273 | image = QImage(path, "PNG")
|
||
274 | b1a510c6 | humkyung | symbolEditorDialog = SymbolEditorDialog.QSymbolEditorDialog(self, image,
|
275 | AppDocData.instance().getCurrentProject(), |
||
276 | sym, True)
|
||
277 | 61a7cd2d | esham21 | (isAccepted, isImmediateInsert, offsetX, offsetY, newSym) = symbolEditorDialog.showDialog() |
278 | self.initDirTreeWidget()
|
||
279 | elif sym:
|
||
280 | # for symbol data and detection image
|
||
281 | 4f0ae2af | humkyung | path = sym.getPath() |
282 | image = QImage(path, "PNG")
|
||
283 | b1a510c6 | humkyung | symbolEditorDialog = SymbolEditorDialog.QSymbolEditorDialog(self, image,
|
284 | AppDocData.instance().getCurrentProject(), |
||
285 | sym, False)
|
||
286 | 3828d206 | 김정우 | (isAccepted, isImmediateInsert, offsetX, offsetY, newSym) = symbolEditorDialog.showDialog() |
287 | 4f0ae2af | humkyung | self.initDirTreeWidget()
|
288 | else:
|
||
289 | d88d6f39 | esham21 | QMessageBox.about(self, self.tr('Error'), self.tr('Error occurs during loading symbol data.')) |
290 | 4f0ae2af | humkyung | except Exception as ex: |
291 | b0034990 | humkyung | from App import App |
292 | 61a7cd2d | esham21 | from AppDocData import MessageType |
293 | 3926c898 | 김정우 | |
294 | b1a510c6 | humkyung | message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
295 | sys.exc_info()[-1].tb_lineno)
|
||
296 | b0034990 | humkyung | App.mainWnd().addMessage.emit(MessageType.Error, message) |
297 | e85bb909 | 김정우 | |
298 | e2ae85c2 | humkyung | def select_symbol(self, symbol): |
299 | """select a tree with given symbol"""
|
||
300 | |||
301 | founds = self.findItems(symbol.name, Qt.MatchExactly | Qt.MatchRecursive, 0) |
||
302 | if founds:
|
||
303 | self.setCurrentItem(founds[0]) |
||
304 | |||
305 | e85bb909 | 김정우 | def itemDoubleClickEvent(self, item, columnNo): |
306 | self.isDoubleClicked = True |
||
307 | 2894ed79 | 김정우 | sym = self.getSymbolByItemName(item, columnNo)
|
308 | e85bb909 | 김정우 | itemName = item.text(columnNo) |
309 | 2894ed79 | 김정우 | if sym is not None: |
310 | self.showSymbolEditorDialog(item, columnNo)
|
||
311 | 936111d1 | 김정우 | self.isDoubleClicked = False |
312 | d52b3462 | 김정우 | |
313 | b580f6e4 | 김정우 | '''
|
314 | ed2b4ab0 | 김정우 | @brief Get Symbol data by symbol name
|
315 | @author Jeongwoo
|
||
316 | @date 18.04.20
|
||
317 | '''
|
||
318 | b1a510c6 | humkyung | |
319 | 936111d1 | 김정우 | def getSymbolByItemName(self, item, columnNo): |
320 | d52b3462 | 김정우 | itemName = item.text(columnNo) |
321 | 65f1308c | humkyung | |
322 | ed2b4ab0 | 김정우 | name = itemName |
323 | sym = AppDocData.instance().getSymbolByQuery("name", name)
|
||
324 | return sym
|
||
325 | b192a44e | humkyung | |
326 | '''
|
||
327 | b929957d | humkyung | @breif show symbol's property when selection changed
|
328 | @author humkyung
|
||
329 | @date 2018.07.30
|
||
330 | '''
|
||
331 | b1a510c6 | humkyung | |
332 | b929957d | humkyung | def onCurrentItemChanged(self, current, previous): |
333 | item = self.currentItem()
|
||
334 | if item is not None: |
||
335 | data = item.data(0, self.TREE_DATA_ROLE) |
||
336 | b0034990 | humkyung | if data is not None and type(data) is symbol.SymbolBase: |
337 | b929957d | humkyung | self.singleClicked.emit(data)
|
338 | |||
339 | b192a44e | humkyung | def startDrag(self, dropAction): |
340 | db2dcb47 | humkyung | """start drag"""
|
341 | 4f0ae2af | humkyung | try:
|
342 | items = self.selectedItems()
|
||
343 | 47a4970e | esham21 | if items and hasattr(items[0], 'svgFilePath'): |
344 | 4f0ae2af | humkyung | symData = items[0].data(0, self.TREE_DATA_ROLE) |
345 | |||
346 | mime = QMimeData() |
||
347 | 3a4cc147 | humkyung | mime.setText(symData.getName()) |
348 | a1723c66 | humkyung | mime.tag = symData |
349 | 4f0ae2af | humkyung | |
350 | drag = QDrag(self)
|
||
351 | b1a510c6 | humkyung | drag.setMimeData(mime) |
352 | 4f0ae2af | humkyung | originalPoint = symData.getOriginalPoint() |
353 | b1a510c6 | humkyung | drag.setHotSpot( |
354 | QPoint(int(float(originalPoint.split(",")[0])), int(float(originalPoint.split(",")[1])))) |
||
355 | db2dcb47 | humkyung | drag.setPixmap(symData.pixmap) |
356 | 4f0ae2af | humkyung | drag.exec(Qt.CopyAction) |
357 | except Exception as ex: |
||
358 | b0034990 | humkyung | from App import App |
359 | |||
360 | b1a510c6 | humkyung | message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
361 | sys.exc_info()[-1].tb_lineno)
|
||
362 | b0034990 | humkyung | App.mainWnd().addMessage.emit(MessageType.Error, message) |