[PATCH 5/5] Add storage category, spoke, and builder file.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Initial implementation of the disk selection part of the storage spoke.

some limitations (not an exhaustive list):
 - uses fake disk data due to non-trivial problems with non-root usage
 - can't switch other spokes yet (eg: software)
 - don't know how to get required space for current package set
 - no advanced/specialized devices
---
 pyanaconda/ui/gui/categories/storage.py |   30 +
 pyanaconda/ui/gui/spokes/storage.py     |  534 +++++++++++++++++
 pyanaconda/ui/gui/spokes/storage.ui     |  995 +++++++++++++++++++++++++++++++
 3 files changed, 1559 insertions(+), 0 deletions(-)
 create mode 100644 pyanaconda/ui/gui/categories/storage.py
 create mode 100644 pyanaconda/ui/gui/spokes/storage.py
 create mode 100644 pyanaconda/ui/gui/spokes/storage.ui

diff --git a/pyanaconda/ui/gui/categories/storage.py b/pyanaconda/ui/gui/categories/storage.py
new file mode 100644
index 0000000..bc94447
--- /dev/null
+++ b/pyanaconda/ui/gui/categories/storage.py
@@ -0,0 +1,30 @@
+# Storage category classes
+#
+# Copyright (C) 2011  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): Chris Lumens <clumens@xxxxxxxxxx>
+#                    David Lehman <dlehman@xxxxxxxxxx>
+#
+
+from pyanaconda.ui.gui.categories import SpokeCategory
+from pyanaconda.ui.gui.hubs.summary import SummaryHub
+
+__all__ = ["StorageCategory"]
+
+class StorageCategory(SpokeCategory):
+    displayOnHub = SummaryHub
+    title = "STORAGE"
diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py
new file mode 100644
index 0000000..c961a31
--- /dev/null
+++ b/pyanaconda/ui/gui/spokes/storage.py
@@ -0,0 +1,534 @@
+# Storage configuration spoke classes
+#
+# Copyright (C) 2011  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): David Lehman <dlehman@xxxxxxxxxx>
+#
+
+"""
+    TODO:
+
+        - add button within sw_needs text in options dialogs 2,3
+        - udev data gathering
+            - udev fwraid, mpath would sure be nice
+        - status/completed
+            - what are noteworthy status events?
+                - disks selected
+                    - exclusiveDisks non-empty
+                - sufficient space for software selection
+                - autopart selected
+                - custom selected
+                    - performing custom configuration
+                - storage configuration complete
+        - spacing and border width always 6
+
+"""
+
+from gi.repository import Gtk
+from gi.repository import AnacondaWidgets
+
+from pyanaconda.ui.gui import UIObject
+from pyanaconda.ui.gui.spokes import NormalSpoke
+from pyanaconda.ui.gui.categories.storage import StorageCategory
+
+from pyanaconda.storage.size import Size
+
+# these are all temporary
+from pyanaconda.storage.partitioning import getFreeRegions
+from pyanaconda.storage.partitioning import sectorsToSize
+from pyanaconda.storage.devices import DiskDevice
+from pyanaconda.storage.formats import getFormat
+
+from pyanaconda.product import productName
+
+import gettext
+
+_ = lambda x: gettext.ldgettext("anaconda", x)
+P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
+
+__all__ = ["StorageSpoke"]
+
+class FakeDisk(object):
+    def __init__(self, name, size=0, free=0, partitioned=True, vendor=None,
+                 model=None, serial=None, removable=False):
+        self.name = name
+        self.size = size
+        self.free = free
+        self.partitioned = partitioned
+        self.vendor = vendor
+        self.model = model
+        self.serial = serial
+        self.removable = removable
+
+    @property
+    def description(self):
+        return "%s %s" % (self.vendor, self.model)
+
+def getDisks(devicetree, fake=False):
+    if not fake:
+        disks = [d for d in devicetree.devices if d.isDisk and
+                                                  not d.format.hidden and
+                                                  d.partitioned]
+    else:
+        disks = []
+        disks.append(FakeDisk("sda", size=300000, free=10000, serial="00001",
+                              vendor="Seagate", model="Monster"))
+        disks.append(FakeDisk("sdb", size=300000, free=300000, serial="00002",
+                              vendor="Seagate", model="Monster"))
+        disks.append(FakeDisk("sdc", size=8000, free=2100, removable=True,
+                              vendor="SanDisk", model="Cruzer", serial="00003"))
+
+    return disks
+
+# XXX move these into storage
+def fsFreeSpace(device):
+    free = 0
+    if device.format.exists:
+        current_size = getattr(device.format, "currentSize", None)
+        min_size = getattr(device.format, "minSize", None)
+        if current_size and min_size and current_size != min_size:
+            free = int(current_size - min_size)     # truncate
+
+    return free
+
+def diskFreeSpace(disk):
+    free = 0
+    if disk.partitioned:
+        parted_disk = disk.format.partedDisk
+        sector_size = disk.partedDevice.sectorSize
+
+        free_geoms = getFreeRegions([parted_disk])
+        free_sizes = [sectorsToSize(f.length, sector_size) for f in free_geoms]
+        free = sum(free_sizes)
+
+    return free
+
+def get_free_space_info(disks, devicetree):
+    disk_free = 0
+    fs_free = 0
+    for disk in disks:
+        if hasattr(disk, "free"):
+            disk_free += disk.free
+            continue
+
+        disk_free += diskFreeSpace(disk)
+        for partition in devicetree.getChildren(disk):
+            fs_free += fsFreeSpace(partition)
+
+    print("disks %s have %d free, plus %s in filesystems"
+          % ([d.name for d in disks], disk_free, fs_free))
+    return (disk_free, fs_free)
+
+
+class SelectedDisksDialog(UIObject):
+    builderObjects = ["selected_disks_dialog", "disk_store"]
+    mainWidgetName = "selected_disks_dialog"
+    uiFile = "spokes/storage.ui"
+
+    def populate(self, disks):
+        for disk in disks:
+            if disk.name not in self.data.ignoredisk.onlyuse:
+                continue
+
+            self._store.append(["%s-%s" % (disk.vendor, disk.model),
+                                Size(spec="%s mb" % disk.size).humanReadable().upper(),
+                                Size(spec="%s mb" % disk.free).humanReadable().upper(),
+                                str(disks.index(disk))])
+        self.disks = disks[:]
+        self._update_summary()
+
+    def setup(self, disks):
+        print "SETUP selected disks dialog"
+        super(SelectedDisksDialog, self).setup()
+
+        self._view = self.builder.get_object("disk_view")
+        self._store = self.builder.get_object("disk_store")
+        self._selection = self.builder.get_object("disk_selection")
+        self._summary_label = self.builder.get_object("summary_label")
+
+        # clear out the store and repopulate it from the devicetree
+        self._store.clear()
+        self.populate(disks)
+
+    def run(self):
+        rc = self.window.run()
+        self.window.destroy()
+        return rc
+
+    def _get_selection_refs(self):
+        selected_refs = []
+        if self._selection.count_selected_rows():
+            model, selected_paths = self._selection.get_selected_rows()
+            selected_refs = [Gtk.TreeRowReference() for p in selected_paths]
+
+        return selected_refs
+
+    def _update_summary(self):
+        count = 0
+        size = 0
+        free = 0
+        itr = self._store.get_iter_first()
+        while itr:
+            count += 1
+            size += Size(spec=self._store.get_value(itr, 1))
+            free += Size(spec=self._store.get_value(itr, 2))
+            itr = self._store.iter_next(itr)
+
+        size = Size(bytes=long(size)).humanReadable().upper()
+        free = Size(bytes=long(free)).humanReadable().upper()
+
+        text = P_(("%d disk; %s capacity; %s free space "
+                   "(unpartitioned and in filesystems)"),
+                  ("%d disks; %s capacity; %s free space "
+                   "(unpartitioned and in filesystems)"),
+                  count) % (count, size, free)
+        self._summary_label.set_text(text)
+
+    # signal handlers
+    def on_remove_clicked(self, button):
+        print "REMOVE CLICKED"#: %s" % self._selection.get_selected().get_value(3)
+        # remove the selected disk(s) from the list and update the summary label
+        #selected_refs = self._get_selection_refs()
+        #for ref in selected_refs:
+        #    path = ref.get_path()
+        #    itr = model.get_iter_from_string(path)
+        #    self._store.remove(itr)
+        model, itr = self._selection.get_selected()
+        if itr:
+            idx = int(model.get_value(itr, 3))
+            name = self.disks[idx].name
+            print "removing %s" % name
+            self._store.remove(itr)
+            self.data.ignoredisk.onlyuse.remove(name)
+            self._update_summary()
+
+    def on_close_clicked(self, button):
+        print "CLOSE CLICKED"
+
+    def on_selection_changed(self, *args):
+        print "SELECTION CHANGED"
+        model, itr = self._selection.get_selected()
+        if itr:
+            print "new selection: %s" % model.get_value(itr, 3)
+
+
+class InstallOptions1Dialog(UIObject):
+    builderObjects = ["options1_dialog"]
+    mainWidgetName = "options1_dialog"
+    uiFile = "spokes/storage.ui"
+
+    RESPONSE_CANCEL = 0
+    RESPONSE_CONTINUE = 1
+    RESPONSE_MODIFY_SW = 2
+    RESPONSE_RECLAIM = 3
+    RESPONSE_QUIT = 4
+
+    def run(self):
+        rc = self.window.run()
+        self.window.destroy()
+        return rc
+
+    def setup(self, required_space, disk_free, fs_free):
+        custom = not self.data.autopart.autopart
+        self.custom_checkbutton = self.builder.get_object("options1_custom_check")
+        self.custom_checkbutton.set_active(custom)
+
+        options_label = self.builder.get_object("options1_label")
+
+        options_text = (_("You have plenty of space to install <b>%s</b>, so "
+                          "we can automatically configure the rest of the "
+                          "installation for you.\n\nYou're all set!")
+                        % productName)
+        options_label.set_markup(options_text)
+
+    def _set_free_space_labels(self, disk_free, fs_free):
+        disk_free_text = Size(spec="%dmb" % disk_free).humanReadable().upper()
+        self.disk_free_label.set_text(disk_free_text)
+
+        fs_free_text = Size(spec="%dmb" % fs_free).humanReadable().upper()
+        self.fs_free_label.set_text(fs_free_text)
+
+    def _get_sw_needs_text(self, required_space):
+        required_space_text = Size(spec="%dmb" % required_space).humanReadable().upper()
+        sw_text = (_("Your current <b>%s</b> software selection requires "
+                      "<b>%s</b> of available space.")
+                   % (productName, required_space_text))
+        return sw_text
+
+    @property
+    def customize_state(self):
+        if hasattr(self, "custom_checkbutton"):
+            return self.custom_checkbutton.get_active()
+
+        return False
+
+    # signal handlers
+    def on_cancel_clicked(self, button):
+        # return to the spoke without making any changes
+        print "CANCEL CLICKED"
+
+    def on_quit_clicked(self, button):
+        print "QUIT CLICKED"
+
+    def on_modify_sw_clicked(self, button):
+        # switch to the software selection hub
+        print "MODIFY SOFTWARE CLICKED"
+
+    def on_reclaim_clicked(self, button):
+        # show reclaim screen/dialog
+        print "RECLAIM CLICKED"
+
+    def on_continue_clicked(self, button):
+        # TODO: handle custom checkbutton
+        print "CONTINUE CLICKED"
+
+class InstallOptions2Dialog(InstallOptions1Dialog):
+    builderObjects = ["options2_dialog"]
+    mainWidgetName = "options2_dialog"
+
+    def setup(self, required_space, disk_free, fs_free):
+        custom = not self.data.autopart.autopart
+        self.custom_checkbutton = self.builder.get_object("options2_custom_check")
+        self.custom_checkbutton.set_active(custom)
+
+        sw_text = self._get_sw_needs_text(required_space)
+        label_text = _("%s\nThe disks you've selected have the following "
+                       "amounts of free space:") % sw_text
+        self.builder.get_object("options2_label1").set_markup(label_text)
+
+        self.disk_free_label = self.builder.get_object("options2_disk_free_label")
+        self.fs_free_label = self.builder.get_object("options2_fs_free_label")
+        self._set_free_space_labels(disk_free, fs_free)
+
+        label_text = (_("<b>You don't have enough space available to install "
+                        "%s</b>, but we can help you reclaim space by "
+                        "shrinking or removing existing partitions.")
+                      % productName)
+        self.builder.get_object("options2_label2").set_markup(label_text)
+
+    def on_custom_toggled(self, checkbutton):
+        custom = checkbutton.get_active()
+        self.builder.get_object("options2_cancel_button").set_sensitive(not custom)
+        self.builder.get_object("options2_modify_sw_button").set_sensitive(not custom)
+
+class InstallOptions3Dialog(InstallOptions1Dialog):
+    builderObjects = ["options3_dialog"]
+    mainWidgetName = "options3_dialog"
+
+    def setup(self, required_space, disk_free, fs_free):
+        sw_text = self._get_sw_needs_text(required_space)
+        label_text = (_("%s\nYou don't have enough space available to install "
+                        "<b>%s</b>, even if you used all of the free space "
+                        "available on the selected disks.")
+                      % (sw_text, productName))
+        self.builder.get_object("options3_label1").set_markup(label_text)
+
+        self.disk_free_label = self.builder.get_object("options3_disk_free_label")
+        self.fs_free_label = self.builder.get_object("options3_fs_free_label")
+        self._set_free_space_labels(disk_free, fs_free)
+
+        label_text = _("<b>You don't have enough space available to install "
+                       "%s</b>, even if you used all of the free space "
+                       "available on the selected disks.You could add more "
+                       "disks for additional space, modify your software "
+                       "selection to install a smaller version of <b>%s</b>, "
+                       "or quit the installer.") % (productName, productName)
+        self.builder.get_object("options3_label2").set_markup(label_text)
+
+class StorageSpoke(NormalSpoke):
+    builderObjects = ["storageWindow"]
+    mainWidgetName = "storageWindow"
+    uiFile = "spokes/storage.ui"
+
+    category = StorageCategory
+
+    # other candidates: computer-symbolic, folder-symbolic
+    icon = "drive-harddisk-symbolic"
+    title = "STORAGE CONFIGURATION"
+
+    def apply(self):
+        pass
+
+    @property
+    def completed(self):
+        return False
+
+    @property
+    def status(self):
+        """ A short string describing the current status of storage setup. """
+        msg = "no disks selected"
+        if self.data.ignoredisk.onlyuse:
+            msg = "%d disks selected" % len(self.data.ignoredisk.onlyuse)
+
+            if self.data.autopart.autopart:
+                msg = "Automatic partitioning selected"
+
+                # if we had a storage instance we could check for a defined root
+
+        return msg
+
+    def _on_disk_clicked(self, overview, *args):
+        print "DISK CLICKED: %s" % overview.get_property("popup-info").partition("|")[0].strip()
+
+        self._update_disk_list()
+        self._update_summary()
+
+    def populate(self):
+        NormalSpoke.populate(self)
+
+        local_disks_box = self.builder.get_object("local_disks_box")
+        #specialized_disks_box = self.builder.get_object("specialized_disks_box")
+
+        print self.data.ignoredisk.onlyuse
+        self.disks = getDisks(self.devicetree, fake=True)
+
+        # properties: kind, description, capacity, os, popup-info
+        for disk in self.disks:
+            if disk.removable:
+                kind = "drive-removable"
+            else:
+                kind = "drive-harddisk"
+
+            size = Size(spec="%dmb" % disk.size).humanReadable().upper()
+            popup_info = "%s | %s" % (disk.name, disk.serial)
+            overview = AnacondaWidgets.DiskOverview(disk.description,
+                                                    kind,
+                                                    size,
+                                                    popup=popup_info)
+            local_disks_box.add(overview)
+
+            # FIXME: this will need to get smarter
+            #
+            # maybe a little function that resolves each item in onlyuse using
+            # udev_resolve_devspec and compares that to the DiskDevice?
+            overview.set_selected(disk.name in self.data.ignoredisk.onlyuse)
+            overview.connect("button-press-event", self._on_disk_clicked)
+
+        self._update_summary()
+
+    def setup(self):
+        # XXX this is called every time we switch to this spoke
+        NormalSpoke.setup(self)
+
+    def _update_summary(self):
+        """ Update the summary based on the UI. """
+        print "UPDATING SUMMARY"
+        count = 0
+        capacity = 0
+        free = 0
+
+        overviews = self.builder.get_object("local_disks_box").get_children()
+        for overview in overviews:
+            name = overview.get_property("popup-info").partition("|")[0].strip()
+            selected = overview.get_selected()
+            if selected:
+                disk = None
+                for _disk in self.disks:
+                    if _disk.name == name:
+                        disk = _disk
+                        break
+
+                capacity += disk.size
+                free += disk.free
+                count += 1
+
+        summary = (P_(("%d disk selected; %s capacity; %s free ..."),
+                      ("%d disks selected; %s capacity; %s free ..."),
+                      count)
+                   % (count,
+                      Size(spec="%dmb" % capacity).humanReadable().upper(),
+                      Size(spec="%dmb" % free).humanReadable().upper()))
+        self.builder.get_object("summary_button").set_label(summary)
+
+    def _update_disk_list(self):
+        """ Update ignoredisk.onlyuse based on the UI. """
+        print "UPDATING DISK LIST"
+        overviews = self.builder.get_object("local_disks_box").get_children()
+        for overview in overviews:
+            name = overview.get_property("popup-info").partition("|")[0].strip()
+
+            selected = overview.get_selected()
+            if selected and name not in self.data.ignoredisk.onlyuse:
+                self.data.ignoredisk.onlyuse.append(name)
+
+            if not selected and name in self.data.ignoredisk.onlyuse:
+                self.data.ignoredisk.onlyuse.remove(name)
+
+    # signal handlers
+    def on_summary_clicked(self, button):
+        # show the selected disks dialog
+        dialog = SelectedDisksDialog(self.data)
+        dialog.setup(self.disks)
+        rc = self.run_lightbox_dialog(dialog)
+
+        # update the UI to reflect changes to self.data.ignoredisk.onlyuse
+        overviews = self.builder.get_object("local_disks_box").get_children()
+        for overview in overviews:
+            name = overview.get_property("popup-info").partition("|")[0].strip()
+
+            overview.set_selected(name in self.data.ignoredisk.onlyuse)
+        self._update_summary()
+
+    def run_lightbox_dialog(self, dialog):
+        lightbox = AnacondaWidgets.lb_show_over(self.window)
+        dialog.window.set_transient_for(lightbox)
+        rc = dialog.run()
+        lightbox.destroy()
+        return rc
+
+    def on_continue_clicked(self, button):
+        # show the installation options dialog
+        disks = [d for d in self.disks if d.name in self.data.ignoredisk.onlyuse]
+        (disk_free, fs_free) = get_free_space_info(disks, self.devicetree)
+        required_space = 12000      # TODO: find out where to get this
+        if disk_free >= required_space:
+            dialog = InstallOptions1Dialog(self.data)
+        elif sum([d.size for d in disks]) >= required_space:
+            dialog = InstallOptions2Dialog(self.data)
+        else:
+            dialog = InstallOptions3Dialog(self.data)
+
+        dialog.setup(required_space, disk_free, fs_free)
+        rc = self.run_lightbox_dialog(dialog)
+        if rc == dialog.RESPONSE_CONTINUE:
+            # depending on custom/autopart, either set up autopart or show
+            # custom partitioning ui
+            print "user chose to continue to partitioning (custom is %s)" % dialog.customize_state
+            Gtk.main_quit()
+        elif rc == dialog.RESPONSE_CANCEL:
+            # stay on this spoke
+            print "user chose to continue disk selection"
+            pass
+        elif rc == dialog.RESPONSE_MODIFY_SW:
+            # go to software spoke
+            print "user chose to modify software selection"
+            Gtk.main_quit()
+            pass
+        elif rc == dialog.RESPONSE_RECLAIM:
+            # go to tug-of-war
+            print "user chose to reclaim space"
+            Gtk.main_quit()
+            pass
+        elif rc == dialog.RESPONSE_QUIT:
+            raise SystemExit("user-selected exit")
+
+    def on_add_disk_clicked(self, button):
+        print "ADD DISK CLICKED"
+
+    def on_back_clicked(self, window):
+        self.window.hide()
+        Gtk.main_quit()
diff --git a/pyanaconda/ui/gui/spokes/storage.ui b/pyanaconda/ui/gui/spokes/storage.ui
new file mode 100644
index 0000000..c36124d
--- /dev/null
+++ b/pyanaconda/ui/gui/spokes/storage.ui
@@ -0,0 +1,995 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.0 -->
+  <!-- interface-requires AnacondaWidgets 1.0 -->
+  <object class="GtkListStore" id="disk_store">
+    <columns>
+      <!-- column-name Description -->
+      <column type="gchararray"/>
+      <!-- column-name capacity -->
+      <column type="gchararray"/>
+      <!-- column-name free -->
+      <column type="gchararray"/>
+      <!-- column-name id -->
+      <column type="gchararray"/>
+    </columns>
+  </object>
+  <object class="GtkDialog" id="options1_dialog">
+    <property name="width_request">500</property>
+    <property name="height_request">200</property>
+    <property name="can_focus">False</property>
+    <property name="border_width">5</property>
+    <property name="type">popup</property>
+    <property name="modal">True</property>
+    <property name="window_position">center-on-parent</property>
+    <property name="destroy_with_parent">True</property>
+    <property name="type_hint">dialog</property>
+    <property name="mnemonics_visible">False</property>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="dialog-vbox2">
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">6</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area2">
+            <property name="can_focus">False</property>
+            <child>
+              <object class="GtkButton" id="options1_cancel_button">
+                <property name="label" translatable="yes">Cancel &amp; _add more disks</property>
+                <property name="use_action_appearance">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="halign">center</property>
+                <property name="border_width">6</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_underline">True</property>
+                <signal name="clicked" handler="on_cancel_clicked" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="options_continue_button1">
+                <property name="label" translatable="yes">_Continue</property>
+                <property name="use_action_appearance">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="halign">center</property>
+                <property name="border_width">6</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_underline">True</property>
+                <signal name="clicked" handler="on_continue_clicked" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="pack_type">end</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="box4">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">6</property>
+            <child>
+              <object class="GtkLabel" id="options1_title_label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">INSTALLATION OPTIONS</property>
+                <attributes>
+                  <attribute name="weight" value="bold"/>
+                </attributes>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="options1_label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">Here we'll describe what your options are.</property>
+                <property name="use_markup">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkCheckButton" id="options1_custom_check">
+                <property name="label" translatable="yes">Let me _review &amp; customize the partitioning of the disks anyway.</property>
+                <property name="use_action_appearance">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_underline">True</property>
+                <property name="xalign">0</property>
+                <property name="draw_indicator">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="pack_type">end</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="0">options1_cancel_button</action-widget>
+      <action-widget response="1">options_continue_button1</action-widget>
+    </action-widgets>
+  </object>
+  <object class="GtkDialog" id="options2_dialog">
+    <property name="width_request">600</property>
+    <property name="height_request">400</property>
+    <property name="can_focus">False</property>
+    <property name="border_width">5</property>
+    <property name="type">popup</property>
+    <property name="modal">True</property>
+    <property name="window_position">center-on-parent</property>
+    <property name="destroy_with_parent">True</property>
+    <property name="type_hint">dialog</property>
+    <property name="mnemonics_visible">False</property>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="dialog-vbox5">
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">6</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area5">
+            <property name="can_focus">False</property>
+            <child>
+              <object class="GtkButton" id="options2_cancel_button">
+                <property name="label" translatable="yes">Cancel &amp; _add more disks</property>
+                <property name="use_action_appearance">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="halign">center</property>
+                <property name="border_width">6</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_underline">True</property>
+                <signal name="clicked" handler="on_cancel_clicked" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="options2_modify_sw_button">
+                <property name="label" translatable="yes">_Modify software selection</property>
+                <property name="use_action_appearance">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="halign">center</property>
+                <property name="border_width">6</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_underline">True</property>
+                <signal name="clicked" handler="on_modify_sw_clicked" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="pack_type">end</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="options2_reclaim_button">
+                <property name="label" translatable="yes">Reclaim _space</property>
+                <property name="use_action_appearance">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="halign">center</property>
+                <property name="border_width">6</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_underline">True</property>
+                <signal name="clicked" handler="on_reclaim_clicked" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="box5">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">6</property>
+            <child>
+              <object class="GtkLabel" id="options2_title_label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">INSTALLATION OPTIONS</property>
+                <attributes>
+                  <attribute name="weight" value="bold"/>
+                </attributes>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkCheckButton" id="options2_custom_check">
+                <property name="label" translatable="yes">I don't need help; let me _review &amp; customize disk partitioning to reclaim space.</property>
+                <property name="use_action_appearance">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_underline">True</property>
+                <property name="xalign">0</property>
+                <property name="draw_indicator">True</property>
+                <signal name="toggled" handler="on_custom_toggled" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="pack_type">end</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="options2_label1">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">Here we'll describe how much space is needed for the current software selection.</property>
+                <property name="use_markup">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkGrid" id="grid1">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="row_spacing">6</property>
+                <property name="column_spacing">6</property>
+                <property name="row_homogeneous">True</property>
+                <child>
+                  <object class="GtkLabel" id="options2_disk_free_label">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">disk free</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">0</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="options2_disk_free_desc_label">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">Free space available for use.</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">0</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="options2_fs_free_label">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">fs free</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">1</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="options2_fs_free_desc_label">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">Free space unavailable but reclaimable from existing partitions.</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">1</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">3</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="options2_label2">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">Here we'll describe what your options are.</property>
+                <property name="use_markup">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">4</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="0">options2_cancel_button</action-widget>
+      <action-widget response="2">options2_modify_sw_button</action-widget>
+      <action-widget response="3">options2_reclaim_button</action-widget>
+    </action-widgets>
+  </object>
+  <object class="GtkDialog" id="options3_dialog">
+    <property name="width_request">400</property>
+    <property name="height_request">300</property>
+    <property name="can_focus">False</property>
+    <property name="border_width">5</property>
+    <property name="type">popup</property>
+    <property name="modal">True</property>
+    <property name="window_position">center-on-parent</property>
+    <property name="destroy_with_parent">True</property>
+    <property name="type_hint">dialog</property>
+    <property name="mnemonics_visible">False</property>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="dialog-vbox7">
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">6</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area7">
+            <property name="can_focus">False</property>
+            <child>
+              <object class="GtkButton" id="options3_quit_button">
+                <property name="label" translatable="yes">_Quit installer</property>
+                <property name="use_action_appearance">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="halign">center</property>
+                <property name="border_width">6</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_underline">True</property>
+                <signal name="clicked" handler="on_quit_clicked" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="options3_modify_sw_button">
+                <property name="label" translatable="yes">_Modify software selection</property>
+                <property name="use_action_appearance">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="halign">center</property>
+                <property name="border_width">6</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_underline">True</property>
+                <signal name="clicked" handler="on_modify_sw_clicked" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="pack_type">end</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="options3_cancel_button">
+                <property name="label" translatable="yes">_Cancel</property>
+                <property name="use_action_appearance">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="halign">center</property>
+                <property name="border_width">6</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_underline">True</property>
+                <signal name="clicked" handler="on_cancel_clicked" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="pack_type">end</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="box6">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">6</property>
+            <child>
+              <object class="GtkLabel" id="options3_title_label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">INSTALLATION OPTIONS</property>
+                <attributes>
+                  <attribute name="weight" value="bold"/>
+                </attributes>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="options3_label1">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">Here we'll describe how much space is needed for the current software selection.</property>
+                <property name="use_markup">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkGrid" id="grid2">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="row_spacing">6</property>
+                <property name="column_spacing">6</property>
+                <property name="row_homogeneous">True</property>
+                <child>
+                  <object class="GtkLabel" id="options3_disk_free_label">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">disk free</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">0</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="options3_disk_free_desc_label1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">Free space available for use.</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">0</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="options3_fs_free_label">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">fs free</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">1</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="options3_fs_free_desc_label">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">Free space unavailable but reclaimable from existing partitions.</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="top_attach">1</property>
+                    <property name="width">1</property>
+                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+                <child>
+                  <placeholder/>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="options3_label2">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">Here we'll describe what your options are.</property>
+                <property name="use_markup">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">3</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="4">options3_quit_button</action-widget>
+      <action-widget response="2">options3_modify_sw_button</action-widget>
+      <action-widget response="0">options3_cancel_button</action-widget>
+    </action-widgets>
+  </object>
+  <object class="GtkDialog" id="selected_disks_dialog">
+    <property name="width_request">500</property>
+    <property name="height_request">400</property>
+    <property name="can_focus">False</property>
+    <property name="border_width">5</property>
+    <property name="type">popup</property>
+    <property name="title" translatable="yes">SELECTED DISKS</property>
+    <property name="modal">True</property>
+    <property name="window_position">center-on-parent</property>
+    <property name="destroy_with_parent">True</property>
+    <property name="type_hint">dialog</property>
+    <property name="mnemonics_visible">False</property>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="dialog-vbox1">
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">6</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area1">
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="close_button">
+                <property name="label">_Close</property>
+                <property name="use_action_appearance">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="halign">center</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_underline">True</property>
+                <signal name="clicked" handler="on_close_clicked" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="box3">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">6</property>
+            <child>
+              <object class="GtkLabel" id="label4">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">SELECTED DISKS</property>
+                <attributes>
+                  <attribute name="weight" value="bold"/>
+                </attributes>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkTreeView" id="disk_tree_view">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="model">disk_store</property>
+                <child internal-child="selection">
+                  <object class="GtkTreeSelection" id="disk_selection">
+                    <signal name="changed" handler="on_selection_changed" swapped="no"/>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkTreeViewColumn" id="description_column">
+                    <property name="spacing">6</property>
+                    <property name="title" translatable="yes">Description</property>
+                    <property name="clickable">True</property>
+                    <child>
+                      <object class="GtkCellRendererText" id="description_renderer"/>
+                      <attributes>
+                        <attribute name="text">0</attribute>
+                      </attributes>
+                    </child>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkTreeViewColumn" id="capacity_column">
+                    <property name="spacing">6</property>
+                    <property name="title" translatable="yes">Capacity</property>
+                    <property name="clickable">True</property>
+                    <child>
+                      <object class="GtkCellRendererText" id="capacity_renderer"/>
+                      <attributes>
+                        <attribute name="text">1</attribute>
+                      </attributes>
+                    </child>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkTreeViewColumn" id="free_column">
+                    <property name="spacing">6</property>
+                    <property name="title" translatable="yes">Free</property>
+                    <child>
+                      <object class="GtkCellRendererText" id="free_renderer"/>
+                      <attributes>
+                        <attribute name="text">2</attribute>
+                      </attributes>
+                    </child>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkTreeViewColumn" id="id_column">
+                    <property name="spacing">6</property>
+                    <property name="title" translatable="yes">Id</property>
+                    <child>
+                      <object class="GtkCellRendererText" id="id_renderer"/>
+                      <attributes>
+                        <attribute name="text">3</attribute>
+                      </attributes>
+                    </child>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButtonBox" id="buttonbox1">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="spacing">6</property>
+                <property name="layout_style">start</property>
+                <child>
+                  <object class="GtkButton" id="remove_button">
+                    <property name="label">_Remove</property>
+                    <property name="use_action_appearance">False</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="halign">center</property>
+                    <property name="use_action_appearance">False</property>
+                    <property name="use_underline">True</property>
+                    <signal name="clicked" handler="on_remove_clicked" swapped="no"/>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="summary_label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">Disk summary goes here</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="pack_type">end</property>
+                <property name="position">3</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="0">close_button</action-widget>
+    </action-widgets>
+  </object>
+  <object class="GtkListStore" id="specialized_disk_store">
+    <columns>
+      <!-- column-name disk -->
+      <column type="GObject"/>
+    </columns>
+  </object>
+  <object class="AnacondaSpokeWindow" id="storageWindow">
+    <property name="startup_id">filler</property>
+    <property name="can_focus">False</property>
+    <property name="border_width">6</property>
+    <property name="startup_id">filler</property>
+    <property name="mnemonics_visible">False</property>
+    <child internal-child="main_box">
+      <object class="GtkBox" id="AnacondaSpokeWindow-main_box1">
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">6</property>
+        <child internal-child="nav_area">
+          <object class="GtkGrid" id="AnacondaSpokeWindow-nav_area1">
+            <property name="can_focus">False</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child internal-child="alignment">
+          <object class="GtkAlignment" id="AnacondaSpokeWindow-alignment1">
+            <property name="can_focus">False</property>
+            <property name="yalign">0</property>
+            <property name="xscale">0.9</property>
+            <property name="yscale">0.5</property>
+            <child internal-child="action_area">
+              <object class="GtkBox" id="storageWindow-action_area1">
+                <property name="can_focus">False</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">6</property>
+                <child>
+                  <object class="GtkLabel" id="label1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">LOCAL STANDARD DISKS</property>
+                    <property name="track_visited_links">False</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkScrolledWindow" id="scrolledwindow1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="hexpand">True</property>
+                    <property name="vscrollbar_policy">never</property>
+                    <property name="shadow_type">in</property>
+                    <child>
+                      <object class="GtkViewport" id="viewport1">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <child>
+                          <object class="GtkBox" id="local_disks_box">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="spacing">6</property>
+                            <property name="homogeneous">True</property>
+                            <child>
+                              <placeholder/>
+                            </child>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">3</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="box2">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="spacing">6</property>
+            <child>
+              <object class="GtkButton" id="summary_button">
+                <property name="label" translatable="yes">summary</property>
+                <property name="use_action_appearance">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_action_appearance">False</property>
+                <property name="relief">none</property>
+                <property name="use_underline">True</property>
+                <property name="focus_on_click">False</property>
+                <property name="xalign">0</property>
+                <signal name="clicked" handler="on_summary_clicked" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="continue_button">
+                <property name="label" translatable="yes">_Continue</property>
+                <property name="use_action_appearance">False</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_action_appearance">False</property>
+                <property name="use_underline">True</property>
+                <property name="xalign">1</property>
+                <signal name="clicked" handler="on_continue_clicked" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="pack_type">end</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">4</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>
-- 
1.7.8

_______________________________________________
Anaconda-devel-list mailing list
Anaconda-devel-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/anaconda-devel-list


[Index of Archives]     [Kickstart]     [Fedora Users]     [Fedora Legacy List]     [Fedora Maintainers]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [Yosemite Photos]     [KDE Users]     [Fedora Tools]
  Powered by Linux