diff options
Diffstat (limited to 'rpms/sugar/0042-Database-support-for-3G-control-panel.patch')
-rw-r--r-- | rpms/sugar/0042-Database-support-for-3G-control-panel.patch | 494 |
1 files changed, 494 insertions, 0 deletions
diff --git a/rpms/sugar/0042-Database-support-for-3G-control-panel.patch b/rpms/sugar/0042-Database-support-for-3G-control-panel.patch new file mode 100644 index 0000000..b169a97 --- /dev/null +++ b/rpms/sugar/0042-Database-support-for-3G-control-panel.patch @@ -0,0 +1,494 @@ +From e6412a96e8f7b7e9a498b4d300cccb0acd50abe6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Andr=C3=A9s=20Ambrois?= <andresambrois@gmail.com> +Date: Tue, 11 Jan 2011 19:52:52 +0000 +Subject: [PATCH sugar 42/74] Database support for 3G control panel + +For more information please look at #1630 +--- + configure.ac | 1 + + .../cpsection/modemconfiguration/Makefile.am | 2 + + .../cpsection/modemconfiguration/config.py.in | 20 +++ + extensions/cpsection/modemconfiguration/model.py | 123 ++++++++++++++ + extensions/cpsection/modemconfiguration/view.py | 177 ++++++++++++++++---- + 5 files changed, 290 insertions(+), 33 deletions(-) + create mode 100644 extensions/cpsection/modemconfiguration/config.py.in + mode change 100755 => 100644 extensions/cpsection/modemconfiguration/model.py + +diff --git a/configure.ac b/configure.ac +index df9614f..86f6116 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -57,6 +57,7 @@ extensions/cpsection/frame/Makefile + extensions/cpsection/keyboard/Makefile + extensions/cpsection/language/Makefile + extensions/cpsection/modemconfiguration/Makefile ++extensions/cpsection/modemconfiguration/config.py + extensions/cpsection/Makefile + extensions/cpsection/network/Makefile + extensions/cpsection/power/Makefile +diff --git a/extensions/cpsection/modemconfiguration/Makefile.am b/extensions/cpsection/modemconfiguration/Makefile.am +index 3e2613e..525e02e 100644 +--- a/extensions/cpsection/modemconfiguration/Makefile.am ++++ b/extensions/cpsection/modemconfiguration/Makefile.am +@@ -4,3 +4,5 @@ sugar_PYTHON = \ + __init__.py \ + model.py \ + view.py ++ ++nodist_sugar_PYTHON = config.py +diff --git a/extensions/cpsection/modemconfiguration/config.py.in b/extensions/cpsection/modemconfiguration/config.py.in +new file mode 100644 +index 0000000..6fa688e +--- /dev/null ++++ b/extensions/cpsection/modemconfiguration/config.py.in +@@ -0,0 +1,20 @@ ++# -*- encoding: utf-8 -*- ++# Copyright (C) 2010 Andrés Ambrois ++# ++# 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 US ++ ++PROVIDERS_PATH = "@prefix@/share/mobile-broadband-provider-info/serviceproviders.xml" ++PROVIDERS_FORMAT_SUPPORTED = "2.0" ++COUNTRY_CODES_PATH = "@prefix@/share/zoneinfo/iso3166.tab" +diff --git a/extensions/cpsection/modemconfiguration/model.py b/extensions/cpsection/modemconfiguration/model.py +old mode 100755 +new mode 100644 +index 1e83c44..ca9f75c +--- a/extensions/cpsection/modemconfiguration/model.py ++++ b/extensions/cpsection/modemconfiguration/model.py +@@ -15,11 +15,22 @@ + # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 US + + import gconf ++import gtk ++import os ++import locale ++import logging ++ ++from xml.etree.cElementTree import ElementTree ++from gettext import gettext as _ + + from jarabe.model.network import GSM_USERNAME_PATH, GSM_PASSWORD_PATH, \ + GSM_NUMBER_PATH, GSM_APN_PATH, GSM_PIN_PATH, \ + GSM_PUK_PATH + ++from cpsection.modemconfiguration.config import PROVIDERS_PATH, \ ++ PROVIDERS_FORMAT_SUPPORTED, \ ++ COUNTRY_CODES_PATH ++ + + def get_username(): + client = gconf.client_get_default() +@@ -79,3 +90,115 @@ def set_pin(pin): + def set_puk(puk): + client = gconf.client_get_default() + client.set_string(GSM_PUK_PATH, puk) ++ ++ ++def has_providers_db(): ++ if not os.path.isfile(COUNTRY_CODES_PATH): ++ logging.debug("Mobile broadband provider database: Country " \ ++ "codes path %s not found.", COUNTRY_CODES_PATH) ++ return False ++ try: ++ tree = ElementTree(file=PROVIDERS_PATH) ++ except (IOError, SyntaxError), e: ++ logging.debug("Mobile broadband provider database: Could not read " \ ++ "provider information %s error=%s", PROVIDERS_PATH) ++ return False ++ else: ++ elem = tree.getroot() ++ if elem is None or elem.get('format') != PROVIDERS_FORMAT_SUPPORTED: ++ logging.debug("Mobile broadband provider database: Could not " \ ++ "read provider information. %s is wrong format.", ++ elem.get('format')) ++ return False ++ return True ++ ++ ++class CountryListStore(gtk.ListStore): ++ COUNTRY_CODE = locale.getdefaultlocale()[0][3:5].lower() ++ ++ def __init__(self): ++ gtk.ListStore.__init__(self, str, object) ++ codes = {} ++ with open(COUNTRY_CODES_PATH) as codes_file: ++ for line in codes_file: ++ if line.startswith('#'): ++ continue ++ code, name = line.split('\t')[:2] ++ codes[code.lower()] = name.strip() ++ etree = ElementTree(file=PROVIDERS_PATH).getroot() ++ self._country_idx = None ++ i = 0 ++ for elem in etree.findall('.//country'): ++ code = elem.attrib['code'] ++ if code == self.COUNTRY_CODE: ++ self._country_idx = i ++ else: ++ i += 1 ++ if code in codes: ++ self.append((codes[code], elem)) ++ else: ++ self.append((code, elem)) ++ ++ def get_row_providers(self, row): ++ return self[row][1] ++ ++ def guess_country_row(self): ++ if self._country_idx is not None: ++ return self._country_idx ++ else: ++ return -1 ++ ++ ++class ProviderListStore(gtk.ListStore): ++ def __init__(self, elem): ++ gtk.ListStore.__init__(self, str, object) ++ for provider_elem in elem.findall('.//provider'): ++ apns = provider_elem.findall('.//apn') ++ if not apns: ++ # Skip carriers with CDMA entries only ++ continue ++ self.append((provider_elem.find('.//name').text, apns)) ++ ++ def get_row_plans(self, row): ++ return self[row][1] ++ ++ ++class PlanListStore(gtk.ListStore): ++ LANG_NS_ATTR = '{http://www.w3.org/XML/1998/namespace}lang' ++ LANG = locale.getdefaultlocale()[0][:2] ++ DEFAULT_NUMBER = '*99#' ++ ++ def __init__(self, elems): ++ gtk.ListStore.__init__(self, str, object) ++ for apn_elem in elems: ++ plan = {} ++ names = apn_elem.findall('.//name') ++ if names: ++ for name in names: ++ if name.get(self.LANG_NS_ATTR) is None: ++ # serviceproviders.xml default value ++ plan['name'] = name.text ++ elif name.get(self.LANG_NS_ATTR) == self.LANG: ++ # Great! We found a name value for our locale! ++ plan['name'] = name.text ++ break ++ else: ++ plan['name'] = _('Default') ++ plan['apn'] = apn_elem.get('value') ++ user = apn_elem.find('.//username') ++ if user is not None: ++ plan['username'] = user.text ++ else: ++ plan['username'] = '' ++ passwd = apn_elem.find('.//password') ++ if passwd is not None: ++ plan['password'] = passwd.text ++ else: ++ plan['password'] = '' ++ ++ plan['number'] = self.DEFAULT_NUMBER ++ ++ self.append((plan['name'], plan)) ++ ++ def get_row_plan(self, row): ++ return self[row][1] +diff --git a/extensions/cpsection/modemconfiguration/view.py b/extensions/cpsection/modemconfiguration/view.py +index c31edba..fad141d 100644 +--- a/extensions/cpsection/modemconfiguration/view.py ++++ b/extensions/cpsection/modemconfiguration/view.py +@@ -14,8 +14,6 @@ + # along with this program; if not, write to the Free Software + # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 US + +-import os +-import logging + from gettext import gettext as _ + + import gtk +@@ -33,7 +31,7 @@ class EntryWithLabel(gtk.HBox): + __gtype_name__ = 'SugarEntryWithLabel' + + def __init__(self, label_text): +- gtk.HBox.__init__(self, spacing=style.DEFAULT_SPACING) ++ gtk.HBox.__init__(self, spacing=style.DEFAULT_SPACING * 2) + + self._timeout_sid = 0 + self._changed_handler = None +@@ -46,11 +44,11 @@ def __init__(self, label_text): + self.pack_start(self.label, expand=False) + self.label.show() + +- self._entry = gtk.Entry(25) +- self._entry.connect('changed', self.__entry_changed_cb) +- self._entry.set_width_chars(25) +- self.pack_start(self._entry, expand=False) +- self._entry.show() ++ self.entry = gtk.Entry(25) ++ self.entry.connect('changed', self.__entry_changed_cb) ++ self.entry.set_width_chars(25) ++ self.pack_start(self.entry, expand=False) ++ self.entry.show() + + def __entry_changed_cb(self, widget, data=None): + if self._timeout_sid: +@@ -61,11 +59,11 @@ def __entry_changed_cb(self, widget, data=None): + def __timeout_cb(self): + self._timeout_sid = 0 + +- if self._entry.get_text() == self.get_value(): ++ if self.entry.get_text() == self.get_value(): + return False + + try: +- self.set_value(self._entry.get_text()) ++ self.set_value(self.entry.get_text()) + except ValueError: + self._is_valid = False + else: +@@ -76,16 +74,17 @@ def __timeout_cb(self): + return False + + def set_text_from_model(self): +- self._entry.set_text(self.get_value()) ++ self.entry.set_text(self.get_value()) + + def get_value(self): + raise NotImplementedError + +- def set_value(self): ++ def set_value(self, value): + raise NotImplementedError + + def _get_is_valid(self): + return self._is_valid ++ + is_valid = gobject.property(type=bool, getter=_get_is_valid, default=True) + + +@@ -168,60 +167,149 @@ def __init__(self, model, alerts=None): + self._model = model + self.restart_alerts = alerts + +- self.set_border_width(style.DEFAULT_SPACING) + self.set_spacing(style.DEFAULT_SPACING) +- self._group = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL) ++ ++ label_group = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL) ++ combo_group = gtk.SizeGroup(gtk.SIZE_GROUP_HORIZONTAL) ++ ++ scrolled_win = gtk.ScrolledWindow() ++ scrolled_win.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) ++ scrolled_win.show() ++ self.add(scrolled_win) ++ ++ main_box = gtk.VBox(spacing=style.DEFAULT_SPACING) ++ main_box.set_border_width(style.DEFAULT_SPACING) ++ main_box.show() ++ scrolled_win.add_with_viewport(main_box) + + explanation = _('You will need to provide the following information' + ' to set up a mobile broadband connection to a' + ' cellular (3G) network.') + 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) ++ main_box.pack_start(self._text, False) + self._text.show() + ++ if model.has_providers_db(): ++ self._upper_box = gtk.VBox(spacing=style.DEFAULT_SPACING) ++ self._upper_box.set_border_width(style.DEFAULT_SPACING) ++ main_box.pack_start(self._upper_box, expand=False) ++ self._upper_box.show() ++ ++ ++ box = gtk.HBox(spacing=style.DEFAULT_SPACING * 2) ++ label = gtk.Label(_('Country:')) ++ label.set_alignment(1, 0.5) ++ label_group.add_widget(label) ++ box.pack_start(label, False) ++ label.show() ++ country_store = model.CountryListStore() ++ country_combo = gtk.ComboBox(country_store) ++ combo_group.add_widget(country_combo) ++ cell = gtk.CellRendererText() ++ cell.props.xalign = 0.5 ++ country_combo.pack_start(cell) ++ country_combo.add_attribute(cell, 'text', 0) ++ country_combo.connect('changed', self.__country_selected_cb) ++ box.pack_start(country_combo, False) ++ country_combo.show() ++ self._upper_box.pack_start(box, False) ++ box.show() ++ ++ box = gtk.HBox(spacing=style.DEFAULT_SPACING * 2) ++ label = gtk.Label(_('Provider:')) ++ label.set_alignment(1, 0.5) ++ label_group.add_widget(label) ++ box.pack_start(label, False) ++ label.show() ++ self._providers_combo = gtk.ComboBox() ++ combo_group.add_widget(self._providers_combo) ++ cell = gtk.CellRendererText() ++ cell.props.xalign = 0.5 ++ self._providers_combo.pack_start(cell) ++ self._providers_combo.add_attribute(cell, 'text', 0) ++ self._providers_combo.connect('changed', ++ self.__provider_selected_cb) ++ box.pack_start(self._providers_combo, False) ++ self._providers_combo.show() ++ self._upper_box.pack_start(box, False) ++ box.show() ++ ++ box = gtk.HBox(spacing=style.DEFAULT_SPACING*2) ++ label = gtk.Label(_('Plan:')) ++ label.set_alignment(1, 0.5) ++ label_group.add_widget(label) ++ box.pack_start(label, False) ++ label.show() ++ self._plan_combo = gtk.ComboBox() ++ combo_group.add_widget(self._plan_combo) ++ cell = gtk.CellRendererText() ++ cell.props.xalign = 0.5 ++ self._plan_combo.pack_start(cell) ++ self._plan_combo.add_attribute(cell, 'text', 0) ++ self._plan_combo.connect('changed', self.__plan_selected_cb) ++ box.pack_start(self._plan_combo, False) ++ self._plan_combo.show() ++ self._upper_box.pack_start(box, False) ++ box.show() ++ ++ country_combo.set_active(country_store.guess_country_row()) ++ ++ separator = gtk.HSeparator() ++ main_box.pack_start(separator, False) ++ separator.show() ++ ++ self._lower_box = gtk.VBox(spacing=style.DEFAULT_SPACING) ++ self._lower_box.set_border_width(style.DEFAULT_SPACING) ++ main_box.pack_start(self._lower_box, expand=False) ++ self._lower_box.show() ++ + self._username_entry = UsernameEntry(model) + self._username_entry.connect('notify::is-valid', + self.__notify_is_valid_cb) +- self._group.add_widget(self._username_entry.label) +- self.pack_start(self._username_entry, expand=False) ++ label_group.add_widget(self._username_entry.label) ++ combo_group.add_widget(self._username_entry.entry) ++ self._lower_box.pack_start(self._username_entry, fill=False) + self._username_entry.show() + + self._password_entry = PasswordEntry(model) + self._password_entry.connect('notify::is-valid', + self.__notify_is_valid_cb) +- self._group.add_widget(self._password_entry.label) +- self.pack_start(self._password_entry, expand=False) ++ label_group.add_widget(self._password_entry.label) ++ combo_group.add_widget(self._password_entry.entry) ++ self._lower_box.pack_start(self._password_entry, fill=False) + self._password_entry.show() + + self._number_entry = NumberEntry(model) + self._number_entry.connect('notify::is-valid', + self.__notify_is_valid_cb) +- self._group.add_widget(self._number_entry.label) +- self.pack_start(self._number_entry, expand=False) ++ label_group.add_widget(self._number_entry.label) ++ combo_group.add_widget(self._number_entry.entry) ++ self._lower_box.pack_start(self._number_entry, fill=False) + self._number_entry.show() + + self._apn_entry = ApnEntry(model) + self._apn_entry.connect('notify::is-valid', + self.__notify_is_valid_cb) +- self._group.add_widget(self._apn_entry.label) +- self.pack_start(self._apn_entry, expand=False) ++ label_group.add_widget(self._apn_entry.label) ++ combo_group.add_widget(self._apn_entry.entry) ++ self._lower_box.pack_start(self._apn_entry, fill=False) + self._apn_entry.show() + + self._pin_entry = PinEntry(model) + self._pin_entry.connect('notify::is-valid', + self.__notify_is_valid_cb) +- self._group.add_widget(self._pin_entry.label) +- self.pack_start(self._pin_entry, expand=False) ++ label_group.add_widget(self._pin_entry.label) ++ self._lower_box.pack_start(self._pin_entry, fill=False) + self._pin_entry.show() + + self._puk_entry = PukEntry(model) + self._puk_entry.connect('notify::is-valid', + self.__notify_is_valid_cb) +- self._group.add_widget(self._puk_entry.label) +- self.pack_start(self._puk_entry, expand=False) ++ label_group.add_widget(self._puk_entry.label) ++ combo_group.add_widget(self._puk_entry.entry) ++ self._lower_box.pack_start(self._puk_entry, fill=False) + self._puk_entry.show() + + self.setup() +@@ -239,14 +327,37 @@ def setup(self): + def undo(self): + self._model.undo() + ++ def __country_selected_cb(self, combo): ++ model = combo.get_model() ++ providers = model.get_row_providers(combo.get_active()) ++ self._providers_combo.set_model( ++ self._model.ProviderListStore(providers)) ++ ++ def __provider_selected_cb(self, combo): ++ model = combo.get_model() ++ plans = model.get_row_plans(combo.get_active()) ++ self._plan_combo.set_model(self._model.PlanListStore(plans)) ++ ++ def __plan_selected_cb(self, combo): ++ model = combo.get_model() ++ plan = model.get_row_plan(combo.get_active()) ++ self._username_entry.set_value(plan['username']) ++ self._username_entry.set_text_from_model() ++ self._password_entry.set_value(plan['password']) ++ self._password_entry.set_text_from_model() ++ self._number_entry.set_value(plan['number']) ++ self._number_entry.set_text_from_model() ++ self._apn_entry.set_value(plan['apn']) ++ self._apn_entry.set_text_from_model() ++ + def _validate(self): + if self._username_entry.is_valid and \ +- self._password_entry.is_valid and \ ++ self._password_entry.is_valid and \ + self._number_entry.is_valid and \ +- self._apn_entry.is_valid and \ +- self._pin_entry.is_valid and \ +- self._puk_entry.is_valid: +- self.props.is_valid = True ++ self._apn_entry.is_valid and \ ++ self._pin_entry.is_valid and \ ++ self._puk_entry.is_valid: ++ self.props.is_valid = True + else: + self.props.is_valid = False + +-- +1.7.6 + |