def signal_handler(signal, frame): state_machine_execution_engine = core_singletons.state_machine_execution_engine core_singletons.shut_down_signal = signal # in this case the print is on purpose the see more easily if the interrupt signal reached the thread print _( "Signal '{}' received.\nExecution engine will be stopped and program will be shutdown!" ).format(SIGNALS_TO_NAMES_DICT.get(signal, "[unknown]")) try: if not state_machine_execution_engine.finished_or_stopped(): state_machine_execution_engine.stop() state_machine_execution_engine.join( 3) # Wait max 3 sec for the execution to stop except Exception as e: import traceback print _("Could not stop state machine: {0} {1}").format( e.message, traceback.format_exc()) try: gui_singletons.main_window_controller.prepare_destruction() except Exception as e: print "Exception while preparing destruction", e os._exit(1) stop_gtk() post_gui_destruction() # Do not use sys.exit() in signal handler: # http://thushw.blogspot.de/2010/12/python-dont-use-sysexit-inside-signal.html os._exit(0)
def open_state_machines(paths): import rafcon.gui.helpers.state_machine as gui_helper_state_machine first_sm = None for path in paths: try: sm = gui_helper_state_machine.open_state_machine( path=path, recent_opened_notification=True) if first_sm is None: first_sm = sm except Exception as e: logger.exception( _("Could not load state machine '{}': {}").format(path, e)) return first_sm
def __init__(self): View.__init__(self) button_new = self['button_new'] button_new.set_label_widget( create_label_widget_with_icon(constants.BUTTON_NEW, _("New state machine"))) button_refresh = self['button_refresh'] button_refresh.set_label_widget( create_label_widget_with_icon( constants.BUTTON_REFR, _("Refresh"), "Refresh all libraries and state machines")) button_refresh_selected = self['button_refresh_selected'] button_refresh_selected.set_label_widget( create_label_widget_with_icon(constants.BUTTON_REFR, _("Refresh Selected"), "Refresh selected state machine")) button_open = self['button_open'] button_open.set_label_widget( create_label_widget_with_icon(constants.BUTTON_OPEN, _("Open state machine"))) button_save = self['button_save'] button_save.set_label_widget( create_label_widget_with_icon(constants.BUTTON_SAVE, _("Save state machine"))) button_refresh_libs = self['button_refresh_libs'] button_refresh_libs.set_label_widget( create_label_widget_with_icon(constants.BUTTON_REFR, _("Refresh Libraries"), "Refresh all libraries")) button_bake_state_machine = self['button_bake_state_machine'] button_bake_state_machine.set_label_widget( create_label_widget_with_icon( constants.BUTTON_BAKE, _("Bake State Machine"), "Saves the currently selected state machine and all library folders it refers to" ))
def main(): # check if all env variables are set if not os.environ.get("HOME", False): logger.error( "For starting RAFCON in GUI mode, the HOME environment variable has to be set!" ) return register_signal_handlers(signal_handler) splash_screen = SplashScreen(contains_image=True, width=530, height=350) splash_screen.rotate_image(random_=True) splash_screen.set_text(_("Starting RAFCON...")) while gtk.events_pending(): gtk.main_iteration() setup_installation() setup_l10n() setup_l10n_gtk() splash_screen.set_text("Setting up logger...") setup_gtkmvc_logger() splash_screen.set_text("Initializing plugins...") pre_setup_plugins() splash_screen.set_text("Setting up environment...") setup_mvc_environment() parser = setup_argument_parser() user_input = parser.parse_args() splash_screen.set_text("Loading configurations...") setup_mvc_configuration(user_input.config_path, user_input.gui_config_path, user_input.gui_config_path) # create lock file -> keep behavior for hole instance if global_gui_config.get_config_value('AUTO_RECOVERY_LOCK_ENABLED'): rafcon.gui.models.auto_backup.generate_rafcon_instance_lock_file() # setup the gui before loading the state machine as then the debug console shows the errors that emerged during # loading the state state machine splash_screen.set_text("Loading GUI...") setup_gui() wait_for_gui() post_setup_plugins(user_input) state_machine = None if user_input.state_machine_paths: state_machine = open_state_machines(user_input.state_machine_paths) if user_input.new: create_new_state_machine() # initiate stored session # TODO think about a controller for this if not user_input.new and not user_input.state_machine_paths \ and rafcon.gui.singleton.global_gui_config.get_config_value("SESSION_RESTORE_ENABLED"): glib.idle_add(backup_session.restore_session_from_runtime_config, priority=glib.PRIORITY_LOW) if state_machine and (user_input.start_state_machine_flag or state_machine.get_state_by_path( user_input.start_state_path)): start_state_machine(state_machine, user_input.start_state_path, user_input.quit_flag) splash_screen.destroy() try: start_gtk() logger.info(_("Main window was closed")) finally: post_gui_destruction() if core_singletons.state_machine_execution_engine.status.execution_mode == StateMachineExecutionStatus.STARTED: logger.info(_("Waiting for the state machine execution to finish")) core_singletons.state_machine_execution_engine.join() logger.info(_("State machine execution has finished")) logger.info(_("Exiting ..."))
def setup_argument_parser(): """Sets up teh parser with the required arguments :return: The parser object """ default_config_path = filesystem.get_default_config_path() filesystem.create_path(default_config_path) parser = core_singletons.argument_parser parser.add_argument('-n', '--new', action='store_true', help=_("whether to create a new state-machine")) parser.add_argument( '-o', '--open', action='store', nargs='*', type=parse_state_machine_path, dest='state_machine_paths', metavar='path', help=_( "specify directories of state-machines that shall be opened. Paths must contain a " "statemachine.json file")) parser.add_argument( '-c', '--config', action='store', type=config_path, metavar='path', dest='config_path', default=default_config_path, nargs='?', const=default_config_path, help=_( "path to the configuration file config.yaml. Use 'None' to prevent the generation of a " "config file and use the default configuration. Default: {0}" "").format(default_config_path)) parser.add_argument( '-g', '--gui_config', action='store', type=config_path, metavar='path', dest='gui_config_path', default=default_config_path, nargs='?', const=default_config_path, help=_( "path to the configuration file gui_config.yaml. " "Use 'None' to prevent the generation of a config file and use the default " "configuration. Default: {0}").format(default_config_path)) parser.add_argument( '-ss', '--start_state_machine', dest='start_state_machine_flag', action='store_true', help= _("a flag to specify if the first state machine of -o should be started after opening" )) parser.add_argument( '-s', '--start_state_path', metavar='path', dest='start_state_path', default=None, nargs='?', help= _("path within a state machine to the state that should be launched which consists of " "state ids e.g. QPOXGD/YVWJKZ where QPOXGD is the root state and YVWJKZ its child states" " to start from.")) parser.add_argument( '-q', '--quit', dest='quit_flag', action='store_true', help= _("a flag to specify if the gui should quit after launching a state machine" )) return parser
def __init__(self): View.__init__(self) if os.getenv("RAFCON_START_MINIMIZED", False): self.get_top_widget().iconify() # Add gui components by removing their corresponding placeholders defined in the glade file first and then # adding the widgets. self.left_bar_notebooks = [ self['upper_notebook'], self['lower_notebook'] ] ################################################ # Undock Buttons ################################################ self['undock_left_bar_button'].set_image( gui_helper_label.create_button_label(constants.BUTTON_UNDOCK)) self['undock_left_bar_button'].set_tooltip_text( "Undock left side bar widget") self['undock_right_bar_button'].set_image( gui_helper_label.create_button_label(constants.BUTTON_UNDOCK)) self['undock_right_bar_button'].set_tooltip_text( "Undock right side bar widget") self['collapse_tree_button'].set_image( gui_helper_label.create_button_label(constants.BUTTON_COLLAPSE)) self['collapse_tree_button'].set_tooltip_text( "Collapse tree of widget") ###################################################### # Library Tree ###################################################### self.library_tree = LibraryTreeView() self.library_tree.show() self['libraries_alignment'].add(self.library_tree) ###################################################### # State Icons ###################################################### self.state_icons = StateIconView() self.state_icons.show() self["state_icons_box"].pack_start(self.state_icons.get_top_widget()) ###################################################### # State Machine Tree ###################################################### self.state_machine_tree = StateMachineTreeView() self.state_machine_tree.show() self['states_tree_alignment'].add(self.state_machine_tree) ###################################################### # Global Variable Manager ###################################################### self.global_var_editor = GlobalVariableEditorView() self.global_var_editor.show() self['global_variables_alignment'].add( self.global_var_editor.get_top_widget()) ###################################################### # State Machine History ###################################################### self.state_machine_history = ModificationHistoryView() self.state_machine_history.show() self['history_alignment'].add( self.state_machine_history.get_top_widget()) ###################################################### # State Machine Execution History ###################################################### self.execution_history = ExecutionHistoryView() self.execution_history.show() self['execution_history_alignment'].add( self.execution_history.get_top_widget()) ###################################################### # rotate all tab labels by 90 degrees and make detachable ###################################################### self.rotate_and_detach_tab_labels() self['upper_notebook'].set_current_page(0) self['lower_notebook'].set_current_page(0) ###################################################### # State-machines-editor (graphical) ###################################################### self.state_machines_editor = StateMachinesEditorView() self.state_machines_editor.show() self['graphical_editor_vbox'].pack_start( self.state_machines_editor.get_top_widget(), True, True, 0) self['graphical_editor_vbox'].reorder_child( self.state_machines_editor.get_top_widget(), 0) self['graphical_editor_label_event_box'].remove( self['graphical_editor_label']) self['graphical_editor_label_event_box'].set_border_width( constants.GRID_SIZE) graphical_editor_label = gui_helper_label.create_label_with_text_and_spacing( _('GRAPHICAL EDITOR'), font_size=constants.FONT_SIZE_BIG, letter_spacing=constants.LETTER_SPACING_1PT) graphical_editor_label.set_alignment(0, .5) self['graphical_editor_label_event_box'].add(graphical_editor_label) ###################################################### # States-editor ###################################################### self.states_editor = StatesEditorView() self['state_editor_eventbox'].add(self.states_editor.get_top_widget()) self.states_editor.show() self['state_editor_label_hbox'].remove(self['state_editor_label']) self['state_editor_label_hbox'].set_border_width(constants.GRID_SIZE) state_editor_label = gui_helper_label.create_label_with_text_and_spacing( _('STATE EDITOR'), font_size=constants.FONT_SIZE_BIG, letter_spacing=constants.LETTER_SPACING_1PT) state_editor_label.set_alignment(0., 0.) self['state_editor_label_hbox'].add(state_editor_label) ###################################################### # Debug Console ###################################################### self.debug_console_view = DebugConsoleView() self['debug_console_viewport'].add( self.debug_console_view.get_top_widget()) self.debug_console_view.get_top_widget().show() # map hide and undock buttons within and debug widget to be usable from main window view with generic naming self['undock_console_button'] = self.debug_console_view[ 'undock_console_button'] self['console_hide_button'] = self.debug_console_view[ 'console_hide_button'] self['console_container'] = self.debug_console_view[ 'console_container'] self['console'] = self.debug_console_view['console'] ################################################## # menu bar view ################################################## self.top_tool_bar = TopToolBarView() self.top_tool_bar.show() self['top_menu_hbox'].remove(self['top_tool_bar_placeholder']) self['top_menu_hbox'].pack_end(self.top_tool_bar.get_top_widget(), expand=True, fill=True, padding=0) self['top_menu_hbox'].reorder_child(self.top_tool_bar.get_top_widget(), 1) self.menu_bar = MenuBarView(self) self.menu_bar.show() self['top_menu_hbox'].remove(self['menu_bar_placeholder']) self['top_menu_hbox'].pack_start(self.menu_bar.get_top_widget(), expand=False, fill=True, padding=0) self['top_menu_hbox'].reorder_child(self.menu_bar.get_top_widget(), 0) self.tool_bar = ToolBarView() self.tool_bar.show() self['top_level_vbox'].remove(self['tool_bar_placeholder']) self['top_level_vbox'].pack_start(self.tool_bar.get_top_widget(), expand=False, fill=True, padding=0) self['top_level_vbox'].reorder_child(self.tool_bar.get_top_widget(), 1) ################################################ # Hide Buttons ################################################ self['left_bar_hide_button'].set_image( gui_helper_label.create_button_label(constants.BUTTON_LEFTA)) self['right_bar_hide_button'].set_image( gui_helper_label.create_button_label(constants.BUTTON_RIGHTA)) ################################################ # Return Buttons ################################################ self['left_bar_return_button'].set_image( gui_helper_label.create_button_label(constants.BUTTON_RIGHTA)) self['right_bar_return_button'].set_image( gui_helper_label.create_button_label(constants.BUTTON_LEFTA)) self['console_return_button'].set_image( gui_helper_label.create_button_label(constants.BUTTON_UPA)) # -------------------------------------------------------------------------- # Edit graphical_editor_shortcuts # -------------------------------------------------------------------------- button_start_shortcut = self['button_start_shortcut'] button_start_shortcut.set_tooltip_text('Run') button_stop_shortcut = self['button_stop_shortcut'] button_stop_shortcut.set_tooltip_text('Stop') button_pause_shortcut = self['button_pause_shortcut'] button_pause_shortcut.set_tooltip_text('Pause') button_start_from_shortcut = self['button_start_from_shortcut'] button_start_from_shortcut.set_tooltip_text('Run From Selected State') button_run_to_shortcut = self['button_run_to_shortcut'] button_run_to_shortcut.set_tooltip_text( 'Run Until Selected State (Selected State Excluded)') button_step_mode_shortcut = self['button_step_mode_shortcut'] button_step_mode_shortcut.set_tooltip_text('Enter Step Mode') button_step_in_shortcut = self['button_step_in_shortcut'] button_step_in_shortcut.set_tooltip_text( 'Step Into (One Level In -> Child-State))') button_step_over_shortcut = self['button_step_over_shortcut'] button_step_over_shortcut.set_tooltip_text( 'Step Over (the next Sibling-State))') button_step_out_shortcut = self['button_step_out_shortcut'] button_step_out_shortcut.set_tooltip_text( 'Step Out (One Level Up -> Parent-State)') button_step_backward_shortcut = self['button_step_backward_shortcut'] button_step_backward_shortcut.set_tooltip_text('Step Backward') button_start_shortcut.set_label_widget( gui_helper_label.create_button_label(constants.BUTTON_START)) button_stop_shortcut.set_label_widget( gui_helper_label.create_button_label(constants.BUTTON_STOP)) button_pause_shortcut.set_label_widget( gui_helper_label.create_button_label(constants.BUTTON_PAUSE)) button_start_from_shortcut.set_label_widget( gui_helper_label.create_button_label( constants.BUTTON_START_FROM_SELECTED_STATE)) button_run_to_shortcut.set_label_widget( gui_helper_label.create_button_label( constants.BUTTON_RUN_TO_SELECTED_STATE)) button_step_mode_shortcut.set_label_widget( gui_helper_label.create_button_label(constants.BUTTON_STEPM)) button_step_in_shortcut.set_label_widget( gui_helper_label.create_button_label(constants.BUTTON_STEP_INTO)) button_step_over_shortcut.set_label_widget( gui_helper_label.create_button_label(constants.BUTTON_STEP_OVER)) button_step_out_shortcut.set_label_widget( gui_helper_label.create_button_label(constants.BUTTON_STEP_OUT)) button_step_backward_shortcut.set_label_widget( gui_helper_label.create_button_label(constants.BUTTON_BACKW)) # -------------------------------------------------------------------------- self.get_top_widget().set_decorated(False) self['upper_notebook'].set_tab_hborder(constants.TAB_BORDER_WIDTH * 2) self['upper_notebook'].set_tab_vborder(constants.TAB_BORDER_WIDTH * 3) if global_gui_config.get_config_value("USE_ICONS_AS_TAB_LABELS", True): self['lower_notebook'].set_tab_hborder( int(constants.TAB_BORDER_WIDTH * 2 / 1.4)) else: self['lower_notebook'].set_tab_hborder(constants.TAB_BORDER_WIDTH * 2) self['lower_notebook'].set_tab_vborder(constants.TAB_BORDER_WIDTH * 3) self.left_bar_window = UndockedWindowView('left_bar_window') self.right_bar_window = UndockedWindowView('right_bar_window') self.console_window = UndockedWindowView('console_window')
def remove_rafcon_instance_lock_file(): logger.debug(_("Remove lock file for RAFCON instance {0}".format(os.getpid()))) if os.path.exists(RAFCON_INSTANCE_LOCK_FILE_PATH): os.remove(RAFCON_INSTANCE_LOCK_FILE_PATH) else: logger.warning(_("External remove of lock file detected!"))
def generate_rafcon_instance_lock_file(): logger.debug(_("Generate lock file for RAFCON instance {0}".format(os.getpid()))) file_handler = open(RAFCON_INSTANCE_LOCK_FILE_PATH, 'a+') file_handler.close()
from rafcon.utils import log from rafcon.utils.storage_utils import get_time_string_for_float logger = log.get_logger(__name__) FILE_NAME_AUTO_BACKUP = 'auto_backup.json' MY_RAFCON_TEMP_PATH = str(os.path.sep).join(RAFCON_TEMP_PATH_BASE.split(os.path.sep)[:-1]) RAFCON_RUNTIME_BACKUP_PATH = os.path.join(RAFCON_TEMP_PATH_BASE, 'runtime_backup') if not os.path.exists(RAFCON_RUNTIME_BACKUP_PATH): os.makedirs(RAFCON_RUNTIME_BACKUP_PATH) try: import psutil process_id_list = [process.pid for process in psutil.process_iter()] except (OSError, ImportError): logger.info(_("Could not retrieve list of current process ids")) process_id_list = [] def generate_rafcon_instance_lock_file(): logger.debug(_("Generate lock file for RAFCON instance {0}".format(os.getpid()))) file_handler = open(RAFCON_INSTANCE_LOCK_FILE_PATH, 'a+') file_handler.close() def remove_rafcon_instance_lock_file(): logger.debug(_("Remove lock file for RAFCON instance {0}".format(os.getpid()))) if os.path.exists(RAFCON_INSTANCE_LOCK_FILE_PATH): os.remove(RAFCON_INSTANCE_LOCK_FILE_PATH) else: logger.warning(_("External remove of lock file detected!"))