We can now chat with the same contact or join the same gc using two differenct account;
closes #1421
This commit is contained in:
		
							parent
							
								
									2b956ec93c
								
							
						
					
					
						commit
						170a1db254
					
				
					 5 changed files with 65 additions and 55 deletions
				
			
		| 
						 | 
				
			
			@ -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'''
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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?
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue