Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/extensions/cpsection/language/view.py
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/cpsection/language/view.py')
-rw-r--r--extensions/cpsection/language/view.py281
1 files changed, 281 insertions, 0 deletions
diff --git a/extensions/cpsection/language/view.py b/extensions/cpsection/language/view.py
new file mode 100644
index 0000000..1553959
--- /dev/null
+++ b/extensions/cpsection/language/view.py
@@ -0,0 +1,281 @@
+# Copyright (C) 2008, OLPC
+# Copyright (C) 2009, Simon Schampijer
+#
+# 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 gtk
+import gobject
+import gettext
+
+from sugar.graphics import style
+from sugar.graphics.icon import Icon
+
+from jarabe.controlpanel.sectionview import SectionView
+from jarabe.controlpanel.inlinealert import InlineAlert
+
+_translate_language = lambda msg: gettext.dgettext('iso_639', msg)
+_translate_country = lambda msg: gettext.dgettext('iso_3166', msg)
+
+CLASS = 'Language'
+ICON = 'module-language'
+TITLE = gettext.gettext('Language')
+
+
+class Language(SectionView):
+ def __init__(self, model, alerts):
+ SectionView.__init__(self)
+
+ self._model = model
+ self.restart_alerts = alerts
+ self._lang_sid = 0
+ self._selected_lang_count = 0
+ self._labels = []
+ self._stores = []
+ self._comboboxes = []
+ self._add_remove_boxes = []
+ self._changed = False
+ self._cursor_change_handler = None
+
+ self._available_locales = self._model.read_all_languages()
+ self._selected_locales = self._model.get_languages()
+
+ self.set_border_width(style.DEFAULT_SPACING * 2)
+ self.set_spacing(style.DEFAULT_SPACING)
+
+ explanation = gettext.gettext('Add languages in the order you prefer.'
+ ' If a translation is not available,'
+ ' the next in the list will be used.')
+ self._text = gtk.Label(explanation)
+ self._text.set_width_chars(100)
+ self._text.set_line_wrap(True)
+ self._text.set_alignment(0, 0)
+ self.pack_start(self._text, False)
+ self._text.show()
+
+ scrolled = gtk.ScrolledWindow()
+ scrolled.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+ scrolled.show()
+ self.pack_start(scrolled, expand=True)
+
+ self._table = gtk.Table(rows=1, columns=3, homogeneous=False)
+ self._table.set_border_width(style.DEFAULT_SPACING * 2)
+ self._table.show()
+ scrolled.add_with_viewport(self._table)
+
+ self._lang_alert_box = gtk.HBox(spacing=style.DEFAULT_SPACING)
+ self.pack_start(self._lang_alert_box, False)
+
+ self._lang_alert = InlineAlert()
+ self._lang_alert_box.pack_start(self._lang_alert)
+ if 'lang' in self.restart_alerts:
+ self._lang_alert.props.msg = self.restart_msg
+ self._lang_alert.show()
+ self._lang_alert_box.show()
+
+ self.setup()
+
+ def _add_row(self, locale_code=None):
+ """Adds a row to the table"""
+
+ self._selected_lang_count += 1
+
+ self._table.resize(self._selected_lang_count, 3)
+
+ label = gtk.Label(str=str(self._selected_lang_count))
+ label.modify_fg(gtk.STATE_NORMAL,
+ style.COLOR_SELECTION_GREY.get_gdk_color())
+ self._labels.append(label)
+ self._attach_to_table(label, 0, 1, padding=1)
+ label.show()
+
+ store = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
+ for language, country, code in self._available_locales:
+ description = '%s (%s)' % (_translate_language(language), \
+ _translate_country(country))
+ store.append([code, description])
+
+ combobox = gtk.ComboBox(model=store)
+ cell = gtk.CellRendererText()
+ combobox.pack_start(cell)
+ combobox.add_attribute(cell, 'text', 1)
+
+ if locale_code:
+ for row in store:
+ lang = locale_code.split('.')[0]
+ lang_column = row[0].split('.')[0]
+ if lang in lang_column:
+ combobox.set_active_iter(row.iter)
+ break
+ else:
+ combobox.set_active(1)
+
+ combobox.connect('changed', self.__combobox_changed_cb)
+
+ self._stores.append(store)
+ self._comboboxes.append(combobox)
+ self._attach_to_table(combobox, 1, 2, yoptions=gtk.SHRINK)
+
+ add_remove_box = self._create_add_remove_box()
+ self._add_remove_boxes.append(add_remove_box)
+ self._attach_to_table(add_remove_box, 2, 3)
+
+ add_remove_box.show_all()
+
+ if self._selected_lang_count > 1:
+ previous_add_removes = self._add_remove_boxes[-2]
+ previous_add_removes.hide_all()
+
+ self._determine_add_remove_visibility()
+
+ combobox.show()
+
+ def _attach_to_table(self, widget, row, column, padding=20, \
+ yoptions=gtk.FILL):
+ self._table.attach(widget, row, column, \
+ self._selected_lang_count - 1, self._selected_lang_count, \
+ xoptions=gtk.FILL, yoptions=yoptions, xpadding=padding, \
+ ypadding=padding)
+
+ def _delete_last_row(self):
+ """Deletes the last row of the table"""
+
+ self._selected_lang_count -= 1
+
+ label, add_remove_box, combobox, store_ = self._get_last_row()
+
+ label.destroy()
+ add_remove_box.destroy()
+ combobox.destroy()
+
+ self._table.resize(self._selected_lang_count, 3)
+
+ self._add_remove_boxes[-1].show_all()
+
+ def _get_last_row(self):
+ label = self._labels.pop()
+ add_remove_box = self._add_remove_boxes.pop()
+ combobox = self._comboboxes.pop()
+ store = self._stores.pop()
+
+ return label, add_remove_box, combobox, store
+
+ def setup(self):
+ for locale in self._selected_locales:
+ self._add_row(locale_code=locale)
+
+ def undo(self):
+ self._model.undo()
+ self._lang_alert.hide()
+
+ def _create_add_remove_box(self):
+ """Creates gtk.Hbox with add/remove buttons"""
+ add_icon = Icon(icon_name='list-add')
+
+ add_button = gtk.Button()
+ add_button.set_image(add_icon)
+ add_button.connect('clicked',
+ self.__add_button_clicked_cb)
+
+ remove_icon = Icon(icon_name='list-remove')
+ remove_button = gtk.Button()
+ remove_button.set_image(remove_icon)
+ remove_button.connect('clicked',
+ self.__remove_button_clicked_cb)
+
+ add_remove_box = gtk.HButtonBox()
+ add_remove_box.set_layout(gtk.BUTTONBOX_START)
+ add_remove_box.set_spacing(10)
+ add_remove_box.pack_start(add_button)
+ add_remove_box.pack_start(remove_button)
+
+ return add_remove_box
+
+ def __add_button_clicked_cb(self, button):
+ self._add_row()
+ self._check_change()
+
+ def __remove_button_clicked_cb(self, button):
+ self._delete_last_row()
+ self._check_change()
+
+ def __combobox_changed_cb(self, button):
+ self._check_change()
+
+ def _check_change(self):
+ selected_langs = self._get_selected_langs()
+ last_lang = selected_langs[-1]
+
+ self._determine_add_remove_visibility(last_lang=last_lang)
+
+ self._changed = (selected_langs != self._selected_locales)
+
+ if self._changed == False:
+ # The user reverted back to the original config
+ self.needs_restart = False
+ if 'lang' in self.restart_alerts:
+ self.restart_alerts.remove('lang')
+ self._lang_alert.hide()
+ if self._lang_sid:
+ gobject.source_remove(self._lang_sid)
+ self._model.undo()
+ return False
+
+ if self._lang_sid:
+ gobject.source_remove(self._lang_sid)
+ self._lang_sid = gobject.timeout_add(self._APPLY_TIMEOUT,
+ self.__lang_timeout_cb,
+ selected_langs)
+
+ def _get_selected_langs(self):
+ new_codes = []
+ for combobox in self._comboboxes:
+ it = combobox.get_active_iter()
+ model = combobox.get_model()
+ lang_code = model.get(it, 0)[0]
+ new_codes.append(lang_code)
+
+ return new_codes
+
+ def _determine_add_remove_visibility(self, last_lang=None):
+ # We should not let users add fallback languages for English (USA)
+ # This is because the software is not usually _translated_ into English
+ # which means that the fallback gets selected automatically
+
+ if last_lang is None:
+ selected_langs = self._get_selected_langs()
+ last_lang = selected_langs[-1]
+
+ add_remove_box = self._add_remove_boxes[-1]
+ buttons = add_remove_box.get_children()
+ add_button, remove_button = buttons
+
+ if last_lang.startswith('en_US'):
+ add_button.props.visible = False
+ else:
+ add_button.props.visible = True
+
+ if self._selected_lang_count == 1:
+ remove_button.props.visible = False
+ else:
+ remove_button.props.visible = True
+
+ def __lang_timeout_cb(self, codes):
+ self._lang_sid = 0
+ self._model.set_languages_list(codes)
+ self.restart_alerts.append('lang')
+ self.needs_restart = True
+ self._lang_alert.props.msg = self.restart_msg
+ self._lang_alert.show()
+ return False