Lots of little tweaks to various issues
[gc-dialer] / src / dc_glade.py
index 99889c5..49b9bf8 100755 (executable)
@@ -29,7 +29,7 @@ import threading
 import base64
 import ConfigParser
 import itertools
-import warnings
+import logging
 
 import gtk
 import gtk.glade
@@ -42,7 +42,7 @@ import gtk_toolbox
 def getmtime_nothrow(path):
        try:
                return os.path.getmtime(path)
-       except StandardError:
+       except Exception:
                return 0
 
 
@@ -130,7 +130,8 @@ class Dialcentral(object):
                        self._window.connect("key-press-event", self._on_key_press)
                        self._window.connect("window-state-event", self._on_window_state_change)
                else:
-                       pass # warnings.warn("No Hildon", UserWarning, 2)
+                       logging.warning("No hildonization support")
+
 
                hildonize.set_application_title(self._window, "%s" % constants.__pretty_app_name__)
 
@@ -158,8 +159,8 @@ class Dialcentral(object):
                """
                If something can be done after the UI loads, push it here so it's not blocking the UI
                """
+               # Barebones UI handlers
                try:
-                       # Barebones UI handlers
                        import null_backend
                        import null_views
 
@@ -176,11 +177,15 @@ class Dialcentral(object):
                                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
+               # Setup maemo specifics
+               try:
                        try:
                                import osso
-                       except ImportError:
+                       except (ImportError, OSError):
                                osso = None
                        self._osso = None
                        if osso is not None:
@@ -188,25 +193,25 @@ class Dialcentral(object):
                                device = osso.DeviceState(self._osso)
                                device.set_device_state_callback(self._on_device_state_change, 0)
                        else:
-                               pass # warnings.warn("No OSSO", UserWarning, 2)
+                               logging.warning("No device state support")
 
                        try:
                                import alarm_handler
                                self._alarmHandler = alarm_handler.AlarmHandler()
-                       except ImportError:
+                       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:
                                import led_handler
                                self._ledHandler = led_handler.LedHandler()
 
-                       # Setup maemo specifics
                        try:
                                import conic
-                       except ImportError:
+                       except (ImportError, OSError):
                                conic = None
                        self._connection = None
                        if conic is not None:
@@ -214,9 +219,13 @@ class Dialcentral(object):
                                self._connection.connect("connection-event", self._on_connection_change, constants.__app_magic__)
                                self._connection.request_connection(conic.CONNECT_FLAG_NONE)
                        else:
-                               pass # warnings.warn("No Internet Connectivity API ", UserWarning)
+                               logging.warning("No connection support")
+               except Exception, e:
+                       with gtk_toolbox.gtk_lock():
+                               self._errorDisplay.push_exception()
 
-                       # Setup costly backends
+               # Setup costly backends
+               try:
                        import gv_backend
                        import file_backend
                        import gv_views
@@ -226,18 +235,13 @@ class Dialcentral(object):
                        except OSError, e:
                                if e.errno != 17:
                                        raise
-                       gcCookiePath = os.path.join(constants._data_path_, "gc_cookies.txt")
                        gvCookiePath = os.path.join(constants._data_path_, "gv_cookies.txt")
-                       self._defaultBackendId = self._guess_preferred_backend((
-                               (self.GV_BACKEND, gvCookiePath),
-                       ))
 
                        self._phoneBackends.update({
                                self.GV_BACKEND: gv_backend.GVDialer(gvCookiePath),
                        })
                        with gtk_toolbox.gtk_lock():
                                unifiedDialpad = gv_views.Dialpad(self._widgetTree, self._errorDisplay)
-                               unifiedDialpad.set_number("")
                                self._dialpads.update({
                                        self.GV_BACKEND: unifiedDialpad,
                                })
@@ -265,24 +269,25 @@ class Dialcentral(object):
 
                        fsContactsPath = os.path.join(constants._data_path_, "contacts")
                        fileBackend = file_backend.FilesystemAddressBookFactory(fsContactsPath)
