Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
@todo Collapse voicemails
-@todo Alternate UI for dialogs (stackables)
"""
from __future__ import with_statement
'+13456789000'
"""
uglynumber = re.sub('[^0-9+]', '', prettynumber)
+
if uglynumber.startswith("+"):
pass
- elif uglynumber.startswith("1") and len(uglynumber) == 11:
+ elif uglynumber.startswith("1"):
uglynumber = "+"+uglynumber
- elif len(uglynumber) == 10:
+ elif 10 <= len(uglynumber):
+ assert uglynumber[0] not in ("+", "1")
uglynumber = "+1"+uglynumber
else:
pass
- #validateRe = re.compile("^\+?[0-9]{10,}$")
- #assert validateRe.match(uglynumber) is not None
-
return uglynumber
-def _make_pretty_with_areacodde(phonenumber):
+def _make_pretty_with_areacode(phonenumber):
prettynumber = "(%s)" % (phonenumber[0:3], )
if 3 < len(phonenumber):
prettynumber += " %s" % (phonenumber[3:6], )
def _make_pretty_international(phonenumber):
prettynumber = phonenumber
- if phonenumber.startswith("0"):
- prettynumber = "+%s " % (phonenumber[0:3], )
- if 3 < len(phonenumber):
- prettynumber += _make_pretty_with_areacodde(phonenumber[3:])
if phonenumber.startswith("1"):
prettynumber = "1 "
- prettynumber += _make_pretty_with_areacodde(phonenumber[1:])
+ prettynumber += _make_pretty_with_areacode(phonenumber[1:])
return prettynumber
prettynumber = _make_pretty_international(phonenumber[1:])
if not prettynumber.startswith("+"):
prettynumber = "+"+prettynumber
- elif 8 < len(phonenumber) and phonenumber[0] in ("0", "1"):
+ elif 8 < len(phonenumber) and phonenumber[0] in ("1", ):
prettynumber = _make_pretty_international(phonenumber)
elif 7 < len(phonenumber):
- prettynumber = _make_pretty_with_areacodde(phonenumber)
+ prettynumber = _make_pretty_with_areacode(phonenumber)
elif 3 < len(phonenumber):
prettynumber = _make_pretty_local(phonenumber)
else:
return "\n".join(_collapse_message(messageLines, maxCharsPerLine, maxLines))
-class SmsEntryDialog(object):
- """
- @todo Add multi-SMS messages like GoogleVoice
- """
+def _get_contact_numbers(backend, contactId, number):
+ if contactId and contactId != '0':
+ contactPhoneNumbers = list(backend.get_contact_details(contactId))
+ uglyContactNumbers = (
+ make_ugly(contactNumber)
+ for (numberDescription, contactNumber) in contactPhoneNumbers
+ )
+ defaultMatches = [
+ (
+ number == contactNumber or
+ number[1:] == contactNumber and number.startswith("1") or
+ number[2:] == contactNumber and number.startswith("+1") or
+ number == contactNumber[1:] and contactNumber.startswith("1") or
+ number == contactNumber[2:] and contactNumber.startswith("+1")
+ )
+ for contactNumber in uglyContactNumbers
+ ]
+ try:
+ defaultIndex = defaultMatches.index(True)
+ except ValueError:
+ contactPhoneNumbers.append(("Other", number))
+ defaultIndex = len(contactPhoneNumbers)-1
+ _moduleLogger.warn(
+ "Could not find contact %r's number %s among %r" % (
+ contactId, number, contactPhoneNumbers
+ )
+ )
+ else:
+ contactPhoneNumbers = [("Phone", number)]
+ defaultIndex = -1
+
+ return contactPhoneNumbers, defaultIndex
+
- ACTION_CANCEL = "cancel"
- ACTION_DIAL = "dial"
- ACTION_SEND_SMS = "sms"
+class SmsEntryWindow(object):
MAX_CHAR = 160
- def __init__(self, widgetTree):
+ def __init__(self, widgetTree, parent, app):
self._clipboard = gtk.clipboard_get()
self._widgetTree = widgetTree
- self._dialog = self._widgetTree.get_widget("smsDialog")
+ self._parent = parent
+ self._app = app
+ self._isFullScreen = False
+
+ self._window = self._widgetTree.get_widget("smsWindow")
+ self._window = hildonize.hildonize_window(self._app, self._window)
+ self._window.set_title("SMS")
+ self._window.connect("delete-event", self._on_delete)
+ self._window.connect("key-press-event", self._on_key_press)
+ self._window.connect("window-state-event", self._on_window_state_change)
+ self._widgetTree.get_widget("smsMessagesViewPort").get_parent().show()
+
+ errorBox = self._widgetTree.get_widget("smsErrorEventBox")
+ errorDescription = self._widgetTree.get_widget("smsErrorDescription")
+ errorClose = self._widgetTree.get_widget("smsErrorClose")
+ self._errorDisplay = gtk_toolbox.ErrorDisplay(errorBox, errorDescription, errorClose)
self._smsButton = self._widgetTree.get_widget("sendSmsButton")
self._smsButton.connect("clicked", self._on_send)
self._dialButton = self._widgetTree.get_widget("dialButton")
self._dialButton.connect("clicked", self._on_dial)
- 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")
+ 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)
+ self._messagesView.set_model(self._messagemodel)
+ self._messagesView.set_fixed_height_mode(False)
+
self._conversationView = self._messagesView.get_parent()
self._conversationViewPort = self._conversationView.get_parent()
self._scrollWindow = self._conversationViewPort.get_parent()
+ self._targetList = self._widgetTree.get_widget("smsTargetList")
self._phoneButton = self._widgetTree.get_widget("phoneTypeSelection")
+ self._phoneButton.connect("clicked", self._on_phone)
self._smsEntry = self._widgetTree.get_widget("smsEntry")
+ self._smsEntry.get_buffer().connect("changed", self._on_entry_changed)
self._smsEntrySize = None
- self._action = self.ACTION_CANCEL
-
- self._numberIndex = -1
- self._contactDetails = []
-
- def run(self, contactDetails, messages = (), parent = None, defaultIndex = -1):
- entryConnectId = self._smsEntry.get_buffer().connect("changed", self._on_entry_changed)
- phoneConnectId = self._phoneButton.connect("clicked", self._on_phone)
- keyConnectId = self._keyPressEventId = self._dialog.connect("key-press-event", self._on_key_press)
- try:
- # Setup the phone selection button
- del self._contactDetails[:]
- for phoneType, phoneNumber in contactDetails:
- display = " - ".join((make_pretty(phoneNumber), phoneType))
- row = (phoneNumber, display)
- self._contactDetails.append(row)
- if 0 < len(self._contactDetails):
- self._numberIndex = defaultIndex if defaultIndex != -1 else 0
- self._phoneButton.set_label(self._contactDetails[self._numberIndex][1])
- else:
- self._numberIndex = -1
- self._phoneButton.set_label("Error: No Number Available")
+ self._contacts = []
+
+ def add_contact(self, name, contactDetails, messages = (), defaultIndex = -1):
+ contactNumbers = list(self._to_contact_numbers(contactDetails))
+ assert contactNumbers, "Contact must have at least one number"
+ contactIndex = defaultIndex if defaultIndex != -1 else 0
+ contact = contactNumbers, contactIndex, messages
+ self._contacts.append(contact)
+
+ nameLabel = gtk.Label(name)
+ selector = gtk.Button(contactNumbers[0][1])
+ if len(contactNumbers) == 1:
+ selector.set_sensitive(False)
+ removeContact = gtk.Button(stock="gtk-delete")
+ row = gtk.HBox()
+ row.pack_start(nameLabel, True, True)
+ row.pack_start(selector, True, True)
+ row.pack_start(removeContact, False, False)
+ row.show_all()
+ self._targetList.pack_start(row)
+ selector.connect("clicked", self._on_choose_phone_n, row)
+ removeContact.connect("clicked", self._on_remove_phone_n, row)
+ self._update_button_state()
+ self._update_context()
+
+ parentSize = self._parent.get_size()
+ self._window.resize(parentSize[0], max(parentSize[1]-10, 100))
+ self._window.show()
+ self._window.present()
+
+ self._smsEntry.grab_focus()
+ self._scroll_to_bottom()
- # Add the column to the messages tree view
- self._messagemodel.clear()
- self._messagesView.set_model(self._messagemodel)
- self._messagesView.set_fixed_height_mode(False)
+ def clear(self):
+ del self._contacts[:]
- 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)
+ for row in list(self._targetList.get_children()):
+ self._targetList.remove(row)
+ self._smsEntry.get_buffer().set_text("")
+ self._update_letter_count()
+ self._update_context()
- 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()
+ def fullscreen(self):
+ self._window.fullscreen()
- self._smsEntry.get_buffer().set_text("")
- self._update_letter_count()
+ def unfullscreen(self):
+ self._window.unfullscreen()
- if parent is not None:
- self._dialog.set_transient_for(parent)
- parentSize = parent.get_size()
- self._dialog.resize(parentSize[0], max(parentSize[1]-10, 100))
+ def _remove_contact(self, contactIndex):
+ del self._contacts[contactIndex]
- # Run
- try:
- self._dialog.show_all()
- self._smsEntry.grab_focus()
- adjustment = self._scrollWindow.get_vadjustment()
- dx = self._conversationView.get_allocation().height - self._conversationViewPort.get_allocation().height
- dx = max(dx, 0)
- adjustment.value = dx
-
- if 1 < len(self._contactDetails):
- if defaultIndex == -1:
- self._request_number()
- self._phoneButton.set_sensitive(True)
- else:
- self._phoneButton.set_sensitive(False)
+ row = list(self._targetList.get_children())[contactIndex]
+ self._targetList.remove(row)
+ self._update_button_state()
+ self._update_context()
+ self._scroll_to_bottom()
- userResponse = self._dialog.run()
- finally:
- self._dialog.hide_all()
+ def _scroll_to_bottom(self):
+ dx = self._conversationView.get_allocation().height - self._conversationViewPort.get_allocation().height
+ dx = max(dx, 0)
+ adjustment = self._scrollWindow.get_vadjustment()
+ adjustment.value = dx
- # Process the users response
- if userResponse == gtk.RESPONSE_OK and 0 <= self._numberIndex:
- phoneNumber = self._contactDetails[self._numberIndex][0]
- phoneNumber = make_ugly(phoneNumber)
- else:
- phoneNumber = ""
- if not phoneNumber:
- self._action = self.ACTION_CANCEL
- if self._action == self.ACTION_SEND_SMS:
- entryBuffer = self._smsEntry.get_buffer()
- enteredMessage = entryBuffer.get_text(entryBuffer.get_start_iter(), entryBuffer.get_end_iter())
- enteredMessage = enteredMessage.strip()
- if not enteredMessage:
- phoneNumber = ""
- self._action = self.ACTION_CANCEL
- else:
- enteredMessage = ""
-
- self._messagesView.remove_column(messageColumn)
- self._messagesView.set_model(None)
-
- return self._action, phoneNumber, enteredMessage
- finally:
- self._smsEntry.get_buffer().disconnect(entryConnectId)
- self._phoneButton.disconnect(phoneConnectId)
- self._keyPressEventId = self._dialog.disconnect(keyConnectId)
-
- def _update_letter_count(self, *args):
+ def _update_letter_count(self):
if self._smsEntrySize is None:
self._smsEntrySize = self._smsEntry.size_request()
else:
self._smsEntry.set_size_request(*self._smsEntrySize)
entryLength = self._smsEntry.get_buffer().get_char_count()
- charsLeft = self.MAX_CHAR - entryLength
numTexts, numCharInText = divmod(entryLength, self.MAX_CHAR)
if numTexts:
self._letterCountLabel.set_text("%s.%s" % (numTexts, numCharInText))
else:
self._letterCountLabel.set_text("%s" % (numCharInText, ))
- if entryLength == 0:
- self._dialButton.set_sensitive(True)
+ self._update_button_state()
+
+ def _update_context(self):
+ self._messagemodel.clear()
+ if len(self._contacts) == 0:
+ self._messagesView.hide()
+ self._targetList.hide()
+ self._phoneButton.hide()
+ self._phoneButton.set_label("Error: You shouldn't see this")
+ elif len(self._contacts) == 1:
+ contactNumbers, index, messages = self._contacts[0]
+ if messages:
+ self._messagesView.show()
+ for message in messages:
+ row = (message, )
+ self._messagemodel.append(row)
+ messagesSelection = self._messagesView.get_selection()
+ messagesSelection.select_path((len(messages)-1, ))
+ else:
+ self._messagesView.hide()
+ self._targetList.hide()
+ self._phoneButton.show()
+ self._phoneButton.set_label(contactNumbers[index][1])
+ if 1 < len(contactNumbers):
+ self._phoneButton.set_sensitive(True)
+ else:
+ self._phoneButton.set_sensitive(False)
+ else:
+ self._messagesView.hide()
+ self._targetList.show()
+ self._phoneButton.hide()
+ self._phoneButton.set_label("Error: You shouldn't see this")
+
+ def _update_button_state(self):
+ if len(self._contacts) == 0:
+ self._dialButton.set_sensitive(False)
self._smsButton.set_sensitive(False)
+ elif len(self._contacts) == 1:
+ entryLength = self._smsEntry.get_buffer().get_char_count()
+ if entryLength == 0:
+ self._dialButton.set_sensitive(True)
+ self._smsButton.set_sensitive(False)
+ else:
+ self._dialButton.set_sensitive(False)
+ self._smsButton.set_sensitive(True)
else:
self._dialButton.set_sensitive(False)
self._smsButton.set_sensitive(True)
- def _request_number(self):
+ def _to_contact_numbers(self, contactDetails):
+ for phoneType, phoneNumber in contactDetails:
+ display = " - ".join((make_pretty(phoneNumber), phoneType))
+ yield (phoneNumber, display)
+
+ def _pseudo_destroy(self):
+ self.clear()
+ self._window.hide()
+
+ def _request_number(self, contactIndex):
+ contactNumbers, index, messages = self._contacts[contactIndex]
+ assert 0 <= index, "%r" % index
+
+ index = hildonize.touch_selector(
+ self._window,
+ "Phone Numbers",
+ (description for (number, description) in contactNumbers),
+ index,
+ )
+ self._contacts[contactIndex] = contactNumbers, index, messages
+
+ def send_sms(self, numbers, message):
+ raise NotImplementedError()
+
+ def dial(self, number):
+ raise NotImplementedError()
+
+ def _on_phone(self, *args):
try:
- assert 0 <= self._numberIndex, "%r" % self._numberIndex
+ assert len(self._contacts) == 1, "One and only one contact is required"
+ self._request_number(0)
+
+ contactNumbers, numberIndex, messages = self._contacts[0]
+ self._phoneButton.set_label(contactNumbers[numberIndex][1])
+ row = list(self._targetList.get_children())[0]
+ phoneButton = list(row.get_children())[1]
+ phoneButton.set_label(contactNumbers[numberIndex][1])
+ except Exception, e:
+ self._errorDisplay.push_exception()
- self._numberIndex = hildonize.touch_selector(
- self._dialog,
- "Phone Numbers",
- (description for (number, description) in self._contactDetails),
- self._numberIndex,
- )
- self._phoneButton.set_label(self._contactDetails[self._numberIndex][1])
+ def _on_choose_phone_n(self, button, row):
+ try:
+ assert 1 < len(self._contacts), "More than one contact required"
+ targetList = list(self._targetList.get_children())
+ index = targetList.index(row)
+ self._request_number(index)
+
+ contactNumbers, numberIndex, messages = self._contacts[0]
+ phoneButton = list(row.get_children())[1]
+ phoneButton.set_label(contactNumbers[numberIndex][1])
except Exception, e:
- _moduleLogger.exception("%s" % str(e))
+ self._errorDisplay.push_exception()
- def _on_phone(self, *args):
- self._request_number()
+ def _on_remove_phone_n(self, button, row):
+ try:
+ assert 1 < len(self._contacts), "More than one contact required"
+ targetList = list(self._targetList.get_children())
+ index = targetList.index(row)
+
+ del self._contacts[index]
+ self._targetList.remove(row)
+ self._update_context()
+ self._update_button_state()
+ except Exception, e:
+ self._errorDisplay.push_exception()
def _on_entry_changed(self, *args):
- self._update_letter_count()
+ try:
+ self._update_letter_count()
+ except Exception, e:
+ self._errorDisplay.push_exception()
def _on_send(self, *args):
- self._dialog.response(gtk.RESPONSE_OK)
- self._action = self.ACTION_SEND_SMS
+ try:
+ assert 0 < len(self._contacts), "At least one contact required (%r)" % self._contacts
+ phoneNumbers = [
+ make_ugly(contact[0][contact[1]][0])
+ for contact in self._contacts
+ ]
+
+ entryBuffer = self._smsEntry.get_buffer()
+ enteredMessage = entryBuffer.get_text(entryBuffer.get_start_iter(), entryBuffer.get_end_iter())
+ enteredMessage = enteredMessage.strip()
+ assert enteredMessage, "No message provided"
+ self.send_sms(phoneNumbers, enteredMessage)
+ self._pseudo_destroy()
+ except Exception, e:
+ self._errorDisplay.push_exception()
def _on_dial(self, *args):
- self._dialog.response(gtk.RESPONSE_OK)
- self._action = self.ACTION_DIAL
+ try:
+ assert len(self._contacts) == 1, "One and only one contact allowed (%r)" % self._contacts
+ contact = self._contacts[0]
+ contactNumber = contact[0][contact[1]][0]
+ phoneNumber = make_ugly(contactNumber)
+ self.dial(phoneNumber)
+ self._pseudo_destroy()
+ except Exception, e:
+ self._errorDisplay.push_exception()
- def _on_cancel(self, *args):
- self._dialog.response(gtk.RESPONSE_CANCEL)
- self._action = self.ACTION_CANCEL
+ def _on_delete(self, *args):
+ try:
+ self._window.emit_stop_by_name("delete-event")
+ if hildonize.IS_FREMANTLE_SUPPORTED:
+ self._window.hide()
+ else:
+ self._pseudo_destroy()
+ except Exception, e:
+ self._errorDisplay.push_exception()
+ return True
+
+ def _on_window_state_change(self, widget, event, *args):
+ 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):
+ RETURN_TYPES = (gtk.keysyms.Return, gtk.keysyms.ISO_Enter, gtk.keysyms.KP_Enter)
try:
- if event.keyval == ord("c") and event.get_state() & gtk.gdk.CONTROL_MASK:
+ if (
+ event.keyval == gtk.keysyms.F6 or
+ event.keyval in RETURN_TYPES and event.get_state() & gtk.gdk.CONTROL_MASK
+ ):
+ if self._isFullScreen:
+ self._window.unfullscreen()
+ else:
+ self._window.fullscreen()
+ elif event.keyval == ord("c") and event.get_state() & gtk.gdk.CONTROL_MASK:
message = "\n".join(
messagePart[0]
for messagePart in self._messagemodel
)
self._clipboard.set_text(str(message))
+ elif (
+ event.keyval == gtk.keysyms.h and
+ event.get_state() & gtk.gdk.CONTROL_MASK
+ ):
+ self._window.hide()
+ elif (
+ event.keyval == gtk.keysyms.w and
+ event.get_state() & gtk.gdk.CONTROL_MASK
+ ):
+ self._pseudo_destroy()
+ elif (
+ event.keyval == gtk.keysyms.q and
+ event.get_state() & gtk.gdk.CONTROL_MASK
+ ):
+ self._parent.destroy()
except Exception, e:
- _moduleLogger.exception(str(e))
+ self._errorDisplay.push_exception()
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._callButton = widgetTree.get_widget("dialpadCall")
+ self._sendSMSButton = widgetTree.get_widget("dialpadSMS")
self._backButton = widgetTree.get_widget("back")
- self._zeroOrPlusButton = widgetTree.get_widget("digit0")
+ self._plusButton = widgetTree.get_widget("plus")
self._phonenumber = ""
self._prettynumber = ""
"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._sendSMSButton.connect("clicked", self._on_sms_clicked)
+ self._callButton.connect("clicked", self._on_call_clicked)
+ self._plusButton.connect("clicked", self._on_plus)
self._originalLabel = self._backButton.get_label()
self._backTapHandler = gtk_toolbox.TapOrHold(self._backButton)
self._backTapHandler.on_hold = self._on_clearall
self._backTapHandler.on_holding = self._set_clear_button
self._backTapHandler.on_cancel = self._reset_back_button
- self._zeroOrPlusTapHandler = gtk_toolbox.TapOrHold(self._zeroOrPlusButton)
- self._zeroOrPlusTapHandler.on_tap = self._on_zero
- self._zeroOrPlusTapHandler.on_hold = self._on_plus
self._window = gtk_toolbox.find_parent_window(self._numberdisplay)
self._keyPressEventId = 0
def enable(self):
- self._dialButton.grab_focus()
+ self._sendSMSButton.grab_focus()
self._backTapHandler.enable()
- self._zeroOrPlusTapHandler.enable()
self._keyPressEventId = self._window.connect("key-press-event", self._on_key_press)
def disable(self):
self._keyPressEventId = 0
self._reset_back_button()
self._backTapHandler.disable()
- self._zeroOrPlusTapHandler.disable()
- def number_selected(self, action, number, message):
+ def add_contact(self, *args, **kwds):
"""
- @note Actual dial function is patched in later
+ @note Actual function is patched in later
+ """
+ raise NotImplementedError("Horrible unknown error has occurred")
+
+ def dial(self, number):
+ """
+ @note Actual function is patched in later
"""
raise NotImplementedError("Horrible unknown error has occurred")
self._phonenumber = make_ugly(number)
self._prettynumber = make_pretty(self._phonenumber)
self._numberdisplay.set_label("<span size='30000' weight='bold'>%s</span>" % (self._prettynumber))
+ if self._phonenumber:
+ self._plusButton.set_sensitive(False)
+ else:
+ self._plusButton.set_sensitive(True)
except TypeError, e:
self._errorDisplay.push_exception()
"""
pass
+ def set_orientation(self, orientation):
+ if orientation == gtk.ORIENTATION_VERTICAL:
+ pass
+ elif orientation == gtk.ORIENTATION_HORIZONTAL:
+ pass
+ else:
+ raise NotImplementedError(orientation)
+
def _on_key_press(self, widget, event):
try:
if event.keyval == ord("v") and event.get_state() & gtk.gdk.CONTROL_MASK:
except Exception, e:
self._errorDisplay.push_exception()
- def _on_sms_clicked(self, widget):
+ def _on_call_clicked(self, widget):
try:
phoneNumber = self.get_number()
- action, phoneNumber, message = self._smsDialog.run([("Dialer", phoneNumber)], (), self._window)
-
- if action == SmsEntryDialog.ACTION_CANCEL:
- return
- self.number_selected(action, phoneNumber, message)
+ self.dial(phoneNumber)
+ self.set_number("")
except Exception, e:
self._errorDisplay.push_exception()
- def _on_dial_clicked(self, widget):
+ def _on_sms_clicked(self, widget):
try:
- action = SmsEntryDialog.ACTION_DIAL
phoneNumber = self.get_number()
- message = ""
- self.number_selected(action, phoneNumber, message)
+ self.add_contact(
+ "(Dialpad)",
+ [("Dialer", phoneNumber)], ()
+ )
+ self.set_number("")
except Exception, e:
self._errorDisplay.push_exception()
except Exception, e:
self._errorDisplay.push_exception()
- def _on_zero(self, *args):
- try:
- self.set_number(self._phonenumber + "0")
- except Exception, e:
- self._errorDisplay.push_exception()
-
def _on_plus(self, *args):
try:
self.set_number(self._phonenumber + "+")
config.set(section, "notifyOnVoicemail", repr(self._notifyOnVoicemail))
config.set(section, "notifyOnSms", repr(self._notifyOnSms))
+ def set_orientation(self, orientation):
+ if orientation == gtk.ORIENTATION_VERTICAL:
+ pass
+ elif orientation == gtk.ORIENTATION_HORIZONTAL:
+ pass
+ else:
+ raise NotImplementedError(orientation)
+
def _populate_callback_combo(self):
self._isPopulated = True
del self._callbackList[:]
self._nameColumn.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
self._window = gtk_toolbox.find_parent_window(self._historyview)
- self._phoneTypeSelector = SmsEntryDialog(widgetTree)
self._historyFilterSelector = widgetTree.get_widget("historyFilterSelector")
self._historyFilterSelector.connect("clicked", self._on_history_filter_clicked)
self._historyview.remove_column(self._numberColumn)
self._historyview.set_model(None)
- def number_selected(self, action, number, message):
+ def add_contact(self, *args, **kwds):
"""
@note Actual dial function is patched in later
"""
"""
config.set(sectionName, "filter", self._selectedFilter)
+ def set_orientation(self, orientation):
+ if orientation == gtk.ORIENTATION_VERTICAL:
+ pass
+ elif orientation == gtk.ORIENTATION_HORIZONTAL:
+ pass
+ else:
+ raise NotImplementedError(orientation)
+
def _is_history_visible(self, model, iter):
try:
action = model.get_value(iter, self.ACTION_IDX)
except Exception, e:
self._errorDisplay.push_exception()
+ def _history_summary(self, expectedNumber):
+ for number, action, date, whoFrom, whoFromId in self._historymodel:
+ if expectedNumber is not None and expectedNumber == number:
+ yield "%s <i>(%s)</i> - %s %s" % (number, whoFrom, date, action)
+
def _on_historyview_row_activated(self, treeview, path, view_column):
try:
childPath = self._historymodelfiltered.convert_path_to_child_path(path)
if not itr:
return
- number = self._historymodel.get_value(itr, self.NUMBER_IDX)
- number = make_ugly(number)
- description = self._historymodel.get_value(itr, self.FROM_IDX)
+ prettyNumber = self._historymodel.get_value(itr, self.NUMBER_IDX)
+ number = make_ugly(prettyNumber)
+ description = list(self._history_summary(prettyNumber))
+ contactName = self._historymodel.get_value(itr, self.FROM_IDX)
contactId = self._historymodel.get_value(itr, self.FROM_ID_IDX)
- if contactId:
- contactPhoneNumbers = list(self._backend.get_contact_details(contactId))
- defaultMatches = [
- (number == make_ugly(contactNumber) or number[1:] == make_ugly(contactNumber))
- for (numberDescription, contactNumber) in contactPhoneNumbers
- ]
- try:
- defaultIndex = defaultMatches.index(True)
- except ValueError:
- contactPhoneNumbers.append(("Other", number))
- defaultIndex = len(contactPhoneNumbers)-1
- _moduleLogger.warn(
- "Could not find contact %r's number %s among %r" % (
- contactId, number, contactPhoneNumbers
- )
- )
- else:
- contactPhoneNumbers = [("Phone", number)]
- defaultIndex = -1
+ contactPhoneNumbers, defaultIndex = _get_contact_numbers(self._backend, contactId, number)
- action, phoneNumber, message = self._phoneTypeSelector.run(
+ self.add_contact(
+ contactName,
contactPhoneNumbers,
- messages = (description, ),
- parent = self._window,
+ messages = description,
defaultIndex = defaultIndex,
)
- if action == SmsEntryDialog.ACTION_CANCEL:
- return
- assert phoneNumber, "A lack of phone number exists"
-
- self.number_selected(action, phoneNumber, message)
self._historyviewselection.unselect_all()
except Exception, e:
self._errorDisplay.push_exception()
NO_MESSAGES = "None"
VOICEMAIL_MESSAGES = "Voicemail"
- TEXT_MESSAGES = "Texts"
+ TEXT_MESSAGES = "SMS"
ALL_TYPES = "All Messages"
MESSAGE_TYPES = [NO_MESSAGES, VOICEMAIL_MESSAGES, TEXT_MESSAGES, ALL_TYPES]
self._messageColumn.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
self._window = gtk_toolbox.find_parent_window(self._messageview)
- self._phoneTypeSelector = SmsEntryDialog(widgetTree)
self._messageTypeButton = widgetTree.get_widget("messageTypeButton")
self._onMessageTypeClickedId = 0
self._messageview.remove_column(self._messageColumn)
self._messageview.set_model(None)
- def number_selected(self, action, number, message):
+ def add_contact(self, *args, **kwds):
"""
@note Actual dial function is patched in later
"""
config.set(sectionName, "status", self._messageStatus)
config.set(sectionName, "type", self._messageType)
+ def set_orientation(self, orientation):
+ if orientation == gtk.ORIENTATION_VERTICAL:
+ pass
+ elif orientation == gtk.ORIENTATION_HORIZONTAL:
+ pass
+ else:
+ raise NotImplementedError(orientation)
+
def _is_message_visible(self, model, iter):
try:
message = model.get_value(iter, self.MESSAGE_DATA_IDX)
description = self._messagemodel.get_value(itr, self.MESSAGES_IDX)
contactId = self._messagemodel.get_value(itr, self.FROM_ID_IDX)
- if contactId:
- contactPhoneNumbers = list(self._backend.get_contact_details(contactId))
- defaultMatches = [
- (number == make_ugly(contactNumber) or number[1:] == make_ugly(contactNumber))
- for (numberDescription, contactNumber) in contactPhoneNumbers
- ]
- try:
- defaultIndex = defaultMatches.index(True)
- except ValueError:
- contactPhoneNumbers.append(("Other", number))
- defaultIndex = len(contactPhoneNumbers)-1
- _moduleLogger.warn(
- "Could not find contact %r's number %s among %r" % (
- contactId, number, contactPhoneNumbers
- )
- )
- else:
- contactPhoneNumbers = [("Phone", number)]
- defaultIndex = -1
+ header = self._messagemodel.get_value(itr, self.HEADER_IDX)
+ contactPhoneNumbers, defaultIndex = _get_contact_numbers(self._backend, contactId, number)
- action, phoneNumber, message = self._phoneTypeSelector.run(
+ self.add_contact(
+ header,
contactPhoneNumbers,
messages = description,
- parent = self._window,
defaultIndex = defaultIndex,
)
- if action == SmsEntryDialog.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()
self._onContactsviewRowActivatedId = 0
self._onAddressbookButtonChangedId = 0
self._window = gtk_toolbox.find_parent_window(self._contactsview)
- self._phoneTypeSelector = SmsEntryDialog(widgetTree)
self._updateSink = gtk_toolbox.threaded_stage(
gtk_toolbox.comap(
self._contactsview.set_model(None)
self._contactsview.remove_column(self._contactColumn)
- def number_selected(self, action, number, message):
+ def add_contact(self, *args, **kwds):
"""
@note Actual dial function is patched in later
"""
def save_settings(self, config, sectionName):
config.set(sectionName, "selectedAddressbook", str(self._selectedComboIndex))
+ def set_orientation(self, orientation):
+ if orientation == gtk.ORIENTATION_VERTICAL:
+ pass
+ elif orientation == gtk.ORIENTATION_HORIZONTAL:
+ pass
+ else:
+ raise NotImplementedError(orientation)
+
def _idly_populate_contactsview(self):
with gtk_toolbox.gtk_lock():
banner = hildonize.show_busy_banner_start(self._window, "Loading Contacts")
if len(contactPhoneNumbers) == 0:
return
- action, phoneNumber, message = self._phoneTypeSelector.run(
+ self.add_contact(
+ contactName,
contactPhoneNumbers,
messages = (contactName, ),
- parent = self._window,
)
- if action == SmsEntryDialog.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()