summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lumens <clumens@redhat.com>2007-10-26 19:40:21 +0000
committerChris Lumens <clumens@redhat.com>2007-10-26 19:40:21 +0000
commite1059c553d9465ea494ed7fa767f4d047b43f824 (patch)
treedc188742971734462b20b0f5f5ca90366a18d5b1
parent0bbe1d6f487b4d87264ea7879ca36b1a35b878eb (diff)
downloadanaconda-e1059c553d9465ea494ed7fa767f4d047b43f824.tar.gz
anaconda-e1059c553d9465ea494ed7fa767f4d047b43f824.tar.xz
anaconda-e1059c553d9465ea494ed7fa767f4d047b43f824.zip
Rework the exception handling dialog to make it easier to add destinations
other than floppy and remote via scp in the future. USB support is almost there.
-rw-r--r--constants.py5
-rw-r--r--exception.py273
-rwxr-xr-xgui.py139
-rw-r--r--partedUtils.py21
-rw-r--r--text.py127
-rw-r--r--ui/exn.glade18
-rw-r--r--ui/exnSave.glade407
7 files changed, 725 insertions, 265 deletions
diff --git a/constants.py b/constants.py
index ea101c7da..06f2151ef 100644
--- a/constants.py
+++ b/constants.py
@@ -23,6 +23,11 @@ DISPATCH_BACK = -1
DISPATCH_FORWARD = 1
DISPATCH_NOOP = None
+EXN_OK = 0
+EXN_DEBUG = 1
+EXN_SAVE = 2
+EXN_CANCEL = 3
+
# different types of partition requests
# REQUEST_PREEXIST is a placeholder for a pre-existing partition on the system
# REQUEST_NEW is a request for a partition which will be automatically
diff --git a/exception.py b/exception.py
index 21a1408f2..06bdcf436 100644
--- a/exception.py
+++ b/exception.py
@@ -15,6 +15,7 @@
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
+from constants import *
import isys
import sys
import os
@@ -205,69 +206,61 @@ def scpAuthenticate(master, childpid, password):
(pid, childstatus) = os.waitpid (childpid, 0)
return childstatus
-# Returns 0 on success, 1 on cancel, 2 on error.
-def copyExceptionToRemote(intf):
+# Save the traceback to a remote system via SCP. Returns success or not.
+def copyExceptionToRemote(intf, scpInfo):
import pty
- scpWin = intf.scpWindow()
- while 1:
- # Bail if they hit the cancel button.
- scpWin.run()
- scpInfo = scpWin.getrc()
-
- if scpInfo == None:
- scpWin.pop()
- return 1
-
- (host, path, user, password) = scpInfo
-
- if host.find(":") != -1:
- (host, port) = host.split(":")
-
- # Try to convert the port to an integer just as a check to see
- # if it's a valid port number. If not, they'll get a chance to
- # correct the information when scp fails.
- try:
- int(port)
- portArgs = ["-P", port]
- except ValueError:
- portArgs = []
- else:
- portArgs = []
-
- # Thanks to Will Woods <wwoods@redhat.com> for the scp control
- # here and in scpAuthenticate.
-
- # Fork ssh into its own pty
- (childpid, master) = pty.fork()
- if childpid < 0:
- log.critical("Could not fork process to run scp")
- scpWin.pop()
- return 2
- elif childpid == 0:
- # child process - run scp
- args = ["scp", "-oNumberOfPasswordPrompts=1",
- "-oStrictHostKeyChecking=no"] + portArgs + \
- ["/tmp/anacdump.txt", "%s@%s:%s" % (user, host, path)]
- os.execvp("scp", args)
-
- # parent process
- try:
- childstatus = scpAuthenticate(master, childpid, password)
- except OSError:
- scpWin.pop()
- return 2
+ (host, path, user, password) = scpInfo
- os.close(master)
+ if host.find(":") != -1:
+ (host, port) = host.split(":")
- if os.WIFEXITED(childstatus) and os.WEXITSTATUS(childstatus) == 0:
- return 0
- else:
- scpWin.pop()
- return 2
-
-def copyExceptionToFloppy (anaconda):
- # in test mode have save to floppy option just copy to new name
+ # Try to convert the port to an integer just as a check to see
+ # if it's a valid port number. If not, they'll get a chance to
+ # correct the information when scp fails.
+ try:
+ int(port)
+ portArgs = ["-P", port]
+ except ValueError:
+ portArgs = []
+ else:
+ portArgs = []
+
+ # Thanks to Will Woods <wwoods@redhat.com> for the scp control
+ # here and in scpAuthenticate.
+
+ # Fork ssh into its own pty
+ (childpid, master) = pty.fork()
+ if childpid < 0:
+ log.critical("Could not fork process to run scp")
+ return False
+ elif childpid == 0:
+ # child process - run scp
+ args = ["scp", "-oNumberOfPasswordPrompts=1",
+ "-oStrictHostKeyChecking=no"] + portArgs + \
+ ["/tmp/anacdump.txt", "%s@%s:%s" % (user, host, path)]
+ os.execvp("scp", args)
+
+ # parent process
+ try:
+ childstatus = scpAuthenticate(master, childpid, password)
+ except OSError:
+ return False
+
+ os.close(master)
+
+ if os.WIFEXITED(childstatus) and os.WEXITSTATUS(childstatus) == 0:
+ return True
+ else:
+ return False
+
+# Save the traceback to a removable storage device, such as a floppy disk
+# or a usb/firewire drive. In the event of a floppy disk, it is assumed to
+# be unformatted and safe for us to destroy. For all other devices, it is
+# assumed that they are already formatted and we will only attempt to write
+# the traceback file to the device. Returns success or not.
+def copyExceptionToDisk(anaconda, device):
+ # in test mode have save to disk option just copy to new name
if not flags.setupFilesystems:
try:
shutil.copyfile("/tmp/anacdump.txt", "/tmp/test-anacdump.txt")
@@ -276,51 +269,45 @@ def copyExceptionToFloppy (anaconda):
pass
anaconda.intf.__del__ ()
- return 2
+ return False
- while 1:
- # Bail if they hit the cancel button.
- rc = anaconda.intf.dumpWindow()
- if rc:
- return 1
-
- device = anaconda.id.floppyDevice
- file = "/tmp/floppy"
- try:
- isys.makeDevInode(device, file)
- except SystemError:
- pass
+ file = "/tmp/exndev"
+ try:
+ isys.makeDevInode(device, file)
+ except SystemError:
+ pass
- try:
- fd = os.open(file, os.O_RDONLY)
- except:
- continue
+ try:
+ fd = os.open(file, os.O_RDONLY)
+ except:
+ return False
- os.close(fd)
+ os.close(fd)
- if rhpl.getArch() != "ia64":
- cmd = "/usr/sbin/mkdosfs"
+ # Only format floppy devices, not usb storage devices.
+ if device in isys.floppyDriveDict().keys() and rhpl.getArch() != "ia64":
+ cmd = "/usr/sbin/mkdosfs"
- if os.access("/sbin/mkdosfs", os.X_OK):
- cmd = "/sbin/mkdosfs"
+ if os.access("/sbin/mkdosfs", os.X_OK):
+ cmd = "/sbin/mkdosfs"
- iutil.execWithRedirect (cmd, ["/tmp/floppy"], stdout = '/dev/tty5',
- stderr = '/dev/tty5')
+ iutil.execWithRedirect (cmd, ["/tmp/floppy"], stdout = '/dev/tty5',
+ stderr = '/dev/tty5')
- try:
- isys.mount(device, "/tmp/crash", fstype = "vfat")
- except SystemError:
- continue
+ try:
+ isys.mount(device, "/tmp/crash", fstype = "vfat")
+ except SystemError:
+ return False
- # copy trace dump we wrote to local storage to floppy
- try:
- shutil.copyfile("/tmp/anacdump.txt", "/tmp/crash/anacdump.txt")
- except:
- log.error("Failed to copy anacdump.txt to floppy")
- return 2
+ # copy trace dump we wrote to local storage to disk
+ try:
+ shutil.copyfile("/tmp/anacdump.txt", "/tmp/crash/anacdump.txt")
+ except:
+ log.error("Failed to copy anacdump.txt to device %s" % device)
+ return False
- isys.umount("/tmp/crash")
- return 0
+ isys.umount("/tmp/crash")
+ return True
# Reverse the order that tracebacks are printed so people will hopefully quit
# giving us the least useful part of the exception in bug reports.
@@ -332,6 +319,54 @@ def formatException (type, value, tb):
lst.extend(traceback.format_exception_only(type, value))
return lst
+def runSaveDialog(anaconda, longTracebackFile):
+ saveWin = anaconda.intf.saveExceptionWindow(anaconda, longTracebackFile)
+ if not saveWin:
+ anaconda.intf.__del__()
+ os.kill(os.getpid(), signal.SIGKILL)
+
+ while 1:
+ saveWin.run()
+ rc = saveWin.getrc()
+
+ if rc == EXN_OK:
+ if saveWin.saveToDisk():
+ device = saveWin.getDest()
+ cpSucceeded = copyExceptionToDisk(anaconda, device)
+
+ if cpSucceeded:
+ anaconda.intf.messageWindow(_("Dump Written"),
+ _("Your system's state has been successfully written to "
+ "the disk. The installer will now exit."),
+ type="custom", custom_icon="info",
+ custom_buttons=[_("_Exit installer")])
+ sys.exit(0)
+ else:
+ anaconda.intf.messageWindow(_("Dump Not Written"),
+ _("There was a problem writing the system state to the "
+ "disk."))
+ continue
+ else:
+ scpInfo = saveWin.getDest()
+ scpSucceeded = copyExceptionToRemote(anaconda.intf, scpInfo)
+
+ if scpSucceeded:
+ anaconda.intf.messageWindow(_("Dump Written"),
+ _("Your system's state has been successfully written to "
+ "the remote host. The installer will now exit."),
+ type="custom", custom_icon="info",
+ custom_buttons=[_("_Exit installer")])
+ sys.exit(0)
+ else:
+ anaconda.intf.messageWindow(_("Dump Not Written"),
+ _("There was a problem writing the system state to the "
+ "remote host."))
+ continue
+ elif rc == EXN_CANCEL:
+ break
+
+ saveWin.pop()
+
def handleException(anaconda, (type, value, tb)):
if isinstance(value, bdb.BdbQuit):
sys.exit(1)
@@ -363,19 +398,19 @@ def handleException(anaconda, (type, value, tb)):
except:
pass
- win = anaconda.intf.exceptionWindow(text, "/tmp/anacdump.txt")
- if not win:
+ mainWin = anaconda.intf.mainExceptionWindow(text, "/tmp/anacdump.txt")
+ if not mainWin:
anaconda.intf.__del__()
os.kill(os.getpid(), signal.SIGKILL)
while 1:
- win.run()
- rc = win.getrc()
+ mainWin.run()
+ rc = mainWin.getrc()
- if rc == 0:
+ if rc == EXN_OK:
anaconda.intf.__del__ ()
os.kill(os.getpid(), signal.SIGKILL)
- elif rc == 1:
+ elif rc == EXN_DEBUG:
anaconda.intf.__del__ ()
print text
@@ -406,37 +441,5 @@ def handleException(anaconda, (type, value, tb)):
import pdb
pdb.post_mortem (tb)
os.kill(os.getpid(), signal.SIGKILL)
- elif rc == 2:
- floppyRc = copyExceptionToFloppy(anaconda)
-
- if floppyRc == 0:
- anaconda.intf.messageWindow(_("Dump Written"),
- _("Your system's state has been successfully written to "
- "the floppy. The installer will now exit."),
- type="custom", custom_icon="info",
- custom_buttons=[_("_Exit installer")])
- sys.exit(0)
- elif floppyRc == 1:
- continue
- elif floppyRc == 2:
- anaconda.intf.messageWindow(_("Dump Not Written"),
- _("There was a problem writing the system state to the "
- "floppy."))
- continue
- elif rc == 3:
- scpRc = copyExceptionToRemote(anaconda.intf)
-
- if scpRc == 0:
- anaconda.intf.messageWindow(_("Dump Written"),
- _("Your system's state has been successfully written to "
- "the remote host. The installer will now exit."),
- type="custom", custom_icon="info",
- custom_buttons=[_("_Exit installer")])
- sys.exit(0)
- elif scpRc == 1:
- continue
- elif scpRc == 2:
- anaconda.intf.messageWindow(_("Dump Not Written"),
- _("There was a problem writing the system state to the "
- "remote host."))
- continue
+ elif rc == EXN_SAVE:
+ runSaveDialog(anaconda, "/tmp/anacdump.txt")
diff --git a/gui.py b/gui.py
index 363b642b8..63703fe3d 100755
--- a/gui.py
+++ b/gui.py
@@ -562,33 +562,6 @@ class ProgressWindow:
self.window.destroy ()
rootPopBusyCursor()
-class ScpWindow:
- def __init__(self, screen=None):
- self.scpxml = gtk.glade.XML(findGladeFile("scp.glade"),
- domain="anaconda")
- self.win = self.scpxml.get_widget("saveRemoteDlg")
-
- addFrame(self.win)
- self.win.show_all()
- self.window = self.win
-
- def getrc(self):
- if self.rc == 0:
- return None
- else:
- host = self.scpxml.get_widget("hostEntry")
- remotePath = self.scpxml.get_widget("remotePathEntry")
- userName = self.scpxml.get_widget("userNameEntry")
- password = self.scpxml.get_widget("passwordEntry")
- return (host.get_text(), remotePath.get_text(),
- userName.get_text(), password.get_text())
-
- def run(self):
- self.rc = self.window.run()
-
- def pop(self):
- self.window.destroy()
-
class InstallKeyWindow:
def __init__(self, anaconda, key):
(keyxml, self.win) = getGladeWidget("instkey.glade", "instkeyDialog")
@@ -644,9 +617,79 @@ class InstallKeyWindow:
def destroy(self):
self.win.destroy()
-
-class ExceptionWindow:
+class SaveExceptionWindow:
+ def __init__(self, anaconda, longTracebackFile=None, screen=None):
+ exnxml = gtk.glade.XML(findGladeFile("exnSave.glade"), domain="anaconda")
+
+ self.hostEntry = exnxml.get_widget("hostEntry")
+ self.destEntry = exnxml.get_widget("destEntry")
+ self.usernameEntry = exnxml.get_widget("usernameEntry")
+ self.passwordEntry = exnxml.get_widget("passwordEntry")
+
+ self.diskButton = exnxml.get_widget("diskButton")
+ self.diskCombo = exnxml.get_widget("diskCombo")
+ self.remoteButton = exnxml.get_widget("remoteButton")
+ self.remoteBox = exnxml.get_widget("remoteHBox")
+ self.win = exnxml.get_widget("saveDialog")
+
+ self.diskButton.connect("toggled", self.diskButton_changed)
+
+ cell = gtk.CellRendererText()
+ self.diskCombo.pack_start(cell, True)
+ self.diskCombo.set_attributes(cell, text=1)
+
+ store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
+
+ dests = anaconda.id.diskset.exceptionDisks(anaconda)
+
+ if len(dests) > 0:
+ for d in dests:
+ iter = store.append(None)
+ store[iter] = (d[0], "/dev/%s - %s" % (d[0], d[1]))
+
+ self.diskCombo.set_model(store)
+ self.diskCombo.set_active(0)
+ else:
+ self.diskButton.set_sensitive(False)
+ self.remoteButton.set_active(True)
+ self.diskCombo.set_sensitive(False)
+ self.remoteBox.set_sensitive(True)
+
+ addFrame(self.win)
+ self.win.show_all()
+ self.window = self.win
+
+ def diskButton_changed(self, args):
+ self.diskCombo.set_sensitive(self.diskButton.get_active())
+ self.remoteBox.set_sensitive(not self.diskButton.get_active())
+
+ def getrc(self):
+ if self.rc == gtk.RESPONSE_OK:
+ return EXN_OK
+ elif self.rc == gtk.RESPONSE_CANCEL:
+ return EXN_CANCEL
+
+ def getDest(self):
+ if self.saveToDisk():
+ active = self.diskCombo.get_active()
+ if active < 0:
+ return None
+
+ return self.diskCombo.get_model()[active][0]
+ else:
+ return map(lambda e: e.get_text(), [self.hostEntry, self.destEntry, self.usernameEntry, self.passwordEntry])
+
+ def pop(self):
+ self.window.destroy()
+
+ def run(self):
+ self.rc = self.window.run ()
+
+ def saveToDisk(self):
+ return self.diskButton.get_active()
+
+class MainExceptionWindow:
def __init__ (self, shortTraceback, longTracebackFile=None, screen=None):
# Get a bunch of widgets from the XML file.
exnxml = gtk.glade.XML(findGladeFile("exn.glade"), domain="anaconda")
@@ -669,21 +712,11 @@ class ExceptionWindow:
textbuf = gtk.TextBuffer()
textbuf.set_text(shortTraceback)
- # Remove the debug button since it doesn't work in livecd mode anyway
+ # Remove the debug button since it doesn't work in livecd mode anyway.
if flags.livecdInstall:
debugButton = exnxml.get_widget("debugButton")
buttonBox.remove(debugButton)
- # Remove the floppy button if we don't need it.
- if not floppy.hasFloppyDevice() and not flags.debug:
- floppyButton = exnxml.get_widget("floppyButton")
- buttonBox.remove(floppyButton)
-
- # Remove the remote button if there's no network.
- if not hasActiveNetDev() and not flags.debug:
- remoteButton = exnxml.get_widget("remoteButton")
- buttonBox.remove(remoteButton)
-
# If there's an anacdump.txt file, add it to the lower view in the
# expander. If not, remove the expander.
if longTracebackFile:
@@ -708,32 +741,25 @@ class ExceptionWindow:
vbox.remove(expander)
addFrame(self.win)
- self.win.show_all ()
+ self.win.show_all()
self.window = self.win
def run(self):
self.rc = self.window.run ()
def getrc (self):
- # I did it this way for future expantion
- # 0 is debug
if self.rc == 0:
try:
# switch to VC1 so we can debug
isys.vtActivate (1)
except SystemError:
pass
- return 1
- # 1 is save to floppy
+ return EXN_DEBUG
if self.rc == 1:
- return 2
- # 2 is OK
+ return EXN_SAVE
elif self.rc == 2:
- return 0
- # 3 is save to remote host
- elif self.rc == 3:
- return 3
-
+ return EXN_OK
+
def pop(self):
self.window.destroy()
@@ -942,13 +968,14 @@ class InstallInterface:
d.destroy()
return rc
- def exceptionWindow(self, shortText, longTextFile):
+ def mainExceptionWindow(self, shortText, longTextFile):
log.critical(shortText)
- win = ExceptionWindow (shortText, longTextFile)
+ win = MainExceptionWindow (shortText, longTextFile)
return win
- def scpWindow(self):
- return ScpWindow()
+ def saveExceptionWindow(self, anaconda, longTextFile):
+ win = SaveExceptionWindow (anaconda, longTextFile)
+ return win
def getInstallKey(self, anaconda, key = ""):
d = InstallKeyWindow(anaconda, key)
diff --git a/partedUtils.py b/partedUtils.py
index b2a014cc6..273f37232 100644
--- a/partedUtils.py
+++ b/partedUtils.py
@@ -1322,7 +1322,28 @@ class DiskSet:
return False
+ def exceptionDisks(self, anaconda, probe=True):
+ if probe:
+ self.refreshDevices()
+ isys.flushDriveDict()
+ drives = isys.floppyDriveDict().items()
+
+ for d in isys.hardDriveDict().items():
+ if isys.driveUsesModule(d[0], ["usb-storage", "ub", "sbp2", "firewire-sbp2"]):
+ func = lambda p: not p.get_flag(parted.PARTITION_RAID) and not p.get_flag(parted.PARTITION_LVM) and p.fs_type.name in ["ext3", "ext2", "vfat"]
+
+ disk = self.disks[d[0]]
+ parts = filter_partitions(disk, func)
+
+ if len(parts) == 0:
+ drives.append(d)
+ else:
+ for part in parts:
+ name = "%s%s" % (part.disk.dev.path, part.num)
+ drives.append((os.path.basename(name), d[1]))
+
+ return drives
# XXX is this all of the possibilities?
dosPartitionTypes = [ 1, 6, 7, 11, 12, 14, 15 ]
diff --git a/text.py b/text.py
index 36e07e3cc..4773d637b 100644
--- a/text.py
+++ b/text.py
@@ -142,83 +142,95 @@ class ProgressWindow:
g.draw()
self.screen.refresh()
-class ExceptionWindow:
- def __init__ (self, shortTraceback, longTracebackFile=None, screen=None):
- self.text = "%s\n\n" % shortTraceback
+class SaveExceptionWindow:
+ def __init__(self, anaconda, longTracebackFile=None, screen=None):
+ self.anaconda = anaconda
+ self.text = "OH NOES!\n\n"
self.screen = screen
- self.buttons=[TEXT_OK_BUTTON]
-
- if floppy.hasFloppyDevice() or flags.debug:
- self.buttons.append(_("Save"))
-
- if hasActiveNetDev() or flags.debug:
- self.buttons.append(_("Remote"))
-
- if not flags.livecdInstall:
- self.buttons.append(_("Debug"))
-
- def run(self):
- log.info ("in run, screen = %s" % self.screen)
- self.rc = ButtonChoiceWindow(self.screen, _("Exception Occurred"),
- self.text, self.buttons)
-
def getrc(self):
- if self.rc == string.lower(_("Debug")):
- return 1
- elif self.rc == string.lower(_("Save")):
- return 2
- elif self.rc == string.lower(_("Remote")):
- return 3
+ if self.rc == TEXT_OK_CHECK:
+ return EXN_OK
+ elif self.rc == TEXT_CANCEL_CHECK:
+ return EXN_CANCEL
+
+ def getDest(self):
+ if self.saveToDisk():
+ return self.diskList.current()
else:
- return 0
+ return map(lambda e: e.value(), [self.hostEntry, self.destEntry, self.usernameEntry, self.passwordEntry])
def pop(self):
self.screen.popWindow()
- self.screen.refresh()
-
-class ScpWindow:
- def __init__(self, screen=None):
- self.screen = screen
- pass
+ self.screen.refresh()
def run(self):
+ toplevel = GridForm(self.screen, _("Save"), 1, 5)
+
+ self.rg = RadioGroup()
+ diskButton = self.rg.add(_("Save to Disk"), "disk", True)
+ remoteButton = self.rg.add(_("Save to Remote"), "remote", False)
+
buttons = ButtonBar(self.screen, [TEXT_OK_BUTTON, TEXT_CANCEL_BUTTON])
self.hostEntry = Entry(24)
- self.pathEntry = Entry(24)
+ self.destEntry = Entry(24)
self.usernameEntry = Entry(24)
self.passwordEntry = Entry(24, password=1)
- win = GridForm(self.screen, _("Save to Remote Host"), 1, 2)
+ diskList = Listbox(height=3, scroll=1)
+ for (dev, desc) in self.anaconda.id.diskset.exceptionDisks(self.anaconda):
+ distList.append("/dev/%s - %s" % (dev, desc), dev)
+
+ diskList.setCurrent(0)
+
+ remoteGrid = Grid(2, 4)
+ remoteGrid.setField(Label(_("Host")), 0, 0, anchorLeft=1)
+ remoteGrid.setField(self.hostEntry, 1, 0)
+ remoteGrid.setField(Label(_("Remote path")), 0, 1, anchorLeft=1)
+ remoteGrid.setField(self.destEntry, 1, 1)
+ remoteGrid.setField(Label(_("User name")), 0, 2, anchorLeft=1)
+ remoteGrid.setField(self.usernameEntry, 1, 2)
+ remoteGrid.setField(Label(_("Password")), 0, 3, anchorLeft=1)
+ remoteGrid.setField(self.passwordEntry, 1, 3)
+
+ toplevel.add(diskButton, 0, 0, (0, 0, 0, 1))
+ toplevel.add(diskList, 0, 1, (0, 0, 0, 1))
+ toplevel.add(remoteButton, 0, 2, (0, 0, 0, 1))
+ toplevel.add(remoteGrid, 0, 3, (0, 0, 0, 1))
+ toplevel.add(buttons, 0, 4, growx=1)
+
+ result = toplevel.run()
+ self.rc = buttons.buttonPressed(result)
- subgrid = Grid(2, 4)
- subgrid.setField(Label(_("Host")), 0, 0, anchorLeft=1)
- subgrid.setField(self.hostEntry, 1, 0)
- subgrid.setField(Label(_("Remote path")), 0, 1, anchorLeft=1)
- subgrid.setField(self.pathEntry, 1, 1)
- subgrid.setField(Label(_("User name")), 0, 2, anchorLeft=1)
- subgrid.setField(self.usernameEntry, 1, 2)
- subgrid.setField(Label(_("Password")), 0, 3, anchorLeft=1)
- subgrid.setField(self.passwordEntry, 1, 3)
+ def saveToDisk(self):
+ return self.rg.getSelection() == "disk"
- win.add(subgrid, 0, 0, (0, 0, 0, 1))
- win.add(buttons, 0, 1)
+class MainExceptionWindow:
+ def __init__ (self, shortTraceback, longTracebackFile=None, screen=None):
+ self.text = "%s\n\n" % shortTraceback
+ self.screen = screen
- result = win.run()
- self.rc = buttons.buttonPressed(result)
+ self.buttons=[TEXT_OK_BUTTON]
+
+ if not flags.livecdInstall:
+ self.buttons.append(_("Debug"))
+
+ def run(self):
+ log.info ("in run, screen = %s" % self.screen)
+ self.rc = ButtonChoiceWindow(self.screen, _("Exception Occurred"),
+ self.text, self.buttons)
def getrc(self):
- if self.rc == TEXT_CANCEL_CHECK:
- return None
- elif self.rc == TEXT_OK_CHECK:
- retval = (self.hostEntry.value(), self.pathEntry.value(),
- self.usernameEntry.value(), self.passwordEntry.value())
- return retval
+ if self.rc == string.lower(_("Debug")):
+ return EXN_DEBUG
+ elif self.rc == string.lower(_("Save")):
+ return EXN_SAVE
+ else:
+ return EXN_OK
def pop(self):
self.screen.popWindow()
self.screen.refresh()
- pass
class InstallInterface:
def helpWindow(self, screen, key):
@@ -422,12 +434,9 @@ class InstallInterface:
return 0
- def scpWindow(self):
- return ScpWindow(self.screen)
-
- def exceptionWindow(self, shortText, longTextFile):
+ def mainExceptionWindow(self, shortText, longTextFile):
log.critical(shortText)
- exnWin = ExceptionWindow(shortText, longTextFile, self.screen)
+ exnWin = MainExceptionWindow(shortText, longTextFile, self.screen)
return exnWin
def partedExceptionWindow(self, exc):
diff --git a/ui/exn.glade b/ui/exn.glade
index 2a69affce..a41bbf8dd 100644
--- a/ui/exn.glade
+++ b/ui/exn.glade
@@ -34,23 +34,11 @@
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
- <widget class="GtkButton" id="remoteButton">
+ <widget class="GtkButton" id="saveButton">
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="label" translatable="yes">Save to _Remote</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="response_id">3</property>
- </widget>
- </child>
-
- <child>
- <widget class="GtkButton" id="floppyButton">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">_Save to floppy</property>
- <property name="use_underline">True</property>
+ <property name="label">gtk-save</property>
+ <property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">1</property>
diff --git a/ui/exnSave.glade b/ui/exnSave.glade
new file mode 100644
index 000000000..15932e57f
--- /dev/null
+++ b/ui/exnSave.glade
@@ -0,0 +1,407 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkDialog" id="saveDialog">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Save</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_CENTER</property>
+ <property name="modal">True</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="cancelbutton1">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="okbutton1">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-ok</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-5</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Select a destination for the exception information.</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">True</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="xpad">0</property>
+ <property name="ypad">5</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkRadioButton" id="diskButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">_Disk</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">True</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkAlignment" id="alignment2">
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">1</property>
+ <property name="yscale">1</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">10</property>
+ <property name="right_padding">0</property>
+
+ <child>
+ <widget class="GtkComboBox" id="diskCombo">
+ <property name="visible">True</property>
+ <property name="add_tearoffs">False</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">3</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkRadioButton" id="remoteButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="label" translatable="yes">_Remote</property>
+ <property name="use_underline">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">diskButton</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">1</property>
+ <property name="yscale">1</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">10</property>
+ <property name="right_padding">0</property>
+
+ <child>
+ <widget class="GtkHBox" id="remoteHBox">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkVBox" id="vbox2">
+ <property name="border_width">5</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">True</property>
+ <property name="spacing">5</property>
+
+ <child>
+ <widget class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label">Host (host:port)</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="label">Destination file</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="label">User name</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="label">Password</property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox3">
+ <property name="border_width">5</property>
+ <property name="visible">True</property>
+ <property name="homogeneous">True</property>
+ <property name="spacing">5</property>
+
+ <child>
+ <widget class="GtkEntry" id="hostEntry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">•</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="destEntry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">•</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="usernameEntry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">True</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">•</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkEntry" id="passwordEntry">
+ <property name="can_focus">True</property>
+ <property name="editable">True</property>
+ <property name="visibility">False</property>
+ <property name="max_length">0</property>
+ <property name="text" translatable="yes"></property>
+ <property name="has_frame">True</property>
+ <property name="invisible_char">•</property>
+ <property name="activates_default">False</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+</glade-interface>