From b1ce1107deeb4b22e80d2efaf3d22a88c81815d4 Mon Sep 17 00:00:00 2001 From: Yann Leboulanger Date: Tue, 14 Mar 2006 13:10:09 +0000 Subject: [PATCH] we can now talk to a specific resource --- src/chat_control.py | 15 ++++++----- src/common/connection.py | 11 +++++--- src/message_control.py | 7 ++--- src/message_window.py | 17 +++++++----- src/roster_window.py | 57 +++++++++++++++++++++++++++++----------- 5 files changed, 72 insertions(+), 35 deletions(-) diff --git a/src/chat_control.py b/src/chat_control.py index 2b0f612c0..2d099346f 100644 --- a/src/chat_control.py +++ b/src/chat_control.py @@ -76,9 +76,9 @@ class ChatControlBase(MessageControl): def handle_message_textview_mykey_press(self, widget, event_keyval, event_keymod): pass # Derived should implement this rather than connecting to the event itself. - def __init__(self, type_id, parent_win, widget_name, display_names, contact, acct): + def __init__(self, type_id, parent_win, widget_name, display_names, contact, acct, resource = None): MessageControl.__init__(self, type_id, parent_win, widget_name, display_names, - contact, acct); + contact, acct, resource = resource); # FIXME: These are hidden from 0.8 on, but IMO all these things need # to be shown optionally. Esp. the never-used Send button @@ -343,15 +343,16 @@ class ChatControlBase(MessageControl): return True return False - def send_message(self, message, keyID = '', type = 'chat', chatstate = None, msg_id = None, - composing_jep = None): + def send_message(self, message, keyID = '', type = 'chat', chatstate = None, + msg_id = None, composing_jep = None, resource = None): '''Send the given message to the active tab''' if not message or message == '\n': return if not self._process_command(message): MessageControl.send_message(self, message, keyID, type = type, - chatstate = chatstate, msg_id = msg_id, composing_jep = composing_jep) + chatstate = chatstate, msg_id = msg_id, + composing_jep = composing_jep, resource = resource) # Record message history self.save_sent_message(message) @@ -681,9 +682,9 @@ class ChatControl(ChatControlBase): '''A control for standard 1-1 chat''' TYPE_ID = message_control.TYPE_CHAT - def __init__(self, parent_win, contact, acct): + def __init__(self, parent_win, contact, acct, resource = None): ChatControlBase.__init__(self, self.TYPE_ID, parent_win, 'chat_child_vbox', - (_('Chat'), _('Chats')), contact, acct) + (_('Chat'), _('Chats')), contact, acct, resource) self.compact_view_always = gajim.config.get('always_compact_view_chat') self.set_compact_view(self.compact_view_always) diff --git a/src/common/connection.py b/src/common/connection.py index 9827ffeaf..f9872ce58 100644 --- a/src/common/connection.py +++ b/src/common/connection.py @@ -2140,11 +2140,14 @@ class Connection: self.connection.send(msg_iq) def send_message(self, jid, msg, keyID, type = 'chat', subject='', - chatstate = None, msg_id = None, composing_jep = None): + chatstate = None, msg_id = None, composing_jep = None, resource = None): if not self.connection: return if not msg and chatstate is None: return + fjid = jid + if resource: + fjid += '/' + resource msgtxt = msg msgenc = '' if keyID and USE_GPG: @@ -2157,13 +2160,13 @@ class Connection: msgtxt = _('[This message is encrypted]') +\ ' ([This message is encrypted])' # one in locale and one en if type == 'chat': - msg_iq = common.xmpp.Message(to = jid, body = msgtxt, typ = type) + msg_iq = common.xmpp.Message(to = fjid, body = msgtxt, typ = type) else: if subject: - msg_iq = common.xmpp.Message(to = jid, body = msgtxt, + msg_iq = common.xmpp.Message(to = fjid, body = msgtxt, typ = 'normal', subject = subject) else: - msg_iq = common.xmpp.Message(to = jid, body = msgtxt, + msg_iq = common.xmpp.Message(to = fjid, body = msgtxt, typ = 'normal') if msgenc: msg_iq.setTag(common.xmpp.NS_ENCRYPTED + ' x').setData(msgenc) diff --git a/src/message_control.py b/src/message_control.py index 7662688fd..3c99f9dc1 100644 --- a/src/message_control.py +++ b/src/message_control.py @@ -37,7 +37,7 @@ GTKGUI_GLADE = 'gtkgui.glade' class MessageControl: '''An abstract base widget that can embed in the gtk.Notebook of a MessageWindow''' - def __init__(self, type_id, parent_win, widget_name, display_names, contact, account): + def __init__(self, type_id, parent_win, widget_name, display_names, contact, account, resource = None): '''The display_names argument is a two element tuple containing the desired display name (pretty string) for the control in both singular and plural form''' self.type_id = type_id @@ -50,6 +50,7 @@ class MessageControl: self.compact_view_current = False self.nb_unread = 0 self.print_time_timeout_id = None + self.resource = resource gajim.last_message_time[self.account][contact.jid] = 0 @@ -134,13 +135,13 @@ class MessageControl: return n def send_message(self, message, keyID = '', type = 'chat', - chatstate = None, msg_id = None, composing_jep = None): + chatstate = None, msg_id = None, composing_jep = None, resource = None): '''Send the given message to the active tab''' jid = self.contact.jid # Send and update history gajim.connections[self.account].send_message(jid, message, keyID, type = type, chatstate = chatstate, msg_id = msg_id, - composing_jep = composing_jep) + composing_jep = composing_jep, resource = self.resource) def position_menu_under_button(self, menu): #FIXME: BUG http://bugs.gnome.org/show_bug.cgi?id=316786 diff --git a/src/message_window.py b/src/message_window.py index 69f05bf94..050da2cf1 100644 --- a/src/message_window.py +++ b/src/message_window.py @@ -139,7 +139,10 @@ class MessageWindow: def new_tab(self, control): if not self._controls.has_key(control.account): self._controls[control.account] = {} - self._controls[control.account][control.contact.jid] = control + fjid = control.contact.jid + if control.resource: + fjid += '/' + control.resource + self._controls[control.account][fjid] = control if self.get_num_controls() > 1: self.notebook.set_show_tabs(True) @@ -148,8 +151,8 @@ class MessageWindow: # Add notebook page and connect up to the tab's close button xml = gtk.glade.XML(GTKGUI_GLADE, 'chat_tab_ebox', APP) tab_label_box = xml.get_widget('chat_tab_ebox') - xml.signal_connect('on_close_button_clicked', self._on_close_button_clicked, - control) + xml.signal_connect('on_close_button_clicked', + self._on_close_button_clicked, control) xml.signal_connect('on_tab_eventbox_button_press_event', self.on_tab_eventbox_button_press_event, control.widget) self.notebook.append_page(control.widget, tab_label_box) @@ -668,9 +671,11 @@ class MessageWindowMgr: gtkgui_helpers.move_window(win.window, pos[0], pos[1]) - def _mode_to_key(self, contact, acct, type): + def _mode_to_key(self, contact, acct, type, resource = None): if self.mode == self.ONE_MSG_WINDOW_NEVER: key = acct + contact.jid + if resource: + key += '/' + resource elif self.mode == self.ONE_MSG_WINDOW_ALWAYS: key = self.MAIN_WIN elif self.mode == self.ONE_MSG_WINDOW_PERACCT: @@ -679,13 +684,13 @@ class MessageWindowMgr: key = type return key - def create_window(self, contact, acct, type): + def create_window(self, contact, acct, type, resource = None): key = None win_acct = None win_type = None win_role = 'messages' - key = self._mode_to_key(contact, acct, type) + key = self._mode_to_key(contact, acct, type, resource) if self.mode == self.ONE_MSG_WINDOW_PERACCT: win_acct = acct win_role = acct diff --git a/src/roster_window.py b/src/roster_window.py index 242046ff2..04c971003 100644 --- a/src/roster_window.py +++ b/src/roster_window.py @@ -1137,6 +1137,28 @@ class RosterWindow: information_menuitem = childs[12] history_menuitem = childs[13] + contacts = gajim.contacts.get_contact(account, jid) + if len(contacts) > 1: # sevral resources + sub_menu = gtk.Menu() + start_chat_menuitem.set_submenu(sub_menu) + + iconset = gajim.config.get('iconset') + if not iconset: + iconset = DEFAULT_ICONSET + path = os.path.join(gajim.DATA_DIR, 'iconsets', iconset, '16x16') + state_images = self.load_iconset(path) + for c in contacts: + item = gtk.ImageMenuItem(c.resource + ' (' + str(c.priority) + ')') + icon_name = helpers.get_icon_name_to_show(c, account) + icon = state_images[icon_name] + item.set_image(icon) + sub_menu.append(item) + item.connect('activate', self.on_open_chat_window, c, account, + c.resource) + + else: # one resource + start_chat_menuitem.connect('activate', + self.on_roster_treeview_row_activated, path) if contact.resource: send_file_menuitem.connect('activate', @@ -1145,8 +1167,6 @@ class RosterWindow: send_file_menuitem.hide() send_file_menuitem.set_no_show_all(True) - start_chat_menuitem.connect('activate', - self.on_roster_treeview_row_activated, path) send_single_message_menuitem.connect('activate', self.on_send_single_message_menuitem_activate, account, contact) rename_menuitem.connect('activate', self.on_rename, iter, path) @@ -1855,19 +1875,22 @@ _('If "%s" accepts this request you will know his or her status.') % jid) self.actions_menu_needs_rebuild = True self.update_status_combobox() - def new_chat(self, contact, account, private_chat = False): + def new_chat(self, contact, account, private_chat = False, resource = None): # Get target window, create a control, and associate it with the window if not private_chat: type = message_control.TYPE_CHAT else: type = message_control.TYPE_PM - mw = gajim.interface.msg_win_mgr.get_window(contact.jid, account) + fjid = contact.jid + if resource: + fjid += '/' + resource + mw = gajim.interface.msg_win_mgr.get_window(fjid, account) if not mw: mw = gajim.interface.msg_win_mgr.create_window(contact, account, type) if not private_chat: - chat_control = ChatControl(mw, contact, account) + chat_control = ChatControl(mw, contact, account, resource) else: chat_control = PrivateChatControl(mw, contact, account) @@ -2217,6 +2240,19 @@ _('If "%s" accepts this request you will know his or her status.') % jid) return True return False + def on_open_chat_window(self, widget, contact, account, resource = None): + # Get the window containing the chat + fjid = contact.jid + if resource: + fjid += '/' + resource + win = gajim.interface.msg_win_mgr.get_window(fjid, account) + if not win: + self.new_chat(contact, account, resource = resource) + gajim.last_message_time[account][contact.jid] = 0 # long time ago + win = gajim.interface.msg_win_mgr.get_window(fjid, account) + win.set_active_tab(fjid, account) + win.window.present() + def on_roster_treeview_row_activated(self, widget, path, col = 0): '''When an iter is double clicked: open the first event window''' model = self.tree.get_model() @@ -2244,16 +2280,7 @@ _('If "%s" accepts this request you will know his or her status.') % jid) if self.open_event(account, jid, first_ev): return c = gajim.contacts.get_contact_with_highest_priority(account, jid) - # Get the window containing the chat - win = gajim.interface.msg_win_mgr.get_window(jid, account) - if win: - win.set_active_tab(jid, account) - elif c: - self.new_chat(c, account) - gajim.last_message_time[account][c.jid] = 0 # long time ago - win = gajim.interface.msg_win_mgr.get_window(jid, account) - win.set_active_tab(jid, account) - win.window.present() + self.on_open_chat_window(widget, c, account) def on_roster_treeview_row_expanded(self, widget, iter, path): '''When a row is expanded change the icon of the arrow'''