[PATCH 1/2] Add free space information to DiskOverviews (#949746).
by Chris Lumens
This shows unpartitioned space, not reclaimable space on filesystems.
---
pyanaconda/ui/gui/spokes/storage.py | 3 ++
widgets/python/AnacondaWidgets.py | 3 +-
widgets/src/DiskOverview.c | 69 +++++++++++++++++++++++++++++--------
3 files changed, 59 insertions(+), 16 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py
index 24d8818..0cb6b30 100644
--- a/pyanaconda/ui/gui/spokes/storage.py
+++ b/pyanaconda/ui/gui/spokes/storage.py
@@ -580,9 +580,12 @@ class StorageSpoke(NormalSpoke, StorageChecker):
else:
description = disk.description
+ free = self.storage.getFreeSpace(disks=[disk])[disk.name][1]
+
overview = AnacondaWidgets.DiskOverview(description,
kind,
size,
+ _("%s free") % size_str(free),
disk.name,
popup=popup_info)
box.pack_start(overview, False, False, 0)
diff --git a/widgets/python/AnacondaWidgets.py b/widgets/python/AnacondaWidgets.py
index edb9f35..e2899a8 100644
--- a/widgets/python/AnacondaWidgets.py
+++ b/widgets/python/AnacondaWidgets.py
@@ -63,10 +63,11 @@ SpokeSelector = override(SpokeSelector)
__all__.append('SpokeSelector')
class DiskOverview(Anaconda.DiskOverview):
- def __init__(self, description, kind, capacity, name, popup=None):
+ def __init__(self, description, kind, capacity, free, name, popup=None):
Anaconda.DiskOverview.__init__(self)
self.set_property("description", description)
self.set_property("kind", kind)
+ self.set_property("free", free)
self.set_property("capacity", capacity)
self.set_property("name", name)
diff --git a/widgets/src/DiskOverview.c b/widgets/src/DiskOverview.c
index 2dcade1..7685f52 100644
--- a/widgets/src/DiskOverview.c
+++ b/widgets/src/DiskOverview.c
@@ -42,6 +42,7 @@
enum {
PROP_DESCRIPTION = 1,
PROP_KIND,
+ PROP_FREE,
PROP_CAPACITY,
PROP_NAME,
PROP_POPUP_INFO
@@ -51,16 +52,17 @@ enum {
#define DEFAULT_DESCRIPTION N_("New Device")
#define DEFAULT_KIND "drive-harddisk"
#define DEFAULT_CAPACITY N_("0 MB")
+#define DEFAULT_FREE N_("0 MB")
#define DEFAULT_NAME ""
#define DEFAULT_POPUP_INFO ""
#define ICON_SIZE 128
struct _AnacondaDiskOverviewPrivate {
- GtkWidget *vbox;
+ GtkWidget *grid;
GtkWidget *kind_icon;
GtkWidget *description_label;
- GtkWidget *capacity_label;
+ GtkWidget *capacity_label, *free_label;
GtkWidget *name_label;
GtkWidget *tooltip;
@@ -138,6 +140,22 @@ static void anaconda_disk_overview_class_init(AnacondaDiskOverviewClass *klass)
G_PARAM_READWRITE));
/**
+ * AnacondaDiskOverview:free:
+ *
+ * The :free string is the amount of free, unpartitioned space on the disk,
+ * plus units.
+ *
+ * Since: 1.0
+ */
+ g_object_class_install_property(object_class,
+ PROP_FREE,
+ g_param_spec_string("free",
+ P_("Free space"),
+ P_("The drive's unpartitioned free space (including units)"),
+ DEFAULT_FREE,
+ G_PARAM_READWRITE));
+
+ /**
* AnacondaDiskOverview:name:
*
* The :name string provides this device's node name (like 'sda'). Note
@@ -254,9 +272,11 @@ static void anaconda_disk_overview_init(AnacondaDiskOverview *widget) {
/* Set some properties. */
widget->priv->chosen = FALSE;
- /* Create the vbox. */
- widget->priv->vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
- gtk_container_set_border_width(GTK_CONTAINER(widget->priv->vbox), 6);
+ /* Create the grid. */
+ widget->priv->grid = gtk_grid_new();
+ gtk_grid_set_row_spacing(GTK_GRID(widget->priv->grid), 6);
+ gtk_grid_set_column_spacing(GTK_GRID(widget->priv->grid), 6);
+ gtk_container_set_border_width(GTK_CONTAINER(widget->priv->grid), 6);
/* Create the capacity label. */
widget->priv->capacity_label = gtk_label_new(NULL);
@@ -275,14 +295,24 @@ static void anaconda_disk_overview_init(AnacondaDiskOverview *widget) {
/* Create the name label. */
widget->priv->name_label = gtk_label_new(NULL);
+ gtk_widget_set_halign(widget->priv->name_label, GTK_ALIGN_END);
+
+ /* Create the free space label. */
+ widget->priv->free_label = gtk_label_new(NULL);
+ gtk_widget_set_halign(widget->priv->free_label, GTK_ALIGN_START);
+ markup = g_markup_printf_escaped("<span size='large'>%s</span>", _(DEFAULT_FREE));
+ gtk_label_set_markup(GTK_LABEL(widget->priv->capacity_label), markup);
+ g_free(markup);
- /* Add everything to the vbox, add the vbox to the widget. */
- gtk_container_add(GTK_CONTAINER(widget->priv->vbox), widget->priv->capacity_label);
- gtk_container_add(GTK_CONTAINER(widget->priv->vbox), widget->priv->kind_icon);
- gtk_container_add(GTK_CONTAINER(widget->priv->vbox), widget->priv->description_label);
- gtk_container_add(GTK_CONTAINER(widget->priv->vbox), widget->priv->name_label);
+ /* Add everything to the grid, add the grid to the widget. */
+ gtk_grid_attach(GTK_GRID(widget->priv->grid), widget->priv->capacity_label, 0, 0, 3, 1);
+ gtk_grid_attach(GTK_GRID(widget->priv->grid), widget->priv->kind_icon, 0, 1, 3, 1);
+ gtk_grid_attach(GTK_GRID(widget->priv->grid), widget->priv->description_label, 0, 2, 3, 1);
+ gtk_grid_attach(GTK_GRID(widget->priv->grid), widget->priv->name_label, 0, 3, 1, 1);
+ gtk_grid_attach(GTK_GRID(widget->priv->grid), gtk_label_new("/"), 1, 3, 1, 1);
+ gtk_grid_attach(GTK_GRID(widget->priv->grid), widget->priv->free_label, 2, 3, 1, 1);
- gtk_container_add(GTK_CONTAINER(widget), widget->priv->vbox);
+ gtk_container_add(GTK_CONTAINER(widget), widget->priv->grid);
/* We need to handle button-press-event in order to change the background color. */
g_signal_connect(widget, "button-press-event", G_CALLBACK(anaconda_disk_overview_clicked), NULL);
@@ -315,8 +345,7 @@ static void anaconda_disk_overview_toggle_background(AnacondaDiskOverview *widge
gtk_widget_unset_state_flags(GTK_WIDGET(widget), GTK_STATE_FLAG_SELECTED);
set_icon(widget, widget->priv->kind);
- gtk_container_add(GTK_CONTAINER(widget->priv->vbox), widget->priv->kind_icon);
- gtk_box_reorder_child(GTK_BOX(widget->priv->vbox), widget->priv->kind_icon, 1);
+ gtk_grid_attach(GTK_GRID(widget->priv->grid), widget->priv->kind_icon, 0, 1, 3, 1);
gtk_widget_show(widget->priv->kind_icon);
}
@@ -343,6 +372,10 @@ static void anaconda_disk_overview_get_property(GObject *object, guint prop_id,
g_value_set_object (value, (GObject *)priv->kind_icon);
break;
+ case PROP_FREE:
+ g_value_set_string (value, gtk_label_get_text(GTK_LABEL(priv->free_label)));
+ break;
+
case PROP_CAPACITY:
g_value_set_string (value, gtk_label_get_text(GTK_LABEL(priv->capacity_label)));
break;
@@ -375,10 +408,16 @@ static void anaconda_disk_overview_set_property(GObject *object, guint prop_id,
widget->priv->kind = g_strdup(g_value_get_string(value));
set_icon(widget, widget->priv->kind);
- gtk_container_add(GTK_CONTAINER(widget->priv->vbox), widget->priv->kind_icon);
- gtk_box_reorder_child(GTK_BOX(widget->priv->vbox), widget->priv->kind_icon, 1);
+ gtk_grid_attach(GTK_GRID(widget->priv->grid), widget->priv->kind_icon, 0, 1, 3, 1);
break;
+ case PROP_FREE: {
+ char *markup = g_markup_printf_escaped("<span size='large'>%s</span>", g_value_get_string(value));
+ gtk_label_set_markup(GTK_LABEL(priv->free_label), markup);
+ g_free(markup);
+ break;
+ }
+
case PROP_CAPACITY: {
char *markup = g_markup_printf_escaped("<span size='large'>%s</span>", g_value_get_string(value));
gtk_label_set_markup(GTK_LABEL(priv->capacity_label), markup);
--
1.8.1.2
11 years
[PATCH 1/4] Don't traceback when degraded md raid arrays are present. (#953184)
by David Lehman
---
blivet/devicetree.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/blivet/devicetree.py b/blivet/devicetree.py
index 0ed5cbf..29fbce3 100644
--- a/blivet/devicetree.py
+++ b/blivet/devicetree.py
@@ -733,9 +733,6 @@ class DeviceTree(object):
if device is None:
device = self.getDeviceByUuid(info.get("MD_UUID"))
- if device:
- raise DeviceTreeError("MD RAID device %s already in "
- "devicetree as %s" % (name, device.name))
# if we get here, we found all of the slave devices and
# something must be wrong -- if all of the slaves we in
@@ -743,10 +740,13 @@ class DeviceTree(object):
if device is None:
if name is None:
name = udev_device_get_name(info)
+ path = "/dev/" + name
+ else:
+ path = "/dev/md/" + name
log.error("failed to scan md array %s" % name)
try:
- devicelibs.mdraid.mddeactivate("/dev/" + name)
+ devicelibs.mdraid.mddeactivate(path)
except MDRaidError:
log.error("failed to stop broken md array %s" % name)
--
1.8.1.4
11 years
[lorax] no standalone modutils package
by Dan Horák
Resolves this error on s390x:
...
running runtime-install.tmpl
installpkg modutils failed: No package(s) available to install
Looking for extra fedup-dracut packages...
...
---
share/runtime-install.tmpl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/share/runtime-install.tmpl b/share/runtime-install.tmpl
index e8ae7b7..0d90d6f 100644
--- a/share/runtime-install.tmpl
+++ b/share/runtime-install.tmpl
@@ -36,7 +36,7 @@ installpkg kernel
installpkg grub2 grub2-tools yaboot fbset hfsutils kernel-bootwrapper ppc64-utils
%endif
%if basearch == "s390x":
- installpkg lsscsi modutils s390utils-base s390utils-cmsfs-fuse
+ installpkg lsscsi s390utils-base s390utils-cmsfs-fuse
%endif
## yay, plymouth
--
1.8.1.4
11 years
[PATCH 1/2] Show the summary screen before the luks passphrase dialog.
by David Lehman
It's irritating to have to enter a passphrase before you can see the
summary of scheduled actions.
---
pyanaconda/ui/gui/spokes/custom.py | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/custom.py b/pyanaconda/ui/gui/spokes/custom.py
index 1a1cfd9..8fb8b74 100644
--- a/pyanaconda/ui/gui/spokes/custom.py
+++ b/pyanaconda/ui/gui/spokes/custom.py
@@ -1606,6 +1606,20 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
# First, save anything from the currently displayed mountpoint.
self._save_right_side(self._current_selector)
+ # And then display the summary screen. From there, the user will either
+ # head back to the hub, or stay on the custom screen.
+ self.__storage.devicetree.pruneActions()
+ self.__storage.devicetree.sortActions()
+
+ dialog = ActionSummaryDialog(self.data)
+ with enlightbox(self.window, dialog.window):
+ dialog.refresh(self.__storage.devicetree.findActions())
+ rc = dialog.run()
+
+ if rc == 0:
+ # Cancel. Stay on the custom screen.
+ return
+
# Then if they did anything that resulted in new LUKS devices, we need
# to prompt for passphrases.
new_luks = any(d for d in self.__storage.devices
@@ -1621,20 +1635,6 @@ class CustomPartitioningSpoke(NormalSpoke, StorageChecker):
self.passphrase = dialog.passphrase
- # And then display the summary screen. From there, the user will either
- # head back to the hub, or stay on the custom screen.
- self.__storage.devicetree.pruneActions()
- self.__storage.devicetree.sortActions()
-
- dialog = ActionSummaryDialog(self.data)
- with enlightbox(self.window, dialog.window):
- dialog.refresh(self.__storage.devicetree.findActions())
- rc = dialog.run()
-
- if rc == 0:
- # Cancel. Stay on the custom screen.
- return
-
NormalSpoke.on_back_clicked(self, button)
def on_add_clicked(self, button):
--
1.8.1.4
11 years
[master][PATCH] Fix exception handling in rescue mode
by Vratislav Podzimek
The old code didn't work properly because __getattr__ was never called. This
replacement is a bit more straightforward and should work.
Signed-off-by: Vratislav Podzimek <vpodzime(a)redhat.com>
---
pyanaconda/rescue.py | 34 ++++++++++++++++++++++------------
1 file changed, 22 insertions(+), 12 deletions(-)
diff --git a/pyanaconda/rescue.py b/pyanaconda/rescue.py
index ad8da43..b611e7f 100644
--- a/pyanaconda/rescue.py
+++ b/pyanaconda/rescue.py
@@ -118,18 +118,7 @@ class RescueInterface(InstallInterfaceBase):
def __init__(self):
InstallInterfaceBase.__init__(self)
self.screen = SnackScreen()
- self._meh_interface = RescueExceptionHandlingIface(self.screen)
-
-class RescueExceptionHandlingIface(meh.ui.text.TextIntf):
- def __init__(self, snack_screen, *args, **kwargs):
- meh.ui.text.TextIntf.__init__(self, *args, **kwargs)
- self._snack_running = True
- self._snack_screen = snack_screen
-
- def __getattr__(self, attr):
- if self._snack_running:
- self._snack_screen.finish()
- self._snack_running = False
+ self._meh_interface = meh.ui.text.TextIntf()
def makeFStab(instPath = ""):
if os.access("/proc/mounts", os.R_OK):
@@ -212,9 +201,30 @@ def runShell(screen = None, msg=""):
if screen:
screen.finish()
+def _exception_handler_wrapper(orig_except_handler, screen, *args):
+ """
+ Helper function that wraps the exception handler with snack shutdown.
+
+ :param orig_except_handler: original exception handler that should be run
+ after the wrapping changes are done
+ :type orig_except_handler: exception handler as can be set as sys.excepthook
+ :param screen: snack screen that should be shut down before further actions
+ :type screen: snack screen
+
+ """
+
+ screen.finish()
+ return orig_except_handler(*args)
+
def doRescue(intf, rescue_mount, ksdata):
import blivet
+ # XXX: hook the exception handler wrapper that turns off snack first
+ orig_hook = sys.excepthook
+ sys.excepthook = lambda ty, val, tb: _exception_handler_wrapper(orig_hook,
+ intf.screen,
+ ty, val, tb)
+
for file in [ "services", "protocols", "group", "joe", "man.config",
"nsswitch.conf", "selinux", "mke2fs.conf" ]:
try:
--
1.7.11.7
11 years
[master][PATCH] Raise exception if our module fails to be imported
by Vratislav Podzimek
If an addon or something like that fails to be imported we may want to just log
an error, but if an import of our own module fails it is a bug.
Signed-off-by: Vratislav Podzimek <vpodzime(a)redhat.com>
---
pyanaconda/ui/common.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/pyanaconda/ui/common.py b/pyanaconda/ui/common.py
index 2bae250..bc1009e 100644
--- a/pyanaconda/ui/common.py
+++ b/pyanaconda/ui/common.py
@@ -567,8 +567,11 @@ def collect(module_pattern, path, pred):
# skip the file as well
if not module_flags[0].startswith(".py") and loaded_ext.startswith(".py"):
continue
-
+
except ImportError as imperr:
+ if "pyanaconda" in module_path:
+ # failure when importing our own module:
+ raise
log.error("Failed to import module in collect: %s" % imperr)
continue
finally:
--
1.7.11.7
11 years
[PATCH] RFC: Don't relly on /proc/mdstat when enumeraing RAID levels.
by Jan Safranek
/proc/mdstat can be empty or contain mostly random RAID levels. Blivet
should either modrpobe all RAID kernel modules (raid0, raid1, raid456, raid10)
which then populate /proc/mdstat correctly, or don't read /proc/mdstat at all.
This patch simply removes parsing of /proc/mdstat. Do we expect that someone
runs Blivet on a kernel which does not support certain RAID levels?
---
blivet/devicelibs/mdraid.py | 34 +---------------------------------
1 file changed, 1 insertion(+), 33 deletions(-)
diff --git a/blivet/devicelibs/mdraid.py b/blivet/devicelibs/mdraid.py
index 1fc5d46..98d997f 100644
--- a/blivet/devicelibs/mdraid.py
+++ b/blivet/devicelibs/mdraid.py
@@ -43,39 +43,7 @@ RAID4 = 4
RAID1 = 1
RAID0 = 0
-def getRaidLevels():
- mdstat_descriptors = {
- RAID10: ("[RAID10]", "[raid10]"),
- RAID6: ("[RAID6]", "[raid6]"),
- RAID5: ("[RAID5]", "[raid5]"),
- RAID4: ("[RAID4]", "[raid4]"),
- RAID1: ("[RAID1]", "[raid1]"),
- RAID0: ("[RAID0]", "[raid0]"),
- }
- avail = []
- try:
- f = open("/proc/mdstat", "r")
- except IOError:
- pass
- else:
- for l in f.readlines():
- if not l.startswith("Personalities"):
- continue
-
- lst = l.split()
-
- for level in mdstat_descriptors:
- for d in mdstat_descriptors[level]:
- if d in lst:
- avail.append(level)
- break
-
- f.close()
-
- avail.sort()
- return avail
-
-raid_levels = getRaidLevels()
+raid_levels = [ RAID0, RAID1, RAID4, RAID5, RAID6, RAID10 ]
raid_descriptors = {RAID10: ("raid10", "RAID10", "10", 10),
RAID6: ("raid6", "RAID6", "6", 6),
11 years
[master] Another battle in the "Gtk war" won
by Vratislav Podzimek
Small patches in the end, but it took me ages to find out that I need the change
from the PATCH 1/2 to make the PATCH 2/2 work.
I'm gonna make "Shift+Click" work for multiple selection next week.
Vratislav Podzimek (2):
DiskOverview needs to grab focus if clicked
Select all disks when Ctrl+A is pressed (#864707)
pyanaconda/ui/gui/spokes/storage.glade | 2 ++
pyanaconda/ui/gui/spokes/storage.py | 13 +++++++++++--
widgets/src/DiskOverview.c | 1 +
3 files changed, 14 insertions(+), 2 deletions(-)
--
1.7.11.7
11 years
[PATCH post F19 alpha] Update network ksdata with cmdline options (#893784)
by Radek Vykydal
---
pyanaconda/ui/gui/spokes/network.py | 30 ++++++++++++++----------------
1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/pyanaconda/ui/gui/spokes/network.py b/pyanaconda/ui/gui/spokes/network.py
index 81ecdef..63e247f 100644
--- a/pyanaconda/ui/gui/spokes/network.py
+++ b/pyanaconda/ui/gui/spokes/network.py
@@ -1102,15 +1102,7 @@ class NetworkSpoke(NormalSpoke):
device.connect("state-changed", self.on_device_state_changed)
def apply(self):
- # TODO: sanity check
- self.data.network.network = []
- for dev in self.network_control_box.listed_devices:
- network_data = getKSNetworkData(dev)
- if network_data is not None:
- self.data.network.network.append(network_data)
- hostname = self.network_control_box.hostname
- network.update_hostname_data(self.data, hostname)
-
+ _read_network_ksdata(self.data, self.network_control_box)
log.debug("network: apply ksdata %s" % self.data.network)
@property
@@ -1187,6 +1179,8 @@ class NetworkSpoke(NormalSpoke):
def initialize(self):
NormalSpoke.initialize(self)
self.network_control_box.initialize()
+ if not self.data.network.seen:
+ _update_network_data(self.data, self.network_control_box)
def refresh(self):
NormalSpoke.refresh(self)
@@ -1225,6 +1219,7 @@ class NetworkSpoke(NormalSpoke):
self.clear_info()
NormalSpoke.on_back_clicked(self, button)
+
class NetworkStandaloneSpoke(StandaloneSpoke):
builderObjects = ["networkStandaloneWindow", "networkControlBox_vbox", "liststore_wireless_network", "liststore_devices", "add_device_dialog", "liststore_add_device"]
mainWidgetName = "networkStandaloneWindow"
@@ -1249,13 +1244,7 @@ class NetworkStandaloneSpoke(StandaloneSpoke):
self._now_available = False
def apply(self):
- self.data.network.network = []
- for dev in self.network_control_box.listed_devices:
- network_data = getKSNetworkData(dev)
- if network_data is not None:
- self.data.network.network.append(network_data)
- hostname = self.network_control_box.hostname
- network.update_hostname_data(self.data, hostname)
+ _update_network_data(self.data, self.network_control_box)
log.debug("network: apply ksdata %s" % self.data.network)
@@ -1305,6 +1294,15 @@ class NetworkStandaloneSpoke(StandaloneSpoke):
network.update_hostname_data(self.data, hostname)
self.network_control_box.hostname = self.data.network.hostname
+def _update_network_data(data, ncb):
+ data.network.network = []
+ for dev in ncb.listed_devices:
+ network_data = getKSNetworkData(dev)
+ if network_data is not None:
+ data.network.network.append(network_data)
+ hostname = ncb.hostname
+ network.update_hostname_data(data, hostname)
+
def getKSNetworkData(device):
retval = None
--
1.7.11.7
11 years
[PATCH 1/2] Add a checkmark on a DiskOverview when it is selected.
by Chris Lumens
This is to help make it a little more obvious when a disk is selected,
especially when there is only one disk available and we select it by
default. It can be hard to tell what the blue background means then.
---
data/pixmaps/Makefile.am | 2 +-
data/pixmaps/anaconda-selected-icon.svg | 136 ++++++++++++++++++++++++++++++++
widgets/src/DiskOverview.c | 82 +++++++++++++++----
3 files changed, 205 insertions(+), 15 deletions(-)
create mode 100644 data/pixmaps/anaconda-selected-icon.svg
diff --git a/data/pixmaps/Makefile.am b/data/pixmaps/Makefile.am
index 00320b0..26d1f77 100644
--- a/data/pixmaps/Makefile.am
+++ b/data/pixmaps/Makefile.am
@@ -18,6 +18,6 @@
# Author: David Cantrell <dcantrell(a)redhat.com>
pixmapsdir = $(datadir)/$(PACKAGE_NAME)/pixmaps
-dist_pixmaps_DATA = *.png
+dist_pixmaps_DATA = *.png *.svg
MAINTAINERCLEANFILES = Makefile.in
diff --git a/data/pixmaps/anaconda-selected-icon.svg b/data/pixmaps/anaconda-selected-icon.svg
new file mode 100644
index 0000000..32c90fd
--- /dev/null
+++ b/data/pixmaps/anaconda-selected-icon.svg
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg7384"
+ sodipodi:docname="anaconda-selected-icon.svg"
+ version="1.1"
+ inkscape:version="0.48+devel r11963"
+ height="16"
+ width="16">
+ <metadata
+ id="metadata90">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>Gnome Symbolic Icon Theme</dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <sodipodi:namedview
+ inkscape:cy="6.5413406"
+ pagecolor="#ffffff"
+ borderopacity="1"
+ showborder="true"
+ inkscape:bbox-paths="false"
+ guidetolerance="10"
+ inkscape:object-paths="true"
+ inkscape:window-width="1145"
+ showguides="true"
+ inkscape:object-nodes="true"
+ inkscape:snap-bbox="true"
+ inkscape:pageshadow="2"
+ inkscape:guide-bbox="true"
+ inkscape:snap-nodes="false"
+ bordercolor="#666666"
+ objecttolerance="10"
+ id="namedview88"
+ showgrid="false"
+ inkscape:window-maximized="0"
+ inkscape:window-x="201"
+ inkscape:snap-global="true"
+ inkscape:window-y="27"
+ gridtolerance="10"
+ inkscape:window-height="709"
+ inkscape:snap-to-guides="true"
+ inkscape:current-layer="layer15"
+ inkscape:snap-bbox-midpoints="false"
+ inkscape:zoom="16"
+ inkscape:cx="6.9516857"
+ inkscape:snap-grids="true"
+ inkscape:pageopacity="0"
+ borderlayer="true">
+ <inkscape:grid
+ spacingx="1px"
+ spacingy="1px"
+ id="grid4866"
+ empspacing="2"
+ enabled="true"
+ type="xygrid"
+ snapvisiblegridlinesonly="true"
+ visible="true" />
+ </sodipodi:namedview>
+ <title
+ id="title9167">Gnome Symbolic Icon Theme</title>
+ <defs
+ id="defs7386" />
+ <g
+ inkscape:label="status"
+ transform="translate(-482,-381.99998)"
+ inkscape:groupmode="layer"
+ id="layer9"
+ style="display:inline" />
+ <g
+ inkscape:label="devices"
+ transform="translate(-482,-381.99998)"
+ inkscape:groupmode="layer"
+ id="layer10" />
+ <g
+ inkscape:label="apps"
+ transform="translate(-482,-381.99998)"
+ inkscape:groupmode="layer"
+ id="layer11" />
+ <g
+ inkscape:label="actions"
+ transform="translate(-482,-381.99998)"
+ inkscape:groupmode="layer"
+ id="layer12" />
+ <g
+ inkscape:label="places"
+ transform="translate(-482,-381.99998)"
+ inkscape:groupmode="layer"
+ id="layer13" />
+ <g
+ inkscape:label="mimetypes"
+ transform="translate(-482,-381.99998)"
+ inkscape:groupmode="layer"
+ id="layer14" />
+ <g
+ inkscape:label="emblems"
+ transform="translate(-482,-381.99998)"
+ inkscape:groupmode="layer"
+ id="layer15"
+ style="display:inline">
+ <g
+ inkscape:label="emblem-important"
+ transform="translate(135.8093,-581.17812)"
+ id="g17779" />
+ <path
+ style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+ d="M 11.53125 4.3125 C 11.784964 4.3148534 12.043986 4.3496993 12.28125 4.40625 C 12.035802 4.3478581 11.794428 4.3125 11.53125 4.3125 z M 12.28125 4.40625 C 12.505761 4.4597611 12.733193 4.5282014 12.9375 4.625 C 12.73111 4.5265635 12.508413 4.460292 12.28125 4.40625 z M 13.6875 5.125 C 13.850992 5.2667533 13.991932 5.4225624 14.125 5.59375 C 13.993811 5.4260074 13.847799 5.2645304 13.6875 5.125 z M 14.125 5.59375 L 11.71875 7.90625 L 10.8125 6.90625 L 9.78125 7.90625 L 11.71875 9.84375 L 14.78125 7.09375 C 14.688509 6.5295894 14.461839 6.0244437 14.125 5.59375 z M 14.84375 7.625 C 14.84375 8.544865 14.444846 9.3969938 13.84375 10 C 14.452893 9.395735 14.84375 8.5537662 14.84375 7.625 z "
+ transform="translate(482,381.99998)"
+ id="path1012" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 493.51417,386.30805 c -1.82723,0 -3.30412,1.49216 -3.30412,3.33188 0,1.83973 1.47689,3.33189 3.30412,3.33189 1.82723,0 3.318,-1.49216 3.318,-3.33189 0,-0.18508 -0.0267,-0.36456 -0.0555,-0.54143 l -3.06223,2.74335 -1.92929,-1.93014 1.01176,-0.99284 0.91795,0.98022 2.40931,-2.31382 C 495.51856,386.80617 494.57294,386.30805 493.51417,386.30805 Z"
+ id="path74"
+ sodipodi:nodetypes="ssssccccccs"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
+ </g>
+ <g
+ inkscape:label="categories"
+ transform="translate(-482,-381.99998)"
+ inkscape:groupmode="layer"
+ id="g4953"
+ style="display:inline" />
+</svg>
diff --git a/widgets/src/DiskOverview.c b/widgets/src/DiskOverview.c
index e3c39f4..2dcade1 100644
--- a/widgets/src/DiskOverview.c
+++ b/widgets/src/DiskOverview.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011-2012 Red Hat, Inc.
+ * Copyright (C) 2011-2013 Red Hat, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,6 +18,7 @@
*/
#include <gdk/gdk.h>
+#include <gio/gio.h>
#include <string.h>
#include "DiskOverview.h"
@@ -53,11 +54,11 @@ enum {
#define DEFAULT_NAME ""
#define DEFAULT_POPUP_INFO ""
-#define ICON_SIZE 125
+#define ICON_SIZE 128
struct _AnacondaDiskOverviewPrivate {
GtkWidget *vbox;
- GtkWidget *kind;
+ GtkWidget *kind_icon;
GtkWidget *description_label;
GtkWidget *capacity_label;
GtkWidget *name_label;
@@ -65,6 +66,7 @@ struct _AnacondaDiskOverviewPrivate {
GdkCursor *cursor;
+ gchar *kind;
gboolean chosen;
};
@@ -186,6 +188,50 @@ GtkWidget *anaconda_disk_overview_new() {
return g_object_new(ANACONDA_TYPE_DISK_OVERVIEW, NULL);
}
+static void set_icon(AnacondaDiskOverview *widget, const char *icon_name) {
+ GError *err = NULL;
+ GIcon *base_icon, *emblem_icon, *icon;
+ GEmblem *emblem = NULL;
+
+ if (!icon_name)
+ return;
+
+ if (widget->priv->kind_icon)
+ gtk_widget_destroy(widget->priv->kind_icon);
+
+ if (widget->priv->chosen) {
+ base_icon = g_icon_new_for_string(icon_name, &err);
+ if (!base_icon) {
+ fprintf(stderr, "could not create icon: %s\n", err->message);
+ g_error_free(err);
+ return;
+ }
+
+ emblem_icon = g_icon_new_for_string("/usr/share/anaconda/pixmaps/anaconda-selected-icon.svg", &err);
+ if (!emblem_icon) {
+ fprintf(stderr, "could not create emblem: %s\n", err->message);
+ g_error_free(err);
+ }
+ else {
+ emblem = g_emblem_new(emblem_icon);
+ }
+
+ icon = g_emblemed_icon_new(base_icon, emblem);
+ g_object_unref(base_icon);
+ }
+ else {
+ icon = g_icon_new_for_string(icon_name, &err);
+ if (!icon) {
+ fprintf(stderr, "could not create icon: %s\n", err->message);
+ g_error_free(err);
+ return;
+ }
+ }
+
+ widget->priv->kind_icon = gtk_image_new_from_gicon(icon, GTK_ICON_SIZE_DIALOG);
+ gtk_image_set_pixel_size(GTK_IMAGE(widget->priv->kind_icon), ICON_SIZE);
+}
+
/* Initialize the widgets in a newly allocated DiskOverview. */
static void anaconda_disk_overview_init(AnacondaDiskOverview *widget) {
char *markup;
@@ -219,8 +265,7 @@ static void anaconda_disk_overview_init(AnacondaDiskOverview *widget) {
g_free(markup);
/* Create the spoke's icon. */
- widget->priv->kind = gtk_image_new_from_icon_name(DEFAULT_KIND, GTK_ICON_SIZE_DIALOG);
- gtk_image_set_pixel_size(GTK_IMAGE(widget->priv->kind), ICON_SIZE);
+ set_icon(widget, DEFAULT_KIND);
/* Create the description label. */
widget->priv->description_label = gtk_label_new(NULL);
@@ -233,7 +278,7 @@ static void anaconda_disk_overview_init(AnacondaDiskOverview *widget) {
/* Add everything to the vbox, add the vbox to the widget. */
gtk_container_add(GTK_CONTAINER(widget->priv->vbox), widget->priv->capacity_label);
- gtk_container_add(GTK_CONTAINER(widget->priv->vbox), widget->priv->kind);
+ gtk_container_add(GTK_CONTAINER(widget->priv->vbox), widget->priv->kind_icon);
gtk_container_add(GTK_CONTAINER(widget->priv->vbox), widget->priv->description_label);
gtk_container_add(GTK_CONTAINER(widget->priv->vbox), widget->priv->name_label);
@@ -264,11 +309,15 @@ gboolean anaconda_disk_overview_clicked(AnacondaDiskOverview *widget, GdkEvent *
}
static void anaconda_disk_overview_toggle_background(AnacondaDiskOverview *widget) {
- if (widget->priv->chosen) {
- gtk_widget_set_state_flags(GTK_WIDGET(widget), GTK_STATE_FLAG_SELECTED, FALSE);
- }
+ if (widget->priv->chosen)
+ gtk_widget_set_state_flags(GTK_WIDGET(widget), GTK_STATE_FLAG_SELECTED, FALSE);
else
- gtk_widget_unset_state_flags(GTK_WIDGET(widget), GTK_STATE_FLAG_SELECTED);
+ gtk_widget_unset_state_flags(GTK_WIDGET(widget), GTK_STATE_FLAG_SELECTED);
+
+ set_icon(widget, widget->priv->kind);
+ gtk_container_add(GTK_CONTAINER(widget->priv->vbox), widget->priv->kind_icon);
+ gtk_box_reorder_child(GTK_BOX(widget->priv->vbox), widget->priv->kind_icon, 1);
+ gtk_widget_show(widget->priv->kind_icon);
}
static void anaconda_disk_overview_finalize(AnacondaDiskOverview *widget) {
@@ -291,7 +340,7 @@ static void anaconda_disk_overview_get_property(GObject *object, guint prop_id,
break;
case PROP_KIND:
- g_value_set_object (value, (GObject *)priv->kind);
+ g_value_set_object (value, (GObject *)priv->kind_icon);
break;
case PROP_CAPACITY:
@@ -315,14 +364,19 @@ static void anaconda_disk_overview_set_property(GObject *object, guint prop_id,
switch(prop_id) {
case PROP_DESCRIPTION: {
char *markup = g_markup_printf_escaped("<span weight='bold' size='large'>%s</span>", g_value_get_string(value));
- gtk_label_set_markup(GTK_LABEL(priv->description_label), markup);
+ gtk_label_set_markup(GTK_LABEL(priv->description_label), markup);
g_free(markup);
break;
}
case PROP_KIND:
- gtk_image_set_from_icon_name(GTK_IMAGE(priv->kind), g_value_get_string(value), GTK_ICON_SIZE_DIALOG);
- gtk_image_set_pixel_size(GTK_IMAGE(priv->kind), ICON_SIZE);
+ if (widget->priv->kind)
+ g_free(widget->priv->kind);
+
+ widget->priv->kind = g_strdup(g_value_get_string(value));
+ set_icon(widget, widget->priv->kind);
+ gtk_container_add(GTK_CONTAINER(widget->priv->vbox), widget->priv->kind_icon);
+ gtk_box_reorder_child(GTK_BOX(widget->priv->vbox), widget->priv->kind_icon, 1);
break;
case PROP_CAPACITY: {
--
1.8.1.2
11 years