#
# 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