From 170a1db25454390317768be889ebfef4a24509a0 Mon Sep 17 00:00:00 2001 From: Travis Shirk Date: Wed, 25 Jan 2006 05:39:07 +0000 Subject: [PATCH] We can now chat with the same contact or join the same gc using two differenct account; closes #1421 --- src/chat_control.py | 10 +++---- src/gajim.py | 2 -- src/groupchat_control.py | 8 +++--- src/message_window.py | 62 ++++++++++++++++++++++++---------------- src/roster_window.py | 38 ++++++++++++------------ 5 files changed, 65 insertions(+), 55 deletions(-) diff --git a/src/chat_control.py b/src/chat_control.py index 225c93571..a71bacf17 100644 --- a/src/chat_control.py +++ b/src/chat_control.py @@ -378,7 +378,7 @@ class ChatControlBase(MessageControl): self.nb_unread += 1 if gajim.interface.systray_enabled and self.notify_on_new_messages(): gajim.interface.systray.add_jid(jid, self.account, self.type_id) - self.parent_win.redraw_tab(self.contact) + self.parent_win.redraw_tab(self) if not self.parent_win.is_active(): self.parent_win.show_title(urgent) @@ -492,7 +492,7 @@ class ChatControlBase(MessageControl): #we are at the end if self.nb_unread > 0: self.nb_unread = 0 + self.get_specific_unread() - self.parent_win.redraw_tab(self.contact) + self.parent_win.redraw_tab(self) self.parent_win.show_title() if gajim.interface.systray_enabled: gajim.interface.systray.remove_jid(jid, @@ -500,7 +500,7 @@ class ChatControlBase(MessageControl): self.type_id) self.msg_textview.grab_focus() # Note, we send None chatstate to preserve current - self.parent_win.redraw_tab(self.contact) + self.parent_win.redraw_tab(self) def bring_scroll_to_end(self, textview, diff_y = 0): ''' scrolls to the end of textview if end is not visible ''' @@ -576,7 +576,7 @@ class ChatControlBase(MessageControl): if self.conv_textview.at_the_end() and self.parent_win.window.is_active(): #we are at the end self.nb_unread = self.get_specific_unread() - self.parent_win.redraw_tab(self.contact) + self.parent_win.redraw_tab(self) self.parent_win.show_title() if gajim.interface.systray_enabled: gajim.interface.systray.remove_jid(jid, self.account, @@ -1197,7 +1197,7 @@ class ChatControl(ChatControlBase): ''' handle incoming chatstate that jid SENT TO us ''' self.draw_banner() # update chatstate in tab for this chat - self.parent_win.redraw_tab(self.contact, self.contact.chatstate) + self.parent_win.redraw_tab(self, self.contact.chatstate) def _on_banner_eventbox_button_press_event(self, widget, event): '''If right-clicked, show popup''' diff --git a/src/gajim.py b/src/gajim.py index 1ec6d2dbe..48b11281a 100755 --- a/src/gajim.py +++ b/src/gajim.py @@ -443,8 +443,6 @@ class Interface: # Handle chat states contact = gajim.contacts.get_first_contact_from_jid(account, jid) if chat_control and chat_control.type_id == message_control.TYPE_CHAT: - # FIXME: Why is this here? - #ctrl = gajim.interface.msg_win_mgr.get_control(jid,) if chatstate is not None: # he or she sent us reply, so he supports jep85 contact.chatstate = chatstate if contact.our_chatstate == 'ask': # we were jep85 disco? diff --git a/src/groupchat_control.py b/src/groupchat_control.py index 1eb576c8b..03247acbc 100644 --- a/src/groupchat_control.py +++ b/src/groupchat_control.py @@ -374,7 +374,7 @@ class GroupchatControl(ChatControlBase): else: kind = 'incoming' # muc-specific chatstate - self.parent_win.redraw_tab(self.contact, 'newmsg') + self.parent_win.redraw_tab(self, 'newmsg') else: kind = 'status' @@ -383,7 +383,7 @@ class GroupchatControl(ChatControlBase): (highlight, sound) = self.highlighting_for_message(text, tim) if highlight: # muc-specific chatstate - self.parent_win.redraw_tab(self.contact, 'attention') + self.parent_win.redraw_tab(self, 'attention') other_tags_for_name.append('bold') other_tags_for_text.append('marked') if sound == 'received': @@ -662,7 +662,7 @@ class GroupchatControl(ChatControlBase): c.status = status self.draw_contact(nick) - self.parent_win.redraw_tab(self.contact) + self.parent_win.redraw_tab(self) if (time.time() - self.room_creation) > 30 and \ nick != self.nick and statusCode != '303': if show == 'offline': @@ -1047,7 +1047,7 @@ class GroupchatControl(ChatControlBase): # add the focus-out line to the tab we are leaving self.check_and_possibly_add_focus_out_line() # Sending active to undo unread state - self.parent_win.redraw_tab(self.contact, 'active') + self.parent_win.redraw_tab(self, 'active') def get_specific_unread(self): # returns the number of the number of unread msgs diff --git a/src/message_window.py b/src/message_window.py index bc973cbf3..f93f36c51 100644 --- a/src/message_window.py +++ b/src/message_window.py @@ -42,6 +42,7 @@ class MessageWindow: hid = 0 # drag_data_received handler id def __init__(self, acct, type): + # A dictionary of dictionaries where _contacts[account][jid] == A MessageControl self._controls = {} # If None, the window is not tied to any specific account self.account = acct @@ -93,6 +94,12 @@ class MessageWindow: self.notebook.drag_dest_set(gtk.DEST_DEFAULT_ALL, self.DND_TARGETS, gtk.gdk.ACTION_MOVE) + def get_num_controls(self): + n = 0 + for dict in self._controls.values(): + n += len(dict) + return n + def _on_window_focus(self, widget, event): # window received focus, so if we had urgency REMOVE IT # NOTE: we do not have to read the message (it maybe in a bg tab) @@ -104,11 +111,11 @@ class MessageWindow: ctrl.set_control_active(True) # Undo "unread" state display, etc. if ctrl.type_id == message_control.TYPE_GC: - self.redraw_tab(ctrl.contact, 'active') + self.redraw_tab(ctrl, 'active') else: # NOTE: we do not send any chatstate to preserve # inactive, gone, etc. - self.redraw_tab(ctrl.contact) + self.redraw_tab(ctrl) def _on_window_delete(self, win, event): # Make sure all controls are okay with being deleted @@ -123,8 +130,11 @@ class MessageWindow: self._controls.clear() def new_tab(self, control): - self._controls[control.contact.jid] = control - if len(self._controls) > 1: + if not self._controls.has_key(control.account): + self._controls[control.account] = {} + self._controls[control.account][control.contact.jid] = control + + if self.get_num_controls() > 1: self.notebook.set_show_tabs(True) self.alignment.set_property('top-padding', 2) @@ -139,8 +149,7 @@ class MessageWindow: self.setup_tab_dnd(control.widget) - self.redraw_tab(control.contact) - control.update_ui() + self.redraw_tab(control) self.window.show_all() # NOTE: we do not call set_control_active(True) since we don't know whether # the tab is the active one. @@ -210,8 +219,7 @@ class MessageWindow: gtkgui_helpers.set_unset_urgency_hint(self.window, False) def set_active_tab(self, jid, acct): - # FIXME: Use acct - ctrl = self._controls[jid] + ctrl = self._controls[acct][jid] ctrl_page = self.notebook.page_num(ctrl.widget) self.notebook.set_current_page(ctrl_page) @@ -230,15 +238,18 @@ class MessageWindow: self.disconnect_tab_dnd(ctrl.widget) self.notebook.remove_page(self.notebook.page_num(ctrl.widget)) - del self._controls[ctrl.contact.jid] - if len(self._controls) == 1: # we are going from two tabs to one + del self._controls[ctrl.account][ctrl.contact.jid] + if len(self._controls[ctrl.account]) == 0: + del self._controls[ctrl.account] + + if self.get_num_controls() == 1: # we are going from two tabs to one show_tabs_if_one_tab = gajim.config.get('tabs_always_visible') self.notebook.set_show_tabs(show_tabs_if_one_tab) if not show_tabs_if_one_tab: self.alignment.set_property('top-padding', 0) self.show_title() - elif len(self._controls) == 0: - # FIXME: These are not called when the window is destroyed like this, fake it + elif self.get_num_controls() == 0: + # These are not called when the window is destroyed like this, fake it gajim.interface.msg_win_mgr._on_window_delete(self.window, None) gajim.interface.msg_win_mgr._on_window_destroy(self.window) # dnd clean up @@ -247,8 +258,7 @@ class MessageWindow: self.window.destroy() - def redraw_tab(self, contact, chatstate = None): - ctrl = self._controls[contact.jid] + def redraw_tab(self, ctrl, chatstate = None): ctrl.update_ui() hbox = self.notebook.get_tab_label(ctrl.widget).get_children()[0] @@ -322,16 +332,15 @@ class MessageWindow: def get_control(self, key, acct): '''Return the MessageControl for jid or n, where n is a notebook page index. When key is an int index acct may be None''' - # FIXME: Use acct if isinstance(key, str): key = unicode(key, 'utf-8') if isinstance(key, unicode): jid = key - for ctrl in self.controls(): - if ctrl.contact.jid == jid: - return ctrl - return None + try: + return self._controls[acct][jid] + except: + return None else: page_num = key notebook = self.notebook @@ -341,8 +350,9 @@ class MessageWindow: return self._widget_to_control(nth_child) def controls(self): - for ctrl in self._controls.values(): - yield ctrl + for ctrl_dict in self._controls.values(): + for ctrl in ctrl_dict.values(): + yield ctrl def update_print_time(self): if gajim.config.get('print_time') != 'sometimes': @@ -394,7 +404,7 @@ class MessageWindow: def popup_menu(self, event): menu = self.get_active_control().prepare_context_menu() # common menuitems (tab switches) - if len(self._controls) > 1: # if there is more than one tab + if self.get_num_controls() > 1: # if there is more than one tab menu.append(gtk.SeparatorMenuItem()) # seperator for ctrl in self.controls(): jid = ctrl.contact.jid @@ -582,7 +592,7 @@ class MessageWindowMgr: return None def has_window(self, jid, acct): - return self.get_window(jid, acct) + return self.get_window(jid, acct) != None def one_window_opened(self, contact, acct, type): try: @@ -637,7 +647,7 @@ class MessageWindowMgr: def _mode_to_key(self, contact, acct, type): if self.mode == self.CONFIG_NEVER: - key = contact.jid + key = acct + contact.jid elif self.mode == self.CONFIG_ALWAYS: key = self.MAIN_WIN elif self.mode == self.CONFIG_PERACCT: @@ -776,12 +786,14 @@ class MessageWindowMgr: w.notebook.remove_page(0) page.unparent() controls.append(ctrl) + # Must clear _controls from window to prevent MessageControl.shutdown calls + w._controls = {} w.window.destroy() self._windows = {} for ctrl in controls: - mw = self.get_window(ctrl.contact.jid, ctr.account) + mw = self.get_window(ctrl.contact.jid, ctrl.account) if not mw: mw = self.create_window(ctrl.contact, ctrl.account, ctrl.type_id) ctrl.parent_win = mw diff --git a/src/roster_window.py b/src/roster_window.py index 4d2985209..ea35e5343 100644 --- a/src/roster_window.py +++ b/src/roster_window.py @@ -639,9 +639,9 @@ class RosterWindow: for win in gajim.interface.msg_win_mgr.windows(): win.repaint_themed_widgets() # update gc's roster - for ctl in gajim.interface.msg_win_mgr.controls(): - if ctl.type_id == message_control.TYPE_GC: - ctl.update_ui() + for ctrl in gajim.interface.msg_win_mgr.controls(): + if ctrl.type_id == message_control.TYPE_GC: + ctrl.update_ui() def draw_roster(self): '''Clear and draw roster''' @@ -729,19 +729,19 @@ class RosterWindow: if gajim.interface.msg_win_mgr.has_window(contact.jid, account): jid = contact.jid win = gajim.interface.msg_win_mgr.get_window(contact.jid, account) - ctl = win.get_control(jid, account) - ctl.update_ui() - win.redraw_tab(contact) + ctrl = win.get_control(jid, account) + ctrl.update_ui() + win.redraw_tab(ctrl) name = contact.get_shown_name() if contact.resource != '': name += '/' + contact.resource uf_show = helpers.get_uf_show(show) - ctl.print_conversation(_('%s is now %s (%s)') % (name, uf_show, status), + ctrl.print_conversation(_('%s is now %s (%s)') % (name, uf_show, status), 'status') if contact == gajim.contacts.get_contact_with_highest_priority(account, contact.jid): - ctl.draw_banner() + ctrl.draw_banner() def on_info(self, widget, contact, account): '''Call vcard_information_window class to display contact's information''' @@ -924,8 +924,8 @@ class RosterWindow: for u in gajim.contacts.get_contact(account, contact.jid): u.keyID = keyID[0] if gajim.interface.msg_win_mgr.has_window(contact.jid, account): - ctl = gajim.interface.msg_win_mgr.get_control(contact.jid, account) - ctl.update_ui() + ctrl = gajim.interface.msg_win_mgr.get_control(contact.jid, account) + ctrl.update_ui() keys_str = '' for jid in keys: keys_str += jid + ' ' + keys[jid] + ' ' @@ -1789,8 +1789,8 @@ _('If "%s" accepts this request you will know his or her status.') % jid) typ = '' if msg_type == 'error': typ = 'status' - ctl = gajim.interface.msg_win_mgr.get_control(jid, account) - ctl.print_conversation(msg, typ, tim = tim, encrypted = encrypted, + ctrl = gajim.interface.msg_win_mgr.get_control(jid, account) + ctrl.print_conversation(msg, typ, tim = tim, encrypted = encrypted, subject = subject) return @@ -1982,14 +1982,14 @@ _('If "%s" accepts this request you will know his or her status.') % jid) unread = True for win in gajim.interface.msg_win_mgr.windows(): unrd = 0 - for ctl in win.controls(): - unrd += ctl.nb_unread + for ctrl in win.controls(): + unrd += ctrl.nb_unread if unrd: unread = True break - for ctl in win.controls(): - jid = ctl.contact.jid + for ctrl in win.controls(): + jid = ctrl.contact.jid if gajim.last_message_time[acct].has_key(jid): if time.time() - gajim.last_message_time[acct][jid] < 2: recent = True @@ -2253,9 +2253,9 @@ _('If "%s" accepts this request you will know his or her status.') % jid) gajim.interface.systray.set_img() for win in gajim.interface.msg_win_mgr.windows(): - for ctl in gajim.interface.msg_win_mgr.controls(): - ctl.update_ui() - win.redraw_tab(ctl.contact) + for ctrl in gajim.interface.msg_win_mgr.controls(): + ctrl.update_ui() + win.redraw_tab(ctrl) self.update_status_combobox()