# # partition_ui_helpers_gui.py: convenience functions for partition_gui.py # and friends. # # Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. # All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty 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, see . # # Author(s): Michael Fulbright # import gobject import gtk import checklist import datacombo import iutil from constants import * from fsset import * from partIntfHelpers import * from partRequests import * from partedUtils import * import gettext _ = lambda x: gettext.ldgettext("anaconda", x) def istruefalse(val): if val is None or not val: return False return True class WideCheckList(checklist.CheckList): def toggled_item(self, data, row): rc = True if self.clickCB: rc = self.clickCB(data, row) if rc == True: checklist.CheckList.toggled_item(self, data, row) def __init__(self, columns, store, clickCB=None): checklist.CheckList.__init__(self, columns=columns, custom_store=store) # make checkbox column wider column = self.get_column(columns) self.set_expander_column(column) column = self.get_column(0) column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) column.set_fixed_width(25) self.clickCB = clickCB def createAlignedLabel(text): label = gtk.Label(text) label.set_alignment(0.0, 0.5) label.set_property("use-underline", True) return label def createMountPointCombo(request, excludeMountPoints=[]): mountCombo = gtk.combo_box_entry_new_text() mntptlist = [] if request.type != REQUEST_NEW and request.fslabel: mntptlist.append(request.fslabel) idx = 0 for p in defaultMountPoints: if p in excludeMountPoints: continue if not p in mntptlist and (p[0] == "/"): mntptlist.append(p) map(mountCombo.append_text, mntptlist) mountpoint = request.mountpoint if request.fstype and request.fstype.isMountable(): mountCombo.set_sensitive(1) if mountpoint: mountCombo.get_children()[0].set_text(mountpoint) else: mountCombo.get_children()[0].set_text("") else: mountCombo.get_children()[0].set_text(_("")) mountCombo.set_sensitive(0) mountCombo.set_data("saved_mntpt", None) return mountCombo def setMntPtComboStateFromType(fstype, mountCombo): prevmountable = mountCombo.get_data("prevmountable") mountpoint = mountCombo.get_data("saved_mntpt") if prevmountable and fstype.isMountable(): return if fstype.isMountable(): mountCombo.set_sensitive(1) if mountpoint != None: mountCombo.get_children()[0].set_text(mountpoint) else: mountCombo.get_children()[0].set_text("") else: if mountCombo.get_children()[0].get_text() != _(""): mountCombo.set_data("saved_mntpt", mountCombo.get_children()[0].get_text()) mountCombo.get_children()[0].set_text(_("")) mountCombo.set_sensitive(0) mountCombo.set_data("prevmountable", fstype.isMountable()) def fstypechangeCB(widget, mountCombo): fstype = widget.get_active_value() setMntPtComboStateFromType(fstype, mountCombo) def createAllowedDrivesStore(disks, reqdrives, drivelist, selectDrives=True, disallowDrives=[]): drivelist.clear() drives = disks.keys() drives.sort() for drive in drives: size = getDeviceSizeMB(disks[drive].dev) selected = 0 if selectDrives: if reqdrives: if drive in reqdrives: selected = 1 else: if drive not in disallowDrives: selected = 1 sizestr = "%8.0f MB" % size drivelist.append_row((drive, sizestr, disks[drive].dev.model), selected) if len(disks.keys()) < 2: drivelist.set_sensitive(False) else: drivelist.set_sensitive(True) def createAllowedDrivesList(disks, reqdrives, selectDrives=True, disallowDrives=[]): store = gtk.TreeStore(gobject.TYPE_BOOLEAN, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING) drivelist = WideCheckList(3, store) createAllowedDrivesStore(disks, reqdrives, drivelist, selectDrives=selectDrives, disallowDrives=disallowDrives) return drivelist # pass in callback for when fs changes because of python scope issues def createFSTypeMenu(fstype, fstypechangeCB, mountCombo, availablefstypes = None, ignorefs = None): store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_PYOBJECT) fstypecombo = datacombo.DataComboBox(store) types = fileSystemTypeGetTypes() if availablefstypes: names = availablefstypes else: names = types.keys() if fstype and fstype.isSupported() and fstype.isFormattable(): default = fstype else: default = fileSystemTypeGetDefault() names.sort() defindex = 0 i = 0 for name in names: if not fileSystemTypeGet(name).isSupported(): continue if ignorefs and name in ignorefs: continue if fileSystemTypeGet(name).isFormattable(): fstypecombo.append(name, types[name]) if default and default.getName() == name: defindex = i defismountable = types[name].isMountable() i = i + 1 fstypecombo.set_active(defindex) if fstypechangeCB and mountCombo: fstypecombo.connect("changed", fstypechangeCB, mountCombo) if mountCombo: mountCombo.set_data("prevmountable", fstypecombo.get_active_value().isMountable()) mountCombo.connect("changed", mountptchangeCB, fstypecombo) return fstypecombo def mountptchangeCB(widget, fstypecombo): if iutil.isEfi() and widget.get_children()[0].get_text() == "/boot/efi": fstypecombo.set_active_text("efi") def resizeOptionCB(widget, resizesb): resizesb.set_sensitive(widget.get_active()) def formatOptionResizeCB(widget, resizesb): if widget.get_active(): lower = 1 else: lower = resizesb.get_data("reqlower") adj = resizesb.get_adjustment() adj.lower = lower resizesb.set_adjustment(adj) if resizesb.get_value_as_int() < lower: resizesb.set_value(adj.lower) def formatOptionCB(widget, data): (combowidget, mntptcombo, ofstype, lukscb) = data combowidget.set_sensitive(widget.get_active()) if lukscb is not None: lukscb.set_data("formatstate", widget.get_active()) if not widget.get_active(): # set "Encrypt" checkbutton to match partition's initial state lukscb.set_active(lukscb.get_data("encrypted")) lukscb.set_sensitive(0) else: lukscb.set_sensitive(1) # inject event for fstype menu if widget.get_active(): fstype = combowidget.get_active_value() setMntPtComboStateFromType(fstype, mntptcombo) combowidget.grab_focus() else: setMntPtComboStateFromType(ofstype, mntptcombo) def noformatCB(widget, data): (combowidget, mntptcombo, ofstype) = data combowidget.set_sensitive(not widget.get_active()) # inject event for fstype menu if widget.get_active(): setMntPtComboStateFromType(ofstype, mntptcombo) """ createPreExistFSOptionSection: given inputs for a preexisting partition, create a section that will provide format and migrate options Returns the value of row after packing into the maintable, and a dictionary consistenting of: noformatcb - checkbutton for 'format as new fs' fstype - part of format fstype menu fstypeMenu - part of format fstype menu migratecb - checkbutton for migrate fs migfstypeMenu - menu for migrate fs types lukscb - checkbutton for 'encrypt using LUKS/dm-crypt' resizecb - checkbutton for 'resize fs' resizesb - spinbutton with resize target """ def createPreExistFSOptionSection(origrequest, maintable, row, mountCombo, partitions, ignorefs=[]): rc = {} ofstype = origrequest.fstype formatcb = gtk.CheckButton(label=_("_Format as:")) maintable.attach(formatcb, 0, 1, row, row + 1) formatcb.set_active(istruefalse(origrequest.format)) rc["formatcb"] = formatcb fstypeCombo = createFSTypeMenu(ofstype, fstypechangeCB, mountCombo, ignorefs=ignorefs) fstypeCombo.set_sensitive(formatcb.get_active()) maintable.attach(fstypeCombo, 1, 2, row, row + 1) row += 1 rc["fstypeCombo"] = fstypeCombo if not formatcb.get_active() and not origrequest.migrate: mountCombo.set_data("prevmountable", ofstype.isMountable()) # this gets added to the table a bit later on lukscb = gtk.CheckButton(_("_Encrypt")) formatcb.connect("toggled", formatOptionCB, (fstypeCombo, mountCombo, ofstype, lukscb)) if origrequest.origfstype.isMigratable(): migratecb = gtk.CheckButton(label=_("Mi_grate filesystem to:")) migratecb.set_active(istruefalse(origrequest.migrate)) migtypes = origrequest.origfstype.getMigratableFSTargets() maintable.attach(migratecb, 0, 1, row, row + 1) migfstypeCombo = createFSTypeMenu(ofstype, None, None, availablefstypes = migtypes) migfstypeCombo.set_sensitive(migratecb.get_active()) maintable.attach(migfstypeCombo, 1, 2, row, row + 1) row = row + 1 rc["migratecb"] = migratecb rc["migfstypeCombo"] = migfstypeCombo migratecb.connect("toggled", formatOptionCB, (migfstypeCombo, mountCombo, ofstype, None)) else: migratecb = None migfstypeCombo = None if origrequest.isResizable(partitions): resizecb = gtk.CheckButton(label=_("_Resize")) resizecb.set_active(origrequest.targetSize is not None) rc["resizecb"] = resizecb maintable.attach(resizecb, 0, 1, row, row + 1) if origrequest.targetSize is not None: value = origrequest.targetSize else: value = origrequest.size reqlower = origrequest.getMinimumResizeMB(partitions) requpper = origrequest.getMaximumResizeMB(partitions) if not origrequest.format: lower = reqlower else: lower = 1 adj = gtk.Adjustment(value = value, lower = lower, upper = requpper, step_incr = 1) resizesb = gtk.SpinButton(adj, digits = 0) resizesb.set_property('numeric', True) resizesb.set_data("requpper", requpper) resizesb.set_data("reqlower", reqlower) rc["resizesb"] = resizesb maintable.attach(resizesb, 1, 2, row, row + 1) resizecb.connect('toggled', resizeOptionCB, resizesb) resizeOptionCB(resizecb, resizesb) row = row + 1 formatcb.connect("toggled", formatOptionResizeCB, resizesb) if origrequest.encryption: lukscb.set_active(1) lukscb.set_data("encrypted", 1) else: lukscb.set_data("encrypted", 0) lukscb.set_sensitive(formatcb.get_active()) lukscb.set_data("formatstate", formatcb.get_active()) rc["lukscb"] = lukscb maintable.attach(lukscb, 0, 2, row, row + 1) row = row + 1 return (row, rc) # do tests we just want in UI for now, not kickstart def doUIRAIDLVMChecks(request, diskset): fstype = request.fstype numdrives = len(diskset.disks.keys()) ## if fstype and fstype.getName() == "physical volume (LVM)": ## if request.grow: ## return (_("Partitions of type '%s' must be of fixed size, and " ## "cannot be marked to fill to use available space.")) % (fstype.getName(),) if fstype and fstype.getName() in ["physical volume (LVM)", "software RAID"]: if numdrives > 1 and (request.drive is None or len(request.drive) > 1): return (_("Partitions of type '%s' must be constrained to " "a single drive. To do this, select the " "drive in the 'Allowable Drives' checklist.")) % (fstype.getName(),) return None