#
# gui.py - Graphical front end for anaconda
#
# Matt Wilson <msw@redhat.com>
# Michael Fulbright <msf@redhat.com>
#
# Copyright 1999-2003 Red Hat, Inc.
#
# This software may be freely redistributed under the terms of the GNU
# library public license.
#
# You should have received a copy of the GNU Library Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#

import os
import iutil
import string
import isys
import sys
import parted
import gtk
import htmlbuffer
import rpm
import kudzu
from language import expandLangs
from splashscreen import splashScreenPop
from flags import flags
from constants import *

from rhpl.log import log
from rhpl.translate import _, N_

from product import *
rpm.addMacro("_i18ndomains", "redhat-dist")
isys.bind_textdomain_codeset("redhat-dist", "UTF-8")

StayOnScreen = "stayOnScreen"
mainWindow = None

stepToClass = {
    "language" : ("language_gui", "LanguageWindow"),
    "keyboard" : ("keyboard_gui", "KeyboardWindow"),
    "mouse" : ("mouse_gui", "MouseWindow"),
    "welcome" : ("welcome_gui", "WelcomeWindow"),
    "installtype" : ("installpath_gui", "InstallPathWindow"),
    "partitionmethod" : ("partmethod_gui", "PartitionMethodWindow"),
    "partition" : ("partition_gui", "PartitionWindow"),
    "autopartition" : ("partition_gui", "AutoPartitionWindow"),
    "findinstall" : ("examine_gui", "UpgradeExamineWindow"),
    "addswap" : ("upgrade_swap_gui", "UpgradeSwapWindow"),
    "upgrademigratefs" : ("upgrade_migratefs_gui", "UpgradeMigrateFSWindow"),
    "fdisk" : ("fdisk_gui", "FDiskWindow"),
    "bootloader": ("bootloader_main_gui", "MainBootloaderWindow"),
    "bootloaderadvanced": ("bootloader_advanced_gui", "AdvancedBootloaderWindow"),
    "upgbootloader": ("upgrade_bootloader_gui", "UpgradeBootloaderWindow"),
    "network" : ("network_gui", "NetworkWindow"),
    "firewall" : ("firewall_gui", "FirewallWindow"),
    "languagesupport" : ("language_support_gui", "LanguageSupportWindow"),
    "timezone" : ("timezone_gui", "TimezoneWindow"),
    "accounts" : ("account_gui", "AccountWindow"),
    "authentication" : ("auth_gui", "AuthWindow"),
    "desktopchoice": ("desktop_choice_gui", "DesktopChoiceWindow"),
    "package-selection" : ("package_gui", "PackageSelectionWindow"),
    "indivpackage" : ("package_gui", "IndividualPackageSelectionWindow"),
    "dependencies" : ("dependencies_gui", "UnresolvedDependenciesWindow"),
    "videocard" : ("xconfig_gui", "XConfigWindow"),
    "monitor" : ("xconfig_gui", "MonitorWindow"),
    "xcustom" : ("xconfig_gui", "XCustomWindow"),
    "confirminstall" : ("confirm_gui", "InstallConfirmWindow"),
    "confirmupgrade" : ("confirm_gui", "UpgradeConfirmWindow"),
    "finishxconfig" : None,
    "install" : ("progress_gui", "InstallProgressWindow"),
    "bootdisk" : ("bootdisk_gui", "BootdiskWindow"),
    "complete" : ("congrats_gui", "CongratulationWindow"),
}

if iutil.getArch() == 'sparc':
    stepToClass["bootloader"] = ("silo_gui", "SiloWindow")
elif iutil.getArch() == 's390':
    stepToClass["bootloader"] = ("zipl_gui", "ZiplWindow")



#
# Stuff for screenshots
#
screenshotDir = None
screenshotIndex = 0

def copyScreenshots():
    global screenshotIndex
    global screenshotDir
    
    # see if any screenshots taken
    if screenshotIndex == 0:
	return

    destDir = "/mnt/sysimage/root/anaconda-screenshots"
    if not os.access(destDir, os.R_OK):
	try:
	    os.mkdir(destDir, 0750)
	except:
	    window = MessageWindow("Error Saving Screenshot", 
				   _("An error occurred copying the "
				     "screenshots over."), type="warning")
	    return

    # copy all png's over
    for f in os.listdir(screenshotDir):
	(path, fname) = os.path.split(f)
	(b, ext) = os.path.splitext(f)
	if ext == ".png":
	    iutil.copyFile(screenshotDir + '/' + f,
			   destDir + '/' + fname)

    window = MessageWindow(_("Screenshots Copied"), 
			   _("The screenshots have been saved into the "
			     "directory:\n\n"
			     "\t/root/anaconda-screenshots/\n\n"
			     "You can access these when you reboot and "
			     "login as root."))



def takeScreenShot():
    global screenshotIndex
    global screenshotDir

    if screenshotDir is None:
	screenshotDir = "/tmp/ramfs/anaconda-screenshots"

	if  not os.access(screenshotDir, os.R_OK):
	    try:
		os.mkdir(screenshotDir)
	    except:
		screenshotDir = None
		return

    try:
	screenshot = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, gtk.FALSE, 8,
				    gtk.gdk.screen_width(), gtk.gdk.screen_height())
	screenshot.get_from_drawable(gtk.gdk.get_default_root_window(),
				     gtk.gdk.colormap_get_system(),
				     0, 0, 0, 0,
				     gtk.gdk.screen_width(), gtk.gdk.screen_height())

	if screenshot:
	    while (1):
		sname = "screenshot-%04d.png" % ( screenshotIndex,)
		if not os.access(screenshotDir + '/' + sname, os.R_OK):
		    break

		screenshotIndex = screenshotIndex + 1
		if screenshotIndex > 9999:
		    log("Too many screenshots!")
		    return

	    screenshot.save (screenshotDir + '/' + sname, "png")
	    screenshotIndex = screenshotIndex + 1

	    window = MessageWindow(_("Saving Screenshot"), 
				   _("A screenshot named '%s' has been saved.") % (sname,) ,
				   type="ok")
    except:
	window = MessageWindow(_("Error Saving Screenshot"), 
			       _("An error occurred while saving "
				 "the screenshot.  If this occurred "
				 "during package installation, you may need "
				 "to try several times for it to succeed."),
			       type="warning")

		
def handleShiftPrintScrnRelease (window, event):
    if (event.keyval == gtk.keysyms.Print and event.state & gtk.gdk.SHIFT_MASK):
	takeScreenShot()
	    
	    
	

#
# HACK to make treeview work
# 
 
def setupTreeViewFixupIdleHandler(view, store):
    id = {}
    id["id"] = gtk.idle_add(scrollToIdleHandler, (view, store, id))

def scrollToIdleHandler((view, store, iddict)):
    if not view or not store or not iddict:
	return

    try:
	id = iddict["id"]
    except:
	return
    
    selection = view.get_selection()
    if not selection:
	return
    
    model, iter = selection.get_selected()
    if not iter:
	return

    path = store.get_path(iter)
    col = view.get_column(0)
    view.scroll_to_cell(path, col, gtk.TRUE, 0.5, 0.5)

    if id:
	gtk.idle_remove(id)

# setup globals
def processEvents():
    gtk.gdk.flush()
    while gtk.events_pending():
        gtk.main_iteration(gtk.FALSE)

def partedExceptionWindow(exc):
    # if our only option is to cancel, let us handle the exception
    # in our code and avoid popping up the exception window here.
    if exc.options == parted.EXCEPTION_CANCEL:
        return parted.EXCEPTION_UNHANDLED
    print exc.type_string
    print exc.message
    print exc.options
    win = gtk.Dialog(exc.type_string, mainWindow, gtk.DIALOG_MODAL)
    addFrame(win)
    win.set_position(gtk.WIN_POS_CENTER)
    label = WrappingLabel(exc.message)
    win.vbox.pack_start (label)
    numButtons = 0
    buttonToAction = {}
    
    exflags = ((parted.EXCEPTION_FIX, N_("Fix")),
             (parted.EXCEPTION_YES, N_("Yes")),
             (parted.EXCEPTION_NO, N_("No")),
             (parted.EXCEPTION_OK, N_("OK")),
             (parted.EXCEPTION_RETRY, N_("Retry")),
             (parted.EXCEPTION_IGNORE, N_("Ignore")),
             (parted.EXCEPTION_CANCEL, N_("Cancel")))
    for flag, string in exflags:
        if exc.options & flag:
            win.add_button(_(string), flag)
    win.show_all()
    rc = win.run()
    win.destroy()
    return rc

def widgetExpander(widget, growTo=None):
    widget.connect("size-allocate", growToParent, growTo)

def growToParent(widget, rect, growTo=None):
    return
    if not widget.parent:
        return
    ignore = widget.__dict__.get("ignoreEvents")
    if not ignore:
        if growTo:
            x, y, width, height = growTo.get_allocation()
            widget.set_size_request(width, -1)
        else:
            widget.set_size_request(rect.width, -1)
        widget.ignoreEvents = 1
    else:
        widget.ignoreEvents = 0

_busyCursor = 0

def setCursorToBusy(process=1):
    root = gtk.gdk.get_default_root_window()
    cursor = gtk.gdk.Cursor(gtk.gdk.WATCH)
    root.set_cursor(cursor)
    if process:
        processEvents()

def setCursorToNormal():
    root = gtk.gdk.get_default_root_window()
    cursor = gtk.gdk.Cursor(gtk.gdk.LEFT_PTR)
    root.set_cursor(cursor)

def rootPushBusyCursor(process=1):
    global _busyCursor
    _busyCursor += 1
    if _busyCursor > 0:
	setCursorToBusy(process)

def rootPopBusyCursor():
    global _busyCursor
    _busyCursor -= 1
    if _busyCursor <= 0:
	setCursorToNormal()

def getBusyCursorStatus():
    global _busyCursor
    
    return _busyCursor

class MnemonicLabel(gtk.Label):
    def __init__(self, text=""):
        gtk.Label.__init__(self, "")
        self.set_text_with_mnemonic(text)

class WrappingLabel(gtk.Label):
    def __init__(self, label=""):
        gtk.Label.__init__(self, label)
        self.set_line_wrap(gtk.TRUE)
        self.ignoreEvents = 0
#        self.set_size_request(-1, 1)
        widgetExpander(self)

def titleBarMousePressCB(widget, event, data):
    if event.type & gtk.gdk.BUTTON_PRESS:
	data["state"] = 1
	data["button"] = event.button
	data["deltax"] = event.x
	data["deltay"] = event.y
	
def titleBarMouseReleaseCB(widget, event, data):
    if data["state"] and event.button == data["button"]:
	data["state"] = 0
	data["button"] = 0
	data["deltax"] = 0
	data["deltay"] = 0

def titleBarMotionEventCB(widget, event, data):
    if data["state"]:
	newx = event.x_root-data["deltax"]
	newy = event.y_root-data["deltay"]
	if newx < 0:
	    newx = 0
	if newy < 0:
	    newy = 0
	(w, h) = data["window"].get_size()
	if (newx+w) > gtk.gdk.screen_width():
	    newx = gtk.gdk.screen_width() - w
	if (newy+20) > (gtk.gdk.screen_height()):
	    newy = gtk.gdk.screen_height() - 20
	
	data["window"].move(newx, newy)

def addFrame(dialog, title=None):
    contents = dialog.get_children()[0]
    dialog.remove(contents)
    frame = gtk.Frame()
    frame.set_shadow_type(gtk.SHADOW_OUT)
    box = gtk.VBox()
    try:
	if title is None:
	    title = dialog.get_title()

	if title:
	    data = {}
	    data["state"] = 0
	    data["button"] = 0
	    data["deltax"] = 0
	    data["deltay"] = 0
	    data["window"] = dialog
	    eventBox = gtk.EventBox()
	    eventBox.connect("button-press-event", titleBarMousePressCB, data)
	    eventBox.connect("button-release-event", titleBarMouseReleaseCB, data)
	    eventBox.connect("motion-notify-event", titleBarMotionEventCB,data)
	    titleBox = gtk.HBox(gtk.FALSE, 5)
	    eventBox.add(titleBox)
	    eventBox.modify_bg(gtk.STATE_NORMAL,
                               eventBox.rc_get_style().bg[gtk.STATE_SELECTED])
	    titlelbl = gtk.Label("")
	    titlelbl.set_markup("<b>"+_(title)+"</b>")
	    titlelbl.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse ("white"))
	    titlelbl.set_property("ypad", 4)
	    titleBox.pack_start(titlelbl)
	    box.pack_start(eventBox, gtk.FALSE, gtk.FALSE)
    except:
	pass
    
    frame2=gtk.Frame()
    frame2.set_shadow_type(gtk.SHADOW_NONE)
    frame2.set_border_width(4)
    frame2.add(contents)
    box.pack_start(frame2, gtk.TRUE, gtk.TRUE, padding=5)
    frame.add(box)
    frame.show()
    dialog.add(frame)

    # make screen shots work
    dialog.connect ("key-release-event", handleShiftPrintScrnRelease)


class WaitWindow:
    def __init__(self, title, text):
        self.window = gtk.Window(gtk.WINDOW_POPUP)
        self.window.set_title(title)
        self.window.set_position(gtk.WIN_POS_CENTER)
        self.window.set_modal(gtk.TRUE)
        label = WrappingLabel(text)
        box = gtk.Frame()
        box.set_border_width(10)
        box.add(label)
        box.set_shadow_type(gtk.SHADOW_NONE)
        frame = gtk.Frame ()
        frame.set_shadow_type(gtk.SHADOW_OUT)
        frame.add (box)
	self.window.add(frame)
	self.window.show_all()
        rootPushBusyCursor()
            
    def pop(self):
        self.window.destroy()
        rootPopBusyCursor()

class ProgressWindow:
    def __init__(self, title, text, total):
        self.window = gtk.Window (gtk.WINDOW_POPUP)
        self.window.set_title (title)
        self.window.set_position (gtk.WIN_POS_CENTER)
        self.window.set_modal (gtk.TRUE)
        box = gtk.VBox (gtk.FALSE, 5)
        box.set_border_width (10)

        label = WrappingLabel (text)
        label.set_alignment (0.0, 0.5)
        box.pack_start (label, gtk.FALSE)
        
        self.total = total
	self.progress = gtk.ProgressBar ()
        box.pack_start (self.progress, gtk.TRUE)
        
        frame = gtk.Frame ()
        frame.set_shadow_type (gtk.SHADOW_OUT)
        frame.add (box)
	self.window.add (frame)
	self.window.show_all ()
        rootPushBusyCursor()

    def set (self, amount):
	# only update widget if we've changed by 5%
	curval = self.progress.get_fraction()
	newval = float (amount) / self.total
	if newval < 0.998:
	    if (newval - curval) < 0.05 and newval > curval:
		return
	self.progress.set_fraction (newval)
        processEvents ()        
    
    def pop(self):
        self.window.destroy ()
        rootPopBusyCursor()

class ExceptionWindow:
    def __init__ (self, text):
        try:
            floppyDevices = 0
            for dev in kudzu.probe(kudzu.CLASS_FLOPPY, kudzu.BUS_UNSPEC,
                                   kudzu.PROBE_ALL):
                if not dev.detached:
                    floppyDevices = floppyDevices + 1
        except:
            floppyDevices = 0

        win = gtk.Dialog("Exception Occured", mainWindow, gtk.DIALOG_MODAL)
        win.add_button("_Debug", 0)
        if floppyDevices > 0 or DEBUG:
            win.add_button("_Save to floppy", 1)
        win.add_button('gtk-ok', 2)
        buffer = gtk.TextBuffer(None)
        buffer.set_text(text)
        textbox = gtk.TextView()
        textbox.set_buffer(buffer)
        textbox.set_property("editable", gtk.FALSE)
        textbox.set_property("cursor_visible", gtk.FALSE)
        sw = gtk.ScrolledWindow ()
        sw.add (textbox)
        sw.set_policy (gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)

        hbox = gtk.HBox (gtk.FALSE)
##         file = pixmap_file('gnome-warning.png')
##         if file:
##             hbox.pack_start (GnomePixmap (file), gtk.FALSE)

        if floppyDevices > 0:
            info = WrappingLabel(exceptionText)
        else:
            info = WrappingLabel(exceptionTextNoFloppy)
            
        info.set_size_request (400, -1)

        hbox.pack_start (sw, gtk.TRUE)
        win.vbox.pack_start (info, gtk.FALSE)            
        win.vbox.pack_start (hbox, gtk.TRUE)
        win.set_size_request (500, 300)
        win.set_position (gtk.WIN_POS_CENTER)
        addFrame(win)
        win.show_all ()
        self.window = win
        self.rc = self.window.run ()
#        self.window.destroy()
        
    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
        if self.rc == 1:
            return 2
        # 2 is OK
        elif self.rc == 2:
            return 0

class MessageWindow:
    def getrc (self):
        return self.rc
    
    def __init__ (self, title, text, type="ok", default=None, custom_buttons=None, custom_icon=None):
        if flags.autostep:
            self.rc = 1
            return
        self.rc = None
	docustom = 0
        if type == 'ok':
            buttons = gtk.BUTTONS_OK
            style = gtk.MESSAGE_INFO
        elif type == 'warning':
            buttons = gtk.BUTTONS_OK
            style = gtk.MESSAGE_WARNING
        elif type == 'okcancel':
            buttons = gtk.BUTTONS_OK_CANCEL
            style = gtk.MESSAGE_WARNING
        elif type == 'yesno':
            buttons = gtk.BUTTONS_YES_NO
            style = gtk.MESSAGE_QUESTION
	elif type == 'custom':
	    docustom = 1
	    buttons = gtk.BUTTONS_NONE
	    style = gtk.MESSAGE_QUESTION

	if custom_icon == "warning":
	    style = gtk.MESSAGE_WARNING
	elif custom_icon == "question":
	    style = gtk.MESSAGE_QUESTION
	elif custom_icon == "error":
	    style = gtk.MESSAGE_ERROR
	elif custom_icon == "info":
	    style = gtk.MESSAGE_INFO

	dialog = gtk.MessageDialog(mainWindow, 0, style, buttons, text)

	if docustom:
	    rid=0
	    for button in custom_buttons:
		if button == _("Cancel"):
		    tbutton = "gtk-cancel"
		else:
		    tbutton = button

		widget = dialog.add_button(tbutton, rid)
		rid = rid + 1

            defaultchoice = rid - 1
	else:
	    if default == "no":
                defaultchoice = 0
	    elif default == "yes" or default == "ok":
                defaultchoice = 1
	    else:
                defaultchoice = 0

        addFrame(dialog, title=title)
        dialog.set_position (gtk.WIN_POS_CENTER)
        dialog.set_default_response(defaultchoice)
        dialog.show_all ()

	# XXX - Messy - turn off busy cursor if necessary
	busycursor = getBusyCursorStatus()
	setCursorToNormal()
        rc = dialog.run()

        if rc == gtk.RESPONSE_OK or rc == gtk.RESPONSE_YES:
            self.rc = 1
        elif (rc == gtk.RESPONSE_CANCEL or rc == gtk.RESPONSE_NO
            or rc == gtk.RESPONSE_CLOSE):
            self.rc = 0
	elif rc == gtk.RESPONSE_DELETE_EVENT:
	    self.rc = 0
	else:
	    self.rc = rc
        dialog.destroy()

	# restore busy cursor
	if busycursor:
	    setCursorToBusy()
    
