3 Copyright (C) 1997-2017 JDERobot Developers Team 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2 of the License, or 7 (at your option) any later version. 8 This program is distributed in the hope that it will be useful, 9 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 GNU Library General Public License for more details. 12 You should have received a copy of the GNU General Public License 13 along with this program; if not, see <http://www.gnu.org/licenses/>. 14 Authors : Okan Asik (asik.okan@gmail.com) 16 from PyQt5.QtCore
import Qt
17 from PyQt5.QtGui
import QPainter, QColor, QPixmap
18 from PyQt5.QtWidgets
import QMainWindow, QAction, QDockWidget, QTreeView, QGraphicsView, \
19 QWidget, QFileDialog, QLabel, QVBoxLayout, QPushButton, QMessageBox
20 from .automata.automatascene
import AutomataScene, OpType
21 from ..parsers.filemanager
import FileManager
22 from ..parsers.importmanager
import ImportManager
23 from .tree.treemodel
import TreeModel
24 from ..core.state
import State
25 from ..core.namespace
import Namespace
26 from .transition.timerdialog
import TimerDialog
27 from .dialogs.namespacedialog
import NamespaceDialog
28 from .dialogs.librariesdialog
import LibrariesDialog
29 from .dialogs.rosconfigdialog
import RosConfigDialog
30 from ..configs.rosconfig
import RosConfig
31 from ..generators.cpprosgenerator
import CppRosGenerator
32 from ..generators.pythonrosgenerator
import PythonRosGenerator
33 from ..configs.rospackage
import getPackagePath
34 from .dialogs.aboutdialog
import AboutDialog
41 self.setWindowTitle(
"VisualStates")
56 self.setGeometry(0, 0, 800, 600)
68 newAction = QAction(
'&New', self)
69 newAction.setShortcut(
'Ctrl+N')
70 newAction.setStatusTip(
'Create New Visual States')
71 newAction.triggered.connect(self.
newAction)
73 openAction = QAction(
'&Open', self)
74 openAction.setShortcut(
'Ctrl+O')
75 openAction.setStatusTip(
'Open Visual States')
78 importAction = QAction(
'&Import', self)
79 openAction.setShortcut(
'Ctrl+I')
80 importAction.setStatusTip(
'Import A State')
83 saveAction = QAction(
'&Save', self)
84 saveAction.setShortcut(
'Ctrl+S')
85 saveAction.setStatusTip(
'Save Visual States')
88 saveAsAction = QAction(
'&Save As', self)
89 saveAsAction.setShortcut(
'Ctrl+Shift+S')
90 saveAsAction.setStatusTip(
'Save Visual States as New One')
93 quitAction = QAction(
'&Quit', self)
94 quitAction.setShortcut(
'Ctrl+Q')
95 quitAction.setStatusTip(
'Quit Visual States')
99 stateAction = QAction(
'&State', self)
100 stateAction.setStatusTip(
'Create a state')
103 transitionAction = QAction(
'&Transition', self)
104 transitionAction.setStatusTip(
'Create a transition')
108 timerAction = QAction(
'&Timer', self)
109 timerAction.setShortcut(
'Ctrl+M')
110 timerAction.setStatusTip(
'Set timing of states')
113 globalNamespaceAction = QAction(
'&Global Namespace', self)
114 globalNamespaceAction.setShortcut(
'Ctrl+G')
115 globalNamespaceAction.setStatusTip(
'Open Global Namespace')
118 stateNamespaceAction = QAction(
'&State Namespace', self)
119 stateNamespaceAction.setShortcut(
'Ctrl+T')
120 stateNamespaceAction.setStatusTip(
'Open State Namespace')
124 librariesAction = QAction(
'&Libraries', self)
125 librariesAction.setShortcut(
'Ctrl+L')
126 librariesAction.setStatusTip(
'Add additional libraries')
129 configFileAction = QAction(
'&ROS Config', self)
130 configFileAction.setShortcut(
'Ctrl+R')
131 configFileAction.setStatusTip(
'Edit ROS configuration')
134 generateCppAction = QAction(
'&Generate C++', self)
135 generateCppAction.setShortcut(
'Ctrl+U')
136 generateCppAction.setStatusTip(
'Generate C++ code')
139 generatePythonAction = QAction(
'&Generate Python', self)
140 generatePythonAction.setShortcut(
'Ctrl+Y')
141 generatePythonAction.setStatusTip(
'Generate Python code')
145 aboutAction = QAction(
'&About', self)
146 aboutAction.setShortcut(
'F1')
147 aboutAction.setStatusTip(
'Information about VisualStates')
151 menubar = self.menuBar()
152 archieveMenu = menubar.addMenu(
'&File')
153 archieveMenu.addAction(newAction)
154 archieveMenu.addAction(openAction)
155 archieveMenu.addAction(importAction)
156 archieveMenu.addAction(saveAction)
157 archieveMenu.addAction(saveAsAction)
158 archieveMenu.addAction(quitAction)
160 figuresMenu = menubar.addMenu(
'&Figures')
161 figuresMenu.addAction(stateAction)
162 figuresMenu.addAction(transitionAction)
164 dataMenu = menubar.addMenu(
'&Data')
165 dataMenu.addAction(timerAction)
166 dataMenu.addAction(globalNamespaceAction)
167 dataMenu.addAction(stateNamespaceAction)
169 actionsMenu = menubar.addMenu(
'&Actions')
170 actionsMenu.addAction(librariesAction)
171 actionsMenu.addAction(configFileAction)
172 actionsMenu.addAction(generateCppAction)
174 actionsMenu.addAction(generatePythonAction)
176 helpMenu = menubar.addMenu(
'&Help')
177 helpMenu.addAction(aboutAction)
180 self.automataScene.clearScene()
181 self.treeModel.removeAll()
183 self.fileManager.setPath(
"")
190 self.automataScene.setActiveState(self.
rootState)
192 self.automataScene.resetIndexes()
198 fileDialog = QFileDialog(self)
199 fileDialog.setWindowTitle(
"Open VisualStates File")
200 fileDialog.setViewMode(QFileDialog.Detail)
201 fileDialog.setNameFilters([
'VisualStates File (*.xml)'])
202 fileDialog.setDefaultSuffix(
'.xml')
203 fileDialog.setAcceptMode(QFileDialog.AcceptOpen)
204 if fileDialog.exec_():
205 self.
openFile(fileDialog.selectedFiles()[0])
208 (rootState, config, libraries, globalNamespace) = self.fileManager.open(fileName)
209 if rootState
is not None:
212 self.treeModel.removeAll()
213 self.treeModel.loadFromRoot(self.
rootState)
215 self.automataScene.setActiveState(self.
rootState)
216 self.automataScene.setLastIndexes(self.
rootState)
219 "The selected file is not a valid VisualStates file")
223 if len(self.fileManager.getFileName()) == 0:
229 fileDialog = QFileDialog(self)
230 fileDialog.setWindowTitle(
"Save VisualStates Project")
231 fileDialog.setViewMode(QFileDialog.Detail)
232 fileDialog.setNameFilters([
'VisualStates File (*.xml)'])
233 fileDialog.setAcceptMode(QFileDialog.AcceptSave)
234 if fileDialog.exec_():
235 self.fileManager.setFullPath(fileDialog.selectedFiles()[0])
243 self.automataScene.setOperationType(OpType.ADDSTATE)
246 self.automataScene.setOperationType(OpType.ADDTRANSITION)
249 fileDialog = QFileDialog(self)
250 fileDialog.setWindowTitle(
"Import VisualStates File")
251 fileDialog.setViewMode(QFileDialog.Detail)
252 fileDialog.setNameFilters([
'VisualStates File (*.xml)'])
253 fileDialog.setDefaultSuffix(
'.xml')
254 fileDialog.setAcceptMode(QFileDialog.AcceptOpen)
255 if fileDialog.exec_():
256 tempPath = self.fileManager.getFullPath()
257 file = self.fileManager.open(fileDialog.selectedFiles()[0])
258 if file[0]
is not None:
259 self.fileManager.setPath(tempPath)
262 if self.activeState.getInitialChild()
is not None:
263 for childState
in file[0].getChildren():
264 childState.setInitial(
False)
268 self.treeModel.loadFromRoot(importedState, self.
activeState)
270 self.automataScene.setLastIndexes(self.
rootState)
273 "The selected file is not a valid VisualStates file")
277 timerDialog = TimerDialog(
'Time Step Duration', str(self.activeState.getTimeStep()))
284 self.globalNamespaceDialog.exec_()
289 self.localNamespaceDialog.exec_()
292 librariesDialog = LibrariesDialog(
'Libraries', self.
libraries)
294 librariesDialog.exec_()
300 self.configDialog.exec_()
303 QMessageBox.warning(self, title, msg)
306 QMessageBox.information(self, title, msg)
310 if self.fileManager.hasFile():
315 generator.generate(self.fileManager.getPath(), self.fileManager.getFileName())
316 self.
showInfo(
'C++ Code Generation',
'C++ code generation is successful.')
318 self.
showWarning(
'C++ Generation',
'Please save the project before code generation.')
326 if self.fileManager.hasFile():
331 generator.generate(self.fileManager.getPath(), self.fileManager.getFileName())
332 self.
showInfo(
'Python Code Generation',
'Python code generation is successful.')
334 self.
showWarning(
'Python Generation',
'Please save the project before code generation.')
337 aboutDialog = AboutDialog()
341 dockWidget = QDockWidget()
342 dockWidget.setAllowedAreas(Qt.LeftDockWidgetArea)
343 dockWidget.setFeatures(QDockWidget.NoDockWidgetFeatures)
344 dockWidget.setTitleBarWidget(QWidget())
351 self.upButton.setText(
'Up')
354 leftContainer = QWidget()
355 leftLayout = QVBoxLayout()
358 leftContainer.setLayout(leftLayout)
360 dockWidget.setWidget(leftContainer)
361 self.addDockWidget(Qt.LeftDockWidgetArea, dockWidget)
366 self.automataScene.setSceneRect(0, 0, 2000, 2000)
370 self.automataScene.stateRemoved.connect(self.
stateRemoved)
374 self.automataScene.setActiveState(self.
rootState)
378 self.stateCanvas.setRenderHint(QPainter.Antialiasing)
379 self.stateCanvas.setAcceptDrops(
True)
383 parent = self.treeModel.getByDataId(self.activeState.id)
384 self.treeModel.insertState(state, QColor(Qt.white), parent)
386 self.treeModel.insertState(state, QColor(Qt.white))
390 parent = self.treeModel.getByDataId(self.activeState.id)
391 self.treeModel.removeState(state.stateData, parent)
393 self.treeModel.removeState(state.stateData)
403 dataItem = self.treeModel.getByDataId(state.stateData.id)
405 dataItem.name = state.stateData.name
406 self.treeModel.layoutChanged.emit()
409 if self.automataScene.activeState != self.
activeState:
413 self.treeView.selectionModel().clearSelection()
415 self.treeView.setCurrentIndex(self.treeModel.indexOf(self.treeModel.getByDataId(self.activeState.id)))
423 if self.activeState.parent !=
None:
425 self.automataScene.setActiveState(self.activeState.parent)
432 for child
in state.getChildren():
434 if result
is not None:
441 if state
is not None:
443 self.automataScene.setActiveState(state)
447 self.activeState.setTimeStep(duration)
461 if len(state.getChildren()) > 0:
462 stateList.append(state)
464 for s
in state.getChildren():
def librariesChanged(self, libraries)
def localNamespaceChanged(self)
def stateInserted(self, state)
def transitionAction(self)
def activeStateChanged(self)
def __init__(self, parent=None)
def stateNameChanged(self, state)
def createStateCanvas(self)
def localNamespaceAction(self)
def transitionInserted(self, tran)
def generateCppAction(self)
def librariesAction(self)
def openFile(self, fileName)
def activeNamespaceChanged(self)
def configFileAction(self)
def upButtonClicked(self)
def getStateList(self, state, stateList)
def getStateById(self, state, id)
def stateRemoved(self, state)
def showInfo(self, title, msg)
def generatePythonAction(self)
def globalNamespaceAction(self)
def showWarning(self, title, msg)
def timeStepDurationChanged(self, duration)
def treeItemClicked(self, index)
def globalNamespaceChanged(self)