Example #1
0
def set_window_size_and_position(window, window_key):
    """Adjust GTK Window's size, position and maximized state according to the corresponding values in the
    runtime_config file. The maximize method is triggered last to restore also the last stored size and position of the
    window. If the runtime_config does not exist, or the corresponding values are missing in the file, default values
    for the window size are used, and the mouse position is used to adjust the window's position.

    :param window: The GTK Window to be adjusted
    :param window_key: The window's key stored in the runtime config file
     """
    size = global_runtime_config.get_config_value(window_key + '_WINDOW_SIZE')
    position = global_runtime_config.get_config_value(window_key +
                                                      '_WINDOW_POS')
    maximized = global_runtime_config.get_config_value(window_key +
                                                       '_WINDOW_MAXIMIZED')

    # un-maximize here on purpose otherwise resize and reposition fails
    if not maximized:
        window.unmaximize()

    if not size:
        size = constants.WINDOW_SIZE[window_key + '_WINDOW']
    window.resize(*size)
    if position:
        position = (max(0, position[0]), max(0, position[1]))
        screen_width = gtk.gdk.screen_width()
        screen_height = gtk.gdk.screen_height()
        if position[0] < screen_width and position[1] < screen_height:
            window.move(*position)
    else:
        window.set_position(gtk.WIN_POS_MOUSE)
    if maximized:
        window.maximize()
    window.show()
Example #2
0
def save_folder(query, default_name=None):
    """Shows a user dialog to save a folder/file

    A dialog is opened with the prompt `query`. The current path is set to the last path that was opened/created. The
    roots of all libraries is added to the list of shortcut folders. The file name can be folder or file.
    No existence check is performed.

    :param str query: Prompt asking the user for a specific path and a name in the entry widget
    :param str default_name: Default name of mounting point/library root key
    :return: Path handed by the user or `last_path`/`default_name` if no path was specified and None if directory
      does not exist (parent of name)
    :rtype: str
    """
    from os.path import expanduser, dirname, join, exists, isdir
    from gi.repository import Gtk
    from rafcon.core.storage.storage import STATEMACHINE_FILE
    from rafcon.gui.singleton import main_window_controller
    from rafcon.gui.runtime_config import global_runtime_config
    last_path = global_runtime_config.get_config_value('LAST_PATH_OPEN_SAVE',
                                                       "")

    if last_path and isdir(last_path) and not exists(
            join(last_path, STATEMACHINE_FILE)):
        pass
    elif last_path:
        last_path = dirname(last_path)
    else:
        last_path = expanduser('~')

    dialog = Gtk.FileChooserDialog(title=query,
                                   transient_for=None,
                                   action=Gtk.FileChooserAction.SAVE)
    dialog.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                       Gtk.STOCK_OPEN, Gtk.ResponseType.OK)
    # Allows confirming with Enter and double-click
    dialog.set_default_response(Gtk.ResponseType.OK)
    if main_window_controller:
        dialog.set_transient_for(
            main_window_controller.view.get_parent_widget())
    dialog.set_current_folder(last_path)
    if default_name:
        dialog.set_current_name(default_name)
    dialog.set_show_hidden(False)

    # Add library roots to list of shortcut folders
    add_library_root_path_to_shortcut_folders_of_dialog(dialog)

    response = dialog.run()

    if response != Gtk.ResponseType.OK:
        dialog.destroy()
        return None

    path = dialog.get_filename()
    dialog.destroy()

    # check path existence
    if not exists(dirname(path)):
        return None
    return path
Example #3
0
    def prepare_destruction(self):
        """Saves current configuration of windows and panes to the runtime config file, before RAFCON is closed."""
        plugins.run_hook("pre_destruction")

        logger.debug("Saving runtime config to {0}".format(
            global_runtime_config.config_file_path))

        # store pane last positions
        for key, widget_name in constants.PANE_ID.items():
            global_runtime_config.store_widget_properties(
                self.view[widget_name], key.replace('_POS', ''))

        # store hidden or undocked widget flags correctly -> make them independent for restoring
        for window_key in constants.UNDOCKABLE_WINDOW_KEYS:
            hidden = False
            if not global_runtime_config.get_config_value(window_key +
                                                          "_WINDOW_UNDOCKED"):
                hidden = getattr(self, window_key.lower() + '_hidden')
            global_runtime_config.set_config_value(window_key + '_HIDDEN',
                                                   hidden)

        global_runtime_config.save_configuration()

        # state-editor will relieve it's model => it won't observe the state machine manager any more
        self.get_controller('states_editor_ctrl').prepare_destruction(
        )  # avoid new state editor TODO tbd (deleted)
        rafcon.core.singleton.state_machine_manager.delete_all_state_machines()
        rafcon.core.singleton.library_manager.prepare_destruction()

        # Recursively destroys the main window
        self.destroy()
        from rafcon.gui.clipboard import global_clipboard
        global_clipboard.destroy()
        gui_singletons.main_window_controller = None
Example #4
0
def get_stored_window_size(window_name):
    from rafcon.gui.runtime_config import global_runtime_config
    from rafcon.gui.utils import constants
    size = global_runtime_config.get_config_value(window_name.upper() + '_SIZE')
    if not size:
        size = constants.WINDOW_SIZE[window_name.upper()]
    return size
