Removing a lot of code that shouldn't be needed for telepathy
authorEd Page <eopage@byu.net>
Fri, 25 Sep 2009 18:06:34 +0000 (13:06 -0500)
committerEd Page <eopage@byu.net>
Fri, 25 Sep 2009 18:06:34 +0000 (13:06 -0500)
25 files changed:
src/alarm_handler.py [deleted file]
src/alarm_notify.py [deleted file]
src/dc_glade.py [deleted file]
src/dialcentral.glade [deleted file]
src/dialcentral.py [deleted file]
src/example_custom_notifier.py [deleted file]
src/file_backend.py [deleted file]
src/gv_views.py [deleted file]
src/hildonize.py [deleted file]
src/led_handler.py [deleted file]
src/null_views.py [deleted file]
support/dialcentral.desktop [deleted file]
tests/basic_data/basic.csv [deleted file]
tests/basic_data/empty.csv [deleted file]
tests/basic_data/google.csv [deleted file]
tests/basic_data/grandcentral.csv [deleted file]
tests/basic_data/settings.ini [deleted file]
tests/dummy_hildon/__init__.py [deleted file]
tests/dummy_hildon/hildon.py [deleted file]
tests/gc_samples/__init__.py [deleted file]
tests/gc_samples/dump_cookies.py [deleted file]
tests/gc_samples/generate_gc_samples.py [deleted file]
tests/test_file_backend.py [deleted file]
tests/test_gc_backend.py [deleted file]
tests/test_startup.py [deleted file]