class InstallInterface:
    def __init__ (self):
        # figure out if we want to run interface at 800x600 or 640x480
        if gtk.gdk.screen_width() >= 800:
            self.runres = "800x600"
        else:
            self.runres = "640x480"

    def __del__ (self):
        pass

    def shutdown (self):
	pass

    def setPackageProgressWindow (self, ppw):
        self.ppw = ppw

    def waitWindow (self, title, text):
	return WaitWindow (title, text)

    def progressWindow (self, title, text, total):
	return ProgressWindow (title, text, total)

    def packageProgressWindow (self, total, totalSize):
        self.ppw.setSizes (total, totalSize)
        return self.ppw

    def messageWindow(self, title, text, type="ok", default = None,
		     custom_buttons=None,  custom_icon=None):
        rc = MessageWindow (title, text, type, default,
			    custom_buttons, custom_icon).getrc()
        return rc

    def exceptionWindow(self, title, text):
        print text
        win = ExceptionWindow (text)
        return win.getrc ()

    def dumpWindow(self):
        window = MessageWindow("Save Crash Dump", 
                               _("Please insert a floppy now. All contents "
                                 "of the disk will be erased, so please "
                                 "choose your diskette carefully."),
                               "okcancel")
        rc = window.getrc()
	return not rc

    def getBootdisk (self):
        return None

    def run(self, id, dispatch, configFileData):
##         from xkb import XKB
##         kb = XKB()

	self.dispatch = dispatch

        # XXX users complain when the keypad doesn't work for input.
##         if 0 and flags.setupFilesystems:
##             try:
##                 kb.setMouseKeys (1)
##             except SystemError:
##                 pass

        # XXX x_already_set is a hack
        if id.keyboard and not id.x_already_set:
            id.keyboard.activate()
## 	    info = id.keyboard.getXKB()
## 	    if info:
##                 (rules, model, layout, variant, options) = info
##                 kb.setRule (model, layout, variant, "complete")

        id.fsset.registerMessageWindow(self.messageWindow)
        id.fsset.registerProgressWindow(self.progressWindow)
        id.fsset.registerWaitWindow(self.waitWindow)
        parted.exception_set_handler(partedExceptionWindow)

	lang = id.instLanguage.getCurrent()
	lang = id.instLanguage.getLangNick(lang)
        self.icw = InstallControlWindow (self, self.dispatch, lang)
        self.icw.run (self.runres, configFileData)

class TextViewBrowser(gtk.TextView):
    def __init__(self):
        self.hadj = None
        self.vadj = None

        gtk.TextView.__init__(self)
        self.set_property('editable', gtk.FALSE)
        self.set_property('cursor_visible', gtk.FALSE)
        self.set_left_margin(10)
        self.set_wrap_mode(gtk.WRAP_WORD)
        self.connect('move-cursor', self.moveCursor)
        self.connect('set-scroll-adjustments', self.cacheAdjustments)

    def swallowFocus(self, *args):
        self.emit_stop_by_name('focus-in-event')        
        
    def cacheAdjustments(self, view, hadj, vadj):
        self.hadj = hadj
        self.vadj = vadj

    def moveCursor(self, view, step, count, extend_selection):
        if step == gtk.MOVEMENT_DISPLAY_LINES:
            if count == -1 and self.vadj != None:
                self.vadj.value = max(self.vadj.value - self.vadj.step_increment,
                                      self.vadj.lower)
                self.vadj.value_changed()
            elif count == 1 and self.vadj != None:
                self.vadj.value = min(self.vadj.value + self.vadj.step_increment - 1,
                                      self.vadj.upper - self.vadj.page_increment - 1)
                self.vadj.value_changed()
        elif step == gtk.MOVEMENT_PAGES:
            if count == -1 and self.vadj != None:
                self.vadj.value = max(self.vadj.value - self.vadj.page_increment,
                                      self.vadj.lower)
                self.vadj.value_changed()
            elif count == 1 and self.vadj != None:
                self.vadj.value = min(self.vadj.value + self.vadj.page_increment - 1,
                                      self.vadj.upper - self.vadj.page_increment - 1)
                self.vadj.value_changed()

        self.emit_stop_by_name ('move-cursor')

    
class InstallControlWindow:
    def setLanguage (self, locale):
        #gtk_set_locale ()
        #gtk_rc_init ()
        #gtk_rc_reparse_all ()

	self.langSearchPath = expandLangs(locale) + ['C']
        
##         found = 0
##         for l in self.langSearchPath:
##             if os.access ("/etc/gtk/gtkrc." + l, os.R_OK):
##                 rc_parse("/etc/gtk/gtkrc." + l)
##                 found = 1
##         if not found:
##             rc_parse("/etc/gtk/gtkrc")

