|
Server : Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8e-fips-rhel5 DAV/2 PHP/5.2.17 System : Linux localhost 2.6.18-419.el5 #1 SMP Fri Feb 24 22:47:42 UTC 2017 x86_64 User : nobody ( 99) PHP Version : 5.2.17 Disable Function : NONE Directory : /proc/21572/root/usr/share/firstboot/ |
Upload File : |
## firstbootWindow.py - the main firstboot UI and framework.py
##
## Copyright (C) 2002, 2003 Red Hat, Inc.
## Copyright (C) 2002, 2003 Brent Fox <bfox@redhat.com>
##
## 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, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
import string
import os
import traceback
os.environ["PYGTK_DISABLE_THREADS"] = "1"
os.environ["PYGTK_FATAL_EXCEPTIONS"] = "1"
os.environ["GNOME_DISABLE_CRASH_DIALOG"] = "1"
import sys
import gtk
import functions
import firstbootBackend
from firstboot import Firstboot
from rhpl.translate import cat
from rhpl import ethtool
##
## I18N
##
from rhpl.translate import _, N_
import rhpl.translate as translate
translate.textdomain ("firstboot")
#
# Stuff for screenshots
#
screenshotDir = None
screenshotIndex = 0
class firstbootWindow:
def __init__(self, fb):
self.needsReboot = []
self.xserver_pid = fb.xserver_pid
self.wm_pid = fb.wm_pid
self.doReconfig = fb.doReconfig
self.doDebug = fb.doDebug
self.lowRes = fb.lowRes
self.autoscreenshot = fb.autoscreenshot
self.moduleList = []
self.moduleDict = {}
self.pageHistory = []
self.nextPage = None
# Create the initial window and a vbox to fill it with.
self.win = gtk.Window()
self.win.set_position(gtk.WIN_POS_CENTER)
self.win.set_decorated(False)
if not self.doReconfig:
self.win.set_keep_below(True)
self.x_screen = gtk.gdk.screen_width()
self.y_screen = gtk.gdk.screen_height()
# Create a box that will hold all other widgets.
self.mainHBox = gtk.HBox(False, 10)
# leftVBox holds the labels for the various modules.
self.leftVBox = gtk.VBox()
self.leftVBox.set_border_width(5)
# leftEventBox exists only so we have somewhere to paint an image.
self.leftEventBox = gtk.EventBox()
self.leftEventBox.add(self.leftVBox)
self.leftEventBox.connect("realize", self.leb_realized)
# rightVBox holds the notebook and the button box.
self.rightVBox = gtk.VBox()
self.rightVBox.set_border_width(5)
# If we're in low res mode, grow the right hand box to take up the
# entire window.
if self.x_screen >= 800:
self.leftEventBox.set_size_request(int(0.2*self.x_screen),
self.y_screen)
self.rightVBox.set_size_request(int(0.8*self.x_screen),
self.y_screen)
self.win.fullscreen()
else:
self.rightVBox.set_size_request(self.x_screen, self.y_screen)
self.win.set_size_request(self.x_screen, self.y_screen)
self.lowRes = 1
# Create a button box to handle navigation.
self.buttonBox = gtk.HButtonBox()
self.buttonBox.set_layout(gtk.BUTTONBOX_END)
self.buttonBox.set_spacing(10)
# Create the "go back" button, marking it insensitive by default.
self.backButton = gtk.Button(use_underline=True, stock='gtk-go-back',
label=_("_Back"))
self.backButton.set_sensitive(False)
self.backButton.connect('clicked', self.backClicked)
self.buttonBox.set_border_width(10)
self.buttonBox.pack_start(self.backButton)
# Create the "go forward" button.
self.nextButton = gtk.Button(use_underline=True, stock='gtk-go-forward',
label=_("_Forward"))
self.nextHandler = self.nextButton.connect('clicked', self.nextClicked)
self.buttonBox.pack_start(self.nextButton)
# Create the notebook. We use a ListView to control which page in the
# notebook is displayed.
self.notebook = gtk.Notebook()
if self.doDebug:
#self.modulePath = ('/usr/src/rhn/up2date/firstboot')
self.modulePath = ('/usr/share/firstboot/modules')
self.notebook.set_show_tabs(False)
self.notebook.set_scrollable(True)
self.notebook.set_show_border(False)
else:
self.modulePath = ('/usr/share/firstboot/modules')
self.notebook.set_show_tabs(False)
self.notebook.set_show_border(False)
self.notebook.connect("switch-page", self.switchPage)
sys.path.append(self.modulePath)
self.loadModules()
self.notebook.set_current_page(0)
self.setPointer(0)
# Add the widgets into the right side.
self.rightVBox.pack_start(self.notebook)
self.rightVBox.pack_start(self.buttonBox, expand=False)
# Add the widgets into the main widget.
if not self.lowRes:
self.mainHBox.pack_start(self.leftEventBox)
self.mainHBox.pack_start(self.rightVBox)
self.win.add(self.mainHBox)
self.win.connect("destroy", self.destroy)
self.winHandler = self.win.connect ("key-release-event",
self.keyRelease)
# This should really be in firstboot.py, but something about
# importing all the modules screws the keyboard up only when we
# start from rhgb. So here it is.
if not fb.doDebug:
from rhpl.keyboard import Keyboard
kbd = Keyboard()
kbd.read()
kbd.activate()
self.win.show_all()
self.win.present()
self.nextButton.grab_focus()
gtk.main()
def setPage(self, modulename):
self.nextPage = self.moduleNameToIndex[modulename][0]
def switchPage(self, notebook, page, page_num, *args):
# catch the switch page signal, so we can re poke modules
# that need a signal that they are being shown
try:
module = self.moduleList[page_num]
except:
pass
if hasattr(module, "updatePage"):
module.updatePage()
def destroy(self, *args):
#Exit the GTK loop
gtk.main_quit()
#Kill the window manager
if self.wm_pid and not self.doDebug:
os.kill(self.wm_pid, 15)
if self.xserver_pid and not self.doDebug:
os.kill(self.xserver_pid, 15)
#Exit firstboot. This should take down the X server as well
os._exit(0)
def finishClicked(self, *args):
try:
module = self.moduleList[self.notebook.get_current_page()]
except:
pass
#Call the apply method if it exists
try:
module.apply(self.notebook)
except:
pass
#Call exitFirstboot to do some cleanup before exiting
self.exitFirstboot()
def exitFirstboot(self, *args):
#Write the /etc/sysconfig/firstboot file to make sure firstboot doesn't run again
firstbootBackend.writeSysconfigFile(self.doDebug)
#Exit the GTK loop
gtk.main_quit()
if self.doDebug:
os._exit(0)
if self.wm_pid:
# Kill the window manager
os.kill(self.wm_pid, 15)
if self.doReconfig:
try:
os.unlink("/etc/reconfigSys")
except:
pass
if len(self.needsReboot) > 0:
dlg = gtk.MessageDialog(None, 0, gtk.MESSAGE_INFO, gtk.BUTTONS_OK,
_("The system must now reboot for some of your selections to take effect."))
dlg.set_position(gtk.WIN_POS_CENTER)
dlg.show_all()
dlg.run()
dlg.destroy()
os.system("/sbin/reboot")
if self.xserver_pid:
os.kill(self.xserver_pid, 15)
#Give the X server a second to exit
import time
time.sleep(1)
os._exit(0)
def nextClicked(self, *args):
try:
module = self.moduleList[self.notebook.get_current_page()]
except:
pass
if self.autoscreenshot:
self.takeScreenShot()
result = None
#Call the apply method if it exists
try:
result = module.apply(self.notebook)
except:
import exceptionWindow
(ty, value, tb) = sys.exc_info()
lst = traceback.format_exception(ty, value, tb)
text = string.joinfields(lst, "")
result = exceptionWindow.ExceptionWindow(module, text)
pass
# Store the name of every module that requires a reboot. This allows
# us to remove a single module if the user moves back and forth through
# the UI while still knowing that other modules still require reboot.
if hasattr(module, "needsReboot") and module.needsReboot:
print "adding needsReboot for %s" % module.moduleName
self.needsReboot.append(module.moduleName)
elif hasattr(module, "needsReboot") and not module.needsReboot:
if module.moduleName in self.needsReboot:
print "removing needsReboot for %s" % module.moduleName
self.needsReboot.remove(module.moduleName)
# record the current page as the new previous page
self.prevPage = self.moduleNameToIndex[module.__module__][0]
if result != None:
pgNum = self.moduleNameToIndex[module.__module__][0]
self.pageHistory.append(pgNum)
# print "self.pageHistory: %s" % self.pageHistory
if self.nextPage:
self.notebook.set_current_page(self.nextPage)
module = self.moduleList[self.nextPage]
self.nextPage = None
else:
self.notebook.next_page()
module = self.moduleList[self.notebook.get_current_page()]
#Call setPointer to make the left hand pointer move to the correct pointer
self.setPointer(self.moduleNameToIndex[module.__module__][1])
if "grabFocus" in dir(module):
#If the module needs to grab the focus, let it
module.grabFocus()
else:
#Something went wrong in the module. Don't advance
return
#Check to see if we're on the last page.
tmp = self.notebook.get_nth_page(self.notebook.get_current_page() + 1)
if not tmp:
self.nextButton.disconnect(self.nextHandler)
self.nextHandler = self.nextButton.connect('clicked', self.finishClicked)
self.nextButton.set_label(_("_Finish"))
self.nextButton.set_use_underline(True)
self.win.disconnect(self.winHandler)
self.winHandler = self.win.connect ("key-release-event", self.closeRelease)
self.backButton.set_sensitive(True)
def backClicked(self, *args):
# print "back: %s" % self.pageHistory
if len(self.pageHistory):
self.notebook.set_current_page(self.pageHistory[-1])
del self.pageHistory[-1]
else:
self.notebook.prev_page()
try:
module = self.moduleList[self.notebook.get_current_page()]
except:
pass
#Call setPointer to make the left hand pointer move to the correct pointer
self.setPointer(self.moduleNameToIndex[module.__module__][1])
if self.notebook.get_current_page() == 0:
self.backButton.set_sensitive(False)
self.nextButton.disconnect(self.nextHandler)
self.nextHandler = self.nextButton.connect('clicked', self.nextClicked)
self.nextButton.set_label('gtk-go-forward')
self.nextButton.set_use_stock(True)
self.nextButton.set_use_underline(True)
self.win.disconnect(self.winHandler)
self.winHandler = self.win.connect ("key-release-event", self.keyRelease)
def keyRelease(self, window, event):
if (event.keyval == gtk.keysyms.F12):
self.nextClicked()
if (event.keyval == gtk.keysyms.F11):
self.backClicked()
if (event.keyval == gtk.keysyms.Print and event.state & gtk.gdk.SHIFT_MASK):
self.takeScreenShot()
def closeRelease(self, window, event):
if (event.keyval == gtk.keysyms.F12):
self.finishClicked()
if (event.keyval == gtk.keysyms.F11):
self.backClicked()
def setPointer(self, number):
items = self.leftVBox.get_children()
for i in range(len(items)):
alignment, label = self.leftVBox.get_children()[i].get_children()
pix = alignment.get_children()[0]
if i == number:
pix.set_from_file("/usr/share/firstboot/pixmaps/pointer-white.png")
else:
pix.set_from_file("/usr/share/firstboot/pixmaps/pointer-blank.png")
def leb_realized(self, eb):
self.pixbuf = functions.pixbufFromPath("/usr/share/firstboot/pixmaps/firstboot-left.png")
scaledPixbuf = self.pixbuf.scale_simple(int(0.2*self.x_screen),
self.y_screen,
gtk.gdk.INTERP_BILINEAR)
bgimage = gtk.gdk.Pixmap(eb.window, int(0.2*self.x_screen),
self.y_screen, -1)
bgimage.draw_pixbuf(None, scaledPixbuf, 0, 0, 0, 0)
style = gtk.Style()
style.bg_pixmap[gtk.STATE_NORMAL] = bgimage
eb.set_style(style)
def checkNetwork(self):
# see if we have a non loopback interface up
intfs = ethtool.get_active_devices()
for intf in intfs:
if intf != "lo":
return 1
return 0
def loadModules(self):
self.moduleList = []
self.moduleDict = {}
# Generate a list of all of the module files (which becomes the list of
# all non-hidden files in the directory with extensions other than .py.
files = os.listdir(self.modulePath)
lst = []
for f in files:
if f[0] == '.':
continue
if f[-3:] != ".py":
continue
lst.append(f[:-3])
# Import each module, and filter out those
for module in lst:
cmd = ("import %s\nif %s.__dict__.has_key('childWindow'):"
"obj = %s.childWindow()") % (module, module, module)
try:
exec(cmd)
except:
print _("module import of %s failed: %s") % (module,sys.exc_type)
continue
# if the exec fails, skip this module
try:
obj = obj
except NameError:
continue
# XXX - hack to allow firstboot to pass in the parent class into language
# this will allow the language module to change firstboot's current locale
if module == "language" or hasattr(obj, "needsparent"):
obj.passInParent(self)
# if a module decides not to run, skip it first before trying any
# of the other hooks. bz #158095
if hasattr(obj, "skipme"):
# the module itself has decided for some reason that
# that it should not be shown, so skip it
continue
# if the module needs network access, and we dont have it, skip
# the module
if hasattr(obj, "needsnetwork"):
if not self.checkNetwork():
# we need a way to run some stuff from the modules
# if they have no network
if hasattr(obj, "noNetwork"):
obj.noNetwork()
continue
# If the module defines a moduleClass, it has to match the mode
# we're starting up in, otherwise it's always used. Add it to
# a dictionary keyed by the module's declared priority.
if hasattr(obj, "moduleClass"):
if (self.doReconfig and (obj.moduleClass == "reconfig")):
self.moduleDict[float(obj.runPriority)] = obj
elif (not self.doReconfig and (obj.moduleClass != "reconfig")):
self.moduleDict[float(obj.runPriority)] = obj
else:
self.moduleDict[float(obj.runPriority)] = obj
# Get the list of module priorities, sort them to determine a run
# order, and build a list with the modules in the proper order.
modulePriorityList = self.moduleDict.keys()
modulePriorityList.sort()
# Add the modules to the proper lists.
pages = 0
sidebarIndex = -1
self.moduleNameToIndex = {}
for priority in modulePriorityList:
# Add the module to the list of modules.
module = self.moduleDict[priority]
# Launch the module's GUI.
vbox = None
if self.doDebug:
try:
print "calling", module.moduleName
result = module.launch(self.doDebug)
if result is None:
continue
else:
vbox, pix, title = result
except:
import exceptionWindow
(ty, value, tb) = sys.exc_info()
lst = traceback.format_exception(ty, value, tb)
text = string.joinfields(lst, "")
exceptionWindow.ExceptionWindow(module, text)
pass
else:
try:
result = module.launch()
if result is None:
continue
else:
vbox, pix, title = result
except:
import exceptionWindow
(ty, value, tb) = sys.exc_info()
lst = traceback.format_exception(ty, value, tb)
text = string.joinfields(lst, "")
exceptionWindow.ExceptionWindow(module, text)
pass
continue
if vbox and title:
# If it launched, add it to the module list.
self.moduleList.append(module)
title_label = gtk.Label("")
title_label.set_alignment(0.0, 0.5)
title_label.set_markup("<span foreground='#000000' size='30000' font_family='Helvetica'><b>%s</b></span>" % (_(title)))
titleBox = gtk.HBox()
if pix:
titleBox.pack_start(pix, False)
titleBox.pack_start(title_label, True)
titleBox.set_spacing(8)
vbox.pack_start(titleBox, False)
vbox.reorder_child(titleBox, 0)
if self.lowRes:
# If we're in 640x480 mode, remove the title bars
vbox.remove(vbox.get_children()[0])
# If the module has a name, add it to the list of labels
if hasattr(module, "moduleName"):
if not hasattr(module, "noSidebar") or getattr(module, "noSidebar") == False:
hbox = gtk.HBox(False, 5)
pix = functions.imageFromFile("pointer-blank.png")
label = gtk.Label("")
label.set_markup("<span foreground='#FFFFFF'><b>%s</b></span>" % (_(module.moduleName)))
label.set_alignment(0.0, 0.5)
# Wrap the lines if they're too long
label.set_line_wrap(True)
(w, h) = self.leftEventBox.get_size_request()
label.set_size_request((int)(w*0.8), -1)
# Make sure the arrow is at the top of any wrapped line
alignment = gtk.Alignment(yalign=0.2)
alignment.add(pix)
hbox.pack_start(alignment, False)
hbox.pack_end(label, True)
self.leftVBox.pack_start(hbox, False, True, 3)
sidebarIndex += 1
# we need a non tranlated name for each module so we can
# jump around
self.moduleNameToIndex[module.__module__] = (pages, sidebarIndex)
self.notebook.append_page(vbox, gtk.Label(_(module.moduleName)))
else:
self.notebook.append_page(vbox, gtk.Label(" "))
self.moduleNameToIndex["unamemodule-%s" % pages] = (pages, sidebarIndex)
pages += 1
def clearNotebook(self):
for widget in self.leftVBox.get_children():
self.leftVBox.remove(widget)
pageNum = len(self.notebook.get_children())
for i in range(pageNum):
self.notebook.hide()
self.notebook.remove_page(i)
def changeLocale(self, lang, fullName):
lc, encoding = string.split(lang, ".")
prefix, suffix = string.split(lc, "_")
os.environ["RUNTIMELANG"] = fullName
os.environ["LANG"] = lc
os.environ["LC_NUMERIC"] = "C"
import locale
locale.setlocale(locale.LC_ALL, "")
newlangs = [lang, lc, prefix]
cat.setlangs(newlangs)
self.leftVBox.get_children()[0].get_children()[1].set_text(_("Welcome"))
# Change the locale on the buttons.
self.backButton.set_label('gtk-go-back')
self.backButton.set_use_stock(True)
self.backButton.set_use_underline(True)
self.nextButton.set_label('gtk-go-forward')
self.nextButton.set_use_stock(True)
self.nextButton.set_use_underline(True)
self.clearNotebook()
self.loadModules()
self.leftVBox.show_all()
self.notebook.show_all()
self.notebook.set_current_page(1)
def takeScreenShot(self):
global screenshotIndex
global screenshotDir
#Let's take some screenshots
if screenshotDir is None:
screenshotDir = "/root/firstboot-screenshots"
if not os.access(screenshotDir, os.R_OK):
try:
os.mkdir(screenshotDir)
except:
screenshotDir = None
screen_width = gtk.gdk.screen_width()
screen_height = gtk.gdk.screen_height()
src_x = (screen_width - 800) / 2
src_y = (screen_height - 600) / 2
screenshot = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8,
800, 600)
screenshot.get_from_drawable(gtk.gdk.get_default_root_window(),
gtk.gdk.colormap_get_system(),
src_x, src_y, 0, 0,
800, 600)
if screenshot:
while (1):
sname = "screenshot-%04d.png" % ( screenshotIndex,)
if not os.access(screenshotDir + '/' + sname, os.R_OK):
break
screenshotIndex = screenshotIndex + 1
screenshot.save (screenshotDir + '/' + sname, "png")
screenshotIndex = screenshotIndex + 1