Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/rpms/sugar/0042-Database-support-for-3G-control-panel.patch
diff options
context:
space:
mode:
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.patch494
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
+