##         #_gtk_nuke_rc_mtimes ()
##         gtk_rc_reparse_all ()
        
	if not self.__dict__.has_key('window'): return

        self.reloadRcQueued = 1

	self.updateStockButtons()
        self.helpFrame.set_label (_("Online Help"))
        self.installFrame.set_label (_("Language Selection"))
	self.loadReleaseNotes()
        self.refreshHelp(recreate = 1)

    def prevClicked (self, *args):
	try:
	    self.currentWindow.getPrev ()
	except StayOnScreen:
	    return

	self.dispatch.gotoPrev()
	self.dir = -1

        self.setScreen ()

    def nextClicked (self, *args):
	try:
	    rc = self.currentWindow.getNext ()
	except StayOnScreen:
	    return

	self.dispatch.gotoNext()
	self.dir = 1

        self.setScreen ()

    def helpClicked (self, widget, simulated=0):
        self.hbox.remove (widget)
        if widget == self.hideHelpButton:
            self.bin.remove (self.table)
            self.installFrame.reparent (self.bin)
            self.showHelpButton.show ()
            self.showHelpButton.set_state (gtk.STATE_NORMAL)
            self.hbox.pack_start (self.showHelpButton, gtk.FALSE)
            self.hbox.reorder_child (self.showHelpButton, 0)
            self.showHelpButton.grab_focus()            
            self.displayHelp = gtk.FALSE
        else:
            self.bin.remove (self.installFrame)
            self.table.attach (self.installFrame, 1, 3, 0, 1,
                               gtk.FILL | gtk.EXPAND,
                               gtk.FILL | gtk.EXPAND)
            self.bin.add (self.table)
            self.refreshHelp()
            self.hideHelpButton.show ()
            self.showHelpButton.set_state (gtk.STATE_NORMAL)
            self.hbox.pack_start (self.hideHelpButton, gtk.FALSE)
            self.hbox.reorder_child (self.hideHelpButton, 0)
            self.hideHelpButton.grab_focus()
            self.displayHelp = gtk.TRUE

    def debugClicked (self, *args):
        try:
            # switch to VC1 so we can debug
            isys.vtActivate (1)
        except SystemError:
            pass
        import pdb
        try:
            pdb.set_trace()
        except:
            sys.exit(-1)
        try:
            # switch back
            isys.vtActivate (7)
        except SystemError:
            pass
        
    def refreshHelp(self, recreate = 0):
        buffer = htmlbuffer.HTMLBuffer()
        ics = self.currentWindow.getICS()
        buffer.feed(ics.getHTML(self.langSearchPath))
        textbuffer = buffer.get_buffer()
        if recreate == 0:
            self.help.set_buffer(textbuffer)
        else:
            self.help_sw.remove(self.help)
            self.help = TextViewBrowser()
            self.help_sw.add(self.help)
            self.help.set_buffer(textbuffer)
            self.help.show()
        # scroll to the top.  Do this with a mark so it's done in the idle loop
        iter = textbuffer.get_iter_at_offset(0)
        mark = textbuffer.create_mark("top", iter, gtk.FALSE)
        self.help.scroll_to_mark(mark, 0.0, gtk.FALSE, 0.0, 0.0)

    def relnotes_closed (self, *args):
        self.textWin.destroy()

#
# XXX - disabling this behavior for now due to bug where if you pop up
#       release notes during package selection, then close it after
#       package selection is done and install has moved to next screen,
#       the stockButtons get their state screwed up
#
#        for (icon, name, text, func) in self.stockButtons:
#            if self.__dict__.has_key(name):
#		self.__dict__[name].set_sensitive(self.relnotes_buttonstate[name])
        return

    def releaseClicked (self, widget):
        self.textWin = gtk.Dialog(parent=mainWindow, flags=gtk.DIALOG_MODAL)


