프로젝트

일반

사용자정보

통계
| 개정판:

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)
클립보드 이미지 추가 (최대 크기: 500 MB)