Example #5
0
def create_folder(query, default_name=None, default_path=None):
    """Shows a user dialog for folder creation
    
    A dialog is opened with the prompt `query`. The current path is set to the last path that was opened/created. The 
    roots of all libraries is added to the list of shortcut folders.
    
    :param str query: Prompt asking the user for a specific folder
    :param str default_name: Default name of the folder to be created 
    :param str default_path: Path in which the folder is created if the user doesn't specify a path 
    :return: Path created by the user or `default_path`\`default_name` if no path was specified or None if none of the
      paths is valid
    :rtype: str
    """
    from os.path import expanduser, dirname, join, exists, isdir
    from rafcon.core.storage.storage import STATEMACHINE_FILE
    last_path = global_runtime_config.get_config_value('LAST_PATH_OPEN_SAVE',
                                                       "")

    if last_path and isdir(last_path) and not exists(
            join(last_path, STATEMACHINE_FILE)):
        pass
    elif last_path:
        last_path = dirname(last_path)
    else:
        last_path = expanduser('~')

    dialog = gtk.FileChooserDialog(query, None,
                                   gtk.FILE_CHOOSER_ACTION_CREATE_FOLDER,
                                   (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                                    gtk.STOCK_SAVE, gtk.RESPONSE_OK))
    # Allows confirming with Enter and double-click
    dialog.set_default_response(gtk.RESPONSE_OK)
    if main_window_controller:
        dialog.set_transient_for(main_window_controller.view.get_top_widget())
    dialog.set_current_folder(last_path)
    if default_name:
        dialog.set_current_name(default_name)
    dialog.set_show_hidden(False)

    # Add library roots to list of shortcut folders
    add_library_root_path_to_shortcut_folders_of_dialog(dialog)

    response = dialog.run()

    if response != gtk.RESPONSE_OK:
        dialog.destroy()
        if default_path and default_name:
            default = os.path.join(default_path, default_name)
            if os.path.isdir(default):
                return default
        return None

    path = dialog.get_filename()
    dialog.destroy()

    if os.path.isdir(path):
        global_runtime_config.set_config_value('LAST_PATH_OPEN_SAVE', path)
        return path
    return None
Example #6
0
def open_folder(query, default_path=None):
    """Shows a user dialog for folder selection
    
    A dialog is opened with the prompt `query`. The current path is set to the last path that was opened/created. The 
    roots of all libraries is added to the list of shortcut folders.
    
    :param str query: Prompt asking the user for a specific folder
    :param str default_path: Path to use if user does not specify one 
    :return: Path selected by the user or `default_path` if no path was specified or None if none of the paths is valid
    :rtype: str
    """
    from gi.repository import Gtk
    from os.path import expanduser, pathsep, dirname, isdir
    from rafcon.gui.singleton import main_window_controller
    from rafcon.gui.runtime_config import global_runtime_config
    last_path = global_runtime_config.get_config_value('LAST_PATH_OPEN_SAVE',
                                                       "")
    selected_filename = None
    if last_path and isdir(last_path):
        selected_filename = last_path.split(pathsep)[-1]
        last_path = dirname(last_path)
    else:
        last_path = expanduser('~')

    dialog = Gtk.FileChooserDialog(title=query,
                                   transient_for=None,
                                   action=Gtk.FileChooserAction.SELECT_FOLDER)
    dialog.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                       Gtk.STOCK_OPEN, Gtk.ResponseType.OK)
    # Allows confirming with Enter and double-click
    dialog.set_default_response(Gtk.ResponseType.OK)
    if main_window_controller:
        dialog.set_transient_for(
            main_window_controller.view.get_parent_widget())
    dialog.set_current_folder(last_path)
    if selected_filename is not None:
        dialog.select_filename(selected_filename)

    dialog.set_show_hidden(False)

    # Add library roots to list of shortcut folders
    add_library_root_path_to_shortcut_folders_of_dialog(dialog)

    response = dialog.run()

    if response != Gtk.ResponseType.OK:
        dialog.destroy()
        if default_path and os.path.isdir(default_path):
            return default_path
        return None

    path = dialog.get_filename()
    dialog.destroy()

    if os.path.isdir(path):
        global_runtime_config.set_config_value('LAST_PATH_OPEN_SAVE', path)
        return path
    return None
Example #7
0
 def has_label(self):
     if self.has_outgoing_connection():
         return False
     if not global_runtime_config.get_config_value(
             "SHOW_ABORTED_PREEMPTED", False) and self.outcome_id in [
                 -1, -2
             ]:
         return False
     return True
Example #8
0
    def set_pane_position(self, config_id):
        """Adjusts the position of a GTK Pane to a value stored in the runtime config file. If there was no value
        stored, the pane's position is set to a default value.

        :param config_id: The pane identifier saved in the runtime config file
        """
        default_pos = constants.DEFAULT_PANE_POS[config_id]
        position = global_runtime_config.get_config_value(config_id, default_pos)
        pane_id = constants.PANE_ID[config_id]
        self.view[pane_id].set_position(position)
Example #9
0
    def pane_position_check(self):
        """ Update right bar pane position if needed

        Checks calculates if the cursor is still visible and updates the pane position if it is close to not be seen.
        In case of an un-docked right-bar this method does nothing.
        :return:
        """
        text_buffer = self.get_buffer()

        # not needed if the right side bar is un-docked
        from rafcon.gui.singleton import main_window_controller

        if main_window_controller is None or main_window_controller.view is None:
            return
        from rafcon.gui.runtime_config import global_runtime_config
        if global_runtime_config.get_config_value('RIGHT_BAR_WINDOW_UNDOCKED'):
            return

        # move the pane left if the cursor is to far right and the pane position is less then 440 from its max position
        button_container_min_width = self.button_container_min_width
        width_of_all = button_container_min_width + self.tab_width
        text_view_width = button_container_min_width - self.line_numbers_width
        min_line_string_length = float(button_container_min_width) / float(
            self.source_view_character_size)

        current_pane_pos = main_window_controller.view[
            'right_h_pane'].get_property('position')
        max_position = main_window_controller.view[
            'right_h_pane'].get_property('max_position')
        pane_rel_pos = main_window_controller.view[
            'right_h_pane'].get_property('max_position') - current_pane_pos
        if pane_rel_pos >= width_of_all + self.line_numbers_width:
            pass
        else:
            cursor_line_offset = text_buffer.get_iter_at_offset(
                text_buffer.props.cursor_position).get_line_offset()
            needed_rel_pos = text_view_width/min_line_string_length*cursor_line_offset \
                             + self.tab_width + self.line_numbers_width
            needed_rel_pos = min(width_of_all, needed_rel_pos)
            if pane_rel_pos >= needed_rel_pos:
                pass
            else:
                main_window_controller.view['right_h_pane'].set_property(
                    'position', max_position - needed_rel_pos)
                spacer_width = int(width_of_all + self.line_numbers_width -
                                   needed_rel_pos)
                self.spacer_frame.set_size_request(width=spacer_width,
                                                   height=-1)