#
# XXX - disabling this behavior for now due to bug where if you pop up
#       release notes during package selection, then close it after
#       package selection is done and install has moved to next screen,
#       the stockButtons get their state screwed up
#	self.relnotes_buttonstate={}
#        for (icon, name, text, func) in self.stockButtons:
#            if self.__dict__.has_key(name):
#		self.relnotes_buttonstate[name] = self.__dict__[name].get_property("sensitive")
#                self.__dict__[name].set_sensitive(gtk.FALSE)

        table = gtk.Table(3, 3, gtk.FALSE)
        self.textWin.vbox.pack_start(table)
        self.textWin.add_button('gtk-close', gtk.RESPONSE_NONE)
        self.textWin.connect("response", self.relnotes_closed)
        vbox1 = gtk.VBox ()        
        vbox1.set_border_width (10)
        frame = gtk.Frame (_("Release Notes"))
        frame.add(vbox1)
        frame.set_label_align (0.5, 0.5)
        frame.set_shadow_type (gtk.SHADOW_NONE)
        
        self.textWin.set_position (gtk.WIN_POS_CENTER)

        if self.releaseNotesBuffer:
            text = TextViewBrowser()
            text.set_buffer(self.releaseNotesBuffer)
            
            sw = gtk.ScrolledWindow()
            sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS)
            sw.set_shadow_type(gtk.SHADOW_IN)
            sw.add(text)
            vbox1.pack_start(sw)

            a = gtk.Alignment (0, 0, 1.0, 1.0)
            a.add (frame)
            
            self.textWin.set_default_size (635, 393)
            self.textWin.set_size_request (635, 393)
            self.textWin.set_position (gtk.WIN_POS_CENTER)

            table.attach (a, 1, 2, 1, 2,
                          gtk.FILL | gtk.EXPAND,
                          gtk.FILL | gtk.EXPAND, 5, 5)

            self.textWin.set_border_width(0)
            addFrame(self.textWin, _("Release Notes"))
            self.textWin.show_all()

        else:
            self.textWin.set_position (gtk.WIN_POS_CENTER)
            label = gtk.Label(_("Unable to load file!"))

            table.attach (label, 1, 2, 1, 2,
                          gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND, 5, 5)

            self.textWin.set_border_width(0)
            addFrame(self.textWin)
            self.textWin.show_all()

    def loadReleaseNotes(self):
	langList = self.langSearchPath + [ "" ]
        sourcepath = self.dispatch.method.getSourcePath()
        suffixList = []        
	for lang in langList:
	    if lang:
                suffixList.append("-%s.html" % (lang,))
                suffixList.append(".%s" % (lang,))
            else:
                suffixList.append(".html")
                suffixList.append("")
                
            for suffix in suffixList:
                fn = "%s/RELEASE-NOTES%s" % (sourcepath, suffix)
                if os.access(fn, os.R_OK):
                    file = open(fn, "r")
                    if suffix.endswith('.html'):
                        buffer = htmlbuffer.HTMLBuffer()
                        buffer.feed(file.read())
                        self.releaseNotesBuffer = buffer.get_buffer()
                    else:
                        buffer = gtk.TextBuffer(None)
                        buffer.set_text(file.read())
                        self.releaseNotesBuffer = buffer
                    file.close()
                    return
            
        buffer = gtk.TextBuffer(None)
        buffer.set_text(_("Release notes are missing.\n"))
        self.releaseNotesBuffer = buffer

    def handleRenderCallback(self):
        self.currentWindow.renderCallback()
        if flags.autostep:
            self.nextClicked()
        else:
            gtk.idle_remove(self.handle)

    def setScreen (self):
	(step, args) = self.dispatch.currentStep()
	if step is None:
	    gtk.mainquit()
	    return

	if not stepToClass[step]:
	    if self.dir == 1:
		return self.nextClicked()
	    else:
		return self.prevClicked()
		
	(file, className) = stepToClass[step]
        newScreenClass = None
	s = "from %s import %s; newScreenClass = %s" % (file, className,
                                                        className)
        while 1:
            try:
                exec s
                break
            except ImportError, e:
                print e
                win = MessageWindow(_("Error!"),
                                   _("An error occurred when attempting "
                                     "to load an installer interface "
                                     "component.\n\nclassName = %s") % (className,),
                                    type="custom", custom_icon="warning",
                                    custom_buttons=[_("_Exit"),
                                                    _("_Retry")])
                if not win.getrc():
                    MessageWindow(_("Rebooting System"),
                                  _("Your system will now be rebooted..."),
                                  type="custom",
                                  custom_icon="warning",
                                  custom_buttons=[_("_Reboot")])
                    sys.exit(0)
                
	ics = InstallControlState (self)
        ics.setPrevEnabled(self.dispatch.canGoBack())
        
	self.destroyCurrentWindow()
        self.currentWindow = newScreenClass(ics)

	new_screen = apply(self.currentWindow.getScreen, args)
	if not new_screen:
            return

        self.update (ics)

        self.installFrame.set_label(ics.getTitle ())
        self.installFrame.add(new_screen)
        self.installFrame.show_all()

	self.handle = gtk.idle_add(self.handleRenderCallback)

        if self.reloadRcQueued:
            self.window.reset_rc_styles()
            self.reloadRcQueued = 0

        if self.displayHelp:
            self.refreshHelp()
            
    def destroyCurrentWindow(self):
        children = self.installFrame.get_children ()
        if children:
            child = children[0]
            self.installFrame.remove (child)
            child.destroy ()
	self.currentWindow = None

    def update (self, ics):
        self.installFrame.set_label (ics.getTitle ())

	prevButton = self.prevButtonStock
	nextButton = self.nextButtonStock

	if ics.getNextButton():
	    (icon, text) = ics.getNextButton()
            button = gtk.Button()
            box = gtk.HBox(gtk.FALSE, 0)
            image = gtk.Image()
            image.set_from_stock(icon, gtk.ICON_SIZE_BUTTON)
            box.pack_start(image, gtk.FALSE, gtk.FALSE)
            label = gtk.Label(_(text))
            label.set_property("use-underline", gtk.TRUE)
            box.pack_start(label, gtk.TRUE, gtk.TRUE)
            button.add(box)
	    button.connect("clicked", self.nextClicked)
	    button.show_all()
            button.label = label
            nextButton = button

        children = self.buttonBox.get_children()

        if not nextButton in children and self.nextButtonStock in children:
            pos = children.index(self.nextButtonStock)
            self.buttonBox.remove(self.nextButtonStock)
            self.buttonBox.pack_end(nextButton)
            self.buttonBox.reorder_child(nextButton, pos)
            self.nextButtonStock = nextButton

        prevButton.set_sensitive (ics.getPrevEnabled ())
        nextButton.set_sensitive (ics.getNextEnabled ())
        self.hideHelpButton.set_sensitive (ics.getHelpButtonEnabled ())
        self.showHelpButton.set_sensitive (ics.getHelpButtonEnabled ())

        if ics.getHelpEnabled () == gtk.FALSE:
            if self.displayHelp:
                self.helpClicked (self.hideHelpButton, 1)
        elif ics.getHelpEnabled () == gtk.TRUE:
            if not self.displayHelp:
                self.helpClicked (self.showHelpButton, 1)
 
        if (ics.getGrabNext ()):
            nextButton.grab_focus ()

    def __init__ (self, ii, dispatch, locale):
        self.prevButtonStock = None
        self.nextButtonStock = None
        self.releaseButton = None
        self.showHelpButton = None
        self.hideHelpButton = None
        self.debugButton = None

	self.stockButtons = (('gtk-go-back', "prevButtonStock",
                              N_("_Back"), self.prevClicked),
                             ('gtk-go-forward', "nextButtonStock",
                              N_("_Next"), self.nextClicked),
                             ('gtk-new', "releaseButton",
			       N_("_Release Notes"), self.releaseClicked),
                             ('gtk-help', "showHelpButton",
                              N_("Show _Help"), self.helpClicked),
                             ('gtk-help', "hideHelpButton",
                              N_("Hide _Help"), self.helpClicked),
                             ('gtk-execute', 'debugButton',
                              N_("_Debug"), self.debugClicked))

        self.reloadRcQueued = 0
        self.ii = ii
        self.dispatch = dispatch
	self.setLanguage(locale)
        self.handle = None

    def keyRelease (self, window, event):
        if ((event.keyval == gtk.keysyms.KP_Delete
             or event.keyval == gtk.keysyms.Delete)
            and (event.state & (gtk.gdk.CONTROL_MASK | gtk.gdk.MOD1_MASK))):
            gtk.mainquit()
            os._exit(0)
        # XXX hack: remove me when the accelerators work again.
        elif (event.keyval == gtk.keysyms.F12
              and self.currentWindow.getICS().getNextEnabled()):
            self.nextClicked()
	elif (event.keyval == gtk.keysyms.Print
	      and event.state & gtk.gdk.SHIFT_MASK):
	    takeScreenShot()

    def buildStockButtons(self):
	for (icon, item, text, action) in self.stockButtons:
            button = gtk.Button()
            box = gtk.HBox(gtk.FALSE, 0)
            image = gtk.Image()
            image.set_from_stock(icon, gtk.ICON_SIZE_BUTTON)
            box.pack_start(image, gtk.FALSE, gtk.FALSE)
            label = gtk.Label(_(text))
            label.set_property("use-underline", gtk.TRUE)
            box.pack_start(label, gtk.TRUE, gtk.TRUE)
            button.add(box)
	    button.connect("clicked", action)
	    button.show_all()
            button.label = label
	    self.__dict__[item] = button

    def updateStockButtons(self):
	for (icon, item, text, action) in self.stockButtons:
	    button = self.__dict__[item]

            for child in button.get_children():
                button.remove(child)

            # FIXME: this is cut and pasted from above; make a nicer
            # function that knows how to replace the contents in the
            # button for a future release
            box = gtk.HBox(gtk.FALSE, 0)
            image = gtk.Image()
            image.set_from_stock(icon, gtk.ICON_SIZE_BUTTON)
            box.pack_start(image, gtk.FALSE, gtk.FALSE)
            label = gtk.Label(_(text))
            label.set_property("use-underline", gtk.TRUE)
            box.pack_start(label, gtk.TRUE, gtk.TRUE)
            button.add(box)
            button.show_all()
            button.label = label
            button.queue_resize()

    def findPixmap(self, file):
        for path in ("/mnt/source/" + productSite + "/RHupdates/pixmaps/",
		     "/mnt/source/" + productSite + "/RHupdates/",
                     "/tmp/updates/pixmaps/", "/tmp/updates/",
        	     "/mnt/source/RHupdates/pixmaps/",
                     "/mnt/source/RHupdates/",
                     "/tmp/product/pixmaps/", "/tmp/product/",
                     "/usr/share/anaconda/pixmaps/", "pixmaps/",
                     "/usr/share/pixmaps/",
                     "/usr/share/anaconda/", ""):
            fn = path + file
            if os.access(fn, os.R_OK):
                return fn
        return None
                
    def setup_window (self, runres):
        self.window = gtk.Window ()
        global mainWindow
        mainWindow = self.window
        self.window.set_events (gtk.gdk.KEY_RELEASE_MASK)

        if runres == '640x480':
            self.window.set_default_size (640, 480)
            self.window.set_size_request (640, 480)
        else:
            self.window.set_default_size (800, 600)
            self.window.set_size_request (800, 600)

        self.window.set_border_width (10)

	title = _("%s Installer") % (productName,)
	if os.environ["DISPLAY"][:1] != ':':
	    # from gnome.zvt import *
	    # zvtwin = gtk.Window ()
#	    shtitle = _("Red Hat Linux Install Shell")
	    try:
		f = open ("/tmp/netinfo", "r")
	    except:
		pass
	    else:
		lines = f.readlines ()
		f.close ()
		for line in lines:
		    netinf = string.splitfields (line, '=')
		    if netinf[0] == "HOSTNAME":
			title = _("%s Installer on %s") % (productName, string.strip (netinf[1]))
#			shtitle = _("Red Hat Linux Install Shell on %s") % string.strip (netinf[1])
			break

	    # zvtwin.set_title (shtitle)
	    # zvt = ZvtTerm (80, 24)
	    # if zvt.forkpty() == 0:
	    #     os.execv ("/bin/sh", [ "/bin/sh" ])
	    # zvt.show ()
	    # zvtwin.add (zvt)
	    # zvtwin.show_all ()

	self.window.set_title (title)
        self.window.set_position (gtk.WIN_POS_CENTER)
        self.window.set_border_width(0)
        vbox = gtk.VBox (gtk.FALSE, 10)

        image = self.configFileData["TitleBar"]

        pixbuf = None
        # Create header at the top of the installer
        if runres != '640x480':
            fn = self.findPixmap(image)
            if not fn:
                log("unable to load %s", image)
	    else :
                pixbuf = gtk.gdk.pixbuf_new_from_file(fn)
                
            if pixbuf:
                p = gtk.Image()
                p.set_from_pixbuf(pixbuf)
                a = gtk.Alignment()
                a.set(0.5, 0.5, 1.0, 1.0)
                a.add(p)
                vbox.pack_start(a, gtk.FALSE, gtk.TRUE, 0)
            else:
                print _("Unable to load title bar")


	self.loadReleaseNotes()

        vbox.set_spacing(0)

        self.buttonBox = gtk.HButtonBox ()
        self.buttonBox.set_layout (gtk.BUTTONBOX_END)
        self.buttonBox.set_spacing (30)

	self.buildStockButtons()

        group = gtk.AccelGroup()
        self.window.add_accel_group(group)
        self.nextButtonStock.add_accelerator('clicked', group,
                                             gtk.keysyms.F12,
                                             gtk.gdk.RELEASE_MASK, 0);

        # set up ctrl+alt+delete handler
        self.window.connect ("key-release-event", self.keyRelease)

        if DEBUG:
            self.buttonBox.add (self.debugButton)
            
        self.buttonBox.add (self.prevButtonStock)
        self.buttonBox.add (self.nextButtonStock)

	self.hbox = gtk.HBox ()
        self.hbox.set_border_width(5)
	self.hbox.pack_start (self.hideHelpButton, gtk.FALSE)
        self.hbox.set_spacing (25)
        self.hbox.pack_start (self.releaseButton, gtk.FALSE)
	self.hbox.pack_start (self.buttonBox)

        vbox.pack_end (self.hbox, gtk.FALSE)

        self.help = TextViewBrowser()

        self.displayHelp = gtk.TRUE
        self.helpState = gtk.TRUE

        self.helpFrame = gtk.Frame (_("Online Help"))
        self.box = gtk.VBox (gtk.FALSE, 0)
        self.box.set_spacing(0)

        self.help_sw = gtk.ScrolledWindow()
        self.help_sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.help_sw.set_shadow_type(gtk.SHADOW_IN)
        self.help_sw.add(self.help)
        self.box.pack_start(self.help_sw, gtk.TRUE)
        
        self.helpFrame.add (self.box)

        table = gtk.Table (1, 3, gtk.TRUE)
        table.attach (self.helpFrame, 0, 1, 0, 1,
                      gtk.FILL | gtk.EXPAND,
                      gtk.FILL | gtk.EXPAND)

        self.installFrame = gtk.Frame ()

        self.windowList = []

        #self.setStateList (self.steps, 0)
        self.setScreen ()
                          
        table.attach (self.installFrame, 1, 3, 0, 1,
                      gtk.FILL | gtk.EXPAND,
                      gtk.FILL | gtk.EXPAND)
        table.set_col_spacing (0, 5)

        self.bin = gtk.Frame ()
        self.bin.set_shadow_type (gtk.SHADOW_NONE)
        self.bin.add (table)
        vbox.pack_end (self.bin, gtk.TRUE, gtk.TRUE)
        self.table = table

        self.window.add (vbox)

        # Popup the ICW and wait for it to wake us back up
        self.window.show_all ()

        splashScreenPop()

    def busyCursorPush(self):
        rootPushBusyCursor()
        
    def busyCursorPop(self):
        rootPopBusyCursor()
        
    def run (self, runres, configFileData):
        self.configFileData = configFileData
        self.setup_window(runres)
        gtk.main()
            