diff --git a/src/alarm_handler.py b/src/alarm_handler.py
deleted file mode 100644 (file)
index d3a9bb9..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-#!/usr/bin/env python
-
-import os
-import time
-import datetime
-import ConfigParser
-
-import dbus
-import osso.alarmd as alarmd
-
-
-class AlarmHandler(object):
-
-       _INVALID_COOKIE = -1
-       _TITLE = "Dialcentral Notifications"
-       _LAUNCHER = os.path.abspath(os.path.join(os.path.dirname(__file__), "alarm_notify.py"))
-       _REPEAT_FOREVER = -1
-       _DEFAULT_FLAGS = (
-               alarmd.ALARM_EVENT_NO_DIALOG |
-               alarmd.ALARM_EVENT_NO_SNOOZE |
-               alarmd.ALARM_EVENT_CONNECTED
-       )
-
-       def __init__(self):
-               self._recurrence = 5
-
-               bus = dbus.SystemBus()
-               self._alarmdDBus = bus.get_object("com.nokia.alarmd", "/com/nokia/alarmd");
-               self._alarmCookie = self._INVALID_COOKIE
-               self._launcher = self._LAUNCHER
-
-       def load_settings(self, config, sectionName):
-               try:
-                       self._recurrence = config.getint(sectionName, "recurrence")
-                       self._alarmCookie = config.getint(sectionName, "alarmCookie")
-                       launcher = config.get(sectionName, "notifier")
-                       if launcher:
-                               self._launcher = launcher
-               except ConfigParser.NoOptionError:
-                       pass
-
-       def save_settings(self, config, sectionName):
-               config.set(sectionName, "recurrence", str(self._recurrence))
-               config.set(sectionName, "alarmCookie", str(self._alarmCookie))
-               launcher = self._launcher if self._launcher != self._LAUNCHER else ""
-               config.set(sectionName, "notifier", launcher)
-
-       def apply_settings(self, enabled, recurrence):
-               if recurrence != self._recurrence or enabled != self.isEnabled:
-                       if self.isEnabled:
-                               self._clear_alarm()
-                       if enabled:
-                               self._set_alarm(recurrence)
-               self._recurrence = int(recurrence)
-
-       @property
-       def recurrence(self):
-               return self._recurrence
-
-       @property
-       def isEnabled(self):
-               return self._alarmCookie != self._INVALID_COOKIE
-
-       def _get_start_time(self, recurrence):
-               now = datetime.datetime.now()
-               startTimeMinute = now.minute + max(recurrence, 5) # being safe
-               startTimeHour = now.hour + int(startTimeMinute / 60)
-               startTimeMinute = startTimeMinute % 59
-               now.replace(minute=startTimeMinute)
-               timestamp = int(time.mktime(now.timetuple()))
-               return timestamp
-
-       def _set_alarm(self, recurrence):
-               assert 1 <= recurrence, "Notifications set to occur too frequently: %d" % recurrence
-               alarmTime = self._get_start_time(recurrence)
-
-               #Setup the alarm arguments so that they can be passed to the D-Bus add_event method
-               action = []
-               action.extend(['flags', self._DEFAULT_FLAGS])
-               action.extend(['title', self._TITLE])
-               action.extend(['path', self._launcher])
-               action.extend([
-                       'arguments',
-                       dbus.Array(
-                               [alarmTime, int(27)],
-                               signature=dbus.Signature('v')
-                       )
-               ])  #int(27) used in place of alarm_index
-
-               event = []
-               event.extend([dbus.ObjectPath('/AlarmdEventRecurring'), dbus.UInt32(4)])
-               event.extend(['action', dbus.ObjectPath('/AlarmdActionExec')])  #use AlarmdActionExec instead of AlarmdActionDbus
-               event.append(dbus.UInt32(len(action) / 2))
-               event.extend(action)
-               event.extend(['time', dbus.Int64(alarmTime)])
-               event.extend(['recurr_interval', dbus.UInt32(recurrence)])
-               event.extend(['recurr_count', dbus.Int32(self._REPEAT_FOREVER)])
-
-               self._alarmCookie = self._alarmdDBus.add_event(*event);
-
-       def _clear_alarm(self):
-               if self._alarmCookie == self._INVALID_COOKIE:
-                       return
-               deleteResult = self._alarmdDBus.del_event(dbus.Int32(self._alarmCookie))
-               self._alarmCookie = self._INVALID_COOKIE
-               assert deleteResult != -1, "Deleting of alarm event failed"
-
-
-def main():
-       import ConfigParser
-       import constants
-       try:
-               import optparse
-       except ImportError:
-               return
-
-       parser = optparse.OptionParser()
-       parser.add_option("-x", "--display", action="store_true", dest="display", help="Display data")
-       parser.add_option("-e", "--enable", action="store_true", dest="enabled", help="Whether the alarm should be enabled or not", default=False)
-       parser.add_option("-d", "--disable", action="store_false", dest="enabled", help="Whether the alarm should be enabled or not", default=False)
-       parser.add_option("-r", "--recurrence", action="store", type="int", dest="recurrence", help="How often the alarm occurs", default=5)
-       (commandOptions, commandArgs) = parser.parse_args()
-
-       alarmHandler = AlarmHandler()
-       config = ConfigParser.SafeConfigParser()
-       config.read(constants._user_settings_)
-       alarmHandler.load_settings(config, "alarm")
-
-       if commandOptions.display:
-               print "Alarm (%s) is %s for every %d minutes" % (
-                       alarmHandler._alarmCookie,
-                       "enabled" if alarmHandler.isEnabled else "disabled",
-                       alarmHandler.recurrence,
-               )
-       else:
-               isEnabled = commandOptions.enabled
-               recurrence = commandOptions.recurrence
-               alarmHandler.apply_settings(isEnabled, recurrence)
-
-               alarmHandler.save_settings(config, "alarm")
-               configFile = open(constants._user_settings_, "wb")
-               try:
-                       config.write(configFile)
-               finally:
-                       configFile.close()
-
-
-if __name__ == "__main__":
-       main()
diff --git a/src/alarm_notify.py b/src/alarm_notify.py
deleted file mode 100755 (executable)
index 9cb42b8..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-#!/usr/bin/env python
-
-import os
-import filecmp
-import ConfigParser
-import pprint
-
-import constants
-import gv_backend
-
-
-def get_missed(backend):
-       missedPage = backend._browser.download(backend._missedCallsURL)
-       missedJson = backend._grab_json(missedPage)
-       return missedJson
-
-
-def get_voicemail(backend):
-       voicemailPage = backend._browser.download(backend._voicemailURL)
-       voicemailJson = backend._grab_json(voicemailPage)
-       return voicemailJson
-
-
-def get_sms(backend):
-       smsPage = backend._browser.download(backend._smsURL)
-       smsJson = backend._grab_json(smsPage)
-       return smsJson
-
-
-def remove_reltime(data):
-       for messageData in data["messages"].itervalues():
-               del messageData["relativeStartTime"]
-
-
-def is_type_changed(backend, type, get_material):
-       jsonMaterial = get_material(backend)
-       unreadCount = jsonMaterial["unreadCounts"][type]
-
-       previousSnapshotPath = os.path.join(constants._data_path_, "snapshot_%s.old.json" % type)
-       currentSnapshotPath = os.path.join(constants._data_path_, "snapshot_%s.json" % type)
-
-       try:
-               os.remove(previousSnapshotPath)
-       except OSError, e:
-               # check if failed purely because the old file didn't exist, which is fine
-               if e.errno != 2:
-                       raise
-       try:
-               os.rename(currentSnapshotPath, previousSnapshotPath)
-               previousExists = True
-       except OSError, e:
-               # check if failed purely because the new old file didn't exist, which is fine
-               if e.errno != 2:
-                       raise
-               previousExists = False
-
-       remove_reltime(jsonMaterial)
-       textMaterial = pprint.pformat(jsonMaterial)
-       currentSnapshot = file(currentSnapshotPath, "w")
-       try:
-               currentSnapshot.write(textMaterial)
-       finally:
-               currentSnapshot.close()
-
-       if unreadCount == 0 or not previousExists:
-               return False
-
-       seemEqual = filecmp.cmp(previousSnapshotPath, currentSnapshotPath)
-       return not seemEqual
-
-
-def is_changed():
-       gvCookiePath = os.path.join(constants._data_path_, "gv_cookies.txt")
-       backend = gv_backend.GVDialer(gvCookiePath)
-
-       loggedIn = False
-
-       if not loggedIn:
-               loggedIn = backend.is_authed()
-
-       config = ConfigParser.SafeConfigParser()
-       config.read(constants._user_settings_)
-       if not loggedIn:
-               import base64
-               try:
-                       blobs = (
-                               config.get(constants.__pretty_app_name__, "bin_blob_%i" % i)
-                               for i in xrange(2)
-                       )
-                       creds = (
-                               base64.b64decode(blob)
-                               for blob in blobs
-                       )
-                       username, password = tuple(creds)
-                       loggedIn = backend.login(username, password)
-               except ConfigParser.NoOptionError, e:
-                       pass
-               except ConfigParser.NoSectionError, e:
-                       pass
-
-       try:
-               notifyOnMissed = config.getboolean("2 - Account Info", "notifyOnMissed")
-               notifyOnVoicemail = config.getboolean("2 - Account Info", "notifyOnVoicemail")
-               notifyOnSms = config.getboolean("2 - Account Info", "notifyOnSms")
-       except ConfigParser.NoOptionError, e:
-               notifyOnMissed = False
-               notifyOnVoicemail = False
-               notifyOnSms = False
-       except ConfigParser.NoSectionError, e:
-               notifyOnMissed = False
-               notifyOnVoicemail = False
-               notifyOnSms = False
-
-       assert loggedIn
-       notifySources = []
-       if notifyOnMissed:
-               notifySources.append(("missed", get_missed))
-       if notifyOnVoicemail:
-               notifySources.append(("voicemail", get_voicemail))
-       if notifyOnSms:
-               notifySources.append(("sms", get_sms))
-
-       notifyUser = False
-       for type, get_material in notifySources:
-               if is_type_changed(backend, type, get_material):
-                       notifyUser = True
-       return notifyUser
-
-
-def notify_on_change():
-       notifyUser = is_changed()
-
-       if notifyUser:
-               import led_handler
-               led = led_handler.LedHandler()
-               led.on()
-
-
-if __name__ == "__main__":
-       notify_on_change()
diff --git a/src/dc_glade.py b/src/dc_glade.py
deleted file mode 100755 (executable)
index b23521a..0000000
+++ /dev/null
@@ -1,868 +0,0 @@
-#!/usr/bin/python2.5
-
-"""
-DialCentral - Front end for Google's GoogleVoice service.
-Copyright (C) 2008  Mark Bergman bergman AT merctech DOT com
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version.
-
-This library 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
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-@todo Add "login failed" and "attempting login" notifications
-"""
-
-
-from __future__ import with_statement
-
-import sys
-import gc
-import os
-import threading
-import base64
-import ConfigParser
-import itertools
-import logging
-
-import gtk
-import gtk.glade
-
-import constants
-import hildonize
-import gtk_toolbox
-
-
-def getmtime_nothrow(path):
-       try:
-               return os.path.getmtime(path)
-       except Exception:
-               return 0
-
-
-def display_error_message(msg):
-       error_dialog = gtk.MessageDialog(None, 0, gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE, msg)
-
-       def close(dialog, response):
-               dialog.destroy()
-       error_dialog.connect("response", close)
-       error_dialog.run()
-
-
-class Dialcentral(object):
-
-       _glade_files = [
-               os.path.join(os.path.dirname(__file__), "dialcentral.glade"),
-               os.path.join(os.path.dirname(__file__), "../lib/dialcentral.glade"),
-               '/usr/lib/dialcentral/dialcentral.glade',
-       ]
-
-       KEYPAD_TAB = 0
-       RECENT_TAB = 1
-       MESSAGES_TAB = 2
-       CONTACTS_TAB = 3
-       ACCOUNT_TAB = 4
-
-       NULL_BACKEND = 0
-       GV_BACKEND = 2
-       BACKENDS = (NULL_BACKEND, GV_BACKEND)
-
-       def __init__(self):
-               self._initDone = False
-               self._connection = None
-               self._osso = None
-               self._clipboard = gtk.clipboard_get()
-
-               self._credentials = ("", "")
-               self._selectedBackendId = self.NULL_BACKEND
-               self._defaultBackendId = self.GV_BACKEND
-               self._phoneBackends = None
-               self._dialpads = None
-               self._accountViews = None
-               self._messagesViews = None
-               self._recentViews = None
-               self._contactsViews = None
-               self._alarmHandler = None
-               self._ledHandler = None
-               self._originalCurrentLabels = []
-
-               for path in self._glade_files:
-                       if os.path.isfile(path):
-                               self._widgetTree = gtk.glade.XML(path)
-                               break
-               else:
-                       display_error_message("Cannot find dialcentral.glade")
-                       gtk.main_quit()
-                       return
-
-               self._window = self._widgetTree.get_widget("mainWindow")
-               self._notebook = self._widgetTree.get_widget("notebook")
-               self._errorDisplay = gtk_toolbox.ErrorDisplay(self._widgetTree)
-               self._credentialsDialog = gtk_toolbox.LoginWindow(self._widgetTree)
-
-               self._isFullScreen = False
-               self._app = hildonize.get_app_class()()
-               self._window = hildonize.hildonize_window(self._app, self._window)
-               hildonize.hildonize_text_entry(self._widgetTree.get_widget("usernameentry"))
-               hildonize.hildonize_password_entry(self._widgetTree.get_widget("passwordentry"))
-
-               for scrollingWidget in (
-                       'recent_scrolledwindow',
-                       'message_scrolledwindow',
-                       'contacts_scrolledwindow',
-                       "phoneSelectionMessages_scrolledwindow",
-                       "smsMessages_scrolledwindow",
-               ):
-                       hildonize.hildonize_scrollwindow(self._widgetTree.get_widget(scrollingWidget))
-               for scrollingWidget in (
-                       "phonetypes_scrolledwindow",
-                       "smsMessage_scrolledEntry",
-               ):
-                       hildonize.hildonize_scrollwindow_with_viewport(self._widgetTree.get_widget(scrollingWidget))
-
-               replacementButtons = [gtk.Button("Test")]
-               menu = hildonize.hildonize_menu(
-                       self._window,
-                       self._widgetTree.get_widget("dialpad_menubar"),
-                       replacementButtons
-               )
-
-               self._window.connect("key-press-event", self._on_key_press)
-               self._window.connect("window-state-event", self._on_window_state_change)
-               if not hildonize.IS_HILDON_SUPPORTED:
-                       logging.warning("No hildonization support")
-
-               hildonize.set_application_title(self._window, "%s" % constants.__pretty_app_name__)
-
-               self._window.connect("destroy", self._on_close)
-               self._window.set_default_size(800, 300)
-               self._window.show_all()
-
-               self._loginSink = gtk_toolbox.threaded_stage(
-                       gtk_toolbox.comap(
-                               self._attempt_login,
-                               gtk_toolbox.null_sink(),
-                       )
-               )
-
-               backgroundSetup = threading.Thread(target=self._idle_setup)
-               backgroundSetup.setDaemon(True)
-               backgroundSetup.start()
-
-       def _idle_setup(self):
-               """
-               If something can be done after the UI loads, push it here so it's not blocking the UI
-               """
-               # Barebones UI handlers
-               try:
-                       import null_backend
-                       import null_views
-
-                       self._phoneBackends = {self.NULL_BACKEND: null_backend.NullDialer()}
-                       with gtk_toolbox.gtk_lock():
-                               self._dialpads = {self.NULL_BACKEND: null_views.Dialpad(self._widgetTree)}
-                               self._accountViews = {self.NULL_BACKEND: null_views.AccountInfo(self._widgetTree)}
-                               self._recentViews = {self.NULL_BACKEND: null_views.RecentCallsView(self._widgetTree)}
-                               self._messagesViews = {self.NULL_BACKEND: null_views.MessagesView(self._widgetTree)}
-                               self._contactsViews = {self.NULL_BACKEND: null_views.ContactsView(self._widgetTree)}
-
-                               self._dialpads[self._selectedBackendId].enable()
-                               self._accountViews[self._selectedBackendId].enable()
-                               self._recentViews[self._selectedBackendId].enable()
-                               self._messagesViews[self._selectedBackendId].enable()
-                               self._contactsViews[self._selectedBackendId].enable()
-               except Exception, e:
-                       with gtk_toolbox.gtk_lock():
-                               self._errorDisplay.push_exception()
-
-               # Setup maemo specifics
-               try:
-                       try:
-                               import osso
-                       except (ImportError, OSError):
-                               osso = None
-                       self._osso = None
-                       if osso is not None:
-                               self._osso = osso.Context(constants.__app_name__, constants.__version__, False)
-                               device = osso.DeviceState(self._osso)
-                               device.set_device_state_callback(self._on_device_state_change, 0)
-                       else:
-                               logging.warning("No device state support")
-
-                       try:
-                               import alarm_handler
-                               self._alarmHandler = alarm_handler.AlarmHandler()
-                       except (ImportError, OSError):
-                               alarm_handler = None
-                       except Exception:
-                               with gtk_toolbox.gtk_lock():
-                                       self._errorDisplay.push_exception()
-                               alarm_handler = None
-                               logging.warning("No notification support")
-                       if hildonize.IS_HILDON_SUPPORTED:
-                               try:
-                                       import led_handler
-                                       self._ledHandler = led_handler.LedHandler()
-                               except Exception, e:
-                                       logging.exception('LED Handling failed: "%s"' % str(e))
-                                       self._ledHandler = None
-                       else:
-                               self._ledHandler = None
-
-                       try:
-                               import conic
-                       except (ImportError, OSError):
-                               conic = None
-                       self._connection = None
-                       if conic is not None:
-                               self._connection = conic.Connection()
-                               self._connection.connect("connection-event", self._on_connection_change, constants.__app_magic__)
-                               self._connection.request_connection(conic.CONNECT_FLAG_NONE)
-                       else:
-                               logging.warning("No connection support")
-               except Exception, e:
-                       with gtk_toolbox.gtk_lock():
-                               self._errorDisplay.push_exception()
-
-               # Setup costly backends
-               try:
-                       import gv_backend
-                       import file_backend
-                       import gv_views
-
-                       try:
-                               os.makedirs(constants._data_path_)
-                       except OSError, e:
-                               if e.errno != 17:
-                                       raise
-                       gvCookiePath = os.path.join(constants._data_path_, "gv_cookies.txt")
-
-                       self._phoneBackends.update({
-                               self.GV_BACKEND: gv_backend.GVDialer(gvCookiePath),
-                       })
-                       with gtk_toolbox.gtk_lock():
-                               unifiedDialpad = gv_views.Dialpad(self._widgetTree, self._errorDisplay)
-                               self._dialpads.update({
-                                       self.GV_BACKEND: unifiedDialpad,
-                               })
-                               self._accountViews.update({
-                                       self.GV_BACKEND: gv_views.AccountInfo(
-                                               self._widgetTree, self._phoneBackends[self.GV_BACKEND], self._alarmHandler, self._errorDisplay
-                                       ),
-                               })
-                               self._accountViews[self.GV_BACKEND].save_everything = self._save_settings
-                               self._recentViews.update({
-                                       self.GV_BACKEND: gv_views.RecentCallsView(
-                                               self._widgetTree, self._phoneBackends[self.GV_BACKEND], self._errorDisplay
-                                       ),
-                               })
-                               self._messagesViews.update({
-                                       self.GV_BACKEND: gv_views.MessagesView(
-                                               self._widgetTree, self._phoneBackends[self.GV_BACKEND], self._errorDisplay
-                                       ),
-                               })
-                               self._contactsViews.update({
-                                       self.GV_BACKEND: gv_views.ContactsView(
-                                               self._widgetTree, self._phoneBackends[self.GV_BACKEND], self._errorDisplay
-                                       ),
-                               })
-
-                       fsContactsPath = os.path.join(constants._data_path_, "contacts")
-                       fileBackend = file_backend.FilesystemAddressBookFactory(fsContactsPath)
-
-                       self._dialpads[self.GV_BACKEND].number_selected = self._select_action
-                       self._recentViews[self.GV_BACKEND].number_selected = self._select_action
-                       self._messagesViews[self.GV_BACKEND].number_selected = self._select_action
-                       self._contactsViews[self.GV_BACKEND].number_selected = self._select_action
-
-                       addressBooks = [
-                               self._phoneBackends[self.GV_BACKEND],
-                               fileBackend,
-                       ]
-                       mergedBook = gv_views.MergedAddressBook(addressBooks, gv_views.MergedAddressBook.advanced_lastname_sorter)
-                       self._contactsViews[self.GV_BACKEND].append(mergedBook)
-                       self._contactsViews[self.GV_BACKEND].extend(addressBooks)
-                       self._contactsViews[self.GV_BACKEND].open_addressbook(*self._contactsViews[self.GV_BACKEND].get_addressbooks().next()[0][0:2])
-
-                       callbackMapping = {
-                               "on_paste": self._on_paste,
-                               "on_refresh": self._on_menu_refresh,
-                               "on_clearcookies_clicked": self._on_clearcookies_clicked,
-                               "on_about_activate": self._on_about_activate,
-                       }
-                       if hildonize.GTK_MENU_USED:
-                               self._widgetTree.signal_autoconnect(callbackMapping)
-                       self._notebook.connect("switch-page", self._on_notebook_switch_page)
-                       self._widgetTree.get_widget("clearcookies").connect("clicked", self._on_clearcookies_clicked)
-
-                       with gtk_toolbox.gtk_lock():
-                               self._originalCurrentLabels = [
-                                       self._notebook.get_tab_label(self._notebook.get_nth_page(pageIndex)).get_text()
-                                       for pageIndex in xrange(self._notebook.get_n_pages())
-                               ]
-                               self._notebookTapHandler = gtk_toolbox.TapOrHold(self._notebook)
-                               self._notebookTapHandler.enable()
-                       self._notebookTapHandler.on_tap = self._reset_tab_refresh
-                       self._notebookTapHandler.on_hold = self._on_tab_refresh
-                       self._notebookTapHandler.on_holding = self._set_tab_refresh
-                       self._notebookTapHandler.on_cancel = self._reset_tab_refresh
-
-                       self._initDone = True
-
-                       config = ConfigParser.SafeConfigParser()
-                       config.read(constants._user_settings_)
-                       with gtk_toolbox.gtk_lock():
-                               self.load_settings(config)
-               except Exception, e:
-                       with gtk_toolbox.gtk_lock():
-                               self._errorDisplay.push_exception()
-               finally:
-                       self._spawn_attempt_login(2)
-
-       def _spawn_attempt_login(self, *args):
-               self._loginSink.send(args)
-
-       def _attempt_login(self, numOfAttempts = 10, force = False):
-               """
-               @note This must be run outside of the UI lock
-               """
-               try:
-                       assert 0 <= numOfAttempts, "That was pointless having 0 or less login attempts"
-                       assert self._initDone, "Attempting login before app is fully loaded"
-
-                       serviceId = self.NULL_BACKEND
-                       loggedIn = False
-                       if not force:
-                               try:
-                                       self.refresh_session()
-                                       serviceId = self._defaultBackendId
-                                       loggedIn = True
-                               except Exception, e:
-                                       logging.exception('Session refresh failed with the following message "%s"' % str(e))
-
-                       if not loggedIn:
-                               loggedIn, serviceId = self._login_by_user(numOfAttempts)
-
-                       with gtk_toolbox.gtk_lock():
-                               self._change_loggedin_status(serviceId)
-                               if loggedIn:
-                                       hildonize.show_information_banner(self._window, "Logged In")
-               except Exception, e:
-                       with gtk_toolbox.gtk_lock():
-                               self._errorDisplay.push_exception()
-
-       def refresh_session(self):
-               """
-               @note Thread agnostic
-               """
-               assert self._initDone, "Attempting login before app is fully loaded"
-
-               loggedIn = False
-               if not loggedIn:
-                       loggedIn = self._login_by_cookie()
-               if not loggedIn:
-                       loggedIn = self._login_by_settings()
-
-               if not loggedIn:
-                       raise RuntimeError("Login Failed")
-
-       def _login_by_cookie(self):
-               """
-               @note Thread agnostic
-               """
-               loggedIn = self._phoneBackends[self._defaultBackendId].is_authed()
-               if loggedIn:
-                       logging.info("Logged into %r through cookies" % self._phoneBackends[self._defaultBackendId])
-               return loggedIn
-
-       def _login_by_settings(self):
-               """
-               @note Thread agnostic
-               """
-               username, password = self._credentials
-               loggedIn = self._phoneBackends[self._defaultBackendId].login(username, password)
-               if loggedIn:
-                       self._credentials = username, password
-                       logging.info("Logged into %r through settings" % self._phoneBackends[self._defaultBackendId])
-               return loggedIn
-
-       def _login_by_user(self, numOfAttempts):
-               """
-               @note This must be run outside of the UI lock
-               """
-               loggedIn, (username, password) = False, self._credentials
-               tmpServiceId = self.GV_BACKEND
-               for attemptCount in xrange(numOfAttempts):
-                       if loggedIn:
-                               break
-                       with gtk_toolbox.gtk_lock():
-                               credentials = self._credentialsDialog.request_credentials(
-                                       defaultCredentials = self._credentials
-                               )
-                               if not self._phoneBackends[tmpServiceId].get_callback_number():
-                                       # subtle reminder to the users to configure things
-                                       self._notebook.set_current_page(self.ACCOUNT_TAB)
-                       username, password = credentials
-                       loggedIn = self._phoneBackends[tmpServiceId].login(username, password)
-
-               if loggedIn:
-                       serviceId = tmpServiceId
-                       self._credentials = username, password
-                       logging.info("Logged into %r through user request" % self._phoneBackends[serviceId])
-               else:
-                       serviceId = self.NULL_BACKEND
-                       self._notebook.set_current_page(self.ACCOUNT_TAB)
-
-               return loggedIn, serviceId
-
-       def _select_action(self, action, number, message):
-               self.refresh_session()
-               if action == "select":
-                       self._dialpads[self._selectedBackendId].set_number(number)
-                       self._notebook.set_current_page(self.KEYPAD_TAB)
-               elif action == "dial":
-                       self._on_dial_clicked(number)
-               elif action == "sms":
-                       self._on_sms_clicked(number, message)
-               else:
-                       assert False, "Unknown action: %s" % action
-
-       def _change_loggedin_status(self, newStatus):
-               oldStatus = self._selectedBackendId
-               if oldStatus == newStatus:
-                       return
-
-               self._dialpads[oldStatus].disable()
-               self._accountViews[oldStatus].disable()
-               self._recentViews[oldStatus].disable()
-               self._messagesViews[oldStatus].disable()
-               self._contactsViews[oldStatus].disable()
-
-               self._dialpads[newStatus].enable()
-               self._accountViews[newStatus].enable()
-               self._recentViews[newStatus].enable()
-               self._messagesViews[newStatus].enable()
-               self._contactsViews[newStatus].enable()
-
-               if self._phoneBackends[self._selectedBackendId].get_callback_number() is None:
-                       self._phoneBackends[self._selectedBackendId].set_sane_callback()
-
-               self._selectedBackendId = newStatus
-
-               self._accountViews[self._selectedBackendId].update()
-               self._refresh_active_tab()
-
-       def load_settings(self, config):
-               """
-               @note UI Thread
-               """
-               try:
-                       self._defaultBackendId = config.getint(constants.__pretty_app_name__, "active")
-                       blobs = (
-                               config.get(constants.__pretty_app_name__, "bin_blob_%i" % i)
-                               for i in xrange(len(self._credentials))
-                       )
-                       creds = (
-                               base64.b64decode(blob)
-                               for blob in blobs
-                       )
-                       self._credentials = tuple(creds)
-
-                       if self._alarmHandler is not None:
-                               self._alarmHandler.load_settings(config, "alarm")
-               except ConfigParser.NoOptionError, e:
-                       logging.exception(
-                               "Settings file %s is missing section %s" % (
-                                       constants._user_settings_,
-                                       e.section,
-                               ),
-                       )
-               except ConfigParser.NoSectionError, e:
-                       logging.exception(
-                               "Settings file %s is missing section %s" % (
-                                       constants._user_settings_,
-                                       e.section,
-                               ),
-                       )
-
-               for backendId, view in itertools.chain(
-                       self._dialpads.iteritems(),
-                       self._accountViews.iteritems(),
-                       self._messagesViews.iteritems(),
-                       self._recentViews.iteritems(),
-                       self._contactsViews.iteritems(),
-               ):
-                       sectionName = "%s - %s" % (backendId, view.name())
-                       try:
-                               view.load_settings(config, sectionName)
-                       except ConfigParser.NoOptionError, e:
-                               logging.exception(
-                                       "Settings file %s is missing section %s" % (
-                                               constants._user_settings_,
-                                               e.section,
-                                       ),
-                               )
-                       except ConfigParser.NoSectionError, e:
-                               logging.exception(
-                                       "Settings file %s is missing section %s" % (
-                                               constants._user_settings_,
-                                               e.section,
-                                       ),
-                               )
-
-               try:
-                       previousOrientation = config.getint(constants.__pretty_app_name__, "orientation")
-                       if previousOrientation == gtk.ORIENTATION_HORIZONTAL:
-                               hildonize.window_to_landscape(self._window)
-                       elif previousOrientation == gtk.ORIENTATION_VERTICAL:
-                               hildonize.window_to_portrait(self._window)
-               except ConfigParser.NoOptionError, e:
-                       logging.exception(
-                               "Settings file %s is missing section %s" % (
-                                       constants._user_settings_,
-                                       e.section,
-                               ),
-                       )
-               except ConfigParser.NoSectionError, e:
-                       logging.exception(
-                               "Settings file %s is missing section %s" % (
-                                       constants._user_settings_,
-                                       e.section,
-                               ),
-                       )
-
-       def save_settings(self, config):
-               """
-               @note Thread Agnostic
-               """
-               config.add_section(constants.__pretty_app_name__)
-               config.set(constants.__pretty_app_name__, "active", str(self._selectedBackendId))
-               config.set(constants.__pretty_app_name__, "orientation", str(int(gtk_toolbox.get_screen_orientation())))
-               for i, value in enumerate(self._credentials):
-                       blob = base64.b64encode(value)
-                       config.set(constants.__pretty_app_name__, "bin_blob_%i" % i, blob)
-               config.add_section("alarm")
-               if self._alarmHandler is not None:
-                       self._alarmHandler.save_settings(config, "alarm")
-
-               for backendId, view in itertools.chain(
-                       self._dialpads.iteritems(),
-                       self._accountViews.iteritems(),
-                       self._messagesViews.iteritems(),
-                       self._recentViews.iteritems(),
-                       self._contactsViews.iteritems(),
-               ):
-                       sectionName = "%s - %s" % (backendId, view.name())
-                       config.add_section(sectionName)
-                       view.save_settings(config, sectionName)
-
-       def _save_settings(self):
-               """
-               @note Thread Agnostic
-               """
-               config = ConfigParser.SafeConfigParser()
-               self.save_settings(config)
-               with open(constants._user_settings_, "wb") as configFile:
-                       config.write(configFile)
-
-       def _refresh_active_tab(self):
-               pageIndex = self._notebook.get_current_page()
-               if pageIndex == self.CONTACTS_TAB:
-                       self._contactsViews[self._selectedBackendId].update(force=True)
-               elif pageIndex == self.RECENT_TAB:
-                       self._recentViews[self._selectedBackendId].update(force=True)
-               elif pageIndex == self.MESSAGES_TAB:
-                       self._messagesViews[self._selectedBackendId].update(force=True)
-
-               if pageIndex in (self.RECENT_TAB, self.MESSAGES_TAB):
-                       if self._ledHandler is not None:
-                               self._ledHandler.off()
-
-       def _on_close(self, *args, **kwds):
-               try:
-                       if self._osso is not None:
-                               self._osso.close()
-
-                       if self._initDone:
-                               self._save_settings()
-               finally:
-                       gtk.main_quit()
-
-       def _on_device_state_change(self, shutdown, save_unsaved_data, memory_low, system_inactivity, message, userData):
-               """
-               For shutdown or save_unsaved_data, our only state is cookies and I think the cookie manager handles that for us.
-               For system_inactivity, we have no background tasks to pause
-
-               @note Hildon specific
-               """
-               try:
-                       if memory_low:
-                               for backendId in self.BACKENDS:
-                                       self._phoneBackends[backendId].clear_caches()
-                               self._contactsViews[self._selectedBackendId].clear_caches()
-                               gc.collect()
-
-                       if save_unsaved_data or shutdown:
-                               self._save_settings()
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_connection_change(self, connection, event, magicIdentifier):
-               """
-               @note Hildon specific
-               """
-               try:
-                       import conic
-
-                       status = event.get_status()
-                       error = event.get_error()
-                       iap_id = event.get_iap_id()
-                       bearer = event.get_bearer_type()
-
-                       if status == conic.STATUS_CONNECTED:
-                               if self._initDone:
-                                       self._spawn_attempt_login(2)
-                       elif status == conic.STATUS_DISCONNECTED:
-                               if self._initDone:
-                                       self._defaultBackendId = self._selectedBackendId
-                                       self._change_loggedin_status(self.NULL_BACKEND)
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_window_state_change(self, widget, event, *args):
-               """
-               @note Hildon specific
-               """
-               try:
-                       if event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN:
-                               self._isFullScreen = True
-                       else:
-                               self._isFullScreen = False
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_key_press(self, widget, event, *args):
-               """
-               @note Hildon specific
-               """
-               try:
-                       if (
-                               event.keyval == gtk.keysyms.F6 or
-                               event.keyval == gtk.keysyms.Return and event.get_state() & gtk.gdk.CONTROL_MASK
-                       ):
-                               if self._isFullScreen:
-                                       self._window.unfullscreen()
-                               else:
-                                       self._window.fullscreen()
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_clearcookies_clicked(self, *args):
-               try:
-                       self._phoneBackends[self._selectedBackendId].logout()
-                       self._accountViews[self._selectedBackendId].clear()
-                       self._recentViews[self._selectedBackendId].clear()
-                       self._messagesViews[self._selectedBackendId].clear()
-                       self._contactsViews[self._selectedBackendId].clear()
-                       self._change_loggedin_status(self.NULL_BACKEND)
-
-                       self._spawn_attempt_login(2, True)
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_notebook_switch_page(self, notebook, page, pageIndex):
-               try:
-                       self._reset_tab_refresh()
-
-                       didRecentUpdate = False
-                       didMessagesUpdate = False
-
-                       if pageIndex == self.RECENT_TAB:
-                               didRecentUpdate = self._recentViews[self._selectedBackendId].update()
-                       elif pageIndex == self.MESSAGES_TAB:
-                               didMessagesUpdate = self._messagesViews[self._selectedBackendId].update()
-                       elif pageIndex == self.CONTACTS_TAB:
-                               self._contactsViews[self._selectedBackendId].update()
-                       elif pageIndex == self.ACCOUNT_TAB:
-                               self._accountViews[self._selectedBackendId].update()
-
-                       if didRecentUpdate or didMessagesUpdate:
-                               if self._ledHandler is not None:
-                                       self._ledHandler.off()
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _set_tab_refresh(self, *args):
-               try:
-                       pageIndex = self._notebook.get_current_page()
-                       child = self._notebook.get_nth_page(pageIndex)
-                       self._notebook.get_tab_label(child).set_text("Refresh?")
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-               return False
-
-       def _reset_tab_refresh(self, *args):
-               try:
-                       pageIndex = self._notebook.get_current_page()
-                       child = self._notebook.get_nth_page(pageIndex)
-                       self._notebook.get_tab_label(child).set_text(self._originalCurrentLabels[pageIndex])
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-               return False
-
-       def _on_tab_refresh(self, *args):
-               try:
-                       self._refresh_active_tab()
-                       self._reset_tab_refresh()
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-               return False
-
-       def _on_sms_clicked(self, number, message):
-               try:
-                       assert number, "No number specified"
-                       assert message, "Empty message"
-                       try:
-                               loggedIn = self._phoneBackends[self._selectedBackendId].is_authed()
-                       except Exception, e:
-                               loggedIn = False
-                               self._errorDisplay.push_exception()
-                               return
-
-                       if not loggedIn:
-                               self._errorDisplay.push_message(
-                                       "Backend link with GoogleVoice is not working, please try again"
-                               )
-                               return
-
-                       dialed = False
-                       try:
-                               self._phoneBackends[self._selectedBackendId].send_sms(number, message)
-                               hildonize.show_information_banner(self._window, "Sending to %s" % number)
-                               dialed = True
-                       except Exception, e:
-                               self._errorDisplay.push_exception()
-
-                       if dialed:
-                               self._dialpads[self._selectedBackendId].clear()
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_dial_clicked(self, number):
-               try:
-                       assert number, "No number to call"
-                       try:
-                               loggedIn = self._phoneBackends[self._selectedBackendId].is_authed()
-                       except Exception, e:
-                               loggedIn = False
-                               self._errorDisplay.push_exception()
-                               return
-
-                       if not loggedIn:
-                               self._errorDisplay.push_message(
-                                       "Backend link with GoogleVoice is not working, please try again"
-                               )
-                               return
-
-                       dialed = False
-                       try:
-                               assert self._phoneBackends[self._selectedBackendId].get_callback_number() != "", "No callback number specified"
-                               self._phoneBackends[self._selectedBackendId].dial(number)
-                               hildonize.show_information_banner(self._window, "Calling %s" % number)
-                               dialed = True
-                       except Exception, e:
-                               self._errorDisplay.push_exception()
-
-                       if dialed:
-                               self._dialpads[self._selectedBackendId].clear()
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_menu_refresh(self, *args):
-               try:
-                       self._refresh_active_tab()
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_paste(self, *args):
-               try:
-                       contents = self._clipboard.wait_for_text()
-                       if contents is not None:
-                               self._dialpads[self._selectedBackendId].set_number(contents)
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_about_activate(self, *args):
-               try:
-                       dlg = gtk.AboutDialog()
-                       dlg.set_name(constants.__pretty_app_name__)
-                       dlg.set_version("%s-%d" % (constants.__version__, constants.__build__))
-                       dlg.set_copyright("Copyright 2008 - LGPL")
-                       dlg.set_comments("Dialcentral is a touch screen enhanced interface to your GoogleVoice account.  This application is not affiliated with Google in any way")
-                       dlg.set_website("http://gc-dialer.garage.maemo.org/")
-                       dlg.set_authors(["<z2n@merctech.com>", "Eric Warnke <ericew@gmail.com>", "Ed Page <edpage@byu.net>"])
-                       dlg.run()
-                       dlg.destroy()
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-
-def run_doctest():
-       import doctest
-
-       failureCount, testCount = doctest.testmod()
-       if not failureCount:
-               print "Tests Successful"
-               sys.exit(0)
-       else:
-               sys.exit(1)
-
-
-def run_dialpad():
-       _lock_file = os.path.join(constants._data_path_, ".lock")
-       #with gtk_toolbox.flock(_lock_file, 0):
-       gtk.gdk.threads_init()
-
-       if hildonize.IS_HILDON_SUPPORTED:
-               gtk.set_application_name(constants.__pretty_app_name__)
-       handle = Dialcentral()
-       gtk.main()
-
-
-class DummyOptions(object):
-
-       def __init__(self):
-               self.test = False
-
-
-if __name__ == "__main__":
-       logging.basicConfig(level=logging.DEBUG)
-       try:
-               if len(sys.argv) > 1:
-                       try:
-                               import optparse
-                       except ImportError:
-                               optparse = None
-
-                       if optparse is not None:
-                               parser = optparse.OptionParser()
-                               parser.add_option("-t", "--test", action="store_true", dest="test", help="Run tests")
-                               (commandOptions, commandArgs) = parser.parse_args()
-               else:
-                       commandOptions = DummyOptions()
-                       commandArgs = []
-
-               if commandOptions.test:
-                       run_doctest()
-               else:
-                       run_dialpad()
-       finally:
-               logging.shutdown()
diff --git a/src/dialcentral.glade b/src/dialcentral.glade
deleted file mode 100644 (file)
index ba8d0ff..0000000
+++ /dev/null
@@ -1,1292 +0,0 @@
-<?xml version="1.0"?>
-<glade-interface>
-  <!-- interface-requires gtk+ 2.16 -->
-  <!-- interface-naming-policy toplevel-contextual -->
-  <widget class="GtkWindow" id="mainWindow">
-    <property name="title" translatable="yes">Dialer</property>
-    <property name="default_width">800</property>
-    <property name="default_height">480</property>
-    <child>
-      <widget class="GtkVBox" id="mainLayout">
-        <property name="visible">True</property>
-        <child>
-          <widget class="GtkMenuBar" id="dialpad_menubar">
-            <property name="visible">True</property>
-            <child>
-              <widget class="GtkMenuItem" id="login_menu_item">
-                <property name="visible">True</property>
-                <property name="label">_Login</property>
-                <property name="use_underline">True</property>
-                <signal name="activate" handler="on_clearcookies_clicked"/>
-              </widget>
-            </child>
-            <child>
-              <widget class="GtkMenuItem" id="paste_menu_item">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">Paste</property>
-                <property name="use_underline">True</property>
-                <signal name="activate" handler="on_paste"/>
-              </widget>
-            </child>
-            <child>
-              <widget class="GtkMenuItem" id="refreshMenuItem">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">Refresh</property>
-                <property name="use_underline">True</property>
-                <signal name="activate" handler="on_refresh"/>
-              </widget>
-            </child>
-            <child>
-              <widget class="GtkMenuItem" id="about">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">_About</property>
-                <property name="use_underline">True</property>
-                <signal name="activate" handler="on_about_activate"/>
-              </widget>
-            </child>
-          </widget>
-          <packing>
-            <property name="expand">False</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <widget class="GtkEventBox" id="errorEventBox">
-            <property name="visible">True</property>
-            <child>
-              <widget class="GtkHBox" id="errorBox">
-                <property name="visible">True</property>
-                <child>
-                  <widget class="GtkImage" id="errorImage">
-                    <property name="visible">True</property>
-                    <property name="stock">gtk-dialog-error</property>
-                  </widget>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkLabel" id="errorDescription">
-                    <property name="visible">True</property>
-                    <property name="use_markup">True</property>
-                    <property name="ellipsize">end</property>
-                    <property name="single_line_mode">True</property>
-                  </widget>
-                  <packing>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkImage" id="errorClose">
-                    <property name="visible">True</property>
-                    <property name="stock">gtk-close</property>
-                  </widget>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">2</property>
-                  </packing>
-                </child>
-              </widget>
-            </child>
-          </widget>
-          <packing>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child>
-          <widget class="GtkNotebook" id="notebook">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
-            <property name="tab_pos">left</property>
-            <property name="show_border">False</property>
-            <property name="homogeneous">True</property>
-            <child>
-              <widget class="GtkVBox" id="keypad_vbox">
-                <property name="visible">True</property>
-                <child>
-                  <widget class="GtkHBox" id="hbox3">
-                    <property name="visible">True</property>
-                    <child>
-                      <widget class="GtkLabel" id="numberdisplay">
-                        <property name="height_request">50</property>
-                        <property name="visible">True</property>
-                        <property name="label" translatable="yes">&lt;span size="35000" weight="bold"&gt;&lt;/span&gt;</property>
-                        <property name="use_markup">True</property>
-                        <property name="justify">center</property>
-                      </widget>
-                      <packing>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <widget class="GtkButton" id="back">
-                        <property name="label" translatable="yes">gtk-go-back</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">True</property>
-                        <property name="use_stock">True</property>
-                        <property name="focus_on_click">False</property>
-                        <accelerator key="BackSpace" signal="clicked"/>
-                      </widget>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                  </widget>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkTable" id="keypadview">
-                    <property name="visible">True</property>
-                    <property name="n_rows">4</property>
-                    <property name="n_columns">3</property>
-                    <property name="homogeneous">True</property>
-                    <child>
-                      <widget class="GtkButton" id="digit1">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="receives_default">False</property>
-                        <property name="focus_on_click">False</property>
-                        <signal name="clicked" handler="on_digit_clicked"/>
-                        <accelerator key="1" signal="clicked"/>
-                        <child>
-                          <widget class="GtkLabel" id="label12">
-                            <property name="visible">True</property>
-                            <property name="label" translatable="yes">&lt;span size="33000" weight="bold"&gt;1&lt;/span&gt;
-&lt;span size="9000"&gt;  &lt;/span&gt;</property>
-                            <property name="use_markup">True</property>
-                          </widget>
-                        </child>
-                      </widget>
-                    </child>
-                    <child>
-                      <widget class="GtkButton" id="digit2">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="receives_default">False</property>
-                        <property name="focus_on_click">False</property>
-                        <signal name="clicked" handler="on_digit_clicked"/>
-                        <accelerator key="2" signal="clicked"/>
-                        <accelerator key="a" signal="clicked"/>
-                        <accelerator key="b" signal="clicked"/>
-                        <accelerator key="c" signal="clicked"/>
-                        <child>
-                          <widget class="GtkLabel" id="label10">
-                            <property name="visible">True</property>
-                            <property name="label" translatable="yes">&lt;span size="30000" weight="bold"&gt;2&lt;/span&gt;
-&lt;span size="12000"&gt;ABC&lt;/span&gt;</property>
-                            <property name="use_markup">True</property>
-                            <property name="justify">center</property>
-                          </widget>
-                        </child>
-                      </widget>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <widget class="GtkButton" id="digit3">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="receives_default">False</property>
-                        <property name="focus_on_click">False</property>
-                        <signal name="clicked" handler="on_digit_clicked"/>
-                        <accelerator key="3" signal="clicked"/>
-                        <accelerator key="d" signal="clicked"/>
-                        <accelerator key="e" signal="clicked"/>
-                        <accelerator key="f" signal="clicked"/>
-                        <child>
-                          <widget class="GtkLabel" id="label11">
-                            <property name="visible">True</property>
-                            <property name="label" translatable="yes">&lt;span size="30000" weight="bold" stretch="ultraexpanded"&gt;3&lt;/span&gt;
-&lt;span size="12000"&gt;DEF&lt;/span&gt;</property>
-                            <property name="use_markup">True</property>
-                            <property name="justify">center</property>
-                          </widget>
-                        </child>
-                      </widget>
-                      <packing>
-                        <property name="left_attach">2</property>
-                        <property name="right_attach">3</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <widget class="GtkButton" id="digit4">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="receives_default">False</property>
-                        <property name="focus_on_click">False</property>
-                        <signal name="clicked" handler="on_digit_clicked"/>
-                        <accelerator key="4" signal="clicked"/>
-                        <accelerator key="g" signal="clicked"/>
-                        <accelerator key="h" signal="clicked"/>
-                        <accelerator key="i" signal="clicked"/>
-                        <child>
-                          <widget class="GtkLabel" id="label13">
-                            <property name="visible">True</property>
-                            <property name="label" translatable="yes">&lt;span size="30000" weight="bold"&gt;4&lt;/span&gt;
-&lt;span size="12000"&gt;GHI&lt;/span&gt;</property>
-                            <property name="use_markup">True</property>
-                            <property name="justify">center</property>
-                          </widget>
-                        </child>
-                      </widget>
-                      <packing>
-                        <property name="top_attach">1</property>
-                        <property name="bottom_attach">2</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <widget class="GtkButton" id="digit5">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="receives_default">False</property>
-                        <property name="focus_on_click">False</property>
-                        <signal name="clicked" handler="on_digit_clicked"/>
-                        <accelerator key="5" signal="clicked"/>
-                        <accelerator key="j" signal="clicked"/>
-                        <accelerator key="k" signal="clicked"/>
-                        <accelerator key="l" signal="clicked"/>
-                        <child>
-                          <widget class="GtkLabel" id="label14">
-                            <property name="visible">True</property>
-                            <property name="label" translatable="yes">&lt;span size="30000" weight="bold"&gt;5&lt;/span&gt;
-&lt;span size="12000"&gt;JKL&lt;/span&gt;</property>
-                            <property name="use_markup">True</property>
-                            <property name="justify">center</property>
-                          </widget>
-                        </child>
-                      </widget>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
-                        <property name="top_attach">1</property>
-                        <property name="bottom_attach">2</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <widget class="GtkButton" id="digit6">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="receives_default">False</property>
-                        <property name="focus_on_click">False</property>
-                        <signal name="clicked" handler="on_digit_clicked"/>
-                        <accelerator key="6" signal="clicked"/>
-                        <accelerator key="m" signal="clicked"/>
-                        <accelerator key="n" signal="clicked"/>
-                        <accelerator key="o" signal="clicked"/>
-                        <child>
-                          <widget class="GtkLabel" id="label15">
-                            <property name="visible">True</property>
-                            <property name="label" translatable="yes">&lt;span size="30000" weight="bold"&gt;6&lt;/span&gt;
-&lt;span size="12000"&gt;MNO&lt;/span&gt;</property>
-                            <property name="use_markup">True</property>
-                            <property name="justify">center</property>
-                          </widget>
-                        </child>
-                      </widget>
-                      <packing>
-                        <property name="left_attach">2</property>
-                        <property name="right_attach">3</property>
-                        <property name="top_attach">1</property>
-                        <property name="bottom_attach">2</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <widget class="GtkButton" id="digit7">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="receives_default">False</property>
-                        <property name="focus_on_click">False</property>
-                        <signal name="clicked" handler="on_digit_clicked"/>
-                        <accelerator key="7" signal="clicked"/>
-                        <accelerator key="p" signal="clicked"/>
-                        <accelerator key="q" signal="clicked"/>
-                        <accelerator key="r" signal="clicked"/>
-                        <accelerator key="s" signal="clicked"/>
-                        <child>
-                          <widget class="GtkLabel" id="label16">
-                            <property name="visible">True</property>
-                            <property name="label" translatable="yes">&lt;span size="30000" weight="bold"&gt;7&lt;/span&gt;
-&lt;span size="12000"&gt;PQRS&lt;/span&gt;</property>
-                            <property name="use_markup">True</property>
-                            <property name="justify">center</property>
-                          </widget>
-                        </child>
-                      </widget>
-                      <packing>
-                        <property name="top_attach">2</property>
-                        <property name="bottom_attach">3</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <widget class="GtkButton" id="digit8">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="receives_default">False</property>
-                        <property name="focus_on_click">False</property>
-                        <signal name="clicked" handler="on_digit_clicked"/>
-                        <accelerator key="8" signal="clicked"/>
-                        <accelerator key="t" signal="clicked"/>
-                        <accelerator key="u" signal="clicked"/>
-                        <accelerator key="v" signal="clicked"/>
-                        <child>
-                          <widget class="GtkLabel" id="label17">
-                            <property name="visible">True</property>
-                            <property name="label" translatable="yes">&lt;span size="30000" weight="bold"&gt;8&lt;/span&gt;
-&lt;span size="12000"&gt;TUV&lt;/span&gt;</property>
-                            <property name="use_markup">True</property>
-                            <property name="justify">center</property>
-                          </widget>
-                        </child>
-                      </widget>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
-                        <property name="top_attach">2</property>
-                        <property name="bottom_attach">3</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <widget class="GtkButton" id="digit9">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="receives_default">False</property>
-                        <property name="focus_on_click">False</property>
-                        <signal name="clicked" handler="on_digit_clicked"/>
-                        <accelerator key="9" signal="clicked"/>
-                        <accelerator key="w" signal="clicked"/>
-                        <accelerator key="x" signal="clicked"/>
-                        <accelerator key="y" signal="clicked"/>
-                        <accelerator key="z" signal="clicked"/>
-                        <child>
-                          <widget class="GtkLabel" id="label18">
-                            <property name="visible">True</property>
-                            <property name="label" translatable="yes">&lt;span size="30000" weight="bold"&gt;9&lt;/span&gt;
-&lt;span size="12000"&gt;WXYZ&lt;/span&gt;</property>
-                            <property name="use_markup">True</property>
-                            <property name="justify">center</property>
-                          </widget>
-                        </child>
-                      </widget>
-                      <packing>
-                        <property name="left_attach">2</property>
-                        <property name="right_attach">3</property>
-                        <property name="top_attach">2</property>
-                        <property name="bottom_attach">3</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <widget class="GtkButton" id="digit0">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="receives_default">False</property>
-                        <property name="focus_on_click">False</property>
-                        <signal name="clicked" handler="on_digit_clicked"/>
-                        <accelerator key="0" signal="clicked"/>
-                        <child>
-                          <widget class="GtkLabel" id="label19">
-                            <property name="visible">True</property>
-                            <property name="label" translatable="yes">&lt;span size="33000" weight="bold"&gt;0&lt;/span&gt;
-&lt;span size="9000"&gt;&lt;/span&gt;</property>
-                            <property name="use_markup">True</property>
-                            <property name="justify">center</property>
-                          </widget>
-                        </child>
-                      </widget>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="right_attach">2</property>
-                        <property name="top_attach">3</property>
-                        <property name="bottom_attach">4</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <widget class="GtkButton" id="dial">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="receives_default">False</property>
-                        <accelerator key="Return" signal="clicked"/>
-                        <child>
-                          <widget class="GtkHBox" id="hbox1">
-                            <property name="visible">True</property>
-                            <child>
-                              <widget class="GtkImage" id="image1">
-                                <property name="visible">True</property>
-                                <property name="xalign">1</property>
-                                <property name="stock">gtk-yes</property>
-                              </widget>
-                              <packing>
-                                <property name="position">0</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <widget class="GtkLabel" id="label8">
-                                <property name="visible">True</property>
-                                <property name="xalign">0</property>
-                                <property name="xpad">5</property>
-                                <property name="label" translatable="yes">&lt;span size="17000" weight="bold"&gt;Dial&lt;/span&gt;</property>
-                                <property name="use_markup">True</property>
-                              </widget>
-                              <packing>
-                                <property name="position">1</property>
-                              </packing>
-                            </child>
-                          </widget>
-                        </child>
-                      </widget>
-                      <packing>
-                        <property name="left_attach">2</property>
-                        <property name="right_attach">3</property>
-                        <property name="top_attach">3</property>
-                        <property name="bottom_attach">4</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <widget class="GtkButton" id="sms">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">True</property>
-                        <accelerator key="Return" signal="clicked"/>
-                        <child>
-                          <widget class="GtkHBox" id="hbox2">
-                            <property name="visible">True</property>
-                            <child>
-                              <widget class="GtkImage" id="image2">
-                                <property name="visible">True</property>
-                                <property name="xalign">1</property>
-                                <property name="stock">gtk-file</property>
-                              </widget>
-                              <packing>
-                                <property name="position">0</property>
-                              </packing>
-                            </child>
-                            <child>
-                              <widget class="GtkLabel" id="label1">
-                                <property name="visible">True</property>
-                                <property name="xalign">0</property>
-                                <property name="xpad">5</property>
-                                <property name="label" translatable="yes">&lt;span size="17000" weight="bold"&gt;SMS&lt;/span&gt;</property>
-                                <property name="use_markup">True</property>
-                              </widget>
-                              <packing>
-                                <property name="position">1</property>
-                              </packing>
-                            </child>
-                          </widget>
-                        </child>
-                      </widget>
-                      <packing>
-                        <property name="top_attach">3</property>
-                        <property name="bottom_attach">4</property>
-                      </packing>
-                    </child>
-                  </widget>
-                  <packing>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-              </widget>
-              <packing>
-                <property name="tab_expand">True</property>
-                <property name="tab_fill">False</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkLabel" id="keypad">
-                <property name="height_request">30</property>
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">Keypad</property>
-              </widget>
-              <packing>
-                <property name="tab_expand">True</property>
-                <property name="tab_fill">False</property>
-                <property name="type">tab</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkVBox" id="vbox2">
-                <property name="visible">True</property>
-                <property name="orientation">vertical</property>
-                <child>
-                  <widget class="GtkScrolledWindow" id="recent_scrolledwindow">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="hscrollbar_policy">never</property>
-                    <child>
-                      <widget class="GtkTreeView" id="recentview">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="rules_hint">True</property>
-                        <property name="enable_grid_lines">horizontal</property>
-                        <property name="enable_tree_lines">True</property>
-                      </widget>
-                    </child>
-                  </widget>
-                  <packing>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-              </widget>
-              <packing>
-                <property name="position">1</property>
-                <property name="tab_expand">True</property>
-                <property name="tab_fill">False</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkLabel" id="recent">
-                <property name="height_request">30</property>
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">Recent</property>
-              </widget>
-              <packing>
-                <property name="position">1</property>
-                <property name="tab_expand">True</property>
-                <property name="tab_fill">False</property>
-                <property name="type">tab</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkVBox" id="vbox3">
-                <property name="visible">True</property>
-                <property name="orientation">vertical</property>
-                <child>
-                  <widget class="GtkScrolledWindow" id="message_scrolledwindow">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="hscrollbar_policy">never</property>
-                    <property name="vscrollbar_policy">automatic</property>
-                    <child>
-                      <widget class="GtkTreeView" id="messages_view">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="rules_hint">True</property>
-                        <property name="enable_grid_lines">horizontal</property>
-                        <property name="enable_tree_lines">True</property>
-                      </widget>
-                    </child>
-                  </widget>
-                  <packing>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-              </widget>
-              <packing>
-                <property name="position">2</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkLabel" id="messages">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">Messages</property>
-              </widget>
-              <packing>
-                <property name="position">2</property>
-                <property name="tab_expand">True</property>
-                <property name="tab_fill">False</property>
-                <property name="type">tab</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkVBox" id="vbox5">
-                <property name="visible">True</property>
-                <property name="orientation">vertical</property>
-                <child>
-                  <widget class="GtkButton" id="addressbookSelectButton">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                  </widget>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkScrolledWindow" id="contacts_scrolledwindow">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="hscrollbar_policy">never</property>
-                    <child>
-                      <widget class="GtkTreeView" id="contactsview">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="headers_visible">False</property>
-                        <property name="rules_hint">True</property>
-                        <property name="fixed_height_mode">True</property>
-                        <property name="enable_grid_lines">horizontal</property>
-                        <property name="enable_tree_lines">True</property>
-                      </widget>
-                    </child>
-                  </widget>
-                  <packing>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-              </widget>
-              <packing>
-                <property name="position">3</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkLabel" id="contacts">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">Contacts</property>
-              </widget>
-              <packing>
-                <property name="position">3</property>
-                <property name="tab_expand">True</property>
-                <property name="tab_fill">False</property>
-                <property name="type">tab</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkTable" id="accountview">
-                <property name="visible">True</property>
-                <property name="border_width">11</property>
-                <property name="n_rows">7</property>
-                <property name="n_columns">2</property>
-                <child>
-                  <widget class="GtkLabel" id="gcnumber_display">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                    <property name="label" translatable="yes">No Number Available</property>
-                    <property name="use_markup">True</property>
-                  </widget>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="right_attach">2</property>
-                    <property name="x_options">GTK_FILL</property>
-                    <property name="y_options"></property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkLabel" id="gcnumber_label">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                    <property name="yalign">0</property>
-                    <property name="ypad">10</property>
-                    <property name="label" translatable="yes">Account Number:</property>
-                  </widget>
-                  <packing>
-                    <property name="y_options"></property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkLabel" id="callback_number_label">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                    <property name="yalign">0</property>
-                    <property name="ypad">10</property>
-                    <property name="label" translatable="yes">Callback Number:</property>
-                  </widget>
-                  <packing>
-                    <property name="top_attach">1</property>
-                    <property name="bottom_attach">2</property>
-                    <property name="y_options"></property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkLabel" id="label4">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                  </widget>
-                  <packing>
-                    <property name="top_attach">2</property>
-                    <property name="bottom_attach">3</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkLabel" id="label5">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                  </widget>
-                  <packing>
-                    <property name="top_attach">4</property>
-                    <property name="bottom_attach">5</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkVBox" id="vbox1">
-                    <property name="visible">True</property>
-                    <property name="orientation">vertical</property>
-                    <child>
-                      <widget class="GtkCheckButton" id="missedCheckbox">
-                        <property name="label" translatable="yes">Missed Calls</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="draw_indicator">True</property>
-                      </widget>
-                      <packing>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <widget class="GtkCheckButton" id="voicemailCheckbox">
-                        <property name="label" translatable="yes">Voicemail</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="draw_indicator">True</property>
-                      </widget>
-                      <packing>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <widget class="GtkCheckButton" id="smsCheckbox">
-                        <property name="label" translatable="yes">SMS</property>
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="receives_default">False</property>
-                        <property name="draw_indicator">True</property>
-                      </widget>
-                      <packing>
-                        <property name="position">2</property>
-                      </packing>
-                    </child>
-                  </widget>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="right_attach">2</property>
-                    <property name="top_attach">4</property>
-                    <property name="bottom_attach">5</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkCheckButton" id="notifyCheckbox">
-                    <property name="label" translatable="yes">Notifications</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="yalign">0</property>
-                    <property name="draw_indicator">True</property>
-                  </widget>
-                  <packing>
-                    <property name="top_attach">3</property>
-                    <property name="bottom_attach">4</property>
-                    <property name="x_options">GTK_FILL</property>
-                    <property name="y_options"></property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkButton" id="clearcookies">
-                    <property name="label" translatable="yes">Login</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                    <property name="focus_on_click">False</property>
-                  </widget>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="right_attach">2</property>
-                    <property name="top_attach">6</property>
-                    <property name="bottom_attach">7</property>
-                    <property name="x_options">GTK_FILL</property>
-                    <property name="y_options"></property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkLabel" id="label3">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                  </widget>
-                  <packing>
-                    <property name="top_attach">5</property>
-                    <property name="bottom_attach">6</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkButton" id="minutesEntryButton">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                  </widget>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="right_attach">2</property>
-                    <property name="top_attach">3</property>
-                    <property name="bottom_attach">4</property>
-                    <property name="y_options">GTK_FILL</property>
-                  </packing>
-                </child>
-                <child>
-                  <widget class="GtkButton" id="callbackSelectButton">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">True</property>
-                  </widget>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="right_attach">2</property>
-                    <property name="top_attach">1</property>
-                    <property name="bottom_attach">2</property>
-                    <property name="y_options"></property>
-                  </packing>
-                </child>
-                <child>
-                  <placeholder/>
-                </child>
-                <child>
-                  <placeholder/>
-                </child>
-                <child>
-                  <placeholder/>
-                </child>
-              </widget>
-              <packing>
-                <property name="position">4</property>
-                <property name="tab_expand">True</property>
-                <property name="tab_fill">False</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkLabel" id="account">
-                <property name="height_request">30</property>
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">Account</property>
-              </widget>
-              <packing>
-                <property name="position">4</property>
-                <property name="tab_fill">False</property>
-                <property name="type">tab</property>
-              </packing>
-            </child>
-          </widget>
-          <packing>
-            <property name="position">2</property>
-          </packing>
-        </child>
-      </widget>
-    </child>
-  </widget>
-  <widget class="GtkDialog" id="loginDialog">
-    <property name="border_width">5</property>
-    <property name="title" translatable="yes">Login</property>
-    <property name="resizable">False</property>
-    <property name="modal">True</property>
-    <property name="window_position">center-on-parent</property>
-    <property name="destroy_with_parent">True</property>
-    <property name="type_hint">dialog</property>
-    <property name="skip_taskbar_hint">True</property>
-    <property name="skip_pager_hint">True</property>
-    <property name="deletable">False</property>
-    <property name="transient_for">mainWindow</property>
-    <property name="has_separator">False</property>
-    <child internal-child="vbox">
-      <widget class="GtkVBox" id="loginLayout">
-        <property name="visible">True</property>
-        <property name="spacing">2</property>
-        <child>
-          <widget class="GtkComboBox" id="serviceCombo">
-            <property name="visible">True</property>
-          </widget>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">False</property>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child>
-          <widget class="GtkTable" id="table1">
-            <property name="visible">True</property>
-            <property name="n_rows">2</property>
-            <property name="n_columns">2</property>
-            <child>
-              <widget class="GtkLabel" id="username_label">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">Username</property>
-              </widget>
-            </child>
-            <child>
-              <widget class="GtkLabel" id="password_label">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">Password</property>
-              </widget>
-              <packing>
-                <property name="top_attach">1</property>
-                <property name="bottom_attach">2</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkEntry" id="usernameentry">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-              </widget>
-              <packing>
-                <property name="left_attach">1</property>
-                <property name="right_attach">2</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkEntry" id="passwordentry">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="visibility">False</property>
-              </widget>
-              <packing>
-                <property name="left_attach">1</property>
-                <property name="right_attach">2</property>
-                <property name="top_attach">1</property>
-                <property name="bottom_attach">2</property>
-              </packing>
-            </child>
-          </widget>
-          <packing>
-            <property name="position">2</property>
-          </packing>
-        </child>
-        <child internal-child="action_area">
-          <widget class="GtkHButtonBox" id="dialog-action_area1">
-            <property name="visible">True</property>
-            <property name="layout_style">end</property>
-            <child>
-              <widget class="GtkButton" id="logins_close_button">
-                <property name="label" translatable="yes">gtk-close</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="use_stock">True</property>
-              </widget>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkButton" id="loginbutton">
-                <property name="label" translatable="yes">gtk-ok</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="receives_default">True</property>
-                <property name="use_stock">True</property>
-              </widget>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </widget>
-          <packing>
-            <property name="expand">False</property>
-            <property name="pack_type">end</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-      </widget>
-    </child>
-  </widget>
-  <widget class="GtkDialog" id="phonetype_dialog">
-    <property name="border_width">5</property>
-    <property name="title" translatable="yes">Select Phone Type</property>
-    <property name="modal">True</property>
-    <property name="window_position">center-on-parent</property>
-    <property name="default_width">500</property>
-    <property name="default_height">300</property>
-    <property name="destroy_with_parent">True</property>
-    <property name="type_hint">dialog</property>
-    <property name="skip_taskbar_hint">True</property>
-    <property name="skip_pager_hint">True</property>
-    <property name="has_separator">False</property>
-    <child internal-child="vbox">
-      <widget class="GtkVBox" id="phoneTypeLayout">
-        <property name="visible">True</property>
-        <property name="spacing">2</property>
-        <child>
-          <widget class="GtkVBox" id="vbox1">
-            <property name="visible">True</property>
-            <property name="orientation">vertical</property>
-            <child>
-              <widget class="GtkScrolledWindow" id="phoneSelectionMessages_scrolledwindow">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="hscrollbar_policy">never</property>
-                <property name="vscrollbar_policy">automatic</property>
-                <child>
-                  <widget class="GtkTreeView" id="phoneSelectionMessages">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                  </widget>
-                </child>
-              </widget>
-              <packing>
-                <property name="position">0</property>
-              </packing>
-            </child>
-          </widget>
-          <packing>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child>
-          <widget class="GtkHSeparator" id="hseparator1">
-            <property name="visible">True</property>
-          </widget>
-          <packing>
-            <property name="expand">False</property>
-            <property name="position">2</property>
-          </packing>
-        </child>
-        <child>
-          <widget class="GtkVBox" id="vbox2">
-            <property name="visible">True</property>
-            <property name="orientation">vertical</property>
-            <child>
-              <widget class="GtkScrolledWindow" id="phonetypes_scrolledwindow">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="hscrollbar_policy">never</property>
-                <property name="vscrollbar_policy">automatic</property>
-                <child>
-                  <widget class="GtkTreeView" id="phonetypes">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="rules_hint">True</property>
-                    <property name="enable_search">False</property>
-                  </widget>
-                </child>
-              </widget>
-              <packing>
-                <property name="expand">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-          </widget>
-          <packing>
-            <property name="expand">False</property>
-            <property name="position">3</property>
-          </packing>
-        </child>
-        <child internal-child="action_area">
-          <widget class="GtkHButtonBox" id="dialog-action_area3">
-            <property name="visible">True</property>
-            <property name="layout_style">end</property>
-            <child>
-              <widget class="GtkButton" id="sms_button">
-                <property name="label" translatable="yes">SMS</property>
-                <property name="response_id">-4</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-              </widget>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkButton" id="dial_button">
-                <property name="label" translatable="yes">Dial</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-              </widget>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkButton" id="select_button">
-                <property name="label" translatable="yes">Select</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-              </widget>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">2</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkButton" id="cancel_button">
-                <property name="label" translatable="yes">gtk-cancel</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="use_stock">True</property>
-              </widget>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">3</property>
-              </packing>
-            </child>
-          </widget>
-          <packing>
-            <property name="expand">False</property>
-            <property name="pack_type">end</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-      </widget>
-    </child>
-  </widget>
-  <widget class="GtkDialog" id="smsDialog">
-    <property name="border_width">5</property>
-    <property name="title" translatable="yes">Send SMS</property>
-    <property name="modal">True</property>
-    <property name="window_position">center-on-parent</property>
-    <property name="default_width">500</property>
-    <property name="default_height">300</property>
-    <property name="destroy_with_parent">True</property>
-    <property name="type_hint">dialog</property>
-    <property name="skip_taskbar_hint">True</property>
-    <property name="skip_pager_hint">True</property>
-    <property name="has_separator">False</property>
-    <child internal-child="vbox">
-      <widget class="GtkVBox" id="smsLayout">
-        <property name="visible">True</property>
-        <property name="orientation">vertical</property>
-        <property name="spacing">2</property>
-        <child>
-          <widget class="GtkVBox" id="vbox1">
-            <property name="visible">True</property>
-            <property name="orientation">vertical</property>
-            <child>
-              <widget class="GtkScrolledWindow" id="smsMessages_scrolledwindow">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="hscrollbar_policy">never</property>
-                <property name="vscrollbar_policy">automatic</property>
-                <child>
-                  <widget class="GtkTreeView" id="smsMessages">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                  </widget>
-                </child>
-              </widget>
-              <packing>
-                <property name="position">0</property>
-              </packing>
-            </child>
-          </widget>
-          <packing>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child>
-          <widget class="GtkHSeparator" id="hseparator1">
-            <property name="visible">True</property>
-          </widget>
-          <packing>
-            <property name="expand">False</property>
-            <property name="position">2</property>
-          </packing>
-        </child>
-        <child>
-          <widget class="GtkVBox" id="vbox2">
-            <property name="visible">True</property>
-            <property name="orientation">vertical</property>
-            <child>
-              <widget class="GtkScrolledWindow" id="smsMessage_scrolledEntry">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="hscrollbar_policy">never</property>
-                <property name="vscrollbar_policy">automatic</property>
-                <child>
-                  <widget class="GtkTextView" id="smsEntry">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="wrap_mode">word</property>
-                  </widget>
-                </child>
-              </widget>
-              <packing>
-                <property name="position">0</property>
-              </packing>
-            </child>
-          </widget>
-          <packing>
-            <property name="position">3</property>
-          </packing>
-        </child>
-        <child>
-          <widget class="GtkHBox" id="smsCountBox">
-            <property name="visible">True</property>
-            <child>
-              <widget class="GtkLabel" id="smsLetterCount1">
-                <property name="visible">True</property>
-                <property name="label" translatable="yes">Letters Left:</property>
-                <property name="use_markup">True</property>
-              </widget>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkLabel" id="smsLetterCount">
-                <property name="visible">True</property>
-                <property name="use_markup">True</property>
-              </widget>
-              <packing>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </widget>
-          <packing>
-            <property name="expand">False</property>
-            <property name="position">4</property>
-          </packing>
-        </child>
-        <child internal-child="action_area">
-          <widget class="GtkHButtonBox" id="dialog-action_area3">
-            <property name="visible">True</property>
-            <property name="layout_style">end</property>
-            <child>
-              <widget class="GtkButton" id="sendSmsButton">
-                <property name="label" translatable="yes">Send</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-              </widget>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="GtkButton" id="cancelSmsButton">
-                <property name="label" translatable="yes">gtk-cancel</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="use_stock">True</property>
-              </widget>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-          </widget>
-          <packing>
-            <property name="expand">False</property>
-            <property name="pack_type">end</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-      </widget>
-    </child>
-  </widget>
-</glade-interface>
diff --git a/src/dialcentral.py b/src/dialcentral.py
deleted file mode 100755 (executable)
index 4f669ff..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/python
-
-import os
-import sys
-import logging
-
-
-sys.path.insert(0,"/usr/lib/dialcentral/")
-
-
-import constants
-import dc_glade
-
-
-try:
-       os.makedirs(constants._data_path_)
-except OSError, e:
-       if e.errno != 17:
-               raise
-
-userLogPath = "%s/dialcentral.log" % constants._data_path_
-logging.basicConfig(level=logging.DEBUG, filename=userLogPath)
-logging.info("Dialcentral %s-%s" % (constants.__version__, constants.__build__))
-
-try:
-       dc_glade.run_dialpad()
-finally:
-       logging.shutdown()
diff --git a/src/example_custom_notifier.py b/src/example_custom_notifier.py
deleted file mode 100755 (executable)
index 3679b5b..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-
-
-sys.path.insert(0,"/usr/lib/dialcentral/")
-
-
-import alarm_notify
-
-
-def notify_on_change():
-       notifyUser = alarm_notify.is_changed()
-
-       if notifyUser:
-               import subprocess
-               import led_handler
-               led = led_handler.LedHandler()
-               led.on()
-               soundOn = subprocess.call("/usr/bin/dbus-send --dest=com.nokia.osso_media_server --print-reply /com/nokia/osso_media_server com.nokia.osso_media_server.music.play_media string:file:///usr/lib/gv-notifier/alert.mp3",shell=True)
-
-
-if __name__ == "__main__":
-       notify_on_change()
diff --git a/src/file_backend.py b/src/file_backend.py
deleted file mode 100644 (file)
index b373561..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-#!/usr/bin/python
-
-"""
-DialCentral - Front end for Google's Grand Central service.
-Copyright (C) 2008  Eric Warnke ericew AT gmail DOT com
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version.
-
-This library 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
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-Filesystem backend for contact support
-"""
-
-
-import os
-import re
-import csv
-
-
-class CsvAddressBook(object):
-       """
-       Currently supported file format
-       @li Has the first line as a header
-       @li Escapes with quotes
-       @li Comma as delimiter
-       @li Column 0 is name, column 1 is number
-       """
-
-       _nameRe = re.compile("name", re.IGNORECASE)
-       _phoneRe = re.compile("phone", re.IGNORECASE)
-       _mobileRe = re.compile("mobile", re.IGNORECASE)
-
-       def __init__(self, csvPath):
-               self.__csvPath = csvPath
-               self.__contacts = list(
-                       self.read_csv(csvPath)
-               )
-
-       @classmethod
-       def read_csv(cls, csvPath):
-               try:
-                       csvReader = iter(csv.reader(open(csvPath, "rU")))
-               except IOError, e:
-                       if e.errno != 2:
-                               raise
-                       return
-
-               header = csvReader.next()
-               nameColumn, phoneColumns = cls._guess_columns(header)
-
-               yieldCount = 0
-               for row in csvReader:
-                       contactDetails = []
-                       for (phoneType, phoneColumn) in phoneColumns:
-                               try:
-                                       if len(row[phoneColumn]) == 0:
-                                               continue
-                                       contactDetails.append((phoneType, row[phoneColumn]))
-                               except IndexError:
-                                       pass
-                       if len(contactDetails) != 0:
-                               yield str(yieldCount), row[nameColumn], contactDetails
-                               yieldCount += 1
-
-       @classmethod
-       def _guess_columns(cls, row):
-               names = []
-               phones = []
-               for i, item in enumerate(row):
-                       if cls._nameRe.search(item) is not None:
-                               names.append((item, i))
-                       elif cls._phoneRe.search(item) is not None:
-                               phones.append((item, i))
-                       elif cls._mobileRe.search(item) is not None:
-                               phones.append((item, i))
-               if len(names) == 0:
-                       names.append(("Name", 0))
-               if len(phones) == 0:
-                       phones.append(("Phone", 1))
-
-               return names[0][1], phones
-
-       def clear_caches(self):
-               pass
-
-       @staticmethod
-       def factory_name():
-               return "csv"
-
-       @staticmethod
-       def contact_source_short_name(contactId):
-               return "csv"
-
-       def get_contacts(self):
-               """
-               @returns Iterable of (contact id, contact name)
-               """
-               for contact in self.__contacts:
-                       yield contact[0:2]
-
-       def get_contact_details(self, contactId):
-               """
-               @returns Iterable of (Phone Type, Phone Number)
-               """
-               contactId = int(contactId)
-               return iter(self.__contacts[contactId][2])
-
-
-class FilesystemAddressBookFactory(object):
-
-       FILETYPE_SUPPORT = {
-               "csv": CsvAddressBook,
-       }
-
-       def __init__(self, path):
-               self.__path = path
-
-       def clear_caches(self):
-               pass
-
-       def get_addressbooks(self):
-               """
-               @returns Iterable of (Address Book Factory, Book Id, Book Name)
-               """
-               for root, dirs, filenames in os.walk(self.__path):
-                       for filename in filenames:
-                               try:
-                                       name, ext = filename.rsplit(".", 1)
-                               except ValueError:
-                                       continue
-
-                               if ext in self.FILETYPE_SUPPORT:
-                                       yield self, os.path.join(root, filename), name
-
-       def open_addressbook(self, bookId):
-               name, ext = bookId.rsplit(".", 1)
-               assert ext in self.FILETYPE_SUPPORT, "Unsupported file extension %s" % ext
-               return self.FILETYPE_SUPPORT[ext](bookId)
-
-       @staticmethod
-       def factory_name():
-               return "File"
-
-
-def print_filebooks(contactPath = None):
-       """
-       Included here for debugging.
-
-       Either insert it into the code or launch python with the "-i" flag
-       """
-       if contactPath is None:
-               contactPath = os.path.join(os.path.expanduser("~"), ".dialcentral", "contacts")
-
-       abf = FilesystemAddressBookFactory(contactPath)
-       for book in abf.get_addressbooks():
-               ab = abf.open_addressbook(book[1])
-               print book
-               for contact in ab.get_contacts():
-                       print "\t", contact
-                       for details in ab.get_contact_details(contact[0]):
-                               print "\t\t", details
diff --git a/src/gv_views.py b/src/gv_views.py
deleted file mode 100644 (file)
index 0eac88b..0000000
+++ /dev/null
@@ -1,1483 +0,0 @@
-#!/usr/bin/python2.5
-
-"""
-DialCentral - Front end for Google's GoogleVoice service.
-Copyright (C) 2008  Mark Bergman bergman AT merctech DOT com
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version.
-
-This library 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
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-@todo Alternate UI for dialogs (stackables)
-"""
-
-from __future__ import with_statement
-
-import ConfigParser
-import logging
-
-import gobject
-import pango
-import gtk
-
-import gtk_toolbox
-import hildonize
-import null_backend
-
-
-def make_ugly(prettynumber):
-       """
-       function to take a phone number and strip out all non-numeric
-       characters
-
-       >>> make_ugly("+012-(345)-678-90")
-       '01234567890'
-       """
-       import re
-       uglynumber = re.sub('\D', '', prettynumber)
-       return uglynumber
-
-
-def make_pretty(phonenumber):
-       """
-       Function to take a phone number and return the pretty version
-       pretty numbers:
-               if phonenumber begins with 0:
-                       ...-(...)-...-....
-               if phonenumber begins with 1: ( for gizmo callback numbers )
-                       1 (...)-...-....
-               if phonenumber is 13 digits:
-                       (...)-...-....
-               if phonenumber is 10 digits:
-                       ...-....
-       >>> make_pretty("12")
-       '12'
-       >>> make_pretty("1234567")
-       '123-4567'
-       >>> make_pretty("2345678901")
-       '(234)-567-8901'
-       >>> make_pretty("12345678901")
-       '1 (234)-567-8901'
-       >>> make_pretty("01234567890")
-       '+012-(345)-678-90'
-       """
-       if phonenumber is None or phonenumber is "":
-               return ""
-
-       phonenumber = make_ugly(phonenumber)
-
-       if len(phonenumber) < 3:
-               return phonenumber
-
-       if phonenumber[0] == "0":
-               prettynumber = ""
-               prettynumber += "+%s" % phonenumber[0:3]
-               if 3 < len(phonenumber):
-                       prettynumber += "-(%s)" % phonenumber[3:6]
-                       if 6 < len(phonenumber):
-                               prettynumber += "-%s" % phonenumber[6:9]
-                               if 9 < len(phonenumber):
-                                       prettynumber += "-%s" % phonenumber[9:]
-               return prettynumber
-       elif len(phonenumber) <= 7:
-               prettynumber = "%s-%s" % (phonenumber[0:3], phonenumber[3:])
-       elif len(phonenumber) > 8 and phonenumber[0] == "1":
-               prettynumber = "1 (%s)-%s-%s" % (phonenumber[1:4], phonenumber[4:7], phonenumber[7:])
-       elif len(phonenumber) > 7:
-               prettynumber = "(%s)-%s-%s" % (phonenumber[0:3], phonenumber[3:6], phonenumber[6:])
-       return prettynumber
-
-
-def abbrev_relative_date(date):
-       """
-       >>> abbrev_relative_date("42 hours ago")
-       '42 h'
-       >>> abbrev_relative_date("2 days ago")
-       '2 d'
-       >>> abbrev_relative_date("4 weeks ago")
-       '4 w'
-       """
-       parts = date.split(" ")
-       return "%s %s" % (parts[0], parts[1][0])
-
-
-class MergedAddressBook(object):
-       """
-       Merger of all addressbooks
-       """
-
-       def __init__(self, addressbookFactories, sorter = None):
-               self.__addressbookFactories = addressbookFactories
-               self.__addressbooks = None
-               self.__sort_contacts = sorter if sorter is not None else self.null_sorter
-
-       def clear_caches(self):
-               self.__addressbooks = None
-               for factory in self.__addressbookFactories:
-                       factory.clear_caches()
-
-       def get_addressbooks(self):
-               """
-               @returns Iterable of (Address Book Factory, Book Id, Book Name)
-               """
-               yield self, "", ""
-
-       def open_addressbook(self, bookId):
-               return self
-
-       def contact_source_short_name(self, contactId):
-               if self.__addressbooks is None:
-                       return ""
-               bookIndex, originalId = contactId.split("-", 1)
-               return self.__addressbooks[int(bookIndex)].contact_source_short_name(originalId)
-
-       @staticmethod
-       def factory_name():
-               return "All Contacts"
-
-       def get_contacts(self):
-               """
-               @returns Iterable of (contact id, contact name)
-               """
-               if self.__addressbooks is None:
-                       self.__addressbooks = list(
-                               factory.open_addressbook(id)
-                               for factory in self.__addressbookFactories
-                               for (f, id, name) in factory.get_addressbooks()
-                       )
-               contacts = (
-                       ("-".join([str(bookIndex), contactId]), contactName)
-                               for (bookIndex, addressbook) in enumerate(self.__addressbooks)
-                                       for (contactId, contactName) in addressbook.get_contacts()
-               )
-               sortedContacts = self.__sort_contacts(contacts)
-               return sortedContacts
-
-       def get_contact_details(self, contactId):
-               """
-               @returns Iterable of (Phone Type, Phone Number)
-               """
-               if self.__addressbooks is None:
-                       return []
-               bookIndex, originalId = contactId.split("-", 1)
-               return self.__addressbooks[int(bookIndex)].get_contact_details(originalId)
-
-       @staticmethod
-       def null_sorter(contacts):
-               """
-               Good for speed/low memory
-               """
-               return contacts
-
-       @staticmethod
-       def basic_firtname_sorter(contacts):
-               """
-               Expects names in "First Last" format
-               """
-               contactsWithKey = [
-                       (contactName.rsplit(" ", 1)[0], (contactId, contactName))
-                               for (contactId, contactName) in contacts
-               ]
-               contactsWithKey.sort()
-               return (contactData for (lastName, contactData) in contactsWithKey)
-
-       @staticmethod
-       def basic_lastname_sorter(contacts):
-               """
-               Expects names in "First Last" format
-               """
-               contactsWithKey = [
-                       (contactName.rsplit(" ", 1)[-1], (contactId, contactName))
-                               for (contactId, contactName) in contacts
-               ]
-               contactsWithKey.sort()
-               return (contactData for (lastName, contactData) in contactsWithKey)
-
-       @staticmethod
-       def reversed_firtname_sorter(contacts):
-               """
-               Expects names in "Last, First" format
-               """
-               contactsWithKey = [
-                       (contactName.split(", ", 1)[-1], (contactId, contactName))
-                               for (contactId, contactName) in contacts
-               ]
-               contactsWithKey.sort()
-               return (contactData for (lastName, contactData) in contactsWithKey)
-
-       @staticmethod
-       def reversed_lastname_sorter(contacts):
-               """
-               Expects names in "Last, First" format
-               """
-               contactsWithKey = [
-                       (contactName.split(", ", 1)[0], (contactId, contactName))
-                               for (contactId, contactName) in contacts
-               ]
-               contactsWithKey.sort()
-               return (contactData for (lastName, contactData) in contactsWithKey)
-
-       @staticmethod
-       def guess_firstname(name):
-               if ", " in name:
-                       return name.split(", ", 1)[-1]
-               else:
-                       return name.rsplit(" ", 1)[0]
-
-       @staticmethod
-       def guess_lastname(name):
-               if ", " in name:
-                       return name.split(", ", 1)[0]
-               else:
-                       return name.rsplit(" ", 1)[-1]
-
-       @classmethod
-       def advanced_firstname_sorter(cls, contacts):
-               contactsWithKey = [
-                       (cls.guess_firstname(contactName), (contactId, contactName))
-                               for (contactId, contactName) in contacts
-               ]
-               contactsWithKey.sort()
-               return (contactData for (lastName, contactData) in contactsWithKey)
-
-       @classmethod
-       def advanced_lastname_sorter(cls, contacts):
-               contactsWithKey = [
-                       (cls.guess_lastname(contactName), (contactId, contactName))
-                               for (contactId, contactName) in contacts
-               ]
-               contactsWithKey.sort()
-               return (contactData for (lastName, contactData) in contactsWithKey)
-
-
-class PhoneTypeSelector(object):
-
-       ACTION_CANCEL = "cancel"
-       ACTION_SELECT = "select"
-       ACTION_DIAL = "dial"
-       ACTION_SEND_SMS = "sms"
-
-       def __init__(self, widgetTree, gcBackend):
-               self._gcBackend = gcBackend
-               self._widgetTree = widgetTree
-
-               self._dialog = self._widgetTree.get_widget("phonetype_dialog")
-               self._smsDialog = SmsEntryDialog(self._widgetTree)
-
-               self._smsButton = self._widgetTree.get_widget("sms_button")
-               self._smsButton.connect("clicked", self._on_phonetype_send_sms)
-
-               self._dialButton = self._widgetTree.get_widget("dial_button")
-               self._dialButton.connect("clicked", self._on_phonetype_dial)
-
-               self._selectButton = self._widgetTree.get_widget("select_button")
-               self._selectButton.connect("clicked", self._on_phonetype_select)
-
-               self._cancelButton = self._widgetTree.get_widget("cancel_button")
-               self._cancelButton.connect("clicked", self._on_phonetype_cancel)
-
-               self._messagemodel = gtk.ListStore(gobject.TYPE_STRING)
-               self._messagesView = self._widgetTree.get_widget("phoneSelectionMessages")
-               self._scrollWindow = self._messagesView.get_parent()
-
-               self._typemodel = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
-               self._typeviewselection = None
-               self._typeview = self._widgetTree.get_widget("phonetypes")
-               self._typeview.connect("row-activated", self._on_phonetype_select)
-
-               self._action = self.ACTION_CANCEL
-
-       def run(self, contactDetails, messages = (), parent = None):
-               self._action = self.ACTION_CANCEL
-
-               # Add the column to the phone selection tree view
-               self._typemodel.clear()
-               self._typeview.set_model(self._typemodel)
-
-               textrenderer = gtk.CellRendererText()
-               numberColumn = gtk.TreeViewColumn("Phone Numbers", textrenderer, text=0)
-               self._typeview.append_column(numberColumn)
-
-               textrenderer = gtk.CellRendererText()
-               typeColumn = gtk.TreeViewColumn("Phone Type", textrenderer, text=1)
-               self._typeview.append_column(typeColumn)
-
-               for phoneType, phoneNumber in contactDetails:
-                       display = " - ".join((phoneNumber, phoneType))
-                       display = phoneType
-                       row = (phoneNumber, display)
-                       self._typemodel.append(row)
-
-               self._typeviewselection = self._typeview.get_selection()
-               self._typeviewselection.set_mode(gtk.SELECTION_SINGLE)
-               self._typeviewselection.select_iter(self._typemodel.get_iter_first())
-
-               # Add the column to the messages tree view
-               self._messagemodel.clear()
-               self._messagesView.set_model(self._messagemodel)
-
-               textrenderer = gtk.CellRendererText()
-               textrenderer.set_property("wrap-mode", pango.WRAP_WORD)
-               textrenderer.set_property("wrap-width", 450)
-               messageColumn = gtk.TreeViewColumn("")
-               messageColumn.pack_start(textrenderer, expand=True)
-               messageColumn.add_attribute(textrenderer, "markup", 0)
-               messageColumn.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
-               self._messagesView.append_column(messageColumn)
-               self._messagesView.set_headers_visible(False)
-
-               if messages:
-                       for message in messages:
-                               row = (message, )
-                               self._messagemodel.append(row)
-                       self._messagesView.show()
-                       self._scrollWindow.show()
-                       messagesSelection = self._messagesView.get_selection()
-                       messagesSelection.select_path((len(messages)-1, ))
-               else:
-                       self._messagesView.hide()
-                       self._scrollWindow.hide()
-
-               if parent is not None:
-                       self._dialog.set_transient_for(parent)
-
-               try:
-                       self._dialog.show()
-                       if messages:
-                               self._messagesView.scroll_to_cell((len(messages)-1, ))
-
-                       userResponse = self._dialog.run()
-               finally:
-                       self._dialog.hide()
-
-               if userResponse == gtk.RESPONSE_OK:
-                       phoneNumber = self._get_number()
-                       phoneNumber = make_ugly(phoneNumber)
-               else:
-                       phoneNumber = ""
-               if not phoneNumber:
-                       self._action = self.ACTION_CANCEL
-
-               if self._action == self.ACTION_SEND_SMS:
-                       smsMessage = self._smsDialog.run(phoneNumber, messages, parent)
-                       if not smsMessage:
-                               phoneNumber = ""
-                               self._action = self.ACTION_CANCEL
-               else:
-                       smsMessage = ""
-
-               self._messagesView.remove_column(messageColumn)
-               self._messagesView.set_model(None)
-
-               self._typeviewselection.unselect_all()
-               self._typeview.remove_column(numberColumn)
-               self._typeview.remove_column(typeColumn)
-               self._typeview.set_model(None)
-
-               return self._action, phoneNumber, smsMessage
-
-       def _get_number(self):
-               model, itr = self._typeviewselection.get_selected()
-               if not itr:
-                       return ""
-
-               phoneNumber = self._typemodel.get_value(itr, 0)
-               return phoneNumber
-
-       def _on_phonetype_dial(self, *args):
-               self._dialog.response(gtk.RESPONSE_OK)
-               self._action = self.ACTION_DIAL
-
-       def _on_phonetype_send_sms(self, *args):
-               self._dialog.response(gtk.RESPONSE_OK)
-               self._action = self.ACTION_SEND_SMS
-
-       def _on_phonetype_select(self, *args):
-               self._dialog.response(gtk.RESPONSE_OK)
-               self._action = self.ACTION_SELECT
-
-       def _on_phonetype_cancel(self, *args):
-               self._dialog.response(gtk.RESPONSE_CANCEL)
-               self._action = self.ACTION_CANCEL
-
-
-class SmsEntryDialog(object):
-       """
-       @todo Add multi-SMS messages like GoogleVoice
-       """
-
-       MAX_CHAR = 160
-
-       def __init__(self, widgetTree):
-               self._widgetTree = widgetTree
-               self._dialog = self._widgetTree.get_widget("smsDialog")
-
-               self._smsButton = self._widgetTree.get_widget("sendSmsButton")
-               self._smsButton.connect("clicked", self._on_send)
-
-               self._cancelButton = self._widgetTree.get_widget("cancelSmsButton")
-               self._cancelButton.connect("clicked", self._on_cancel)
-
-               self._letterCountLabel = self._widgetTree.get_widget("smsLetterCount")
-
-               self._messagemodel = gtk.ListStore(gobject.TYPE_STRING)
-               self._messagesView = self._widgetTree.get_widget("smsMessages")
-               self._scrollWindow = self._messagesView.get_parent()
-
-               self._smsEntry = self._widgetTree.get_widget("smsEntry")
-               self._smsEntry.get_buffer().connect("changed", self._on_entry_changed)
-
-       def run(self, number, messages = (), parent = None):
-               # Add the column to the messages tree view
-               self._messagemodel.clear()
-               self._messagesView.set_model(self._messagemodel)
-
-               textrenderer = gtk.CellRendererText()
-               textrenderer.set_property("wrap-mode", pango.WRAP_WORD)
-               textrenderer.set_property("wrap-width", 450)
-               messageColumn = gtk.TreeViewColumn("")
-               messageColumn.pack_start(textrenderer, expand=True)
-               messageColumn.add_attribute(textrenderer, "markup", 0)
-               messageColumn.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
-               self._messagesView.append_column(messageColumn)
-               self._messagesView.set_headers_visible(False)
-
-               if messages:
-                       for message in messages:
-                               row = (message, )
-                               self._messagemodel.append(row)
-                       self._messagesView.show()
-                       self._scrollWindow.show()
-                       messagesSelection = self._messagesView.get_selection()
-                       messagesSelection.select_path((len(messages)-1, ))
-               else:
-                       self._messagesView.hide()
-                       self._scrollWindow.hide()
-
-               self._smsEntry.get_buffer().set_text("")
-               self._update_letter_count()
-
-               if parent is not None:
-                       self._dialog.set_transient_for(parent)
-
-               try:
-                       self._dialog.show()
-                       if messages:
-                               self._messagesView.scroll_to_cell((len(messages)-1, ))
-                       self._smsEntry.grab_focus()
-
-                       userResponse = self._dialog.run()
-               finally:
-                       self._dialog.hide()
-
-               if userResponse == gtk.RESPONSE_OK:
-                       entryBuffer = self._smsEntry.get_buffer()
-                       enteredMessage = entryBuffer.get_text(entryBuffer.get_start_iter(), entryBuffer.get_end_iter())
-                       enteredMessage = enteredMessage[0:self.MAX_CHAR]
-               else:
-                       enteredMessage = ""
-
-               self._messagesView.remove_column(messageColumn)
-               self._messagesView.set_model(None)
-
-               return enteredMessage.strip()
-
-       def _update_letter_count(self, *args):
-               entryLength = self._smsEntry.get_buffer().get_char_count()
-               charsLeft = self.MAX_CHAR - entryLength
-               self._letterCountLabel.set_text(str(charsLeft))
-               if charsLeft < 0:
-                       self._smsButton.set_sensitive(False)
-               else:
-                       self._smsButton.set_sensitive(True)
-
-       def _on_entry_changed(self, *args):
-               self._update_letter_count()
-
-       def _on_send(self, *args):
-               self._dialog.response(gtk.RESPONSE_OK)
-
-       def _on_cancel(self, *args):
-               self._dialog.response(gtk.RESPONSE_CANCEL)
-
-
-class Dialpad(object):
-
-       def __init__(self, widgetTree, errorDisplay):
-               self._clipboard = gtk.clipboard_get()
-               self._errorDisplay = errorDisplay
-               self._smsDialog = SmsEntryDialog(widgetTree)
-
-               self._numberdisplay = widgetTree.get_widget("numberdisplay")
-               self._smsButton = widgetTree.get_widget("sms")
-               self._dialButton = widgetTree.get_widget("dial")
-               self._backButton = widgetTree.get_widget("back")
-               self._phonenumber = ""
-               self._prettynumber = ""
-
-               callbackMapping = {
-                       "on_digit_clicked": self._on_digit_clicked,
-               }
-               widgetTree.signal_autoconnect(callbackMapping)
-               self._dialButton.connect("clicked", self._on_dial_clicked)
-               self._smsButton.connect("clicked", self._on_sms_clicked)
-
-               self._originalLabel = self._backButton.get_label()
-               self._backTapHandler = gtk_toolbox.TapOrHold(self._backButton)
-               self._backTapHandler.on_tap = self._on_backspace
-               self._backTapHandler.on_hold = self._on_clearall
-               self._backTapHandler.on_holding = self._set_clear_button
-               self._backTapHandler.on_cancel = self._reset_back_button
-
-               self._window = gtk_toolbox.find_parent_window(self._numberdisplay)
-               self._keyPressEventId = 0
-
-       def enable(self):
-               self._dialButton.grab_focus()
-               self._backTapHandler.enable()
-               self._keyPressEventId = self._window.connect("key-press-event", self._on_key_press)
-
-       def disable(self):
-               self._window.disconnect(self._keyPressEventId)
-               self._keyPressEventId = 0
-               self._reset_back_button()
-               self._backTapHandler.disable()
-
-       def number_selected(self, action, number, message):
-               """
-               @note Actual dial function is patched in later
-               """
-               raise NotImplementedError("Horrible unknown error has occurred")
-
-       def get_number(self):
-               return self._phonenumber
-
-       def set_number(self, number):
-               """
-               Set the number to dial
-               """
-               try:
-                       self._phonenumber = make_ugly(number)
-                       self._prettynumber = make_pretty(self._phonenumber)
-                       self._numberdisplay.set_label("<span size='30000' weight='bold'>%s</span>" % (self._prettynumber))
-               except TypeError, e:
-                       self._errorDisplay.push_exception()
-
-       def clear(self):
-               self.set_number("")
-
-       @staticmethod
-       def name():
-               return "Dialpad"
-
-       def load_settings(self, config, section):
-               pass
-
-       def save_settings(self, config, section):
-               """
-               @note Thread Agnostic
-               """
-               pass
-
-       def _on_key_press(self, widget, event):
-               try:
-                       if event.keyval == ord("v") and event.get_state() & gtk.gdk.CONTROL_MASK:
-                               contents = self._clipboard.wait_for_text()
-                               if contents is not None:
-                                       self.set_number(contents)
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_sms_clicked(self, widget):
-               try:
-                       action = PhoneTypeSelector.ACTION_SEND_SMS
-                       phoneNumber = self.get_number()
-
-                       message = self._smsDialog.run(phoneNumber, (), self._window)
-                       if not message:
-                               phoneNumber = ""
-                               action = PhoneTypeSelector.ACTION_CANCEL
-
-                       if action == PhoneTypeSelector.ACTION_CANCEL:
-                               return
-                       self.number_selected(action, phoneNumber, message)
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_dial_clicked(self, widget):
-               try:
-                       action = PhoneTypeSelector.ACTION_DIAL
-                       phoneNumber = self.get_number()
-                       message = ""
-                       self.number_selected(action, phoneNumber, message)
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_digit_clicked(self, widget):
-               try:
-                       self.set_number(self._phonenumber + widget.get_name()[-1])
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_backspace(self, taps):
-               try:
-                       self.set_number(self._phonenumber[:-taps])
-                       self._reset_back_button()
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_clearall(self, taps):
-               try:
-                       self.clear()
-                       self._reset_back_button()
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-               return False
-
-       def _set_clear_button(self):
-               try:
-                       self._backButton.set_label("gtk-clear")
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _reset_back_button(self):
-               try:
-                       self._backButton.set_label(self._originalLabel)
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-
-class AccountInfo(object):
-
-       def __init__(self, widgetTree, backend, alarmHandler, errorDisplay):
-               self._errorDisplay = errorDisplay
-               self._backend = backend
-               self._isPopulated = False
-               self._alarmHandler = alarmHandler
-               self._notifyOnMissed = False
-               self._notifyOnVoicemail = False
-               self._notifyOnSms = False
-
-               self._callbackList = []
-               self._accountViewNumberDisplay = widgetTree.get_widget("gcnumber_display")
-               self._callbackSelectButton = widgetTree.get_widget("callbackSelectButton")
-               self._onCallbackSelectChangedId = 0
-
-               self._notifyCheckbox = widgetTree.get_widget("notifyCheckbox")
-               self._minutesEntryButton = widgetTree.get_widget("minutesEntryButton")
-               self._missedCheckbox = widgetTree.get_widget("missedCheckbox")
-               self._voicemailCheckbox = widgetTree.get_widget("voicemailCheckbox")
-               self._smsCheckbox = widgetTree.get_widget("smsCheckbox")
-               self._onNotifyToggled = 0
-               self._onMinutesChanged = 0
-               self._onMissedToggled = 0
-               self._onVoicemailToggled = 0
-               self._onSmsToggled = 0
-               self._applyAlarmTimeoutId = None
-
-               self._window = gtk_toolbox.find_parent_window(self._minutesEntryButton)
-               self._defaultCallback = ""
-
-       def enable(self):
-               assert self._backend.is_authed(), "Attempting to enable backend while not logged in"
-
-               self._accountViewNumberDisplay.set_use_markup(True)
-               self.set_account_number("")
-
-               del self._callbackList[:]
-               self._onCallbackSelectChangedId = self._callbackSelectButton.connect("clicked", self._on_callbackentry_clicked)
-
-               if self._alarmHandler is not None:
-                       self._notifyCheckbox.set_active(self._alarmHandler.isEnabled)
-                       self._minutesEntryButton.set_label("%d minutes" % self._alarmHandler.recurrence)
-                       self._missedCheckbox.set_active(self._notifyOnMissed)
-                       self._voicemailCheckbox.set_active(self._notifyOnVoicemail)
-                       self._smsCheckbox.set_active(self._notifyOnSms)
-
-                       self._onNotifyToggled = self._notifyCheckbox.connect("toggled", self._on_notify_toggled)
-                       self._onMinutesChanged = self._minutesEntryButton.connect("clicked", self._on_minutes_clicked)
-                       self._onMissedToggled = self._missedCheckbox.connect("toggled", self._on_missed_toggled)
-                       self._onVoicemailToggled = self._voicemailCheckbox.connect("toggled", self._on_voicemail_toggled)
-                       self._onSmsToggled = self._smsCheckbox.connect("toggled", self._on_sms_toggled)
-               else:
-                       self._notifyCheckbox.set_sensitive(False)
-                       self._minutesEntryButton.set_sensitive(False)
-                       self._missedCheckbox.set_sensitive(False)
-                       self._voicemailCheckbox.set_sensitive(False)
-                       self._smsCheckbox.set_sensitive(False)
-
-               self.update(force=True)
-
-       def disable(self):
-               self._callbackSelectButton.disconnect(self._onCallbackSelectChangedId)
-               self._onCallbackSelectChangedId = 0
-
-               if self._alarmHandler is not None:
-                       self._notifyCheckbox.disconnect(self._onNotifyToggled)
-                       self._minutesEntryButton.disconnect(self._onMinutesChanged)
-                       self._missedCheckbox.disconnect(self._onNotifyToggled)
-                       self._voicemailCheckbox.disconnect(self._onNotifyToggled)
-                       self._smsCheckbox.disconnect(self._onNotifyToggled)
-                       self._onNotifyToggled = 0
-                       self._onMinutesChanged = 0
-                       self._onMissedToggled = 0
-                       self._onVoicemailToggled = 0
-                       self._onSmsToggled = 0
-               else:
-                       self._notifyCheckbox.set_sensitive(True)
-                       self._minutesEntryButton.set_sensitive(True)
-                       self._missedCheckbox.set_sensitive(True)
-                       self._voicemailCheckbox.set_sensitive(True)
-                       self._smsCheckbox.set_sensitive(True)
-
-               self.clear()
-               del self._callbackList[:]
-
-       def get_selected_callback_number(self):
-               currentLabel = self._callbackSelectButton.get_label()
-               if currentLabel is not None:
-                       return make_ugly(currentLabel)
-               else:
-                       return ""
-
-       def set_account_number(self, number):
-               """
-               Displays current account number
-               """
-               self._accountViewNumberDisplay.set_label("<span size='23000' weight='bold'>%s</span>" % (number))
-
-       def update(self, force = False):
-               if not force and self._isPopulated:
-                       return False
-               self._populate_callback_combo()
-               self.set_account_number(self._backend.get_account_number())
-               return True
-
-       def clear(self):
-               self._callbackSelectButton.set_label("")
-               self.set_account_number("")
-               self._isPopulated = False
-
-       def save_everything(self):
-               raise NotImplementedError
-
-       @staticmethod
-       def name():
-               return "Account Info"
-
-       def load_settings(self, config, section):
-               self._defaultCallback = config.get(section, "callback")
-               self._notifyOnMissed = config.getboolean(section, "notifyOnMissed")
-               self._notifyOnVoicemail = config.getboolean(section, "notifyOnVoicemail")
-               self._notifyOnSms = config.getboolean(section, "notifyOnSms")
-
-       def save_settings(self, config, section):
-               """
-               @note Thread Agnostic
-               """
-               callback = self.get_selected_callback_number()
-               config.set(section, "callback", callback)
-               config.set(section, "notifyOnMissed", repr(self._notifyOnMissed))
-               config.set(section, "notifyOnVoicemail", repr(self._notifyOnVoicemail))
-               config.set(section, "notifyOnSms", repr(self._notifyOnSms))
-
-       def _populate_callback_combo(self):
-               self._isPopulated = True
-               del self._callbackList[:]
-               try:
-                       callbackNumbers = self._backend.get_callback_numbers()
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-                       self._isPopulated = False
-                       return
-
-               for number, description in callbackNumbers.iteritems():
-                       self._callbackList.append(make_pretty(number))
-
-               if not self.get_selected_callback_number():
-                       self._set_callback_number(self._defaultCallback)
-
-       def _set_callback_number(self, number):
-               try:
-                       if not self._backend.is_valid_syntax(number) and 0 < len(number):
-                               self._errorDisplay.push_message("%s is not a valid callback number" % number)
-                       elif number == self._backend.get_callback_number():
-                               logging.warning(
-                                       "Callback number already is %s" % (
-                                               self._backend.get_callback_number(),
-                                       ),
-                               )
-                       else:
-                               self._backend.set_callback_number(number)
-                               assert make_ugly(number) == make_ugly(self._backend.get_callback_number()), "Callback number should be %s but instead is %s" % (
-                                       make_pretty(number), make_pretty(self._backend.get_callback_number())
-                               )
-                               self._callbackSelectButton.set_label(make_pretty(number))
-                               logging.info(
-                                       "Callback number set to %s" % (
-                                               self._backend.get_callback_number(),
-                                       ),
-                               )
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _update_alarm_settings(self, recurrence):
-               try:
-                       isEnabled = self._notifyCheckbox.get_active()
-                       if isEnabled != self._alarmHandler.isEnabled or recurrence != self._alarmHandler.recurrence:
-                               self._alarmHandler.apply_settings(isEnabled, recurrence)
-               finally:
-                       self.save_everything()
-                       self._notifyCheckbox.set_active(self._alarmHandler.isEnabled)
-                       self._minutesEntryButton.set_label("%d Minutes" % self._alarmHandler.recurrence)
-
-       def _on_callbackentry_clicked(self, *args):
-               try:
-                       actualSelection = make_pretty(self.get_selected_callback_number())
-
-                       userSelection = hildonize.touch_selector_entry(
-                               self._window,
-                               "Callback Number",
-                               self._callbackList,
-                               actualSelection,
-                       )
-                       number = make_ugly(userSelection)
-                       self._set_callback_number(number)
-               except RuntimeError, e:
-                       logging.exception("%s" % str(e))
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_notify_toggled(self, *args):
-               try:
-                       if self._applyAlarmTimeoutId is not None:
-                               gobject.source_remove(self._applyAlarmTimeoutId)
-                               self._applyAlarmTimeoutId = None
-                       self._applyAlarmTimeoutId = gobject.timeout_add(500, self._on_apply_timeout)
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_minutes_clicked(self, *args):
-               recurrenceChoices = [
-                       (1, "1 minute"),
-                       (2, "2 minutes"),
-                       (3, "3 minutes"),
-                       (5, "5 minutes"),
-                       (8, "8 minutes"),
-                       (10, "10 minutes"),
-                       (15, "15 minutes"),
-                       (30, "30 minutes"),
-                       (45, "45 minutes"),
-                       (60, "1 hour"),
-                       (3*60, "3 hours"),
-                       (6*60, "6 hours"),
-                       (12*60, "12 hours"),
-               ]
-               try:
-                       actualSelection = self._alarmHandler.recurrence
-
-                       closestSelectionIndex = 0
-                       for i, possible in enumerate(recurrenceChoices):
-                               if possible[0] <= actualSelection:
-                                       closestSelectionIndex = i
-                       recurrenceIndex = hildonize.touch_selector(
-                               self._window,
-                               "Minutes",
-                               (("%s" % m[1]) for m in recurrenceChoices),
-                               closestSelectionIndex,
-                       )
-                       recurrence = recurrenceChoices[recurrenceIndex][0]
-
-                       self._update_alarm_settings(recurrence)
-               except RuntimeError, e:
-                       logging.exception("%s" % str(e))
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_apply_timeout(self, *args):
-               try:
-                       self._applyAlarmTimeoutId = None
-
-                       self._update_alarm_settings(self._alarmHandler.recurrence)
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-               return False
-
-       def _on_missed_toggled(self, *args):
-               try:
-                       self._notifyOnMissed = self._missedCheckbox.get_active()
-                       self.save_everything()
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_voicemail_toggled(self, *args):
-               try:
-                       self._notifyOnVoicemail = self._voicemailCheckbox.get_active()
-                       self.save_everything()
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_sms_toggled(self, *args):
-               try:
-                       self._notifyOnSms = self._smsCheckbox.get_active()
-                       self.save_everything()
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-
-class RecentCallsView(object):
-
-       NUMBER_IDX = 0
-       DATE_IDX = 1
-       ACTION_IDX = 2
-       FROM_IDX = 3
-
-       def __init__(self, widgetTree, backend, errorDisplay):
-               self._errorDisplay = errorDisplay
-               self._backend = backend
-
-               self._isPopulated = False
-               self._recentmodel = gtk.ListStore(
-                       gobject.TYPE_STRING, # number
-                       gobject.TYPE_STRING, # date
-                       gobject.TYPE_STRING, # action
-                       gobject.TYPE_STRING, # from
-               )
-               self._recentview = widgetTree.get_widget("recentview")
-               self._recentviewselection = None
-               self._onRecentviewRowActivatedId = 0
-
-               textrenderer = gtk.CellRendererText()
-               textrenderer.set_property("yalign", 0)
-               self._dateColumn = gtk.TreeViewColumn("Date")
-               self._dateColumn.pack_start(textrenderer, expand=True)
-               self._dateColumn.add_attribute(textrenderer, "text", self.DATE_IDX)
-
-               textrenderer = gtk.CellRendererText()
-               textrenderer.set_property("yalign", 0)
-               self._actionColumn = gtk.TreeViewColumn("Action")
-               self._actionColumn.pack_start(textrenderer, expand=True)
-               self._actionColumn.add_attribute(textrenderer, "text", self.ACTION_IDX)
-
-               textrenderer = gtk.CellRendererText()
-               textrenderer.set_property("yalign", 0)
-               textrenderer.set_property("ellipsize", pango.ELLIPSIZE_END)
-               textrenderer.set_property("width-chars", len("1 (555) 555-1234"))
-               self._numberColumn = gtk.TreeViewColumn("Number")
-               self._numberColumn.pack_start(textrenderer, expand=True)
-               self._numberColumn.add_attribute(textrenderer, "text", self.NUMBER_IDX)
-
-               textrenderer = gtk.CellRendererText()
-               textrenderer.set_property("yalign", 0)
-               hildonize.set_cell_thumb_selectable(textrenderer)
-               self._nameColumn = gtk.TreeViewColumn("From")
-               self._nameColumn.pack_start(textrenderer, expand=True)
-               self._nameColumn.add_attribute(textrenderer, "text", self.FROM_IDX)
-               self._nameColumn.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
-
-               self._window = gtk_toolbox.find_parent_window(self._recentview)
-               self._phoneTypeSelector = PhoneTypeSelector(widgetTree, self._backend)
-
-               self._updateSink = gtk_toolbox.threaded_stage(
-                       gtk_toolbox.comap(
-                               self._idly_populate_recentview,
-                               gtk_toolbox.null_sink(),
-                       )
-               )
-
-       def enable(self):
-               assert self._backend.is_authed(), "Attempting to enable backend while not logged in"
-               self._recentview.set_model(self._recentmodel)
-
-               self._recentview.append_column(self._dateColumn)
-               self._recentview.append_column(self._actionColumn)
-               self._recentview.append_column(self._numberColumn)
-               self._recentview.append_column(self._nameColumn)
-               self._recentviewselection = self._recentview.get_selection()
-               self._recentviewselection.set_mode(gtk.SELECTION_SINGLE)
-
-               self._onRecentviewRowActivatedId = self._recentview.connect("row-activated", self._on_recentview_row_activated)
-
-       def disable(self):
-               self._recentview.disconnect(self._onRecentviewRowActivatedId)
-
-               self.clear()
-
-               self._recentview.remove_column(self._dateColumn)
-               self._recentview.remove_column(self._actionColumn)
-               self._recentview.remove_column(self._nameColumn)
-               self._recentview.remove_column(self._numberColumn)
-               self._recentview.set_model(None)
-
-       def number_selected(self, action, number, message):
-               """
-               @note Actual dial function is patched in later
-               """
-               raise NotImplementedError("Horrible unknown error has occurred")
-
-       def update(self, force = False):
-               if not force and self._isPopulated:
-                       return False
-               self._updateSink.send(())
-               return True
-
-       def clear(self):
-               self._isPopulated = False
-               self._recentmodel.clear()
-
-       @staticmethod
-       def name():
-               return "Recent Calls"
-
-       def load_settings(self, config, section):
-               pass
-
-       def save_settings(self, config, section):
-               """
-               @note Thread Agnostic
-               """
-               pass
-
-       def _idly_populate_recentview(self):
-               with gtk_toolbox.gtk_lock():
-                       banner = hildonize.show_busy_banner_start(self._window, "Loading Recent History")
-               try:
-                       self._recentmodel.clear()
-                       self._isPopulated = True
-
-                       try:
-                               recentItems = self._backend.get_recent()
-                       except Exception, e:
-                               self._errorDisplay.push_exception_with_lock()
-                               self._isPopulated = False
-                               recentItems = []
-
-                       for personName, phoneNumber, date, action in recentItems:
-                               if not personName:
-                                       personName = "Unknown"
-                               date = abbrev_relative_date(date)
-                               prettyNumber = phoneNumber[2:] if phoneNumber.startswith("+1") else phoneNumber
-                               prettyNumber = make_pretty(prettyNumber)
-                               item = (prettyNumber, date, action.capitalize(), personName)
-                               with gtk_toolbox.gtk_lock():
-                                       self._recentmodel.append(item)
-               except Exception, e:
-                       self._errorDisplay.push_exception_with_lock()
-               finally:
-                       with gtk_toolbox.gtk_lock():
-                               hildonize.show_busy_banner_end(banner)
-
-               return False
-
-       def _on_recentview_row_activated(self, treeview, path, view_column):
-               try:
-                       model, itr = self._recentviewselection.get_selected()
-                       if not itr:
-                               return
-
-                       number = self._recentmodel.get_value(itr, self.NUMBER_IDX)
-                       number = make_ugly(number)
-                       contactPhoneNumbers = [("Phone", number)]
-                       description = self._recentmodel.get_value(itr, self.FROM_IDX)
-
-                       action, phoneNumber, message = self._phoneTypeSelector.run(
-                               contactPhoneNumbers,
-                               messages = (description, ),
-                               parent = self._window,
-                       )
-                       if action == PhoneTypeSelector.ACTION_CANCEL:
-                               return
-                       assert phoneNumber, "A lack of phone number exists"
-
-                       self.number_selected(action, phoneNumber, message)
-                       self._recentviewselection.unselect_all()
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-
-class MessagesView(object):
-
-       NUMBER_IDX = 0
-       DATE_IDX = 1
-       HEADER_IDX = 2
-       MESSAGE_IDX = 3
-       MESSAGES_IDX = 4
-
-       def __init__(self, widgetTree, backend, errorDisplay):
-               self._errorDisplay = errorDisplay
-               self._backend = backend
-
-               self._isPopulated = False
-               self._messagemodel = gtk.ListStore(
-                       gobject.TYPE_STRING, # number
-                       gobject.TYPE_STRING, # date
-                       gobject.TYPE_STRING, # header
-                       gobject.TYPE_STRING, # message
-                       object, # messages
-               )
-               self._messageview = widgetTree.get_widget("messages_view")
-               self._messageviewselection = None
-               self._onMessageviewRowActivatedId = 0
-
-               self._messageRenderer = gtk.CellRendererText()
-               self._messageRenderer.set_property("wrap-mode", pango.WRAP_WORD)
-               self._messageRenderer.set_property("wrap-width", 500)
-               self._messageColumn = gtk.TreeViewColumn("Messages")
-               self._messageColumn.pack_start(self._messageRenderer, expand=True)
-               self._messageColumn.add_attribute(self._messageRenderer, "markup", self.MESSAGE_IDX)
-               self._messageColumn.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
-
-               self._window = gtk_toolbox.find_parent_window(self._messageview)
-               self._phoneTypeSelector = PhoneTypeSelector(widgetTree, self._backend)
-
-               self._updateSink = gtk_toolbox.threaded_stage(
-                       gtk_toolbox.comap(
-                               self._idly_populate_messageview,
-                               gtk_toolbox.null_sink(),
-                       )
-               )
-
-       def enable(self):
-               assert self._backend.is_authed(), "Attempting to enable backend while not logged in"
-               self._messageview.set_model(self._messagemodel)
-               self._messageview.set_headers_visible(False)
-
-               self._messageview.append_column(self._messageColumn)
-               self._messageviewselection = self._messageview.get_selection()
-               self._messageviewselection.set_mode(gtk.SELECTION_SINGLE)
-
-               self._onMessageviewRowActivatedId = self._messageview.connect("row-activated", self._on_messageview_row_activated)
-
-       def disable(self):
-               self._messageview.disconnect(self._onMessageviewRowActivatedId)
-
-               self.clear()
-
-               self._messageview.remove_column(self._messageColumn)
-               self._messageview.set_model(None)
-
-       def number_selected(self, action, number, message):
-               """
-               @note Actual dial function is patched in later
-               """
-               raise NotImplementedError("Horrible unknown error has occurred")
-
-       def update(self, force = False):
-               if not force and self._isPopulated:
-                       return False
-               self._updateSink.send(())
-               return True
-
-       def clear(self):
-               self._isPopulated = False
-               self._messagemodel.clear()
-
-       @staticmethod
-       def name():
-               return "Messages"
-
-       def load_settings(self, config, section):
-               pass
-
-       def save_settings(self, config, section):
-               """
-               @note Thread Agnostic
-               """
-               pass
-
-       def _idly_populate_messageview(self):
-               with gtk_toolbox.gtk_lock():
-                       banner = hildonize.show_busy_banner_start(self._window, "Loading Messages")
-               try:
-                       self._messagemodel.clear()
-                       self._isPopulated = True
-
-                       try:
-                               messageItems = self._backend.get_messages()
-                       except Exception, e:
-                               self._errorDisplay.push_exception_with_lock()
-                               self._isPopulated = False
-                               messageItems = []
-
-                       for header, number, relativeDate, messages in messageItems:
-                               prettyNumber = number[2:] if number.startswith("+1") else number
-                               prettyNumber = make_pretty(prettyNumber)
-
-                               firstMessage = "<b>%s - %s</b> <i>(%s)</i>" % (header, prettyNumber, relativeDate)
-                               newMessages = [firstMessage]
-                               newMessages.extend(messages)
-
-                               number = make_ugly(number)
-
-                               row = (number, relativeDate, header, "\n".join(newMessages), newMessages)
-                               with gtk_toolbox.gtk_lock():
-                                       self._messagemodel.append(row)
-               except Exception, e:
-                       self._errorDisplay.push_exception_with_lock()
-               finally:
-                       with gtk_toolbox.gtk_lock():
-                               hildonize.show_busy_banner_end(banner)
-
-               return False
-
-       def _on_messageview_row_activated(self, treeview, path, view_column):
-               try:
-                       model, itr = self._messageviewselection.get_selected()
-                       if not itr:
-                               return
-
-                       contactPhoneNumbers = [("Phone", self._messagemodel.get_value(itr, self.NUMBER_IDX))]
-                       description = self._messagemodel.get_value(itr, self.MESSAGES_IDX)
-
-                       action, phoneNumber, message = self._phoneTypeSelector.run(
-                               contactPhoneNumbers,
-                               messages = description,
-                               parent = self._window,
-                       )
-                       if action == PhoneTypeSelector.ACTION_CANCEL:
-                               return
-                       assert phoneNumber, "A lock of phone number exists"
-
-                       self.number_selected(action, phoneNumber, message)
-                       self._messageviewselection.unselect_all()
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-
-class ContactsView(object):
-
-       def __init__(self, widgetTree, backend, errorDisplay):
-               self._errorDisplay = errorDisplay
-               self._backend = backend
-
-               self._addressBook = None
-               self._selectedComboIndex = 0
-               self._addressBookFactories = [null_backend.NullAddressBook()]
-
-               self._booksList = []
-               self._bookSelectionButton = widgetTree.get_widget("addressbookSelectButton")
-
-               self._isPopulated = False
-               self._contactsmodel = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING, gobject.TYPE_STRING)
-               self._contactsviewselection = None
-               self._contactsview = widgetTree.get_widget("contactsview")
-
-               self._contactColumn = gtk.TreeViewColumn("Contact")
-               displayContactSource = False
-               if displayContactSource:
-                       textrenderer = gtk.CellRendererText()
-                       self._contactColumn.pack_start(textrenderer, expand=False)
-                       self._contactColumn.add_attribute(textrenderer, 'text', 0)
-               textrenderer = gtk.CellRendererText()
-               hildonize.set_cell_thumb_selectable(textrenderer)
-               self._contactColumn.pack_start(textrenderer, expand=True)
-               self._contactColumn.add_attribute(textrenderer, 'text', 1)
-               textrenderer = gtk.CellRendererText()
-               self._contactColumn.pack_start(textrenderer, expand=True)
-               self._contactColumn.add_attribute(textrenderer, 'text', 4)
-               self._contactColumn.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
-               self._contactColumn.set_sort_column_id(1)
-               self._contactColumn.set_visible(True)
-
-               self._onContactsviewRowActivatedId = 0
-               self._onAddressbookButtonChangedId = 0
-               self._window = gtk_toolbox.find_parent_window(self._contactsview)
-               self._phoneTypeSelector = PhoneTypeSelector(widgetTree, self._backend)
-
-               self._updateSink = gtk_toolbox.threaded_stage(
-                       gtk_toolbox.comap(
-                               self._idly_populate_contactsview,
-                               gtk_toolbox.null_sink(),
-                       )
-               )
-
-       def enable(self):
-               assert self._backend.is_authed(), "Attempting to enable backend while not logged in"
-
-               self._contactsview.set_model(self._contactsmodel)
-               self._contactsview.append_column(self._contactColumn)
-               self._contactsviewselection = self._contactsview.get_selection()
-               self._contactsviewselection.set_mode(gtk.SELECTION_SINGLE)
-
-               del self._booksList[:]
-               for (factoryId, bookId), (factoryName, bookName) in self.get_addressbooks():
-                       if factoryName and bookName:
-                               entryName = "%s: %s" % (factoryName, bookName)
-                       elif factoryName:
-                               entryName = factoryName
-                       elif bookName:
-                               entryName = bookName
-                       else:
-                               entryName = "Bad name (%d)" % factoryId
-                       row = (str(factoryId), bookId, entryName)
-                       self._booksList.append(row)
-
-               self._onContactsviewRowActivatedId = self._contactsview.connect("row-activated", self._on_contactsview_row_activated)
-               self._onAddressbookButtonChangedId = self._bookSelectionButton.connect("clicked", self._on_addressbook_button_changed)
-
-               if len(self._booksList) <= self._selectedComboIndex:
-                       self._selectedComboIndex = 0
-               self._bookSelectionButton.set_label(self._booksList[self._selectedComboIndex][2])
-
-               selectedFactoryId = self._booksList[self._selectedComboIndex][0]
-               selectedBookId = self._booksList[self._selectedComboIndex][1]
-               self.open_addressbook(selectedFactoryId, selectedBookId)
-
-       def disable(self):
-               self._contactsview.disconnect(self._onContactsviewRowActivatedId)
-               self._bookSelectionButton.disconnect(self._onAddressbookButtonChangedId)
-
-               self.clear()
-
-               self._bookSelectionButton.set_label("")
-               self._contactsview.set_model(None)
-               self._contactsview.remove_column(self._contactColumn)
-
-       def number_selected(self, action, number, message):
-               """
-               @note Actual dial function is patched in later
-               """
-               raise NotImplementedError("Horrible unknown error has occurred")
-
-       def get_addressbooks(self):
-               """
-               @returns Iterable of ((Factory Id, Book Id), (Factory Name, Book Name))
-               """
-               for i, factory in enumerate(self._addressBookFactories):
-                       for bookFactory, bookId, bookName in factory.get_addressbooks():
-                               yield (str(i), bookId), (factory.factory_name(), bookName)
-
-       def open_addressbook(self, bookFactoryId, bookId):
-               bookFactoryIndex = int(bookFactoryId)
-               addressBook = self._addressBookFactories[bookFactoryIndex].open_addressbook(bookId)
-
-               forceUpdate = True if addressBook is not self._addressBook else False
-
-               self._addressBook = addressBook
-               self.update(force=forceUpdate)
-
-       def update(self, force = False):
-               if not force and self._isPopulated:
-                       return False
-               self._updateSink.send(())
-               return True
-
-       def clear(self):
-               self._isPopulated = False
-               self._contactsmodel.clear()
-               for factory in self._addressBookFactories:
-                       factory.clear_caches()
-               self._addressBook.clear_caches()
-
-       def append(self, book):
-               self._addressBookFactories.append(book)
-
-       def extend(self, books):
-               self._addressBookFactories.extend(books)
-
-       @staticmethod
-       def name():
-               return "Contacts"
-
-       def load_settings(self, config, sectionName):
-               try:
-                       self._selectedComboIndex = config.getint(sectionName, "selectedAddressbook")
-               except ConfigParser.NoOptionError:
-                       self._selectedComboIndex = 0
-
-       def save_settings(self, config, sectionName):
-               config.set(sectionName, "selectedAddressbook", str(self._selectedComboIndex))
-
-       def _idly_populate_contactsview(self):
-               with gtk_toolbox.gtk_lock():
-                       banner = hildonize.show_busy_banner_start(self._window, "Loading Contacts")
-               try:
-                       addressBook = None
-                       while addressBook is not self._addressBook:
-                               addressBook = self._addressBook
-                               with gtk_toolbox.gtk_lock():
-                                       self._contactsview.set_model(None)
-                                       self.clear()
-
-                               try:
-                                       contacts = addressBook.get_contacts()
-                               except Exception, e:
-                                       contacts = []
-                                       self._isPopulated = False
-                                       self._errorDisplay.push_exception_with_lock()
-                               for contactId, contactName in contacts:
-                                       contactType = (addressBook.contact_source_short_name(contactId), )
-                                       self._contactsmodel.append(contactType + (contactName, "", contactId) + ("", ))
-
-                               with gtk_toolbox.gtk_lock():
-                                       self._contactsview.set_model(self._contactsmodel)
-
-                       self._isPopulated = True
-               except Exception, e:
-                       self._errorDisplay.push_exception_with_lock()
-               finally:
-                       with gtk_toolbox.gtk_lock():
-                               hildonize.show_busy_banner_end(banner)
-               return False
-
-       def _on_addressbook_button_changed(self, *args, **kwds):
-               try:
-                       try:
-                               newSelectedComboIndex = hildonize.touch_selector(
-                                       self._window,
-                                       "Addressbook",
-                                       (("%s" % m[2]) for m in self._booksList),
-                                       self._selectedComboIndex,
-                               )
-                       except RuntimeError:
-                               return
-
-                       selectedFactoryId = self._booksList[newSelectedComboIndex][0]
-                       selectedBookId = self._booksList[newSelectedComboIndex][1]
-                       self.open_addressbook(selectedFactoryId, selectedBookId)
-                       self._selectedComboIndex = newSelectedComboIndex
-                       self._bookSelectionButton.set_label(self._booksList[self._selectedComboIndex][2])
-               except Exception, e:
-                       self._errorDisplay.push_exception()
-
-       def _on_contactsview_row_activated(self, treeview, path, view_column):
-               try:
-                       model, itr = self._contactsviewselection.get_selected()
-                       if not itr:
-                               return
-
-                       contactId = self._contactsmodel.get_value(itr, 3)
-                       contactName = self._contactsmodel.get_value(itr, 1)
-                       try:
-                               contactDetails = self._addressBook.get_contact_details(contactId)
-                       except Exception, e:
-                               contactDetails = []
-                               self._errorDisplay.push_exception()
-                       contactPhoneNumbers = [phoneNumber for phoneNumber in contactDetails]
-
-                       if len(contactPhoneNumbers) == 0:
-                               return
-
-                       action, phoneNumber, message = self._phoneTypeSelector.run(
-                               contactPhoneNumbers,
-                               messages = (contactName, ),
-                               parent = self._window,
-                       )
-                       if action == PhoneTypeSelector.ACTION_CANCEL:
-                               return
-                       assert phoneNumber, "A lack of phone number exists"
-
-                       self.number_selected(action, phoneNumber, message)
-                       self._contactsviewselection.unselect_all()
-               except Exception, e:
-                       self._errorDisplay.push_exception()
diff --git a/src/hildonize.py b/src/hildonize.py
deleted file mode 100755 (executable)
index 391b365..0000000
+++ /dev/null
@@ -1,646 +0,0 @@
-#!/usr/bin/env python
-
-
-import gobject
-import gtk
-import dbus
-
-
-class _NullHildonModule(object):
-       pass
-
-
-try:
-       import hildon as _hildon
-       hildon  = _hildon # Dumb but gets around pyflakiness
-except (ImportError, OSError):
-       hildon = _NullHildonModule
-
-
-IS_HILDON_SUPPORTED = hildon is not _NullHildonModule
-
-
-class _NullHildonProgram(object):
-
-       def add_window(self, window):
-               pass
-
-
-def _hildon_get_app_class():
-       return hildon.Program
-
-
-def _null_get_app_class():
-       return _NullHildonProgram
-
-
-try:
-       hildon.Program
-       get_app_class = _hildon_get_app_class
-except AttributeError:
-       get_app_class = _null_get_app_class
-
-
-def _hildon_set_application_title(window, title):
-       pass
-
-
-def _null_set_application_title(window, title):
-       window.set_title(title)
-
-
-if IS_HILDON_SUPPORTED:
-       set_application_title = _hildon_set_application_title
-else:
-       set_application_title = _null_set_application_title
-
-
-def _fremantle_hildonize_window(app, window):
-       oldWindow = window
-       newWindow = hildon.StackableWindow()
-       oldWindow.get_child().reparent(newWindow)
-       app.add_window(newWindow)
-       return newWindow
-
-
-def _hildon_hildonize_window(app, window):
-       oldWindow = window
-       newWindow = hildon.Window()
-       oldWindow.get_child().reparent(newWindow)
-       app.add_window(newWindow)
-       return newWindow
-
-
-def _null_hildonize_window(app, window):
-       return window
-
-
-try:
-       hildon.StackableWindow
-       hildonize_window = _fremantle_hildonize_window
-except AttributeError:
-       try:
-               hildon.Window
-               hildonize_window = _hildon_hildonize_window
-       except AttributeError:
-               hildonize_window = _null_hildonize_window
-
-
-def _fremantle_hildonize_menu(window, gtkMenu, buttons):
-       appMenu = hildon.AppMenu()
-       for button in buttons:
-               appMenu.append(button)
-       window.set_app_menu(appMenu)
-       gtkMenu.get_parent().remove(gtkMenu)
-       return appMenu
-
-
-def _hildon_hildonize_menu(window, gtkMenu, ignoredButtons):
-       hildonMenu = gtk.Menu()
-       for child in gtkMenu.get_children():
-               child.reparent(hildonMenu)
-       window.set_menu(hildonMenu)
-       gtkMenu.destroy()
-       return hildonMenu
-
-
-def _null_hildonize_menu(window, gtkMenu, ignoredButtons):
-       return gtkMenu
-
-
-try:
-       hildon.AppMenu
-       GTK_MENU_USED = False
-       IS_FREMANTLE_SUPPORTED = True
-       hildonize_menu = _fremantle_hildonize_menu
-except AttributeError:
-       GTK_MENU_USED = True
-       IS_FREMANTLE_SUPPORTED = False
-       if IS_HILDON_SUPPORTED:
-               hildonize_menu = _hildon_hildonize_menu
-       else:
-               hildonize_menu = _null_hildonize_menu
-
-
-def _hildon_set_cell_thumb_selectable(renderer):
-       renderer.set_property("scale", 1.5)
-
-
-def _null_set_cell_thumb_selectable(renderer):
-       pass
-
-
-if IS_HILDON_SUPPORTED:
-       set_cell_thumb_selectable = _hildon_set_cell_thumb_selectable
-else:
-       set_cell_thumb_selectable = _null_set_cell_thumb_selectable
-
-
-def _fremantle_show_information_banner(parent, message):
-       hildon.hildon_banner_show_information(parent, "", message)
-
-
-def _hildon_show_information_banner(parent, message):
-       hildon.hildon_banner_show_information(parent, None, message)
-
-
-def _null_show_information_banner(parent, message):
-       pass
-
-
-if IS_FREMANTLE_SUPPORTED:
-       show_information_banner = _fremantle_show_information_banner
-else:
-       try:
-               hildon.hildon_banner_show_information
-               show_information_banner = _hildon_show_information_banner
-       except AttributeError:
-               show_information_banner = _null_show_information_banner
-
-
-def _fremantle_show_busy_banner_start(parent, message):
-       hildon.hildon_gtk_window_set_progress_indicator(parent, True)
-       return parent
-
-
-def _fremantle_show_busy_banner_end(banner):
-       hildon.hildon_gtk_window_set_progress_indicator(banner, False)
-
-
-def _hildon_show_busy_banner_start(parent, message):
-       return hildon.hildon_banner_show_animation(parent, None, message)
-
-
-def _hildon_show_busy_banner_end(banner):
-       banner.destroy()
-
-
-def _null_show_busy_banner_start(parent, message):
-       return None
-
-
-def _null_show_busy_banner_end(banner):
-       assert banner is None
-
-
-try:
-       hildon.hildon_gtk_window_set_progress_indicator
-       show_busy_banner_start = _fremantle_show_busy_banner_start
-       show_busy_banner_end = _fremantle_show_busy_banner_end
-except AttributeError:
-       try:
-               hildon.hildon_banner_show_animation
-               show_busy_banner_start = _hildon_show_busy_banner_start
-               show_busy_banner_end = _hildon_show_busy_banner_end
-       except AttributeError:
-               show_busy_banner_start = _null_show_busy_banner_start
-               show_busy_banner_end = _null_show_busy_banner_end
-
-
-def _hildon_hildonize_text_entry(textEntry):
-       textEntry.set_property('hildon-input-mode', 7)
-
-
-def _null_hildonize_text_entry(textEntry):
-       pass
-
-
-if IS_HILDON_SUPPORTED:
-       hildonize_text_entry = _hildon_hildonize_text_entry
-else:
-       hildonize_text_entry = _null_hildonize_text_entry
-
-
-def _hildon_mark_window_rotatable(window):
-       # gtk documentation is unclear whether this does a "=" or a "|="
-       window.set_flags(hildon.HILDON_PORTRAIT_MODE_SUPPORT)
-
-
-def _null_mark_window_rotatable(window):
-       pass
-
-
-try:
-       hildon.HILDON_PORTRAIT_MODE_SUPPORT
-       mark_window_rotatable = _hildon_mark_window_rotatable
-except AttributeError:
-       mark_window_rotatable = _null_mark_window_rotatable
-
-
-def _hildon_window_to_portrait(window):
-       # gtk documentation is unclear whether this does a "=" or a "|="
-       window.set_flags(hildon.HILDON_PORTRAIT_MODE_SUPPORT)
-
-
-def _hildon_window_to_landscape(window):
-       # gtk documentation is unclear whether this does a "=" or a "&= ~"
-       window.unset_flags(hildon.HILDON_PORTRAIT_MODE_REQUEST)
-
-
-def _null_window_to_portrait(window):
-       pass
-
-
-def _null_window_to_landscape(window):
-       pass
-
-
-try:
-       hildon.HILDON_PORTRAIT_MODE_SUPPORT
-       hildon.HILDON_PORTRAIT_MODE_REQUEST
-
-       window_to_portrait = _hildon_window_to_portrait
-       window_to_landscape = _hildon_window_to_landscape
-except AttributeError:
-       window_to_portrait = _null_window_to_portrait
-       window_to_landscape = _null_window_to_landscape
-
-
-def get_device_orientation():
-       bus = dbus.SystemBus()
-       try:
-               rawMceRequest = bus.get_object("com.nokia.mce", "/com/nokia/mce/request")
-               mceRequest = dbus.Interface(rawMceRequest, dbus_interface="com.nokia.mce.request")
-               orientation, standState, faceState, xAxis, yAxis, zAxis = mceRequest.get_device_orientation()
-       except dbus.exception.DBusException:
-               # catching for documentation purposes that when a system doesn't
-               # support this, this is what to expect
-               raise
-
-       if orientation == "":
-               return gtk.ORIENTATION_HORIZONTAL
-       elif orientation == "":
-               return gtk.ORIENTATION_VERTICAL
-       else:
-               raise RuntimeError("Unknown orientation: %s" % orientation)
-
-
-def _hildon_hildonize_password_entry(textEntry):
-       textEntry.set_property('hildon-input-mode', 7 | (1 << 29))
-
-
-def _null_hildonize_password_entry(textEntry):
-       pass
-
-
-if IS_HILDON_SUPPORTED:
-       hildonize_password_entry = _hildon_hildonize_password_entry
-else:
-       hildonize_password_entry = _null_hildonize_password_entry
-
-
-def _hildon_hildonize_combo_entry(comboEntry):
-       comboEntry.set_property('hildon-input-mode', 1 << 4)
-
-
-def _null_hildonize_combo_entry(textEntry):
-       pass
-
-
-if IS_HILDON_SUPPORTED:
-       hildonize_combo_entry = _hildon_hildonize_combo_entry
-else:
-       hildonize_combo_entry = _null_hildonize_combo_entry
-
-
-def _fremantle_hildonize_scrollwindow(scrolledWindow):
-       pannableWindow = hildon.PannableArea()
-
-       child = scrolledWindow.get_child()
-       scrolledWindow.remove(child)
-       pannableWindow.add(child)
-
-       parent = scrolledWindow.get_parent()
-       parent.remove(scrolledWindow)
-       parent.add(pannableWindow)
-
-       return pannableWindow
-
-
-def _hildon_hildonize_scrollwindow(scrolledWindow):
-       hildon.hildon_helper_set_thumb_scrollbar(scrolledWindow, True)
-       return scrolledWindow
-
-
-def _null_hildonize_scrollwindow(scrolledWindow):
-       return scrolledWindow
-
-
-try:
-       hildon.PannableArea
-       hildonize_scrollwindow = _fremantle_hildonize_scrollwindow
-       hildonize_scrollwindow_with_viewport = _hildon_hildonize_scrollwindow
-except AttributeError:
-       try:
-               hildon.hildon_helper_set_thumb_scrollbar
-               hildonize_scrollwindow = _hildon_hildonize_scrollwindow
-               hildonize_scrollwindow_with_viewport = _hildon_hildonize_scrollwindow
-       except AttributeError:
-               hildonize_scrollwindow = _null_hildonize_scrollwindow
-               hildonize_scrollwindow_with_viewport = _null_hildonize_scrollwindow
-
-
-def _hildon_request_number(parent, title, range, default):
-       spinner = hildon.NumberEditor(*range)
-       spinner.set_value(default)
-
-       dialog = gtk.Dialog(
-               title,
-               parent,
-               gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
-               (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
-       )
-       dialog.set_default_response(gtk.RESPONSE_CANCEL)
-       dialog.get_child().add(spinner)
-
-       try:
-               dialog.show_all()
-               response = dialog.run()
-       finally:
-               dialog.hide()
-
-       if response == gtk.RESPONSE_OK:
-               return spinner.get_value()
-       elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
-               raise RuntimeError("User cancelled request")
-       else:
-               raise RuntimeError("Unrecognized response %r", response)
-
-
-def _null_request_number(parent, title, range, default):
-       adjustment = gtk.Adjustment(default, range[0], range[1], 1, 5, 0)
-       spinner = gtk.SpinButton(adjustment, 0, 0)
-       spinner.set_wrap(False)
-
-       dialog = gtk.Dialog(
-               title,
-               parent,
-               gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
-               (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
-       )
-       dialog.set_default_response(gtk.RESPONSE_CANCEL)
-       dialog.get_child().add(spinner)
-
-       try:
-               dialog.show_all()
-               response = dialog.run()
-       finally:
-               dialog.hide()
-
-       if response == gtk.RESPONSE_OK:
-               return spinner.get_value_as_int()
-       elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
-               raise RuntimeError("User cancelled request")
-       else:
-               raise RuntimeError("Unrecognized response %r", response)
-
-
-try:
-       hildon.NumberEditor # TODO deprecated in fremantle
-       request_number = _hildon_request_number
-except AttributeError:
-       request_number = _null_request_number
-
-
-def _hildon_touch_selector(parent, title, items, defaultIndex):
-       model = gtk.ListStore(gobject.TYPE_STRING)
-       for item in items:
-               model.append((item, ))
-
-       selector = hildon.TouchSelector()
-       selector.append_text_column(model, True)
-       selector.set_column_selection_mode(hildon.TOUCH_SELECTOR_SELECTION_MODE_SINGLE)
-       selector.set_active(0, defaultIndex)
-
-       dialog = hildon.PickerDialog(parent)
-       dialog.set_selector(selector)
-
-       try:
-               dialog.show_all()
-               response = dialog.run()
-       finally:
-               dialog.hide()
-
-       if response == gtk.RESPONSE_OK:
-               return selector.get_active(0)
-       elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
-               raise RuntimeError("User cancelled request")
-       else:
-               raise RuntimeError("Unrecognized response %r", response)
-
-
-def _on_null_touch_selector_activated(treeView, path, column, dialog):
-       dialog.response(gtk.RESPONSE_OK)
-
-
-def _null_touch_selector(parent, title, items, defaultIndex = -1):
-       model = gtk.ListStore(gobject.TYPE_STRING)
-       for item in items:
-               model.append((item, ))
-
-       cell = gtk.CellRendererText()
-       set_cell_thumb_selectable(cell)
-       column = gtk.TreeViewColumn(title)
-       column .pack_start(cell, expand=True)
-       column.add_attribute(cell, "text", 0)
-
-       treeView = gtk.TreeView()
-       treeView.set_model(model)
-       treeView.append_column(column)
-       selection = treeView.get_selection()
-       selection.set_mode(gtk.SELECTION_SINGLE)
-       if 0 < defaultIndex:
-               selection.select_path((defaultIndex, ))
-
-       scrolledWin = gtk.ScrolledWindow()
-       scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-       scrolledWin.add(treeView)
-       hildonize_scrollwindow(scrolledWin)
-
-       dialog = gtk.Dialog(
-               title,
-               parent,
-               gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
-               (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
-       )
-       dialog.set_default_response(gtk.RESPONSE_CANCEL)
-       dialog.get_child().add(scrolledWin)
-       parentSize = parent.get_size()
-       dialog.resize(parentSize[0], max(parentSize[1]-100, 100))
-       treeView.connect("row-activated", _on_null_touch_selector_activated, dialog)
-
-       try:
-               dialog.show_all()
-               response = dialog.run()
-       finally:
-               dialog.hide()
-
-       if response == gtk.RESPONSE_OK:
-               model, itr = selection.get_selected()
-               if itr is None:
-                       raise RuntimeError("No selection made")
-               return model.get_path(itr)[0]
-       elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
-               raise RuntimeError("User cancelled request")
-       else:
-               raise RuntimeError("Unrecognized response %r", response)
-
-
-try:
-       hildon.PickerDialog
-       hildon.TouchSelector
-       touch_selector = _hildon_touch_selector
-except AttributeError:
-       touch_selector = _null_touch_selector
-
-
-def _hildon_touch_selector_entry(parent, title, items, defaultItem):
-       # Got a segfault when using append_text_column with TouchSelectorEntry, so using this way
-       selector = hildon.hildon_touch_selector_entry_new_text()
-       defaultIndex = -1
-       for i, item in enumerate(items):
-               selector.append_text(item)
-               if item == defaultItem:
-                       defaultIndex = i
-
-       dialog = hildon.PickerDialog(parent)
-       dialog.set_selector(selector)
-
-       if 0 < defaultIndex:
-               selector.set_active(0, defaultIndex)
-       else:
-               selector.get_entry().set_text(defaultItem)
-
-       try:
-               dialog.show_all()
-               response = dialog.run()
-       finally:
-               dialog.hide()
-
-       if response == gtk.RESPONSE_OK:
-               selectedIndex = selector.get_active(0)
-               return selector.get_entry().get_text()
-       elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
-               raise RuntimeError("User cancelled request")
-       else:
-               raise RuntimeError("Unrecognized response %r", response)
-
-
-def _on_null_touch_selector_entry_entry_activated(entry, dialog, customEntry, result):
-       dialog.response(gtk.RESPONSE_OK)
-       result.append(customEntry.get_text())
-
-
-def _on_null_touch_selector_entry_tree_activated(treeView, path, column, dialog, selection, result):
-       dialog.response(gtk.RESPONSE_OK)
-       model, itr = selection.get_selected()
-       if itr is not None:
-               result.append(model.get_value(itr, 0))
-
-
-def _null_touch_selector_entry(parent, title, items, defaultItem):
-       model = gtk.ListStore(gobject.TYPE_STRING)
-       defaultIndex = -1
-       for i, item in enumerate(items):
-               model.append((item, ))
-               if item == defaultItem:
-                       defaultIndex = i
-
-       cell = gtk.CellRendererText()
-       set_cell_thumb_selectable(cell)
-       column = gtk.TreeViewColumn(title)
-       column .pack_start(cell, expand=True)
-       column.add_attribute(cell, "text", 0)
-
-       treeView = gtk.TreeView()
-       treeView.set_model(model)
-       treeView.append_column(column)
-       selection = treeView.get_selection()
-       selection.set_mode(gtk.SELECTION_SINGLE)
-
-       scrolledWin = gtk.ScrolledWindow()
-       scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-       scrolledWin.add(treeView)
-       hildonize_scrollwindow(scrolledWin)
-
-       customEntry = gtk.Entry()
-
-       layout = gtk.VBox()
-       layout.pack_start(customEntry, expand=False)
-       layout.pack_start(scrolledWin)
-
-       dialog = gtk.Dialog(
-               title,
-               parent,
-               gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
-               (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
-       )
-       dialog.set_default_response(gtk.RESPONSE_CANCEL)
-       dialog.get_child().add(layout)
-       parentSize = parent.get_size()
-       dialog.resize(parentSize[0], max(parentSize[1]-100, 100))
-
-       if 0 < defaultIndex:
-               selection.select_path((defaultIndex, ))
-       else:
-               customEntry.set_text(defaultItem)
-       result = []
-       customEntry.connect("activate", _on_null_touch_selector_entry_entry_activated, dialog, customEntry, result)
-       treeView.connect("row-activated", _on_null_touch_selector_entry_tree_activated, dialog, selection, result)
-
-       try:
-               dialog.show_all()
-               response = dialog.run()
-       finally:
-               dialog.hide()
-
-       if response == gtk.RESPONSE_OK:
-               model, itr = selection.get_selected()
-               if len(result) != 1:
-                       raise RuntimeError("No selection made")
-               else:
-                       return result[0]
-       elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
-               raise RuntimeError("User cancelled request")
-       else:
-               raise RuntimeError("Unrecognized response %r", response)
-
-
-try:
-       hildon.PickerDialog
-       hildon.TouchSelectorEntry
-       touch_selector_entry = _hildon_touch_selector_entry
-except AttributeError:
-       touch_selector_entry = _null_touch_selector_entry
-
-
-if __name__ == "__main__":
-       app = get_app_class()()
-
-       label = gtk.Label("Hello World from a Label!")
-
-       win = gtk.Window()
-       win.add(label)
-       win = hildonize_window(app, win)
-       if False:
-               print touch_selector(win, "Test", ["A", "B", "C", "D"], 2)
-       if True:
-               print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "C")
-               print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "Blah")
-       if False:
-               import pprint
-               name, value = "", ""
-               goodLocals = [
-                       (name, value) for (name, value) in locals().iteritems()
-                       if not name.startswith("_")
-               ]
-               pprint.pprint(goodLocals)
-       if False:
-               import time
-               show_information_banner(win, "Hello World")
-               time.sleep(5)
-       if False:
-               import time
-               banner = show_busy_banner_start(win, "Hello World")
-               time.sleep(5)
-               show_busy_banner_end(banner)
diff --git a/src/led_handler.py b/src/led_handler.py
deleted file mode 100755 (executable)
index 211036e..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env python
-
-import dbus
-
-
-class LedHandler(object):
-
-       def __init__(self):
-               self._bus = dbus.SystemBus()
-               self._rawMceRequest = self._bus.get_object("com.nokia.mce", "/com/nokia/mce/request")
-               self._mceRequest = dbus.Interface(self._rawMceRequest, dbus_interface="com.nokia.mce.request")
-
-               self._ledPattern = "PatternCommunicationChat"
-
-       def on(self):
-               self._mceRequest.req_led_pattern_activate(self._ledPattern)
-
-       def off(self):
-               self._mceRequest.req_led_pattern_deactivate(self._ledPattern)
-
-
-if __name__ == "__main__":
-       leds = LedHandler()
-       leds.off()
diff --git a/src/null_views.py b/src/null_views.py
deleted file mode 100644 (file)
index 41d759a..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-#!/usr/bin/python2.5
-
-"""
-DialCentral - Front end for Google's Grand Central service.
-Copyright (C) 2008  Mark Bergman bergman AT merctech DOT com
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation; either
-version 2.1 of the License, or (at your option) any later version.
-
-This library 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
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-"""
-
-import gobject
-import gtk
-
-
-class Dialpad(object):
-
-       def __init__(self, widgetTree):
-               self._numberdisplay = widgetTree.get_widget("numberdisplay")
-               self._dialButton = widgetTree.get_widget("dial")
-               self._smsButton = widgetTree.get_widget("sms")
-
-       def enable(self):
-               self._dialButton.set_sensitive(False)
-               self._smsButton.set_sensitive(False)
-
-       def disable(self):
-               self._dialButton.set_sensitive(True)
-               self._smsButton.set_sensitive(True)
-
-       @staticmethod
-       def name():
-               return "Dialpad"
-
-       def load_settings(self, config, sectionName):
-               pass
-
-       def save_settings(self, config, sectionName):
-               """
-               @note Thread Agnostic
-               """
-               pass
-
-
-class AccountInfo(object):
-
-       def __init__(self, widgetTree):
-               self._callbackList = gtk.ListStore(gobject.TYPE_STRING)
-               self._accountViewNumberDisplay = widgetTree.get_widget("gcnumber_display")
-               self._callbackSelectButton = widgetTree.get_widget("callbackSelectButton")
-               self._clearCookiesButton = widgetTree.get_widget("clearcookies")
-
-               self._notifyCheckbox = widgetTree.get_widget("notifyCheckbox")
-               self._minutesEntryButton = widgetTree.get_widget("minutesEntryButton")
-               self._missedCheckbox = widgetTree.get_widget("missedCheckbox")
-               self._voicemailCheckbox = widgetTree.get_widget("voicemailCheckbox")
-               self._smsCheckbox = widgetTree.get_widget("smsCheckbox")
-
-       def enable(self):
-               self._callbackSelectButton.set_sensitive(False)
-               self._clearCookiesButton.set_sensitive(False)
-
-               self._notifyCheckbox.set_sensitive(False)
-               self._minutesEntryButton.set_sensitive(False)
-               self._missedCheckbox.set_sensitive(False)
-               self._voicemailCheckbox.set_sensitive(False)
-               self._smsCheckbox.set_sensitive(False)
-
-               self._accountViewNumberDisplay.set_label("")
-
-       def disable(self):
-               self._callbackSelectButton.set_sensitive(True)
-               self._clearCookiesButton.set_sensitive(True)
-
-               self._notifyCheckbox.set_sensitive(True)
-               self._minutesEntryButton.set_sensitive(True)
-               self._missedCheckbox.set_sensitive(True)
-               self._voicemailCheckbox.set_sensitive(True)
-               self._smsCheckbox.set_sensitive(True)
-
-       @staticmethod
-       def update(force = False):
-               return False
-
-       @staticmethod
-       def clear():
-               pass
-
-       @staticmethod
-       def name():
-               return "Account Info"
-
-       def load_settings(self, config, sectionName):
-               pass
-
-       def save_settings(self, config, sectionName):
-               """
-               @note Thread Agnostic
-               """
-               pass
-
-
-class RecentCallsView(object):
-
-       def __init__(self, widgetTree):
-               pass
-
-       def enable(self):
-               pass
-
-       def disable(self):
-               pass
-
-       def update(self, force = False):
-               return False
-
-       @staticmethod
-       def clear():
-               pass
-
-       @staticmethod
-       def name():
-               return "Recent Calls"
-
-       def load_settings(self, config, sectionName):
-               pass
-
-       def save_settings(self, config, sectionName):
-               """
-               @note Thread Agnostic
-               """
-               pass
-
-
-class MessagesView(object):
-
-       def __init__(self, widgetTree):
-               pass
-
-       def enable(self):
-               pass
-
-       def disable(self):
-               pass
-
-       def update(self, force = False):
-               return False
-
-       @staticmethod
-       def clear():
-               pass
-
-       @staticmethod
-       def name():
-               return "Messages"
-
-       def load_settings(self, config, sectionName):
-               pass
-
-       def save_settings(self, config, sectionName):
-               """
-               @note Thread Agnostic
-               """
-               pass
-
-
-class ContactsView(object):
-
-       def __init__(self, widgetTree):
-               self._bookSelectionButton = widgetTree.get_widget("addressbookSelectButton")
-
-       def enable(self):
-               self._bookSelectionButton.set_sensitive(False)
-
-       def disable(self):
-               self._bookSelectionButton.set_sensitive(True)
-
-       def update(self, force = False):
-               return False
-
-       @staticmethod
-       def clear():
-               pass
-
-       @staticmethod
-       def name():
-               return "Contacts"
-
-       def load_settings(self, config, sectionName):
-               pass
-
-       def save_settings(self, config, sectionName):
-               """
-               @note Thread Agnostic
-               """
-               pass
diff --git a/support/dialcentral.desktop b/support/dialcentral.desktop
deleted file mode 100644 (file)
index ce28c88..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-[Desktop Entry]
-Encoding=UTF-8
-Version=1.0
-Type=Application
-Name=DialCentral
-Exec=/usr/bin/run-standalone.sh /usr/bin/dialcentral.py
-Icon=dialcentral
diff --git a/tests/basic_data/basic.csv b/tests/basic_data/basic.csv
deleted file mode 100644 (file)
index 6ffd844..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-familyname,phone,addr1,addr2,addr3,addr4,name1,name2,name3,name4\r
-"Last, First","555-123-4567","1234 Foo St","Austin, Texas 78727","","","First <name@domain.com>"\r
diff --git a/tests/basic_data/empty.csv b/tests/basic_data/empty.csv
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/tests/basic_data/google.csv b/tests/basic_data/google.csv
deleted file mode 100644 (file)
index 3fa4d3e..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-Name,E-mail,Notes,Section 1 - Description,Section 1 - Email,Section 1 - IM,Section 1 - Phone,Section 1 - Mobile,Section 1 - Pager,Section 1 - Fax,Section 1 - Company,Section 1 - Title,Section 1 - Other,Section 1 - Address,Section 2 - Description,Section 2 - Email,Section 2 - IM,Section 2 - Phone,Section 2 - Mobile,Section 2 - Pager,Section 2 - Fax,Section 2 - Company,Section 2 - Title,Section 2 - Other,Section 2 - Address,Section 3 - Description,Section 3 - Email,Section 3 - IM,Section 3 - Phone,Section 3 - Mobile,Section 3 - Pager,Section 3 - Fax,Section 3 - Company,Section 3 - Title,Section 3 - Other,Section 3 - Address\r
-First Last,name@domain.com,"Categories: Others\r
-\r
-\r
-Categories: Others",Other,name2@domain.com,,,,,,,,,,Personal,name3@domain.com; name4@domain.com; name5@domain.com; name6@domain.com,,17471234567,5551234567,,,,,,\r
-First1 Last,,"Categories: Friends\r
-",Personal,,,,5557654321,,,,,,\r
diff --git a/tests/basic_data/grandcentral.csv b/tests/basic_data/grandcentral.csv
deleted file mode 100644 (file)
index 4808cf2..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-Name,E-mail Address,Categories,Company,Job Title,Home Address,Home Phone,Mobile Phone,Business Phone,GrandCentral,Suffix,Title,Initials,Web Page,Notes\r
-First Last,,Family,,,1234567 Foo St Austn Tx 78727,5559983254,5554023626,5559988899,,,,,,\r
-First1 Last,,Others,,,,5556835460,,,,,,,,\r
diff --git a/tests/basic_data/settings.ini b/tests/basic_data/settings.ini
deleted file mode 100644 (file)
index d9a6c81..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-[1 - Contacts]
-
-[2 - Account Info]
-callback = 
-
-[1 - Recent Calls]
-
-[2 - Messages]
-
-[0 - Messages]
-
-[1 - Messages]
-
-[2 - Dialpad]
-
-[2 - Contacts]
-
-[0 - Recent Calls]
-
-[DialCentral]
-active = 0
-bin_blob_0 = 
-bin_blob_1 = 
-
-[1 - Account Info]
-callback = 
-
-[1 - Dialpad]
-
-[0 - Dialpad]
-
-[0 - Account Info]
-
-[0 - Contacts]
-
-[2 - Recent Calls]
-
diff --git a/tests/dummy_hildon/__init__.py b/tests/dummy_hildon/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/tests/dummy_hildon/hildon.py b/tests/dummy_hildon/hildon.py
deleted file mode 100644 (file)
index 331e979..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-import gobject
-import gtk
-
-class FileChooserDialog(gtk.FileChooserDialog):
-       """
-       @bug The buttons currently don't do anything
-       """
-
-       def __init__(self, *args, **kwds):
-               super(FileChooserDialog, self).__init__(*args, **kwds)
-               self.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
-               self.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
-
-
-class Program(object):
-
-       def add_window(self, window):
-               pass
-
-
-class Window(gtk.Window, object):
-
-       def __init__(self):
-               super(Window, self).__init__(gtk.WINDOW_TOPLEVEL)
-               self.set_default_size(700, 500)
-
-       def set_menu(self, menu):
-               self._hildonMenu = menu
-
-
-gobject.type_register(Window)
-
-
-def hildon_helper_set_thumb_scrollbar(widget, value):
-       pass
diff --git a/tests/gc_samples/__init__.py b/tests/gc_samples/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/tests/gc_samples/dump_cookies.py b/tests/gc_samples/dump_cookies.py
deleted file mode 100755 (executable)
index 810a03b..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/usr/bin/env python
-
-import os
-import urllib
-import urllib2
-import traceback
-import warnings
-
-import sys
-sys.path.append("../../src")
-
-import browser_emu
-import gc_backend
-
-# Create Browser
-browser = browser_emu.MozillaEmulator(1)
-cookieFile = os.path.join(".", ".gc_cookies.txt")
-browser.cookies.filename = cookieFile
-
-# Login
-username = sys.argv[1]
-password = sys.argv[2]
-
-loginPostData = urllib.urlencode({
-       'Email' : username,
-       'Passwd' : password,
-       'service': "grandcentral",
-       "ltmpl": "mobile",
-       "btmpl": "mobile",
-       "PersistentCookie": "yes",
-})
-
-try:
-       loginSuccessOrFailurePage = browser.download(gc_backend.GCDialer._loginURL, loginPostData)
-except urllib2.URLError, e:
-       warnings.warn(traceback.format_exc())
-       raise RuntimeError("%s is not accesible" % gc_backend.GCDialer._loginURL)
-
-forwardPage = browser.download(gc_backend.GCDialer._forwardselectURL)
-
-tokenGroup = gc_backend.GCDialer._accessTokenRe.search(forwardPage)
-if tokenGroup is None:
-       print forwardPage
-       raise RuntimeError("Could not extract authentication token from GrandCentral")
-token = tokenGroup.group(1)
-
-
-with open("cookies.txt", "w") as f:
-       f.writelines(
-               "%s: %s\n" % (c.name, c.value)
-               for c in browser.cookies
-       )
diff --git a/tests/gc_samples/generate_gc_samples.py b/tests/gc_samples/generate_gc_samples.py
deleted file mode 100755 (executable)
index 0608ffd..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/usr/bin/env python
-
-import os
-import urllib
-import urllib2
-import traceback
-import warnings
-
-import sys
-sys.path.append("../../src")
-
-import browser_emu
-import gc_backend
-
-webpages = [
-       ("forward", gc_backend.GCDialer._forwardselectURL),
-       ("login", gc_backend.GCDialer._loginURL),
-       ("setforward", gc_backend.GCDialer._setforwardURL),
-       ("clicktocall", gc_backend.GCDialer._clicktocallURL),
-       ("recent", gc_backend.GCDialer._inboxallURL),
-       ("contacts", gc_backend.GCDialer._contactsURL),
-]
-
-
-# Create Browser
-browser = browser_emu.MozillaEmulator(1)
-cookieFile = os.path.join(".", ".gc_cookies.txt")
-browser.cookies.filename = cookieFile
-
-# Get Pages
-for name, url in webpages:
-       try:
-               page = browser.download(url)
-       except StandardError, e:
-               print e.message
-               continue
-       with open("not_loggedin_%s.txt" % name, "w") as f:
-               f.write(page)
-
-# Login
-username = sys.argv[1]
-password = sys.argv[2]
-
-loginPostData = urllib.urlencode({
-       'username' : username,
-       'password' : password,
-})
-
-try:
-       loginSuccessOrFailurePage = browser.download(gc_backend.GCDialer._loginURL, loginPostData)
-except urllib2.URLError, e:
-       warnings.warn(traceback.format_exc())
-       raise RuntimeError("%s is not accesible" % gc_backend.GCDialer._loginURL)
-
-forwardPage = browser.download(gc_backend.GCDialer._forwardselectURL)
-
-tokenGroup = gc_backend.GCDialer._accessTokenRe.search(forwardPage)
-if tokenGroup is None:
-       print "="*60
-       print forwardPage
-       print "="*60
-       raise RuntimeError("Could not extract authentication token from GrandCentral")
-token = tokenGroup.group(1)
-
-# Get Pages
-for name, url in webpages:
-       try:
-               page = browser.download(url)
-       except StandardError, e:
-               warnings.warn(traceback.format_exc())
-               continue
-       print "Writing to file"
-       with open("loggedin_%s.txt" % name, "w") as f:
-               f.write(page)
diff --git a/tests/test_file_backend.py b/tests/test_file_backend.py
deleted file mode 100644 (file)
index edd6c85..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-from __future__ import with_statement
-
-import os
-import warnings
-
-import test_utils
-
-import sys
-sys.path.append("../src")
-
-import file_backend
-
-
-def test_factory():
-       warnings.simplefilter("always")
-       try:
-               csvPath = os.path.join(os.path.dirname(__file__), "basic_data")
-               factory = file_backend.FilesystemAddressBookFactory(csvPath)
-               assert factory.factory_name() == "File"
-               abooks = list(factory.get_addressbooks())
-               abooks.sort()
-               assert len(abooks) == 4
-               abookNames = [abook[2] for abook in abooks]
-               assert abookNames == ["basic", "empty", "google", "grandcentral"], "%s" % abookNames
-
-               for abook_factory, abookId, abookName in abooks:
-                       abook = abook_factory.open_addressbook(abookId)
-                       assert isinstance(abook, file_backend.CsvAddressBook)
-       finally:
-               warnings.resetwarnings()
-
-
-def test_nonexistent_csv():
-       warnings.simplefilter("always")
-       try:
-               csvPath = os.path.join(os.path.dirname(__file__), "basic_data", "nonexistent.csv")
-               abook = file_backend.CsvAddressBook(csvPath)
-
-               assert abook.factory_name() == "csv"
-
-               contacts = list(abook.get_contacts())
-               assert len(contacts) == 0
-       finally:
-               warnings.resetwarnings()
-
-
-def test_empty_csv():
-       warnings.simplefilter("always")
-       try:
-               csvPath = os.path.join(os.path.dirname(__file__), "basic_data", "empty.csv")
-               abook = file_backend.CsvAddressBook(csvPath)
-
-               assert abook.factory_name() == "csv"
-
-               contacts = list(abook.get_contacts())
-               assert len(contacts) == 0
-       finally:
-               warnings.resetwarnings()
-
-
-def test_basic_csv():
-       warnings.simplefilter("always")
-       try:
-               csvPath = os.path.join(os.path.dirname(__file__), "basic_data", "basic.csv")
-               abook = file_backend.CsvAddressBook(csvPath)
-
-               assert abook.factory_name() == "csv"
-
-               contacts = list(abook.get_contacts())
-               contacts.sort()
-               assert len(contacts) == 1
-
-               contactId, contactName = contacts[0]
-               assert contactName == "Last, First"
-               assert abook.contact_source_short_name(contactId) == "csv"
-
-               details = list(abook.get_contact_details(contactId))
-               assert len(details) == 1
-               details.sort()
-               assert details == [("phone", "555-123-4567")], "%s" % details
-       finally:
-               warnings.resetwarnings()
-
-
-def test_google_csv():
-       warnings.simplefilter("always")
-       try:
-               csvPath = os.path.join(os.path.dirname(__file__), "basic_data", "google.csv")
-               abook = file_backend.CsvAddressBook(csvPath)
-
-               assert abook.factory_name() == "csv"
-
-               contacts = list(abook.get_contacts())
-               contacts.sort()
-               assert len(contacts) == 2
-
-               contactId, contactName = contacts[0]
-               assert contactName == "First Last"
-               assert abook.contact_source_short_name(contactId) == "csv"
-
-               details = list(abook.get_contact_details(contactId))
-               assert len(details) == 2
-               details.sort()
-               assert details == [
-                       ("Section 2 - Mobile", "5551234567"),
-                       ("Section 2 - Phone", "17471234567"),
-               ], "%s" % details
-
-               contactId, contactName = contacts[1]
-               assert contactName == "First1 Last"
-               assert abook.contact_source_short_name(contactId) == "csv"
-
-               details = list(abook.get_contact_details(contactId))
-               assert len(details) == 1
-               details.sort()
-               assert details == [("Section 1 - Mobile", "5557654321")], "%s" % details
-       finally:
-               warnings.resetwarnings()
-
-
-def test_grandcentral_csv():
-       warnings.simplefilter("always")
-       try:
-               csvPath = os.path.join(os.path.dirname(__file__), "basic_data", "grandcentral.csv")
-               abook = file_backend.CsvAddressBook(csvPath)
-
-               assert abook.factory_name() == "csv"
-
-               contacts = list(abook.get_contacts())
-               contacts.sort()
-               assert len(contacts) == 2
-
-               contactId, contactName = contacts[0]
-               assert contactName == "First Last"
-               assert abook.contact_source_short_name(contactId) == "csv"
-
-               details = list(abook.get_contact_details(contactId))
-               assert len(details) == 3
-               details.sort()
-               assert details == [
-                       ("Business Phone", "5559988899"),
-                       ("Home Phone", "5559983254"),
-                       ("Mobile Phone", "5554023626"),
-               ], "%s" % details
-
-               contactId, contactName = contacts[1]
-               assert contactName == "First1 Last"
-               assert abook.contact_source_short_name(contactId) == "csv"
-
-               details = list(abook.get_contact_details(contactId))
-               assert len(details) == 1
-               details.sort()
-               assert details == [("Home Phone", "5556835460")], "%s" % details
-       finally:
-               warnings.resetwarnings()
diff --git a/tests/test_gc_backend.py b/tests/test_gc_backend.py
deleted file mode 100644 (file)
index e60e777..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-from __future__ import with_statement
-
-import os
-import warnings
-import cookielib
-
-import test_utils
-
-import sys
-sys.path.append("../src")
-
-import gc_backend
-
-
-def generate_mock(cookiesSucceed, username, password):
-
-       class MockModule(object):
-
-               class MozillaEmulator(object):
-
-                       def __init__(self, trycount = 1):
-                               self.cookies = cookielib.LWPCookieJar()
-                               self.trycount = trycount
-
-                       def download(self, url,
-                                       postdata = None, extraheaders = None, forbid_redirect = False,
-                                       trycount = None, only_head = False,
-                               ):
-                               return ""
-
-       return MockModule
-
-
-def test_not_logged_in():
-       correctUsername, correctPassword = "", ""
-       MockBrowserModule = generate_mock(False, correctUsername, correctPassword)
-       gc_backend.browser_emu, RealBrowser = MockBrowserModule, gc_backend.browser_emu
-       try:
-               backend = gc_backend.GCDialer()
-               assert not backend.is_authed()
-               assert not backend.login("bad_name", "bad_password")
-               backend.logout()
-               with test_utils.expected(RuntimeError):
-                       backend.dial("5551234567")
-               with test_utils.expected(RuntimeError):
-                       backend.send_sms("5551234567", "Hello World")
-               assert backend.get_account_number() == "", "%s" % backend.get_account_number()
-               backend.set_sane_callback()
-               assert backend.get_callback_number() == ""
-               recent = list(backend.get_recent())
-               messages = list(backend.get_messages())
-       finally:
-               gc_backend.browser_emu = RealBrowser
diff --git a/tests/test_startup.py b/tests/test_startup.py
deleted file mode 100644 (file)
index 5058fc0..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-from __future__ import with_statement
-
-import os
-import time
-import warnings
-
-import test_utils
-
-import sys
-sys.path.append("../src")
-
-import dc_glade
-
-
-def startup(factory):
-       handle = factory()
-       with test_utils.expected(AssertionError("Attempting login before app is fully loaded")):
-               handle.refresh_session()
-
-       for i in xrange(10):
-               if handle._initDone:
-                       print "Completed init on iteration %d" % i
-                       break
-               time.sleep(1)
-       assert handle._initDone
-
-       with test_utils.expected(RuntimeError("Login Failed")):
-               handle.refresh_session()
-
-       handle._save_settings()
-
-       del handle
-
-
-def atest_startup_with_no_data_dir_with_dummy_hildon():
-       warnings.simplefilter("always")
-       hildonPath = os.path.join(os.path.dirname(__file__), "dummy_hildon")
-       sys.path.insert(0, hildonPath)
-       import hildon
-       dc_glade.hildon = hildon
-       try:
-               dc_glade.Dialcentral._data_path = os.path.join(os.path.dirname(__file__), "notexistent_data")
-               dc_glade.Dialcentral._user_settings = "%s/settings.ini" % dc_glade.Dialcentral._data_path
-
-               try:
-                       startup(dc_glade.Dialcentral)
-               finally:
-                       try:
-                               os.remove(dc_glade.Dialcentral._user_settings)
-                       except:
-                               pass
-                       try:
-                               os.removedirs(dc_glade.Dialcentral._data_path)
-                       except:
-                               pass
-       finally:
-               dc_glade.hildon = None
-               sys.path.remove(hildonPath)
-               warnings.resetwarnings()
-
-
-def atest_startup_with_no_data_dir():
-       warnings.simplefilter("always")
-       dc_glade.Dialcentral._data_path = os.path.join(os.path.dirname(__file__), "notexistent_data")
-       dc_glade.Dialcentral._user_settings = "%s/settings.ini" % dc_glade.Dialcentral._data_path
-
-       try:
-               startup(dc_glade.Dialcentral)
-       finally:
-               try:
-                       os.remove(dc_glade.Dialcentral._user_settings)
-               except:
-                       pass
-               try:
-                       os.removedirs(dc_glade.Dialcentral._data_path)
-               except:
-                       pass
-               warnings.resetwarnings()
-
-
-def atest_startup_with_empty_data_dir():
-       warnings.simplefilter("always")
-       dc_glade.Dialcentral._data_path = os.path.join(os.path.dirname(__file__), "empty_data")
-       dc_glade.Dialcentral._user_settings = "%s/settings.ini" % dc_glade.Dialcentral._data_path
-
-       try:
-               startup(dc_glade.Dialcentral)
-       finally:
-               try:
-                       os.remove(dc_glade.Dialcentral._user_settings)
-               except:
-                       pass
-               try:
-                       os.removedirs(dc_glade.Dialcentral._data_path)
-               except:
-                       pass
-               warnings.resetwarnings()
-
-
-def atest_startup_with_basic_data_dir():
-       warnings.simplefilter("always")
-       try:
-               dc_glade.Dialcentral._data_path = os.path.join(os.path.dirname(__file__), "basic_data")
-               dc_glade.Dialcentral._user_settings = "%s/settings.ini" % dc_glade.Dialcentral._data_path
-
-               startup(dc_glade.Dialcentral)
-       finally:
-               warnings.resetwarnings()