We don't want people to be able to deselect these devices, but we still want to show them. Not showing them leads to a variety of annoying hacks and has the unpleasant side effect of having previously hidden devices suddenly show up in later UI screens. --- iw/DeviceSelector.py | 15 +++++++++++- iw/filter_gui.py | 58 ++++++++++++++++++++++++++++++++----------------- 2 files changed, 51 insertions(+), 22 deletions(-) diff --git a/iw/DeviceSelector.py b/iw/DeviceSelector.py index 7669ca8..e9b8c7a 100644 --- a/iw/DeviceSelector.py +++ b/iw/DeviceSelector.py @@ -36,6 +36,11 @@ OBJECT_COL = 0 VISIBLE_COL = 1 ACTIVE_COL = 2 +# This should not be overridden. It controls whether or not a row may be +# deselected. Rows with this column set will stay in selected or not +# (whichever they were initialized to) permanently. +IMMUTABLE_COL = 3 + class DeviceDisplayer(object): def _column_toggled(self, menuItem, col): # This is called when a selection is made in the column visibility drop @@ -160,8 +165,8 @@ class DeviceSelector(DeviceDisplayer): # Don't check the boxes of rows that aren't visible or aren't part # of the currently displayed page. We'd like the all button to # only operate on the current page, after all. - if not model[path][self.visible] or \ - (membershipCB and not membershipCB(model[path][OBJECT_COL])): + if not model[path][self.visible] or model[path][IMMUTABLE_COL] or \ + (membershipCB and not membershipCB(model[path][OBJECT_COL])): return # Don't try to set a row to active if it's already been checked. @@ -196,6 +201,9 @@ class DeviceSelector(DeviceDisplayer): # to uncheck everything in the store, then we check the one that # was clicked on. for r in self.store: + if self.store[storeRow][IMMUTABLE_COL]: + return + r[self.active] = False self.store[storeRow][self.active] = True @@ -203,6 +211,9 @@ class DeviceSelector(DeviceDisplayer): if cb: cb(True, self.store[storeRow][OBJECT_COL]) else: + if self.store[storeRow][IMMUTABLE_COL]: + return + is_checked = self.store[storeRow][self.active] self.store[storeRow][self.active] = not is_checked diff --git a/iw/filter_gui.py b/iw/filter_gui.py index f29b4af..43ec243 100644 --- a/iw/filter_gui.py +++ b/iw/filter_gui.py @@ -29,6 +29,7 @@ from DeviceSelector import * from baseudev import * from constants import * from iw_gui import * +from storage.devices import devicePathToName from storage.udev import * from storage.devicelibs.mpath import * import storage.iscsi @@ -38,17 +39,17 @@ import storage.zfcp import gettext _ = lambda x: gettext.ldgettext("anaconda", x) -DEVICE_COL = 3 -MODEL_COL = 4 -CAPACITY_COL = 5 -VENDOR_COL = 6 -INTERCONNECT_COL = 7 -SERIAL_COL = 8 -ID_COL = 9 -PATHS_COL = 10 -PORT_COL = 11 -TARGET_COL = 12 -LUN_COL = 13 +DEVICE_COL = 4 +MODEL_COL = 5 +CAPACITY_COL = 6 +VENDOR_COL = 7 +INTERCONNECT_COL = 8 +SERIAL_COL = 9 +ID_COL = 10 +PATHS_COL = 11 +PORT_COL = 12 +TARGET_COL = 13 +LUN_COL = 14 # This is kind of a magic class that is used for populating the device store. # It mostly acts like a list except for some funny behavior on adding/getting. @@ -147,7 +148,7 @@ class Callbacks(object): # visibility function, though they should also take a look at this # one to see what the model says. return self.isMember(model.get_value(iter, OBJECT_COL)) and \ - model.get_value(iter, 1) + model.get_value(iter, VISIBLE_COL) class RAIDCallbacks(Callbacks): def isMember(self, info): @@ -302,7 +303,7 @@ class SearchCallbacks(FilteredCallbacks): return True def visible(self, model, iter, view): - if not model.get_value(iter, 1): + if not model.get_value(iter, VISIBLE_COL): return False if self.filtering: @@ -526,11 +527,12 @@ class FilterWindow(InstallWindow): # unused much of the time. Oh well. # Object, - # visible, active (checked), + # visible, active (checked), immutable, # device, model, capacity, vendor, interconnect, serial number, wwid # paths, port, target, lun self.store = gtk.TreeStore(gobject.TYPE_PYOBJECT, gobject.TYPE_BOOLEAN, gobject.TYPE_BOOLEAN, + gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, @@ -614,11 +616,27 @@ class FilterWindow(InstallWindow): totalDevices += 1 totalSize += tuple[0]["XXX_SIZE"] - if tuple[2]: + if tuple[ACTIVE_COL]: selectedDevices += 1 selectedSize += tuple[0]["XXX_SIZE"] - def _active(name): + def _isProtected(info): + protectedNames = map(udev_resolve_devspec, self.anaconda.protected) + + sysfs_path = udev_device_get_sysfs_path(info) + for protected in protectedNames: + _p = "/sys/%s/%s" % (sysfs_path, protected) + if os.path.exists(os.path.normpath(_p)): + return True + + return False + + def _active(info): + if _isProtected(info): + return True + + name = udev_device_get_name(info) + if self.anaconda.storage.exclusiveDisks and \ name in self.anaconda.storage.exclusiveDisks: return True @@ -653,7 +671,7 @@ class FilterWindow(InstallWindow): else: ident = udev_device_get_wwid(d) - tuple = (d, True, _active(name), name, + tuple = (d, True, _active(d), _isProtected(d), name, partedDevice.model, str(d["XXX_SIZE"]) + " MB", udev_device_get_vendor(d), udev_device_get_bus(d), udev_device_get_serial(d), ident, "", "", "", "") @@ -686,8 +704,8 @@ class FilterWindow(InstallWindow): "name": rs.name} model = "BIOS RAID set (%s)" % rs.rs.set_type - tuple = (data, True, _active(rs.name), rs.name, model, - str(size) + " MB", "", "", "", "", "", "", "", "") + tuple = (data, True, _active(rs.name), _isProtected(d), rs.name, + model, str(size) + " MB", "", "", "", "", "", "", "", "") _addTuple(tuple) rs.deactivate() @@ -713,7 +731,7 @@ class FilterWindow(InstallWindow): # However, we do need all the paths making up this multipath set. paths = "\n".join(map(udev_device_get_name, mpath)) - tuple = (mpath[0], True, _active(name), + tuple = (mpath[0], True, _active(mpath[0]), _isProtected(mpath[0]), udev_device_get_multipath_name(mpath[0]), model, str(mpath[0]["XXX_SIZE"]) + " MB", udev_device_get_vendor(mpath[0]), -- 1.6.5.1 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list