From b3b34310721c514c140ec295ee719805f739e944 Mon Sep 17 00:00:00 2001
From: Yann Leboulanger <asterix@lagaule.org>
Date: Wed, 19 Jul 2006 10:49:23 +0000
Subject: [PATCH] add a self contact when another resource is connected to our
 account. Fixes #744 and usefull for ad-hoc commands

---
 data/glade/roster_contact_context_menu.glade | 30 ++++----
 src/gajim.py                                 | 18 +++--
 src/roster_window.py                         | 76 ++++++++++++++++----
 3 files changed, 93 insertions(+), 31 deletions(-)

diff --git a/data/glade/roster_contact_context_menu.glade b/data/glade/roster_contact_context_menu.glade
index 60a98dfc30..0f54cfd2af 100644
--- a/data/glade/roster_contact_context_menu.glade
+++ b/data/glade/roster_contact_context_menu.glade
@@ -2,6 +2,7 @@
 <!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
 
 <glade-interface>
+
 <widget class="GtkMenu" id="roster_contact_context_menu">
 
   <child>
@@ -11,7 +12,7 @@
       <property name="use_underline">True</property>
 
       <child internal-child="image">
-	<widget class="GtkImage" id="image1423">
+	<widget class="GtkImage" id="image1447">
 	  <property name="visible">True</property>
 	  <property name="stock">gtk-jump-to</property>
 	  <property name="icon_size">1</property>
@@ -31,7 +32,7 @@
       <property name="use_underline">True</property>
 
       <child internal-child="image">
-	<widget class="GtkImage" id="image1424">
+	<widget class="GtkImage" id="image1448">
 	  <property name="visible">True</property>
 	  <property name="stock">gtk-new</property>
 	  <property name="icon_size">1</property>
@@ -50,7 +51,7 @@
       <property name="use_underline">True</property>
 
       <child internal-child="image">
-	<widget class="GtkImage" id="image1425">
+	<widget class="GtkImage" id="image1449">
 	  <property name="visible">True</property>
 	  <property name="stock">gtk-refresh</property>
 	  <property name="icon_size">1</property>
@@ -83,7 +84,7 @@
       <property name="use_underline">True</property>
 
       <child internal-child="image">
-	<widget class="GtkImage" id="image1426">
+	<widget class="GtkImage" id="image1450">
 	  <property name="visible">True</property>
 	  <property name="stock">gtk-file</property>
 	  <property name="icon_size">1</property>
@@ -103,7 +104,7 @@
       <signal name="activate" handler="on_assign_openpgp_key_menuitem_activate" last_modification_time="Thu, 30 Jun 2005 22:57:59 GMT"/>
 
       <child internal-child="image">
-	<widget class="GtkImage" id="image1427">
+	<widget class="GtkImage" id="image1451">
 	  <property name="visible">True</property>
 	  <property name="stock">gtk-dialog-authentication</property>
 	  <property name="icon_size">1</property>
@@ -123,7 +124,7 @@
       <property name="use_underline">True</property>
 
       <child internal-child="image">
-	<widget class="GtkImage" id="image1428">
+	<widget class="GtkImage" id="image1452">
 	  <property name="visible">True</property>
 	  <property name="stock">gtk-info</property>
 	  <property name="icon_size">1</property>
@@ -137,7 +138,7 @@
   </child>
 
   <child>
-    <widget class="GtkSeparatorMenuItem" id="separator5">
+    <widget class="GtkSeparatorMenuItem" id="above_subscription_separator">
       <property name="visible">True</property>
     </widget>
   </child>
@@ -148,7 +149,7 @@
       <property name="use_underline">True</property>
 
       <child internal-child="image">
-	<widget class="GtkImage" id="image1429">
+	<widget class="GtkImage" id="image1453">
 	  <property name="visible">True</property>
 	  <property name="stock">gtk-dialog-question</property>
 	  <property name="icon_size">1</property>
@@ -169,7 +170,7 @@
 	      <property name="use_underline">True</property>
 
 	      <child internal-child="image">
-		<widget class="GtkImage" id="image1430">
+		<widget class="GtkImage" id="image1454">
 		  <property name="visible">True</property>
 		  <property name="stock">gtk-go-up</property>
 		  <property name="icon_size">1</property>
@@ -189,7 +190,7 @@
 	      <property name="use_underline">True</property>
 
 	      <child internal-child="image">
-		<widget class="GtkImage" id="image1431">
+		<widget class="GtkImage" id="image1455">
 		  <property name="visible">True</property>
 		  <property name="stock">gtk-go-down</property>
 		  <property name="icon_size">1</property>
@@ -209,7 +210,7 @@
 	      <property name="use_underline">True</property>
 
 	      <child internal-child="image">
-		<widget class="GtkImage" id="image1432">
+		<widget class="GtkImage" id="image1456">
 		  <property name="visible">True</property>
 		  <property name="stock">gtk-stop</property>
 		  <property name="icon_size">1</property>
