Exemplo n.º 1
0
    def __init__(self, parent=None):
        super(QMainWindow, self).__init__()

        self.setWindowTitle("VisualStates")
        self.configDialog = None

        # root state
        self.rootState = State(0, "root", True)
        self.activeState = self.rootState

        # create status bar
        self.statusBar()

        self.createMenu()
        self.createTreeView()
        self.createStateCanvas()

        self.setGeometry(0, 0, 800, 600)
        self.show()

        self.fileManager = FileManager()

        self.libraries = []
        self.config = None
        self.interfaceHeaderMap = Interfaces.getInterfaces()
Exemplo n.º 2
0
	def _initTools(self):
		""" Initializes tools """
		if self._options.plugin_dir is not None:
			sys.path.append(os.path.abspath(self._options.plugin_dir))

		self._pluginmanager = plugin.PluginManager(self.getSettings(), self._options.plugin_dir)
		
		self._filemanager = FileManager()
		self._toolbar.adaptLayout()
		self._mapeditor = MapEditor()
Exemplo n.º 3
0
Arquivo: editor.py Projeto: m64/PEG
	def _initTools(self):
		""" Initializes tools """
		self._pluginmanager = plugin.PluginManager(self.getSettings())
		
		self._filemanager = FileManager()
		self._toolbar.adaptLayout()
		self._mapeditor = MapEditor()
Exemplo n.º 4
0
	def _initTools(self):
		""" Initializes tools """
		if self._options.plugin_dir is not None:
			sys.path.append(os.path.abspath(self._options.plugin_dir))
		self._pluginmanager = plugin.PluginManager(self.getSettings(), self._options.plugin_dir)

		self._filemanager = FileManager()
		self._toolbar.adaptLayout()
		self._mapeditor = MapEditor()
