def __init__(self): # Menu Run Testsuite with coverage self.runtest_action = GPS.Action('gsh_runtest_action') self.runtest_action.create(GSHActions.runtest_action, category="GSH", description="Run GSH testsuite") self.runtest_action.menu("GSH/Run Testsuite") # Menu show full coverage self.showcov_action = GPS.Action('gsh_showcov_action') self.showcov_action.create(GSHActions.showcov_action, category="GSH", description="Display full coverage") self.showcov_action.menu("GSH/Show Full Coverage") # Menu Run Testsuite without coverage self.runtestnocov_action = GPS.Action('gsh_runtestnocov_action') self.runtestnocov_action.create(GSHActions.runtestnocov_action, category="GSH", description="Run GSH testsuite") self.runtestnocov_action.menu("GSH/Run Testsuite (no cov)") # Menu Build self.build_action = GPS.Action('gsh_build_action') self.build_action.create(GSHActions.build_action, category="GSH", description="Build") self.build_action.menu("GSH/Build") # Menu Console AdaLua self.console_action = GPS.Action('gsh_console_action') self.console_action.create(GSHActions.console_action, category="GSH", description="Launch AdaLua console") self.console_action.menu("GSH/Console AdaLua")
def initialize_project_plugin(): """Called automatically when gps.gpr is loaded""" # Create a specific menu under Analyze/GPS to flag if not GPS.Action("find project types stored").exists(): @interactive(category="General", name="find project types stored", menu="/Analyze/GPS/Flag stored Project Types") def find_project_types_stored(): all_ada_sources = [ x for x in GPS.Project.root().sources(recursive=True) if x.language().lower() == 'ada' ] for source_file in all_ada_sources: flag_storage_of_project_type(source_file) if not GPS.Action("new gps ada package").exists(): # Register the GPS package file templates GPS.parse_xml(gps_aliases_xml) GPS.FileTemplate.register(alias_name="package_gps_header", label="GPS Ada Package", unit_param="name", language="ada", is_impl=False, impl_alias_name="package_gps_header_body")
def __gps_started(): GPS.Action('cut to clipboard').button( toolbar='main', section='editor', label='Cut') GPS.Action('copy to clipboard').button( toolbar='main', section='editor', label='Copy') GPS.Action('paste from clipboard').button( toolbar='main', section='editor', label='Paste')
def create_menus(system_name, actions): global global_vcs_menus global contextual_menu_labels need_to_create_contextual_menus = \ system_name not in contextual_menu_labels need_to_create_menus = len(global_vcs_menus) == 0 if need_to_create_contextual_menus: contextual_menu_labels[system_name] = [] separator_count = 0 for dict in actions: label = dict[LABEL] action_name = dict[ACTION] if action_name: action = GPS.Action(action_name) # Add item in the global menu if need_to_create_menus: menu = action.menu("/_VCS/%s" % label) global_vcs_menus.append(menu) # Add item in the contextual menu contextual_label = "Version Control/%s" % label.replace( "_", "") if need_to_create_contextual_menus: action.contextual( path=contextual_label, # filter=not_in_explorer, # ref=last_menu, add_before=True) contextual_menu_labels[system_name] += [contextual_label] else: GPS.Contextual(contextual_label).show() else: separator_count += 1 # Add a separator in the global menu a = GPS.Action('__separator') menu = a.menu('/VCS/-%s-' % (separator_count, )) global_vcs_menus.append(menu) # Add a separator in the contextual menu if need_to_create_contextual_menus: GPS.Contextual('').create( on_activate=None, label='Version Control/-', # filter=only_in_submenu, ref=last_menu, add_before=True)
def __gps_started(): GPS.Action('comment lines').button(toolbar='main', section='editor', label='Comment', icon='comment-symbolic') GPS.Action('uncomment lines').button(toolbar='main', section='editor', label='Uncomment', icon='uncomment-symbolic')
def on_gps_started(hook): GPS.Action('open Project Properties').disable() GPS.Action('open Switches editor').disable() GPS.Action('save all projects').disable() GPS.Action('new project').disable() GPS.Action('create project from template').disable() # Remove the contextual menus that may cause modifications in the # projects GPS.Contextual("Add scenario variable").hide()
def __gps_started(): global grey_out_contextual if GPS.Preference("Plugins/copy_paste/stdmenu").get(): grey_out_contextual = GPS.Preference( "Plugins/copy_paste/greyedout").get() # ??? Should still show them when inapplicable if grey_out_contextual GPS.Action('cut to clipboard').contextual('Cut', group=-1) GPS.Action('copy to clipboard').contextual('Copy', group=-1) if GPS.Preference("Plugins/copy_paste/copy_with_line_nums").get(): GPS.Action('Copy with line numbers').contextual( 'Copy with line numbers', group=-1) GPS.Action('paste from clipboard').contextual('Paste', group=-1)
def __gps_started(): global grey_out_contextual if GPS.Preference("Plugins/copy_paste/stdmenu").get(): GPS.Action('cut to clipboard').contextual( 'Cut', group=GPS.Contextual.Group.CUT_COPY_PASTE) GPS.Action('copy to clipboard').contextual( 'Copy', group=GPS.Contextual.Group.CUT_COPY_PASTE) if GPS.Preference("Plugins/copy_paste/copy_with_line_nums").get(): GPS.Action('Copy with line numbers').contextual( 'Copy with line numbers', group=GPS.Contextual.Group.CUT_COPY_PASTE) GPS.Action('paste from clipboard').contextual( 'Paste', group=GPS.Contextual.Group.CUT_COPY_PASTE)
def test_driver(): buf = GPS.EditorBuffer.get(GPS.File("default.gpr")) buf.current_view().goto(buf.at(5, 1)) gps_assert( GPS.Action("debug set line breakpoint").can_execute(), False, "The 'debug set line breakpoint' should not be executable from " + "project files.")
def do_something(): """ React to the Esc key, and return True iff something was done. """ editor = GPS.EditorBuffer.get(force=False, open=False) if editor: if aliases.is_in_alias_expansion(editor): aliases.exit_alias_expand(editor) return True if editor.has_slave_cursors(): editor.remove_all_slave_cursors() return True if GPS.Action("Cancel completion").execute_if_possible(): return True c = [ c for c in GPS.MDI.children() if (c.is_floating() and c.get_child().__class__ == GPS.GUI) ] if c: c[0].close() return True
def should_escape(context): """ Filter for the 'smart escape' action """ editor = GPS.EditorBuffer.get(force=False, open=False) if editor: if GPS.Action("Cancel completion").can_execute(): return True if aliases.is_in_alias_expansion(editor): return True if editor.has_slave_cursors(): return True current_view = GPS.MDI.current() if current_view and current_view.is_floating(): try: window = current_view.get_child().pywidget().get_toplevel() focus_widget = window.get_focus() # Don't perform smart escape when the focus is on the preferences # editor's search bar. return focus_widget.get_name() != "preferences_editor_search" except Exception: return False return False
def do_something(): """ React to the Esc key, and return True if something was done. """ editor = GPS.EditorBuffer.get(force=False, open=False) if editor: if GPS.Action("Cancel completion").execute_if_possible(): return True if aliases.is_in_alias_expansion(editor): aliases.exit_alias_expand(editor) return True if editor.has_slave_cursors(): editor.remove_all_slave_cursors() return True current_view = GPS.MDI.current() if current_view and current_view.is_floating(): try: window = current_view.get_child().pywidget().get_toplevel() if window.get_transient_for(): current_view.close() else: GPS.MDI.present_main_window() except Exception: return False return True return False
def create_action(method, vcs_name, extension_class=None): """ Register a GPS action. Nothing is done if the action has already been registered for another instance of the same VCS kind. :param Func method: the function to call. It receives either the instance of the active VCS or the instance of the extension, depending on whether extension_name is specified. This must be a method that was decorated with @vcs_action. :param str vcs_name: the name of the VCS system to which the action applies. The action is only enabled when this is the current VCS (any instance of that VCS, in case for instance the user has multiple git working directories in a project. :param type extension_class: the class of the VCS extension to which this action applies. When specified, the parameter given to the method is the instance of the VCS extension, not the VCS itself. """ action = method._vcs2_is_action if action.name in vcs_action._actions: return vcs_action._actions.add(action.name) class __Proxy: def __init__(self, method): self.method = run_in_background(method) def filter(self, context): return (GPS.VCS2.active_vcs() and GPS.VCS2.active_vcs().name == vcs_name) def __call__(self): v = GPS.VCS2.active_vcs() if extension_class is None: self.method(v) else: for e in v._extensions: if e.__class__ == extension_class: self.method(e) break p = __Proxy(method) gs_utils.make_interactive(p, description=method.__doc__, name=action.name, category='VCS2', menu=action.menu, after=action.after, icon=action.icon, filter=p.filter) if action.toolbar: act = GPS.Action(action.name) act.button(toolbar=action.toolbar, section=action.toolbar_section, hide=True)
def goto_beginning_of_line(): """ Move the cursor to the beginning of the line: * if the cursor is anywhere within the line, move back to column 1 * if the cursor is already on column 1, move to the first non-blank character of the line. """ GPS.Action("Cancel completion").execute_if_possible() _goto_line_bound(beginning=True, extend_selection=False)
def __init__(self, command, close_on_exit=True, force=False, ansi=False, manage_prompt=True, task_manager=False): self.close_on_exit = close_on_exit toolbar_name = command[0] + '_toolbar' try: GPS.Console.__init__(self, command[0], manage_prompt=manage_prompt, on_input=self.on_input, on_destroy=Console_Process.on_destroy, toolbar_name=toolbar_name, on_resize=self.on_resize, on_interrupt=Console_Process.on_interrupt, on_completion=self.on_completion, on_key=self.on_key, ansi=ansi, force=force, save_desktop=self.save_desktop) GPS.Process.__init__( self, command=command, regexp='.+', single_line_regexp=True, # For efficiency strip_cr=not ansi, # if ANSI terminal, CR is irrelevant task_manager=task_manager, on_exit=self.on_exit, on_match=self.on_output) except Exception: GPS.Console().write(str(sys.exc_info()[1]) + '\n') try: self.destroy() self.kill() except Exception: pass GPS.Console().write('Could not spawn: %s\n' % (' '.join(command))) # Create the associated clear action and button self.__clear_action = GPS.Action('clear ' + command[0] + " console") if self.__clear_action.exists(): self.__clear_action.unregister() self.__clear_action.create(on_activate=lambda: self.clear(), description='Clear the ' + command[0] + ' console.', icon='gps-clear-symbolic') self.__clear_action.button(toolbar=toolbar_name, label='Clear')
def append(self, widget, tooltip=''): """Append a widget to the Toolbar. The widget must be either a GPS.ToolButton or a GPS.Button.""" self.action = GPS.Action(widget.action_name) self.action.create(on_activate=lambda: widget.on_click(widget), filter="", category="Custom ToolButtons", description=tooltip, icon=widget.stock_id) self.action.button()
def initialize_project_plugin(): """Called automatically when gps.gpr is loaded""" # Create a specific menu under Analyze/GPS to flag if not GPS.Action("find project types stored").exists(): @interactive(category="General", name="find project types stored", menu="/Analyze/GPS/Flag stored Project Types") def find_project_types_stored(): all_ada_sources = filter( lambda x: x.language().lower() == 'ada', GPS.Project.root().sources(recursive=True)) for source_file in all_ada_sources: flag_storage_of_project_type(source_file)
def run_test(): GPS.Preference("Smart-Completion-Mode").set("3") buf = GPS.EditorBuffer.get(GPS.File("main.adb")) view = buf.current_view() view.goto(buf.at(7, 1).end_of_line()) yield wait_idle() # Insert a completion snippet received from clangd for ch in "Not": send_key_event(ord(ch)) yield timeout(100) yield wait_until_true( lambda: get_widget_by_name("completion-view") != None) pop_tree = get_widget_by_name("completion-view") model = pop_tree.get_model() yield wait_idle() click_in_tree(pop_tree, path="0", events=double_click_events) yield wait_idle() # Verify that it has been correctly parsed by the aliases plugin line = buf.get_chars(buf.at(7, 1), buf.at(7, 1).end_of_line()) gps_assert(line.strip(), EXPECTED_SNIPPET.strip(), "The completion snippet has not been correctly inserted") # Iterate over the snippet params using TAB and give a value to # each of them for ch in "12": send_key_event(ord(ch)) yield wait_idle() yield wait_until_true( lambda: GPS.Action("toggle to next alias field").can_execute()) GPS.execute_action("toggle to next alias field") yield wait_idle() # Verify that the snippet parameters have been inserted properly line = buf.get_chars(buf.at(7, 1), buf.at(7, 1).end_of_line()) gps_assert(line.strip(), EXPECTED_RESULT.strip(), "The snippet parameter values have not been inserted properly") # Verify that we jumped to the final tab stop gps_assert(view.cursor(), buf.at(7, 1).end_of_line(), "last TAB did not jump to the snippet final tab stop")
def smart_tab(): """ This action is the default binding for the tab key, and will apply different behaviors depending on the current context. When expanding aliases, <tab> will move to the next field. Otherwise, when multiple lines are selected it will try to align special sequences like ":", "=>", "use" and ":=". Finally, it will automatically indent the selected lines. """ editor = GPS.EditorBuffer.get() # When expanding aliases, <tab> should move to the next field if aliases.is_in_alias_expansion(editor): aliases.toggle_next_field(editor) return # If multiple lines are selected, perform various alignments if not GPS.Logger("GPS.INTERNAL.PREVENT_ALIGN_ON_TAB").active: if tabs_align_selection.get(): start = editor.selection_start() end = editor.selection_end() if abs(start.line() - end.line()) >= 1: align.align_colons() align.align_arrows() align.align_use_clauses() align.align_assignments() # if it's a python code, do it in python way if editor.file().language() == "python": python_tab_indent(editor, editor.selection_start(), editor.selection_end()) # Otherwise, reformat the current selection else: action = GPS.Action("Autoindent selection") if not action.execute_if_possible(): editor.insert(editor.current_view().cursor(), "\t")
def should_escape(context): """ Filter for the 'smart escape' action """ editor = GPS.EditorBuffer.get(force=False, open=False) if editor: if aliases.is_in_alias_expansion(editor): return True if editor.has_slave_cursors(): return True if GPS.Action("Cancel completion").can_execute(): return True current_view = GPS.MDI.current() if current_view and current_view.is_floating(): return True return False
def smart_tab(): """ This action is the default binding for the tab key, and will apply different behaviors depending on the current context. When expanding aliases, <tab> will move to the next field. Otherwise: - if there is a multi-line selection, the selection will be reformatted; - otherwise, the current line will be reformatted """ editor = GPS.EditorBuffer.get() # When expanding aliases, <tab> will be handled by the aliases package if aliases.is_in_alias_expansion(editor): return # If multiple lines are selected, perform various alignments if not GPS.Logger("GPS.INTERNAL.PREVENT_ALIGN_ON_TAB").active: if tabs_align_selection.get(): start = editor.selection_start() end = editor.selection_end() if abs(start.line() - end.line()) >= 1: align.align_colons() align.align_arrows() align.align_use_clauses() align.align_assignments() # if it's a python code, do it in python way if editor.file().language() == "python": python_tab_indent(editor, editor.selection_start(), editor.selection_end()) # Otherwise, reformat the current selection else: action = GPS.Action("format selection") if not action.execute_if_possible(): editor.insert(editor.current_view().cursor(), "\t")
def should_escape(context): """ Filter for the 'smart escape' action """ editor = GPS.EditorBuffer.get(force=False, open=False) if editor: if aliases.is_in_alias_expansion(editor): return True if editor.has_slave_cursors(): return True if GPS.Action("Cancel completion").can_execute(): return True if [ c for c in GPS.MDI.children() if (c.is_floating() and c.get_child().__class__ == GPS.GUI) ]: return True return False
def _populate_menu(self): """ Populate the Help menu for the AdaCore tools """ help_actions = [] for exec_name in _DOC_ENTRIES.keys(): executable = exec_name if exec_name == 'gnatls' and GPS.get_target(): executable = '{}-gnatls'.format(GPS.get_target()) ex = os_utils.locate_exec_on_path(executable) if ex: for descr, tup in _DOC_ENTRIES[exec_name].iteritems(): html_files, menu_base = tup menu_path = menu_base + '/' + descr action_descr = 'display documentation {}'.format(descr) # Do not create a menu if the action already exists if GPS.Action(action_descr).exists(): continue # As a convenience, html_files can either be a string or a # list of strings. Deal with this here. if type(html_files) != list: html_files = [html_files] for file in html_files: path = os.path.realpath( os.path.join(os.path.dirname(ex), '..', 'share', 'doc', file) ) if os.path.isfile(path): action = HTMLAction(action_descr, path, '/Help/{}'.format(menu_path)) help_actions.append(action) break help_actions.sort(key=lambda x: x.menu_path) for a in help_actions: a.menu(a.menu_path, ref='About', add_before=False)
def __build_and_run_all_wf(self, main_name): """ Workflow that calls "Build All" and then runs all the executables sequentially. """ # Build All builder = promises.TargetWrapper("Build All") r0 = yield builder.wait_on_execute() if r0 is not 0: return # Call "Run Main Number ..." on each main i = 1 while True: run_action = GPS.Action("Run Main Number %i" % (i)) if not run_action.exists(): break run_action.execute_if_possible() yield promises.wait_tasks() i += 1
def create( path, on_activate='', ref='', add_before=True, filter=None, group=''): """ Creates a new menu in the GPS system. The menu is added at the given location (see :func:`GPS.Menu.get` for more information on the ``path`` parameter). Submenus are created as necessary so ``path`` is valid. It is recommended now to use :class:`gs_utils.interactive` instead of creating menus explicitly. The latter creates GPS actions, to which keybindings can be associated with the user. They can also be executed more conveniently using keyboard only with the omni-search. If ``on_activate`` is specified, it is executed every time the user selects that menu. It is called with only one parameter, the instance of :class:`GPS.Menu` that was just created. If ``ref`` and ``add_before`` are specified, they specify the name of another item in the parent menu (and not a full path) before or after which the new menu should be added. If the name of the menu starts with a '-' sign, as in "/Edit/-", a menu separator is inserted instead. In this case, on_activate is ignored. Underscore characters ('_') need to be duplicated in the path. A single underscore indicates the mnemonic to be used for that menu. For example, if you create the menu "/_File", then the user can open the menu by pressing :kbd:`Alt-f`. But the underscore itself is not be displayed in the name of the menu. If ``group`` is specified, create a radio menu item in given group. :param path: A string :param on_activate: A subprogram, see the GPS documentation on subprogram parameters :param ref: A string :param add_before: A boolean :param filter: A subprogram :param group: A string :return: The instance of :class:`GPS.Menu` .. code-block:: python def on_activate(self): print "A menu was selected: " + self.data menu = GPS.Menu.create("/Edit/My Company/My Action", on_activate) menu.data = "my own data" ## Store your own data in the instance """ if on_activate: GPS.Console().write( 'GPS.Menu.create("%s") is deprecated.' % path + ' Please use gs_utils.interactive()\n') # Ignore 'group' m = None a = GPS.Action(path) a.create(lambda: on_activate(m), filter=filter) m = a.menu(path, add_before=add_before, ref=ref)
def create( self, on_activate, label=None, filter=None, ref='', add_before=True, group='0', visibility_filter=None, action=None): """ OBSOLETE: please use GPS.Action.contextual() instead. All contextual menus should be associated with a specific action, so that this action can also be associated with a key shortcut, or reused in toolbars,... Creates a new contextual menu entry. Whenever this menu entry is selected by the user, GPS executes :func:`on_activate`, passing one parameter which is the context for which the menu is displayed (this is usually the same as :func:`GPS.current_contextual`). If ``on_activate`` is None, a separator is created. The ``filter`` parameter can be used to filter when the entry should be displayed in the menu. It is a function that receives one parameter, an instance of :class:`GPS.Context`, and returns a boolean. If it returns True, the entry is displayed, otherwise it is hidden. The ``label`` parameter can be used to control the text displayed in the contextual menu. By default, it is the same as the contextual name (used in the constructor to :func:`GPS.Contextual.__init__`). If specified, it must be a subprogram that takes an instance of :class:`GPS.Context` in a parameter and returns a string, which is displayed in the menu. The parameters ``group``, ``ref`` and ``add_before`` can be used to control the location of the entry within the contextual menu. ``group`` allows you to create groups of contextual menus that will be put together. Items of the same group appear before all items with a greater group number. ``ref`` is the name of another contextual menu entry, and add_before indicates whether the new entry is put before or after that second entry. :param self: An instance of GPS.Contextual :param on_activate: A subprogram with one parameter context :param label: A subprogram :param ref: A string :param add_before: A boolean :param filter: A subprogram :param group: An integer :param GPS.Action action: An action instance to be executed on menu activation .. code-block:: python ## This example demonstrates how to create a contextual ## menu with global functions def on_contextual(context): GPS.Console("Messages").write("You selected the custom entry") def on_filter(context): return context.entity_name() is not None def on_label(context): global count count += 1 return "Custom " + count GPS.Contextual("Custom").create( on_activate=on_contextual, filter=on_filter, label=on_label) .. code-block:: python ## This example is similar to the one above, but uses a python ## class to encapsulate date. ## Note how the extra parameter self can be passed to the callbacks ## thanks to the call to self.create class My_Context(GPS.Contextual): def on_contextual(self, context): GPS.Console("Messages").write( "You selected the custom entry " + self.data) def on_filter(self, context): return context.entity_name() is not None def on_label(self, context): return self.data def __init__(self): GPS.Contextual.__init__(self, "Custom") self.data = "Menu Name" self.create(on_activate=self.on_contextual, filter=self.on_filter, label=self.on_label) """ # Unless we are creating a separator if not label or not label.endswith('-'): GPS.Console().write( 'GPS.Contextual("%s").create is deprecated.' % self.name + ' Please use GPS.Action.contextual()\n') if not action: # Create a dummy action action = GPS.Action('__%s' % self.name) action.create( on_activate=lambda: on_activate(GPS.contextual_context()), category='', # hidden filter=filter) # Unused parameters: 'group' and 'visibility_filter' action.contextual( path=label or self.name, ref=ref, add_before=add_before) else: action = GPS.Action('__separator') action.contextual( path=label or self.name, ref=ref, add_before=add_before)
def __init__(self, ispell): """Create a new static contextual menu for spell checking""" GPS.Action('spell check word').contextual( self._label, group=GPS.Contextual.Group.EDITING)
# This file contains GNATStudio customisations. import GPS try: from gs_utils import hook except: from gps_utils import hook GPS.Action("Build & Run number 1").key("control-F4", True)
def __gps_started(): if is_defined: GPS.Project.root().set_property('last_test', '') GPS.Action('Rerun test').button(toolbar='main', label='Rerun', icon='rerun-symbolic') GPS.Action('Open BCS project').button(toolbar='main', label='Project', icon='project-symbolic') GPS.Action('Open BCS test').button(toolbar='main', label='Test', icon='test-symbolic')
def __init__(self, cmdargs=[], spawn_console=False, directory=None, regexp='.+', single_line_regexp=True, block_exit=True, give_focus_on_create=False, ignore_error=False): """ Initialize and run a process with no promises, no user-defined pattern to match, but a omnipotent regexp that catches everything. The process has empty output and two flags saying that the process is unfinished and no pattern has matched yet. If spawn_console is True, a console is spawned to display the process output. This console also allows the user to relaunch the associated process with a "Relaunch" button in the console toolbar. :param bool|str spawn_console: whether to display the process and its output to a console. If this is a boolean, then a new console named like the process is opened. If it is a string, it is the name of the console to use (the empty string reused GPS's Messages window). :param bool single_line_regexp: if True, then '.' in the regexp will also match '\n'. This is useful to capture larger parts of the output at once. :param bool block_exit: whether the user should be asked when GPS exits and this process is still running. :param bool give_focus_on_create: set it to True to give the focus to the spawned console, if any. :param bool ignore_error: set it to True to hide the error message when this Process fails. """ # __current_promise = about on waiting wish for match something self.__current_promise = None # the stream that includes all output from the process self.__stream = None # __current_pattern = regexp that user waiting for in the output self.__current_pattern = None # __output = a buffer for current output of self.__process self.__output = "" # __whether process has finished self.finished = False # Used to know when the attached process is being relaunched via # th relaunch button. self.__relaunched = False # handler of process will be created -> start running # Remove empty command line arguments self.__command = [c for c in cmdargs if c] # The console associated with the process. # Created only if spawn_console is set to True. self.__console = None # Should we ignore the error when this command fails self.__ignore_error = ignore_error # Launch the command try: self.__process = GPS.Process(command=self.__command, directory=directory, regexp=regexp, single_line_regexp=single_line_regexp, block_exit=block_exit, on_match=self.__on_match, on_exit=self.__on_exit) except Exception: GPS.Logger("PROMISES").log("Failed to spawn %s" % (self.__command, )) self.__process = None return # Save the start time self.__start_time = time.time() # If requested, spawn a console to display the process output if spawn_console is not False: if isinstance(spawn_console, str): console_name = spawn_console else: console_name = cmdargs[0] toolbar_name = cmdargs[0] + '_toolbar' self.__console = GPS.Console( name=console_name, accept_input=False, on_destroy=self.__on_console_destroy, toolbar_name=toolbar_name, give_focus_on_create=give_focus_on_create) self.__action = GPS.Action('launch ' + cmdargs[0]) self.__console.write_with_links("%s\n" % ' '.join(self.__command)) # Create the associated action and relaunch button if it # does not exist yet. if not self.__action.exists(): self.__action.create( on_activate=self.__relaunch, description='relaunch the spawned process', icon='gps-refresh-symbolic') self.__action.button(toolbar=toolbar_name, label='Relaunch') def __show_console_on_exit(status): end_time = time.time() output = "\n" + TimeDisplay.get_timestamp(end_time) if not status: output += " process terminated successfully" else: output += " process exited with status " + str(status) output += ", elapsed time: " + TimeDisplay.get_elapsed( self.__start_time, end_time) + "\n" if self.__console: self.__console.write_with_links(output) def __display_output(out): if self.__console: self.__console.write_with_links("%s\n" % out) self.stream.subscribe(__display_output, oncompleted=__show_console_on_exit)