#
# autopart_type.py: Allows the user to choose how they want to partition
#
# Copyright (C) 2005, 2006 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): Jeremy Katz
#
import gtk
import gobject
import math
from constants import *
import gui
from partition_ui_helpers_gui import *
from pixmapRadioButtonGroup_gui import pixmapRadioButtonGroup
from iw_gui import *
from flags import flags
from storage.deviceaction import *
import gettext
_ = lambda x: gettext.ldgettext("anaconda", x)
def whichToShrink(storage, intf):
def getActive(combo):
act = combo.get_active_iter()
return combo.get_model().get_value(act, 1)
def comboCB(combo, shrinkSB):
# partition to resize changed, let's update our spinbutton
newSize = shrinkSB.get_value_as_int()
part = getActive(combo)
reqlower = long(math.ceil(part.format.minSize))
requpper = long(math.floor(part.format.currentSize))
adj = shrinkSB.get_adjustment()
adj.lower = reqlower
adj.upper = requpper
adj.set_value(reqlower)
(dxml, dialog) = gui.getGladeWidget("autopart.glade", "shrinkDialog")
store = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_PYOBJECT)
combo = dxml.get_widget("shrinkPartCombo")
combo.set_model(store)
crt = gtk.CellRendererText()
combo.pack_start(crt, True)
combo.set_attributes(crt, text = 0)
combo.connect("changed", comboCB, dxml.get_widget("shrinkSB"))
biggest = -1
for part in storage.partitions:
if not part.exists:
continue
entry = None
if part.resizable and part.format.resizable:
entry = ("%s (%s, %d MB)" % (part.name,
part.format.name,
math.floor(part.format.size)),
part)
if entry:
i = store.append(None)
store[i] = entry
combo.set_active_iter(i)
if biggest == -1:
biggest = i
else:
current = store.get_value(biggest, 1)
if part.format.targetSize > current.format.targetSize:
biggest = i
if biggest > -1:
combo.set_active_iter(biggest)
if len(store) == 0:
dialog.destroy()
intf.messageWindow(_("Error"),
_("No partitions are available to resize. Only "
"physical partitions with specific filesystems "
"can be resized."),
type="warning", custom_icon="error")
return (gtk.RESPONSE_CANCEL, [])
gui.addFrame(dialog)
dialog.show_all()
runResize = True
while runResize:
rc = dialog.run()
if rc != gtk.RESPONSE_OK:
dialog.destroy()
return (rc, [])
request = getActive(combo)
newSize = dxml.get_widget("shrinkSB").get_value_as_int()
actions = []
try:
actions.append(ActionResizeFormat(request, newSize))
except ValueError as e:
intf.messageWindow(_("Resize FileSystem Error"),
_("%(device)s: %(msg)s")
% {'device': request.format.device,
'msg': e.message},
type="warning", custom_icon="error")
continue
try:
actions.append(ActionResizeDevice(request, newSize))
except ValueError as e:
intf.messageWindow(_("Resize Device Error"),
_("%(name)s: %(msg)s")
% {'name': request.name, 'msg': e.message},
type="warning", custom_icon="error")
continue
runResize = False
dialog.destroy()
return (rc, actions)
class PartitionTypeWindow(InstallWindow):
def __init__(self, ics):
InstallWindow.__init__(self, ics)
ics.setTitle("Automatic Partitioning")
ics.setNextEnabled(True)
def getNext(self):
if self.storage.checkNoDisks():
raise gui.StayOnScreen
if self.buttonGroup.getCurrent() == "custom":
self.dispatch.skipStep("autopartitionexecute", skip = 1)
self.dispatch.skipStep("partition", skip = 0)
self.dispatch.skipStep("bootloader", skip = 0)
self.storage.clearPartType = CLEARPART_TYPE_NONE
else:
if self.buttonGroup.getCurrent() == "shrink":
(rc, actions) = whichToShrink(self.storage, self.intf)
if rc == gtk.RESPONSE_OK:
for action in actions:
self.storage.devicetree.registerAction(action)
else:
raise gui.StayOnScreen
# we're not going to delete any partitions in the resize case
self.storage.clearPartType = CLEARPART_TYPE_NONE
elif self.buttonGroup.getCurrent() == "all":
self.storage.clearPartType = CLEARPART_TYPE_ALL
elif self.buttonGroup.getCurrent() == "replace":
self.storage.clearPartType = CLEARPART_TYPE_LINUX
elif self.buttonGroup.getCurrent() == "freespace":
self.storage.clearPartType = CLEARPART_TYPE_NONE
self.dispatch.skipStep("autopartitionexecute", skip = 0)
if self.encryptButton.get_active():
self.storage.encryptedAutoPart = True
else:
self.storage.encryptionPassphrase = ""
self.storage.retrofitPassphrase = False
self.storage.encryptedAutoPart = False
self.storage.doAutoPart = True
if self.reviewButton.get_active():
self.dispatch.skipStep("partition", skip = 0)
self.dispatch.skipStep("bootloader", skip = 0)
else:
self.dispatch.skipStep("partition")
self.dispatch.skipStep("bootloader")
self.dispatch.skipStep("bootloaderadvanced")
return None
def typeChanged(self, *args):
if self.buttonGroup.getCurrent() == "custom":
if not self.prevrev:
self.prevrev = self.reviewButton.get_active()
self.reviewButton.set_active(True)
self.reviewButton.set_sensitive(False)
self.encryptButton.set_sensitive(False)
else:
if self.prevrev:
self.reviewButton.set_active(self.prevrev)
self.prevrev = None
self.reviewButton.set_sensitive(True)
self.encryptButton.set_sensitive(True)
def getScreen(self, anaconda):
self.anaconda = anaconda
self.storage = anaconda.storage
self.intf = anaconda.intf
self.dispatch = anaconda.dispatch
(self.xml, vbox) = gui.getGladeWidget("autopart.glade", "parttypeTable")
self.encryptButton = self.xml.get_widget("encryptButton")
self.reviewButton = self.xml.get_widget("reviewButton")
self.table = self.xml.get_widget("parttypeTable")
self.prevrev = None
self.reviewButton.set_active(not self.dispatch.stepInSkipList("partition"))
self.encryptButton.set_active(self.storage.encryptedAutoPart)
self.buttonGroup = pixmapRadioButtonGroup()
self.buttonGroup.addEntry("all", _("Use All Space"),
pixmap=gui.readImageFromFile("partscheme-all.png"),
descr=_("Removes all partitions on the selected "
"device(s). This includes partitions "
"created by other operating systems.\n\n"
"Tip: This option will remove "
"data from the selected device(s). Make "
"sure you have backups."))
self.buttonGroup.addEntry("replace", _("Replace Existing Linux System(s)"),
pixmap=gui.readImageFromFile("partscheme-replace.png"),
descr=_("Removes all Linux partitions on the "
"selected device(s). This does "
"not remove other partitions you may have "
"on your storage device(s) (such as VFAT or "
"FAT32).\n\n"
"Tip: This option will remove "
"data from the selected device(s). Make "
"sure you have backups."))
self.buttonGroup.addEntry("shrink", _("Shrink Current System"),
pixmap=gui.readImageFromFile("partscheme-shrink.png"),
descr=_("Shrinks existing partitions to create free "
"space for the default layout."))
self.buttonGroup.addEntry("freespace", _("Use Free Space"),
pixmap=gui.readImageFromFile("partscheme-freespace.png"),
descr=_("Retains your current data and partitions and "
"uses only the unpartitioned space on the "
"selected device(s), assuming you have enough "
"free space available."))
self.buttonGroup.addEntry("custom", _("Create Custom Layout"),
pixmap=gui.readImageFromFile("partscheme-custom.png"),
descr=_("Manually create your own custom layout on "
"the selected device(s) using our partitioning "
"tool."))
self.buttonGroup.setToggleCallback(self.typeChanged)
widget = self.buttonGroup.render()
self.table.attach(widget, 0, 1, 1, 2)
# if not set in ks, use UI default
if self.storage.clearPartType is None or self.storage.clearPartType == CLEARPART_TYPE_LINUX:
self.buttonGroup.setCurrent("replace")
elif self.storage.clearPartType == CLEARPART_TYPE_NONE:
self.buttonGroup.setCurrent("freespace")
elif self.storage.clearPartType == CLEARPART_TYPE_ALL:
self.buttonGroup.setCurrent("all")
if self.buttonGroup.getCurrent() == "custom":
# make sure reviewButton is active and not sensitive
if self.prevrev == None:
self.prevrev = self.reviewButton.get_active()
self.reviewButton.set_active(True)
self.reviewButton.set_sensitive(False)
self.encryptButton.set_sensitive(False)
return vbox