From 6080bea67211ab26afad0c10ba2c5fa19b2e163c Mon Sep 17 00:00:00 2001
From: Yann Leboulanger <asterix@lagaule.org>
Date: Sat, 10 Jan 2009 16:37:57 +0000
Subject: [PATCH] abilty to do some exceptions to invisible rule (to send
 custom status). Fixes #4631

---
 src/common/connection.py | 31 ++++++++++++++++++++++++++++---
 src/roster_window.py     | 32 ++++++++++++++++++++++++--------
 2 files changed, 52 insertions(+), 11 deletions(-)

diff --git a/src/common/connection.py b/src/common/connection.py
index 65fbd21bb9..5cedc16fa7 100644
--- a/src/common/connection.py
+++ b/src/common/connection.py
@@ -856,14 +856,39 @@ class Connection(ConnectionHandlers):
 			return
 		common.xmpp.features_nb.setDefaultPrivacyList(self.connection, listname)
 
-	def build_privacy_rule(self, name, action):
+	def build_privacy_rule(self, name, action, order=1):
 		'''Build a Privacy rule stanza for invisibility'''
 		iq = common.xmpp.Iq('set', common.xmpp.NS_PRIVACY, xmlns = '')
 		l = iq.getTag('query').setTag('list', {'name': name})
-		i = l.setTag('item', {'action': action, 'order': '1'})
+		i = l.setTag('item', {'action': action, 'order': str(order)})
 		i.setTag('presence-out')
 		return iq
 
+	def build_invisible_rule(self):
+		iq = common.xmpp.Iq('set', common.xmpp.NS_PRIVACY, xmlns = '')
+		l = iq.getTag('query').setTag('list', {'name': 'invisible'})
+		if self.name in gajim.interface.status_sent_to_groups and \
+		len(gajim.interface.status_sent_to_groups[self.name]) > 0:
+			for group in gajim.interface.status_sent_to_groups[self.name]:
+				i = l.setTag('item', {'type': 'group', 'value': group,
+					'action': 'allow', 'order': '1'})
+				i.setTag('presence-out')
+		if self.name in gajim.interface.status_sent_to_users and \
+		len(gajim.interface.status_sent_to_users[self.name]) > 0:
+			for jid in gajim.interface.status_sent_to_users[self.name]:
+				i = l.setTag('item', {'type': 'jid', 'value': jid,
+					'action': 'allow', 'order': '2'})
+				i.setTag('presence-out')
+		i = l.setTag('item', {'action': 'deny', 'order': '3'})
+		i.setTag('presence-out')
+		return iq
+
+	def set_invisible_rule(self):
+		if not gajim.account_is_connected(self.name):
+			return
+		iq = self.build_invisible_rule()
+		self.connection.send(iq)
+
 	def activate_privacy_rule(self, name):
 		'''activate a privacy rule'''
 		if not self.connection:
@@ -892,7 +917,7 @@ class Connection(ConnectionHandlers):
 			self.connection.send(p)
 
 		# try to set the privacy rule
-		iq = self.build_privacy_rule('invisible', 'deny')
+		iq = self.build_invisible_rule()
 		self.connection.SendAndCallForResponse(iq, self._continue_invisible,
 			{'msg': msg, 'signed': signed, 'initial': initial})
 
diff --git a/src/roster_window.py b/src/roster_window.py
index 39acbec6ab..964bf69681 100644
--- a/src/roster_window.py
+++ b/src/roster_window.py
@@ -2041,7 +2041,7 @@ class RosterWindow:
 
 		# unset custom status
 		if account in gajim.interface.status_sent_to_users and \
-			contact.jid in gajim.interface.status_sent_to_users[account]:
+		contact.jid in gajim.interface.status_sent_to_users[account]:
 			del gajim.interface.status_sent_to_users[account][contact.jid]
 
 		# Delete pep if needed
@@ -3150,24 +3150,40 @@ class RosterWindow:
 
 	def on_send_custom_status(self, widget, contact_list, show, group=None):
 		'''send custom status'''
+		# contact_list has only one element except if group != None
 		def on_response(message):
 			if message is None: # None if user pressed Cancel
 				return
+			account_list = []
 			for (contact, account) in contact_list:
-				our_jid = gajim.get_jid_from_account(account)
-				accounts = []
-				if group and account not in accounts:
+				if account not in account_list:
+					account_list.append(account)
+			# 1. update status_sent_to_[groups|users] list
+			if group:
+				for account in account_list:
 					if account not in gajim.interface.status_sent_to_groups:
 						gajim.interface.status_sent_to_groups[account] = {}
 					gajim.interface.status_sent_to_groups[account][group] = show
-					accounts.append(group)
+			else:
+				for (contact, account) in contact_list:
+					if account not in gajim.interface.status_sent_to_users:
+						gajim.interface.status_sent_to_users[account] = {}
+					gajim.interface.status_sent_to_users[account][contact.jid] = show
+
+			# 2. update privacy lists if main status is invisible
+			for account in account_list:
+				if gajim.SHOW_LIST[gajim.connections[account].connected] == \
+				'invisible':
+					gajim.connections[account].set_invisible_rule()
+
+			# 3. send directed presence
+			for (contact, account) in contact_list:
+				our_jid = gajim.get_jid_from_account(account)
 				jid = contact.jid
 				if jid == our_jid:
 					jid += '/' + contact.resource
 				self.send_status(account, show, message, to=jid)
-				if account not in gajim.interface.status_sent_to_users:
-					gajim.interface.status_sent_to_users[account] = {}
-				gajim.interface.status_sent_to_users[account][contact.jid] = show
+
 		dialogs.ChangeStatusMessageDialog(on_response, show)
 
 	def on_status_combobox_changed(self, widget):
-- 
GitLab