@@ -232,7 +233,7 @@
       <property name="use_underline">True</property>
 
       <child internal-child="image">
-	<widget class="GtkImage" id="image1433">
+	<widget class="GtkImage" id="image1457">
 	  <property name="visible">True</property>
 	  <property name="stock">gtk-add</property>
 	  <property name="icon_size">1</property>
@@ -251,7 +252,7 @@
       <property name="use_underline">True</property>
 
       <child internal-child="image">
-	<widget class="GtkImage" id="image1434">
+	<widget class="GtkImage" id="image1458">
 	  <property name="visible">True</property>
 	  <property name="stock">gtk-remove</property>
 	  <property name="icon_size">1</property>
@@ -283,7 +284,7 @@
       <property name="use_underline">True</property>
 
       <child internal-child="image">
-	<widget class="GtkImage" id="image1435">
+	<widget class="GtkImage" id="image1459">
 	  <property name="visible">True</property>
 	  <property name="stock">gtk-justify-fill</property>
 	  <property name="icon_size">1</property>
@@ -296,4 +297,5 @@
     </widget>
   </child>
 </widget>
+
 </glade-interface>
diff --git a/src/gajim.py b/src/gajim.py
index 7aacbfc56a..558b10a321 100755
--- a/src/gajim.py
+++ b/src/gajim.py
@@ -377,7 +377,7 @@ class Interface:
 
 		# Update contact
 		jid_list = gajim.contacts.get_jid_list(account)
-		if ji in jid_list:
+		if ji in jid_list or jid == gajim.get_jid_from_account(account):
 			lcontact = gajim.contacts.get_contacts_from_jid(account, ji)
 			contact1 = None
 			resources = []
@@ -394,7 +394,18 @@ class Interface:
 					return
 			else:
 				contact1 = gajim.contacts.get_first_contact_from_jid(account, ji)
-				if contact1.show in statuss:
+				if not contact1:
+					# presence of another resource of out jid
+					contact1 = gajim.contacts.create_contact(jid = ji,
+						name = gajim.nicks[account], groups = [],
+						show = array[1], status = status_message, sub = 'both',
+						ask = 'none', priority = priority, keyID = keyID,
+						resource = resource)
+					old_show = 0
+					gajim.contacts.add_contact(account, contact1)
+					lcontact.append(contact1)
+					self.roster.add_self_contact(account)
+				elif contact1.show in statuss:
 					old_show = statuss.index(contact1.show)
 				if (resources != [''] and (len(lcontact) != 1 or 
 					lcontact[0].show != 'offline')) and jid.find('@') > 0:
@@ -440,9 +451,6 @@ class Interface:
 				gajim.block_signed_in_notifications[account_ji] = True
 				gobject.timeout_add(30000, self.unblock_signed_in_notifications,
 					account_ji)
-		elif jid == gajim.get_jid_from_account(account):
-			# It's another of our resources.  We don't need to see that!
-			return
 		elif ji in jid_list:
 			# It isn't an agent
 			# reset chatstate if needed:
diff --git a/src/roster_window.py b/src/roster_window.py
index a741e0fcf5..034b2b5993 100644
--- a/src/roster_window.py
+++ b/src/roster_window.py
@@ -82,6 +82,12 @@ class RosterWindow:
 		return group_iter
 
 	def get_contact_iter(self, jid, account):
+		if jid == gajim.get_jid_from_account(account):
+			iter = self.get_self_contact_iter(account)
+			if iter:
+				return [iter]
+			else:
+				return []
 		model = self.tree.get_model()
 		acct = self.get_account_iter(account)
 		found = []
@@ -203,6 +209,9 @@ class RosterWindow:
 		# If contact already in roster, do not add it
 		if len(self.get_contact_iter(jid, account)):
 			return
+		if jid == gajim.get_jid_from_account(account):
+			self.add_self_contact(account)
+			return
 		if gajim.jid_is_transport(contact.jid):
 			contact.groups = [_('Transports')]
 
@@ -324,6 +333,29 @@ class RosterWindow:
 				data['jid'])
 			self.add_contact_to_roster(data['jid'], data['account'])
 