Example #10
0
    def prepare_destruction(self):
        """Saves current configuration of windows and panes to the runtime config file, before RAFCON is closed."""
        plugins.run_hook("pre_destruction")

        logger.debug("Saving runtime config to {0}".format(
            global_runtime_config.config_file_path))

        # store pane last positions
        for key, widget_name in constants.PANE_ID.items():
            global_runtime_config.store_widget_properties(
                self.view[widget_name], key.replace('_POS', ''))

        # store hidden or undocked widget flags correctly -> make them independent for restoring
        for window_key in constants.UNDOCKABLE_WINDOW_KEYS:
            hidden = False
            if not global_runtime_config.get_config_value(window_key +
                                                          "_WINDOW_UNDOCKED"):
                hidden = getattr(self, window_key.lower() + '_hidden')
            global_runtime_config.set_config_value(window_key + '_HIDDEN',
                                                   hidden)

        global_runtime_config.save_configuration()

        # state-editor will relieve it's model => it won't observe the state machine manager any more
        self.get_controller('states_editor_ctrl').prepare_destruction(
        )  # avoid new state editor TODO tbd (deleted)
        rafcon.core.singleton.state_machine_manager.delete_all_state_machines()
        rafcon.core.singleton.library_manager.prepare_destruction()

        # gtkmvc installs a global glade custom handler that holds a reference to the last created View class,
        # preventing it from being destructed. By installing a dummy callback handler, after all views have been
        # created, the old handler is being removed and with it the reference, allowing all Views to be destructed.

        # Gtk TODO: check if necessary and search for replacement
        # try:
        #     from gtk import glade
        #     def dummy(*args, **kwargs):
        #         pass
        #     glade.set_custom_handler(dummy)
        # except ImportError:
        #     pass

        # Recursively destroys the main window
        self.destroy()
        from rafcon.gui.clipboard import global_clipboard
        global_clipboard.destroy()
        gui_singletons.main_window_controller = None
Example #11
0
    def _update_recently_opened_state_machines(self):
        """Update the sub menu Open Recent in File menu

        Method clean's first all menu items of the sub menu 'recent open', then insert the user menu item to clean
        recent opened state machine paths and finally insert menu items for all elements in recent opened state machines
        list.
        """
        if not self.registered_view:
            return

        for item in self.view.sub_menu_open_recently.get_children():
            self.view.sub_menu_open_recently.remove(item)

        menu_item = gui_helper_label.create_menu_item(
            "remove invalid paths", constants.ICON_ERASE,
            global_runtime_config.clean_recently_opened_state_machines)
        self.view.sub_menu_open_recently.append(menu_item)
        self.view.sub_menu_open_recently.append(Gtk.SeparatorMenuItem())

        for sm_path in global_runtime_config.get_config_value(
                "recently_opened_state_machines", []):
            # define label string
            root_state_name = gui_helper_state_machine.get_root_state_name_of_sm_file_system_path(
                sm_path)
            if root_state_name is None and not os.path.isdir(sm_path):
                root_state_name = 'NOT_ACCESSIBLE'
            label_string = "'{0}' in {1}".format(
                root_state_name,
                sm_path) if root_state_name is not None else sm_path

            # define icon of menu item
            is_in_libs = library_manager.is_os_path_within_library_root_paths(
                sm_path)
            button_image = constants.SIGN_LIB if is_in_libs else constants.BUTTON_OPEN

            # prepare state machine open call_back function
            sm_open_function = partial(self.on_open_activate, path=sm_path)

            # create and insert new menu item
            menu_item = gui_helper_label.create_menu_item(
                label_string, button_image, sm_open_function)
            self.view.sub_menu_open_recently.append(menu_item)

        self.view.sub_menu_open_recently.show_all()
Example #12
0
 def show_connection(self):
     return global_runtime_config.get_config_value("SHOW_TRANSITIONS", True)
