hytos / DTI_PID / DTI_PID / SymbolTreeWidget.py @ 8701ed58
이력 | 보기 | 이력해설 | 다운로드 (15.2 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 | editDisplaySymbolAction = QAction(self.tr("Edit Symbol for Dispay")) |
||
76 | 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 | b0034990 | humkyung | symbolTypeList = AppDocData.instance().getSymbolTypeList() |
204 | 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 | d0db0878 | humkyung | symbolList = AppDocData.instance().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 | pixmap = QPixmap(QSize(32, 32)) |
||
216 | 4d9163f7 | humkyung | pixmap.loadFromData(svg if isinstance(svg, bytes) else svg.encode()) |
217 | b1a510c6 | humkyung | icon = QIcon(pixmap) |
218 | symbolItem.setIcon(0, icon)
|
||
219 | symbolItem.svgFilePath = None # save svg file path |
||
220 | else:
|
||
221 | svgPath = symbol.getSvgFileFullPath() |
||
222 | icon = QIcon(svgPath) |
||
223 | symbolItem.setIcon(0, icon)
|
||
224 | symbolItem.svgFilePath = svgPath # save svg file path
|
||
225 | ed2b4ab0 | 김정우 | |
226 | b0034990 | humkyung | parent.sortChildren(0, Qt.AscendingOrder)
|
227 | except Exception as ex: |
||
228 | from App import App |
||
229 | |||
230 | b1a510c6 | humkyung | message = 'error occurred({}) in {}:{}'.format(repr(ex), sys.exc_info()[-1].tb_frame.f_code.co_filename, |
231 | sys.exc_info()[-1].tb_lineno)
|
||
232 | b0034990 | humkyung | App.mainWnd().addMessage.emit(MessageType.Error, message) |
233 | cdbc7e7f | 김정우 | |
234 | 9b09db27 | 김정우 | '''
|
235 | @brief Make Directory
|
||
236 | @author Jeongwoo
|
||
237 | @date 18.04.??
|
||
238 | @history 18.04.12 Jeongwoo Add output, temp Directory
|
||
239 | '''
|
||
240 | b1a510c6 | humkyung | |
241 | cb51acb2 | 김정우 | def makeChildDir(self): |
242 | project = AppDocData.instance().getCurrentProject() |
||
243 | dbDir = project.getDbFilePath() |
||
244 | d52b3462 | 김정우 | if not os.path.exists(dbDir): |
245 | os.makedirs(dbDir) |
||
246 | cb51acb2 | 김정우 | imgDir = project.getImageFilePath() |
247 | d52b3462 | 김정우 | if not os.path.exists(imgDir): |
248 | os.makedirs(imgDir) |
||
249 | cb51acb2 | 김정우 | svgDir = project.getSvgFilePath() |
250 | d52b3462 | 김정우 | if not os.path.exists(svgDir): |
251 | os.makedirs(svgDir) |
||
252 | 9b09db27 | 김정우 | outputDir = project.getOutputPath() |
253 | if not os.path.exists(outputDir): |
||
254 | os.makedirs(outputDir) |
||
255 | tempDir = project.getTempPath() |
||
256 | if not os.path.exists(tempDir): |
||
257 | os.makedirs(tempDir) |
||
258 | d52b3462 | 김정우 | |
259 | b1a510c6 | humkyung | def showSymbolEditorDialog(self, item, columnNo, display=False): |
260 | 4f0ae2af | humkyung | try:
|
261 | sym = self.getSymbolByItemName(item, columnNo)
|
||
262 | 61a7cd2d | esham21 | if sym and display: |
263 | # for symbol image for display
|
||
264 | path = os.path.splitext(sym.getPath()) |
||
265 | path = path[0] + '_display' + path[1] |
||
266 | if os.path.exists(path):
|
||
267 | image = QImage(path, "PNG")
|
||
268 | else:
|
||
269 | path = sym.getPath() |
||
270 | image = QImage(path, "PNG")
|
||
271 | b1a510c6 | humkyung | symbolEditorDialog = SymbolEditorDialog.QSymbolEditorDialog(self, image,
|
272 | AppDocData.instance().getCurrentProject(), |
||
273 | sym, True)
|
||
274 | 61a7cd2d | esham21 | (isAccepted, isImmediateInsert, offsetX, offsetY, newSym) = symbolEditorDialog.showDialog() |
275 | self.initDirTreeWidget()
|
||
276 | elif sym:
|
||
277 | # for symbol data and detection image
|
||
278 | 4f0ae2af | humkyung | path = sym.getPath() |
279 | image = QImage(path, "PNG")
|
||
280 | b1a510c6 | humkyung | symbolEditorDialog = SymbolEditorDialog.QSymbolEditorDialog(self, image,
|
281 | AppDocData.instance().getCurrentProject(), |
||
282 | sym, False)
|
||
283 | 3828d206 | 김정우 | (isAccepted, isImmediateInsert, offsetX, offsetY, newSym) = symbolEditorDialog.showDialog() |
284 | 4f0ae2af | humkyung | self.initDirTreeWidget()
|
285 | else:
|
||
286 | d88d6f39 | esham21 | QMessageBox.about(self, self.tr('Error'), self.tr('Error occurs during loading symbol data.')) |
287 | 4f0ae2af | humkyung | except Exception as ex: |
288 | b0034990 | humkyung | from App import App |
289 | 61a7cd2d | esham21 | from AppDocData import MessageType |
290 | 3926c898 | 김정우 | |
291 | b1a510c6 | humkyung | message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
292 | sys.exc_info()[-1].tb_lineno)
|
||
293 | b0034990 | humkyung | App.mainWnd().addMessage.emit(MessageType.Error, message) |
294 | e85bb909 | 김정우 | |
295 | def itemDoubleClickEvent(self, item, columnNo): |
||
296 | self.isDoubleClicked = True |
||
297 | 2894ed79 | 김정우 | sym = self.getSymbolByItemName(item, columnNo)
|
298 | e85bb909 | 김정우 | itemName = item.text(columnNo) |
299 | 2894ed79 | 김정우 | if sym is not None: |
300 | self.showSymbolEditorDialog(item, columnNo)
|
||
301 | 936111d1 | 김정우 | self.isDoubleClicked = False |
302 | d52b3462 | 김정우 | |
303 | b580f6e4 | 김정우 | '''
|
304 | ed2b4ab0 | 김정우 | @brief Get Symbol data by symbol name
|
305 | @author Jeongwoo
|
||
306 | @date 18.04.20
|
||
307 | '''
|
||
308 | b1a510c6 | humkyung | |
309 | 936111d1 | 김정우 | def getSymbolByItemName(self, item, columnNo): |
310 | d52b3462 | 김정우 | itemName = item.text(columnNo) |
311 | 65f1308c | humkyung | |
312 | ed2b4ab0 | 김정우 | name = itemName |
313 | sym = AppDocData.instance().getSymbolByQuery("name", name)
|
||
314 | return sym
|
||
315 | b192a44e | humkyung | |
316 | '''
|
||
317 | b929957d | humkyung | @breif show symbol's property when selection changed
|
318 | @author humkyung
|
||
319 | @date 2018.07.30
|
||
320 | '''
|
||
321 | b1a510c6 | humkyung | |
322 | b929957d | humkyung | def onCurrentItemChanged(self, current, previous): |
323 | item = self.currentItem()
|
||
324 | if item is not None: |
||
325 | data = item.data(0, self.TREE_DATA_ROLE) |
||
326 | b0034990 | humkyung | if data is not None and type(data) is symbol.SymbolBase: |
327 | b929957d | humkyung | self.singleClicked.emit(data)
|
328 | |||
329 | '''
|
||
330 | b192a44e | humkyung | @brief start drag
|
331 | @author humkyung
|
||
332 | @date 2018.04.17
|
||
333 | ed2b4ab0 | 김정우 | @history 18.04.20 Jeongwoo Change Path in QPixmap
|
334 | fbedb942 | 김정우 | 18.06.21 Jeongwoo Casting string to float and int
|
335 | b192a44e | humkyung | '''
|
336 | b1a510c6 | humkyung | |
337 | b192a44e | humkyung | def startDrag(self, dropAction): |
338 | 4f0ae2af | humkyung | try:
|
339 | items = self.selectedItems()
|
||
340 | 47a4970e | esham21 | if items and hasattr(items[0], 'svgFilePath'): |
341 | 4f0ae2af | humkyung | symData = items[0].data(0, self.TREE_DATA_ROLE) |
342 | b1a510c6 | humkyung | if items[0].svgFilePath: |
343 | pixmap = QPixmap(items[0].svgFilePath)
|
||
344 | else:
|
||
345 | app_doc_data = AppDocData.instance() |
||
346 | _, svg = app_doc_data.read_symbol_shape(symData.getName()) |
||
347 | if svg:
|
||
348 | pixmap = QPixmap() |
||
349 | a7d203dc | esham21 | pixmap.loadFromData(svg if isinstance(svg, bytes) else svg.encode()) |
350 | 4f0ae2af | humkyung | |
351 | mime = QMimeData() |
||
352 | 3a4cc147 | humkyung | mime.setText(symData.getName()) |
353 | 4f0ae2af | humkyung | |
354 | drag = QDrag(self)
|
||
355 | b1a510c6 | humkyung | drag.setMimeData(mime) |
356 | 4f0ae2af | humkyung | originalPoint = symData.getOriginalPoint() |
357 | b1a510c6 | humkyung | drag.setHotSpot( |
358 | QPoint(int(float(originalPoint.split(",")[0])), int(float(originalPoint.split(",")[1])))) |
||
359 | drag.setPixmap(pixmap) |
||
360 | 4f0ae2af | humkyung | drag.exec(Qt.CopyAction) |
361 | except Exception as ex: |
||
362 | b0034990 | humkyung | from App import App |
363 | |||
364 | b1a510c6 | humkyung | message = 'error occurred({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, |
365 | sys.exc_info()[-1].tb_lineno)
|
||
366 | b0034990 | humkyung | App.mainWnd().addMessage.emit(MessageType.Error, message) |