-                       for backendId in (self.GV_BACKEND, ):
-                               self._dialpads[backendId].number_selected = self._select_action
-                               self._recentViews[backendId].number_selected = self._select_action
-                               self._messagesViews[backendId].number_selected = self._select_action
-                               self._contactsViews[backendId].number_selected = self._select_action
-
-                               addressBooks = [
-                                       self._phoneBackends[backendId],
-                                       fileBackend,
-                               ]
-                               mergedBook = gv_views.MergedAddressBook(addressBooks, gv_views.MergedAddressBook.advanced_lastname_sorter)
-                               self._contactsViews[backendId].append(mergedBook)
-                               self._contactsViews[backendId].extend(addressBooks)
-                               self._contactsViews[backendId].open_addressbook(*self._contactsViews[backendId].get_addressbooks().next()[0][0:2])
+
+                       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_rotate": self._on_menu_rotate,
                                "on_clearcookies_clicked": self._on_clearcookies_clicked,
                                "on_notebook_switch_page": self._on_notebook_switch_page,
                                "on_about_activate": self._on_about_activate,
@@ -307,11 +312,11 @@ class Dialcentral(object):
                        config.read(constants._user_settings_)
                        with gtk_toolbox.gtk_lock():
                                self.load_settings(config)
-
-                       self._spawn_attempt_login(2)
                except Exception, e:
                        with gtk_toolbox.gtk_lock():
                                self._errorDisplay.push_exception()
+               finally:
+                       self._spawn_attempt_login(2)
 
        def attempt_login(self, numOfAttempts = 10, force = False):
                """
@@ -330,15 +335,15 @@ class Dialcentral(object):
                                        self.refresh_session()
                                        serviceId = self._defaultBackendId
                                        loggedIn = True
-                               except StandardError, e:
-                                       warnings.warn('Session refresh failed with the following message "%s"' % e.message, UserWarning, 2)
+                               except Exception, e:
+                                       logging.exception('Session refresh failed with the following message "%s"' % e.message)
 
                        if not loggedIn:
                                loggedIn, serviceId = self._login_by_user(numOfAttempts)
 
                        with gtk_toolbox.gtk_lock():
                                self._change_loggedin_status(serviceId)
-               except StandardError, e:
+               except Exception, e:
                        with gtk_toolbox.gtk_lock():
                                self._errorDisplay.push_exception()
 
@@ -366,10 +371,7 @@ class Dialcentral(object):
                """
                loggedIn = self._phoneBackends[self._defaultBackendId].is_authed()
                if loggedIn:
-                       warnings.warn(
-                               "Logged into %r through cookies" % self._phoneBackends[self._defaultBackendId],
-                               UserWarning, 2
-                       )
+                       logging.info("Logged into %r through cookies" % self._phoneBackends[self._defaultBackendId])
                return loggedIn
 
        def _login_by_settings(self):
@@ -380,10 +382,7 @@ class Dialcentral(object):
                loggedIn = self._phoneBackends[self._defaultBackendId].login(username, password)
                if loggedIn:
                        self._credentials = username, password
-                       warnings.warn(
-                               "Logged into %r through settings" % self._phoneBackends[self._defaultBackendId],
-                               UserWarning, 2
-                       )
+                       logging.info("Logged into %r through settings" % self._phoneBackends[self._defaultBackendId])
                return loggedIn
 
        def _login_by_user(self, numOfAttempts):
@@ -391,27 +390,21 @@ class Dialcentral(object):
                @note This must be run outside of the UI lock
                """
                loggedIn, (username, password) = False, self._credentials
-               tmpServiceId = self.NULL_BACKEND
+               tmpServiceId = self.GV_BACKEND
                for attemptCount in xrange(numOfAttempts):
                        if loggedIn:
                                break
-                       availableServices = (
-                               (self.GV_BACKEND, "Google Voice"),
-                       )
                        with gtk_toolbox.gtk_lock():
-                               credentials = self._credentialsDialog.request_credentials_from(
-                                       availableServices, defaultCredentials = self._credentials
+                               credentials = self._credentialsDialog.request_credentials(
+                                       defaultCredentials = self._credentials
                                )
-                       tmpServiceId, username, password = credentials
+                       username, password = credentials
                        loggedIn = self._phoneBackends[tmpServiceId].login(username, password)
 
                if loggedIn:
                        serviceId = tmpServiceId
                        self._credentials = username, password
-                       warnings.warn(
-                               "Logged into %r through user request" % self._phoneBackends[serviceId],
-                               UserWarning, 2
-                       )
+                       logging.info("Logged into %r through user request" % self._phoneBackends[serviceId])
                else:
                        serviceId = self.NULL_BACKEND
 
@@ -457,7 +450,7 @@ class Dialcentral(object):
                @note UI Thread
                """
                try:
-                       self._defaultBackendId = int(config.get(constants.__pretty_app_name__, "active"))
+                       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))
@@ -470,21 +463,25 @@ class Dialcentral(object):
 
                        if self._alarmHandler is not None:
                                self._alarmHandler.load_settings(config, "alarm")
+
+                       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:
-                       warnings.warn(
+                       logging.exception(
                                "Settings file %s is missing section %s" % (
                                        constants._user_settings_,
                                        e.section,
                                ),
-                               stacklevel=2
                        )
                except ConfigParser.NoSectionError, e:
-                       warnings.warn(
+                       logging.exception(
                                "Settings file %s is missing section %s" % (
                                        constants._user_settings_,
                                        e.section,
                                ),
-                               stacklevel=2
                        )
 
                for backendId, view in itertools.chain(
@@ -498,20 +495,18 @@ class Dialcentral(object):
                        try:
                                view.load_settings(config, sectionName)
                        except ConfigParser.NoOptionError, e:
-                               warnings.warn(
+                               logging.exception(
                                        "Settings file %s is missing section %s" % (
                                                constants._user_settings_,
                                                e.section,
                                        ),
-                                       stacklevel=2
                                )
                        except ConfigParser.NoSectionError, e:
-                               warnings.warn(
+                               logging.exception(
                                        "Settings file %s is missing section %s" % (
                                                constants._user_settings_,
                                                e.section,
                                        ),
-                                       stacklevel=2
                                )
 
        def save_settings(self, config):
@@ -520,6 +515,7 @@ class Dialcentral(object):
                """
                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)
@@ -538,14 +534,6 @@ class Dialcentral(object):
                        config.add_section(sectionName)
                        view.save_settings(config, sectionName)
 
-       def _guess_preferred_backend(self, backendAndCookiePaths):
-               modTimeAndPath = [
-                       (getmtime_nothrow(path), backendId, path)
-                       for backendId, path in backendAndCookiePaths
-               ]
-               modTimeAndPath.sort()
-               return modTimeAndPath[-1][1]
-
        def _save_settings(self):
                """
                @note Thread Agnostic
@@ -585,172 +573,220 @@ class Dialcentral(object):
 
                @note Hildon specific
                """
-               if memory_low:
-                       for backendId in self.BACKENDS:
-                               self._phoneBackends[backendId].clear_caches()
-                       self._contactsViews[self._selectedBackendId].clear_caches()
-                       gc.collect()
+               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()
+                       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
                """
-               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)
+               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
                """
-               if event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN:
-                       self._isFullScreen = True
-               else:
-                       self._isFullScreen = False
+               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
                """
-               if event.keyval == gtk.keysyms.F6:
-                       if self._isFullScreen:
-                               self._window.unfullscreen()
-                       else:
-                               self._window.fullscreen()
+               try:
+                       if event.keyval == gtk.keysyms.F6:
+                               if self._isFullScreen:
+                                       self._window.unfullscreen()
+                               else:
+                                       self._window.fullscreen()
+               except Exception, e:
+                       self._errorDisplay.push_exception()
 
        def _on_clearcookies_clicked(self, *args):
-               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)
+               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):
-               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()
+               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):
-               pageIndex = self._notebook.get_current_page()
-               child = self._notebook.get_nth_page(pageIndex)
-               self._notebook.get_tab_label(child).set_text("Refresh?")
+               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):
-               pageIndex = self._notebook.get_current_page()
-               child = self._notebook.get_nth_page(pageIndex)
-               self._notebook.get_tab_label(child).set_text(self._originalCurrentLabels[pageIndex])
+               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):
-               self._refresh_active_tab()
-               self._reset_tab_refresh()
+               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):
-               assert number, "No number specified"
-               assert message, "Empty message"
                try:
-                       loggedIn = self._phoneBackends[self._selectedBackendId].is_authed()
-               except StandardError, e:
-                       loggedIn = False
-                       self._errorDisplay.push_exception()
-                       return
+                       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 grandcentral is not working, please try again"
-                       )
-                       return
+                       if not loggedIn:
+                               self._errorDisplay.push_message(
+                                       "Backend link with grandcentral is not working, please try again"
+                               )
+                               return
 
-               dialed = False
-               try:
-                       self._phoneBackends[self._selectedBackendId].send_sms(number, message)
-                       dialed = True
-               except StandardError, e:
-                       self._errorDisplay.push_exception()
-               except ValueError, e:
-                       self._errorDisplay.push_exception()
+                       dialed = False
+                       try:
+                               self._phoneBackends[self._selectedBackendId].send_sms(number, message)
+                               dialed = True
+                       except Exception, e:
+                               self._errorDisplay.push_exception()
 
-               if dialed:
-                       self._dialpads[self._selectedBackendId].clear()
+                       if dialed:
+                               self._dialpads[self._selectedBackendId].clear()
+               except Exception, e:
+                       self._errorDisplay.push_exception()
 
        def _on_dial_clicked(self, number):
-               assert number, "No number to call"
                try:
-                       loggedIn = self._phoneBackends[self._selectedBackendId].is_authed()
-               except StandardError, e:
-                       loggedIn = False
-                       self._errorDisplay.push_exception()
-                       return
+                       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 grandcentral is not working, please try again"
-                       )
-                       return
+                       if not loggedIn:
+                               self._errorDisplay.push_message(
+                                       "Backend link with grandcentral 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)
-                       dialed = True
-               except StandardError, e:
-                       self._errorDisplay.push_exception()
-               except ValueError, e:
-                       self._errorDisplay.push_exception()
+                       dialed = False
+                       try:
+                               assert self._phoneBackends[self._selectedBackendId].get_callback_number() != "", "No callback number specified"
+                               self._phoneBackends[self._selectedBackendId].dial(number)
+                               dialed = True
+                       except Exception, e:
+                               self._errorDisplay.push_exception()
 
-               if dialed:
-                       self._dialpads[self._selectedBackendId].clear()
+                       if dialed:
+                               self._dialpads[self._selectedBackendId].clear()
+               except Exception, e:
+                       self._errorDisplay.push_exception()
 
        def _on_menu_refresh(self, *args):
-               self._refresh_active_tab()
+               try:
+                       self._refresh_active_tab()
+               except Exception, e:
+                       self._errorDisplay.push_exception()
+
+       def _on_menu_rotate(self, *args):
+               try:
+                       orientation = gtk_toolbox.get_screen_orientation()
+                       if orientation == gtk.ORIENTATION_HORIZONTAL:
+                               hildonize.window_to_portrait(self._window)
+                       elif orientation == gtk.ORIENTATION_VERTICAL:
+                               hildonize.window_to_landscape(self._window)
+               except Exception, e:
+                       self._errorDisplay.push_exception()
 
        def _on_paste(self, *args):
-               contents = self._clipboard.wait_for_text()
-               self._dialpads[self._selectedBackendId].set_number(contents)
+               try:
+                       contents = self._clipboard.wait_for_text()
+                       self._dialpads[self._selectedBackendId].set_number(contents)
+               except Exception, e:
+                       self._errorDisplay.push_exception()
 
        def _on_about_activate(self, *args):
-               dlg = gtk.AboutDialog()
-               dlg.set_name(constants.__pretty_app_name__)
-               dlg.set_version(constants.__version__)
-               dlg.set_copyright("Copyright 2008 - LGPL")
-               dlg.set_comments("Dialcentral is a touch screen enhanced interface to your GoogleVoice/Grandcentral 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()
+               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/Grandcentral 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():
@@ -782,21 +818,25 @@ class DummyOptions(object):
 
 
 if __name__ == "__main__":
-       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 = []
+       logging.basicConfig(level=logging.DEBUG)
+       try:
+               if len(sys.argv) > 1:
+                       try:
+                               import optparse
+                       except ImportError:
+                               optparse = None
 
-       if commandOptions.test:
-               run_doctest()
-       else:
-               run_dialpad()
+                       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()