Example #13
0
    def register_view(self, view):
        super(MainWindowController, self).register_view(view)
        self.register_actions(self.shortcut_manager)

        self.view.get_top_widget().connect("key-press-event",
                                           self._on_key_press)
        self.view.get_top_widget().connect("key-release-event",
                                           self._on_key_release)

        # using helper function to connect functions to GUI elements to be able to access the handler id later on

        self.connect_button_to_function(
            'main_window', "delete_event",
            self.get_controller('menu_bar_controller').on_quit_activate)

        # connect left bar, right bar and console hide buttons' signals to their corresponding methods
        self.connect_button_to_function('left_bar_hide_button', "clicked",
                                        self.on_left_bar_hide_clicked)
        self.connect_button_to_function('right_bar_hide_button', "clicked",
                                        self.on_right_bar_hide_clicked)
        self.connect_button_to_function('console_hide_button', "clicked",
                                        self.on_console_hide_clicked)

        # Connect left bar, right bar and console return buttons' signals to their corresponding methods
        self.connect_button_to_function('left_bar_return_button', "clicked",
                                        self.on_left_bar_return_clicked)
        self.connect_button_to_function('right_bar_return_button', "clicked",
                                        self.on_right_bar_return_clicked)
        self.connect_button_to_function('console_return_button', "clicked",
                                        self.on_console_return_clicked)

        # Connect undock buttons signals
        for window_key in constants.UNDOCKABLE_WINDOW_KEYS:
            self.connect_button_to_function(
                'undock_{}_button'.format(window_key.lower()), "clicked",
                partial(self.undock_sidebar, window_key))

        # Connect collapse button for trees
        self.connect_button_to_function('collapse_tree_button', "clicked",
                                        self.on_collapse_button_clicked)

        # Connect Shortcut buttons' signals to their corresponding methods
        self.connect_button_to_function('button_start_shortcut', "toggled",
                                        self.on_button_start_shortcut_toggled)
        self.connect_button_to_function('button_stop_shortcut', "clicked",
                                        self.on_button_stop_shortcut_clicked)
        self.connect_button_to_function('button_pause_shortcut', "toggled",
                                        self.on_button_pause_shortcut_toggled)
        self.connect_button_to_function(
            'button_start_from_shortcut', "clicked",
            self.on_button_start_from_shortcut_clicked)
        self.connect_button_to_function('button_run_to_shortcut', "clicked",
                                        self.on_button_run_to_shortcut_clicked)
        self.connect_button_to_function(
            'button_step_mode_shortcut', "toggled",
            self.on_button_step_mode_shortcut_toggled)
        self.connect_button_to_function(
            'button_step_in_shortcut', "clicked",
            self.on_button_step_in_shortcut_clicked)
        self.connect_button_to_function(
            'button_step_over_shortcut', "clicked",
            self.on_button_step_over_shortcut_clicked)
        self.connect_button_to_function(
            'button_step_out_shortcut', "clicked",
            self.on_button_step_out_shortcut_clicked)
        self.connect_button_to_function(
            'button_step_backward_shortcut', "clicked",
            self.on_button_step_backward_shortcut_clicked)

        view['upper_notebook'].connect('switch-page',
                                       self.on_notebook_tab_switch,
                                       view['upper_notebook_title'],
                                       view.left_bar_window, 'upper')
        view['lower_notebook'].connect('switch-page',
                                       self.on_notebook_tab_switch,
                                       view['lower_notebook_title'],
                                       view.left_bar_window, 'lower')

        view.get_top_widget().connect("configure-event",
                                      self.update_widget_runtime_config,
                                      "MAIN_WINDOW")
        view.left_bar_window.get_top_widget().connect(
            "configure-event", self.update_widget_runtime_config,
            "LEFT_BAR_WINDOW")
        view.right_bar_window.get_top_widget().connect(
            "configure-event", self.update_widget_runtime_config,
            "RIGHT_BAR_WINDOW")
        view.console_window.get_top_widget().connect(
            "configure-event", self.update_widget_runtime_config,
            "CONSOLE_WINDOW")

        # save pane positions in the runtime config on every change
        view['top_level_h_pane'].connect("button-release-event",
                                         self.update_widget_runtime_config,
                                         "LEFT_BAR_DOCKED")
        view['right_h_pane'].connect("button-release-event",
                                     self.update_widget_runtime_config,
                                     "RIGHT_BAR_DOCKED")
        view['central_v_pane'].connect("button-release-event",
                                       self.update_widget_runtime_config,
                                       "CONSOLE_DOCKED")

        # hide not usable buttons
        self.view['step_buttons'].hide()

        # Initializing Main Window Size & Position
        # secure un maximize in initial condition to restore correct position and size
        view.get_top_widget().unmaximize()
        gui_helper_label.set_window_size_and_position(view.get_top_widget(),
                                                      'MAIN')

        wait_for_gui()

        # Initializing Pane positions
        for config_id in constants.PANE_ID:
            self.set_pane_position(config_id)

        # set the hidden status of all bars
        for window_key in constants.UNDOCKABLE_WINDOW_KEYS:
            if global_runtime_config.get_config_value(window_key + '_HIDDEN'):
                func = getattr(self,
                               'on_{}_hide_clicked'.format(window_key.lower()))
                func(None)

        # restore undock state of bar windows
        if gui_config.get_config_value("RESTORE_UNDOCKED_SIDEBARS"):
            for window_key in constants.UNDOCKABLE_WINDOW_KEYS:
                if global_runtime_config.get_config_value(window_key +
                                                          "_WINDOW_UNDOCKED"):
                    self.undock_sidebar(window_key)

        # secure maximized state
        if global_runtime_config.get_config_value("MAIN_WINDOW_MAXIMIZED"):
            wait_for_gui()
            view.get_top_widget().maximize()

        # check for auto backups
        if gui_config.get_config_value(
                'AUTO_BACKUP_ENABLED') and gui_config.get_config_value(
                    'AUTO_RECOVERY_CHECK'):
            import rafcon.gui.models.auto_backup as auto_backup
            auto_backup.check_for_crashed_rafcon_instances()

        plugins.run_hook("main_window_setup", self)

        wait_for_gui()
        # Ensure that the next message is being printed (needed for LN manager to detect finished startup)
        level = logger.level
        logger.setLevel(logging.INFO)
        logger.info("Ready")
        logger.setLevel(level)
Example #14
0
def test_pane_positions(gui):
    from rafcon.gui.runtime_config import global_runtime_config
    from rafcon.gui.utils import constants
    main_window_controller = gui.singletons.main_window_controller
    debug_sleep_time = 0.0

    stored_pane_positions = {}
    for config_id, pan_id in constants.PANE_ID.items():
        default_pos = constants.DEFAULT_PANE_POS[config_id]
        stored_pane_positions[
            config_id] = global_runtime_config.get_config_value(
                config_id, default_pos)
        if stored_pane_positions[config_id] is None:
            import logging
            logging.warning("runtime_config-file has missing values?")
            return

    def test_bar(window, window_key):

        configure_handler_id = connect_window(gui, window, 'configure-event',
                                              notify_on_event)
        hide_handler_id = connect_window(gui, window, 'hide', notify_on_event)

        print("undocking...")
        time.sleep(debug_sleep_time)
        ready.clear()
        gui(
            main_window_controller.view["undock_{}_button".format(
                window_key.lower())].emit, "clicked")
        wait_for_event_notification(gui)

        print("docking...")
        time.sleep(debug_sleep_time)
        ready.clear()
        attribute_name_of_undocked_window_view = window_key.lower() + "_window"
        undocked_window_view = getattr(main_window_controller.view,
                                       attribute_name_of_undocked_window_view)
        redock_button = undocked_window_view['redock_button']
        gui(redock_button.emit, "clicked")
        wait_for_event_notification(gui)

        time.sleep(debug_sleep_time)
        gui(window.disconnect, configure_handler_id)
        gui(window.disconnect, hide_handler_id)

    # Info: un- and redocking the left bar will change the right bar position;
    # thus, the equality check has to be done directly after un- and redocking the right bar
    print("=> test right_bar_window")
    test_bar(main_window_controller.view.right_bar_window.get_top_widget(),
             "RIGHT_BAR")
    gui(wait_for_gui)
    config_id = 'RIGHT_BAR_DOCKED_POS'
    pane_id = constants.PANE_ID['RIGHT_BAR_DOCKED_POS']
    print("check pos of ", config_id, pane_id)
    assert_pos_equality(main_window_controller.view[pane_id].get_position(),
                        stored_pane_positions[config_id], 10)

    print("=> test console_window")
    test_bar(main_window_controller.view.console_window.get_top_widget(),
             "CONSOLE")
    gui(wait_for_gui)
    config_id = 'CONSOLE_DOCKED_POS'
    pane_id = constants.PANE_ID['CONSOLE_DOCKED_POS']
    print("check pos of ", config_id, pane_id)
    assert_pos_equality(main_window_controller.view[pane_id].get_position(),
                        stored_pane_positions[config_id], 10)

    print("=> test left_bar_window")
    test_bar(main_window_controller.view.left_bar_window.get_top_widget(),
             "LEFT_BAR")
    gui(wait_for_gui)
    config_id = 'LEFT_BAR_DOCKED_POS'
    pane_id = constants.PANE_ID['LEFT_BAR_DOCKED_POS']
    print("check pos of ", config_id, pane_id)
    assert_pos_equality(main_window_controller.view[pane_id].get_position(),
                        stored_pane_positions[config_id], 10)
