diff --git a/anaconda.spec.in b/anaconda.spec.in index f2f674f769a..f71d98aba4a 100644 --- a/anaconda.spec.in +++ b/anaconda.spec.in @@ -30,7 +30,6 @@ Source0: https://github.com/rhinstaller/%{name}/releases/download/%{name}-%{vers %define fcoeutilsver 1.0.12-3.20100323git %define gettextver 0.19.8 %define gtk3ver 3.22.17 -%define helpver 26.2-1 %define isomd5sumver 1.0.10 %define langtablever 0.0.60 %define libarchivever 3.0.4 @@ -283,8 +282,6 @@ Requires: nm-connection-editor %ifnarch s390 s390x Requires: NetworkManager-wifi %endif -Requires: anaconda-user-help >= %{helpver} -Requires: yelp %if ! 0%{?rhel} Requires: blivet-gui-runtime >= %{blivetguiver} %endif diff --git a/data/anaconda.conf b/data/anaconda.conf index 34d2d26802a..e3781100649 100644 --- a/data/anaconda.conf +++ b/data/anaconda.conf @@ -274,9 +274,6 @@ reformat_blocklist = /home /usr/local /opt /var/www # The path to a custom stylesheet. custom_stylesheet = -# The path to a directory with help files. -help_directory = /usr/share/anaconda/help - # A list of spokes to hide in UI. # FIXME: Use other identification then names of the spokes. hidden_spokes = diff --git a/data/profile.d/fedora.conf b/data/profile.d/fedora.conf index d4fe6d0f26b..6c074df73b8 100644 --- a/data/profile.d/fedora.conf +++ b/data/profile.d/fedora.conf @@ -19,7 +19,6 @@ default_scheme = BTRFS btrfs_compression = zstd:1 [User Interface] -help_directory = /usr/share/anaconda/help/fedora custom_stylesheet = /usr/share/anaconda/pixmaps/fedora.css [Payload] diff --git a/data/profile.d/ovirt.conf b/data/profile.d/ovirt.conf index eccd159b7b0..b5e941ee37d 100644 --- a/data/profile.d/ovirt.conf +++ b/data/profile.d/ovirt.conf @@ -32,7 +32,6 @@ req_partition_sizes = /boot 1 GiB [User Interface] -help_directory = /usr/share/anaconda/help/rhel hidden_spokes = UserSpoke [Payload] diff --git a/data/profile.d/rhel.conf b/data/profile.d/rhel.conf index 0a645fd0cad..368f74794e8 100644 --- a/data/profile.d/rhel.conf +++ b/data/profile.d/rhel.conf @@ -37,7 +37,6 @@ default_partitioning = swap_is_recommended = True [User Interface] -help_directory = /usr/share/anaconda/help/rhel custom_stylesheet = /usr/share/anaconda/pixmaps/redhat.css [License] diff --git a/data/profile.d/rhvh.conf b/data/profile.d/rhvh.conf index 558f6584030..8d61932bcf7 100644 --- a/data/profile.d/rhvh.conf +++ b/data/profile.d/rhvh.conf @@ -38,7 +38,6 @@ req_partition_sizes = /boot 1 GiB [User Interface] -help_directory = /usr/share/anaconda/help/rhel hidden_spokes = UserSpoke [Payload] diff --git a/docs/release-notes/remove-help-support.rst b/docs/release-notes/remove-help-support.rst new file mode 100644 index 00000000000..17895cfaa29 --- /dev/null +++ b/docs/release-notes/remove-help-support.rst @@ -0,0 +1,15 @@ +:Type: User interfaces +:Summary: Remove all support of the built-in help system + +:Description: + The support of the built-in help accessible from spokes and hubs of all user interfaces + is removed. The ``help_directory`` Anaconda configuration option is deprecated and removed. + The ``anaconda-user-help`` package will be deprecated and removed. + + Anaconda will aim to make user interfaces self-descriptive and encourage users to use the + official documentation of specific Linux distributions available on-line. + +:Links: + - https://docs.fedoraproject.org/en-US/fedora/latest/getting-started/ + - https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/ + - https://src.fedoraproject.org/rpms/anaconda-user-help/ diff --git a/pyanaconda/core/configuration/ui.py b/pyanaconda/core/configuration/ui.py index e4432f68f8e..50df96f1c1a 100644 --- a/pyanaconda/core/configuration/ui.py +++ b/pyanaconda/core/configuration/ui.py @@ -29,11 +29,6 @@ def custom_stylesheet(self): """The path to a custom stylesheet.""" return self._get_option("custom_stylesheet", str) - @property - def help_directory(self): - """The path to a directory with help files.""" - return self._get_option("help_directory", str) - @property def hidden_spokes(self): """A list of spokes to hide in UI. diff --git a/pyanaconda/ui/gui/__init__.py b/pyanaconda/ui/gui/__init__.py index 7cddde29900..520c9b942e9 100644 --- a/pyanaconda/ui/gui/__init__.py +++ b/pyanaconda/ui/gui/__init__.py @@ -49,7 +49,6 @@ from pyanaconda.core.async_utils import async_action_wait from pyanaconda.ui.gui.utils import watch_children, unwatch_children from pyanaconda.ui.gui.helpers import autoinstall_stopped -from pyanaconda.ui.lib.help import show_graphical_help_for_screen import os.path from pyanaconda.anaconda_loggers import get_module_logger @@ -105,10 +104,6 @@ class GUIObject(common.UIObject): that use GUI elements (Hubs & Spokes) from Anaconda can override the translation domain with their own, so that their subclasses are properly translated. - helpFile -- The location of the yelp-compatible help file for the - given GUI object. The default value of "" indicates - that the object has not specific help file assigned - and the default help file should be used. """ builderObjects = [] mainWidgetName = None @@ -353,8 +348,6 @@ def __init__(self, fullscreen=False, decorated=False): # Help button mnemonics handling self._mnemonic_signal = None - # we have a sensible initial value, just in case - self._saved_help_button_label = _("Help!") # Apply the initial language attributes self._language = None @@ -379,20 +372,6 @@ def _on_overlay_get_child_position(self, overlay_container, overlayed_widget, al # Return False to indicate that the child allocation is not yet set return False - def _on_mnemonics_visible_changed(self, window, property_type, obj): - # mnemonics display has been activated or deactivated, - # add or remove the F1 mnemonics display from the help button - help_button = obj.window.get_help_button() - if window.props.mnemonics_visible: - # save current label - old_label = help_button.get_label() - self._saved_help_button_label = old_label - # add the (F1) "mnemonics" to the help button - help_button.set_label("%s (F1)" % old_label) - else: - # restore the old label - help_button.set_label(self._saved_help_button_label) - def _on_child_added(self, widget, user_data): # If this is GtkLabel, apply the language attribute if isinstance(widget, Gtk.Label): @@ -434,17 +413,6 @@ def _setVisibleChild(self, child): child.window.add_accelerator("button-clicked", self._accel_group, Gdk.KEY_F12, 0, 0) - # Configure the help button - child.window.add_accelerator("help-button-clicked", self._accel_group, - Gdk.KEY_F1, 0, 0) - child.window.add_accelerator("help-button-clicked", self._accel_group, - Gdk.KEY_F1, Gdk.ModifierType.MOD1_MASK, 0) - - # Connect to mnemonics-visible to add the (F1) mnemonic to the button label - if self._mnemonic_signal: - self.disconnect(self._mnemonic_signal) - self._mnemonic_signal = self.connect("notify::mnemonics-visible", self._on_mnemonics_visible_changed, child) - self._stack.set_visible_child(child.window) if child.focusWidgetName: @@ -699,7 +667,6 @@ def _instantiateAction(self, actionClass): # Use connect_after so classes can add actions before we change screens obj.window.connect_after("continue-clicked", self._on_continue_clicked) - obj.window.connect_after("help-button-clicked", self._on_help_clicked, obj) obj.window.connect_after("quit-clicked", self._on_quit_clicked) return obj @@ -907,11 +874,6 @@ def _on_continue_clicked(self, window, user_data=None): self._currentAction = nextAction self._actions.pop(0) - def _on_help_clicked(self, window, obj): - # the help button has been clicked, start the yelp viewer with - # content for the current screen - show_graphical_help_for_screen(obj.get_screen_id()) - def _on_quit_clicked(self, win, userData=None): if not win.get_quit_button(): return diff --git a/pyanaconda/ui/gui/spokes/__init__.py b/pyanaconda/ui/gui/spokes/__init__.py index a43b245bb7a..f1885e34d5a 100644 --- a/pyanaconda/ui/gui/spokes/__init__.py +++ b/pyanaconda/ui/gui/spokes/__init__.py @@ -18,7 +18,6 @@ from pyanaconda.ui import common from pyanaconda.ui.gui import GUIObject -from pyanaconda.ui.lib.help import show_graphical_help_for_screen from pyanaconda.anaconda_loggers import get_module_logger log = get_module_logger(__name__) @@ -56,17 +55,9 @@ def __init__(self, data, storage, payload): GUIObject.__init__(self, data) common.NormalSpoke.__init__(self, storage, payload) - # Add a help handler - self.window.connect_after("help-button-clicked", self._on_help_clicked) - # warning message self._current_warning_message = "" - def _on_help_clicked(self, window): - # the help button has been clicked, start the yelp viewer with - # content for the current spoke - show_graphical_help_for_screen(self.get_screen_id()) - def on_back_clicked(self, button): # Notify the hub that we're finished. # The hub will be the current-action of the main window. diff --git a/pyanaconda/ui/lib/help.py b/pyanaconda/ui/lib/help.py deleted file mode 100644 index 62784bb2df8..00000000000 --- a/pyanaconda/ui/lib/help.py +++ /dev/null @@ -1,282 +0,0 @@ -# -# Copyright (C) 2014 Red Hat, Inc. -# -# This copyrighted material is made available to anyone wishing to use, -# modify, copy, or redistribute it subject to the terms and conditions of -# the GNU General Public License v.2, or (at your option) any later version. -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY expressed or implied, including the implied warranties of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. You should have received a copy of the -# GNU General Public License along with this program; if not, write to the -# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the -# source code or documentation are not subject to the GNU General Public -# License and may only be used or replicated with the express permission of -# Red Hat, Inc. -# -""" -Anaconda built-in help module -""" -import functools -import os -import json -from collections import namedtuple - -from pyanaconda.anaconda_loggers import get_module_logger -from pyanaconda.core.configuration.anaconda import conf -from pyanaconda.core.constants import DEFAULT_LANG, DisplayModes -from pyanaconda.core.util import startProgram -from pyanaconda.core.path import join_paths -from pyanaconda.core.live_user import get_live_user -from pyanaconda.localization import find_best_locale_match - -log = get_module_logger(__name__) - -__all__ = [ - "show_graphical_help_for_screen", - "get_help_path_for_screen", - "localize_help_file", - "show_graphical_help", -] - -# Arguments of the built-in help for one screen: -# -# path An absolute path to the localized help file. -# file An relative path to the help file. -# anchor A name of the anchor in the help file. -# -HelpArguments = namedtuple("HelpArguments", ["path", "file", "anchor"]) - -# An identifier of the default help content. -DEFAULT_HELP_ID = "_default_" - -# The running yelp process. -yelp_process = None - - -def show_graphical_help_for_screen(screen_id): - """Show a help file of the specified screen in the GUI display mode. - - :param str screen_id: an identifier of a ui screen - """ - log.info("Requested a graphical help for the '%s' screen.", screen_id) - help_args = _get_help_args_for_screen(DisplayModes.GUI, screen_id) - - if not help_args: - log.debug("There is no help for the '%s' screen.", screen_id) - return - - show_graphical_help(help_args.path, help_args.anchor) - - -def get_help_path_for_screen(screen_id, display_mode=DisplayModes.TUI): - """Return a path to the help file for the specified screen. - - :param str screen_id: an identifier of a ui screen - :param DisplayModes display_mode: a type of the display mode - :return str: an absolute path to the help file or None - """ - log.info("Requested a help path for the '%s' screen.", screen_id) - help_args = _get_help_args_for_screen(display_mode, screen_id) - - if not help_args: - log.debug("There is no help for the '%s' screen.", screen_id) - return None - - return help_args.path - - -def _get_help_args_for_screen(display_mode, screen_id): - """Return help arguments for the specified screen. - - Use the default help if there is no help for the screen. - If there is also no default help, return None. - - :param str screen_id: an identifier of a ui screen - :param DisplayModes display_mode: a type of the display mode - :return HelpArguments: help arguments for the screen or None - """ - help_mapping = _get_help_mapping(display_mode) - - for help_id in (screen_id, DEFAULT_HELP_ID): - help_args = _get_help_args(help_mapping, help_id) - - if help_args.path: - return help_args - - log.debug("There is no help for the '%s' help id.", help_id) - - return None - - -@functools.cache -def _get_help_mapping(display_mode): - """Parse the json file containing the help mapping. - - The mappings files are located in the root of the help directory. - For example for RHEL, they are expected to be at: - - /usr/share/anaconda/help/rhel/anaconda-gui.json - /usr/share/anaconda/help/rhel/anaconda-tui.json - - :param DisplayModes display_mode: a type of the display mode - :return dict: a help mapping dictionary - """ - help_directory = conf.ui.help_directory - - name = "anaconda-{}.json".format(display_mode.value.lower()) - path = join_paths(help_directory, name) - - if not os.path.exists(path): - log.error("The help mapping file is not found at %s.", path) - return {} - - mapping = {} - - try: - with open(path, "rt") as f: - mapping = json.load(f) - except (IOError, json.JSONDecodeError) as e: - log.error("Failed to parse the help mapping file at %s: %s", path, str(e)) - - return mapping - - -def _get_help_args(help_mapping, help_id): - """Return a help arguments for the specified help id. - - :param dict help_mapping: a help mapping dictionary - :param str help_id: an identifier of a help content - :return HelpArguments: arguments of the help content - """ - item = help_mapping.get(help_id, {}) - file = item.get("file") or "" - anchor = item.get("anchor") or "" - path = localize_help_file(file) or "" - - return HelpArguments( - path=path, - file=file, - anchor=anchor, - ) - - -def localize_help_file(help_file, help_directory=None, current_locale=None): - """Return an absolute path to the localized help file. - - Get the path to a localized help file for specified language. - - List all available languages for the Anaconda help. Content is stored in - directories named after the given language code (en-US, cs-CZ, jp-JP, etc.). - We check if the given folder contains the currently needed help file and - only consider it fit to use if it does have the file - - :param str help_file: a relative path to the requested help file - :param str help_directory: a path to directory with help files or None - :param str current_locale: a valid locale (e.g. en_US.UTF-8) or None - :return str: a path to the localized file or None - """ - # Collect languages and files that provide the help content. - if help_directory is None: - help_directory = conf.ui.help_directory - - available_files = _collect_help_files(help_directory, help_file) - - # Find the best help file for the current locale. - if current_locale is None: - current_locale = os.environ.get("LANG", "") - - return _find_best_help_file(current_locale, available_files) - - -def _collect_help_files(help_directory, help_file): - """Collect available help files. - - :param str help_directory: a path to directory with help files or None - :param str help_file: a relative path to the requested help file - :return dict: a dictionary of langcodes and absolute paths to the help files - """ - if not help_file: - return {} - - if not help_directory or not os.path.exists(help_directory): - log.debug("The %s help directory does not exist.", help_directory) - return {} - - files = {} - - for lang in os.listdir(help_directory): - # Does the help file exist for this language? - path = join_paths(help_directory, lang, help_file) - if not os.path.isfile(path): - continue - - # Create a valid langcode. For example, use en_US instead of en-US. - code = lang.replace('-', '_') - files[code] = path - - return files - - -def _find_best_help_file(current_locale, available_files): - """Find the best help file for the specified locale. - - :param str current_locale: a valid locale (e.g. en_US.UTF-8) - :param dict available_files: a dictionary of langcodes and help paths - :return str: a path to the best help file or None - """ - for locale in (current_locale, DEFAULT_LANG): - best_lang = find_best_locale_match(locale, available_files.keys()) - best_path = available_files.get(best_lang, None) - - if best_path: - return best_path - - return None - - -def show_graphical_help(help_path, help_anchor=None): - """Start a new yelp process and make sure to kill any existing ones. - - :param str help_path: a path to the help file yelp should load - :param str help_anchor: a name of the anchor in the help file - """ - global yelp_process - - # Kill the existing process. - if yelp_process: - yelp_process.kill() - yelp_process.wait() - yelp_process = None - - # Quit if there is nothing to show. - if not help_path: - log.error("No help file to show.") - return - - # Start yelp and show the specified help file at the given anchor. - args = [] - - if help_anchor: - args.append("ghelp:{}?{}".format(help_path, help_anchor)) - else: - args.append(help_path) - - user_id = None - env_prune = None - env_add = None - - user = get_live_user() - if user: - user_id = user.uid - env_prune = user.env_prune - env_add = user.env_add - - yelp_process = startProgram( - ["yelp", *args], - reset_lang=False, - user=user_id, - env_prune=env_prune, - env_add=env_add, - ) diff --git a/pyanaconda/ui/tui/hubs/__init__.py b/pyanaconda/ui/tui/hubs/__init__.py index 2ace1f71387..7aeddc13ab6 100644 --- a/pyanaconda/ui/tui/hubs/__init__.py +++ b/pyanaconda/ui/tui/hubs/__init__.py @@ -18,10 +18,8 @@ # from pyanaconda import lifecycle from pyanaconda.ui.tui.tuiobject import TUIObject -from pyanaconda.ui.lib.help import get_help_path_for_screen from pyanaconda.ui import common -from simpleline.render.adv_widgets import HelpScreen from simpleline.render.containers import ListRowContainer from simpleline.render.prompt import Prompt from simpleline.render.screen import InputState @@ -123,10 +121,6 @@ def _item_called(self, data): item = data ScreenHandler.push_screen(item) - def _get_help(self): - """Get the help path for this screen.""" - return get_help_path_for_screen(self.get_screen_id()) - def input(self, args, key): """Handle user input. Numbers are used to show a spoke, the rest is passed to the higher level for processing.""" @@ -141,12 +135,6 @@ def input(self, args, key): if not spoke.completed and spoke.mandatory: print(_("Please complete all spokes before continuing")) return InputState.DISCARDED - elif key == Prompt.HELP: - help_path = self._get_help() - - if help_path: - ScreenHandler.push_screen_modal(HelpScreen(help_path)) - return InputState.PROCESSED_AND_REDRAW return key @@ -167,7 +155,4 @@ def prompt(self, args=None): if self._spoke_count == 1: prompt.add_option("1", _("to enter the %(spoke_title)s spoke") % {"spoke_title": list(self._spokes.values())[0].title}) - if self._get_help(): - prompt.add_help_option() - return prompt diff --git a/pyanaconda/ui/tui/spokes/__init__.py b/pyanaconda/ui/tui/spokes/__init__.py index 4298c63ff75..864dad5a71f 100644 --- a/pyanaconda/ui/tui/spokes/__init__.py +++ b/pyanaconda/ui/tui/spokes/__init__.py @@ -18,13 +18,8 @@ # from pyanaconda.ui.common import Spoke, StandaloneSpoke, NormalSpoke from pyanaconda.ui.tui.tuiobject import TUIObject -from pyanaconda.ui.lib.help import get_help_path_for_screen from pyanaconda.core.i18n import N_, _ -from simpleline.render.adv_widgets import HelpScreen -from simpleline.render.screen import InputState -from simpleline.render.screen_handler import ScreenHandler -from simpleline.render.prompt import Prompt from simpleline.render.widgets import Widget, CheckboxWidget __all__ = ["TUISpoke", "StandaloneSpoke", "NormalTUISpoke"] @@ -94,31 +89,7 @@ class NormalTUISpoke(TUISpoke, NormalSpoke): .. inheritance-diagram:: NormalTUISpoke :parts: 3 """ - - def _get_help(self): - """Get the help path for this screen.""" - return get_help_path_for_screen(self.get_screen_id()) - - def input(self, args, key): - """Handle the input.""" - if key.lower() == Prompt.HELP: - help_path = self._get_help() - - if help_path: - ScreenHandler.push_screen_modal(HelpScreen(help_path)) - return InputState.PROCESSED_AND_REDRAW - - return super().input(args, key) - - def prompt(self, args=None): - """Return the prompt.""" - prompt = TUISpoke.prompt(self, args) - - if self._get_help(): - prompt.add_help_option() - - return prompt - + pass class StandaloneTUISpoke(TUISpoke, StandaloneSpoke): """ diff --git a/tests/unit_tests/pyanaconda_tests/ui/test_help.py b/tests/unit_tests/pyanaconda_tests/ui/test_help.py deleted file mode 100644 index e81e36df263..00000000000 --- a/tests/unit_tests/pyanaconda_tests/ui/test_help.py +++ /dev/null @@ -1,310 +0,0 @@ -# -# Copyright (C) 2020 Red Hat, Inc. -# -# This copyrighted material is made available to anyone wishing to use, -# modify, copy, or redistribute it subject to the terms and conditions of -# the GNU General Public License v.2, or (at your option) any later version. -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY expressed or implied, including the implied warranties of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General -# Public License for more details. You should have received a copy of the -# GNU General Public License along with this program; if not, write to the -# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the -# source code or documentation are not subject to the GNU General Public -# License and may only be used or replicated with the express permission of -# Red Hat, Inc. -# -import os -import tempfile - -import unittest -from unittest.mock import patch - -from pyanaconda.core.constants import DisplayModes -from pyanaconda.ui.lib.help import _get_help_mapping, show_graphical_help, _get_help_args, \ - HelpArguments, get_help_path_for_screen, show_graphical_help_for_screen, localize_help_file, \ - _get_help_args_for_screen - -INVALID_MAPPING = """ -This is an invalid mapping. -""" - -GUI_MAPPING = """ -{ - "_default_": { - "file": "Installation_Guide.xml", - "anchor": "" - }, - "installation-summary": { - "file": "SummaryHub.xml", - "anchor": "" - }, - "user-configuration": { - "file": "UserSpoke.xml", - "anchor": "create-user" - } -} -""" - -TUI_MAPPING = """ -{ - "_default_": { - "file": "Installation_Guide.txt" - }, - "installation-summary": { - "file": "SummaryHub.txt" - }, - "user-configuration": { - "file": "UserSpoke.txt" - } -} -""" - - -class HelpSupportTestCase(unittest.TestCase): - """Test the built-in help support.""" - - def tearDown(self): - """Clean up after a test.""" - _get_help_mapping.cache_clear() - - def _create_file(self, file_dir, file_name, file_content): - """Create a file with the help mapping.""" - os.makedirs(file_dir, exist_ok=True) - file_path = os.path.join(file_dir, file_name) - - with open(file_path, mode="w") as f: - f.write(file_content) - - @patch('pyanaconda.ui.lib.help.conf') - def test_get_help_mapping(self, conf_mock): - """Test the _get_help_mapping function.""" - with tempfile.TemporaryDirectory() as tmp_dir: - conf_mock.ui.help_directory = tmp_dir - - _get_help_mapping.cache_clear() - assert _get_help_mapping(DisplayModes.TUI) == {} - - _get_help_mapping.cache_clear() - self._create_file(tmp_dir, "anaconda-tui.json", INVALID_MAPPING) - assert _get_help_mapping(DisplayModes.TUI) == {} - - _get_help_mapping.cache_clear() - self._create_file(tmp_dir, "anaconda-gui.json", GUI_MAPPING) - assert _get_help_mapping(DisplayModes.GUI) == { - "_default_": { - "file": "Installation_Guide.xml", - "anchor": "" - }, - "installation-summary": { - "file": "SummaryHub.xml", - "anchor": "" - }, - "user-configuration": { - "file": "UserSpoke.xml", - "anchor": "create-user" - } - } - - @patch('pyanaconda.ui.lib.help.conf') - def test_get_help_args(self, conf_mock): - """Test the _get_help_args function.""" - conf_mock.ui.help_directory = "/fake/path" - - mapping = { - "_default_": { - "file": "Installation_Guide.xml", - "anchor": "" - }, - "installation-summary": { - "file": "SummaryHub.xml", - "anchor": "" - }, - "user-configuration": { - "file": "UserSpoke.xml", - "anchor": "create-user" - } - } - - assert _get_help_args({}, "") == \ - HelpArguments("", "", "") - - assert _get_help_args({}, "installation-summary") == \ - HelpArguments("", "", "") - - assert _get_help_args(mapping, "installation-summary") == \ - HelpArguments("", "SummaryHub.xml", "") - - assert _get_help_args(mapping, "user-configuration") == \ - HelpArguments("", "UserSpoke.xml", "create-user") - - assert _get_help_args(mapping, "unknown-spoke") == \ - HelpArguments("", "", "") - - def test_localize_help_file(self): - """Test the localize_help_file function.""" - with tempfile.TemporaryDirectory() as tmp_dir: - - # No available file. - assert localize_help_file("file.txt", tmp_dir, "cs_CZ.UTF-8") is None - - # File in default locale. - self._create_file( - file_name="file.txt", - file_dir=os.path.join(tmp_dir, "en-US"), - file_content="" - ) - - assert localize_help_file("file.txt", tmp_dir, "cs_CZ.UTF-8") == \ - os.path.join(tmp_dir, "en-US", "file.txt") - - # File in both locales. - self._create_file( - file_name="file.txt", - file_dir=os.path.join(tmp_dir, "cs-CZ"), - file_content="" - ) - - assert localize_help_file("file.txt", tmp_dir, "cs_CZ.UTF-8") == \ - os.path.join(tmp_dir, "cs-CZ", "file.txt") - - @patch('pyanaconda.ui.lib.help.conf') - def test_get_help_args_for_screen(self, conf_mock): - """Test the _get_help_args_for_screen function.""" - with tempfile.TemporaryDirectory() as tmp_dir: - conf_mock.ui.help_directory = tmp_dir - content_dir = os.path.join(tmp_dir, "en-US") - - # No mapping. - _get_help_mapping.cache_clear() - assert _get_help_args_for_screen(DisplayModes.GUI, "installation-summary") is None - - # No help and no default. - _get_help_mapping.cache_clear() - self._create_file(tmp_dir, "anaconda-gui.json", GUI_MAPPING) - assert _get_help_args_for_screen(DisplayModes.GUI, "installation-summary") is None - - # No help, return default. - self._create_file(content_dir, "Installation_Guide.xml", "") - help_path = os.path.join(tmp_dir, "en-US", "Installation_Guide.xml") - - assert _get_help_args_for_screen(DisplayModes.GUI, "installation-summary") == \ - HelpArguments(help_path, "Installation_Guide.xml", "") - - # Return help. - self._create_file(content_dir, "SummaryHub.xml", "") - help_path = os.path.join(tmp_dir, "en-US", "SummaryHub.xml") - - assert _get_help_args_for_screen(DisplayModes.GUI, "installation-summary") == \ - HelpArguments(help_path, "SummaryHub.xml", "") - - # Return help with anchor. - self._create_file(content_dir, "UserSpoke.xml", "") - help_path = os.path.join(tmp_dir, "en-US", "UserSpoke.xml") - - assert _get_help_args_for_screen(DisplayModes.GUI, "user-configuration") == \ - HelpArguments(help_path, "UserSpoke.xml", "create-user") - - @patch("pyanaconda.ui.lib.help.get_live_user", return_value=None) - @patch('pyanaconda.ui.lib.help.startProgram') - def test_show_graphical_help(self, starter, user_mock): - """Test the show_graphical_help function.""" - show_graphical_help("/my/file") - starter.assert_called_once_with( - ["yelp", "/my/file"], - reset_lang=False, - user=None, - env_prune=None, - env_add=None, - ) - user_mock.assert_called_once_with() - user_mock.reset_mock() - starter.reset_mock() - - show_graphical_help("/my/file", "my-anchor") - starter.assert_called_once_with( - ["yelp", "ghelp:/my/file?my-anchor"], - reset_lang=False, - user=None, - env_prune=None, - env_add=None, - ) - user_mock.assert_called_once_with() - user_mock.reset_mock() - starter.reset_mock() - - show_graphical_help("") - starter.assert_not_called() - user_mock.assert_not_called() - - @patch('pyanaconda.ui.lib.help.conf') - def test_get_help_path_for_screen(self, conf_mock): - """Test the get_help_path_for_screen function.""" - with tempfile.TemporaryDirectory() as tmp_dir: - conf_mock.ui.help_directory = tmp_dir - content_dir = os.path.join(tmp_dir, "en-US") - - # No help. - _get_help_mapping.cache_clear() - self._create_file(tmp_dir, "anaconda-tui.json", TUI_MAPPING) - assert get_help_path_for_screen("installation-summary") is None - - # Help file. - self._create_file(content_dir, "SummaryHub.txt", "") - self._create_file(content_dir, "UserSpoke.txt", "") - - assert get_help_path_for_screen("installation-summary") == \ - os.path.join(tmp_dir, "en-US", "SummaryHub.txt") - - assert get_help_path_for_screen("user-configuration") == \ - os.path.join(tmp_dir, "en-US", "UserSpoke.txt") - - @patch("pyanaconda.ui.lib.help.get_live_user", return_value=None) - @patch('pyanaconda.ui.lib.help.startProgram') - @patch('pyanaconda.ui.lib.help.conf') - def test_show_graphical_help_for_screen(self, conf_mock, starter, user_mock): - with tempfile.TemporaryDirectory() as tmp_dir: - conf_mock.ui.help_directory = tmp_dir - content_dir = os.path.join(tmp_dir, "en-US") - - # No help. - _get_help_mapping.cache_clear() - self._create_file(tmp_dir, "anaconda-gui.json", GUI_MAPPING) - - show_graphical_help_for_screen("installation-summary") - starter.assert_not_called() - user_mock.assert_not_called() - starter.reset_mock() - user_mock.reset_mock() - - # Help file. - self._create_file(content_dir, "SummaryHub.xml", "") - show_graphical_help_for_screen("installation-summary") - - help_path = os.path.join(tmp_dir, "en-US", "SummaryHub.xml") - starter.assert_called_once_with( - ["yelp", help_path], - reset_lang=False, - user=None, - env_prune=None, - env_add=None, - ) - user_mock.assert_called_once_with() - starter.reset_mock() - user_mock.reset_mock() - - # Help file with anchor. - self._create_file(content_dir, "UserSpoke.xml", "") - show_graphical_help_for_screen("user-configuration") - - help_path = os.path.join(tmp_dir, "en-US", "UserSpoke.xml") - yelp_arg = "ghelp:" + help_path + "?create-user" - user_mock.assert_called_once_with() - starter.assert_called_once_with( - ["yelp", yelp_arg], - reset_lang=False, - user=None, - env_prune=None, - env_add=None, - ) diff --git a/widgets/glade/AnacondaWidgets.xml b/widgets/glade/AnacondaWidgets.xml index f166052625b..fb17a7580cb 100644 --- a/widgets/glade/AnacondaWidgets.xml +++ b/widgets/glade/AnacondaWidgets.xml @@ -25,9 +25,6 @@ - - - info_bar_clicked = NULL; - klass->help_button_clicked = NULL; /** * AnacondaBaseWindow::info-bar-clicked: @@ -244,24 +234,6 @@ static void anaconda_base_window_class_init(AnacondaBaseWindowClass *klass) { g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - /** - * AnacondaBaseWindow::help-button-clicked: - * @window: the window that received the signal - * - * Emitted when the help button in the right corner has been activated - * (pressed and released). This is commonly used to open the help view with - * help content for the given spoke or hub - * - * Since: 3.1 - */ - window_signals[SIGNAL_HELP_BUTTON_CLICKED] = g_signal_new("help-button-clicked", - G_TYPE_FROM_CLASS(object_class), - G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET(AnacondaBaseWindowClass, help_button_clicked), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - g_type_class_add_private(object_class, sizeof(AnacondaBaseWindowPrivate)); gtk_widget_class_set_css_name(widget_class, "AnacondaBaseWindow"); @@ -393,30 +365,11 @@ G_GNUC_END_IGNORE_DEPRECATIONS gtk_widget_set_margin_top(win->priv->layout_indicator, 6); gtk_widget_set_margin_bottom(win->priv->layout_indicator, 6); - /* Create the help button. */ - win->priv->help_button = gtk_button_new_with_label(_(HELP_BUTTON_LABEL)); - gtk_widget_set_halign(win->priv->help_button, GTK_ALIGN_END); - gtk_widget_set_vexpand(win->priv->help_button, FALSE); - gtk_widget_set_valign(win->priv->help_button, GTK_ALIGN_END); - gtk_widget_set_margin_bottom(win->priv->help_button, 6); - gtk_widget_set_name(win->priv->help_button, "anaconda-help-button"); - - atk = gtk_widget_get_accessible(win->priv->help_button); - atk_object_set_name(atk, _(HELP_BUTTON_LABEL)); - - /* Hook up some signals for that button. The signal handlers here will - * just raise our own custom signals for the whole window. - */ - g_signal_connect(win->priv->help_button, "clicked", - G_CALLBACK(anaconda_base_window_help_button_clicked), win); - - /* Add everything to the nav area. */ gtk_grid_attach(GTK_GRID(win->priv->nav_area), win->priv->name_label, 0, 0, 1, 1); gtk_grid_attach(GTK_GRID(win->priv->nav_area), win->priv->distro_label, 1, 0, 2, 1); gtk_grid_attach(GTK_GRID(win->priv->nav_area), win->priv->beta_label, 1, 1, 1, 1); gtk_grid_attach(GTK_GRID(win->priv->nav_area), win->priv->layout_indicator, 1, 2, 1, 1); - gtk_grid_attach(GTK_GRID(win->priv->nav_area), win->priv->help_button, 2, 1, 1, 2); /* Last thing for the main_box is a revealer for the info bar */ win->priv->info_revealer = gtk_revealer_new(); @@ -543,20 +496,6 @@ GtkWidget *anaconda_base_window_get_nav_area(AnacondaBaseWindow *win) { return win->priv->nav_area; } -/** - * anaconda_base_window_get_help_button: - * @win: a #AnacondaBaseWindow - * - * Returns the help button. - * - * Returns: (transfer none): the help button - * - * Since: 3.1 - */ -GtkWidget *anaconda_base_window_get_help_button(AnacondaBaseWindow *win) { - return win->priv->help_button; -} - /** * anaconda_base_window_get_layout_indicator_box: * @win: a #AnacondaBaseWindow @@ -784,11 +723,6 @@ static gboolean anaconda_base_window_info_bar_clicked(GtkWidget *wiget, GdkEvent return FALSE; } -static void anaconda_base_window_help_button_clicked(GtkButton *button, - AnacondaBaseWindow *win) { - g_signal_emit(win, window_signals[SIGNAL_HELP_BUTTON_CLICKED], 0); -} - /** * anaconda_base_window_clear_info: * @win: a #AnacondaBaseWindow @@ -846,8 +780,6 @@ void anaconda_base_window_retranslate(AnacondaBaseWindow *win) { gtk_label_set_text(GTK_LABEL(win->priv->beta_label), _(win->priv->orig_beta)); - gtk_button_set_label(GTK_BUTTON(win->priv->help_button), _(HELP_BUTTON_LABEL)); - /* retranslate the layout indicator */ anaconda_layout_indicator_retranslate(ANACONDA_LAYOUT_INDICATOR(win->priv->layout_indicator)); } diff --git a/widgets/src/BaseWindow.h b/widgets/src/BaseWindow.h index 43eef0811de..ba7a59ba974 100644 --- a/widgets/src/BaseWindow.h +++ b/widgets/src/BaseWindow.h @@ -54,14 +54,11 @@ struct _AnacondaBaseWindow { * pointer to be cast to a #GtkBin pointer. * @info_bar_clicked : Function pointer called when the #AnacondaBaseWindow::info-bar-clicked * signal is emitted. - * @help_button_clicked: Function pointer called when the #AnacondaBaseWindow::help-button-clicked - * signal is emitted. */ struct _AnacondaBaseWindowClass { GtkBinClass parent_class; void (* info_bar_clicked) (AnacondaBaseWindow *window); - void (* help_button_clicked) (AnacondaBaseWindow *window); }; GType anaconda_base_window_get_type (void); @@ -82,7 +79,6 @@ GtkWidget *anaconda_base_window_get_alignment (AnacondaBaseWindow *win); GtkWidget *anaconda_base_window_get_main_box (AnacondaBaseWindow *win); GtkWidget *anaconda_base_window_get_nav_area (AnacondaBaseWindow *win); GtkWidget *anaconda_base_window_get_nav_area_background_window (AnacondaBaseWindow *win); -GtkWidget *anaconda_base_window_get_help_button (AnacondaBaseWindow *win); GtkWidget *anaconda_base_window_get_layout_indicator_box (AnacondaBaseWindow *win); G_END_DECLS