Adding notification support back in and fixing a dialog bug
authorEd Page <eopage@byu.net>
Mon, 3 Jan 2011 18:53:31 +0000 (12:53 -0600)
committerEd Page <eopage@byu.net>
Mon, 3 Jan 2011 18:53:31 +0000 (12:53 -0600)
src/alarm_notify.py
src/dialcentral_qt.py
src/dialogs.py

index 7b7e93f..8904ec6 100755 (executable)
@@ -7,7 +7,7 @@ import pprint
 import logging
 
 import constants
-from backends import gvoice
+from backends.gvoice import gvoice
 
 
 def get_missed(backend):
index fed410d..db535fc 100755 (executable)
@@ -37,6 +37,9 @@ class Dialcentral(object):
                self._hiddenUnits = {}
                self._clipboard = QtGui.QApplication.clipboard()
                self._dataPath = None
+               self.notifyOnMissed = False
+               self.notifyOnVoicemail = False
+               self.notifyOnSms = False
 
                self._mainWindow = None
 
@@ -60,6 +63,20 @@ class Dialcentral(object):
                self._mainWindow = MainWindow(None, self)
                self._mainWindow.window.destroyed.connect(self._on_child_close)
 
+               try:
+                       import alarm_handler
+                       if alarm_handler.AlarmHandler is not alarm_handler._NoneAlarmHandler:
+                               self._alarmHandler = alarm_handler.AlarmHandler()
+                       else:
+                               self._alarmHandler = None
+               except (ImportError, OSError):
+                       self._alarmHandler = None
+               except Exception:
+                       _moduleLogger.exception("Notification failure")
+                       self._alarmHandler = None
+               if self._alarmHandler is None:
+                       _moduleLogger.info("No notification support")
+
                self.load_settings()
 
                self._mainWindow.show()
@@ -114,6 +131,31 @@ class Dialcentral(object):
                        _moduleLogger.exception("Unknown loading error")
                        return
 