Example #15
0
 def show_data_port_label(self):
     return global_runtime_config.get_config_value("SHOW_DATA_FLOWS", True)
Example #16
0
    def test_bar(window, window_key):
        attribute_name_of_undocked_window_view = window_name = window_key.lower(
        ) + "_window"

        configure_handler_id = connect_window(gui, window, 'configure-event',
                                              notify_on_resize_event)
        hide_handler_id = connect_window(gui, window, 'hide', notify_on_event)

        logger.info("undocking...")
        time.sleep(debug_sleep_time)
        ready.clear()
        gui(
            main_window_controller.view["undock_{}_button".format(
                window_key.lower())].emit, "clicked")
        wait_for_event_notification(gui)
        assert window.get_property('visible') is True
        expected_size = get_stored_window_size(window_name)
        new_size = window.get_size()
        # print dir(window)
        if not bool(window.is_maximized()):
            assert_size_equality(new_size, expected_size, 90)
        else:
            maximized_parameter_name = window_key + "_WINDOW_MAXIMIZED"
            assert bool(window.is_maximized()
                        ) and global_runtime_config.get_config_value(
                            maximized_parameter_name)

        logger.info("resizing...")
        time.sleep(debug_sleep_time)
        ready.clear()
        target_size = (1400, 800)
        try:
            assert_size_equality(new_size, target_size, 90)
            # Change target size if it is similar to the current size
            target_size = (1600, 900)
        except AssertionError:
            pass

        logger.debug("target size: {}".format(target_size))
        gui(window.resize, *target_size)
        wait_for_event_notification(gui)
        try:
            assert_size_equality(event_size, target_size, 90)
        except AssertionError:
            # For unknown reasons, there are two configure events and only the latter one if for the new window size
            ready.clear()
            wait_for_event_notification(gui)
            assert_size_equality(event_size, target_size, 90)
            logger.info("got additional configure-event")

        logger.info("docking...")
        undocked_window_view = getattr(main_window_controller.view,
                                       attribute_name_of_undocked_window_view)
        redock_button = undocked_window_view['redock_button']
        time.sleep(debug_sleep_time)
        ready.clear()
        gui(redock_button.emit, "clicked")
        wait_for_event_notification(gui)
        assert window.get_property('visible') is False

        logger.info("undocking...")
        time.sleep(debug_sleep_time)
        ready.clear()

        show_handler_id = connect_window(gui, window, 'show', notify_on_event)

        gui(
            main_window_controller.view["undock_{}_button".format(
                window_key.lower())].emit, "clicked")
        wait_for_event_notification(gui)
        assert window.get_property('visible') is True
        assert_size_equality(window.get_size(), target_size, 90)

        logger.info("docking...")
        time.sleep(debug_sleep_time)
        ready.clear()
        gui(redock_button.emit, "clicked")
        wait_for_event_notification(gui)
        assert window.get_property('visible') is False

        gui(window.disconnect, configure_handler_id)
        gui(window.disconnect, show_handler_id)
        gui(window.disconnect, hide_handler_id)
Example #17
0
def create_folder(query,
                  default_name=None,
                  default_path=None,
                  current_folder=None):
    """Shows a user dialog for folder creation
    
    A dialog is opened with the prompt `query`. The current path is set to the last path that was opened/created. The 
    roots of all libraries is added to the list of shortcut folders.
    
    :param str query: Prompt asking the user for a specific folder
    :param str default_name: Default name of the folder to be created 
    :param str default_path: Path in which the folder is created if the user doesn't specify a path
    :param str current_folder: Current folder that the FileChooserDialog points to in the beginning
    :return: Path created by the user or `default_path`/`default_name` if no path was specified or None if none of the
      paths is valid
    :rtype: str
    """
    from gi.repository import Gtk
    from os.path import expanduser, dirname, join, exists, isdir
    from rafcon.core.storage.storage import STATEMACHINE_FILE
    from rafcon.gui.singleton import main_window_controller
    from rafcon.gui.runtime_config import global_runtime_config
    last_path = global_runtime_config.get_config_value('LAST_PATH_OPEN_SAVE',
                                                       "")

    if last_path and isdir(last_path) and not exists(
            join(last_path, STATEMACHINE_FILE)):
        pass
    elif last_path:
        last_path = dirname(last_path)
    else:
        last_path = expanduser('~')

    dialog = Gtk.FileChooserDialog(title=query,
                                   transient_for=None,
                                   action=Gtk.FileChooserAction.CREATE_FOLDER)
    dialog.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                       Gtk.STOCK_OPEN, Gtk.ResponseType.OK)
    # dialog.add_buttons(Gtk.ButtonsType.OK_CANCEL)
    # Allows confirming with Enter and double-click
    dialog.set_default_response(Gtk.ResponseType.OK)
    if main_window_controller:
        dialog.set_transient_for(
            main_window_controller.view.get_parent_widget())
    dialog.set_current_folder(last_path)
    if current_folder:
        dialog.set_current_folder(current_folder)
    if default_name:
        dialog.set_current_name(default_name)
    dialog.set_show_hidden(False)

    # Add library roots to list of shortcut folders
    add_library_root_path_to_shortcut_folders_of_dialog(dialog)

    response = dialog.run()

    if response != Gtk.ResponseType.OK:
        dialog.destroy()
        if default_path and default_name:
            default = os.path.join(default_path, default_name)
            if os.path.isdir(default):
                return default
        return None

    path = dialog.get_filename()
    dialog.destroy()

    if os.path.isdir(path):
        global_runtime_config.set_config_value('LAST_PATH_OPEN_SAVE', path)
        return path
    return None
