Switching from QTextEdit to QLabel for better scrolling behavior with the SMS Window
[gc-dialer] / src / dialogs.py
index 7b8ae52..07a9ae9 100644 (file)
@@ -80,6 +80,8 @@ class CredentialsDialog(object):
 
 class AccountDialog(object):
 
+       # @bug Can't enter custom callback numbers
+
        def __init__(self, app):
                self._doClear = False
 
@@ -87,10 +89,15 @@ class AccountDialog(object):
                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._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(QtGui.QLabel(""), 3, 0)
@@ -128,6 +135,27 @@ class AccountDialog(object):
                lambda self, num: self._accountNumberLabel.setText(num),
        )
 
+       @property
+       def selectedCallback(self):
+               index = self._callbackSelector.currentIndex()
+               data = str(self._callbackSelector.itemData(index).toPyObject())
+               return data
+
+       def set_callbacks(self, choices, default):
+               self._callbackSelector.clear()
+
+               uglyDefault = misc_utils.make_ugly(default)
+               for i, (number, description) in enumerate(choices.iteritems()):
+                       prettyNumber = misc_utils.make_pretty(number)
+                       uglyNumber = misc_utils.make_ugly(number)
+                       if not uglyNumber:
+                               continue
+
+                       self._callbackSelector.addItem("%s - %s" % (prettyNumber, description), uglyNumber)
+                       if uglyNumber == uglyDefault:
+                               self._callbackSelector.setCurrentIndex(i)
+
+
        def run(self, parent=None):
                self._doClear = False
                self._dialog.setParent(parent)
@@ -150,18 +178,29 @@ class AccountDialog(object):
 
 class SMSEntryWindow(object):
 
+       MAX_CHAR = 160
+
        def __init__(self, parent, app, session, errorLog):
                self._session = session
                self._session.draft.recipientsChanged.connect(self._on_recipients_changed)
+               self._session.draft.sendingMessage.connect(self._on_op_started)
+               self._session.draft.calling.connect(self._on_op_started)
+               self._session.draft.cancelling.connect(self._on_op_started)
+               self._session.draft.calling.connect(self._on_calling_started)
                self._session.draft.called.connect(self._on_op_finished)
                self._session.draft.sentMessage.connect(self._on_op_finished)
                self._session.draft.cancelled.connect(self._on_op_finished)
+               self._session.draft.error.connect(self._on_op_error)
                self._errorLog = errorLog
 
+               self._errorDisplay = qui_utils.ErrorDisplay(self._errorLog)
+
                self._targetLayout = QtGui.QVBoxLayout()
                self._targetList = QtGui.QWidget()
                self._targetList.setLayout(self._targetLayout)
-               self._history = QtGui.QTextEdit()
+               self._history = QtGui.QLabel()
+               self._history.setTextFormat(QtCore.Qt.RichText)
+               self._history.setWordWrap(True)
                self._smsEntry = QtGui.QTextEdit()
                self._smsEntry.textChanged.connect(self._on_letter_count_changed)
 
@@ -169,28 +208,37 @@ class SMSEntryWindow(object):
                self._entryLayout.addWidget(self._targetList)
                self._entryLayout.addWidget(self._history)
                self._entryLayout.addWidget(self._smsEntry)
+               self._entryLayout.setContentsMargins(0, 0, 0, 0)
                self._entryWidget = QtGui.QWidget()
                self._entryWidget.setLayout(self._entryLayout)
+               self._entryWidget.setContentsMargins(0, 0, 0, 0)
                self._scrollEntry = QtGui.QScrollArea()
                self._scrollEntry.setWidget(self._entryWidget)
+               self._scrollEntry.setWidgetResizable(True)
                self._scrollEntry.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignBottom)
                self._scrollEntry.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
                self._scrollEntry.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
 
-               self._characterCountLabel = QtGui.QLabel("Letters: %s" % 0)
+               self._characterCountLabel = QtGui.QLabel("0 (0)")
                self._singleNumberSelector = QtGui.QComboBox()
                self._smsButton = QtGui.QPushButton("SMS")
                self._smsButton.clicked.connect(self._on_sms_clicked)
+               self._smsButton.setEnabled(False)
                self._dialButton = QtGui.QPushButton("Dial")
                self._dialButton.clicked.connect(self._on_call_clicked)
+               self._cancelButton = QtGui.QPushButton("Cancel Call")
+               self._cancelButton.clicked.connect(self._on_cancel_clicked)
+               self._cancelButton.setVisible(False)
 
                self._buttonLayout = QtGui.QHBoxLayout()
                self._buttonLayout.addWidget(self._characterCountLabel)
                self._buttonLayout.addWidget(self._singleNumberSelector)
                self._buttonLayout.addWidget(self._smsButton)
                self._buttonLayout.addWidget(self._dialButton)