+               if self._alarmHandler is not None:
+                       try:
+                               self._alarmHandler.load_settings(config, "alarm")
+                               self.notifyOnMissed = config.getboolean("2 - Account Info", "notifyOnMissed")
+                               self.notifyOnVoicemail = config.getboolean("2 - Account Info", "notifyOnVoicemail")
+                               self.notifyOnSms = config.getboolean("2 - Account Info", "notifyOnSms")
+                       except ConfigParser.NoOptionError, e:
+                               _moduleLogger.info(
+                                       "Settings file %s is missing option %s" % (
+                                               constants._user_settings_,
+                                               e.option,
+                                       ),
+                               )
+                       except ConfigParser.NoSectionError, e:
+                               _moduleLogger.info(
+                                       "Settings file %s is missing section %s" % (
+                                               constants._user_settings_,
+                                               e.section,
+                                       ),
+                               )
+                               return
+                       except Exception:
+                               _moduleLogger.exception("Unknown loading error")
+                               return
+
                creds = (
                        base64.b64decode(blob)
                        for blob in blobs
@@ -134,6 +176,13 @@ class Dialcentral(object):
                        blob = base64.b64encode(value)
                        config.set(constants.__pretty_app_name__, "bin_blob_%i" % i, blob)
 
+               if self._alarmHandler is not None:
+                       self._alarmHandler.save_settings(config, "alarm")
+               config.add_section("2 - Account Info")
+               config.set("2 - Account Info", "notifyOnMissed", repr(self.notifyOnMissed))
+               config.set("2 - Account Info", "notifyOnVoicemail", repr(self.notifyOnVoicemail))
+               config.set("2 - Account Info", "notifyOnSms", repr(self.notifyOnSms))
+
                self._mainWindow.save_settings(config)
 
                with open(constants._user_settings_, "wb") as configFile:
@@ -462,14 +511,7 @@ class MainWindow(object):
                return self._defaultCredentials
 
        def walk_children(self):
-               return (diag for diag in (
-                       self._credentialsDialog,
-                       self._smsEntryDialog,
-                       self._accountDialog,
-                       self._aboutDialog,
-                       )
-                       if diag is not None
-               )
+               return ()
 
        def start(self):
                assert self._session.state == self._session.LOGGEDOUT_STATE, "Initialization messed up"
@@ -484,6 +526,14 @@ class MainWindow(object):
                for child in self.walk_children():
                        child.window.destroyed.disconnect(self._on_child_close)
                        child.close()
+               for diag in (
+                       self._credentialsDialog,
+                       self._smsEntryDialog,
+                       self._accountDialog,
+                       self._aboutDialog,
+               ):
+                       if diag is not None:
+                               diag.close()
                self._window.close()
 
        def destroy(self):
@@ -574,6 +624,14 @@ class MainWindow(object):
                if self._accountDialog is None:
                        import dialogs
                        self._accountDialog = dialogs.AccountDialog(self._app)
+                       if self._alarmHandler is None:
+                               self._accountDialog.setIfNotificationsSupported(False)
+               if self._alarmHandler is not None:
+                       self._accountDialog.notifications = self._alarmHandler.isEnabled
+                       self._accountDialog.notificationTime = self._alarmHandler.recurrence
+                       self._accountDialog.notifyOnMissed = self._app.notifyOnMissed
+                       self._accountDialog.notifyOnVoicemail = self._app.notifyOnVoicemail
+                       self._accountDialog.notifyOnSms = self._app.notifyOnSms
                self._accountDialog.set_callbacks(
                        self._session.get_callback_numbers(), self._session.get_callback_number()
                )
@@ -585,6 +643,11 @@ class MainWindow(object):
                        else:
                                callbackNumber = self._accountDialog.selectedCallback
                                self._session.set_callback_number(callbackNumber)
+                       if self._alarmHandler is not None:
+                               self._alarmHandler.apply_settings(self._accountDialog.notifications, self._accountDialog.notificationTime)
+                               self._app.notifyOnMissed = self._accountDialog.notifyOnMissed
+                               self._app.notifyOnVoicemail = self._accountDialog.notifyOnVoicemail
+                               self._app.notifyOnSms = self._accountDialog.notifyOnSms
                elif response == QtGui.QDialog.Rejected:
                        _moduleLogger.info("Cancelled")
                else:
index 0271758..35c0312 100644 (file)
@@ -139,24 +139,61 @@ class AccountDialog(object):
 
        # @bug Can't enter custom callback numbers
 
+
+       _RECURRENCE_CHOICES = [
+               (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"),
+       ]
+
        def __init__(self, app):
                self._doClear = False
 
                self._accountNumberLabel = QtGui.QLabel("NUMBER NOT SET")
+               self._notificationButton = QtGui.QCheckBox("Notifications")
+               self._notificationButton.stateChanged.connect(self._on_notification_change)
+               self._notificationTimeSelector = QtGui.QComboBox()
+               #self._notificationTimeSelector.setEditable(True)
+               self._notificationTimeSelector.setInsertPolicy(QtGui.QComboBox.InsertAtTop)
+               for _, label in self._RECURRENCE_CHOICES:
+                       self._notificationTimeSelector.addItem(label)
+               self._missedCallsNotificationButton = QtGui.QCheckBox("Missed Calls")
+               self._voicemailNotificationButton = QtGui.QCheckBox("Voicemail")
+               self._smsNotificationButton = QtGui.QCheckBox("SMS")
                self._clearButton = QtGui.QPushButton("Clear Account")
                self._clearButton.clicked.connect(self._on_clear)
-
                self._callbackSelector = QtGui.QComboBox()
                #self._callbackSelector.setEditable(True)
                self._callbackSelector.setInsertPolicy(QtGui.QComboBox.InsertAtTop)
 
+               self._update_notification_state()
+
                self._credLayout = QtGui.QGridLayout()
                self._credLayout.addWidget(QtGui.QLabel("Account"), 0, 0)
                self._credLayout.addWidget(self._accountNumberLabel, 0, 1)
                self._credLayout.addWidget(QtGui.QLabel("Callback"), 1, 0)
                self._credLayout.addWidget(self._callbackSelector, 1, 1)
-               self._credLayout.addWidget(QtGui.QLabel(""), 2, 0)
-               self._credLayout.addWidget(self._clearButton, 2, 1)
+               self._credLayout.addWidget(self._notificationButton, 2, 0)
+               self._credLayout.addWidget(self._notificationTimeSelector, 2, 1)
+               self._credLayout.addWidget(QtGui.QLabel(""), 3, 0)
+               self._credLayout.addWidget(self._missedCallsNotificationButton, 3, 1)
+               self._credLayout.addWidget(QtGui.QLabel(""), 4, 0)
+               self._credLayout.addWidget(self._voicemailNotificationButton, 4, 1)
+               self._credLayout.addWidget(QtGui.QLabel(""), 5, 0)
+               self._credLayout.addWidget(self._smsNotificationButton, 5, 1)
+
+               self._credLayout.addWidget(QtGui.QLabel(""), 6, 0)
+               self._credLayout.addWidget(self._clearButton, 6, 1)
                self._credLayout.addWidget(QtGui.QLabel(""), 3, 0)
 
                self._loginButton = QtGui.QPushButton("&Apply")
@@ -187,11 +224,60 @@ class AccountDialog(object):
        def doClear(self):
                return self._doClear
 
+       def setIfNotificationsSupported(self, isSupported):
+               if isSupported:
+                       self._notificationButton.setVisible(True)
+                       self._notificationTimeSelector.setVisible(True)
+                       self._missedCallsNotificationButton.setVisible(True)
+                       self._voicemailNotificationButton.setVisible(True)
+                       self._smsNotificationButton.setVisible(True)
+               else:
+                       self._notificationButton.setVisible(False)
+                       self._notificationTimeSelector.setVisible(False)
+                       self._missedCallsNotificationButton.setVisible(False)
+                       self._voicemailNotificationButton.setVisible(False)
+                       self._smsNotificationButton.setVisible(False)
+
        accountNumber = property(
                lambda self: str(self._accountNumberLabel.text()),
                lambda self, num: self._accountNumberLabel.setText(num),
        )
 
+       notifications = property(
+               lambda self: self._notificationButton.isChecked(),
+               lambda self, enabled: self._notificationButton.setChecked(enabled),
+       )
+
+       notifyOnMissed = property(
+               lambda self: self._missedCallsNotificationButton.isChecked(),
+               lambda self, enabled: self._missedCallsNotificationButton.setChecked(enabled),
+       )
+
+       notifyOnVoicemail = property(
+               lambda self: self._voicemailNotificationButton.isChecked(),
+               lambda self, enabled: self._voicemailNotificationButton.setChecked(enabled),
+       )
+
+       notifyOnSms = property(
+               lambda self: self._smsNotificationButton.isChecked(),
+               lambda self, enabled: self._smsNotificationButton.setChecked(enabled),
+       )
+
+       def _get_notification_time(self):
+               index = self._notificationTimeSelector.currentIndex()
+               minutes = self._RECURRENCE_CHOICES[index][0]
+               return minutes
+
+       def _set_notification_time(self, minutes):
+               for i, (time, _) in enumerate(self._RECURRENCE_CHOICES):
+                       if time == minutes:
+                               self._callbackSelector.setCurrentIndex(i)
+                               break
+               else:
+                               self._callbackSelector.setCurrentIndex(0)
+
+       notificationTime = property(_get_notification_time, _set_notification_time)
+
        @property
        def selectedCallback(self):
                index = self._callbackSelector.currentIndex()
@@ -214,7 +300,6 @@ class AccountDialog(object):
                        if uglyNumber == uglyDefault:
                                self._callbackSelector.setCurrentIndex(i)
 
-
        def run(self, parent=None):
                self._doClear = False
                self._dialog.setParent(parent)
@@ -225,6 +310,22 @@ class AccountDialog(object):
        def close(self):
                self._dialog.reject()
 
+       def _update_notification_state(self):
+               if self._notificationButton.isChecked():
+                       self._notificationTimeSelector.setEnabled(True)
+                       self._missedCallsNotificationButton.setEnabled(True)
+                       self._voicemailNotificationButton.setEnabled(True)
+                       self._smsNotificationButton.setEnabled(True)
+               else:
+                       self._notificationTimeSelector.setEnabled(False)
+                       self._missedCallsNotificationButton.setEnabled(False)
+                       self._voicemailNotificationButton.setEnabled(False)
+                       self._smsNotificationButton.setEnabled(False)
+
+       @QtCore.pyqtSlot(int)
+       def _on_notification_change(self, state):
+               self._update_notification_state()
+
        @QtCore.pyqtSlot()
        @QtCore.pyqtSlot(bool)
        def _on_clear(self, checked = False):