[PATCH 1/2] Add a help button to every Anaconda screen
Vratislav Podzimek
vpodzime at redhat.com
Wed Aug 27 08:09:46 UTC 2014
On Tue, 2014-08-26 at 08:46 -0400, Anne Mulhern wrote:
>
>
>
> ----- Original Message -----
> > From: "Anne Mulhern" <amulhern at redhat.com>
> > To: "anaconda patch review" <anaconda-patches at lists.fedorahosted.org>
> > Sent: Monday, August 25, 2014 4:24:00 PM
> > Subject: Re: [PATCH 1/2] Add a help button to every Anaconda screen
> >
> >
> >
> >
> >
> > ----- Original Message -----
> > > From: "Martin Kolman" <mkolman at redhat.com>
> > > To: anaconda-patches at lists.fedorahosted.org
> > > Sent: Monday, August 25, 2014 10:17:36 AM
> > > Subject: [PATCH 1/2] Add a help button to every Anaconda screen
> > >
> > > This makes context aware help possible for every Anaconda screen by
> > > providing a help button in the upper right corner of the screen.
> > > Clicking the button opens the yelp help viewer with either a help page
> > > tailored for the given screen, the main page of the installation guide
> > > (if no help is available for the screen) or a "no help found" placeholder
> > > page.
> > > The new helpFile GUIObject attribute is used to specify which help
> > > file to show for the given screen. If no help file is specified
> > > either the main page of the Installation Guide will be shown (if
> > > available) or the placeholder page will be shown.
> > >
> > > Signed-off-by: Martin Kolman <mkolman at redhat.com>
> > > ---
> > > anaconda.spec.in | 1 +
> > > data/help/FedoraPlaceholder.html | 5 ++
> > > data/help/FedoraPlaceholderWithLinks.html | 13 ++++
> > > data/help/Makefile.am | 22 ++++++
> > > pyanaconda/ihelp.py | 123
> > > ++++++++++++++++++++++++++++++
> > > pyanaconda/installclass.py | 6 ++
> > > pyanaconda/installclasses/fedora.py | 3 +
> > > pyanaconda/ui/gui/__init__.py | 12 +++
> > > pyanaconda/ui/gui/spokes/__init__.py | 9 +++
> > > widgets/configure.ac | 2 +-
> > > widgets/glade/AnacondaWidgets.xml | 9 ++-
> > > widgets/src/BaseWindow.c | 48 ++++++++++++
> > > widgets/src/BaseWindow.h | 3 +
> > > widgets/src/Makefile.am | 2 +-
> > > 14 files changed, 254 insertions(+), 4 deletions(-)
> > > create mode 100644 data/help/FedoraPlaceholder.html
> > > create mode 100644 data/help/FedoraPlaceholderWithLinks.html
> > > create mode 100644 data/help/Makefile.am
> > > create mode 100644 pyanaconda/ihelp.py
> > >
> > > diff --git a/anaconda.spec.in b/anaconda.spec.in
> > > index d897888..ffb6785 100644
> > > --- a/anaconda.spec.in
> > > +++ b/anaconda.spec.in
> > > @@ -174,6 +174,7 @@ Requires: zenity
> > > %endif
> > > Requires: keybinder3
> > > Requires: NetworkManager-wifi
> > > +Requires: yelp
> > >
> > > %description gui
> > > This package contains graphical user interface for the Anaconda installer.
> > > diff --git a/data/help/FedoraPlaceholder.html
> > > b/data/help/FedoraPlaceholder.html
> > > new file mode 100644
> > > index 0000000..4d1781a
> > > --- /dev/null
> > > +++ b/data/help/FedoraPlaceholder.html
> > > @@ -0,0 +1,5 @@
> > > +<body>
> > > +<h1>The Anaconda built-in help</h1>
> > > +<p>...is not yet available for this screen.</p>
> > > +<p>You can check the Anaconda wiki page, the Fedora Installation Guide or
> > > other online help resources instead.</p>
> > > +</body>
> > > diff --git a/data/help/FedoraPlaceholderWithLinks.html
> > > b/data/help/FedoraPlaceholderWithLinks.html
> > > new file mode 100644
> > > index 0000000..5fe0485
> > > --- /dev/null
> > > +++ b/data/help/FedoraPlaceholderWithLinks.html
> > > @@ -0,0 +1,13 @@
> > > +<body>
> > > +<h1>The Anaconda built-in help</h1>
> > > +<p>...is not yet available for this screen.</p>
> > > +<p>You can check the Anaconda wiki page, the Fedora Installation Guide or
> > > other online help resources instead:</p>
> > > +<p>
> > > +<ul>
> > > + <li><a
> > > href="http://docs.fedoraproject.org/en-US/Fedora/20/html/Installation_Guide/">Fedora
> > > Installation Guide</a></li>
> > > + <li><a href="https://fedoraproject.org/wiki/Anaconda">Anaconda
> > > Wiki</a></li>
> > > + <li><a
> > > href="http://fedoraproject.org/wiki/Anaconda_Boot_Options">Anaconda Boot
> > > Options</a></li>
> > > + <li><a
> > > href="http://fedoraproject.org/wiki/Anaconda/Kickstart">Anaconda
> > > Kickstart</a></li>
> > > +</ul>
> > > +</p>
> > > +</body>
> > > diff --git a/data/help/Makefile.am b/data/help/Makefile.am
> > > new file mode 100644
> > > index 0000000..8ecdd18
> > > --- /dev/null
> > > +++ b/data/help/Makefile.am
> > > @@ -0,0 +1,22 @@
> > > +# data/Makefile.am for anaconda
> > > +#
> > > +# Copyright (C) 2014 Red Hat, Inc.
> > > +#
> > > +# This program is free software; you can redistribute it and/or modify
> > > +# it under the terms of the GNU Lesser General Public License as published
> > > +# by the Free Software Foundation; either version 2.1 of the License, or
> > > +# (at your option) any later version.
> > > +#
> > > +# This program is distributed in the hope that it will be useful,
> > > +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> > > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> > > +# GNU Lesser General Public License for more details.
> > > +#
> > > +# You should have received a copy of the GNU Lesser General Public License
> > > +# along with this program. If not, see <http://www.gnu.org/licenses/>.
> > > +#
> > > +# Author: Martin Kolman <mkolman at redhat.com>
> > > +
> > > +dist_doc_DATA = HelpPlaceholder.html HelpPlaceholderWithLinks.html
> > > +
> > > +MAINTAINERCLEANFILES = Makefile.in
> > > diff --git a/pyanaconda/ihelp.py b/pyanaconda/ihelp.py
> > > new file mode 100644
> > > index 0000000..4c8dbad
> > > --- /dev/null
> > > +++ b/pyanaconda/ihelp.py
> > > @@ -0,0 +1,123 @@
> > > +#
> > > +# 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.
> > > +#
> > > +# Red Hat Author(s): Martin Kolman <mkolman at redhat.com>
> > > +#
> > > +"""
> > > +Anaconda built-in help module
> > > +"""
> > > +import os
> > > +import subprocess
> > > +
> > > +from pyanaconda.flags import flags
> > > +from pyanaconda.localization import find_best_locale_match
> > > +from pyanaconda.constants import DEFAULT_LANG
> > > +
> > > +import logging
> > > +log = logging.getLogger("anaconda")
> > > +
> > > +yelp_process = None
> > > +
> > > +def _get_best_lang_code(instclass):
> > > + """Return the best language code for the current language and
> > > available
> > > + help content
> > > +
> > > + :param instclass: current install class instance
> > > + :return: best language code for help content or None is no match is
> > > found
> > > + :rtype: str or None
> > > +
> > > + """
> > > + help_langs = []
> > > + # list all available languages for the Anaconda help,
> > > + # content is stored in folders named after the given
> > > + # language code (en-US, cs-CZ, jp-JP, etc.)
> > > + for item in os.listdir(instclass.help_folder):
> > > + if os.path.isdir(os.path.join(instclass.help_folder, item)):
> > > + help_langs.append(item)
> >
> > I'm not sure if there's much point in checking if the matches are
> > directories.
> > If they are empty directories or missing a few files...what then?
> > You still need a fallback.
> >
> > I would probably turn the above into a list comprehension, maybe:
> >
> > help_langs = (item for item in os.listdir(instclass.help_folder))
> >
> > and have this function take another parameter, help_file, and instead of
> > finding the best
> > language code, find the best help file for the locale, i.e., move some
> > of the functionality of get_help_path into this function. It can always
> > exit early if help_file is None.
> >
> > The advantage isn't all that large but this would mean that if a help_file
> > is not provided in the best locale match directory, the code could still
> > fall back on the help file in the default locale directory.
> >
> > > + best_lang = find_best_locale_match(os.environ["LANG"], help_langs)
> > > + if not best_lang:
> > > + # nothing found, try the default language
> > > + best_lang = find_best_locale_match(DEFAULT_LANG, help_langs)
> > > + return best_lang
> > > +
> > > +def get_help_path(help_file, instclass):
> > > + """Return the full path for the given help file name,
> > > + if the help file path does not exist a fallback path is returned.
> > > + There are actually two possible fallback paths that might be returned:
> > > + * first we try to return path to the main page of the installation
> > > guide
> > > + (if it exists)
> > > + * if we can't find the main page of the installation page, path to a
> > > + "no help found" placeholder bundled with Anaconda is returned
> > > +
> > > + :param str help_file: help file name
> >
> > Since help_file may be None, that should be documented here. Something like:
> >
> > :type help_file: str or NoneType
> >
> > > + :param instclass: current install class instance
> > > + :return str: full path to the help file requested or to a placeholder
> > > + """
> > > + # help l10n handling
> > > + lang_code = _get_best_lang_code(instclass)
> > > +
> > > + # no lang code means we don't have any help content,
> > > + # not even untranslated in the default language (English)
> > > + if lang_code:
> > > + # check if the screen has any helpFile defined
> > > + if help_file:
> > > + # check if the help file exists
> > > + help_path = os.path.join(instclass.help_folder, lang_code,
> > > help_file)
> > > + if os.path.isfile(help_path):
> > > + return help_path
> > > + else:
> > > + log.debug("the %s help file has been requested, but is not
> > > available", help_file)
> > > +
> > > + # the screen did not have a helpFile defined or the defined help
> > > file
> > > + # does not exist, so next try to check if we can find the main
> > > page
> > > + # of the installation guide and use it instead
> > > + help_path = os.path.join(instclass.help_folder, lang_code,
> > > instclass.help_main_page)
> > > + if os.path.exists(help_path):
> > > + return help_path
> > > + else:
> > > + log.warning("no help content found, using a placeholder")
> > > +
> > > + # looks like the installation guide is not available, so just return
> > > + # a placeholder page that should always be available
> > > + if flags.livecdInstall:
> > > + return os.path.join(instclass.help_folder,
> > > instclass.help_placeholder_with_links)
> > > + else:
> > > + return os.path.join(instclass.help_folder,
> > > instclass.help_placeholder)
> > > +
> > > +def start_yelp(help_path):
> > > + """Start a new yelp process and make sure to kill any existing ones
> > > +
> > > + :param str help_path: path to the help file yelp should load
> > > + """
> > > +
> > > + kill_yelp()
> > > + log.debug("starting yelp")
> > > + global yelp_process
> > > + yelp_process = subprocess.Popen(["yelp", help_path])
> > > +
> > > +def kill_yelp():
> > > + """Try to kill any existing yelp processes"""
> > > +
> > > + global yelp_process
> > > + if not yelp_process:
> > > + return False
> > > +
> > > + log.debug("killing yelp")
> > > + yelp_process.kill()
> > > + yelp_process = None
> > > + return True
> > > +
> > > diff --git a/pyanaconda/installclass.py b/pyanaconda/installclass.py
> > > index 4fd8865..e17f33d 100644
> > > --- a/pyanaconda/installclass.py
> > > +++ b/pyanaconda/installclass.py
> > > @@ -61,6 +61,12 @@ class BaseInstallClass(object):
> > > # don't select this class by default
> > > default = 0
> > >
> > > + # help
> > > + help_folder = "/usr/share/doc/anaconda"
> > > + help_main_page = "Installation_Guide.xml"
> > > + help_placeholder = None
> > > + help_placeholder_with_links = None
> > > +
> > > @property
> > > def l10n_domain(self):
> > > if self._l10n_domain is None:
> > > diff --git a/pyanaconda/installclasses/fedora.py
> > > b/pyanaconda/installclasses/fedora.py
> > > index 1fe192b..ec110aa 100644
> > > --- a/pyanaconda/installclasses/fedora.py
> > > +++ b/pyanaconda/installclasses/fedora.py
> > > @@ -37,6 +37,9 @@ class InstallClass(BaseInstallClass):
> > >
> > > efi_dir = "fedora"
> > >
> > > + help_placeholder = "FedoraPlaceholder.html"
> > > + help_placeholder_with_links = "FedoraPlaceholderWithLinks.html"
> > > +
> > > def configure(self, anaconda):
> > > BaseInstallClass.configure(self, anaconda)
> > > BaseInstallClass.setDefaultPartitioning(self, anaconda.storage)
> >
> > Should probably do the correct thing for pyanaconda/installclasses/rhel7.py
> > while you're doing this one.
> >
> > > diff --git a/pyanaconda/ui/gui/__init__.py b/pyanaconda/ui/gui/__init__.py
> > > index 117879b..dca0280 100644
> > > --- a/pyanaconda/ui/gui/__init__.py
> > > +++ b/pyanaconda/ui/gui/__init__.py
> > > @@ -31,6 +31,7 @@ from pyanaconda import product, iutil
> > >
> > > from pyanaconda.ui import UserInterface, common
> > > from pyanaconda.ui.gui.utils import gtk_action_wait, busyCursor,
> > > unbusyCursor
> > > +from pyanaconda import ihelp
> > > import os.path
> > >
> > > import logging
> > > @@ -81,6 +82,10 @@ 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
> > > @@ -91,6 +96,7 @@ class GUIObject(common.UIObject):
> > > focusWidgetName = None
> > >
> > > uiFile = ""
> > > + helpFile = ""
> > > translationDomain = "anaconda"
> > >
> > > screenshots_directory = "/tmp/anaconda-screenshots"
> > > @@ -536,6 +542,7 @@ class GraphicalUserInterface(UserInterface):
> > >
> > > # 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)
> > >
> >
> > I'm not sure whether any of these should really be connect_after...the
> > comment
> > does not really help me much.
> >
> > > return obj
> > > @@ -697,6 +704,11 @@ class GraphicalUserInterface(UserInterface):
> > > 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
> > > + ihelp.start_yelp(ihelp.get_help_path(obj.helpFile,
> > > self.instclass))
> > > +
> > > 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 183dc6f..1227d44 100644
> > > --- a/pyanaconda/ui/gui/spokes/__init__.py
> > > +++ b/pyanaconda/ui/gui/spokes/__init__.py
> > > @@ -21,6 +21,7 @@
> > >
> > > from pyanaconda.ui import common
> > > from pyanaconda.ui.gui import GUIObject
> > > +from pyanaconda import ihelp
> > >
> > > __all__ = ["StandaloneSpoke", "NormalSpoke"]
> > >
> > > @@ -44,6 +45,14 @@ class NormalSpoke(GUIObject, common.NormalSpoke):
> > > GUIObject.__init__(self, data)
> > > common.NormalSpoke.__init__(self, storage, payload, instclass)
> > >
> > > + # Add a help handler
> > > + self.window.connect_after("help-button-clicked",
> > > self._on_help_clicked)
> >
> > Should this really be connect_after instead of connect?
> >
> > > +
> > > + def _on_help_clicked(self, window):
> > > + # the help button has been clicked, start the yelp viewer with
> > > + # content for the current spoke
> > > + ihelp.start_yelp(ihelp.get_help_path(self.helpFile,
> > > self.instclass))
> > > +
> > > def on_back_clicked(self, window):
> > > # Notify the hub that we're finished.
> > > # The hub will be the current-action of the main window.
> > > diff --git a/widgets/configure.ac b/widgets/configure.ac
> > > index 1035c6c..6456db9 100644
> > > --- a/widgets/configure.ac
> > > +++ b/widgets/configure.ac
> > > @@ -20,7 +20,7 @@
> > > #
> > >
> > > AC_PREREQ([2.63])
> > > -AC_INIT([AnacondaWidgets], [3.0], [clumens at redhat.com])
> > > +AC_INIT([AnacondaWidgets], [3.1], [clumens at redhat.com])
> > > AM_INIT_AUTOMAKE([foreign])
> > > AM_SILENT_RULES([yes])
> > >
> > > diff --git a/widgets/glade/AnacondaWidgets.xml
> > > b/widgets/glade/AnacondaWidgets.xml
> > > index 42c4194..044ceb2 100644
> > > --- a/widgets/glade/AnacondaWidgets.xml
> > > +++ b/widgets/glade/AnacondaWidgets.xml
> > > @@ -1,6 +1,6 @@
> > > <glade-catalog name="AnacondaWidgets"
> > > - version="3.0"
> > > - targetable="2.0,1.0"
> > > + version="3.1"
> > > + targetable="3.0,2.0,1.0"
> > > library="AnacondaWidgets"
> > > domain="glade-3"
> > > depends="gtk+">
> > > @@ -25,6 +25,11 @@
> > > <property id="distribution" translatable="True" />
> > > <property id="window-name" translatable="True" />
> > > </properties>
> > > +
> > > + <signals>
> > > + <signal since="3.1" id="help-button-clicked" />
> > > + </signals>
> > > +
> > > </glade-widget-class>
> > >
> > > <glade-widget-class title="Standalone Spoke Window"
> > > diff --git a/widgets/src/BaseWindow.c b/widgets/src/BaseWindow.c
> > > index 5b7f337..94dee1f 100644
> > > --- a/widgets/src/BaseWindow.c
> > > +++ b/widgets/src/BaseWindow.c
> > > @@ -28,6 +28,8 @@
> > > #include "BaseWindow.h"
> > > #include "intl.h"
> > >
> > > + #include <atk/atk.h>
> > > +
> > > /**
> > > * SECTION: BaseWindow
> > > * @title: AnacondaBaseWindow
> > > @@ -95,6 +97,7 @@
> > >
> > > enum {
> > > SIGNAL_INFO_BAR_CLICKED,
> > > + SIGNAL_HELP_BUTTON_CLICKED,
> > > LAST_SIGNAL
> > > };
> > >
> > > @@ -109,6 +112,7 @@ enum {
> > > #define DEFAULT_WINDOW_NAME N_("SPOKE NAME")
> > > #define DEFAULT_BETA N_("PRE-RELEASE / TESTING")
> > > #define LAYOUT_INDICATOR_LABEL_WIDTH 10
> > > +#define HELP_BUTTON_LABEL _("_Help!")
> > >
> > > struct _AnacondaBaseWindowPrivate {
> > > gboolean is_beta, info_shown;
> > > @@ -117,6 +121,7 @@ struct _AnacondaBaseWindowPrivate {
> > > GtkWidget *nav_box, *nav_area, *action_area;
> > > GtkWidget *name_label, *distro_label, *beta_label;
> > > GtkWidget *layout_indicator;
> > > + GtkWidget *help_button;
> > >
> > > /* Untranslated versions of various things. */
> > > gchar *orig_name, *orig_distro, *orig_beta;
> > > @@ -128,6 +133,7 @@ static void
> > > anaconda_base_window_buildable_init(GtkBuildableIface *iface);
> > > static void format_beta_label(AnacondaBaseWindow *window, const char
> > > *markup);
> > >
> > > static gboolean anaconda_base_window_info_bar_clicked(GtkWidget *widget,
> > > GdkEvent *event, AnacondaBaseWindow *win);
> > > +static void anaconda_base_window_help_button_clicked(GtkButton *button,
> > > AnacondaBaseWindow *win);
> > >
> > > G_DEFINE_TYPE_WITH_CODE(AnacondaBaseWindow, anaconda_base_window,
> > > GTK_TYPE_BIN,
> > > G_IMPLEMENT_INTERFACE(GTK_TYPE_BUILDABLE,
> > > anaconda_base_window_buildable_init))
> > > @@ -173,6 +179,7 @@ static void
> > > anaconda_base_window_class_init(AnacondaBaseWindowClass *klass) {
> > > G_PARAM_READWRITE));
> > >
> > > klass->info_bar_clicked = NULL;
> > > + klass->help_button_clicked = NULL;
> > >
> > > /**
> > > * AnacondaBaseWindow::info-bar-clicked:
> > > @@ -192,6 +199,24 @@ 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: 4.0
> > > + */
> > > + 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));
> > > }
> > >
> > > @@ -210,6 +235,7 @@ GtkWidget *anaconda_base_window_new() {
> > >
> > > static void anaconda_base_window_init(AnacondaBaseWindow *win) {
> > > char *markup;
> > > + AtkObject *atk;
> > >
> > > win->priv = G_TYPE_INSTANCE_GET_PRIVATE(win,
> > > ANACONDA_TYPE_BASE_WINDOW,
> > > @@ -325,11 +351,28 @@ 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_mnemonic(HELP_BUTTON_LABEL);
> > > + gtk_widget_set_halign(win->priv->help_button, GTK_ALIGN_START);
> > > + 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);
> > > +
> > > + 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, 1, 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);
> > > }
> > >
> > > static void anaconda_base_window_get_property(GObject *object, guint
> > > prop_id, GValue *value, GParamSpec *pspec) {
> > > @@ -587,6 +630,11 @@ 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
> > > diff --git a/widgets/src/BaseWindow.h b/widgets/src/BaseWindow.h
> > > index eb6191d..19891c1 100644
> > > --- a/widgets/src/BaseWindow.h
> > > +++ b/widgets/src/BaseWindow.h
> > > @@ -56,11 +56,14 @@ 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
> > > #AnacondaSpokeWindow::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);
> > > diff --git a/widgets/src/Makefile.am b/widgets/src/Makefile.am
> > > index dfed620..42615c2 100644
> > > --- a/widgets/src/Makefile.am
> > > +++ b/widgets/src/Makefile.am
> > > @@ -65,7 +65,7 @@ libAnacondaWidgets_la_CFLAGS = $(GTK_CFLAGS)
> > > $(GLADEUI_CFLAGS) $(LIBXKLAVIER_CFL
> > > -DWIDGETS_DATADIR=$(WIDGETSDATA)\
> > > -DTZMAP_DATADIR=$(TZMAPDATA)
> > > libAnacondaWidgets_la_LIBADD = $(GTK_LIBS) $(GLADEUI_LIBS)
> > > $(LIBXKLAVIER_LIBS)
> > > -libAnacondaWidgets_la_LDFLAGS = $(LTLIBINTL) -version-info 2:0:0
> > > +libAnacondaWidgets_la_LDFLAGS = $(LTLIBINTL) -version-info 3:0:1
> > > libAnacondaWidgets_la_SOURCES = $(SOURCES) $(HDRS) \
> > > glade-adaptor.c
> > >
> > > --
> > > 1.9.3
> > >
> > > _______________________________________________
> > > anaconda-patches mailing list
> > > anaconda-patches at lists.fedorahosted.org
> > > https://lists.fedorahosted.org/mailman/listinfo/anaconda-patches
> > >
> >
> > Just a few inline comments.
> >
> > - mulhern
> > _______________________________________________
> > anaconda-patches mailing list
> > anaconda-patches at lists.fedorahosted.org
> > https://lists.fedorahosted.org/mailman/listinfo/anaconda-patches
> >
>
> Actually,
>
> I think that, ideally, we would store all this data in an sqlite
> database, rather than in separate files in separate directories.
> We would do the same for the CLI help text, now that it
> has gotten so mature, and we would be able to use _exactly_ the
> same database schema for both, since, at least in theory, CLI
> help text should be available in any language.
>
> However, we would have to handle version control of the structure
> of the database and also its contents.
>
> It might be that adding an sqlite dependency to anaconda
> is not so attractive to some.
>
> Also, I don't know how translation is expected to work with the
> contents of databases.
>
> So maybe this idea is a bit too ambitious. But now is as good
> a time to think about it as any.
I don't think we need such a big-hammer approach. Using directories for
translations is really common and not so hard.
--
Vratislav Podzimek
Anaconda Rider | RHCE | Red Hat, Inc. | Brno - Czech Republic
More information about the anaconda-patches
mailing list