+               self._buttonLayout.addWidget(self._cancelButton)
 
                self._layout = QtGui.QVBoxLayout()
+               self._layout.addWidget(self._errorDisplay.toplevel)
                self._layout.addWidget(self._scrollEntry)
                self._layout.addLayout(self._buttonLayout)
 
@@ -219,7 +267,10 @@ class SMSEntryWindow(object):
 
        def _update_letter_count(self):
                count = self._smsEntry.toPlainText().size()
-               self._characterCountLabel.setText("Letters: %s" % count)
+               numTexts, numCharInText = divmod(count, self.MAX_CHAR)
+               numTexts += 1
+               numCharsLeftInText = self.MAX_CHAR - numCharInText
+               self._characterCountLabel.setText("%d (%d)" % (numCharsLeftInText, numTexts))
 
        def _update_button_state(self):
                if self._session.draft.get_num_contacts() == 0:
@@ -249,16 +300,17 @@ class SMSEntryWindow(object):
 
                        self._targetList.setVisible(False)
                        if description:
-                               self._history.setHtml(description)
+                               self._history.setText(description)
                                self._history.setVisible(True)
                        else:
-                               self._history.setHtml("")
+                               self._history.setText("")
                                self._history.setVisible(False)
                        self._populate_number_selector(self._singleNumberSelector, cid, numbers)
 
                        self._scroll_to_bottom()
                        self._window.setWindowTitle(title)
                        self._window.show()
+                       self._smsEntry.setFocus(QtCore.Qt.OtherFocusReason)
                else:
                        self._targetList.setVisible(True)
                        while self._targetLayout.count():
@@ -288,17 +340,17 @@ class SMSEntryWindow(object):
                                rowWidget = QtGui.QWidget()
                                rowWidget.setLayout(rowLayout)
                                self._targetLayout.addWidget(rowWidget)
-                       self._history.setHtml("")
+                       self._history.setText("")
                        self._history.setVisible(False)
                        self._singleNumberSelector.setVisible(False)
 
                        self._scroll_to_bottom()
                        self._window.setWindowTitle("Contacts")
                        self._window.show()
+                       self._smsEntry.setFocus(QtCore.Qt.OtherFocusReason)
 
        def _populate_number_selector(self, selector, cid, numbers):
-               while 0 < selector.count():
-                       selector.removeItem(0)
+               selector.clear()
 
                if len(numbers) == 1:
                        numbers, defaultIndex = _get_contact_numbers(self._session, cid, numbers[0])
@@ -340,6 +392,11 @@ class SMSEntryWindow(object):
                self._session.draft.call()
                self._smsEntry.setPlainText("")
 
+       @QtCore.pyqtSlot()
+       @misc_utils.log_exception(_moduleLogger)
+       def _on_cancel_clicked(self, message):
+               self._session.draft.cancel()
+
        @misc_utils.log_exception(_moduleLogger)
        def _on_remove_contact(self, cid, toggled):
                self._session.draft.remove_contact(cid)
@@ -358,9 +415,37 @@ class SMSEntryWindow(object):
 
        @QtCore.pyqtSlot()
        @misc_utils.log_exception(_moduleLogger)
+       def _on_op_started(self):
+               self._smsEntry.setReadOnly(True)
+               self._smsButton.setVisible(False)
+               self._dialButton.setVisible(False)
+               self._window.show()
+
+       @QtCore.pyqtSlot()
+       @misc_utils.log_exception(_moduleLogger)
+       def _on_calling_started(self):
+               self._cancelButton.setVisible(True)
+
+       @QtCore.pyqtSlot()
+       @misc_utils.log_exception(_moduleLogger)
        def _on_op_finished(self):
                self._window.hide()
 
+               self._smsEntry.setReadOnly(False)
+               self._cancelButton.setVisible(False)
+               self._smsButton.setVisible(True)
+               self._dialButton.setVisible(True)
+
+       @QtCore.pyqtSlot()
+       @misc_utils.log_exception(_moduleLogger)
+       def _on_op_error(self, message):
+               self._smsEntry.setReadOnly(False)
+               self._cancelButton.setVisible(False)
+               self._smsButton.setVisible(True)
+               self._dialButton.setVisible(True)
+
+               self._errorLog.push_message(message)
+
        @QtCore.pyqtSlot()
        @misc_utils.log_exception(_moduleLogger)
        def _on_letter_count_changed(self):