class InstallControlState:
    def __init__ (self, cw):
        self.searchPath = ("/mnt/source/RHupdates",
                           "./", "/usr/share/anaconda/")
        self.cw = cw
        self.prevEnabled = 1
        self.nextEnabled = 1
	self.nextButtonInfo = None
        self.helpButtonEnabled = gtk.TRUE
        self.title = _("Install Window")
        self.html = ""
        self.htmlFile = None
        self.nextButton = 'gtk-next'
        self.prevButton = 'gtk-prev'
        self.nextButtonLabel = None
        self.prevButtonLabel = None
        # Values other than gtk.TRUE or gtk.FALSE don't change the help setting        
        self.helpEnabled = 3 
        self.grabNext = 0

    def setTitle (self, title):
        self.title = title
        self.cw.update (self)
        
    def getTitle (self):
        return self.title

    def setPrevEnabled (self, value):
        if value == self.prevEnabled: return
        self.prevEnabled = value
        self.cw.update (self)

    def getPrevEnabled (self):
        return self.prevEnabled
    
    def setNextEnabled (self, value):
        if value != self.nextEnabled:
	    self.nextEnabled = value
	    self.cw.update (self)

    def getNextEnabled (self):
        return self.nextEnabled

    def setHelpButtonEnabled (self, value):
        if value == self.helpButtonEnabled: return
        self.helpButtonEnabled = value
        self.cw.update (self)

    def getHelpButtonEnabled (self):
        return self.helpButtonEnabled

    def findPixmap(self, file):
        for path in ("/mnt/source/" + productSite + "/RHupdates/pixmaps/",
		     "/mnt/source/" + productSite + "/RHupdates/",
                     "/tmp/updates/pixmaps/", "/tmp/updates/",
        	     "/mnt/source/RHupdates/pixmaps/",
                     "/mnt/source/RHupdates/",
                     "/tmp/product/pixmaps/", "/tmp/product/",
                     "/usr/share/anaconda/pixmaps/", "pixmaps/",
                     "/usr/share/pixmaps/",
                     "/usr/share/anaconda/", ""):
            fn = path + file
            if os.access(fn, os.R_OK):
                return fn
        return None
        
    def readPixmap (self, file, height = None, width = None):
        fn = self.findPixmap(file)
        if not fn:
            log("unable to load %s", file)
            return None
        try:
            pixbuf = gtk.gdk.pixbuf_new_from_file(fn)
        except RuntimeError, msg:
            log("unable to read %s: %s", file, msg)
            return None
        if (height is not None and width is not None
            and height != pixbuf.get_height()
            and width != pixbuf.get_width()):
            sclpix = pixbuf.scale_simple(height, width,
                                         gtk.gdk.INTERP_BILINEAR)
            p = gtk.Image()
            p.set_from_pixbuf(sclpix)
        else:
            source = gtk.IconSource()
            source.set_pixbuf(pixbuf)
            source.set_size(gtk.ICON_SIZE_DIALOG)
            source.set_size_wildcarded(gtk.FALSE)
            iconset = gtk.IconSet()
            iconset.add_source(source)
            p = gtk.image_new_from_icon_set(iconset, gtk.ICON_SIZE_DIALOG)
        return p

    def readPixmapDithered(self, file, height = None, width = None):
        fn = self.findPixmap(file)
        if not fn:
            log("unable to load %s", file)
            return None
        try:
            pixbuf = gtk.gdk.pixbuf_new_from_file(fn)
        except RuntimeError, msg:
            log("unable to read %s: %s", file, msg)
            return None
        if (height is not None and width is not None
            and height != pixbuf.get_height()
            and width != pixbuf.get_width()):
            pixbuf = pixbuf.scale_simple(height, width,
                                         gtk.gdk.INTERP_BILINEAR)

        (pixmap, mask) = pixbuf.render_pixmap_and_mask()
        pixbuf.render_to_drawable(pixmap, gtk.gdk.GC(pixmap), 0, 0, 0, 0,
                                  pixbuf.get_width(), pixbuf.get_height(),
                                  gtk.gdk.RGB_DITHER_MAX, 0, 0)
        p = gtk.Image()
        p.set_from_pixmap(pixmap, mask)
        return p

    def readHTML (self, file):
        self.htmlFile = file

    def setHTML (self, text):
        self.html = text
        self.cw.update (self)

    def getHTML (self, langPath):
        text = None
        if self.htmlFile:
            file = self.htmlFile

            if self.cw.configFileData.has_key("helptag"):
                helpTag = "-%s" % (self.cw.configFileData["helptag"],)
            else:
                helpTag = ""

            arch = "-%s" % (iutil.getArch(),)
            tags = [ "%s%s" % (helpTag, arch), "%s" % (helpTag,),
                     "%s" % (arch,), "" ]

            found = 0
            for path in self.searchPath:
                if found:
                    break
                for lang in langPath + ['C']:
                    if found:
                        break
                    for tag in tags:
                        try:
                            text = open("%s/help/%s/s1-help-screens-%s%s.html"
                                        % (path, lang, file, tag)).read ()
                            found = 1
                            break
                        except IOError:
                            continue
                if text:
                    break

            if text:
                text = text.replace("@RHL@", productName)
                text = text.replace("@RHLVER@", productVersion)
                return text

            print "Unable to read %s help text" % (file,)

        return self.html
    
    def setScreenPrev (self):
        self.cw.prevClicked ()

    def setScreenNext (self):
        self.cw.nextClicked ()

    def setHelpEnabled (self, value):
        self.helpEnabled = value
        self.cw.update (self)

    def getHelpEnabled (self):
        return self.helpEnabled

    def setGrabNext (self, value):
        self.grabNext = value
        self.cw.update (self)

    def getGrabNext (self):
        return self.grabNext

    def getICW (self):
        return self.cw

    def setNextButton(self, icon, text):
	self.nextButtonInfo = (icon, text)

    def getNextButton(self):
	return self.nextButtonInfo