+	def get_self_contact_iter(self, account):
+		model = self.tree.get_model()
+		iterAcct = self.get_account_iter(account)
+		iter = model.iter_children(iterAcct)
+		if not iter:
+			return None
+		if model[iter][C_TYPE] == 'self_contact':
+			return iter
+		return None
+
+	def add_self_contact(self, account):
+		jid = gajim.get_jid_from_account(account)
+		if self.get_self_contact_iter(account):
+			self.draw_contact(jid, account)
+			self.draw_avatar(jid, account)
+			return
+		model = self.tree.get_model()
+		iterAcct = self.get_account_iter(account)
+		model.append(iterAcct, (None, gajim.nicks[account], 'self_contact', jid,
+			account, False, None))
+		self.draw_contact(jid, account)
+		self.draw_avatar(jid, account)
+
 	def add_transport_to_roster(self, account, transport):
 		c = gajim.contacts.create_contact(jid = transport, name = transport,
 			groups = [_('Transports')], show = 'offline', status = 'offline',
@@ -1078,7 +1110,7 @@ class RosterWindow:
 			except:
 				self.tooltip.hide_tooltip()
 				return
-			if model[iter][C_TYPE] == 'contact':
+			if model[iter][C_TYPE] in ('contact', 'self_contact'):
 				# we're on a contact entry in the roster
 				account = model[iter][C_ACCOUNT].decode('utf-8')
 				jid = model[iter][C_JID].decode('utf-8')
@@ -1238,7 +1270,10 @@ class RosterWindow:
 		if contact is None:
 			dialogs.SingleMessageWindow(account, action = 'send')
 		else:
-			dialogs.SingleMessageWindow(account, contact.jid, 'send')
+			jid = contact.jid
+			if contact.jid == gajim.get_jid_from_account(account):
+				jid += '/' + contact.resource
+			dialogs.SingleMessageWindow(account, jid, 'send')
 
 	def on_send_file_menuitem_activate(self, widget, account, contact):
 		gajim.interface.instances['file_transfers'].show_file_send_request(
@@ -1253,6 +1288,7 @@ class RosterWindow:
 		jid = model[iter][C_JID].decode('utf-8')
 		path = model.get_path(iter)
 		account = model[iter][C_ACCOUNT].decode('utf-8')
+		our_jid = jid == gajim.get_jid_from_account(account)
 		contact = gajim.contacts.get_contact_with_highest_priority(account, jid)
 		if not contact:
 			return
@@ -1276,20 +1312,30 @@ class RosterWindow:
 		
 		add_special_notification_menuitem.hide()
 		add_special_notification_menuitem.set_no_show_all(True)
-		
-		# add a special img for rename menuitem
-		path_to_kbd_input_img = os.path.join(gajim.DATA_DIR, 'pixmaps',
-			'kbd_input.png')
-		img = gtk.Image()
-		img.set_from_file(path_to_kbd_input_img)
-		rename_menuitem.set_image(img)
 
-		# skip a separator
+		if not our_jid:
+			# add a special img for rename menuitem
+			path_to_kbd_input_img = os.path.join(gajim.DATA_DIR, 'pixmaps',
+				'kbd_input.png')
+			img = gtk.Image()
+			img.set_from_file(path_to_kbd_input_img)
+			rename_menuitem.set_image(img)
+
+		above_subscription_separator = xml.get_widget(
+			'above_subscription_separator')
 		subscription_menuitem = xml.get_widget('subscription_menuitem')
 		send_auth_menuitem, ask_auth_menuitem, revoke_auth_menuitem =\
 			subscription_menuitem.get_submenu().get_children()
 		add_to_roster_menuitem = xml.get_widget('add_to_roster_menuitem')
-		remove_from_roster_menuitem = xml.get_widget('remove_from_roster_menuitem')
+		remove_from_roster_menuitem = xml.get_widget(
+			'remove_from_roster_menuitem')
+
+		if our_jid:
+			for menuitem in (rename_menuitem, edit_groups_menuitem,
+			above_subscription_separator, subscription_menuitem,
+			remove_from_roster_menuitem):
+				menuitem.set_no_show_all(True)
+				menuitem.hide()
 		# skip a separator
 		information_menuitem = xml.get_widget('information_menuitem')
 		history_menuitem = xml.get_widget('history_menuitem')
@@ -1706,7 +1752,7 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
 			self.make_group_menu(event, iter)
 		elif type == 'agent':
 			self.make_transport_menu(event, iter)
-		elif type == 'contact':
+		elif type in ('contact', 'self_contact'):
 			self.make_contact_menu(event, iter)
 		elif type == 'account':
 			self.make_account_menu(event, iter)
@@ -2559,6 +2605,8 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
 				if self.open_event(account, fjid, first_ev):
 					return
 			c = gajim.contacts.get_contact_with_highest_priority(account, jid)
+			if jid == gajim.get_jid_from_account(account):
+				resource = c.resource
 			self.on_open_chat_window(widget, c, account, resource = resource)
 
 	def on_roster_treeview_row_expanded(self, widget, iter, path):
@@ -2972,6 +3020,10 @@ _('If "%s" accepts this request you will know his or her status.') % jid)
 		name2 = name2.decode('utf-8')
 		type1 = model[iter1][C_TYPE]
 		type2 = model[iter2][C_TYPE]
+		if type1 == 'self_contact':
+			return -1
+		if type2 == 'self_contact':
+			return 1
 		if type1 == 'group':
 			if name1 == _('Transports'):
 				return 1
-- 
GitLab