[PATCH 2/2] Add a column to the disk shopping cart for setting the boot device (#860430).

Chris Lumens clumens at redhat.com
Thu Oct 4 16:19:58 UTC 2012


---
 pyanaconda/ui/gui/spokes/lib/cart.glade | 71 +++++++++++++++++++++------
 pyanaconda/ui/gui/spokes/lib/cart.py    | 86 ++++++++++++++++++++++++---------
 pyanaconda/ui/gui/spokes/storage.py     |  2 +-
 3 files changed, 122 insertions(+), 37 deletions(-)

diff --git a/pyanaconda/ui/gui/spokes/lib/cart.glade b/pyanaconda/ui/gui/spokes/lib/cart.glade
index bb45172..c2334ee 100644
--- a/pyanaconda/ui/gui/spokes/lib/cart.glade
+++ b/pyanaconda/ui/gui/spokes/lib/cart.glade
@@ -1,9 +1,10 @@
 <?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 isBootDisk -->
+      <column type="gboolean"/>
       <!-- column-name Description -->
       <column type="gchararray"/>
       <!-- column-name capacity -->
@@ -104,6 +105,19 @@
                           <object class="GtkTreeSelection" id="disk_selection"/>
                         </child>
                         <child>
+                          <object class="GtkTreeViewColumn" id="boot_column">
+                            <property name="title" translatable="yes">Boot</property>
+                            <child>
+                              <object class="GtkCellRendererPixbuf" id="boot_renderer">
+                                <property name="stock_id">gtk-apply</property>
+                              </object>
+                              <attributes>
+                                <attribute name="visible">0</attribute>
+                              </attributes>
+                            </child>
+                          </object>
+                        </child>
+                        <child>
                           <object class="GtkTreeViewColumn" id="description_column">
                             <property name="spacing">6</property>
                             <property name="title" translatable="yes">Description</property>
@@ -111,7 +125,7 @@
                             <child>
                               <object class="GtkCellRendererText" id="description_renderer"/>
                               <attributes>
-                                <attribute name="text">0</attribute>
+                                <attribute name="text">1</attribute>
                               </attributes>
                             </child>
                           </object>
@@ -124,7 +138,7 @@
                             <child>
                               <object class="GtkCellRendererText" id="capacity_renderer"/>
                               <attributes>
-                                <attribute name="text">1</attribute>
+                                <attribute name="text">2</attribute>
                               </attributes>
                             </child>
                           </object>
@@ -136,7 +150,7 @@
                             <child>
                               <object class="GtkCellRendererText" id="free_renderer"/>
                               <attributes>
-                                <attribute name="text">2</attribute>
+                                <attribute name="text">3</attribute>
                               </attributes>
                             </child>
                           </object>
@@ -148,7 +162,7 @@
                             <child>
                               <object class="GtkCellRendererText" id="id_renderer"/>
                               <attributes>
-                                <attribute name="text">3</attribute>
+                                <attribute name="text">4</attribute>
                               </attributes>
                             </child>
                           </object>
@@ -165,16 +179,45 @@
               </packing>
             </child>
             <child>
-              <object class="GtkButton" id="remove_button">
-                <property name="label">_Remove</property>
-                <property name="use_action_appearance">False</property>
+              <object class="GtkBox" id="box1">
                 <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="halign">start</property>
-                <property name="use_action_appearance">False</property>
-                <property name="use_underline">True</property>
-                <signal name="clicked" handler="on_remove_clicked" swapped="no"/>
+                <property name="can_focus">False</property>
+                <property name="spacing">12</property>
+                <child>
+                  <object class="GtkButton" id="set_as_boot_button">
+                    <property name="label" translatable="yes">_Set as Boot Device</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>
+                    <signal name="clicked" handler="on_set_as_boot_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="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">start</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">1</property>
+                  </packing>
+                </child>
               </object>
               <packing>
                 <property name="expand">False</property>
diff --git a/pyanaconda/ui/gui/spokes/lib/cart.py b/pyanaconda/ui/gui/spokes/lib/cart.py
index 2c1f025..b3d437c 100644
--- a/pyanaconda/ui/gui/spokes/lib/cart.py
+++ b/pyanaconda/ui/gui/spokes/lib/cart.py
@@ -31,6 +31,13 @@ P_ = lambda x, y, z: gettext.ldngettext("anaconda", x, y, z)
 
 __all__ = ["SelectedDisksDialog"]
 
+IS_BOOT_COL = 0
+DESCRIPTION_COL = 1
+SIZE_COL = 2
+FREE_SPACE_COL = 3
+SERIAL_COL = 4
+ID_COL = 5
+
 def size_str(mb):
     if isinstance(mb, Size):
         spec = str(mb)
@@ -44,9 +51,14 @@ class SelectedDisksDialog(GUIObject):
     mainWidgetName = "selected_disks_dialog"
     uiFile = "spokes/lib/cart.glade"
 
+    def __init__(self, data, storage):
+        GUIObject.__init__(self, data)
+        self.storage = storage
+
     def initialize(self, disks, free, showRemove=True):
         for disk in disks:
-            self._store.append([disk.description,
+            self._store.append([False,
+                                disk.description,
                                 size_str(disk.size),
                                 size_str(free[disk.name][0]),
                                 disk.serial,
@@ -57,6 +69,19 @@ class SelectedDisksDialog(GUIObject):
         if not showRemove:
             self.builder.get_object("remove_button").hide()
 
+        # Set up the default boot device.  Use what's in the ksdata if anything,
+        # then fall back to the first device.
+        if self.data.bootloader.bootDrive:
+            dev = self.storage.devicetree.getDeviceByName(self.data.bootloader.bootDrive)
+            default_id = dev.id
+        else:
+            default_id = self.storage.disks[0].id
+
+        for row in self._store:
+            if row[ID_COL] == default_id:
+                row[IS_BOOT_COL] = True
+                break
+
     def refresh(self, disks, free, showRemove=True):
         super(SelectedDisksDialog, self).refresh()
 
@@ -88,8 +113,8 @@ class SelectedDisksDialog(GUIObject):
         free = 0
         for row in self._store:
             count += 1
-            size += Size(spec=row[1])
-            free += Size(spec=row[2])
+            size += Size(spec=row[SIZE_COL])
+            free += Size(spec=row[FREE_SPACE_COL])
 
         size = str(Size(bytes=long(size))).upper()
         free = str(Size(bytes=long(free))).upper()
@@ -103,31 +128,48 @@ class SelectedDisksDialog(GUIObject):
 
     # signal handlers
     def on_remove_clicked(self, button):
-        # 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:
-            disk = None
-            for d in self.disks:
-                if d.id == self._store[itr][4]:
-                    disk = d
-                    break
+        if not itr:
+            return
+
+        disk = self.storage.devicetree.getDeviceByID(self._store[itr][ID_COL])
+        if not disk:
+            return
+
+        # If this disk was marked as the boot device, just change to the first one
+        # instead.
+        resetBootDevice = self._store[itr][IS_BOOT_COL]
 
-            if not disk:
-                return
+        # remove the selected disk(s) from the list and update the summary label
+        self._store.remove(itr)
+        self.disks.remove(disk)
+
+        if resetBootDevice and len(self._store) > 0:
+            self._store[0][IS_BOOT_COL] = True
 
-            self._store.remove(itr)
-            self.disks.remove(disk)
-            self._update_summary()
+        self._update_summary()
 
     def on_close_clicked(self, button):
-        print "CLOSE CLICKED"
+        # Save the boot device setting.
+        for row in self._store:
+            if row[IS_BOOT_COL]:
+                dev = self.storage.devicetree.getDeviceByID(row[ID_COL])
+                self.data.bootloader.bootDrive = dev.name
+                break
 
     def on_selection_changed(self, *args):
         model, itr = self._selection.get_selected()
         if itr:
-            print "new selection: %s" % model.get_value(itr, 3)
+            print "new selection: %s" % model.get_value(itr, SERIAL_COL)
+
+    def on_set_as_boot_clicked(self, button):
+        model, itr = self._selection.get_selected()
+        if not itr:
+            return
+
+        # First make sure the previous device is unselected.
+        for row in self._store:
+            row[IS_BOOT_COL] = False
+
+        # Now set the currently selected device to be the boot target.
+        self._store[itr][IS_BOOT_COL] = True
diff --git a/pyanaconda/ui/gui/spokes/storage.py b/pyanaconda/ui/gui/spokes/storage.py
index 3deeae2..ac19c9b 100644
--- a/pyanaconda/ui/gui/spokes/storage.py
+++ b/pyanaconda/ui/gui/spokes/storage.py
@@ -516,7 +516,7 @@ class StorageSpoke(NormalSpoke, StorageChecker):
         # show the selected disks dialog
         # pass in our disk list so hidden disks' free space is available
         free_space = self.storage.getFreeSpace(disks=self.disks)
-        dialog = SelectedDisksDialog(self.data,)
+        dialog = SelectedDisksDialog(self.data, self.storage)
         dialog.refresh([d for d in self.disks if d.name in self.selected_disks],
                        free_space)
         rc = self.run_lightbox_dialog(dialog)
-- 
1.7.11.2



More information about the anaconda-patches mailing list