def __init__(self): self.setup = Setup() self.installer = InstallerEngine(self.setup) self.d = Dialog(dialog="dialog", autowidgetsize=True) self.page_welcome() self.page_language() self.page_timezone() self.page_keyboard_model()
class InstallerWindow: def __init__(self): self.resource_dir = '/usr/share/live-installer/' #self.glade = 'interface.glade' self.glade = os.path.join(self.resource_dir, 'interface.glade') self.wTree = gtk.glade.XML(self.glade, 'main_window') # should be set early self.done = False self.fail = False # here cometh the installer engine self.installer = InstallerEngine() # the distribution name DISTRIBUTION_NAME = self.installer.get_distribution_name() # load the window object self.window = self.wTree.get_widget("main_window") self.window.set_title(DISTRIBUTION_NAME + " " + _("Installer")) self.window.connect("destroy", self.quit_cb) # set the step names self.wTree.get_widget("label_step_1").set_markup(_("Select language")) self.wTree.get_widget("label_step_2").set_markup(_("Choose partitions")) self.wTree.get_widget("label_step_3").set_markup(_("Who are you?")) self.wTree.get_widget("label_step_4").set_markup(_("Advanced Options")) self.wTree.get_widget("label_step_5").set_markup(_("Keyboard Layout")) self.wTree.get_widget("label_step_6").set_markup(_("About to install")) self.wTree.get_widget("label_step_7").set_markup(_("Install system")) # make first step label bolded. label = self.wTree.get_widget("label_step_1") text = label.get_label() attrs = pango.AttrList() nattr = pango.AttrWeight(pango.WEIGHT_BOLD, 0, len(text)) attrs.insert(nattr) label.set_attributes(attrs) # set the button events (wizard_cb) self.wTree.get_widget("button_next").connect("clicked", self.wizard_cb, False) self.wTree.get_widget("button_back").connect("clicked", self.wizard_cb, True) self.wTree.get_widget("button_quit").connect("clicked", self.quit_cb) # language view self.wTree.get_widget("label_select_language").set_markup(_("Please select the language you wish to use\nfor this installation from the list below")) ren = gtk.CellRendererPixbuf() column = gtk.TreeViewColumn("Flags", ren) column.add_attribute(ren, "pixbuf", 2) self.wTree.get_widget("treeview_language_list").append_column(column) ren = gtk.CellRendererText() column = gtk.TreeViewColumn("Languages", ren) column.add_attribute(ren, "text", 0) self.wTree.get_widget("treeview_language_list").append_column(column) self.wTree.get_widget("treeview_language_list").connect("cursor-changed", self.cb_change_language) # build the language list self.build_lang_list() # disk view self.wTree.get_widget("label_select_partition").set_markup(_("Please edit your filesystem mount points using the options below:\nRemember partitioning <b>may cause data loss!</b>")) self.wTree.get_widget("button_edit").connect("clicked", self.edit_partition) # device ren = gtk.CellRendererText() column = gtk.TreeViewColumn(_("Device"), ren) column.add_attribute(ren, "text", 0) self.wTree.get_widget("treeview_disks").append_column(column) # filesystem ren = gtk.CellRendererText() column = gtk.TreeViewColumn(_("Filesystem"), ren) column.add_attribute(ren, "text", 1) self.wTree.get_widget("treeview_disks").append_column(column) # format ren = gtk.CellRendererToggle() column = gtk.TreeViewColumn(_("Format"), ren) column.add_attribute(ren, "active", 2) self.wTree.get_widget("treeview_disks").append_column(column) # boot flag ren = gtk.CellRendererToggle() column = gtk.TreeViewColumn(_("Boot"), ren) column.add_attribute(ren, "active", 5) self.wTree.get_widget("treeview_disks").append_column(column) # mount point ren = gtk.CellRendererText() column = gtk.TreeViewColumn(_("Mount Point"), ren) column.add_attribute(ren, "text", 3) self.wTree.get_widget("treeview_disks").append_column(column) # size ren = gtk.CellRendererText() column = gtk.TreeViewColumn(_("Size"), ren) column.add_attribute(ren, "text", 4) self.wTree.get_widget("treeview_disks").append_column(column) # about you self.wTree.get_widget("label_setup_user").set_markup(_("You will now need to enter details for your user account\nThis is the account you will use after the installation has completed.")) self.wTree.get_widget("label_your_name").set_markup("<b>%s</b>" % _("Your full name")) self.wTree.get_widget("label_your_name_help").set_label(_("This will be shown in the About Me application")) self.wTree.get_widget("label_username").set_markup("<b>%s</b>" % _("Your username")) self.wTree.get_widget("label_username_help").set_label(_("This is the name you will use to login to your computer")) self.wTree.get_widget("label_choose_pass").set_markup("<b>%s</b>" % _("Your password")) self.wTree.get_widget("label_pass_help").set_label(_("Please enter your password twice to ensure it is correct")) self.wTree.get_widget("label_hostname").set_markup("<b>%s</b>" % _("Hostname")) self.wTree.get_widget("label_hostname_help").set_label(_("This hostname will be the computers name on the network")) # try to set the hostname machine = HostMachine() model = machine.get_model() hostname = "" if(model is not None): model = model.replace(" ", "").lower() hostname = model + "-" if(machine.is_laptop()): hostname += _("laptop") else: hostname += _("desktop") self.wTree.get_widget("entry_hostname").set_text(hostname) # events for detecting password mismatch.. entry1 = self.wTree.get_widget("entry_userpass1") entry2 = self.wTree.get_widget("entry_userpass2") entry1.connect("changed", self.pass_mismatcher) entry2.connect("changed", self.pass_mismatcher) # advanced page self.wTree.get_widget("label_advanced").set_markup(_("On this page you can select advanced options regarding your installation")) # grub self.wTree.get_widget("label_grub").set_markup("<b>%s</b>" % _("Bootloader")) self.wTree.get_widget("checkbutton_grub").set_label(_("Install GRUB")) self.wTree.get_widget("label_grub_help").set_label(_("GRUB is a bootloader used to load the Linux kernel")) # link the checkbutton to the combobox grub_check = self.wTree.get_widget("checkbutton_grub") grub_box = self.wTree.get_widget("combobox_grub") grub_check.connect("clicked", lambda x: grub_box.set_sensitive(x.get_active())) # keyboard page self.wTree.get_widget("label_keyboard").set_markup(_("Please choose your keyboard model and keyboard layout using the\noptions below")) self.wTree.get_widget("label_test_kb").set_label(_("Use this box to test your keyboard layout")) # kb models ren = gtk.CellRendererText() column = gtk.TreeViewColumn(_("Model"), ren) column.add_attribute(ren, "text", 0) self.wTree.get_widget("treeview_models").append_column(column) self.wTree.get_widget("treeview_models").connect("cursor-changed", self.cb_change_kb_model) # kb layouts ren = gtk.CellRendererText() column = gtk.TreeViewColumn(_("Layout"), ren) column.add_attribute(ren, "text", 0) self.wTree.get_widget("treeview_layouts").append_column(column) self.wTree.get_widget("treeview_layouts").connect("cursor-changed", self.cb_change_kb_layout) self.build_kb_lists() # 'about to install' aka overview self.wTree.get_widget("label_overview").set_markup(_("Please review your options below before going any further.\nPress the finish button to install %s to your hard drive" % DISTRIBUTION_NAME)) ren = gtk.CellRendererText() column = gtk.TreeViewColumn(_("Overview"), ren) column.add_attribute(ren, "markup", 0) self.wTree.get_widget("treeview_overview").append_column(column) # install page self.wTree.get_widget("label_installing").set_markup(_("%s is now being installed on your computer\nThis may take some time so please be patient" % DISTRIBUTION_NAME)) self.wTree.get_widget("label_install_progress").set_markup("<i>%s</i>" % _("Calculating file indexes...")) # build partition list self.build_disk_list() # make everything visible. self.window.show() self.should_pulse = False def quit_cb(self, widget, data=None): ''' ask whether we should quit. because touchpads do happen ''' gtk.main_quit() def edit_partition(self, widget, data=None): ''' edit the partition ... ''' disks = self.wTree.get_widget("treeview_disks") model = disks.get_model() active = disks.get_selection().get_selected_rows() if(len(active) < 1): return if(len(active[1]) < 1): return active = active[1][0] if(active is None): return row = model[active] stabber = fstab_entry(row[0], row[3], row[1], None) stabber.format = row[2] dlg = PartitionDialog(stabber) stabber = dlg.show() if(stabber is None): return # now set the model as shown.. row[0] = stabber.device row[3] = stabber.mountpoint row[1] = stabber.filesystem row[2] = stabber.format model[active] = row def build_lang_list(self): #Try to find out where we're located... cur_country_code = None try: whatismyip = 'http://debian.linuxmint.com/installer/show_my_ip.php' ip = urllib.urlopen(whatismyip).readlines()[0] gi = GeoIP.new(GeoIP.GEOIP_MEMORY_CACHE) cur_country_code = gi.country_code_by_addr(ip) except: pass #best effort, we get here if we're not connected to the Internet #Plan B... find out what locale we're in (i.e. USA on the live session) cur_lang = os.environ['LANG'] if("." in cur_lang): cur_lang = cur_lang.split(".")[0] model = gtk.ListStore(str,str,gtk.gdk.Pixbuf) model.set_sort_column_id(0, gtk.SORT_ASCENDING) #Load countries into memory countries = {} file = open(os.path.join(self.resource_dir, 'countries'), "r") for line in file: line = line.strip() split = line.split("=") if len(split) == 2: countries[split[0]] = split[1] file.close() #Load languages into memory languages = {} file = open(os.path.join(self.resource_dir, 'languages'), "r") for line in file: line = line.strip() split = line.split("=") if len(split) == 2: languages[split[0]] = split[1] file.close() path = os.path.join(self.resource_dir, 'locales') locales = open(path, "r") cur_index = -1 # find the locale :P set_index = None for line in locales: cur_index += 1 if "UTF-8" in line: locale_code = line.replace("UTF-8", "") locale_code = locale_code.replace(".", "") locale_code = locale_code.strip() if "_" in locale_code: split = locale_code.split("_") if len(split) == 2: language_code = split[0] if language_code in languages: language = languages[language_code] else: language = language_code country_code = split[1].lower() if country_code in countries: country = countries[country_code] else: country = country_code language_label = "%s (%s)" % (language, country) #language_label = "%s - %s" % (country, language) iter = model.append() model.set_value(iter, 0, language_label) model.set_value(iter, 1, locale_code) flag_path = self.resource_dir + '/flags/16/' + country_code + '.png' if os.path.exists(flag_path): model.set_value(iter, 2, gtk.gdk.pixbuf_new_from_file(flag_path)) else: flag_path = self.resource_dir + '/flags/16/generic.png' model.set_value(iter, 2, gtk.gdk.pixbuf_new_from_file(flag_path)) # If it's matching our country code, that's our language right there.. if ((cur_country_code is not None) and (cur_country_code.lower() == country_code)): if (set_index is None): set_index = iter else: # If we find more than one language for a particular country, one of them being English, go for English by default. if (language_code == "en"): set_index = iter # Guesswork... handy for countries which have their own language (fr_FR, de_DE, es_ES.. etc. ) elif (country_code == language_code): set_index = iter # as a plan B... use the locale (USA) if((set_index is None) and (locale_code == cur_lang)): set_index = iter #print "Set via locale: " + cur_lang treeview = self.wTree.get_widget("treeview_language_list") treeview.set_model(model) if(set_index is not None): column = treeview.get_column(0) path = model.get_path(set_index) treeview.set_cursor(path, focus_column=column) treeview.scroll_to_cell(path, column=column) treeview.set_search_column(0) def build_disk_list(self): model = gtk.ListStore(str,str,bool,str,str,bool) model2 = gtk.ListStore(str) pro = subprocess.Popen("parted -lms", stdout=subprocess.PIPE, shell=True) last_name = "" for line in pro.stdout: line = line.rstrip("\r\n") if ":" in line: split = line.split(":") if(len(split) <= 3): continue if(line.startswith("/dev")): last_name = split[0] model2.append([last_name]) continue # device list sections = line.split(" ") device = "%s%s" % (last_name, split[0]) filesystem = split[4] # hack. love em eh? ... if(filesystem.startswith("linux-swap")): filesystem = "swap" size_ = split[3] if(len(split) > 5): boot = split[6] if(boot == "boot;"): model.append([device, filesystem, False, None, size_, True]) else: model.append([device, filesystem, False, None, size_, False]) else: model.append([device, filesystem, False, None, size_, False]) print "%s - %s" % (device, filesystem) self.wTree.get_widget("treeview_disks").set_model(model) self.wTree.get_widget("combobox_grub").set_model(model2) self.wTree.get_widget("combobox_grub").set_active(0) def build_kb_lists(self): ''' Do some xml kung-fu and load the keyboard stuffs ''' # firstly we'll determine the layouts in use p = subprocess.Popen("setxkbmap -print",shell=True,stdout=subprocess.PIPE) for line in p.stdout: # strip it line = line.rstrip("\r\n") line = line.replace("{","") line = line.replace("}","") line = line.replace(";","") if("xkb_symbols" in line): # decipher the layout in use section = line.split("\"")[1] # split by the " mark self.keyboard_layout = section.split("+")[1] if("xkb_geometry" in line): first_bracket = line.index("(") +1 substr = line[first_bracket:] last_bracket = substr.index(")") substr = substr[0:last_bracket] self.keyboard_geom = substr p.poll() xml_file = '/usr/share/X11/xkb/rules/xorg.xml' model_models = gtk.ListStore(str,str) model_models.set_sort_column_id(0, gtk.SORT_ASCENDING) model_layouts = gtk.ListStore(str,str) model_layouts.set_sort_column_id(0, gtk.SORT_ASCENDING) dom = parse(xml_file) # if we find the users keyboard info we can set it in the list set_keyboard_model = None set_keyboard_layout = None # grab the root element root = dom.getElementsByTagName('xkbConfigRegistry')[0] # build the list of models root_models = root.getElementsByTagName('modelList')[0] for element in root_models.getElementsByTagName('model'): conf = element.getElementsByTagName('configItem')[0] name = conf.getElementsByTagName('name')[0] desc = conf.getElementsByTagName('description')[0] #vendor = conf.getElementsByTagName('vendor')[0] # presently unused.. iter_model = model_models.append([self.getText(desc.childNodes), self.getText(name.childNodes)]) item = self.getText(name.childNodes) if(item == self.keyboard_geom): set_keyboard_model = iter_model root_layouts = root.getElementsByTagName('layoutList')[0] for element in root_layouts.getElementsByTagName('layout'): conf = element.getElementsByTagName('configItem')[0] name = conf.getElementsByTagName('name')[0] desc = conf.getElementsByTagName('description')[0] iter_layout = model_layouts.append([self.getText(desc.childNodes), self.getText(name.childNodes)]) item = self.getText(name.childNodes) if(item == self.keyboard_layout): set_keyboard_layout = iter_layout # now set the model self.wTree.get_widget("treeview_models").set_model(model_models) self.wTree.get_widget("treeview_layouts").set_model(model_layouts) if(set_keyboard_layout is not None): # show it in the list treeview = self.wTree.get_widget("treeview_layouts") model = treeview.get_model() column = treeview.get_column(0) path = model.get_path(set_keyboard_layout) treeview.set_cursor(path, focus_column=column) treeview.scroll_to_cell(path, column=column) if(set_keyboard_model is not None): # show it in the list treeview = self.wTree.get_widget("treeview_models") model = treeview.get_model() column = treeview.get_column(0) path = model.get_path(set_keyboard_model) treeview.set_cursor(path, focus_column=column) treeview.scroll_to_cell(path, column=column) def getText(self, nodelist): rc = [] for node in nodelist: if node.nodeType == node.TEXT_NODE: rc.append(node.data) return ''.join(rc) def cb_change_language(self, treeview, data=None): ''' Called whenever someone updates the language ''' model = treeview.get_model() active = treeview.get_selection().get_selected_rows() if(len(active) < 1): return active = active[1][0] if(active is None): return row = model[active] self.locale = row[1] def cb_change_kb_model(self, treeview, data=None): ''' Called whenever someone updates the keyboard model ''' model = treeview.get_model() active = treeview.get_selection().get_selected_rows() if(len(active) < 1): return active = active[1][0] if(active is None): return row = model[active] os.system("setxkbmap -model %s" % row[1]) self.keyboard_model = row[1] self.keyboard_model_desc = row[0] def cb_change_kb_layout(self, treeview, data=None): ''' Called whenever someone updates the keyboard layout ''' model = treeview.get_model() active = treeview.get_selection().get_selected_rows() if(len(active) < 1): return active = active[1][0] if(active is None): return row = model[active] os.system("setxkbmap -layout %s" % row[1]) self.keyboard_layout = row[1] self.keyboard_layout_desc = row[0] def pass_mismatcher(self, widget): ''' Someone typed into the entry ''' w = self.wTree.get_widget("entry_userpass1") w2 = self.wTree.get_widget("entry_userpass2") txt1 = w.get_text() txt2 = w2.get_text() if(txt1 == "" and txt2 == ""): self.wTree.get_widget("image_mismatch").hide() self.wTree.get_widget("label_mismatch").hide() else: self.wTree.get_widget("image_mismatch").show() self.wTree.get_widget("label_mismatch").show() if(txt1 != txt2): img = self.wTree.get_widget("image_mismatch") img.set_from_stock(gtk.STOCK_NO, gtk.ICON_SIZE_BUTTON) label = self.wTree.get_widget("label_mismatch") label.set_label(_("Passwords do not match")) else: img = self.wTree.get_widget("image_mismatch") img.set_from_stock(gtk.STOCK_OK, gtk.ICON_SIZE_BUTTON) label = self.wTree.get_widget("label_mismatch") label.set_label(_("Passwords match")) def wizard_cb(self, widget, goback, data=None): ''' wizard buttons ''' nb = self.wTree.get_widget("notebook1") sel = nb.get_current_page() # check each page for errors if(not goback): if(sel == 1): # partitions page model = self.wTree.get_widget("treeview_disks").get_model() found_root = False # found_swap = False for row in model: mountpoint = row[3] if(mountpoint == "/"): found_root = True if(not found_root): dlg = MessageDialog(_("Installation Tool"), _("Please select a root (/) partition before proceeding"), gtk.MESSAGE_ERROR) dlg.show() return elif(sel == 2): # about me page username = self.wTree.get_widget("entry_username").get_text() if(username == ""): MessageDialog(_("Installation Tool"), _("Please provide a username"), gtk.MESSAGE_ERROR).show() return # username valid? for char in username: if(char.isupper()): MessageDialog(_("Installation Tool"), _("Your username must be lower case"), gtk.MESSAGE_WARNING).show() return if(char.isspace()): MessageDialog(_("Installation Tool"), _("Your username may not contain whitespace"), gtk.MESSAGE_WARNING).show() return password1 = self.wTree.get_widget("entry_userpass1").get_text() if(password1 == ""): MessageDialog(_("Installation Tool"), _("Please provide a password for your user account"), gtk.MESSAGE_WARNING).show() return password2 = self.wTree.get_widget("entry_userpass2").get_text() if(password1 != password2): MessageDialog(_("Installation Tool"), _("Your passwords do not match"), gtk.MESSAGE_ERROR).show() return elif(sel == 3): pass label = self.wTree.get_widget("label_step_" + str(sel+1)) text = label.get_label() attrs = pango.AttrList() nattr = pango.AttrWeight(pango.WEIGHT_NORMAL, 0, len(text)) attrs.insert(nattr) label.set_attributes(attrs) label.set_sensitive(False) if(goback): sel-=1 if(sel == 0): self.wTree.get_widget("button_back").set_sensitive(False) else: sel+=1 self.wTree.get_widget("button_back").set_sensitive(True) label = self.wTree.get_widget("label_step_" + str(sel+1)) attrs = pango.AttrList() text = label.get_label() battr = pango.AttrWeight(pango.WEIGHT_BOLD, 0, len(text)) attrs.insert(battr) label.set_attributes(attrs) label.set_sensitive(True) self.wTree.get_widget("notebook1").set_current_page(sel) if(sel == 5): self.show_overview() self.wTree.get_widget("treeview_overview").expand_all() if(sel == 6): # do install self.wTree.get_widget("button_next").hide() self.wTree.get_widget("button_back").hide() thr = threading.Thread(name="live-install", group=None, args=(), kwargs={}, target=self.do_install) thr.start() def show_overview(self): ''' build the summary page ''' model = gtk.TreeStore(str) top = model.append(None) model.set(top, 0, "Filesystem operations") disks = self.wTree.get_widget("treeview_disks").get_model() for item in disks: if(item[2]): # format it iter = model.append(top) model.set(iter, 0, "<b>%s</b>" % (_("Format %s (%s) as %s" % (item[0], item[4], item[1])))) if(item[3] is not None and item[3] is not ""): # mount point iter = model.append(top) model.set(iter, 0, "<b>%s</b>" % (_("Mount %s as %s" % (item[0], item[3])))) install_grub = self.wTree.get_widget("checkbutton_grub").get_active() grub_box = self.wTree.get_widget("combobox_grub") grub_active = grub_box.get_active() grub_model = grub_box.get_model() iter = model.append(top) if(install_grub): model.set(iter, 0, _("Install bootloader to %s" % ("<b>%s</b>" % grub_model[grub_active][0]))) else: model.set(iter, 0, _("Do not install bootloader")) # now we show the system info top = model.append(None) model.set(top, 0, _("User settings")) username = self.wTree.get_widget("entry_username").get_text() realname = self.wTree.get_widget("entry_your_name").get_text() iter = model.append(top) model.set(iter, 0, "Username: <b>%s</b>" % username) iter = model.append(top) model.set(iter, 0, "Real name: <b>%s</b>" % realname) # keyboard cruft top = model.append(None) model.set(top, 0, _("Keyboard")) iter = model.append(top) model.set(iter, 0, "Layout: <b>%s</b>" % self.keyboard_layout_desc) iter = model.append(top) model.set(iter, 0, "Model: <b>%s</b>" % self.keyboard_model_desc) # system stuff # todo; probe hostname = self.wTree.get_widget("entry_hostname").get_text() language = self.locale top = model.append(None) model.set(top, 0, _("System settings")) iter = model.append(top) model.set(iter, 0, "Hostname: <b>%s</b>" % hostname) #iter = model.append(top) #model.set(iter, 0, "Locale: <b>%s</b>" % locale) iter = model.append(top) model.set(iter, 0, "Language: <b>%s</b>" % language) self.wTree.get_widget("treeview_overview").set_model(model) def do_install(self): ''' Actually perform the installation .. ''' inst = self.installer # Create fstab files = fstab() model = self.wTree.get_widget("treeview_disks").get_model() for row in model: if(row[2] or row[3] is not None): # format or mountpoint specified. files.add_mount(device=row[0], mountpoint=row[3], filesystem=row[1], format=row[2]) inst.fstab = files # need to add set_fstab() to InstallerEngine # set up the system user username = self.wTree.get_widget("entry_username").get_text() password = self.wTree.get_widget("entry_userpass1").get_text() realname = self.wTree.get_widget("entry_your_name").get_text() hostname = self.wTree.get_widget("entry_hostname").get_text() user = SystemUser(username=username, password=password, realname=realname) inst.set_main_user(user) inst.set_hostname(hostname) # set language inst.set_locale(self.locale) # set keyboard inst.set_keyboard_options(layout=self.keyboard_layout, model=self.keyboard_model) # grub? do_grub = self.wTree.get_widget("checkbutton_grub").get_active() if(do_grub): grub_box = self.wTree.get_widget("combobox_grub") grub_location = grub_box.get_model()[grub_box.get_active()][0] inst.set_install_bootloader(device=grub_location) inst.set_progress_hook(self.update_progress) # do we dare? .. inst.install() # show a message dialog thingum while(not self.done): time.sleep(0.1) gtk.gdk.threads_enter() MessageDialog(_("Installation Tool"), _("Installation is now complete. Please restart your computer to use the new system"), gtk.MESSAGE_INFO).show() gtk.gdk.threads_leave() # safe?? gtk.main_quit() # you are now.. sys.exit(0) def update_progress(self, fail=False, done=False, pulse=False, total=0,current=0,message=""): # TODO: ADD FAIL CHECKS.. if(pulse): gtk.gdk.threads_enter() self.wTree.get_widget("label_install_progress").set_label(message) gtk.gdk.threads_leave() self.do_progress_pulse(message) return if(done): # cool, finished :D self.should_pulse = False self.done = done gtk.gdk.threads_enter() self.wTree.get_widget("progressbar").set_fraction(1) self.wTree.get_widget("label_install_progress").set_label(message) gtk.gdk.threads_leave() return self.should_pulse = False _total = float(total) _current = float(current) pct = float(_current/_total) szPct = int(pct) # thread block gtk.gdk.threads_enter() self.wTree.get_widget("progressbar").set_fraction(pct) self.wTree.get_widget("label_install_progress").set_label(message) gtk.gdk.threads_leave() # end thread block def do_progress_pulse(self, message): def pbar_pulse(): if(not self.should_pulse): return False self.wTree.get_widget("progressbar").pulse() return self.should_pulse if(not self.should_pulse): self.should_pulse = True gobject.timeout_add(100, pbar_pulse) else: # asssume we're "pulsing" already self.should_pulse = True gtk.gdk.threads_enter() pbar_pulse() gtk.gdk.threads_leave()
def __init__(self): self.resource_dir = '/usr/share/live-installer/' #self.glade = 'interface.glade' self.glade = os.path.join(self.resource_dir, 'interface.glade') self.wTree = gtk.glade.XML(self.glade, 'main_window') # should be set early self.done = False self.fail = False # here cometh the installer engine self.installer = InstallerEngine() # the distribution name DISTRIBUTION_NAME = self.installer.get_distribution_name() # load the window object self.window = self.wTree.get_widget("main_window") self.window.set_title(DISTRIBUTION_NAME + " " + _("Installer")) self.window.connect("destroy", self.quit_cb) # set the step names self.wTree.get_widget("label_step_1").set_markup(_("Select language")) self.wTree.get_widget("label_step_2").set_markup(_("Choose partitions")) self.wTree.get_widget("label_step_3").set_markup(_("Who are you?")) self.wTree.get_widget("label_step_4").set_markup(_("Advanced Options")) self.wTree.get_widget("label_step_5").set_markup(_("Keyboard Layout")) self.wTree.get_widget("label_step_6").set_markup(_("About to install")) self.wTree.get_widget("label_step_7").set_markup(_("Install system")) # make first step label bolded. label = self.wTree.get_widget("label_step_1") text = label.get_label() attrs = pango.AttrList() nattr = pango.AttrWeight(pango.WEIGHT_BOLD, 0, len(text)) attrs.insert(nattr) label.set_attributes(attrs) # set the button events (wizard_cb) self.wTree.get_widget("button_next").connect("clicked", self.wizard_cb, False) self.wTree.get_widget("button_back").connect("clicked", self.wizard_cb, True) self.wTree.get_widget("button_quit").connect("clicked", self.quit_cb) # language view self.wTree.get_widget("label_select_language").set_markup(_("Please select the language you wish to use\nfor this installation from the list below")) ren = gtk.CellRendererPixbuf() column = gtk.TreeViewColumn("Flags", ren) column.add_attribute(ren, "pixbuf", 2) self.wTree.get_widget("treeview_language_list").append_column(column) ren = gtk.CellRendererText() column = gtk.TreeViewColumn("Languages", ren) column.add_attribute(ren, "text", 0) self.wTree.get_widget("treeview_language_list").append_column(column) self.wTree.get_widget("treeview_language_list").connect("cursor-changed", self.cb_change_language) # build the language list self.build_lang_list() # disk view self.wTree.get_widget("label_select_partition").set_markup(_("Please edit your filesystem mount points using the options below:\nRemember partitioning <b>may cause data loss!</b>")) self.wTree.get_widget("button_edit").connect("clicked", self.edit_partition) # device ren = gtk.CellRendererText() column = gtk.TreeViewColumn(_("Device"), ren) column.add_attribute(ren, "text", 0) self.wTree.get_widget("treeview_disks").append_column(column) # filesystem ren = gtk.CellRendererText() column = gtk.TreeViewColumn(_("Filesystem"), ren) column.add_attribute(ren, "text", 1) self.wTree.get_widget("treeview_disks").append_column(column) # format ren = gtk.CellRendererToggle() column = gtk.TreeViewColumn(_("Format"), ren) column.add_attribute(ren, "active", 2) self.wTree.get_widget("treeview_disks").append_column(column) # boot flag ren = gtk.CellRendererToggle() column = gtk.TreeViewColumn(_("Boot"), ren) column.add_attribute(ren, "active", 5) self.wTree.get_widget("treeview_disks").append_column(column) # mount point ren = gtk.CellRendererText() column = gtk.TreeViewColumn(_("Mount Point"), ren) column.add_attribute(ren, "text", 3) self.wTree.get_widget("treeview_disks").append_column(column) # size ren = gtk.CellRendererText() column = gtk.TreeViewColumn(_("Size"), ren) column.add_attribute(ren, "text", 4) self.wTree.get_widget("treeview_disks").append_column(column) # about you self.wTree.get_widget("label_setup_user").set_markup(_("You will now need to enter details for your user account\nThis is the account you will use after the installation has completed.")) self.wTree.get_widget("label_your_name").set_markup("<b>%s</b>" % _("Your full name")) self.wTree.get_widget("label_your_name_help").set_label(_("This will be shown in the About Me application")) self.wTree.get_widget("label_username").set_markup("<b>%s</b>" % _("Your username")) self.wTree.get_widget("label_username_help").set_label(_("This is the name you will use to login to your computer")) self.wTree.get_widget("label_choose_pass").set_markup("<b>%s</b>" % _("Your password")) self.wTree.get_widget("label_pass_help").set_label(_("Please enter your password twice to ensure it is correct")) self.wTree.get_widget("label_hostname").set_markup("<b>%s</b>" % _("Hostname")) self.wTree.get_widget("label_hostname_help").set_label(_("This hostname will be the computers name on the network")) # try to set the hostname machine = HostMachine() model = machine.get_model() hostname = "" if(model is not None): model = model.replace(" ", "").lower() hostname = model + "-" if(machine.is_laptop()): hostname += _("laptop") else: hostname += _("desktop") self.wTree.get_widget("entry_hostname").set_text(hostname) # events for detecting password mismatch.. entry1 = self.wTree.get_widget("entry_userpass1") entry2 = self.wTree.get_widget("entry_userpass2") entry1.connect("changed", self.pass_mismatcher) entry2.connect("changed", self.pass_mismatcher) # advanced page self.wTree.get_widget("label_advanced").set_markup(_("On this page you can select advanced options regarding your installation")) # grub self.wTree.get_widget("label_grub").set_markup("<b>%s</b>" % _("Bootloader")) self.wTree.get_widget("checkbutton_grub").set_label(_("Install GRUB")) self.wTree.get_widget("label_grub_help").set_label(_("GRUB is a bootloader used to load the Linux kernel")) # link the checkbutton to the combobox grub_check = self.wTree.get_widget("checkbutton_grub") grub_box = self.wTree.get_widget("combobox_grub") grub_check.connect("clicked", lambda x: grub_box.set_sensitive(x.get_active())) # keyboard page self.wTree.get_widget("label_keyboard").set_markup(_("Please choose your keyboard model and keyboard layout using the\noptions below")) self.wTree.get_widget("label_test_kb").set_label(_("Use this box to test your keyboard layout")) # kb models ren = gtk.CellRendererText() column = gtk.TreeViewColumn(_("Model"), ren) column.add_attribute(ren, "text", 0) self.wTree.get_widget("treeview_models").append_column(column) self.wTree.get_widget("treeview_models").connect("cursor-changed", self.cb_change_kb_model) # kb layouts ren = gtk.CellRendererText() column = gtk.TreeViewColumn(_("Layout"), ren) column.add_attribute(ren, "text", 0) self.wTree.get_widget("treeview_layouts").append_column(column) self.wTree.get_widget("treeview_layouts").connect("cursor-changed", self.cb_change_kb_layout) self.build_kb_lists() # 'about to install' aka overview self.wTree.get_widget("label_overview").set_markup(_("Please review your options below before going any further.\nPress the finish button to install %s to your hard drive" % DISTRIBUTION_NAME)) ren = gtk.CellRendererText() column = gtk.TreeViewColumn(_("Overview"), ren) column.add_attribute(ren, "markup", 0) self.wTree.get_widget("treeview_overview").append_column(column) # install page self.wTree.get_widget("label_installing").set_markup(_("%s is now being installed on your computer\nThis may take some time so please be patient" % DISTRIBUTION_NAME)) self.wTree.get_widget("label_install_progress").set_markup("<i>%s</i>" % _("Calculating file indexes...")) # build partition list self.build_disk_list() # make everything visible. self.window.show() self.should_pulse = False
def __init__(self, fullscreen=False): #Disable the screensaver to prevent a segfault situation in GTK2 os.system("sudo -u mint gsettings set org.cinnamon.desktop.screensaver lock-enabled false 2> /dev/null") os.system("sudo -u mint gsettings set org.mate.screensaver lock-enabled false 2> /dev/null") #Build the Setup object (where we put all our choices) self.setup = Setup() self.resource_dir = '/usr/share/live-installer/' #self.glade = 'interface.glade' self.glade = os.path.join(self.resource_dir, 'interface.glade') self.wTree = gtk.glade.XML(self.glade, 'main_window') # should be set early self.done = False self.fail = False self.paused = False # here comes the installer engine self.installer = InstallerEngine() # the distribution name DISTRIBUTION_NAME = self.installer.get_distribution_name() # load the window object self.window = self.wTree.get_widget("main_window") if __debug__: self.window.set_title((_("%s Installer") % DISTRIBUTION_NAME) + ' (debug)') else: self.window.set_title((_("%s Installer") % DISTRIBUTION_NAME)) self.window.connect("destroy", self.quit_cb) # Wizard pages (self.PAGE_LANGUAGE, self.PAGE_PARTITIONS, self.PAGE_USER, self.PAGE_ADVANCED, self.PAGE_KEYBOARD, self.PAGE_OVERVIEW, self.PAGE_INSTALL, self.PAGE_TIMEZONE, self.PAGE_CUSTOMWARNING, self.PAGE_CUSTOMPAUSED) = range(10) self.wizard_pages = range(10) self.wizard_pages[self.PAGE_LANGUAGE] = WizardPage(_("Language"), "locales.png") self.wizard_pages[self.PAGE_TIMEZONE] = WizardPage(_("Timezone"), "time.png") self.wizard_pages[self.PAGE_KEYBOARD] = WizardPage(_("Keyboard layout"), "keyboard.png") self.wizard_pages[self.PAGE_USER] = WizardPage(_("User info"), "user.png") self.wizard_pages[self.PAGE_PARTITIONS] = WizardPage(_("Partitioning"), "hdd.svg") self.wizard_pages[self.PAGE_CUSTOMWARNING] = WizardPage(_("Please make sure you wish to manage partitions manually"), "hdd.svg") self.wizard_pages[self.PAGE_ADVANCED] = WizardPage(_("Advanced options"), "advanced.png") self.wizard_pages[self.PAGE_OVERVIEW] = WizardPage(_("Summary"), "summary.png") self.wizard_pages[self.PAGE_INSTALL] = WizardPage(_("Installing Linux Mint..."), "install.png") self.wizard_pages[self.PAGE_CUSTOMPAUSED] = WizardPage(_("Installation is paused: please finish the custom installation"), "install.png") # set the button events (wizard_cb) self.wTree.get_widget("button_next").connect("clicked", self.wizard_cb, False) self.wTree.get_widget("button_back").connect("clicked", self.wizard_cb, True) self.wTree.get_widget("button_quit").connect("clicked", self.quit_cb) col = gtk.TreeViewColumn("", gtk.CellRendererPixbuf(), pixbuf=2) self.wTree.get_widget("treeview_language_list").append_column(col) ren = gtk.CellRendererText() col = gtk.TreeViewColumn(_("Language"), ren, text=0) col.set_sort_column_id(0) self.wTree.get_widget("treeview_language_list").append_column(col) col = gtk.TreeViewColumn(_("Country"), ren, text=1) col.set_sort_column_id(1) self.wTree.get_widget("treeview_language_list").append_column(col) self.wTree.get_widget("treeview_language_list").connect("cursor-changed", self.assign_language) # build user info page self.wTree.get_widget("face_select_picture_button").connect( "button-release-event", self.face_select_picture_button_clicked) self.wTree.get_widget("face_take_picture_button").connect( "button-release-event", self.face_take_picture_button_clicked) os.system("convert /usr/share/pixmaps/faces/t9penguino_trans.png -resize x96 /tmp/live-installer-face.png") self.wTree.get_widget("face_image").set_from_file("/tmp/live-installer-face.png") webcam_detected = 0 == os.system('streamer -o /tmp/live-installer-face07.jpeg') if webcam_detected: self.wTree.get_widget("face_take_picture_button").set_tooltip_text(_("Click this button to take a new picture of yourself with the webcam.")) else: self.wTree.get_widget("face_take_picture_button").set_sensitive(False) self.wTree.get_widget("face_take_picture_button").set_tooltip_text(_("The installer did not detect any webcams.")) # build the language list self.build_lang_list() # build timezones model = timezones.build_timezones(self) self.wTree.get_widget("button_timezones").set_label(_('Select timezone')) self.wTree.get_widget("event_timezones").connect('button-release-event', timezones.cb_map_clicked, model) # partitions self.wTree.get_widget("label_edit_partitions").set_label(_("_Edit partitions")) self.wTree.get_widget("label_custommount").set_label(_("_Expert mode")) self.wTree.get_widget("button_custommount").connect("clicked", self.show_customwarning) self.wTree.get_widget("button_edit").connect("clicked", partitioning.manually_edit_partitions) self.wTree.get_widget("button_refresh").connect("clicked", lambda _: partitioning.build_partitions(self)) self.wTree.get_widget("treeview_disks").get_selection().connect("changed", partitioning.update_html_preview) self.wTree.get_widget("treeview_disks").connect("row_activated", partitioning.edit_partition_dialog) self.wTree.get_widget("treeview_disks").connect("button-release-event", partitioning.partitions_popup_menu) text = gtk.CellRendererText() for i in (partitioning.IDX_PART_PATH, partitioning.IDX_PART_TYPE, partitioning.IDX_PART_DESCRIPTION, partitioning.IDX_PART_MOUNT_AS, partitioning.IDX_PART_FORMAT_AS, partitioning.IDX_PART_SIZE, partitioning.IDX_PART_FREE_SPACE): col = gtk.TreeViewColumn("", text, markup=i) # real title is set in i18n() self.wTree.get_widget("treeview_disks").append_column(col) self.wTree.get_widget("entry_your_name").connect("notify::text", self.assign_realname) self.wTree.get_widget("entry_username").connect("notify::text", self.assign_username) self.wTree.get_widget("entry_hostname").connect("notify::text", self.assign_hostname) # events for detecting password mismatch.. self.wTree.get_widget("entry_userpass1").connect("changed", self.assign_password) self.wTree.get_widget("entry_userpass2").connect("changed", self.assign_password) # link the checkbutton to the combobox grub_check = self.wTree.get_widget("checkbutton_grub") grub_box = self.wTree.get_widget("combobox_grub") grub_check.connect("toggled", self.assign_grub_install, grub_box) grub_box.connect("changed", self.assign_grub_device) # Install Grub by default grub_check.set_active(True) grub_box.set_sensitive(True) # kb models cell = gtk.CellRendererText() self.wTree.get_widget("combobox_kb_model").pack_start(cell, True) self.wTree.get_widget("combobox_kb_model").add_attribute(cell, 'text', 0) self.wTree.get_widget("combobox_kb_model").connect("changed", self.assign_keyboard_model) # kb layouts ren = gtk.CellRendererText() self.column10 = gtk.TreeViewColumn(_("Layout"), ren) self.column10.add_attribute(ren, "text", 0) self.wTree.get_widget("treeview_layouts").append_column(self.column10) self.wTree.get_widget("treeview_layouts").connect("cursor-changed", self.assign_keyboard_layout) ren = gtk.CellRendererText() self.column11 = gtk.TreeViewColumn(_("Variant"), ren) self.column11.add_attribute(ren, "text", 0) self.wTree.get_widget("treeview_variants").append_column(self.column11) self.wTree.get_widget("treeview_variants").connect("cursor-changed", self.assign_keyboard_variant) self.build_kb_lists() # 'about to install' aka overview ren = gtk.CellRendererText() self.column12 = gtk.TreeViewColumn(_("Overview"), ren) self.column12.add_attribute(ren, "markup", 0) self.wTree.get_widget("treeview_overview").append_column(self.column12) # install page self.wTree.get_widget("label_install_progress").set_markup("<i>%s</i>" % _("Calculating file indexes ...")) #i18n self.i18n() # build partition list self.should_pulse = False # make sure we're on the right page (no pun.) self.activate_page(0) # this is a hack atm to steal the menubar's background color self.wTree.get_widget("menubar").realize() style = self.wTree.get_widget("menubar").style.copy() self.wTree.get_widget("menubar").hide() # apply to the header self.title_box = self.wTree.get_widget("title_eventbox") self.title_box.set_border_width(6); bgColor = gtk.gdk.color_parse('#585858') self.title_box.modify_bg(gtk.STATE_NORMAL, bgColor) fgColor = gtk.gdk.color_parse('#FFFFFF') self.help_label = self.wTree.get_widget("help_label") self.help_label.modify_fg(gtk.STATE_NORMAL, fgColor) if(fullscreen): # dedicated installer mode thingum self.window.maximize() self.window.fullscreen() # Configure slideshow webview self.slideshow_browser = webkit.WebView() s = self.slideshow_browser.get_settings() s.set_property('enable-file-access-from-file-uris', True) s.set_property('enable-default-context-menu', False) self.slideshow_browser.load_string(_('No slideshow template found.'), 'text/html', 'UTF-8', 'file:///') self.wTree.get_widget("vbox_install").add(self.slideshow_browser) self.wTree.get_widget("vbox_install").show_all() # Configure disks webview self.partitions_browser = webkit.WebView() s = self.partitions_browser.get_settings() s.set_property('enable-file-access-from-file-uris', True) s.set_property('enable-default-context-menu', False) self.partitions_browser.set_transparent(True) self.wTree.get_widget("scrolled_partitions").add(self.partitions_browser) self.window.show_all() # fix text wrap self.fix_text_wrap()