789 lines
31 KiB
Python
789 lines
31 KiB
Python
# -*- coding: utf-8; Mode: Python; indent-tabs-mode: nil; tab-width: 4 -*-
|
|
|
|
# Copyright (C) 2006, 2007, 2008 Canonical Ltd.
|
|
# Written by Colin Watson <cjwatson@ubuntu.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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
import locale
|
|
import os
|
|
import re
|
|
|
|
import debconf
|
|
|
|
from ubiquity import auto_update, i18n, misc, osextras, plugin
|
|
|
|
|
|
NAME = 'language'
|
|
AFTER = None
|
|
WEIGHT = 10
|
|
|
|
try:
|
|
import lsb_release
|
|
_ver = lsb_release.get_distro_information()['RELEASE']
|
|
except Exception:
|
|
_ver = '12.04'
|
|
_wget_url = 'http://changelogs.ubuntu.com/ubiquity/%s-update-available' % _ver
|
|
|
|
_release_notes_url_path = '/cdrom/.disk/release_notes_url'
|
|
|
|
|
|
class PageBase(plugin.PluginUI):
|
|
def set_language_choices(self, unused_choices, choice_map):
|
|
"""Called with language choices and a map to localised names."""
|
|
self.language_choice_map = dict(choice_map)
|
|
|
|
def set_language(self, language):
|
|
"""Set the current selected language."""
|
|
pass
|
|
|
|
def get_language(self):
|
|
"""Get the current selected language."""
|
|
return 'C'
|
|
|
|
def set_oem_id(self, text):
|
|
pass
|
|
|
|
def get_oem_id(self):
|
|
return ''
|
|
|
|
|
|
class PageGtk(PageBase):
|
|
plugin_is_language = True
|
|
plugin_title = 'ubiquity/text/language_heading_label'
|
|
|
|
def __init__(self, controller, *args, **kwargs):
|
|
self.controller = controller
|
|
self.timeout_id = None
|
|
self.wget_retcode = None
|
|
self.wget_proc = None
|
|
if self.controller.oem_user_config:
|
|
ui_file = 'stepLanguageOnly.ui'
|
|
self.only = True
|
|
else:
|
|
ui_file = 'stepLanguage.ui'
|
|
self.only = False
|
|
from gi.repository import Gtk
|
|
builder = Gtk.Builder()
|
|
builder.add_from_file(os.path.join(
|
|
os.environ['UBIQUITY_GLADE'], ui_file))
|
|
builder.connect_signals(self)
|
|
self.controller.add_builder(builder)
|
|
self.page = builder.get_object('stepLanguage')
|
|
self.iconview = builder.get_object('language_iconview')
|
|
self.treeview = builder.get_object('language_treeview')
|
|
self.oem_id_entry = builder.get_object('oem_id_entry')
|
|
if self.controller.oem_config:
|
|
builder.get_object('oem_id_vbox').show()
|
|
|
|
self.release_notes_url = ''
|
|
self.update_installer = True
|
|
self.updating_installer = False
|
|
self.release_notes_label = builder.get_object('release_notes_label')
|
|
self.release_notes_found = False
|
|
if self.release_notes_label:
|
|
self.release_notes_label.connect(
|
|
'activate-link', self.on_link_clicked)
|
|
if self.controller.oem_config or auto_update.already_updated():
|
|
self.update_installer = False
|
|
try:
|
|
with open(_release_notes_url_path) as release_notes:
|
|
self.release_notes_url = release_notes.read().rstrip('\n')
|
|
self.release_notes_found = True
|
|
except (KeyboardInterrupt, SystemExit):
|
|
raise
|
|
except Exception:
|
|
pass
|
|
self.install_ubuntu = builder.get_object('install_ubuntu')
|
|
self.try_ubuntu = builder.get_object('try_ubuntu')
|
|
if not self.only:
|
|
if 'UBIQUITY_GREETER' not in os.environ:
|
|
choice_section_vbox = builder.get_object('choice_section_vbox')
|
|
choice_section_vbox and choice_section_vbox.hide()
|
|
else:
|
|
def inst(*args):
|
|
self.try_ubuntu.set_sensitive(False)
|
|
self.controller.go_forward()
|
|
self.install_ubuntu.connect('clicked', inst)
|
|
self.try_ubuntu.connect('clicked', self.on_try_ubuntu_clicked)
|
|
self.try_install_text_label = builder.get_object(
|
|
'try_install_text_label')
|
|
# We do not want to show the yet to be substituted strings
|
|
# (${MEDIUM}, etc), so don't show the core of the page until
|
|
# it's ready.
|
|
for w in self.page.get_children():
|
|
w.hide()
|
|
self.plugin_widgets = self.page
|
|
|
|
@plugin.only_this_page
|
|
def on_try_ubuntu_clicked(self, *args):
|
|
if not self.controller.allowed_change_step():
|
|
# The button's already been clicked once, so stop reacting to it.
|
|
# LP: #911907.
|
|
return
|
|
# Spinning cursor.
|
|
self.controller.allow_change_step(False)
|
|
# Queue quit.
|
|
self.install_ubuntu.set_sensitive(False)
|
|
self.controller._wizard.current_page = None
|
|
self.controller.dbfilter.ok_handler()
|
|
|
|
def set_language_choices(self, choices, choice_map):
|
|
from gi.repository import Gtk, GObject
|
|
PageBase.set_language_choices(self, choices, choice_map)
|
|
list_store = Gtk.ListStore.new([GObject.TYPE_STRING])
|
|
longest_length = 0
|
|
longest = ''
|
|
for choice in choices:
|
|
list_store.append([choice])
|
|
# Work around the fact that GtkIconView wraps at 50px or the width
|
|
# of the icon, which is nonexistent here. See adjust_wrap_width ()
|
|
# in gtkiconview.c for the details.
|
|
if self.only:
|
|
length = len(choice)
|
|
if length > longest_length:
|
|
longest_length = length
|
|
longest = choice
|
|
# Support both iconview and treeview
|
|
if self.only:
|
|
self.iconview.set_model(list_store)
|
|
self.iconview.set_text_column(0)
|
|
pad = self.iconview.get_property('item-padding')
|
|
layout = self.iconview.create_pango_layout(longest)
|
|
self.iconview.set_item_width(layout.get_pixel_size()[0] + pad * 2)
|
|
else:
|
|
if len(self.treeview.get_columns()) < 1:
|
|
column = Gtk.TreeViewColumn(
|
|
None, Gtk.CellRendererText(), text=0)
|
|
column.set_sizing(Gtk.TreeViewColumnSizing.GROW_ONLY)
|
|
self.treeview.append_column(column)
|
|
selection = self.treeview.get_selection()
|
|
selection.connect(
|
|
'changed', self.on_language_selection_changed)
|
|
self.treeview.set_model(list_store)
|
|
|
|
def set_language(self, language):
|
|
# Support both iconview and treeview
|
|
if self.only:
|
|
model = self.iconview.get_model()
|
|
iterator = model.iter_children(None)
|
|
while iterator is not None:
|
|
if misc.utf8(model.get_value(iterator, 0)) == language:
|
|
path = model.get_path(iterator)
|
|
self.iconview.select_path(path)
|
|
self.iconview.scroll_to_path(path, True, 0.5, 0.5)
|
|
break
|
|
iterator = model.iter_next(iterator)
|
|
else:
|
|
model = self.treeview.get_model()
|
|
iterator = model.iter_children(None)
|
|
while iterator is not None:
|
|
if misc.utf8(model.get_value(iterator, 0)) == language:
|
|
path = model.get_path(iterator)
|
|
self.treeview.get_selection().select_path(path)
|
|
self.treeview.scroll_to_cell(
|
|
path, use_align=True, row_align=0.5)
|
|
break
|
|
iterator = model.iter_next(iterator)
|
|
|
|
if not self.only and 'UBIQUITY_GREETER' in os.environ:
|
|
self.try_ubuntu.set_sensitive(True)
|
|
self.install_ubuntu.set_sensitive(True)
|
|
|
|
def get_language(self):
|
|
# Support both iconview and treeview
|
|
if self.only:
|
|
model = self.iconview.get_model()
|
|
items = self.iconview.get_selected_items()
|
|
if not items:
|
|
return None
|
|
iterator = model.get_iter(items[0])
|
|
else:
|
|
selection = self.treeview.get_selection()
|
|
(model, iterator) = selection.get_selected()
|
|
if iterator is None:
|
|
return None
|
|
else:
|
|
value = misc.utf8(model.get_value(iterator, 0))
|
|
return self.language_choice_map[value][1]
|
|
|
|
def on_language_activated(self, *args, **kwargs):
|
|
self.controller.go_forward()
|
|
|
|
def on_language_selection_changed(self, *args, **kwargs):
|
|
lang = self.get_language()
|
|
self.controller.allow_go_forward(bool(lang))
|
|
if not lang:
|
|
return
|
|
if 'UBIQUITY_GREETER' in os.environ:
|
|
misc.set_indicator_keymaps(lang)
|
|
# strip encoding; we use UTF-8 internally no matter what
|
|
lang = lang.split('.')[0]
|
|
self.controller.translate(lang)
|
|
from gi.repository import Gtk
|
|
ltr = i18n.get_string('default-ltr', lang, 'ubiquity/imported')
|
|
if ltr == 'default:RTL':
|
|
Gtk.Widget.set_default_direction(Gtk.TextDirection.RTL)
|
|
else:
|
|
Gtk.Widget.set_default_direction(Gtk.TextDirection.LTR)
|
|
|
|
if self.only:
|
|
# The language page for oem-config doesn't have the fancy greeter.
|
|
return
|
|
|
|
# TODO: Cache these.
|
|
release = misc.get_release()
|
|
install_medium = misc.get_install_medium()
|
|
install_medium = i18n.get_string(install_medium, lang)
|
|
# Set the release name (Ubuntu 10.04) and medium (USB or CD) where
|
|
# necessary.
|
|
w = self.try_install_text_label
|
|
text = i18n.get_string(Gtk.Buildable.get_name(w), lang)
|
|
text = text.replace('${RELEASE}', release.name)
|
|
text = text.replace('${MEDIUM}', install_medium)
|
|
w.set_label(text)
|
|
|
|
# Big buttons.
|
|
for w in (self.try_ubuntu, self.install_ubuntu):
|
|
text = i18n.get_string(Gtk.Buildable.get_name(w), lang)
|
|
text = text.replace('${RELEASE}', release.name)
|
|
text = text.replace('${MEDIUM}', install_medium)
|
|
w.get_child().set_markup('<span size="x-large">%s</span>' % text)
|
|
|
|
# We need to center each button under each image *and* have a homogeous
|
|
# size between the two buttons.
|
|
self.try_ubuntu.set_size_request(-1, -1)
|
|
self.install_ubuntu.set_size_request(-1, -1)
|
|
try_w = self.try_ubuntu.size_request().width
|
|
install_w = self.install_ubuntu.size_request().width
|
|
if try_w > install_w:
|
|
self.try_ubuntu.set_size_request(try_w, -1)
|
|
self.install_ubuntu.set_size_request(try_w, -1)
|
|
elif install_w > try_w:
|
|
self.try_ubuntu.set_size_request(install_w, -1)
|
|
self.install_ubuntu.set_size_request(install_w, -1)
|
|
|
|
# Make the forward button a consistent size, regardless of its text.
|
|
install_label = i18n.get_string('install_button', lang)
|
|
next_button = self.controller._wizard.next
|
|
next_label = next_button.get_label()
|
|
|
|
next_button.set_size_request(-1, -1)
|
|
next_w = next_button.size_request().width
|
|
next_button.set_label(install_label)
|
|
install_w = next_button.size_request().width
|
|
next_button.set_label(next_label)
|
|
if next_w > install_w:
|
|
next_button.set_size_request(next_w, -1)
|
|
else:
|
|
next_button.set_size_request(install_w, -1)
|
|
|
|
self.update_release_notes_label()
|
|
for w in self.page.get_children():
|
|
w.show()
|
|
|
|
def plugin_set_online_state(self, state):
|
|
from gi.repository import GLib
|
|
if self.release_notes_label:
|
|
if self.timeout_id:
|
|
GLib.source_remove(self.timeout_id)
|
|
if state:
|
|
self.release_notes_label.show()
|
|
self.timeout_id = GLib.timeout_add(
|
|
300, self.check_returncode)
|
|
else:
|
|
self.release_notes_label.hide()
|
|
|
|
def check_returncode(self, *args):
|
|
import subprocess
|
|
if self.wget_retcode is not None or self.wget_proc is None:
|
|
self.wget_proc = subprocess.Popen(
|
|
['wget', '-q', _wget_url, '--timeout=15', '--tries=1',
|
|
'-O', '/dev/null'])
|
|
self.wget_retcode = self.wget_proc.poll()
|
|
if self.wget_retcode is None:
|
|
return True
|
|
else:
|
|
if self.wget_retcode == 0:
|
|
self.update_installer = True
|
|
else:
|
|
self.update_installer = False
|
|
self.update_release_notes_label()
|
|
return False
|
|
|
|
def update_release_notes_label(self):
|
|
print("update_release_notes_label()")
|
|
lang = self.get_language()
|
|
if not lang:
|
|
return
|
|
# strip encoding; we use UTF-8 internally no matter what
|
|
lang = lang.split('.')[0]
|
|
# Either leave the release notes label alone (both release notes and a
|
|
# critical update are available), set it to just the release notes,
|
|
# just the critical update, or neither, as appropriate.
|
|
if self.release_notes_label:
|
|
if self.release_notes_found and self.update_installer:
|
|
text = i18n.get_string('release_notes_label', lang)
|
|
self.release_notes_label.set_markup(text)
|
|
elif self.release_notes_found:
|
|
text = i18n.get_string('release_notes_only', lang)
|
|
self.release_notes_label.set_markup(text)
|
|
elif self.update_installer:
|
|
text = i18n.get_string('update_installer_only', lang)
|
|
self.release_notes_label.set_markup(text)
|
|
else:
|
|
self.release_notes_label.set_markup('')
|
|
|
|
def set_oem_id(self, text):
|
|
return self.oem_id_entry.set_text(text)
|
|
|
|
def get_oem_id(self):
|
|
return self.oem_id_entry.get_text()
|
|
|
|
def on_link_clicked(self, widget, uri):
|
|
# Connected in glade.
|
|
lang = self.get_language()
|
|
if not lang:
|
|
lang = 'C'
|
|
lang = lang.split('.')[0] # strip encoding
|
|
if uri == 'update':
|
|
if self.updating_installer:
|
|
return True
|
|
self.updating_installer = True
|
|
if not auto_update.update(self.controller._wizard):
|
|
# no updates, so don't check again
|
|
if self.release_notes_url:
|
|
text = i18n.get_string('release_notes_only', lang)
|
|
self.release_notes_label.set_markup(text)
|
|
else:
|
|
self.release_notes_label.hide()
|
|
self.updating_installer = False
|
|
elif uri == 'release-notes':
|
|
uri = self.release_notes_url.replace('${LANG}', lang)
|
|
misc.launch_uri(uri)
|
|
return True
|
|
|
|
|
|
class PageKde(PageBase):
|
|
plugin_breadcrumb = 'ubiquity/text/breadcrumb_language'
|
|
plugin_is_language = True
|
|
|
|
def __init__(self, controller, *args, **kwargs):
|
|
self.controller = controller
|
|
self.wget_retcode = None
|
|
self.wget_proc = None
|
|
if self.controller.oem_user_config:
|
|
self.only = True
|
|
else:
|
|
self.only = False
|
|
|
|
try:
|
|
from PyQt5 import uic
|
|
from PyQt5.QtGui import QPixmap, QIcon
|
|
from PyQt5.QtWidgets import QWidget
|
|
self.page = uic.loadUi('/usr/share/ubiquity/qt/stepLanguage.ui')
|
|
self.combobox = self.page.language_combobox
|
|
# Tell layout that all items are of uniform sizes
|
|
# Fixes LP:1187762
|
|
self.combobox.view().setUniformItemSizes(True)
|
|
self.combobox.currentIndexChanged[str].connect(
|
|
self.on_language_selection_changed)
|
|
if not self.controller.oem_config:
|
|
self.page.oem_widget.hide()
|
|
|
|
def init_big_button(button, image_name):
|
|
pix = QPixmap('/usr/share/ubiquity/qt/images/' + image_name)
|
|
icon = QIcon(pix)
|
|
button.setIcon(icon)
|
|
button.setIconSize(pix.size())
|
|
# Set a fixed height to ensure the button text is not cropped
|
|
# when the window is resized
|
|
button.setFixedHeight(button.sizeHint().height())
|
|
|
|
def inst(*args):
|
|
self.page.try_ubuntu.setEnabled(False)
|
|
self.controller.go_forward()
|
|
self.page.install_ubuntu.clicked.connect(inst)
|
|
self.page.try_ubuntu.clicked.connect(self.on_try_ubuntu_clicked)
|
|
init_big_button(self.page.install_ubuntu, 'install.png')
|
|
init_big_button(self.page.try_ubuntu, 'try.png')
|
|
|
|
self.release_notes_url = ''
|
|
self.update_installer = True
|
|
self.updating_installer = False
|
|
if self.controller.oem_config or auto_update.already_updated():
|
|
self.update_installer = False
|
|
self.release_notes_found = False
|
|
try:
|
|
with open(_release_notes_url_path) as release_notes:
|
|
self.release_notes_url = release_notes.read().rstrip('\n')
|
|
self.release_notes_found = True
|
|
except (KeyboardInterrupt, SystemExit):
|
|
raise
|
|
except Exception:
|
|
pass
|
|
|
|
if self.release_notes_url:
|
|
self.page.release_notes_label.linkActivated.connect(
|
|
self.on_release_notes_link)
|
|
else:
|
|
self.page.release_notes_label.hide()
|
|
|
|
if 'UBIQUITY_GREETER' not in os.environ:
|
|
self.page.try_ubuntu.hide()
|
|
self.page.try_install_text_label.hide()
|
|
self.page.install_ubuntu.hide()
|
|
|
|
# We do not want to show the yet to be substituted strings
|
|
# (${MEDIUM}, etc), so don't show the core of the page until
|
|
# it's ready.
|
|
self.widgetHidden = []
|
|
for w in self.page.children():
|
|
if isinstance(w, QWidget) and not w.isHidden():
|
|
self.widgetHidden.append(w)
|
|
w.hide()
|
|
|
|
except Exception as e:
|
|
self.debug('Could not create language page: %s', e)
|
|
self.page = None
|
|
|
|
self.plugin_widgets = self.page
|
|
|
|
@plugin.only_this_page
|
|
def on_try_ubuntu_clicked(self, *args):
|
|
if not self.controller.allowed_change_step():
|
|
# The button's already been clicked once, so stop reacting to it.
|
|
# LP: #911907.
|
|
return
|
|
# Spinning cursor.
|
|
self.controller.allow_change_step(False)
|
|
# Queue quit.
|
|
self.page.install_ubuntu.setEnabled(False)
|
|
self.controller._wizard.current_page = None
|
|
self.controller.dbfilter.ok_handler()
|
|
|
|
def on_release_notes_link(self, link):
|
|
lang = self.selected_language()
|
|
if link == "release-notes":
|
|
if lang:
|
|
lang = lang.split('.')[0].lower()
|
|
url = self.release_notes_url.replace('${LANG}', lang)
|
|
self.openURL(url)
|
|
elif link == "update":
|
|
if self.updating_installer:
|
|
return
|
|
self.updating_installer = True
|
|
if not auto_update.update(self.controller._wizard):
|
|
# no updates, so don't check again
|
|
text = i18n.get_string('release_notes_only', lang)
|
|
self.page.release_notes_label.setText(text)
|
|
self.updating_installer = False
|
|
|
|
def openURL(self, url):
|
|
from PyQt5.QtGui import QDesktopServices
|
|
from PyQt5.QtCore import QUrl
|
|
import shutil
|
|
import os
|
|
|
|
# this nonsense is needed because kde doesn't want to be root
|
|
misc.drop_privileges()
|
|
misc.drop_privileges_save()
|
|
# copy over gtkrc-2.0 to get the themeing right
|
|
if os.path.exists("/usr/share/kubuntu-default-settings"):
|
|
shutil.copy("/usr/share/kubuntu-default-settings/" +
|
|
"dot-gtkrc-2.0-kde4",
|
|
os.getenv("HOME") + "/.gtkrc-2.0")
|
|
QDesktopServices.openUrl(QUrl(url))
|
|
misc.regain_privileges()
|
|
misc.regain_privileges_save()
|
|
|
|
def set_language_choices(self, choices, choice_map):
|
|
PageBase.set_language_choices(self, choices, choice_map)
|
|
self.combobox.clear()
|
|
self.combobox.addItems(choices)
|
|
|
|
def set_language(self, language):
|
|
index = self.combobox.findText(str(language))
|
|
if index < 0:
|
|
self.combobox.addItem("C")
|
|
else:
|
|
self.combobox.setCurrentIndex(index)
|
|
|
|
if not self.only and 'UBIQUITY_GREETER' in os.environ:
|
|
self.page.try_ubuntu.setEnabled(True)
|
|
self.page.install_ubuntu.setEnabled(True)
|
|
|
|
def get_language(self):
|
|
lang = self.selected_language()
|
|
return lang if lang else 'C'
|
|
|
|
def selected_language(self):
|
|
lang = self.combobox.currentText()
|
|
if not lang or not hasattr(self, 'language_choice_map'):
|
|
return None
|
|
else:
|
|
return self.language_choice_map[str(lang)][1]
|
|
|
|
def on_language_selection_changed(self):
|
|
lang = self.selected_language()
|
|
if not lang:
|
|
return
|
|
# strip encoding; we use UTF-8 internally no matter what
|
|
lang = lang.split('.')[0]
|
|
self.controller.translate(lang)
|
|
if not self.only:
|
|
release = misc.get_release()
|
|
install_medium = misc.get_install_medium()
|
|
install_medium = i18n.get_string(install_medium, lang)
|
|
for widget in (self.page.try_install_text_label,
|
|
self.page.try_ubuntu,
|
|
self.page.install_ubuntu):
|
|
text = widget.text()
|
|
text = text.replace('${RELEASE}', release.name)
|
|
text = text.replace('${MEDIUM}', install_medium)
|
|
text = text.replace('Ubuntu', 'Kubuntu')
|
|
widget.setText(text)
|
|
|
|
self.update_release_notes_label()
|
|
for w in self.widgetHidden:
|
|
w.show()
|
|
self.widgetHidden = []
|
|
|
|
def plugin_set_online_state(self, state):
|
|
from PyQt5.QtCore import QTimer
|
|
if self.page.release_notes_label:
|
|
if state:
|
|
self.page.release_notes_label.show()
|
|
QTimer.singleShot(300, self.check_returncode)
|
|
self.timer = QTimer(self.page)
|
|
self.timer.timeout.connect(self.check_returncode)
|
|
self.timer.start(300)
|
|
else:
|
|
self.page.release_notes_label.hide()
|
|
|
|
def check_returncode(self, *args):
|
|
import subprocess
|
|
if self.wget_retcode is not None or self.wget_proc is None:
|
|
self.wget_proc = subprocess.Popen(
|
|
['wget', '-q', _wget_url, '--timeout=15', '--tries=1',
|
|
'-O', '/dev/null'])
|
|
self.wget_retcode = self.wget_proc.poll()
|
|
if self.wget_retcode is None:
|
|
return True
|
|
else:
|
|
if self.wget_retcode == 0:
|
|
self.update_installer = True
|
|
else:
|
|
self.update_installer = False
|
|
self.update_release_notes_label()
|
|
self.timer.timeout.disconnect(self.check_returncode)
|
|
|
|
def update_release_notes_label(self):
|
|
lang = self.selected_language()
|
|
if not lang:
|
|
return
|
|
# strip encoding; we use UTF-8 internally no matter what
|
|
lang = lang.split('.')[0]
|
|
# Either leave the release notes label alone (both release notes and a
|
|
# critical update are available), set it to just the release notes,
|
|
# just the critical update, or neither, as appropriate.
|
|
if self.page.release_notes_label:
|
|
if self.release_notes_found and self.update_installer:
|
|
text = i18n.get_string('release_notes_label', lang)
|
|
self.page.release_notes_label.setText(text)
|
|
elif self.release_notes_found:
|
|
text = i18n.get_string('release_notes_only', lang)
|
|
self.page.release_notes_label.setText(text)
|
|
elif self.update_installer:
|
|
text = i18n.get_string('update_installer_only', lang)
|
|
self.page.release_notes_label.setText(text)
|
|
|
|
def set_oem_id(self, text):
|
|
return self.page.oem_id_entry.setText(text)
|
|
|
|
def get_oem_id(self):
|
|
return str(self.page.oem_id_entry.text())
|
|
|
|
|
|
class PageDebconf(PageBase):
|
|
plugin_title = 'ubiquity/text/language_heading_label'
|
|
|
|
def __init__(self, controller, *args, **kwargs):
|
|
self.controller = controller
|
|
|
|
|
|
class PageNoninteractive(PageBase):
|
|
def __init__(self, controller, *args, **kwargs):
|
|
self.controller = controller
|
|
|
|
def set_language(self, language):
|
|
"""Set the current selected language."""
|
|
# Use the language code, not the translated name
|
|
self.language = self.language_choice_map[language][1]
|
|
|
|
def get_language(self):
|
|
"""Get the current selected language."""
|
|
return self.language
|
|
|
|
|
|
class Page(plugin.Plugin):
|
|
def prepare(self, unfiltered=False):
|
|
self.language_question = None
|
|
self.initial_language = None
|
|
self.db.fset('localechooser/languagelist', 'seen', 'false')
|
|
with misc.raised_privileges():
|
|
osextras.unlink_force('/var/lib/localechooser/preseeded')
|
|
osextras.unlink_force('/var/lib/localechooser/langlevel')
|
|
if self.ui.controller.oem_config:
|
|
try:
|
|
self.ui.set_oem_id(self.db.get('oem-config/id'))
|
|
except debconf.DebconfError:
|
|
pass
|
|
|
|
localechooser_script = '/usr/lib/ubiquity/localechooser/localechooser'
|
|
if ('UBIQUITY_FRONTEND' in os.environ and
|
|
os.environ['UBIQUITY_FRONTEND'] == 'debconf_ui'):
|
|
localechooser_script += '-debconf'
|
|
|
|
questions = ['localechooser/languagelist']
|
|
environ = {
|
|
'PATH': '/usr/lib/ubiquity/localechooser:' + os.environ['PATH'],
|
|
}
|
|
if ('UBIQUITY_FRONTEND' in os.environ and
|
|
os.environ['UBIQUITY_FRONTEND'] == "debconf_ui"):
|
|
environ['TERM_FRAMEBUFFER'] = '1'
|
|
else:
|
|
environ['OVERRIDE_SHOW_ALL_LANGUAGES'] = '1'
|
|
return localechooser_script, questions, environ
|
|
|
|
def run(self, priority, question):
|
|
if question == 'localechooser/languagelist':
|
|
self.language_question = question
|
|
if self.initial_language is None:
|
|
self.initial_language = self.db.get(question)
|
|
current_language_index = self.value_index(question)
|
|
only_installable = misc.create_bool(
|
|
self.db.get('ubiquity/only-show-installable-languages'))
|
|
|
|
current_language, sorted_choices, language_display_map = \
|
|
i18n.get_languages(current_language_index, only_installable)
|
|
|
|
self.ui.set_language_choices(sorted_choices,
|
|
language_display_map)
|
|
self.ui.set_language(current_language)
|
|
if len(sorted_choices) == 1:
|
|
self.done = True
|
|
return True
|
|
return plugin.Plugin.run(self, priority, question)
|
|
|
|
def cancel_handler(self):
|
|
# Undo effects of UI translation.
|
|
self.ui.controller.translate(just_me=False, not_me=True)
|
|
plugin.Plugin.cancel_handler(self)
|
|
|
|
def ok_handler(self):
|
|
if self.language_question is not None:
|
|
new_language = self.ui.get_language()
|
|
self.preseed(self.language_question, new_language)
|
|
if (self.initial_language is None or
|
|
self.initial_language != new_language):
|
|
self.db.reset('debian-installer/country')
|
|
if self.ui.controller.oem_config:
|
|
self.preseed('oem-config/id', self.ui.get_oem_id())
|
|
plugin.Plugin.ok_handler(self)
|
|
|
|
def cleanup(self):
|
|
plugin.Plugin.cleanup(self)
|
|
i18n.reset_locale(self.frontend)
|
|
self.frontend.stop_debconf()
|
|
self.ui.controller.translate(just_me=False, not_me=True, reget=True)
|
|
|
|
|
|
class Install(plugin.InstallPlugin):
|
|
def prepare(self, unfiltered=False):
|
|
if 'UBIQUITY_OEM_USER_CONFIG' in os.environ:
|
|
command = ['/usr/share/ubiquity/localechooser-apply']
|
|
else:
|
|
command = [
|
|
'sh', '-c',
|
|
'/usr/lib/ubiquity/localechooser/post-base-installer ' +
|
|
'&& /usr/lib/ubiquity/localechooser/finish-install',
|
|
]
|
|
return command, []
|
|
|
|
def _pam_env_lines(self, fd):
|
|
"""Yield a sequence of logical lines from a PAM environment file."""
|
|
buf = ""
|
|
for line in fd:
|
|
line = line.lstrip()
|
|
if line and line[0] != "#":
|
|
if "#" in line:
|
|
line = line[:line.index("#")]
|
|
for i in range(len(line) - 1, -1, -1):
|
|
if line[i].isspace():
|
|
break
|
|
if line[i] == "\\":
|
|
# Continuation line.
|
|
buf = line[:i]
|
|
else:
|
|
buf += line
|
|
yield buf
|
|
buf = ""
|
|
if buf:
|
|
yield buf
|
|
|
|
def _pam_env_parse_file(self, path):
|
|
"""Parse a PAM environment file just as pam_env does.
|
|
|
|
We use this for reading /etc/default/locale after configuring it.
|
|
"""
|
|
try:
|
|
with open(path) as fd:
|
|
for line in self._pam_env_lines(fd):
|
|
line = line.lstrip()
|
|
if not line or line[0] == "#":
|
|
continue
|
|
if line.startswith("export "):
|
|
line = line[7:]
|
|
line = re.sub(r"[#\n].*", "", line)
|
|
if not re.match(r"^[A-Z_]+=", line):
|
|
continue
|
|
# pam_env's handling of quoting is crazy, but in this
|
|
# case it's better to imitate it than to fix it.
|
|
key, value = line.split("=", 1)
|
|
if value.startswith('"') or value.startswith("'"):
|
|
value = re.sub(r"[\"'](.|$)", r"\1", value[1:])
|
|
yield key, value
|
|
except IOError:
|
|
pass
|
|
|
|
def install(self, target, progress, *args, **kwargs):
|
|
progress.info('ubiquity/install/locales')
|
|
rv = plugin.InstallPlugin.install(
|
|
self, target, progress, *args, **kwargs)
|
|
if not rv:
|
|
locale_file = "/etc/default/locale"
|
|
if 'UBIQUITY_OEM_USER_CONFIG' not in os.environ:
|
|
locale_file = "/target%s" % locale_file
|
|
for key, value in self._pam_env_parse_file(locale_file):
|
|
if key in ("LANG", "LANGUAGE") or key.startswith("LC_"):
|
|
os.environ[key] = value
|
|
# Start using the newly-generated locale, if possible.
|
|
try:
|
|
locale.setlocale(locale.LC_ALL, '')
|
|
except locale.Error:
|
|
pass
|
|
return rv
|