| 1 |
#!/usr/bin/python |
| 2 |
|
| 3 |
# Copyright 1999-2005 Gentoo Foundation |
| 4 |
# This source code is distributed under the terms of version 2 of the GNU |
| 5 |
# General Public License as published by the Free Software Foundation, a copy |
| 6 |
# of which can be found in the main directory of this project. |
| 7 |
|
| 8 |
import sys |
| 9 |
sys.path.append("../..") |
| 10 |
|
| 11 |
import GLIInstallProfile |
| 12 |
import GLIClientController |
| 13 |
import GLIUtility |
| 14 |
from GLIFutureBar import GLIFutureBar |
| 15 |
#from HelpDialog import HelpDialog |
| 16 |
from SplashScreen import SplashScreen |
| 17 |
import gtk |
| 18 |
import pango |
| 19 |
import gobject |
| 20 |
import crypt |
| 21 |
import random |
| 22 |
from gettext import gettext as _ |
| 23 |
import TextBufferMarkup |
| 24 |
|
| 25 |
import RunInstall |
| 26 |
|
| 27 |
class Installer: |
| 28 |
|
| 29 |
SHOW_BUTTON_FINISH = 1 |
| 30 |
SHOW_BUTTON_FORWARD = 1 |
| 31 |
SHOW_BUTTON_BACK = 1 |
| 32 |
# SHOW_BUTTON_HELP = 1 |
| 33 |
SHOW_BUTTON_EXIT = 1 |
| 34 |
install_profile_xml_file = "" |
| 35 |
install_window = None |
| 36 |
install_type = "standard" |
| 37 |
|
| 38 |
menuItems = [ { 'text': _('Welcome'), 'module': __import__("Welcome") }, |
| 39 |
# { 'text': _('Pre-install Config'), 'module': __import__("ClientConfig") }, |
| 40 |
{ 'text': _('Partitioning'), 'module': __import__("Partition") }, |
| 41 |
# { 'text': _('Network Mounts'), 'module': __import__("NetworkMounts") }, |
| 42 |
{ 'text': _('Stage'), 'module': __import__("Stage") }, |
| 43 |
{ 'text': _('Portage tree'), 'module': __import__("PortageTree") }, |
| 44 |
{ 'text': _('make.conf'), 'module': __import__("MakeDotConf") }, |
| 45 |
{ 'text': _('Kernel'), 'module': __import__("Kernel") }, |
| 46 |
{ 'text': _('Bootloader'), 'module': __import__("Bootloader") }, |
| 47 |
{ 'text': _('Timezone'), 'module': __import__("Timezone") }, |
| 48 |
{ 'text': _('Networking'), 'module': __import__("Networking") }, |
| 49 |
{ 'text': _('Daemons'), 'module': __import__("Daemons") }, |
| 50 |
{ 'text': _('Extra Packages'), 'module': __import__("ExtraPackages") }, |
| 51 |
{ 'text': _('Startup Services'), 'module': __import__("StartupServices") }, |
| 52 |
{ 'text': _('Other Settings'), 'module': __import__("OtherSettings") }, |
| 53 |
{ 'text': _('Users'), 'module': __import__("Users") }, |
| 54 |
{ 'text': _('Review'), 'module': __import__("InstallSummary") } |
| 55 |
] |
| 56 |
|
| 57 |
def __init__(self): |
| 58 |
# self.client_profile = GLIClientConfiguration.ClientConfiguration() |
| 59 |
self.install_profile = GLIInstallProfile.InstallProfile() |
| 60 |
self._pretend = False |
| 61 |
self._debug = False |
| 62 |
|
| 63 |
for arg in sys.argv: |
| 64 |
if arg == "-p" or arg == "--pretend": |
| 65 |
self._pretend = True |
| 66 |
elif arg == "-d" or arg == "--debug": |
| 67 |
self._debug = True |
| 68 |
|
| 69 |
self.cc = GLIClientController.GLIClientController(pretend=self._pretend) |
| 70 |
|
| 71 |
self.window = None |
| 72 |
self.panel = None |
| 73 |
self._cur_panel = 0 |
| 74 |
self.__full_path = self.get_current_path() |
| 75 |
self.splash = SplashScreen(self.__full_path) |
| 76 |
self.splash.show() |
| 77 |
while gtk.events_pending(): |
| 78 |
gtk.main_iteration() |
| 79 |
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) |
| 80 |
self.title = _("Gentoo Linux Installer") |
| 81 |
self.window.realize() |
| 82 |
self.window.connect("delete_event", self.delete_event) |
| 83 |
self.window.connect("destroy", self.destroy) |
| 84 |
self.window.set_border_width(0) |
| 85 |
self.window.set_default_size(800,600) |
| 86 |
self.window.set_geometry_hints(None, min_width=800, min_height=600, max_width=800, max_height=600) |
| 87 |
self.window.set_title(_("Gentoo Linux Installer")) |
| 88 |
self.globalbox = gtk.VBox(False, 0) |
| 89 |
self.window.add(self.globalbox) |
| 90 |
|
| 91 |
# Banner image |
| 92 |
self.headerbox = gtk.HBox(False, 0) |
| 93 |
headerimg = gtk.Image() |
| 94 |
headerimg.set_from_file(self.__full_path + '/installer-banner-800x64.png') |
| 95 |
self.headerbox.add(headerimg) |
| 96 |
self.globalbox.pack_start(self.headerbox, expand=False, fill=False, padding=0) |
| 97 |
|
| 98 |
# Future bar |
| 99 |
self.futurebar = GLIFutureBar([element['text'] for element in self.menuItems]) |
| 100 |
self.globalbox.pack_start(self.futurebar, expand=False, fill=False, padding=5) |
| 101 |
self.globalbox.pack_start(gtk.HSeparator(), expand=False, fill=False, padding=0) |
| 102 |
|
| 103 |
# Top box |
| 104 |
self.topbox = gtk.HBox(False, 0) |
| 105 |
self.globalbox.pack_start(self.topbox, expand=True, fill=True, padding=5) |
| 106 |
|
| 107 |
# Bottom box |
| 108 |
self.bottombox = gtk.HBox(False, 0) |
| 109 |
self.globalbox.pack_end(self.bottombox, expand=False, fill=False, padding=5) |
| 110 |
self.globalbox.pack_end(gtk.HSeparator(), expand=False, fill=False, padding=0) |
| 111 |
|
| 112 |
# Left frame |
| 113 |
self.leftframe = gtk.Frame() |
| 114 |
self.leftframe.set_size_request(300, -1) |
| 115 |
self.leftframe.set_shadow_type(gtk.SHADOW_ETCHED_OUT) |
| 116 |
self.textbuff = TextBufferMarkup.PangoBuffer() |
| 117 |
self.textview = gtk.TextView(self.textbuff) |
| 118 |
self.textview.set_editable(False) |
| 119 |
self.textview.set_wrap_mode(gtk.WRAP_WORD) |
| 120 |
self.textview.set_left_margin(5) |
| 121 |
self.textview.set_right_margin(5) |
| 122 |
self.textview.set_sensitive(False) |
| 123 |
self.textviewscroll = gtk.ScrolledWindow() |
| 124 |
self.textviewscroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) |
| 125 |
self.textviewscroll.add(self.textview) |
| 126 |
self.leftframe.add(self.textviewscroll) |
| 127 |
self.topbox.pack_start(self.leftframe, expand=True, fill=True, padding=5) |
| 128 |
|
| 129 |
# Right frame |
| 130 |
self.rightframe = gtk.VBox(False, 0) |
| 131 |
self.topbox.pack_end(self.rightframe, expand=True, fill=True, padding=5) |
| 132 |
self.globalbox.show_all(); |
| 133 |
|
| 134 |
# Right frame contents |
| 135 |
self.panels = [] |
| 136 |
self.right_pane_box = gtk.Notebook() |
| 137 |
# for item in self.menuItems: |
| 138 |
# if item['module'] == None: break |
| 139 |
# if self._debug: |
| 140 |
# print "Instantiating " + item['text'] + " screen...", |
| 141 |
# panel = item['module'].Panel(self) |
| 142 |
# if self._debug: |
| 143 |
# print "done" |
| 144 |
# self.panels.append(panel) |
| 145 |
# self.right_pane_box.append_page(panel) |
| 146 |
self.right_pane_box.set_show_tabs(False) |
| 147 |
self.right_pane_box.set_show_border(False) |
| 148 |
self.rightframe.add(self.right_pane_box) |
| 149 |
|
| 150 |
buttons_info = [ ('exit', _(" _Exit "), '/button_images/stock_exit.png', self.exit_button, 'start'), |
| 151 |
# ('help', _(" _Help "), '/button_images/stock_help.png', self.help, 'start'), |
| 152 |
('load', _(" _Load "), '/button_images/stock_open.png', self.load_button, 'start'), |
| 153 |
('save', _(" _Save "), '/button_images/stock_save.png', self.save_button, 'start'), |
| 154 |
('finish', _(" _Install "), '/button_images/stock_exec.png', self.finish, 'end'), |
| 155 |
('forward', _(" _Forward "), '/button_images/stock_right.png', self.forward, 'end'), |
| 156 |
('back', _(" _Back "), '/button_images/stock_left.png', self.back, 'end') |
| 157 |
] |
| 158 |
self.buttons = {} |
| 159 |
|
| 160 |
for button in buttons_info: |
| 161 |
self.buttons[button[0]] = gtk.Button() |
| 162 |
tmpbuttonbox = gtk.HBox(False, 0) |
| 163 |
tmpbuttonimg = gtk.Image() |
| 164 |
tmpbuttonimg.set_from_file(self.__full_path + button[2]) |
| 165 |
tmpbuttonbox.pack_start(tmpbuttonimg) |
| 166 |
tmpbuttonlabel = gtk.Label(button[1]) |
| 167 |
tmpbuttonlabel.set_use_underline(True) |
| 168 |
tmpbuttonbox.pack_start(tmpbuttonlabel) |
| 169 |
self.buttons[button[0]].add(tmpbuttonbox) |
| 170 |
self.buttons[button[0]].connect("clicked", button[3], None) |
| 171 |
if button[4] == "start": |
| 172 |
self.bottombox.pack_start(self.buttons[button[0]], expand=False, fill=False, padding=5) |
| 173 |
else: |
| 174 |
self.bottombox.pack_end(self.buttons[button[0]], expand=False, fill=False, padding=5) |
| 175 |
|
| 176 |
gobject.idle_add(self.init_screens) |
| 177 |
|
| 178 |
def redraw_left_pane(self, firstrun=False): |
| 179 |
if not firstrun: self.leftframe.remove(self.navlinks) |
| 180 |
self.navlinks = gtk.VBox(False, 5) |
| 181 |
self.navlinks.set_size_request(140, -1) |
| 182 |
navlinkslabel = gtk.Label(_(" Installation Steps ")) |
| 183 |
self.navlinks.pack_start( navlinkslabel, expand=False, fill=False, padding=10) |
| 184 |
self.num_times = 0 |
| 185 |
for item_ in self.menuItems: |
| 186 |
item = str(self.num_times+1) + ". " + item_['text'] |
| 187 |
self.box = gtk.HBox(False,5) |
| 188 |
box_string = item |
| 189 |
box_label=gtk.Label(box_string) |
| 190 |
box_label.set_alignment(0,0) |
| 191 |
self.box.pack_start( box_label, expand=False, fill=False, padding=5) |
| 192 |
self.navlinks.pack_start( self.box, expand=False, fill=False, padding=3) |
| 193 |
box_label.set_sensitive(True) |
| 194 |
|
| 195 |
if self._cur_panel == self.num_times: |
| 196 |
box_label.set_markup('<b>'+box_string+'</b>') |
| 197 |
|
| 198 |
self.num_times = self.num_times + 1 |
| 199 |
self.leftframe.add(self.navlinks) |
| 200 |
self.leftframe.show_all() |
| 201 |
|
| 202 |
def redraw_buttons(self): |
| 203 |
self.bottombox.hide_all() |
| 204 |
self.buttons['finish'].set_sensitive(self.SHOW_BUTTON_FINISH) |
| 205 |
self.buttons['forward'].set_sensitive(self.SHOW_BUTTON_FORWARD) |
| 206 |
self.buttons['back'].set_sensitive(self.SHOW_BUTTON_BACK) |
| 207 |
# self.buttons['help'].set_sensitive(self.SHOW_BUTTON_HELP) |
| 208 |
self.buttons['exit'].set_sensitive(self.SHOW_BUTTON_EXIT) |
| 209 |
if self.SHOW_BUTTON_FORWARD: |
| 210 |
self.buttons['forward'].set_flags(gtk.CAN_DEFAULT) |
| 211 |
self.buttons['forward'].grab_default() |
| 212 |
elif self.SHOW_BUTTON_FINISH: |
| 213 |
self.buttons['finish'].set_flags(gtk.CAN_DEFAULT) |
| 214 |
self.buttons['finish'].grab_default() |
| 215 |
# if self.install_profile_xml_file != "": |
| 216 |
# self.finishbutton.set_sensitive(True) |
| 217 |
self.bottombox.show_all() |
| 218 |
|
| 219 |
def refresh_right_panel(self): |
| 220 |
self.rightframe.show_all() |
| 221 |
|
| 222 |
def make_visible(self): |
| 223 |
self.window.show_all() |
| 224 |
self.window.present() |
| 225 |
|
| 226 |
def make_invisible(self): |
| 227 |
self.window.hide_all() |
| 228 |
|
| 229 |
def get_current_path(self): |
| 230 |
# this will return the absolute path to the |
| 231 |
# directory containing this file |
| 232 |
# it will only work if this file is imported somewhere, |
| 233 |
# not if it is run directly (__file__ will be undefined) |
| 234 |
import os.path |
| 235 |
return os.path.abspath(os.path.dirname(__file__)) |
| 236 |
|
| 237 |
def add_content(self, content): |
| 238 |
self.right_pane_box.pack_end(content, True, True, 0) |
| 239 |
|
| 240 |
def get_commands(self): |
| 241 |
pass |
| 242 |
|
| 243 |
def set_active(self): |
| 244 |
self.active=1 |
| 245 |
|
| 246 |
def loadPanel(self, panel=0): |
| 247 |
if not self.panels[self._cur_panel].deactivate(): |
| 248 |
return |
| 249 |
self._cur_panel = panel |
| 250 |
self.right_pane_box.set_current_page(panel) |
| 251 |
self.panels[panel].activate() |
| 252 |
self.futurebar.setpos(panel) |
| 253 |
helptext = self.panels[panel]._helptext |
| 254 |
# helptext = " ".join(helptext.split("\n")) |
| 255 |
# helptext = "\n".join(helptext.split('<br>')) |
| 256 |
self.textbuff.set_text(helptext) |
| 257 |
self.redraw_buttons() |
| 258 |
|
| 259 |
def init_screens(self): |
| 260 |
# self.splash.show() |
| 261 |
for item in self.menuItems: |
| 262 |
if item['module'] == None: break |
| 263 |
if self._debug: |
| 264 |
print "Instantiating " + item['text'] + " screen...", |
| 265 |
panel = item['module'].Panel(self) |
| 266 |
if self._debug: |
| 267 |
print "done" |
| 268 |
self.panels.append(panel) |
| 269 |
self.right_pane_box.append_page(panel) |
| 270 |
self.splash.destroy() |
| 271 |
self.make_visible() |
| 272 |
self.loadPanel() |
| 273 |
return False |
| 274 |
|
| 275 |
def run(self): |
| 276 |
gtk.gdk.threads_init() |
| 277 |
gtk.main() |
| 278 |
|
| 279 |
def back(self, widget, data=None): |
| 280 |
if self._cur_panel > 0: |
| 281 |
self.loadPanel(self._cur_panel - 1) |
| 282 |
|
| 283 |
def forward(self, widget, data=None): |
| 284 |
if self._cur_panel < (len(self.menuItems) - 1): |
| 285 |
self.loadPanel(self._cur_panel + 1) |
| 286 |
|
| 287 |
def help(self, widget, data=None): |
| 288 |
# GLIUtility.spawn("firefox http://www.gentoo.org/doc/en/handbook/index.xml &>/dev/null &") |
| 289 |
try: |
| 290 |
helptext = self.panels[self._cur_panel]._helptext |
| 291 |
except: |
| 292 |
helptext = "There is no help available for this screen" |
| 293 |
helpdlg = HelpDialog(self.window, helptext) |
| 294 |
helpdlg.run() |
| 295 |
|
| 296 |
def exit_button(self, widget, data=None): |
| 297 |
msgdlg = gtk.MessageDialog(parent=self.window, type=gtk.MESSAGE_QUESTION, buttons=gtk.BUTTONS_YES_NO, message_format="Are you sure you want to exit?") |
| 298 |
resp = msgdlg.run() |
| 299 |
msgdlg.destroy() |
| 300 |
if resp == gtk.RESPONSE_YES: |
| 301 |
self.exit() |
| 302 |
|
| 303 |
def finish(self, widget, data=None): |
| 304 |
# Remove screens |
| 305 |
while len(self.panels): |
| 306 |
self.right_pane_box.remove_page(-1) |
| 307 |
del self.panels[-1] |
| 308 |
self.make_invisible() |
| 309 |
self.install_window = RunInstall.RunInstall(self) |
| 310 |
|
| 311 |
def load_button(self, widget, data=None): |
| 312 |
filesel = gtk.FileSelection(_("Select the install profile to load")) |
| 313 |
if self.install_profile_xml_file == "": |
| 314 |
filesel.set_filename("installprofile.xml") |
| 315 |
else: |
| 316 |
filesel.set_filename(self.install_profile_xml_file) |
| 317 |
resp = filesel.run() |
| 318 |
filename = filesel.get_filename() |
| 319 |
filesel.destroy() |
| 320 |
if resp == gtk.RESPONSE_OK: |
| 321 |
self.install_profile_xml_file = filename |
| 322 |
try: |
| 323 |
tmp_install_profile = GLIInstallProfile.InstallProfile() |
| 324 |
tmp_install_profile.parse(self.install_profile_xml_file) |
| 325 |
self.install_profile = tmp_install_profile |
| 326 |
msgdlg = gtk.MessageDialog(parent=self.window, type=gtk.MESSAGE_INFO, buttons=gtk.BUTTONS_OK, message_format=_("Install profile loaded successfully!")) |
| 327 |
msgdlg.run() |
| 328 |
msgdlg.destroy() |
| 329 |
except: |
| 330 |
errdlg = gtk.MessageDialog(parent=self.window, type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_OK, message_format=_("An error occured loading the install profile")) |
| 331 |
errdlg.run() |
| 332 |
errdlg.destroy() |
| 333 |
|
| 334 |
def save_button(self, widget, data=None): |
| 335 |
filesel = gtk.FileSelection(_("Select the location to save the install profile")) |
| 336 |
if self.install_profile_xml_file == "": |
| 337 |
filesel.set_filename("installprofile.xml") |
| 338 |
else: |
| 339 |
filesel.set_filename(self.install_profile_xml_file) |
| 340 |
resp = filesel.run() |
| 341 |
filename = filesel.get_filename() |
| 342 |
filesel.destroy() |
| 343 |
if resp == gtk.RESPONSE_OK: |
| 344 |
self.install_profile_xml_file = filename |
| 345 |
try: |
| 346 |
configuration = open(filename, "w") |
| 347 |
configuration.write(self.install_profile.serialize()) |
| 348 |
configuration.close() |
| 349 |
msgdlg = gtk.MessageDialog(parent=self.window, type=gtk.MESSAGE_INFO, buttons=gtk.BUTTONS_OK, message_format=_("Install profile saved successfully!")) |
| 350 |
msgdlg.run() |
| 351 |
msgdlg.destroy() |
| 352 |
except: |
| 353 |
errdlg = gtk.MessageDialog(parent=self.window, type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_OK, message_format=_("An error occured saving the install profile")) |
| 354 |
errdlg.run() |
| 355 |
errdlg.destroy() |
| 356 |
|
| 357 |
def delete_event(self, widget, event, data=None): |
| 358 |
msgdlg = gtk.MessageDialog(parent=self.window, type=gtk.MESSAGE_QUESTION, buttons=gtk.BUTTONS_YES_NO, message_format=_("Do you really want to exit the installer before the install is complete?")) |
| 359 |
resp = msgdlg.run() |
| 360 |
msgdlg.destroy() |
| 361 |
if resp == gtk.RESPONSE_YES: |
| 362 |
return False |
| 363 |
else: |
| 364 |
return True |
| 365 |
|
| 366 |
def destroy(self, widget, data=None): |
| 367 |
gtk.main_quit() |
| 368 |
return True |
| 369 |
|
| 370 |
def exit(self): |
| 371 |
gtk.main_quit() |
| 372 |
sys.exit(0) |
| 373 |
|
| 374 |
if __name__ == "__main__": |
| 375 |
install = Installer() |
| 376 |
install.run() |