Example #18
0
def check_pane_positions():
    from rafcon.gui.singleton import main_window_controller
    from rafcon.gui.runtime_config import global_runtime_config
    from rafcon.gui.utils import constants
    debug_sleep_time = 0

    stored_pane_positions = {}
    for config_id, pan_id in constants.PANE_ID.iteritems():
        default_pos = constants.DEFAULT_PANE_POS[config_id]
        stored_pane_positions[
            config_id] = global_runtime_config.get_config_value(
                config_id, default_pos)
        if stored_pane_positions[config_id] is None:
            import logging
            logging.warning("runtime_config-file has missing values?")
            return

    def test_bar(window, window_key):

        output_list = list()
        call_gui_callback(connect_window, window, 'configure-event',
                          notify_on_event, output_list)
        configure_handler_id = output_list[0]
        output_list = list()
        call_gui_callback(connect_window, window, 'hide', notify_on_event,
                          output_list)
        hide_handler_id = output_list[0]

        print "undocking..."
        time.sleep(debug_sleep_time)
        ready.clear()
        call_gui_callback(
            main_window_controller.view["undock_{}_button".format(
                window_key.lower())].emit, "clicked")
        wait_for_event_notification()

        print "docking..."
        time.sleep(debug_sleep_time)
        ready.clear()
        attribute_name_of_undocked_window_view = window_key.lower() + "_window"
        undocked_window_view = getattr(main_window_controller.view,
                                       attribute_name_of_undocked_window_view)
        redock_button = getattr(undocked_window_view,
                                "top_tool_bar")['redock_button']
        call_gui_callback(redock_button.emit, "clicked")
        wait_for_event_notification()

        window.disconnect(configure_handler_id)
        window.disconnect(hide_handler_id)

    print "=> test left_bar_window"
    test_bar(main_window_controller.view.left_bar_window.get_top_widget(),
             "LEFT_BAR")
    print "=> test right_bar_window"
    test_bar(main_window_controller.view.right_bar_window.get_top_widget(),
             "RIGHT_BAR")
    print "=> test console_window"
    test_bar(main_window_controller.view.console_window.get_top_widget(),
             "CONSOLE")
    testing_utils.wait_for_gui()

    print "check if pane positions are still like in runtime_config.yaml"
    for config_id, pane_id in constants.PANE_ID.iteritems():
        print "check pos of ", config_id, pane_id
        assert main_window_controller.view[pane_id].get_position(
        ) == stored_pane_positions[config_id]
Example #19
0
    def draw_name(self, context, transparency, value):
        c = context.cairo
        port_height = self.port_size[1]
        label_position = self.side if not self.label_print_inside else self.side.opposite(
        )
        position = self.pos

        show_additional_value = False
        if global_runtime_config.get_config_value(
                "SHOW_DATA_FLOW_VALUE_LABELS", True) and value is not None:
            show_additional_value = True

        parameters = {
            'name': self.name,
            'port_height': port_height,
            'side': label_position,
            'transparency': transparency,
            'show_additional_value': show_additional_value
        }

        # add value to parameters only when value is shown on label
        if show_additional_value:
            parameters['value'] = value

        upper_left_corner = (position[0] + self._last_label_relative_pos[0],
                             position[1] + self._last_label_relative_pos[1])
        current_zoom = self.parent.canvas.get_first_view().get_zoom_factor()
        from_cache, image, zoom = self._label_image_cache.get_cached_image(
            self._last_label_size[0], self._last_label_size[1], current_zoom,
            parameters)
        # The parameters for drawing haven't changed, thus we can just copy the content from the last rendering result
        if from_cache and not context.draw_all:
            # print("draw port name from cache")
            self._label_image_cache.copy_image_to_context(c, upper_left_corner)

        # Parameters have changed or nothing in cache => redraw
        else:
            # print("draw port name")

            # First we have to do a "dry run", in order to determine the size of the new label
            c.move_to(position.x.value, position.y.value)
            extents = gap_draw_helper.draw_port_label(
                c,
                self,
                transparency,
                False,
                label_position,
                show_additional_value,
                value,
                only_extent_calculations=True)
            from rafcon.gui.mygaphas.utils.gap_helper import extend_extents
            extents = extend_extents(extents, factor=1.1)
            label_pos = extents[0], extents[1]
            relative_pos = label_pos[0] - position[0], label_pos[1] - position[
                1]
            label_size = extents[2] - extents[0], extents[3] - extents[1]

            # print(label_size[0], self.name, self.parent.model.state.name)
            # if label_size[0] < constants.MINIMUM_PORT_NAME_SIZE_FOR_DISPLAY and self.parent:
            #     return
            self._last_label_relative_pos = relative_pos
            self._last_label_size = label_size

            # The size information is used to update the caching parameters and retrieve an image with the correct size
            self._label_image_cache.get_cached_image(label_size[0],
                                                     label_size[1],
                                                     current_zoom,
                                                     parameters,
                                                     clear=True)
            c = self._label_image_cache.get_context_for_image(current_zoom)
            c.move_to(-relative_pos[0], -relative_pos[1])

            gap_draw_helper.draw_port_label(c, self, transparency, False,
                                            label_position,
                                            show_additional_value, value)

            # Copy image surface to current cairo context
            upper_left_corner = (position[0] + relative_pos[0],
                                 position[1] + relative_pos[1])
            self._label_image_cache.copy_image_to_context(context.cairo,
                                                          upper_left_corner,
                                                          zoom=current_zoom)

            # draw_all means, the bounding box of the state is calculated
            # As we are using drawing operation, not supported by Gaphas, we manually need to update the bounding box
            if context.draw_all:
                from gaphas.geometry import Rectangle
                view = self.parent.canvas.get_first_view()
                abs_pos = view.get_matrix_i2v(
                    self.parent).transform_point(*label_pos)
                abs_pos1 = view.get_matrix_i2v(self.parent).transform_point(
                    extents[2], extents[3])
                bounds = Rectangle(abs_pos[0],
                                   abs_pos[1],
                                   x1=abs_pos1[0],
                                   y1=abs_pos1[1])
                context.cairo._update_bounds(bounds)