Exemplo n.º 5
0
class Editor(ApplicationBase, MainWindow):
	""" Editor sets up all subsystems and provides access to them """
	editor = None

	def __init__(self, options, mapfile, *args, **kwargs):
		Editor.editor = self

		self._filemanager = None

		self._options = options
		self._mapfile = mapfile
		self._eventlistener = None
		self._pluginmanager = None

		self._inited = False

		self._mapview = None
		self._mapviewlist = []
		self._mapgroup = None
		self._mapbar = None
		self._maparea = None
		self._mapeditor = None

		self._file_menu = None
		self._edit_menu = None
		self._view_menu = None
		self._tools_menu = None
		self._help_menu = None

		self._change_map = -1

		self._settings = TDS

		self._lighting_mode = int(TDS.get("FIFE", "Lighting"))
		self._help_dialog = None

		ApplicationBase.__init__(self, TDS, *args, **kwargs)
		MainWindow.__init__(self, *args, **kwargs)

	def _initTools(self):
		""" Initializes tools """
		if self._options.plugin_dir is not None:
			sys.path.append(os.path.abspath(self._options.plugin_dir))
		self._pluginmanager = plugin.PluginManager(self.getSettings(), self._options.plugin_dir)

		self._filemanager = FileManager()
		self._toolbar.adaptLayout()
		self._mapeditor = MapEditor()

	def _initGui(self):
		""" Sets up the GUI """
		screen_width = self.engine.getSettings().getScreenWidth()
		screen_height = self.engine.getSettings().getScreenHeight()
		MainWindow.initGui(self, screen_width, screen_height)

		self._toolbox = ToolBar(title=u"", orientation=1)
		self._toolbox.position_technique = "explicit"
		self._toolbox.position = (150, 150)

		self._mapbar = ToolBar(name="MapBar", panel_size=20)
		self._mapbar.setDocked(True)

		self._maparea = pychan.widgets.VBox()
		self._maparea.opaque = False
		self._maparea.is_focusable = True

		# Capture mouse and key events for EventListener
		cw = self._maparea
		cw.capture(self.__sendMouseEvent, "mouseEntered")
		cw.capture(self.__sendMouseEvent, "mouseExited")
		cw.capture(self.__sendMouseEvent, "mousePressed")
		cw.capture(self.__sendMouseEvent, "mouseReleased")
		cw.capture(self.__sendMouseEvent, "mouseClicked")
		cw.capture(self.__sendMouseEvent, "mouseMoved")
		cw.capture(self.__sendMouseEvent, "mouseWheelMovedUp")
		cw.capture(self.__sendMouseEvent, "mouseWheelMovedDown")
		cw.capture(self.__sendMouseEvent, "mouseDragged")
		cw.capture(self.__sendKeyEvent, "keyPressed")
		cw.capture(self.__sendKeyEvent, "keyReleased")

		self._centralwidget.addChild(self._mapbar)
		self._centralwidget.addChild(self._maparea)

		self._initActions()

		self._toolbox.show()

		events.preMapClosed.connect(self._mapRemoved)

	def _initActions(self):
		""" Initializes toolbar and menubar buttons """
		exitAction = Action(u"Exit", "gui/icons/quit.png")
		exitAction.helptext = u"Exit program"
		action.activated.connect(self.quit, sender=exitAction)

		self._file_menu = Menu(name=u"File")
		self._file_menu.addAction(exitAction)

		self._edit_menu = Menu(name=u"Edit")
		self._view_menu = Menu(name=u"View")
		self._tools_menu = Menu(name=u"Tools")
		self._window_menu = Menu(name=u"Window")
		self._help_menu = Menu(name=u"Help")

		self._action_show_statusbar = Action(u"Statusbar")
		self._action_show_statusbar.helptext = u"Toggle statusbar"
		action.activated.connect(self.toggleStatusbar, sender=self._action_show_statusbar)

		self._action_show_toolbar = Action(u"Toolbar")
		self._action_show_toolbar.helptext = u"Toggle toolbar"
		action.activated.connect(self.toggleToolbar, sender=self._action_show_toolbar)

		self._action_show_toolbox = Action(u"Tool box")
		self._action_show_toolbox.helptext = u"Toggle tool box"
		action.activated.connect(self.toggleToolbox, sender=self._action_show_toolbox)

		self._view_menu.addAction(self._action_show_statusbar)
		self._view_menu.addAction(self._action_show_toolbar)
		self._view_menu.addAction(self._action_show_toolbox)
		self._view_menu.addSeparator()


		test_action1 = Action(u"Cycle buttonstyles", "gui/icons/cycle_styles.png")
		test_action1.helptext = u"Cycles button styles. There are currently four button styles."
		action.activated.connect(self._actionActivated, sender=test_action1)
		self._view_menu.addAction(test_action1)

		test_action2 = Action(u"Toggle Blocking")
		test_action2.helptext = u"Toggles the blocking infos for the instances."
		action.activated.connect(self.toggleBlocking, sender=test_action2)
		self._view_menu.addAction(test_action2)

		test_action3 = Action(u"Toggle Grid")
		test_action3.helptext = u"Toggles the grids of the map."
		action.activated.connect(self.toggleGrid, sender=test_action3)
		self._view_menu.addAction(test_action3)

		test_action4 = Action(u"Toggle Coordinates")
		test_action4.helptext = u"Toggles the coordinates of the map."
		action.activated.connect(self.toggleCoordinates, sender=test_action4)
		self._view_menu.addAction(test_action4)

		self._mapgroup = ActionGroup(exclusive=True, name="Mapgroup")
		self._mapbar.addAction(self._mapgroup)
		self._window_menu.addAction(self._mapgroup)

		help_action = Action(u"Help", "gui/icons/help.png")
		help_action.helptext = u"Displays a window with some simple instructions"
		action.activated.connect(self._showHelpDialog, sender=help_action)
		self._help_menu.addAction(help_action)

		self._menubar.addMenu(self._file_menu)
		self._menubar.addMenu(self._edit_menu)
		self._menubar.addMenu(self._view_menu)
		self._menubar.addMenu(self._tools_menu)
		self._menubar.addMenu(self._window_menu)
		self._menubar.addMenu(self._help_menu)

	def _actionActivated(self, sender):
		self._toolbar.button_style += 1

	def _showHelpDialog(self, sender):
		""" Shows the help dialog """
		if self._help_dialog is not None:
			self._help_dialog.show()
			return

		self._help_dialog = pychan.loadXML("gui/help.xml")
		self._help_dialog.findChild(name="closeButton").capture(self._help_dialog.hide)

		f = open('lang/infotext.txt', 'r')
		self._help_dialog.findChild(name="helpText").text = unicode(f.read())
		f.close()

		self._help_dialog.show()

	def toggleStatusbar(self):
		""" Toggles status bar """
		statusbar = self.getStatusBar()
		if statusbar.max_size[1] > 0:
			statusbar.min_size=(statusbar.min_size[0], 0)
			statusbar.max_size=(statusbar.max_size[0], 0)
			self._action_show_statusbar.setChecked(False)
		else:
			statusbar.min_size=(statusbar.min_size[0], statusbar.min_size[0])
			statusbar.max_size=(statusbar.max_size[0], statusbar.max_size[0])
			self._action_show_statusbar.setChecked(True)
		statusbar.adaptLayout()

	def toggleToolbar(self):
		""" Toggles toolbar """
		toolbar = self.getToolBar()
		if toolbar.isVisible():
			toolbar.setDocked(False)
			toolbar.hide()
			self._action_show_toolbar.setChecked(False)
		else:
			tx = toolbar.x
			ty = toolbar.y
			toolbar.show()
			toolbar.x = tx
			toolbar.y = ty
			self._action_show_toolbar.setChecked(True)

	def toggleToolbox(self):
		""" Toggles tool box """
		toolbox = self.getToolbox()
		if toolbox.isVisible():
			toolbox.setDocked(False)
			toolbox.hide()
			self._action_show_toolbox.setChecked(False)
		else:
			tx = toolbox.x
			ty = toolbox.y
			toolbox.show()
			toolbox.x = tx
			toolbox.y = ty
			self._action_show_toolbox.setChecked(True)
		toolbox.adaptLayout()

	def toggleBlocking(self, sender):
		if self._mapview is not None:
			for cam in self._mapview.getMap().getCameras():
				r = fife.BlockingInfoRenderer.getInstance(cam)
				r.setEnabled(not r.isEnabled())

	def toggleGrid(self, sender):
		if self._mapview is not None:
			for cam in self._mapview.getMap().getCameras():
				r = fife.GridRenderer.getInstance(cam)
				r.setEnabled(not r.isEnabled())

	def toggleCoordinates(self, sender):
		if self._mapview is not None:
			for cam in self._mapview.getMap().getCameras():
				r = fife.CoordinateRenderer.getInstance(cam)
				if not r.isEnabled():
					r.clearActiveLayers()
					color = str(self._settings.get("Colors", "Coordinate", "255,255,255"))
					r.setColor(*[int(c) for c in color.split(',')])
					for layer in self._mapview.getMap().getLayers():
						if layer.areInstancesVisible():
							r.addActiveLayer(layer)
					r.setEnabled(True)
				else:
					r.setEnabled(False)

	def getToolbox(self):
		return self._toolbox

	def getPluginManager(self):
		return self._pluginmanager

	def getEngine(self):
		return self.engine

	def getMapViews(self):
		return self._mapviewlist

	def getActiveMapView(self):
		return self._mapview

	def getSettings(self):
		return self._settings;

	def getObject(self):
		return self._mapeditor.getObject()

	def showMapView(self, mapview):
		""" Switches to mapview. """
		if mapview is None or mapview == self._mapview:
			return

		if self._mapview != None and mapview != self._mapview:
			# need to disable the cameras from the previous map
			# if it exists before switching
			if self._mapview.getMap() != None:
				for cam in self._mapview.getMap().getCameras():
					cam.setEnabled(False)

		# if light model is set then enable LightRenderer for all layers
		if self._lighting_mode is not 0:
			for cam in mapview.getMap().getCameras():
				renderer = fife.LightRenderer.getInstance(cam)
				renderer.activateAllLayers(mapview.getMap())
				renderer.setEnabled(not renderer.isEnabled())

		events.preMapShown.send(sender=self, mapview=mapview)
		self._mapview = mapview
		self._mapview.show()
		events.postMapShown.send(sender=self, mapview=mapview)

	def createListener(self):
		""" Creates the event listener. This is called by ApplicationBase """
		if self._eventlistener is None:
			self._eventlistener = EventListener(self.engine)

		return self._eventlistener

	def getEventListener(self):
		""" Returns the event listener """
		return self._eventlistener

	def newMapView(self, map):
		""" Creates a new map view """
		mapview = MapView(map)

		self._mapviewlist.append(mapview)

		map_action = Action(unicode(map.getId()))
		action.activated.connect(cbwa(self.showMapView, mapview), sender=map_action, weak=False)
		self._mapgroup.addAction(map_action)

		self.showMapView(mapview)

		events.mapAdded.send(sender=self, map=map)

		return mapview

	def _mapRemoved(self, mapview):
		index = self._mapviewlist.index(mapview)-1

		for cam in mapview.getMap().getCameras():
			cam.setEnabled(False)

		self._mapviewlist.remove(mapview)

		# Remove tab
		for map_action in self._mapgroup.getActions():
			if map_action.text == unicode(mapview.getMap().getId()):
				self._mapgroup.removeAction(map_action)
				break

		# Change mapview
		if len(self._mapviewlist) > 0:
			if index < 0:
				index = 0
			self._change_map = index
		else:
			self._mapview = None

	def openFile(self, path):
		""" Opens a file """
		try:
			if self._lighting_mode == 0:
				map = loaders.loadMapFile(path, self.engine)
			else:
				map = loaders.loadMapFile(path, self.engine, extensions = {'lights': True})
			return self.newMapView(map)
		except:
			traceback.print_exc(sys.exc_info()[1])
			errormsg = u"Opening map failed:\n"
			errormsg += u"File: "+unicode(path, sys.getfilesystemencoding())+u"\n"
			errormsg += u"Error: "+unicode(sys.exc_info()[1])
			ErrorDialog(errormsg)
			return None

	def saveAll(self):
		""" Saves all open maps """
		tmpview = self._mapview
		for mapview in self._mapviewlist:
			self._mapview = mapview
			self._filemanager.save()
		self._mapview = tmpview

	def quit(self):
		""" Quits the editor. An onQuit signal is sent before the application closes """
		events.onQuit.send(sender=self)

		self._settings.saveSettings()
		ApplicationBase.quit(self)

	def _pump(self):
		""" Called once per frame """
		# ApplicationBase and Engine should be done initializing at this point
		if self._inited == False:
			self._initGui()
			self._initTools()
			if self._mapfile: self.openFile(self._mapfile)
			self._inited = True

		# FIXME: This isn't very nice, but it is needed to change the map
		#		 outside the callback.
		if self._change_map >= 0 and len(self._mapviewlist) > 0:
			if self._change_map >= len(self._mapviewlist):
				self._change_map = len(self._mapviewlist)-1
			mapview = self._mapviewlist[self._change_map]

			self.showMapView(mapview)
			self._change_map = -1

		events.onPump.send(sender=self)

	def __sendMouseEvent(self, event, **kwargs):
		""" Function used to capture mouse events for EventListener """
		ms_event = fife.MouseEvent
		type = event.getType()

		if type == ms_event.MOVED:
			mouseMoved.send(sender=self._maparea, event=event)

		elif type == ms_event.PRESSED:
			mousePressed.send(sender=self._maparea, event=event)

		elif type == ms_event.RELEASED:
			mouseReleased.send(sender=self._maparea, event=event)

		elif type == ms_event.WHEEL_MOVED_DOWN:
			mouseWheelMovedDown.send(sender=self._maparea, event=event)

		elif type == ms_event.WHEEL_MOVED_UP:
			mouseWheelMovedUp.send(sender=self._maparea, event=event)

		elif type == ms_event.CLICKED:
			mouseClicked.send(sender=self._maparea, event=event)

		elif type == ms_event.ENTERED:
			mouseEntered.send(sender=self._maparea, event=event)

		elif type == ms_event.EXITED:
			mouseExited.send(sender=self._maparea, event=event)

		elif type == ms_event.DRAGGED:
			mouseDragged.send(sender=self._maparea, event=event)

	def __sendKeyEvent(self, event, **kwargs):
		""" Function used to capture key events for EventListener """
		type = event.getType()

		if type == fife.KeyEvent.PRESSED:
			keyPressed.send(sender=self._maparea, event=event)

		elif type == fife.KeyEvent.RELEASED:
			keyReleased.send(sender=self._maparea, event=event)
Exemplo n.º 6
0
Arquivo: editor.py Projeto: m64/PEG
class Editor(ApplicationBase, MainWindow):
	""" Editor sets up all subsystems and provides access to them """
	editor = None

	def __init__(self, params, *args, **kwargs):
		Editor.editor = self
	
		self._filemanager = None
		self._open_files = []
	
		self._params = params
		self._eventlistener = None
		self._pluginmanager = None
		
		self._inited = False
		
		self._mapview = None
		self._mapviewlist = []
		self._mapgroup = None
		self._mapbar = None
		self._maparea = None
		self._mapeditor = None
		
		self._file_menu = None
		self._edit_menu = None
		self._view_menu = None
		self._tools_menu = None
		self._help_menu = None
		
		self._settings = None
		
		self._help_dialog = None
	
		ApplicationBase.__init__(self, *args, **kwargs)
		MainWindow.__init__(self, *args, **kwargs)
		pychan.init(self.engine, debug=False)
		

	def loadSettings(self):
		"""
		Load the settings from a python file and load them into the engine.
		Called in the ApplicationBase constructor.
		"""
		self._settings = Settings()
		TDS = self._settings
		
		glyphDft = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,!?-+/():;%&amp;`'*#=[]\\\""
		engineSetting = self.engine.getSettings()
		engineSetting.setDefaultFontGlyphs(TDS.get("FIFE", "FontGlyphs", glyphDft))
		engineSetting.setDefaultFontPath(TDS.get("FIFE", "Font", "fonts/FreeSans.ttf"))
		engineSetting.setDefaultFontSize(12)
		engineSetting.setBitsPerPixel(TDS.get("FIFE", "BitsPerPixel", 0))
		engineSetting.setInitialVolume(TDS.get("FIFE", "InitialVolume", 5.0))
		engineSetting.setSDLRemoveFakeAlpha(TDS.get("FIFE", "SDLRemoveFakeAlpha", 1))
		engineSetting.setScreenWidth(TDS.get("FIFE", "ScreenWidth", 1024))
		engineSetting.setScreenHeight(TDS.get("FIFE", "ScreenHeight", 768))
		engineSetting.setRenderBackend(TDS.get("FIFE", "RenderBackend", "OpenGL"))
		engineSetting.setFullScreen(TDS.get("FIFE", "FullScreen", 0))

		engineSetting.setWindowTitle(TDS.get("FIFE", "WindowTitle", "No window title set"))
		engineSetting.setWindowIcon(TDS.get("FIFE", "WindowIcon", ""))
		engineSetting.setImageChunkingSize(TDS.get("FIFE", "ImageChunkSize", 256))

	def initLogging(self):
		"""
		Initialize the LogManager.
		"""
		import fifelog
		
		logModules = self._settings.get("FIFE", "LogModules")
		loglevel = self._settings.get("FIFE", "LogLevel", "Warn");
			
		self.log = fifelog.LogManager(self.engine, self._settings.get("FIFE", "LogToPrompt"), self._settings.get("FIFE", "LogToFile"))
		if logModules:
			self.log.setVisibleModules(*logModules)
			
		if loglevel == "Debug":
			loglevel = fife.LogManager.LEVEL_DEBUG
		elif loglevel == "Log":
			loglevel = fife.LogManager.LEVEL_LOG
		elif loglevel == "Error":
			loglevel = fife.LogManager.LEVEL_ERROR
		else:
			loglevel = fife.LogManager.LEVEL_WARN
		self.log.lm.setLevelFilter(loglevel)
		
	def _initTools(self):
		""" Initializes tools """
		self._pluginmanager = plugin.PluginManager(self.getSettings())
		
		self._filemanager = FileManager()
		self._toolbar.adaptLayout()
		self._mapeditor = MapEditor()
		
	def _initGui(self):
		""" Sets up the GUI """
		screen_width = self.engine.getSettings().getScreenWidth()
		screen_height = self.engine.getSettings().getScreenHeight()
		MainWindow.initGui(self, screen_width, screen_height)

		self._toolbox = ToolBar(title=u"", orientation=1)
		self._toolbox.position_technique = "explicit"
		self._toolbox.position = (150, 150)
		
		self._mapbar = ToolBar(name="MapBar", panel_size=20)
		self._mapbar.setDocked(True)
		
		self._maparea = pychan.widgets.VBox()
		self._maparea.opaque = False
		self._maparea.is_focusable = True
		
		# Capture mouse and key events for EventListener
		cw = self._maparea
		cw.capture(self.__sendMouseEvent, "mouseEntered")
		cw.capture(self.__sendMouseEvent, "mouseExited")
		cw.capture(self.__sendMouseEvent, "mousePressed")
		cw.capture(self.__sendMouseEvent, "mouseReleased")
		cw.capture(self.__sendMouseEvent, "mouseClicked")
		cw.capture(self.__sendMouseEvent, "mouseMoved")
		cw.capture(self.__sendMouseEvent, "mouseWheelMovedUp")
		cw.capture(self.__sendMouseEvent, "mouseWheelMovedDown")
		cw.capture(self.__sendMouseEvent, "mouseDragged")
		cw.capture(self.__sendKeyEvent, "keyPressed")
		cw.capture(self.__sendKeyEvent, "keyReleased")
		
		self._centralwidget.addChild(self._mapbar)
		self._centralwidget.addChild(self._maparea)
		
		self._initActions()
		
		self._toolbox.show()

	def _initActions(self):
		""" Initializes toolbar and menubar buttons """
		exitAction = Action(u"Exit", "gui/icons/quit.png")
		exitAction.helptext = u"Exit program"
		action.activated.connect(self.quit, sender=exitAction)
		
		self._file_menu = Menu(name=u"File")
		self._file_menu.addAction(exitAction)
		
		self._edit_menu = Menu(name=u"Edit")
		self._view_menu = Menu(name=u"View")
		self._tools_menu = Menu(name=u"Tools")
		self._window_menu = Menu(name=u"Window")
		self._help_menu = Menu(name=u"Help")
		
		self._action_show_statusbar = Action(u"Statusbar")
		self._action_show_statusbar.helptext = u"Toggle statusbar"
		action.activated.connect(self.toggleStatusbar, sender=self._action_show_statusbar)
		
		self._action_show_toolbar = Action(u"Toolbar")
		self._action_show_toolbar.helptext = u"Toggle toolbar"
		action.activated.connect(self.toggleToolbar, sender=self._action_show_toolbar)
		
		self._action_show_toolbox = Action(u"Tool box")
		self._action_show_toolbox.helptext = u"Toggle tool box"
		action.activated.connect(self.toggleToolbox, sender=self._action_show_toolbox)
		
		self._view_menu.addAction(self._action_show_statusbar)
		self._view_menu.addAction(self._action_show_toolbar)
		self._view_menu.addAction(self._action_show_toolbox)
		self._view_menu.addSeparator()
	
	
		test_action1 = Action(u"Cycle buttonstyles", "gui/icons/cycle_styles.png")
		test_action1.helptext = u"Cycles button styles. There are currently four button styles."
		action.activated.connect(self._actionActivated, sender=test_action1)
		self._view_menu.addAction(test_action1)
		
		self._mapgroup = ActionGroup(exclusive=True, name="Mapgroup")
		self._mapbar.addAction(self._mapgroup)
		self._window_menu.addAction(self._mapgroup)
		
		help_action = Action(u"Help", "gui/icons/help.png")
		help_action.helptext = u"Displays a window with some simple instructions"
		action.activated.connect(self._showHelpDialog, sender=help_action)
		self._help_menu.addAction(help_action)
		
		self._menubar.addMenu(self._file_menu)
		self._menubar.addMenu(self._edit_menu)
		self._menubar.addMenu(self._view_menu)
		self._menubar.addMenu(self._tools_menu)
		self._menubar.addMenu(self._window_menu)
		self._menubar.addMenu(self._help_menu)
	
	def _actionActivated(self, sender):
		self._toolbar.button_style += 1
		
	def _showHelpDialog(self, sender):
		""" Shows the help dialog """
		if self._help_dialog is not None:
			self._help_dialog.show()
			return
		
		self._help_dialog = pychan.loadXML("gui/help.xml")
		self._help_dialog.findChild(name="closeButton").capture(self._help_dialog.hide)
		
		f = open('lang/infotext.txt', 'r')
		self._help_dialog.findChild(name="helpText").text = unicode(f.read())
		f.close()
		
		self._help_dialog.show()
		
	def toggleStatusbar(self):
		""" Toggles status bar """
		statusbar = self.getStatusBar()
		if statusbar.max_size[1] > 0:
			statusbar.min_size=(statusbar.min_size[0], 0)
			statusbar.max_size=(statusbar.max_size[0], 0)
			self._action_show_statusbar.setChecked(False)
		else:
			statusbar.min_size=(statusbar.min_size[0], statusbar.min_size[0])
			statusbar.max_size=(statusbar.max_size[0], statusbar.max_size[0])
			self._action_show_statusbar.setChecked(True)
		statusbar.adaptLayout()
			
	def toggleToolbar(self):
		""" Toggles toolbar """
		toolbar = self.getToolBar()
		if toolbar.isVisible():
			toolbar.setDocked(False)
			toolbar.hide()
			self._action_show_toolbar.setChecked(False)
		else: 
			tx = toolbar.x
			ty = toolbar.y
			toolbar.show()
			toolbar.x = tx
			toolbar.y = ty
			self._action_show_toolbar.setChecked(True)
			
	def toggleToolbox(self):
		""" Toggles tool box """
		toolbox = self.getToolbox()
		if toolbox.isVisible():
			toolbox.setDocked(False)
			toolbox.hide()
			self._action_show_toolbox.setChecked(False)
		else:
			tx = toolbox.x
			ty = toolbox.y
			toolbox.show()
			toolbox.x = tx
			toolbox.y = ty
			self._action_show_toolbox.setChecked(True)
		toolbox.adaptLayout()
			
	def getToolbox(self): 
		return self._toolbox
	
	def getPluginManager(self): 
		return self._pluginmanager
		
	def getEngine(self): 
		return self.engine

	def getMapViews(self):
		return self._mapviewlist
		
	def getActiveMapView(self):
		return self._mapview
		
	def getSettings(self):
		return self._settings;
		
	def showMapView(self, mapview):
		""" Switches to mapview. """
		if mapview is None or mapview == self._mapview:
			return
			
		events.preMapShown.send(sender=self, mapview=mapview)
		self._mapview = mapview
		self._mapview.show()
		events.postMapShown.send(sender=self, mapview=mapview)

	def createListener(self):
		""" Creates the event listener. This is called by ApplicationBase """
		if self._eventlistener is None:
			self._eventlistener = EventListener(self.engine)
		
		return self._eventlistener
		
	def getEventListener(self):
		""" Returns the event listener """
		return self._eventlistener
	
	def newMapView(self, map):
		""" Creates a new map view """
		mapview = MapView(map)
		
		self._mapviewlist.append(mapview)
		
		map_action = Action(unicode(map.getId()))
		action.activated.connect(cbwa(self.showMapView, mapview), sender=map_action, weak=False)
		self._mapgroup.addAction(map_action)
		
		self.showMapView(mapview)
		
		events.preMapClosed.connect(self._preMapRemoved)
		events.postMapClosed.connect(self._postMapRemoved)
		events.mapAdded.send(sender=self, map=map)
		
		return mapview
		
	def _preMapRemoved(self, sender, mapview):
		events.preMapClosed.disconnect(self._preMapRemoved)
	
		# Remove from open files list
		try:
			path = mapview.getMap().getResourceLocation().getFilename()
			try:
				self._open_files.remove(path)
			except ValueError:
				pass
		except RuntimeError:
			# Mapview is not saved
			return
		
		# Remove tab
		for map_action in self._mapgroup.getActions():
			if map_action.text == unicode(mapview.getMap().getId()):
				self._mapgroup.removeAction(map_action)
				break
			
	def _postMapRemoved(self, mapview):
		events.postMapClosed.disconnect(self._postMapRemoved)
		
		# Remove from mapviewlist
		index = self._mapviewlist.index(mapview)-1
		self._mapviewlist.remove(mapview)
		
		# Change mapview
		if index >= 0:
			self.showMapView(self._mapviewlist[index])
		else:
			self._mapview = None
			self.getEngine().getView().clearCameras()
			
	def getMapviewByPath(self, path):
		mappath = ""
		for mv in self._mapviewlist:
			try:
				mappath = mv.getMap().getResourceLocation().getFilename()
			except RuntimeError:
				# Mapview is not saved yet
				continue
				
			if mappath == path:
				return mv

	def openFile(self, path):
		if path in self._open_files:
			# Map is already open, ask user if he wants to reload the map
			mapview = self.getMapviewByPath(path)
			YesNoDialog(u"Map is already open. Do you want to reload it?", cbwa(self.reloadMapview, mapview=mapview))
			return
	
		""" Opens a file """
		try:
			map = loaders.loadMapFile(path, self.engine)
			mapview = self.newMapView(map)
			self._open_files.append(path)
			return mapview
		except:
			traceback.print_exc(sys.exc_info()[1])
			errormsg = u"Opening map failed:\n"
			errormsg += u"File: "+unicode(path, sys.getfilesystemencoding())+u"\n"
			errormsg += u"Error: "+unicode(sys.exc_info()[1])
			ErrorDialog(errormsg)
			return None
			
	def reloadMapview(self, mapview=None):
		if mapview is None:
			mapview = self._mapview
			
		if mapview is None:
			print "Can't reload map: No maps are open."
			return
			
		path = mapview.getMap().getResourceLocation().getFilename()
		mapview.close()
		self.openFile(path)
			
	
	def saveAll(self):
		""" Saves all open maps """
		tmpview = self._mapview
		for mapview in self._mapviewlist:
			self._mapview = mapview
			self._filemanager.save()
		self._mapview = tmpview
		
	def quit(self):
		""" Quits the editor. An onQuit signal is sent before the application closes """
		events.onQuit.send(sender=self)
		
		self._settings.saveSettings()
		ApplicationBase.quit(self)

	def _pump(self):
		""" Called once per frame """
		# ApplicationBase and Engine should be done initializing at this point
		if self._inited == False:
			self._initGui()
			self._initTools()
			if self._params: self.openFile(self._params)
			self._inited = True
		
		events.onPump.send(sender=self)
		
	def __sendMouseEvent(self, event, **kwargs):
		""" Function used to capture mouse events for EventListener """
		ms_event = fife.MouseEvent
		type = event.getType()
		
		if type == ms_event.MOVED:
			mouseMoved.send(sender=self._maparea, event=event)
			
		elif type == ms_event.PRESSED:
			mousePressed.send(sender=self._maparea, event=event)
			
		elif type == ms_event.RELEASED:
			mouseReleased.send(sender=self._maparea, event=event)
			
		elif type == ms_event.WHEEL_MOVED_DOWN:
			mouseWheelMovedDown.send(sender=self._maparea, event=event)
			
		elif type == ms_event.WHEEL_MOVED_UP:
			mouseWheelMovedUp.send(sender=self._maparea, event=event)
			
		elif type == ms_event.CLICKED:
			mouseClicked.send(sender=self._maparea, event=event)
			
		elif type == ms_event.ENTERED:
			mouseEntered.send(sender=self._maparea, event=event)
			
		elif type == ms_event.EXITED:
			mouseExited.send(sender=self._maparea, event=event)
			
		elif type == ms_event.DRAGGED:
			mouseDragged.send(sender=self._maparea, event=event)
		
	def __sendKeyEvent(self, event, **kwargs):
		""" Function used to capture key events for EventListener """
		type = event.getType()
		
		if type == fife.KeyEvent.PRESSED:
			keyPressed.send(sender=self._maparea, event=event)
		
		elif type == fife.KeyEvent.RELEASED:
			keyReleased.send(sender=self._maparea, event=event)
Exemplo n.º 7
0
class Editor(ApplicationBase, MainWindow):
    """ Editor sets up all subsystems and provides access to them """
    editor = None

    def __init__(self, options, mapfile, *args, **kwargs):
        Editor.editor = self

        self._filemanager = None

        self._options = options
        self._mapfile = mapfile
        self._eventlistener = None
        self._pluginmanager = None

        self._inited = False

        self._mapview = None
        self._mapviewlist = []
        self._mapgroup = None
        self._mapbar = None
        self._maparea = None
        self._mapeditor = None

        self._file_menu = None
        self._edit_menu = None
        self._view_menu = None
        self._tools_menu = None
        self._help_menu = None

        self._change_map = -1

        self._settings = TDS

        self._lighting_mode = int(TDS.get("FIFE", "Lighting"))
        self._help_dialog = None

        self._toolbar_docked = False
        self._toolbar_dockname = ""
        self._toolbox_docked = False
        self._toolbox_dockname = ""

        ApplicationBase.__init__(self, TDS, *args, **kwargs)
        MainWindow.__init__(self, *args, **kwargs)

    def _initTools(self):
        """ Initializes tools """
        if self._options.plugin_dir is not None:
            sys.path.append(os.path.abspath(self._options.plugin_dir))

        self._pluginmanager = plugin.PluginManager(self.getSettings(),
                                                   self._options.plugin_dir)

        self._filemanager = FileManager()
        self._toolbar.adaptLayout()
        self._mapeditor = MapEditor()

    def _initGui(self):
        """ Sets up the GUI """
        screen_width = self.engine.getSettings().getScreenWidth()
        screen_height = self.engine.getSettings().getScreenHeight()
        MainWindow.initGui(self, screen_width, screen_height)

        self._toolbox = ToolBar(name="ToolBox", title=u"", orientation=1)
        self._toolbox.position_technique = "explicit"
        self._toolbox.position = (150, 150)

        self._mapbar = ToolBar(name="MapBar", panel_size=20)
        self._mapbar.setDocked(True)

        self._maparea = pychan.widgets.VBox()
        self._maparea.opaque = False
        self._maparea.is_focusable = True

        # Capture mouse and key events for EventListener
        cw = self._maparea
        cw.capture(self.__sendMouseEvent, "mouseEntered")
        cw.capture(self.__sendMouseEvent, "mouseExited")
        cw.capture(self.__sendMouseEvent, "mousePressed")
        cw.capture(self.__sendMouseEvent, "mouseReleased")
        cw.capture(self.__sendMouseEvent, "mouseClicked")
        cw.capture(self.__sendMouseEvent, "mouseMoved")
        cw.capture(self.__sendMouseEvent, "mouseWheelMovedUp")
        cw.capture(self.__sendMouseEvent, "mouseWheelMovedDown")
        cw.capture(self.__sendMouseEvent, "mouseDragged")
        cw.capture(self.__sendKeyEvent, "keyPressed")
        cw.capture(self.__sendKeyEvent, "keyReleased")

        self._centralwidget.addChild(self._mapbar)
        self._centralwidget.addChild(self._maparea)

        self._initActions()

        self._toolbox.show()

        events.preMapClosed.connect(self._mapRemoved)

    def _initActions(self):
        """ Initializes toolbar and menubar buttons """
        exitAction = Action(u"Exit", "gui/icons/quit.png")
        exitAction.helptext = u"Exit program"
        action.activated.connect(self.quit, sender=exitAction)

        self._file_menu = Menu(name=u"File")
        self._file_menu.addAction(exitAction)

        self._edit_menu = Menu(name=u"Edit")
        self._view_menu = Menu(name=u"View")
        self._tools_menu = Menu(name=u"Tools")
        self._window_menu = Menu(name=u"Window")
        self._help_menu = Menu(name=u"Help")

        self._action_show_statusbar = Action(u"Statusbar", checkable=True)
        self._action_show_statusbar.helptext = u"Toggle statusbar"
        action.activated.connect(self.toggleStatusbar,
                                 sender=self._action_show_statusbar)

        self._action_show_toolbar = Action(u"Toolbar", checkable=True)
        self._action_show_toolbar.helptext = u"Toggle toolbar"
        action.activated.connect(self.toggleToolbar,
                                 sender=self._action_show_toolbar)

        self._action_show_toolbox = Action(u"Tool box", checkable=True)
        self._action_show_toolbox.helptext = u"Toggle tool box"
        action.activated.connect(self.toggleToolbox,
                                 sender=self._action_show_toolbox)

        self._view_menu.addAction(self._action_show_statusbar)
        self._view_menu.addAction(self._action_show_toolbar)
        self._view_menu.addAction(self._action_show_toolbox)
        self._view_menu.addSeparator()

        #These 3 are enabled by default therefore should be checked
        self._action_show_statusbar.setChecked(True)
        self._action_show_toolbar.setChecked(True)
        self._action_show_toolbox.setChecked(True)

        test_action1 = Action(u"Cycle buttonstyles",
                              "gui/icons/cycle_styles.png")
        test_action1.helptext = u"Cycles button styles. There are currently four button styles."
        action.activated.connect(self._actionActivated, sender=test_action1)
        self._view_menu.addAction(test_action1)

        test_action2 = Action(u"Toggle Blocking")
        test_action2.helptext = u"Toggles the blocking infos for the instances."
        action.activated.connect(self.toggleBlocking, sender=test_action2)
        self._view_menu.addAction(test_action2)

        test_action3 = Action(u"Toggle Grid")
        test_action3.helptext = u"Toggles the grids of the map."
        action.activated.connect(self.toggleGrid, sender=test_action3)
        self._view_menu.addAction(test_action3)

        test_action4 = Action(u"Toggle Coordinates")
        test_action4.helptext = u"Toggles the coordinates of the map."
        action.activated.connect(self.toggleCoordinates, sender=test_action4)
        self._view_menu.addAction(test_action4)

        self._mapgroup = ActionGroup(exclusive=True, name="Mapgroup")
        self._mapbar.addAction(self._mapgroup)
        self._window_menu.addAction(self._mapgroup)

        help_action = Action(u"Help", "gui/icons/help.png")
        help_action.helptext = u"Displays a window with some simple instructions"
        action.activated.connect(self._showHelpDialog, sender=help_action)
        self._help_menu.addAction(help_action)

        self._menubar.addMenu(self._file_menu)
        self._menubar.addMenu(self._edit_menu)
        self._menubar.addMenu(self._view_menu)
        self._menubar.addMenu(self._tools_menu)
        self._menubar.addMenu(self._window_menu)
        self._menubar.addMenu(self._help_menu)

    def _actionActivated(self, sender):
        self._toolbar.button_style += 1

    def _showHelpDialog(self, sender):
        """ Shows the help dialog """
        if self._help_dialog is not None:
            self._help_dialog.show()
            return

        self._help_dialog = pychan.loadXML("gui/help.xml")
        self._help_dialog.findChild(name="closeButton").capture(
            self._help_dialog.hide)

        f = open('lang/infotext.txt', 'r')
        self._help_dialog.findChild(name="helpText").text = unicode(f.read())
        f.close()

        self._help_dialog.show()

    def toggleStatusbar(self):
        """ Toggles status bar """
        statusbar = self.getStatusBar()
        if statusbar.max_size[1] > 0:
            statusbar.min_size = (statusbar.min_size[0], 0)
            statusbar.max_size = (statusbar.max_size[0], 0)
            self._action_show_statusbar.setChecked(False)
        else:
            statusbar.min_size = (statusbar.min_size[0], statusbar.min_size[0])
            statusbar.max_size = (statusbar.max_size[0], statusbar.max_size[0])
            self._action_show_statusbar.setChecked(True)
        statusbar.adaptLayout()

    def toggleToolbar(self):
        """ Toggles toolbar """
        toolbar = self.getToolBar()
        if toolbar.isVisible():
            self._toolbar_docked = toolbar.isDocked()
            self._toolbar_dockname = toolbar.dockareaname
            toolbar.hide()
            self._action_show_toolbar.setChecked(False)
        else:
            if not self._toolbar_docked:
                tx = toolbar.x
                ty = toolbar.y
                toolbar.show()
                toolbar.x = tx
                toolbar.y = ty
            else:
                toolbar.setDocked(True)
                self.dockWidgetTo(toolbar, self._toolbar_dockname)

            self._action_show_toolbar.setChecked(True)

    def toggleToolbox(self):
        """ Toggles tool box """
        toolbox = self.getToolbox()
        if toolbox.isVisible():
            self._toolbox_docked = toolbox.isDocked()
            self._toolbox_dockname = toolbox.dockareaname
            toolbox.hide()
            self._action_show_toolbox.setChecked(False)
        else:
            if not self._toolbox_docked:
                tx = toolbox.x
                ty = toolbox.y
                toolbox.show()
                toolbox.x = tx
                toolbox.y = ty
            else:
                toolbox.setDocked(True)
                self.dockWidgetTo(toolbox, self._toolbox_dockname)

            self._action_show_toolbox.setChecked(True)
        #toolbox.adaptLayout()

    def toggleBlocking(self, sender):
        if self._mapview is not None:
            for cam in self._mapview.getMap().getCameras():
                r = fife.BlockingInfoRenderer.getInstance(cam)
                r.setEnabled(not r.isEnabled())

    def toggleGrid(self, sender):
        if self._mapview is not None:
            for cam in self._mapview.getMap().getCameras():
                r = fife.GridRenderer.getInstance(cam)
                r.setEnabled(not r.isEnabled())

    def toggleCoordinates(self, sender):
        if self._mapview is not None:
            for cam in self._mapview.getMap().getCameras():
                r = fife.CoordinateRenderer.getInstance(cam)
                if not r.isEnabled():
                    r.clearActiveLayers()
                    color = str(
                        self._settings.get("Colors", "Coordinate",
                                           "255,255,255"))
                    r.setFont(get_manager().getDefaultFont())
                    r.setColor(*[int(c) for c in color.split(',')])
                    for layer in self._mapview.getMap().getLayers():
                        if layer.areInstancesVisible():
                            r.addActiveLayer(layer)
                    r.setEnabled(True)
                else:
                    r.setEnabled(False)

    def getToolbox(self):
        return self._toolbox

    def getPluginManager(self):
        return self._pluginmanager

    def getEngine(self):
        return self.engine

    def getMapViews(self):
        return self._mapviewlist

    def getActiveMapView(self):
        return self._mapview

    def getSettings(self):
        return self._settings

    def getObject(self):
        return self._mapeditor.getObject()

    def showMapView(self, mapview):
        """ Switches to mapview. """
        if mapview is None or mapview == self._mapview:
            return

        if self._mapview != None and mapview != self._mapview:
            # need to disable the cameras from the previous map
            # if it exists before switching
            if self._mapview.getMap() != None:
                for cam in self._mapview.getMap().getCameras():
                    cam.resetRenderers()
                    cam.setEnabled(False)

        # if light model is set then enable LightRenderer for all layers
        if self._lighting_mode is not 0:
            for cam in mapview.getMap().getCameras():
                renderer = fife.LightRenderer.getInstance(cam)
                renderer.activateAllLayers(mapview.getMap())
                renderer.setEnabled(not renderer.isEnabled())

        events.preMapShown.send(sender=self, mapview=mapview)
        self._mapview = mapview
        self._mapview.show()
        events.postMapShown.send(sender=self, mapview=mapview)

    def createListener(self):
        """ Creates the event listener. This is called by ApplicationBase """
        if self._eventlistener is None:
            self._eventlistener = EventListener(self.engine)

        return self._eventlistener

    def getEventListener(self):
        """ Returns the event listener """
        return self._eventlistener

    def newMapView(self, map):
        """ Creates a new map view """
        mapview = MapView(map)

        self._mapviewlist.append(mapview)

        map_action = Action(unicode(map.getId()))
        action.activated.connect(cbwa(self.showMapView, mapview),
                                 sender=map_action,
                                 weak=False)
        self._mapgroup.addAction(map_action)

        self.showMapView(mapview)

        events.mapAdded.send(sender=self, map=map)

        return mapview

    def _mapRemoved(self, mapview):
        index = self._mapviewlist.index(mapview) - 1

        for cam in mapview.getMap().getCameras():
            cam.resetRenderers()
            cam.setEnabled(False)

        self._mapviewlist.remove(mapview)

        # Remove tab
        for map_action in self._mapgroup.getActions():
            if map_action.text == unicode(mapview.getMap().getId()):
                self._mapgroup.removeAction(map_action)
                break

        # Change mapview
        if len(self._mapviewlist) > 0:
            if index < 0:
                index = 0
            self._change_map = index
        else:
            self._mapview = None

    def openFile(self, path):
        """ Opens a file """
        parts = path.split(os.sep)

        for mapview in self._mapviewlist:
            if path == mapview._map.getFilename():
                self.getStatusBar(
                ).text = u"Map already loaded, omitting map " + parts[-1]
                return

        events.onOpenMapFile.send(sender=self, path=path)

        try:
            map = None
            fife_loader = fife.MapLoader(self.engine.getModel(),
                                         self.engine.getVFS(),
                                         self.engine.getImageManager(),
                                         self.engine.getRenderBackend())
            if self._lighting_mode == 0 and fife_loader.isLoadable(path):
                map = fife_loader.load(path)
            else:
                # TODO: vtchill - once lights are supported by the c++ map loader this can be removed
                map = loaders.loadMapFile(path,
                                          self.engine,
                                          extensions={'lights': True})

            if map:
                self.getStatusBar().text = u"Loaded map: " + parts[-1]
                return self.newMapView(map)
            else:
                self.getStatusBar(
                ).text = u"Map could not be loaded: " + parts[-1]
                return None
        except:
            traceback.print_exc(sys.exc_info()[1])
            errormsg = u"Opening map failed:\n"
            errormsg += u"File: " + unicode(
                path, sys.getfilesystemencoding()) + u"\n"
            errormsg += u"Error: " + unicode(sys.exc_info()[1])
            ErrorDialog(errormsg)
            return None

    def saveAll(self):
        """ Saves all open maps """
        tmpview = self._mapview
        for mapview in self._mapviewlist:
            self._mapview = mapview
            self._filemanager.save()
        self._mapview = tmpview

    def quit(self):
        """ Quits the editor. An onQuit signal is sent before the application closes """
        events.onQuit.send(sender=self)

        self._pluginmanager.stop()

        self._settings.saveSettings()
        ApplicationBase.quit(self)

    def _pump(self):
        """ Called once per frame """
        # ApplicationBase and Engine should be done initializing at this point
        if self._inited == False:
            self._initGui()
            self._initTools()
            if self._mapfile: self.openFile(self._mapfile)
            self._inited = True

        # FIXME: This isn't very nice, but it is needed to change the map
        #		 outside the callback.
        if self._change_map >= 0 and len(self._mapviewlist) > 0:
            if self._change_map >= len(self._mapviewlist):
                self._change_map = len(self._mapviewlist) - 1
            mapview = self._mapviewlist[self._change_map]

            self.showMapView(mapview)
            self._change_map = -1

        events.onPump.send(sender=self)

    def __sendMouseEvent(self, event, **kwargs):
        """ Function used to capture mouse events for EventListener """
        ms_event = fife.MouseEvent
        type = event.getType()

        if type == ms_event.MOVED:
            mouseMoved.send(sender=self._maparea, event=event)

        elif type == ms_event.PRESSED:
            mousePressed.send(sender=self._maparea, event=event)

        elif type == ms_event.RELEASED:
            mouseReleased.send(sender=self._maparea, event=event)

        elif type == ms_event.WHEEL_MOVED_DOWN:
            mouseWheelMovedDown.send(sender=self._maparea, event=event)

        elif type == ms_event.WHEEL_MOVED_UP:
            mouseWheelMovedUp.send(sender=self._maparea, event=event)

        elif type == ms_event.CLICKED:
            mouseClicked.send(sender=self._maparea, event=event)

        elif type == ms_event.ENTERED:
            mouseEntered.send(sender=self._maparea, event=event)

        elif type == ms_event.EXITED:
            mouseExited.send(sender=self._maparea, event=event)

        elif type == ms_event.DRAGGED:
            mouseDragged.send(sender=self._maparea, event=event)

    def __sendKeyEvent(self, event, **kwargs):
        """ Function used to capture key events for EventListener """
        type = event.getType()

        if type == fife.KeyEvent.PRESSED:
            keyPressed.send(sender=self._maparea, event=event)

        elif type == fife.KeyEvent.RELEASED:
            keyReleased.send(sender=self._maparea, event=event)
Exemplo n.º 8
-1
class VisualStates(QMainWindow):
    def __init__(self, parent=None):
        super(QMainWindow, self).__init__()

        self.setWindowTitle("VisualStates")
        self.configDialog = None

        # root state
        self.rootState = State(0, "root", True)
        self.activeState = self.rootState

        # create status bar
        self.statusBar()

        self.createMenu()
        self.createTreeView()
        self.createStateCanvas()

        self.setGeometry(0, 0, 800, 600)
        self.show()

        self.fileManager = FileManager()

        self.libraries = []
        self.config = None
        self.interfaceHeaderMap = Interfaces.getInterfaces()

    def createMenu(self):
        # create actions
        newAction = QAction('&New', self)
        newAction.setShortcut('Ctrl+N')
        newAction.setStatusTip('Create New Visual States')
        newAction.triggered.connect(self.newAction)

        openAction = QAction('&Open', self)
        openAction.setShortcut('Ctrl+O')
        openAction.setStatusTip('Open Visual States')
        openAction.triggered.connect(self.openAction)

        saveAction = QAction('&Save', self)
        saveAction.setShortcut('Ctrl+S')
        saveAction.setStatusTip('Save Visual States')
        saveAction.triggered.connect(self.saveAction)

        saveAsAction = QAction('&Save As', self)
        saveAsAction.setShortcut('Ctrl+S')
        saveAsAction.setStatusTip('Save Visual States as New One')
        saveAsAction.triggered.connect(self.saveAsAction)

        quitAction = QAction('&Quit', self)
        quitAction.setShortcut('Ctrl+Q')
        quitAction.setStatusTip('Quit Visual States')
        quitAction.triggered.connect(self.quitAction)

        # figures menu
        stateAction = QAction('&State', self)
        stateAction.setStatusTip('Create a state')
        stateAction.triggered.connect(self.stateAction)

        transitionAction = QAction('&Transition', self)
        transitionAction.setStatusTip('Create a transition')
        transitionAction.triggered.connect(self.transitionAction)

        # data menu
        timerAction = QAction('&Timer', self)
        timerAction.setShortcut('Ctrl+M')
        timerAction.setStatusTip('Set timing of states')
        timerAction.triggered.connect(self.timerAction)

        variablesAction = QAction('&Variables', self)
        variablesAction.setShortcut('Ctrl+V')
        variablesAction.setStatusTip('Define state variables')
        variablesAction.triggered.connect(self.variablesAction)

        functionsAction = QAction('&Functions', self)
        functionsAction.setShortcut('Ctrl+F')
        functionsAction.setStatusTip('Define functions')
        functionsAction.triggered.connect(self.functionsAction)

        # actions menu
        librariesAction = QAction('&Libraries', self)
        librariesAction.setShortcut('Ctrl+L')
        librariesAction.setStatusTip('Add additional libraries')
        librariesAction.triggered.connect(self.librariesAction)

        configFileAction = QAction('&Config File', self)
        configFileAction.setShortcut('Ctrl+C')
        configFileAction.setStatusTip('Edit configuration file')
        configFileAction.triggered.connect(self.configFileAction)

        generateCppAction = QAction('&Generate C++', self)
        generateCppAction.setShortcut('Ctrl+G')
        generateCppAction.setStatusTip('Generate C++ code')
        generateCppAction.triggered.connect(self.generateCppAction)

        compileCppAction = QAction('&Compile C++', self)
        compileCppAction.setShortcut('Ctrl+P')
        compileCppAction.setStatusTip('Compile generated C++ code')
        compileCppAction.triggered.connect(self.compileCppAction)

        generatePythonAction = QAction('&Generate Python', self)
        generatePythonAction.setShortcut('Ctrl+Y')
        generatePythonAction.setStatusTip('Generate Python code')
        generatePythonAction.triggered.connect(self.generatePythonAction)

        # help menu
        aboutAction = QAction('&About', self)
        aboutAction.setShortcut('F1')
        aboutAction.setStatusTip('Information about VisualStates')
        aboutAction.triggered.connect(self.aboutAction)

        # create main menu
        menubar = self.menuBar()
        archieveMenu = menubar.addMenu('&File')
        archieveMenu.addAction(newAction)
        archieveMenu.addAction(openAction)
        archieveMenu.addAction(saveAction)
        archieveMenu.addAction(saveAsAction)
        archieveMenu.addAction(quitAction)

        figuresMenu = menubar.addMenu('&Figures')
        figuresMenu.addAction(stateAction)
        figuresMenu.addAction(transitionAction)

        dataMenu = menubar.addMenu('&Data')
        dataMenu.addAction(timerAction)
        dataMenu.addAction(variablesAction)
        dataMenu.addAction(functionsAction)

        actionsMenu = menubar.addMenu('&Actions')
        actionsMenu.addAction(librariesAction)
        actionsMenu.addAction(configFileAction)
        actionsMenu.addAction(generateCppAction)
        actionsMenu.addAction(compileCppAction)
        actionsMenu.addAction(generatePythonAction)

        helpMenu = menubar.addMenu('&Help')
        helpMenu.addAction(aboutAction)


    def newAction(self):
        self.automataScene.clearScene()
        # create new root state
        self.rootState = State(0, 'root', True)
        self.automataScene.setActiveState(self.rootState)
        self.automataScene.resetIndexes()

    def openAction(self):
        fileDialog = QFileDialog(self)
        fileDialog.setWindowTitle("Open VisualStates File")
        fileDialog.setViewMode(QFileDialog.Detail)
        fileDialog.setNameFilters(['VisualStates File (*.xml)'])
        fileDialog.setDefaultSuffix('.xml')
        fileDialog.setAcceptMode(QFileDialog.AcceptOpen)
        if fileDialog.exec_():
            (self.rootState, self.config, self.libraries) = self.fileManager.open(fileDialog.selectedFiles()[0])
            self.treeModel.removeAll()
            self.treeModel.loadFromRoot(self.rootState)
            # set the active state as the loaded state
            self.automataScene.setActiveState(self.rootState)
            self.automataScene.setLastIndexes(self.rootState)
            # print(str(self.config))
        # else:
        #     print('open is canceled')



    def saveAction(self):
        if len(self.fileManager.getFileName()) == 0:
            self.saveAsAction()
        else:
            self.fileManager.save(self.rootState, self.config, self.libraries)

    def saveAsAction(self):
        fileDialog = QFileDialog(self)
        fileDialog.setWindowTitle("Save VisualStates Project")
        fileDialog.setViewMode(QFileDialog.Detail)
        fileDialog.setNameFilters(['VisualStates File (*.xml)'])
        fileDialog.setAcceptMode(QFileDialog.AcceptSave)
        if fileDialog.exec_():
            self.fileManager.setFullPath(fileDialog.selectedFiles()[0])
            self.fileManager.save(self.rootState, self.config, self.libraries)
        # else:
        #     print('file dialog canceled')


    def quitAction(self):
        # print('Quit')
        self.close()

    def stateAction(self):
        self.automataScene.setOperationType(OpType.ADDSTATE)

    def transitionAction(self):
        self.automataScene.setOperationType(OpType.ADDTRANSITION)

    def timerAction(self):
        if self.activeState is not None:
            timerDialog = TimerDialog('Time Step Duration', str(self.activeState.getTimeStep()))
            timerDialog.timeChanged.connect(self.timeStepDurationChanged)
            timerDialog.exec_()

    def variablesAction(self):
        if self.activeState is not None:
            variablesDialog = CodeDialog('Variables', self.activeState.getVariables())
            variablesDialog.codeChanged.connect(self.variablesChanged)
            variablesDialog.exec_()
        else:
            self.showWarning('Choose a state', 'You can create variables only for a selected state')

    def functionsAction(self):
        if self.activeState is not None:
            functionsDialog = CodeDialog('Functions', self.activeState.getFunctions())
            functionsDialog.codeChanged.connect(self.functionsChanged)
            functionsDialog.exec_()
        else:
            self.showWarning('Choose a state', 'You can create functions only for a selected state')

    def librariesAction(self):
        librariesDialog = LibrariesDialog('Libraries', self.libraries)
        librariesDialog.librariesChanged.connect(self.librariesChanged)
        librariesDialog.exec_()

    def configFileAction(self):
        self.configDialog = ConfigDialog('Config', self.config)
        self.configDialog.configChanged.connect(self.configChanged)
        self.configDialog.exec_()


    def showWarning(self, title, msg):
        QMessageBox.warning(self, title, msg)

    def showInfo(self, title, msg):
        QMessageBox.information(self, title, msg)

    def generateCppAction(self):
        stateList = []
        if self.fileManager.hasFile():
            self.getStateList(self.rootState, stateList)
            if self.config.type == ROS:
                generator = CppRosGenerator(self.libraries, self.config, self.interfaceHeaderMap, stateList)
            elif self.config.type == JDEROBOTCOMM:
                generator = CppGenerator(self.libraries, self.config, self.interfaceHeaderMap, stateList)

            generator.generate(self.fileManager.getPath(), self.fileManager.getFileName())
            self.showInfo('C++ Code Generation', 'C++ code generation is successful.')
        else:
            self.showWarning('C++ Generation', 'Please save the project before code generation.')


    def compileCppAction(self):
        # print('compile cpp action')
        pass

    def generatePythonAction(self):
        stateList = []
        if self.fileManager.hasFile():
            self.getStateList(self.rootState, stateList)
            if self.config.type == ROS:
                generator = PythonRosGenerator(self.libraries, self.config, stateList)
            elif self.config.type == JDEROBOTCOMM:
                generator = PythonGenerator(self.libraries, self.config, self.interfaceHeaderMap, stateList)
            generator.generate(self.fileManager.getPath(), self.fileManager.getFileName())
            self.showInfo('Python Code Generation', 'Python code generation is successful.')
        else:
            self.showWarning('Python Generation', 'Please save the project before code generation.')

    def aboutAction(self):
        pass
        # print('about action')

    def createTreeView(self):
        dockWidget = QDockWidget()
        dockWidget.setAllowedAreas(Qt.LeftDockWidgetArea)
        dockWidget.setFeatures(QDockWidget.NoDockWidgetFeatures)
        dockWidget.setTitleBarWidget(QWidget())
        self.treeView = QTreeView()
        self.treeView.clicked.connect(self.treeItemClicked)
        self.treeModel = TreeModel()
        self.treeView.setModel(self.treeModel)

        self.logo = QLabel()
        logoPixmap = QPixmap(CMAKE_INSTALL_PREFIX + '/share/jderobot/resources/jderobot.png')
        self.logo.setPixmap(logoPixmap)

        self.upButton = QPushButton()
        self.upButton.setText('Up')
        self.upButton.clicked.connect(self.upButtonClicked)

        leftContainer = QWidget()
        leftLayout = QVBoxLayout()
        leftLayout.addWidget(self.treeView)
        leftLayout.addWidget(self.upButton)
        leftLayout.addWidget(self.logo)
        leftContainer.setLayout(leftLayout)

        dockWidget.setWidget(leftContainer)
        self.addDockWidget(Qt.LeftDockWidgetArea, dockWidget)

    def createStateCanvas(self):
        self.stateCanvas = QGraphicsView()
        self.automataScene = AutomataScene()
        self.automataScene.setSceneRect(0, 0, 2000, 2000)
        self.automataScene.activeStateChanged.connect(self.activeStateChanged)
        self.automataScene.stateInserted.connect(self.stateInserted)
        self.automataScene.stateRemoved.connect(self.stateRemoved)
        self.automataScene.transitionInserted.connect(self.transitionInserted)
        self.automataScene.stateNameChangedSignal.connect(self.stateNameChanged)
        self.automataScene.setActiveState(self.rootState)

        self.setCentralWidget(self.stateCanvas)
        self.stateCanvas.setScene(self.automataScene)
        self.stateCanvas.setRenderHint(QPainter.Antialiasing)
        self.stateCanvas.setAcceptDrops(True)

    def stateInserted(self, state):
        if self.activeState != self.rootState:
            parent = self.treeModel.getByDataId(self.activeState.id)
            self.treeModel.insertState(state, QColor(Qt.white), parent)
        else:
            self.treeModel.insertState(state, QColor(Qt.white))

    def stateRemoved(self, state):
        if self.activeState != self.rootState:
            self.treeModel.removeState(state.stateData, self.activeState)
        else:
            self.treeModel.removeState(state.stateData)

    def transitionInserted(self, tran):
        # print('transition inserted:' + tran.transitionData.name)
        pass

    def stateNameChanged(self, state):
        dataItem = self.treeModel.getByDataId(state.stateData.id)
        if dataItem != None:
            dataItem.name = state.stateData.name
            self.treeModel.layoutChanged.emit()

    def activeStateChanged(self):
        if self.automataScene.activeState != self.activeState:
            # print('visual states active state changed:' + self.automataScene.activeState.name)
            self.activeState = self.automataScene.activeState
            if self.activeState == self.rootState:
                self.treeView.selectionModel().clearSelection()
            else:
                self.treeView.setCurrentIndex(self.treeModel.indexOf(self.treeModel.getByDataId(self.activeState.id)))

    def upButtonClicked(self):
        if self.activeState != None:
            if self.activeState.parent != None:
                # print('parent name:' + self.activeState.parent.name)
                self.automataScene.setActiveState(self.activeState.parent)


    def getStateById(self,state, id):
        if state.id == id:
            return state
        else:
            result = None
            for child in state.getChildren():
                result = self.getStateById(child, id)
                if result is not None:
                    return result
            return result

    def treeItemClicked(self, index):
        # print('clicked item.id:' + str(index.internalPointer().id))
        state = self.getStateById(self.rootState, index.internalPointer().id)
        if state is not None:
            # set the active state as the loaded state
            self.automataScene.setActiveState(state)

    def timeStepDurationChanged(self, duration):
        if self.activeState is not None:
            self.activeState.setTimeStep(duration)

    def variablesChanged(self, variables):
        if self.activeState is not None:
            self.activeState.setVariables(variables)

    def functionsChanged(self, functions):
        if self.activeState is not None:
            self.activeState.setFunctions(functions)

    def librariesChanged(self, libraries):
        self.libraries = libraries

    def configChanged(self):
        if self.configDialog is not None:
            self.config = self.configDialog.getConfig()

    def getStateList(self, state, stateList):
        if len(state.getChildren()) > 0:
            stateList.append(state)

        for s in state.getChildren():
            self.getStateList(s, stateList)