# Disk shopping cart # # Copyright (C) 2011, 2012 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 # Chris Lumens # from gi.repository import Gtk from pyanaconda.i18n import _, P_ from pyanaconda.ui.lib.disks import size_str from pyanaconda.ui.gui import GUIObject from blivet.size import Size __all__ = ["SelectedDisksDialog"] IS_BOOT_COL = 0 DESCRIPTION_COL = 1 SIZE_COL = 2 FREE_SPACE_COL = 3 NAME_COL = 4 ID_COL = 5 class SelectedDisksDialog(GUIObject): builderObjects = ["selected_disks_dialog", "disk_store", "disk_tree_view"] mainWidgetName = "selected_disks_dialog" uiFile = "spokes/lib/cart.glade" def __init__(self, data): GUIObject.__init__(self, data) self._view = self.builder.get_object("disk_tree_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") self._set_button = self.builder.get_object("set_as_boot_button") self._remove_button = self.builder.get_object("remove_button") # pylint: disable-msg=W0221 def initialize(self, disks, free, showRemove=True, setBoot=True): self._previousID = None for disk in disks: self._store.append([False, "%s (%s)" % (disk.description, disk.serial), size_str(disk.size), size_str(free[disk.name][0]), disk.name, disk.id]) self.disks = disks[:] self._update_summary() if not showRemove: self.builder.get_object("remove_button").hide() if not setBoot: self._set_button.hide() if not disks: return # Don't select a boot device if no boot device is asked for. if self.data.bootloader.location == "none": return # Set up the default boot device. Use what's in the ksdata if anything, # then fall back to the first device. default_id = None if self.data.bootloader.bootDrive: for d in self.disks: if d.name == self.data.bootloader.bootDrive: default_id = d.id if not default_id: default_id = self.disks[0].id # And then select it in the UI. for row in self._store: if row[ID_COL] == default_id: self._previousID = row[ID_COL] row[IS_BOOT_COL] = True break # pylint: disable-msg=W0221 def refresh(self, disks, free, showRemove=True, setBoot=True): super(SelectedDisksDialog, self).refresh() # clear out the store and repopulate it from the devicetree self._store.clear() self.initialize(disks, free, showRemove=showRemove, setBoot=setBoot) 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(): selected_paths = self._selection.get_selected_rows()[1] selected_refs = [Gtk.TreeRowReference() for _p in selected_paths] return selected_refs def _update_summary(self): count = 0 size = 0 free = 0 for row in self._store: count += 1 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() text = P_("%(count)d disk; %(size)s capacity; %(free)s free space " "(unpartitioned and in filesystems)", "%(count)d disks; %(size)s capacity; %(free)s free space " "(unpartitioned and in filesystems)", count) % {"count" : count, "size" : size, "free" : free} self._summary_label.set_markup(text) # signal handlers def on_remove_clicked(self, button): itr = self._selection.get_selected()[1] if not itr: return disk = None for d in self.disks: if d.id == self._store[itr][ID_COL]: disk = d break 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] # 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._update_summary() # If no disks are available in the cart anymore, grey out the buttons. self._set_button.set_sensitive(len(self._store) > 0) self._remove_button.set_sensitive(len(self._store) > 0) def on_close_clicked(self, button): # Save the boot device setting, if something was selected. for row in self._store: if row[IS_BOOT_COL]: for disk in self.disks: if disk.id == row[ID_COL]: self.data.bootloader.bootDrive = disk.name self.data.bootloader.location = "mbr" return # No device was selected. The user does not want to install # a bootloader. self.data.bootloader.bootDrive = "" self.data.bootloader.location = "none" def _toggle_button_text(self, row): if row[IS_BOOT_COL]: self._set_button.set_label(_("_Do not install bootloader")) else: self._set_button.set_label(_("_Set as Boot Device")) def on_selection_changed(self, *args): itr = self._selection.get_selected()[1] if not itr: return self._toggle_button_text(self._store[itr]) def on_set_as_boot_clicked(self, button): itr = self._selection.get_selected()[1] if not itr: return # There's only two cases: if self._store[itr][ID_COL] == self._previousID: # Either the user clicked on the device they'd previously selected, # in which case we are just toggling here. self._store[itr][IS_BOOT_COL] = not self._store[itr][IS_BOOT_COL] else: # Or they clicked on a different device. First we unselect the # previously selected device. for row in self._store: if row[ID_COL] == self._previousID: row[IS_BOOT_COL] = False break # Then we select the new row. self._store[itr][IS_BOOT_COL] = True self._previousID = self._store[itr][ID_COL] self._toggle_button_text(self._store[itr])