Example #20
0
    def register_view(self, view):
        """Called when the View was registered"""
        super(MenuBarController, self).register_view(view)
        data_flow_mode = global_runtime_config.get_config_value(
            "DATA_FLOW_MODE", False)
        view["data_flow_mode"].set_active(data_flow_mode)

        show_data_flows = global_runtime_config.get_config_value(
            "SHOW_DATA_FLOWS", True)
        view["show_data_flows"].set_active(show_data_flows)

        show_data_values = global_runtime_config.get_config_value(
            "SHOW_DATA_FLOW_VALUE_LABELS", True)
        view["show_data_values"].set_active(show_data_values)

        show_aborted_preempted = global_runtime_config.get_config_value(
            "SHOW_ABORTED_PREEMPTED", False)
        view["show_aborted_preempted"].set_active(show_aborted_preempted)

        view["expert_view"].hide()
        view["grid"].hide()

        # use dedicated function to connect the buttons to be able to access the handler id later on
        self.connect_button_to_function('new', 'activate',
                                        self.on_new_activate)
        self.connect_button_to_function('open', 'activate',
                                        self.on_open_activate)
        self.connect_button_to_function('save', 'activate',
                                        self.on_save_activate)
        self.connect_button_to_function('save_as', 'activate',
                                        self.on_save_as_activate)
        self.connect_button_to_function('save_as_copy', 'activate',
                                        self.on_save_as_copy_activate)
        self.connect_button_to_function('menu_preferences', 'activate',
                                        self.on_menu_preferences_activate)
        self.connect_button_to_function('refresh_all', 'activate',
                                        self.on_refresh_all_activate)
        self.connect_button_to_function('refresh_libraries', 'activate',
                                        self.on_refresh_libraries_activate)
        self.connect_button_to_function('bake_state_machine', 'activate',
                                        self.on_bake_state_machine_activate)
        self.connect_button_to_function('quit', 'activate',
                                        self.on_quit_activate)

        self.connect_button_to_function('cut', 'activate',
                                        self.on_cut_selection_activate)
        self.connect_button_to_function('copy', 'activate',
                                        self.on_copy_selection_activate)
        self.connect_button_to_function('paste', 'activate',
                                        self.on_paste_clipboard_activate)
        self.connect_button_to_function('delete', 'activate',
                                        self.on_delete_activate)
        self.connect_button_to_function('is_start_state', 'activate',
                                        self.on_toggle_is_start_state_active)
        self.connect_button_to_function('add', 'activate',
                                        self.on_add_state_activate)
        self.connect_button_to_function('group', 'activate',
                                        self.on_group_states_activate)
        self.connect_button_to_function('ungroup', 'activate',
                                        self.on_ungroup_state_activate)
        self.connect_button_to_function(
            'substitute_state', 'activate',
            self.on_substitute_selected_state_activate)
        self.connect_button_to_function(
            'save_state_as', 'activate',
            self.on_save_selected_state_as_activate)
        self.connect_button_to_function('undo', 'activate',
                                        self.on_undo_activate)
        self.connect_button_to_function('redo', 'activate',
                                        self.on_redo_activate)
        self.connect_button_to_function('grid', 'activate',
                                        self.on_grid_toggled)

        self.connect_button_to_function('data_flow_mode', 'toggled',
                                        self.on_data_flow_mode_toggled)
        self.connect_button_to_function('show_data_flows', 'toggled',
                                        self.on_show_data_flows_toggled)
        self.connect_button_to_function('show_data_values', 'toggled',
                                        self.on_show_data_values_toggled)
        self.connect_button_to_function('show_aborted_preempted', 'toggled',
                                        self.on_show_aborted_preempted_toggled)
        self.connect_button_to_function('expert_view', 'activate',
                                        self.on_expert_view_activate)
        self.connect_button_to_function('full_screen', 'toggled',
                                        self.on_full_screen_mode_toggled)

        self.connect_button_to_function('start', 'activate',
                                        self.on_start_activate)
        self.connect_button_to_function(
            'start_from_selected', 'activate',
            self.on_start_from_selected_state_activate)
        self.connect_button_to_function('run_to_selected', 'activate',
                                        self.on_run_to_selected_state_activate)
        self.connect_button_to_function('pause', 'activate',
                                        self.on_pause_activate)
        self.connect_button_to_function('stop', 'activate',
                                        self.on_stop_activate)
        self.connect_button_to_function('step_mode', 'activate',
                                        self.on_step_mode_activate)
        self.connect_button_to_function('step_into', 'activate',
                                        self.on_step_into_activate)
        self.connect_button_to_function('step_over', 'activate',
                                        self.on_step_over_activate)
        self.connect_button_to_function('step_out', 'activate',
                                        self.on_step_out_activate)
        self.connect_button_to_function('backward_step', 'activate',
                                        self.on_backward_step_activate)
        self.connect_button_to_function('about', 'activate',
                                        self.on_about_activate)
        self.full_screen_window.connect(
            'key_press_event',
            self.on_escape_key_press_event_leave_full_screen)
        self.view['menu_edit'].connect('select',
                                       self.check_edit_menu_items_status)
        self.registered_view = True
        self._update_recently_opened_state_machines()
        # do not move next line - here to show warning in GUI debug console
        self.create_logger_warning_if_shortcuts_are_overwritten_by_menu_bar()
