In playing with direct dial I found I setup the user-agent incorrectly
[gc-dialer] / src / gv_views.py
index 3bb89f3..f9e5349 100644 (file)
@@ -65,22 +65,21 @@ def normalize_number(prettynumber):
        '+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], )
@@ -98,13 +97,9 @@ def _make_pretty_local(phonenumber):
 
 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
 
 
@@ -148,10 +143,10 @@ def make_pretty(phonenumber):
                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:
@@ -220,16 +215,63 @@ def collapse_message(message, maxCharsPerLine, maxLines):
        return "\n".join(_collapse_message(messageLines, maxCharsPerLine, maxLines))
 
 
+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
+
+
 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._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)
@@ -264,57 +306,68 @@ class SmsEntryWindow(object):
                self._smsEntry.get_buffer().connect("changed", self._on_entry_changed)
                self._smsEntrySize = None
 
-               self._numberIndex = -1
                self._contacts = []
 
-       def add_contact(self, contactDetails, messages = (), parent = None, defaultIndex = -1):
+       def add_contact(self, name, contactDetails, messages = (), defaultIndex = -1):
                contactNumbers = list(self._to_contact_numbers(contactDetails))
-               assert contactNumbers
+               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])
-               #selector.connect("clicked", , len(self._contacts)) TODO
+               if len(contactNumbers) == 1:
+                       selector.set_sensitive(False)
                removeContact = gtk.Button(stock="gtk-delete")
-               #removeContact.connect("clicked", , len(self._contacts)) TODO
                row = gtk.HBox()
+               row.pack_start(nameLabel, True, True)
                row.pack_start(selector, True, True)
                row.pack_start(removeContact, False, False)
                row.show_all()
-               # @bug List appears to be coming up backwards
-               self._targetList.pack_end(row)
+               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()
 
-               if parent is not None:
-                       parentSize = parent.get_size()
-                       self._window.resize(parentSize[0], max(parentSize[1]-10, 100))
+               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()
-               dx = self._conversationView.get_allocation().height - self._conversationViewPort.get_allocation().height
-               dx = max(dx, 0)
-               adjustment = self._scrollWindow.get_vadjustment()
-               adjustment.value = dx
+               self._scroll_to_bottom()
 
        def clear(self):
                del self._contacts[:]
 
-               for contactNumberSelector in list(self._targetList.get_children()):
-                       self._targetList.remove(contactNumberSelector)
+               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()
 
+       def fullscreen(self):
+               self._window.fullscreen()
+
+       def unfullscreen(self):
+               self._window.unfullscreen()
+
        def _remove_contact(self, contactIndex):
                del self._contacts[contactIndex]
 
-               contactNumberSelector = list(self._targetList.get_children())[contactIndex]
-               self._targetList.remove(contactNumberSelector)
+               row = list(self._targetList.get_children())[contactIndex]
+               self._targetList.remove(row)
                self._update_button_state()
                self._update_context()
+               self._scroll_to_bottom()
+
+       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
 
        def _update_letter_count(self):
                if self._smsEntrySize is None:
@@ -383,67 +436,155 @@ class SmsEntryWindow(object):
                        display = " - ".join((make_pretty(phoneNumber), phoneType))
                        yield (phoneNumber, display)
 
-       def _request_number(self):
-               try:
-                       assert 0 <= self._numberIndex, "%r" % self._numberIndex
-
-                       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])
-               except Exception, e:
-                       _moduleLogger.exception("%s" % str(e))
-
-       def _hide(self):
+       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):
-               self._request_number()
+               try:
+                       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()
+
+       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:
+                       self._errorDisplay.push_exception()
+
+       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):
-               assert 0 < len(self._contacts), "%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
-               # @todo
-               self._hide()
+               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):
-               assert len(self._contacts) == 1, "%r" % self._contacts
-               contact = self._contacts[0]
-               contactNumber = contact[0][contact[1]][0]
-               phoneNumber = make_ugly(contactNumber)
-               # @todo
-               self._hide()
+               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_delete(self, *args):
-               self._window.emit_stop_by_name("delete-event")
-               self._hide()
+               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):
@@ -453,10 +594,10 @@ class Dialpad(object):
                self._errorDisplay = errorDisplay
 
                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 = ""
 
@@ -464,8 +605,9 @@ class Dialpad(object):
                        "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)
@@ -473,17 +615,13 @@ class Dialpad(object):
                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):
@@ -491,11 +629,16 @@ class Dialpad(object):
                self._keyPressEventId = 0
                self._reset_back_button()
                self._backTapHandler.disable()
-               self._zeroOrPlusTapHandler.disable()
 
        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")
 
@@ -510,6 +653,10 @@ class Dialpad(object):
                        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()
 
@@ -529,6 +676,14 @@ class Dialpad(object):
                """
                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:
@@ -538,19 +693,22 @@ class Dialpad(object):
                except Exception, e:
                        self._errorDisplay.push_exception()
 
-       def _on_sms_clicked(self, widget):
+       def _on_call_clicked(self, widget):
                try:
                        phoneNumber = self.get_number()
-                       self.add_contact(
-                               [("Dialer", phoneNumber)], (), self._window
-                       )
+                       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:
-                       #self.number_selected(action, phoneNumbers, message) TODO
-                       pass
+                       phoneNumber = self.get_number()
+                       self.add_contact(
+                               "(Dialpad)",
+                               [("Dialer", phoneNumber)], ()
+                       )
+                       self.set_number("")
                except Exception, e:
                        self._errorDisplay.push_exception()
 
@@ -560,12 +718,6 @@ class Dialpad(object):
                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 + "+")
@@ -728,6 +880,14 @@ class AccountInfo(object):
                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[:]
@@ -1024,6 +1184,14 @@ class CallHistoryView(object):
                """
                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)
@@ -1094,6 +1262,11 @@ class CallHistoryView(object):
                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)
@@ -1101,34 +1274,17 @@ class CallHistoryView(object):
                        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)
 
                        self.add_contact(
+                               contactName,
                                contactPhoneNumbers,
-                               messages = (description, ),
-                               parent = self._window,
+                               messages = description,
                                defaultIndex = defaultIndex,
                        )
                        self._historyviewselection.unselect_all()
@@ -1148,7 +1304,7 @@ class MessagesView(object):
 
        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]
 
@@ -1272,6 +1428,14 @@ class MessagesView(object):
                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)
@@ -1368,30 +1532,13 @@ class MessagesView(object):
                        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)
 
                        self.add_contact(
+                               header,
                                contactPhoneNumbers,
                                messages = description,
-                               parent = self._window,
                                defaultIndex = defaultIndex,
                        )
                        self._messageviewselection.unselect_all()
@@ -1586,6 +1733,14 @@ class ContactsView(object):
        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")
@@ -1663,9 +1818,9 @@ class ContactsView(object):
                                return
 
                        self.add_contact(
+                               contactName,
                                contactPhoneNumbers,
                                messages = (contactName, ),
-                               parent = self._window,
                        )
                        self._contactsviewselection.unselect_all()
                except Exception, e: