[master/rhel7-branch] Keyboard configuration patches
by Vratislav Podzimek
Two patches fixing some real and potential issues in our keyboard configuration
code. None of the patches resolves the bug #1024774 as it was caused by a
wrong configuration of the machine together with a weird behaviour of systemd in
that case, but they are closely related to that issue.
Vratislav Podzimek (2):
Implement and use functions for conversion between keymaps and layouts
Be more defensive when getting layouts and their variants
pyanaconda/keyboard.py | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 47 insertions(+), 2 deletions(-)
--
1.8.4.2
10 years, 4 months
[rhel7-branch][PATCH] Make layout and switching options description translated (#1015209)
by Vratislav Podzimek
We have the translations of layout and switching options available we just need
to use them in the GUI.
(ported and squashed commits from the master branch)
Signed-off-by: Vratislav Podzimek <vpodzime(a)redhat.com>
---
pyanaconda/iutil.py | 21 +++++
pyanaconda/keyboard.py | 160 ++++++++++++-----------------------
pyanaconda/localization.py | 27 +-----
pyanaconda/ui/gui/spokes/keyboard.py | 18 ++--
4 files changed, 87 insertions(+), 139 deletions(-)
diff --git a/pyanaconda/iutil.py b/pyanaconda/iutil.py
index 7e6496f..fcacb94 100644
--- a/pyanaconda/iutil.py
+++ b/pyanaconda/iutil.py
@@ -722,3 +722,24 @@ def is_unsupported_hw():
if status:
log.debug("Installing on Unsupported Hardware")
return status
+
+def upcase_first_letter(text):
+ """
+ Helper function that upcases the first letter of the string. Python's
+ standard string.capitalize() not only upcases the first letter but also
+ lowercases all the others. string.title() capitalizes all words in the
+ string.
+
+ :type text: either a str or unicode object
+ :return: the given text with the first letter upcased
+ :rtype: str or unicode (depends on the input)
+
+ """
+
+ if not text:
+ # cannot change anything
+ return text
+ elif len(text) == 1:
+ return text.upper()
+ else:
+ return text[0].upper() + text[1:]
diff --git a/pyanaconda/keyboard.py b/pyanaconda/keyboard.py
index c8e1924..46c1a4d 100755
--- a/pyanaconda/keyboard.py
+++ b/pyanaconda/keyboard.py
@@ -36,6 +36,10 @@ import types
import os
import re
import shutil
+import ctypes
+import gettext
+
+from collections import namedtuple
from pyanaconda import iutil
from pyanaconda import flags
@@ -59,6 +63,12 @@ LAYOUT_VARIANT_RE = re.compile(r'^\s*(\w+)\s*' # layout plus
r'(?:(?:\(\s*([-\w]+)\s*\))' # variant in parentheses
r'|(?:$))\s*') # or nothing
+# namedtuple for information about a keyboard layout (its language and description)
+LayoutInfo = namedtuple("LayoutInfo", ["lang", "desc"])
+
+Xkb_ = lambda x: gettext.ldgettext("xkeyboard-config", x)
+iso_ = lambda x: gettext.ldgettext("iso_639", x)
+
class KeyboardConfigError(Exception):
"""Exception class for keyboard configuration related problems"""
@@ -351,28 +361,10 @@ def item_str(s):
elif type(s) == types.ListType:
# XXX: this is the wrong case that should be fixed (rhbz#920595)
i = s.index(0)
- s = "".join(chr(char) for char in s[:i] if char in xrange(256))
+ s = "".join(chr(ctypes.c_uint8(char).value) for char in s[:i])
return s.decode("utf-8") #there are some non-ascii layout descriptions
-class _Layout(object):
- """Internal class representing a single layout variant"""
-
- def __init__(self, name, desc):
- self.name = name
- self.desc = desc
-
- def __str__(self):
- return '%s (%s)' % (self.name, self.desc)
-
- def __eq__(self, obj):
- return isinstance(obj, self.__class__) and \
- self.name == obj.name
-
- @property
- def description(self):
- return self.desc
-
class XklWrapperError(KeyboardConfigError):
"""Exception class for reporting libxklavier-related problems"""
@@ -436,16 +428,8 @@ class XklWrapper(object):
self.configreg = Xkl.ConfigRegistry.get_instance(self._engine)
self.configreg.load(False)
- self._language_keyboard_variants = dict()
- self._country_keyboard_variants = dict()
- self._switching_options = list()
-
- #we want to display layouts as 'language (description)'
- self.name_to_show_str = dict()
-
- #we want to display layout switching options as e.g. "Alt + Shift" not
- #as "grp:alt_shift_toggle"
- self.switch_to_show_str = dict()
+ self._layout_infos = dict()
+ self._switch_opt_infos = dict()
#this might take quite a long time
self.configreg.foreach_language(self._get_language_variants, None)
@@ -464,14 +448,9 @@ class XklWrapper(object):
#if this layout has already been added for some other language,
#do not add it again (would result in duplicates in our lists)
- if name not in self.name_to_show_str:
- if lang and not description.startswith(lang):
- self.name_to_show_str[name] = "%s (%s)" % (lang.encode("utf-8"),
- description.encode("utf-8"))
- else:
- self.name_to_show_str[name] = "%s" % description.encode("utf-8")
-
- self._variants_list.append(_Layout(name, description))
+ if name not in self._layout_infos:
+ self._layout_infos[name] = LayoutInfo(lang.encode("utf-8"),
+ description.encode("utf-8"))
def _get_country_variant(self, c_reg, item, subitem, country):
if subitem:
@@ -482,109 +461,76 @@ class XklWrapper(object):
description = item_str(item.description)
# if the layout was not added with any language, add it with a country
- if name not in self.name_to_show_str:
- if country:
- self.name_to_show_str[name] = "%s (%s)" % (country.encode("utf-8"),
- description.encode("utf-8"))
- else:
- self.name_to_show_str[name] = "%s" % description.encode("utf-8")
-
- self._variants_list.append(_Layout(name, description))
+ if name not in self._layout_infos:
+ self._layout_infos[name] = LayoutInfo(country.encode("utf-8"),
+ description.encode("utf-8"))
def _get_language_variants(self, c_reg, item, user_data=None):
- #helper "global" variable
- self._variants_list = list()
lang_name, lang_desc = item_str(item.name), item_str(item.description)
c_reg.foreach_language_variant(lang_name, self._get_lang_variant, lang_desc)
- self._language_keyboard_variants[lang_desc] = self._variants_list
-
def _get_country_variants(self, c_reg, item, user_data=None):
- #helper "global" variable
- self._variants_list = list()
country_name, country_desc = item_str(item.name), item_str(item.description)
c_reg.foreach_country_variant(country_name, self._get_country_variant,
country_desc)
- self._country_keyboard_variants[country_name] = self._variants_list
-
def _get_switch_option(self, c_reg, item, user_data=None):
"""Helper function storing layout switching options in foreach cycle"""
desc = item_str(item.description)
name = item_str(item.name)
- self._switching_options.append(name)
- self.switch_to_show_str[name] = desc.encode("utf-8")
+ self._switch_opt_infos[name] = desc.encode("utf-8")
+
def get_available_layouts(self):
"""A generator yielding layouts (no need to store them as a bunch)"""
- return self.name_to_show_str.iterkeys()
+ return self._layout_infos.iterkeys()
def get_switching_options(self):
"""Method returning list of available layout switching options"""
- return self._switching_options
-
- def get_default_language_layout(self, language):
- """Get the default layout for a given language."""
-
- layouts = self.get_language_layouts(language)
- if layouts:
- #first layout (should exist for every language)
- return layouts[0].name
- else:
- return None
-
- def get_language_layouts(self, language):
- """Get layouts for a given language."""
-
- language_layouts = self._language_keyboard_variants.get(language, None)
-
- if language_layouts:
- return language_layouts
+ return self._switch_opt_infos.iterkeys()
- #else try some magic and if everything fails, return None
- for (lang, layouts) in self._language_keyboard_variants.iteritems():
- #XXX: some languages are returned in a weird form from the
- # libxklavier iterations (e.g. "Greek, Modern (1453-)")
- if lang.startswith(language):
- return layouts
-
- return None
-
- def get_default_lang_country_layout(self, language, country):
+ def get_layout_variant_description(self, layout_variant, with_lang=True):
"""
- Get default layout matching both language and country. If none such
- layout is found, get default layout for language. If no layout for
- the given language is found but there is layout for the given country,
- return the one for the country.
+ Get description of the given layout-variant.
+
+ :param layout_variant: layout-variant specification (e.g. 'cz (qwerty)')
+ :type layout_variant: str
+ :param with_lang: whether to include language of the layout-variant (if defined)
+ in the description or not
+ :type with_lang: bool
+ :return: description of the layout-variant specification (e.g. 'Czech (qwerty)')
+ :rtype: str
"""
- language_layouts = self.get_language_layouts(language)
- country_layouts = self._country_keyboard_variants.get(country, None)
- if not language_layouts and not country_layouts:
- return None
+ layout_info = self._layout_infos[layout_variant]
+ if with_lang and layout_info.lang:
+ # translate language and upcase its first letter, translate the
+ # layout-variant description
+ xlated_lang = iso_(layout_info.lang)
+ return "%s (%s)" % (iutil.upcase_first_letter(xlated_lang.decode("utf-8")),
+ Xkb_(layout_info.desc).decode("utf-8"))
+ else:
+ return layout_info.desc
- if not country_layouts:
- return language_layouts[0].name
+ def get_switch_opt_description(self, switch_opt):
+ """
+ Get description of the given layout switching option.
- if not language_layouts:
- return country_layouts[0].name
+ :param switch_opt: switching option name/ID (e.g. 'grp:alt_shift_toggle')
+ :type switch_opt: str
+ :return: description of the layout switching option (e.g. 'Alt + Shift')
+ :rtype: str
- matches_both = (layout for layout in language_layouts
- if layout in country_layouts)
+ """
- try:
- return matches_both.next().name
- except StopIteration:
- if country_layouts:
- return country_layouts[0].name
- else:
- return language_layouts[0].name
+ # translate the description of the switching option
+ return Xkb_(self._switch_opt_infos[switch_opt])
def activate_default_layout(self):
"""
@@ -598,7 +544,7 @@ class XklWrapper(object):
def is_valid_layout(self, layout):
"""Return if given layout is valid layout or not"""
- return layout in self.name_to_show_str
+ return layout in self._layout_infos
def add_layout(self, layout):
"""
diff --git a/pyanaconda/localization.py b/pyanaconda/localization.py
index 191e1a9..b13e047 100644
--- a/pyanaconda/localization.py
+++ b/pyanaconda/localization.py
@@ -26,6 +26,8 @@ import re
import langtable
import glob
+from pyanaconda.iutil import upcase_first_letter
+
import logging
log = logging.getLogger("anaconda")
@@ -47,27 +49,6 @@ class InvalidLocaleSpec(LocalizationConfigError):
pass
-def _upcase_first_letter(string):
- """
- Helper function that upcases the first letter of the string. Python's
- standard string.capitalize() not only upcases the first letter but also
- lowercases all the others. string.title() capitalizes all words in the
- string.
-
- :type string: either a str or unicode object
- :return: the given string with the first letter upcased
- :rtype: str or unicode (depends on the input)
-
- """
-
- if not string:
- # cannot change anything
- return string
- elif len(string) == 1:
- return string.upper()
- else:
- return string[0].upper() + string[1:]
-
def parse_langcode(langcode):
"""
For a given langcode (e.g. 'SR_RS.UTF-8@latin') returns a dictionary
@@ -237,7 +218,7 @@ def get_english_name(locale):
scriptId=parts.get("script", ""),
languageIdQuery="en")
- return _upcase_first_letter(name)
+ return upcase_first_letter(name)
def get_native_name(locale):
"""
@@ -261,7 +242,7 @@ def get_native_name(locale):
languageIdQuery=parts["language"],
scriptIdQuery=parts.get("script", ""))
- return _upcase_first_letter(name)
+ return upcase_first_letter(name)
def get_available_translations(localedir=None):
"""
diff --git a/pyanaconda/ui/gui/spokes/keyboard.py b/pyanaconda/ui/gui/spokes/keyboard.py
index 7ba4cdf..3b76a50 100644
--- a/pyanaconda/ui/gui/spokes/keyboard.py
+++ b/pyanaconda/ui/gui/spokes/keyboard.py
@@ -40,11 +40,11 @@ __all__ = ["KeyboardSpoke"]
LAYOUT_SWITCHING_INFO = N_("%s to switch layouts.")
def _show_layout(column, renderer, model, itr, wrapper):
- value = wrapper.name_to_show_str[model[itr][0]]
+ value = wrapper.get_layout_variant_description(model[itr][0])
renderer.set_property("text", value)
def _show_description(column, renderer, model, itr, wrapper):
- value = wrapper.switch_to_show_str[model[itr][0]]
+ value = wrapper.get_switch_opt_description(model[itr][0])
if model[itr][1]:
value = "<b>%s</b>" % value
renderer.set_property("markup", value)
@@ -61,7 +61,7 @@ class AddLayoutDialog(GUIObject):
def matches_entry(self, model, itr, user_data=None):
value = model[itr][0]
- value = self._xkl_wrapper.name_to_show_str[value]
+ value = self._xkl_wrapper.get_layout_variant_description(value)
entry_text = self._entry.get_text()
if entry_text is not None:
entry_text = entry_text.lower()
@@ -87,8 +87,8 @@ class AddLayoutDialog(GUIObject):
value1 = model[itr1][0]
value2 = model[itr2][0]
- show_str1 = self._xkl_wrapper.name_to_show_str[value1]
- show_str2 = self._xkl_wrapper.name_to_show_str[value2]
+ show_str1 = self._xkl_wrapper.get_layout_variant_description(value1)
+ show_str2 = self._xkl_wrapper.get_layout_variant_description(value2)
if show_str1 < show_str2:
return -1
@@ -223,8 +223,8 @@ class ConfigureSwitchingDialog(GUIObject):
value1 = model[itr1][0]
value2 = model[itr2][0]
- show_str1 = self._xkl_wrapper.switch_to_show_str[value1]
- show_str2 = self._xkl_wrapper.switch_to_show_str[value2]
+ show_str1 = self._xkl_wrapper.get_switch_opt_description(value1)
+ show_str2 = self._xkl_wrapper.get_switch_opt_description(value2)
if show_str1 < show_str2:
return -1
@@ -285,7 +285,7 @@ class KeyboardSpoke(NormalSpoke):
@property
def status(self):
# We don't need to check that self._store is empty, because that isn't allowed.
- descriptions = (self._xkl_wrapper.name_to_show_str[row[0]]
+ descriptions = (self._xkl_wrapper.get_layout_variant_description(row[0])
for row in self._store)
return ", ".join(descriptions)
@@ -374,7 +374,7 @@ class KeyboardSpoke(NormalSpoke):
def _refresh_switching_info(self):
if self.data.keyboard.switch_options:
first_option = self.data.keyboard.switch_options[0]
- desc = self._xkl_wrapper.switch_to_show_str[first_option]
+ desc = self._xkl_wrapper.get_switch_opt_description(first_option)
self._layoutSwitchLabel.set_text(_(LAYOUT_SWITCHING_INFO) % desc)
else:
--
1.8.4.2
10 years, 4 months
[master] Test that pango markup is correct and used correctly
by David Shea
This is mostly an excuse to check the validity of the translations of pango
markup, since some of those strings have some problems.
Two tests, since strings come from two sources: for the strings in python,
there's a pylint module, and for the strings in glade there a new script. Both
tests check that the markup is parseable and matches what pango says we can use
and (if requested) that translated strings contain the same elements and
attributes as the original string. The pylint module additionally checks that
when markup is used as the left side of a format operation (e.g.,
"<b>markup</b> string" % params), that the parameters are all escaped. This
might raise some annoying warnings since it only works if the escape happens in
that expression and not five lines up or whatever, but we don't use markup like
that much anyway, so it shouldn't be so bad.
10 years, 4 months
[master/proposed rhel7-branch] Make the clear icon functional in language spoke.
by Samantha N. Bueno
This was not actually working.
(Also, this should probably go into rhel7-branch.)
---
pyanaconda/ui/gui/spokes/langsupport.glade | 1 +
1 file changed, 1 insertion(+)
diff --git a/pyanaconda/ui/gui/spokes/langsupport.glade b/pyanaconda/ui/gui/spokes/langsupport.glade
index f0dabf6..5c3470f 100644
--- a/pyanaconda/ui/gui/spokes/langsupport.glade
+++ b/pyanaconda/ui/gui/spokes/langsupport.glade
@@ -173,6 +173,7 @@
<property name="secondary_icon_name">edit-clear-symbolic</property>
<property name="placeholder_text">Type here to search.</property>
<signal name="changed" handler="on_entry_changed" swapped="no"/>
+ <signal name="icon-press" handler="on_clear_icon_clicked" swapped="no"/>
</object>
<packing>
<property name="left_attach">0</property>
--
1.8.3.1
10 years, 4 months
[rhel7-branch][PATCH] Fix minimal install usage with incomplete kickstart (#1032066)
by Martin Kolman
Make sure the user can select minimal install when installing
with an incomplete kickstart that does not specify packages.
For such incomplete kickstarts, we require the user to enter
the software spoke and confirm a software environment.
The users must be able to select any of the environments,
including "minimal install", which is selected by default.
Signed-off-by: Martin Kolman <mkolman(a)redhat.com>
---
pyanaconda/ui/gui/spokes/software.py | 34 ++++++++++++++++++++++++++++++++++
1 file changed, 34 insertions(+)
diff --git a/pyanaconda/ui/gui/spokes/software.py b/pyanaconda/ui/gui/spokes/software.py
index b7725e0..a9a7496 100644
--- a/pyanaconda/ui/gui/spokes/software.py
+++ b/pyanaconda/ui/gui/spokes/software.py
@@ -55,6 +55,10 @@ class SoftwareSelectionSpoke(NormalSpoke):
self._errorMsgs = None
self._tx_id = None
self._selectFlag = False
+ # track if the spoke was visited at least once
+ self._visited_once = False
+ self._visited_once_done = False
+ self._first_refresh_done = False
self.selectedGroups = []
self.excludedGroups = []
@@ -125,6 +129,27 @@ class SoftwareSelectionSpoke(NormalSpoke):
@property
def changed(self):
+ # we need to regard the first time user enters the spoke as changed=True,
+ # otherwise the user would not be able to select minimal install when
+ # installing with an incomplete kickstart (kickstart without packages)
+ #
+ # this is because:
+ # - if users does not specify packages in kickstart, we require him
+ # to enter the software selection spoke and select/confirm an environment
+ # - minimal install is the default option
+ # - when the user enters the spoke, leaves the default option ticked
+ # and clicks the apply button, changed is False as the selection
+ # was not actually changed
+ # - if changed is False, apply() is not called so the default option
+ # is not used and the spoke remains incomplete
+
+ if self._visited_once and not self._visited_once_done:
+ self._visited_once_done = True
+ return True
+
+ # this special changed behaviour needs to be done only once,
+ # subsequent visits should use the normal rules
+
row = self._get_selected_environment()
if not row:
return True
@@ -230,14 +255,23 @@ class SoftwareSelectionSpoke(NormalSpoke):
def _first_refresh(self):
try:
self.refresh()
+ self._first_refresh_done = True
return True
except MetadataError:
hubQ.send_message(self.__class__.__name__, _("No installation source available"))
+ self._first_refresh_done = True
return False
def refresh(self):
NormalSpoke.refresh(self)
+ # if the refresh method is running, it usually means
+ # that the spoke has been visited by the user
+ if self._first_refresh_done:
+ # skip the first refresh - it is done by _initialize(),
+ # so it is not yet the user looking at the spoke
+ self._visited_once = True
+
threadMgr.wait(constants.THREAD_PAYLOAD_MD)
self._environmentStore = self.builder.get_object("environmentStore")
--
1.8.4.2
10 years, 4 months
[firstboot][PATCH] Translate the error message if not run as root
by Vratislav Podzimek
Related: rhbz#1044339
Signed-off-by: Vratislav Podzimek <vpodzime(a)redhat.com>
---
progs/firstboot | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/progs/firstboot b/progs/firstboot
index 7f85b70..89a4cc2 100755
--- a/progs/firstboot
+++ b/progs/firstboot
@@ -97,7 +97,7 @@ if __name__ == '__main__':
# only root can do this
if not os.geteuid() == 0:
- print >> sys.stderr, 'only root can do this'
+ print >> sys.stderr, _('only root can do this')
sys.exit(1)
parser = optparse.OptionParser()
--
1.8.4.2
10 years, 4 months
[rhel7-branch] Timezones-related patches
by Vratislav Podzimek
These two ports from the master branch make timezones in the RHEL 7 Anaconda GUI
translated and sorted out in a better way.
Vratislav Podzimek (2):
Translate timezones in GUI (#1015209)
Provide our own sorting functions for regions and timezones (#1025029)
anaconda.spec.in | 2 +-
pyanaconda/localization.py | 24 ++++++++
pyanaconda/ui/gui/spokes/datetime_spoke.glade | 15 ++---
pyanaconda/ui/gui/spokes/datetime_spoke.py | 83 +++++++++++++++++++++++----
4 files changed, 105 insertions(+), 19 deletions(-)
--
1.8.4.2
10 years, 4 months
[blivet] Use blivet's Size class for all size quantities (v2)
by David Lehman
This has been a long time coming. It resolves a whole array of issues
related to conversion between various units. Under the covers, using
Size means we are storing sizes as Decimals representing the number of
bytes. It also switches the size module's default from decimal to binary
since binary is what is actually used at the lower levels (sector size,
lvm extent size, md chunk size, &c). Using decimal makes it impossible
for things to have round-numbered sizes unless you intentionally ignore
or discard some precision, both of which have serious consequences.
This patch set also sigificantly reduces our usage of float. The
function blivet.devicelibs.lvm.clampSize was rewritten to not use any
float math.
Changes in v2:
- fixed unit test broken by patch 1
- moved operand ordering changes to RAIDLevel._get_raw_array_size from
patch 1 to patch 6 where it belongs (patches 1 and 6)
- fixed test case for Size.humanReadable to expect binary unit prefixes
(patch 2)
- improved patch to discard partial bytes in Size constructor to work
regardless of whether spec, en_spec, or bytes was given (patch 3)
- added a unit test for discard of partial bytes (patch 3)
- consistent use of en_spec instead of spec (patch 6)
- fixed buf/zero mess in FileDevice._create (patch 6)
- removed last vestiges of floor from getPossiblePhysicalExtents (patch
6)
10 years, 4 months
[PATCH] Save module list after initial module load (#1050352)
by Brian C. Lane
If we save the module list early it will unload essential things like
libata, cdrom, etc. When the modules are reloaded the driver disk
sometimes shows up as a different disk, resulting in a loop and multiple
copies of the driver disk in /run/install/
Resolves: rhbz#1050352
---
dracut/driver-updates | 1 -
dracut/driver-updates.sh | 6 +++---
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/dracut/driver-updates b/dracut/driver-updates
index cdcddc9..65a4ede 100755
--- a/dracut/driver-updates
+++ b/dracut/driver-updates
@@ -267,7 +267,6 @@ def reload_modules():
# Make a list of modules added since startup
startup_modules = get_module_set("/tmp/dd_modules")
- startup_modules.update(["virtio_blk", "virtio_net"])
current_modules = get_module_set("/proc/modules")
new_modules = current_modules.difference(startup_modules)
log.debug("new_modules = %s" % " ".join(new_modules))
diff --git a/dracut/driver-updates.sh b/dracut/driver-updates.sh
index 74615fe..3765575 100755
--- a/dracut/driver-updates.sh
+++ b/dracut/driver-updates.sh
@@ -2,9 +2,6 @@
# Determine if a Driver Update Disk is present, or inst.dd passed on the cmdline
# and launch the driver update systemd service
-# save module state
-cat /proc/modules > /tmp/dd_modules
-
# load all modules
udevadm trigger
udevadm settle
@@ -22,6 +19,9 @@ if [ -n "$dd_args" -o $blkid_rc -eq 0 ]; then
# kludge to let kernel spit out some extra info w/o stomping on our UI
sleep 5
+ # save module state
+ cat /proc/modules > /tmp/dd_modules
+
echo "$dd_args" > /tmp/dd_args
info "Starting Driver Update Disk Service on $tty"
systemctl start driver-updates(a)$tty.service
--
1.8.4.2
10 years, 4 months
[PATCH] Add back some erroneously removed set_use_underline calls
by David Shea
---
pyanaconda/ui/gui/spokes/custom.py | 1 +
pyanaconda/ui/gui/spokes/filter.py | 1 +
2 files changed, 2 insertions(+)
diff --git a/pyanaconda/ui/gui/spokes/custom.py b/pyanaconda/ui/gui/spokes/custom.py
index 634888d..956ea1f 100644
--- a/pyanaconda/ui/gui/spokes/custom.py
+++ b/pyanaconda/ui/gui/spokes/custom.py
@@ -864,6 +864,7 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
count) % count
self._summaryLabel.set_text(summary)
+ self._summaryLabel.set_use_underline(True)
def _reset_storage(self):
self.__storage = self.storage.copy()
diff --git a/pyanaconda/ui/gui/spokes/filter.py b/pyanaconda/ui/gui/spokes/filter.py
index aa30115..b19703b 100644
--- a/pyanaconda/ui/gui/spokes/filter.py
+++ b/pyanaconda/ui/gui/spokes/filter.py
@@ -516,6 +516,7 @@ class FilterSpoke(NormalSpoke):
count) % count
label.set_text(summary)
+ label.set_use_underline(True)
summaryButton.set_visible(count > 0)
label.set_sensitive(count > 0)
--
1.8.5.2
10 years, 4 months