Example #21
0
def convert(config_path, source_path, target_path=None, gui_config_path=None):
    logger.info("RAFCON launcher")
    rafcon.gui.start.setup_l10n(logger)
    from rafcon.gui.controllers.main_window import MainWindowController
    from rafcon.gui.views.main_window import MainWindowView

    setup_environment()

    gui_config_path = gui_config_path or get_default_config_path()

    setup_config = {}
    setup_config["config_path"] = config_path
    setup_config["gui_config_path"] = gui_config_path
    setup_config["source_path"] = [source_path]
    if not target_path:
        setup_config["target_path"] = [source_path]
    else:
        setup_config["target_path"] = [target_path]

    global_config.load(path=setup_config['config_path'])
    global_gui_config.load(path=setup_config['gui_config_path'])
    global_runtime_config.load(path=setup_config['gui_config_path'])

    # Initialize library
    core_singletons.library_manager.initialize()

    # Create the GUI
    main_window_view = MainWindowView()

    if setup_config['source_path']:
        if len(setup_config['source_path']) > 1:
            logger.error("Only one state machine is supported yet")
            exit(-1)
        for path in setup_config['source_path']:
            try:
                state_machine = gui_helper_state_machine.open_state_machine(
                    path)
            except Exception as e:
                logger.error("Could not load state machine {0}: {1}".format(
                    path, e))
    else:
        logger.error(
            "You need to specify exactly one state machine to be converted!")

    sm_manager_model = gui_singletons.state_machine_manager_model

    main_window_controller = MainWindowController(sm_manager_model,
                                                  main_window_view)

    if not os.getenv("RAFCON_START_MINIMIZED", False):
        main_window = main_window_view.get_top_widget()
        size = global_runtime_config.get_config_value("WINDOW_SIZE", None)
        position = global_runtime_config.get_config_value("WINDOW_POS", None)
        if size:
            main_window.resize(size[0], size[1])
        if position:
            position = (max(0, position[0]), max(0, position[1]))
            screen_width = Gdk.Screen.width()
            screen_height = Gdk.Screen.height()
            if position[0] < screen_width and position[1] < screen_height:
                main_window.move(position[0], position[1])

    wait_for_gui()
    thread = threading.Thread(target=trigger_gui_signals,
                              args=[
                                  sm_manager_model, main_window_controller,
                                  setup_config, state_machine
                              ])
    thread.start()

    Gtk.main()
    logger.debug("Gtk main loop exited!")
    logger.debug("Conversion done")
Example #22
0
    def test_bar(window, window_key):
        attribute_name_of_undocked_window_view = window_name = window_key.lower(
        ) + "_window"

        output_list = list()
        call_gui_callback(connect_window, window, 'configure-event',
                          notify_on_resize_event, output_list)
        configure_handler_id = output_list[0]
        output_list = list()
        call_gui_callback(connect_window, window, 'hide', notify_on_event,
                          output_list)
        hide_handler_id = output_list[0]

        logger.info("undocking...")
        time.sleep(debug_sleep_time)
        ready.clear()
        call_gui_callback(
            main_window_controller.view["undock_{}_button".format(
                window_key.lower())].emit, "clicked")
        wait_for_event_notification()
        assert window.get_property('visible') is True
        expected_size = get_stored_window_size(window_name)
        new_size = window.get_size()
        if not bool(window.maximize_initially):
            assert_size_equality(new_size, expected_size)
        else:
            maximized_parameter_name = window_key + "_WINDOW_MAXIMIZED"
            assert bool(window.maximize_initially
                        ) and global_runtime_config.get_config_value(
                            maximized_parameter_name)

        logger.info("resizing...")
        time.sleep(debug_sleep_time)
        ready.clear()
        target_size = (800, 800)
        if new_size == target_size:
            target_size = (900, 900)
        logger.debug("target size: {}".format(target_size))
        call_gui_callback(window.resize, *target_size)
        wait_for_event_notification()
        try:
            assert_size_equality(event_size, target_size)
        except AssertionError:
            # For unknown reasons, there are two configure events and only the latter one if for the new window size
            ready.clear()
            wait_for_event_notification()
            assert_size_equality(event_size, target_size)
            logger.info("got additional configure-event")

        logger.info("docking...")
        undocked_window_view = getattr(main_window_controller.view,
                                       attribute_name_of_undocked_window_view)
        redock_button = getattr(undocked_window_view,
                                "top_tool_bar")['redock_button']
        time.sleep(debug_sleep_time)
        ready.clear()
        call_gui_callback(redock_button.emit, "clicked")
        wait_for_event_notification()
        assert window.get_property('visible') is False

        logger.info("undocking...")
        time.sleep(debug_sleep_time)
        ready.clear()

        output_list = list()
        call_gui_callback(connect_window, window, 'show', notify_on_event,
                          output_list)
        show_handler_id = output_list[0]

        call_gui_callback(
            main_window_controller.view["undock_{}_button".format(
                window_key.lower())].emit, "clicked")
        wait_for_event_notification()
        assert window.get_property('visible') is True
        assert_size_equality(window.get_size(), target_size)

        logger.info("docking...")
        time.sleep(debug_sleep_time)
        ready.clear()
        call_gui_callback(redock_button.emit, "clicked")
        wait_for_event_notification()
        assert window.get_property('visible') is False

        window.disconnect(configure_handler_id)
        window.disconnect(show_handler_id)
        window.disconnect(hide_handler_id)
Example #23
0
 def show_connection(self):
     return global_runtime_config.get_config_value("SHOW_DATA_FLOWS", True)