From e55e38b7db180b6ae926e6994326a73826599903 Mon Sep 17 00:00:00 2001
From: Nikos Kouremenos <kourem@gmail.com>
Date: Wed, 29 Jun 2005 12:57:46 +0000
Subject: [PATCH] now gui can know connection_type ('tls', 'ssl', 'tcp') roster
 now has another cellrenderer (that holds pixbuf) so does the treestore there
 result: Gajim now shows an icon for accounts that were connected with ssl,
 tls and can show avatar of users too [that is TODO]

---
 src/common/connection.py | 25 ++++++++-----
 src/gajim.py             | 64 +++++++++++++++++---------------
 src/roster_window.py     | 79 +++++++++++++++++++++++++++++++---------
 3 files changed, 111 insertions(+), 57 deletions(-)

diff --git a/src/common/connection.py b/src/common/connection.py
index fec659d39b..df8d90cee8 100644
--- a/src/common/connection.py
+++ b/src/common/connection.py
@@ -120,7 +120,8 @@ class Connection:
 			'AGENT_INFO_ITEMS': [], 'AGENT_INFO_INFO': [], 'QUIT': [],
 			'ACC_OK': [], 'MYVCARD': [], 'OS_INFO': [], 'VCARD': [], 'GC_MSG': [],
 			'GC_SUBJECT': [], 'GC_CONFIG': [], 'BAD_PASSPHRASE': [],
-			'ROSTER_INFO': [], 'ERROR_ANSWER': [], 'BOOKMARKS': [],}
+			'ROSTER_INFO': [], 'ERROR_ANSWER': [], 'BOOKMARKS': [], 'CON_TYPE': [],
+			}
 		self.name = name
 		self.connected = 0 # offline
 		self.connection = None # xmpppy instance
@@ -142,6 +143,7 @@ class Connection:
 	# END __init__
 
 	def dispatch(self, event, data):
+		'''always passes account name as first param'''
 		if not event in self.handlers:
 			return
 		for handler in self.handlers[event]:
@@ -232,7 +234,7 @@ class Connection:
 			msgtxt = decmsg
 			encrypted = True
 		if mtype == 'error':
-			self.dispatch('MSGERROR', (str(msg.getFrom()), \
+			self.dispatch('MSGERROR', (str(msg.getFrom()),
 				msg.getErrorCode(), msg.getError(), msgtxt, tim))
 		elif mtype == 'groupchat':
 			subject = msg.getSubject()
@@ -617,7 +619,8 @@ class Connection:
 				self.dispatch('REGISTER_AGENT_INFO', (data[0], data[1].asDict()))
 
 	def connect(self):
-		"""Connect and authenticate to the Jabber server"""
+		"""Connect and authenticate to the Jabber server
+		Returns connection, and connection type ('tls', 'ssl', 'tcp', '')"""
 		name = gajim.config.get_per('accounts', self.name, 'name')
 		hostname = gajim.config.get_per('accounts', self.name, 'hostname')
 		resource = gajim.config.get_per('accounts', self.name, 'resource')
@@ -662,7 +665,9 @@ class Connection:
 			self.dispatch('STATUS', 'offline')
 			self.dispatch('ERROR', (_('Could not connect to "%s"') % self.name,
 				_('Check your connection or try again later')))
-			return None
+			return None, None
+		
+		self.dispatch('CON_TYPE', con_type) # notify the gui about con_type
 
 		con.RegisterHandler('message', self._messageCB)
 		con.RegisterHandler('presence', self._presenceCB)
@@ -704,11 +709,11 @@ class Connection:
 			self.dispatch('STATUS', 'offline')
 			self.dispatch('ERROR', (_('Could not connect to "%s"') % self.name,
 				_('Check your connection or try again later')))
-			return None
+			return None, None
 		if auth:
 			con.initRoster()
 			self.connected = 2
-			return con
+			return con, con_type # return connection and connection type
 		else:
 			gajim.log.debug("Couldn't authenticate to %s" % self.name)
 			self.connected = 0
@@ -716,7 +721,7 @@ class Connection:
 			self.dispatch('ERROR', (_('Authentication failed with "%s"') % \
 				self.name,
 				_('Please check your login and password for correctness.')))
-			return None
+			return None, None
 	# END connect
 
 	def register_handler(self, event, function):
@@ -772,7 +777,7 @@ class Connection:
 						self.dispatch('BAD_PASSPHRASE', ())
 		self.status = msg
 		if show != 'offline' and not self.connected:
-			self.connection = self.connect()
+			self.connection, self.con_type = self.connect()
 			if self.connected == 2:
 				self.connected = STATUS_LIST.index(show)
 				#send our presence
@@ -942,8 +947,8 @@ class Connection:
 			self.dispatch('ERROR', (_('Could not connect to "%s"') % name,
 				_('Check your connection or try again later.')))
 			return False
-		gajim.log.debug('Connected to server')
-		# FIXME! This blocks!
+		gajim.log.debug('Connected to server with %s', con_type)
+
 		req = common.xmpp.features.getRegInfo(c, config['hostname']).asDict()
 		req['username'] = config['name']
 		req['password'] = config['password']
diff --git a/src/gajim.py b/src/gajim.py
index 88d6e5d7ac..2c0f06ce37 100755
--- a/src/gajim.py
+++ b/src/gajim.py
@@ -187,6 +187,10 @@ class Interface:
 			self.windows[account]['gc'][jid_from].print_conversation(
 				'Error %s: %s' % (array[2], array[1]), jid_from)
 
+	def handle_event_con_type(self, account, con_type):
+		# ('CON_TYPE', account, con_type) which can be 'ssl', 'tls', 'tcp'
+		self.con_types[account] = con_type
+
 	def allow_notif(self, account):
 		self.allow_notifications[account] = True
 
@@ -723,38 +727,39 @@ class Interface:
 		# update regular expressions
 		self.make_regexps()
 
-	def register_handlers(self, conn):
-		conn.register_handler('ROSTER', self.handle_event_roster)
-		conn.register_handler('WARNING', self.handle_event_warning)
-		conn.register_handler('ERROR', self.handle_event_error)
-		conn.register_handler('INFORMATION', self.handle_event_information)
-		conn.register_handler('ERROR_ANSWER', self.handle_event_error_answer)
-		conn.register_handler('STATUS', self.handle_event_status)
-		conn.register_handler('NOTIFY', self.handle_event_notify)
-		conn.register_handler('MSG', self.handle_event_msg)
-		conn.register_handler('MSGERROR', self.handle_event_msgerror)
-		conn.register_handler('MSGSENT', self.handle_event_msgsent)
-		conn.register_handler('SUBSCRIBED', self.handle_event_subscribed)
-		conn.register_handler('UNSUBSCRIBED', self.handle_event_unsubscribed)
-		conn.register_handler('SUBSCRIBE', self.handle_event_subscribe)
-		conn.register_handler('AGENT_INFO', self.handle_event_agent_info)
-		conn.register_handler('REGISTER_AGENT_INFO',
+	def register_handlers(self, con):
+		con.register_handler('ROSTER', self.handle_event_roster)
+		con.register_handler('WARNING', self.handle_event_warning)
+		con.register_handler('ERROR', self.handle_event_error)
+		con.register_handler('INFORMATION', self.handle_event_information)
+		con.register_handler('ERROR_ANSWER', self.handle_event_error_answer)
+		con.register_handler('STATUS', self.handle_event_status)
+		con.register_handler('NOTIFY', self.handle_event_notify)
+		con.register_handler('MSG', self.handle_event_msg)
+		con.register_handler('MSGERROR', self.handle_event_msgerror)
+		con.register_handler('MSGSENT', self.handle_event_msgsent)
+		con.register_handler('SUBSCRIBED', self.handle_event_subscribed)
+		con.register_handler('UNSUBSCRIBED', self.handle_event_unsubscribed)
+		con.register_handler('SUBSCRIBE', self.handle_event_subscribe)
+		con.register_handler('AGENT_INFO', self.handle_event_agent_info)
+		con.register_handler('REGISTER_AGENT_INFO',
 			self.handle_event_register_agent_info)
-		conn.register_handler('AGENT_INFO_ITEMS',
+		con.register_handler('AGENT_INFO_ITEMS',
 			self.handle_event_agent_info_items)
-		conn.register_handler('AGENT_INFO_INFO',
+		con.register_handler('AGENT_INFO_INFO',
 			self.handle_event_agent_info_info)
-		conn.register_handler('QUIT', self.handle_event_quit)
-		conn.register_handler('ACC_OK', self.handle_event_acc_ok)
-		conn.register_handler('MYVCARD', self.handle_event_myvcard)
-		conn.register_handler('VCARD', self.handle_event_vcard)
-		conn.register_handler('OS_INFO', self.handle_event_os_info)
-		conn.register_handler('GC_MSG', self.handle_event_gc_msg)
-		conn.register_handler('GC_SUBJECT', self.handle_event_gc_subject)
-		conn.register_handler('GC_CONFIG', self.handle_event_gc_config)
-		conn.register_handler('BAD_PASSPHRASE', self.handle_event_bad_passphrase)
-		conn.register_handler('ROSTER_INFO', self.handle_event_roster_info)
-		conn.register_handler('BOOKMARKS', self.handle_event_bookmarks)
+		con.register_handler('QUIT', self.handle_event_quit)
+		con.register_handler('ACC_OK', self.handle_event_acc_ok)
+		con.register_handler('MYVCARD', self.handle_event_myvcard)
+		con.register_handler('VCARD', self.handle_event_vcard)
+		con.register_handler('OS_INFO', self.handle_event_os_info)
+		con.register_handler('GC_MSG', self.handle_event_gc_msg)
+		con.register_handler('GC_SUBJECT', self.handle_event_gc_subject)
+		con.register_handler('GC_CONFIG', self.handle_event_gc_config)
+		con.register_handler('BAD_PASSPHRASE', self.handle_event_bad_passphrase)
+		con.register_handler('ROSTER_INFO', self.handle_event_roster_info)
+		con.register_handler('BOOKMARKS', self.handle_event_bookmarks)
+		con.register_handler('CON_TYPE', self.handle_event_con_type)
 
 	def process_connections(self):
 		try:
@@ -816,6 +821,7 @@ class Interface:
 		self.queues = {}
 		self.nicks = {}
 		self.allow_notifications = {}
+		self.con_types = {}
 		self.sleeper_state = {} #whether we pass auto away / xa or not
 		for a in gajim.connections:
 			self.windows[a] = {'infos': {}, 'chats': {}, 'gc': {}, 'gc_config': {}}
diff --git a/src/roster_window.py b/src/roster_window.py
index 91d58996a0..740efcaf3a 100644
--- a/src/roster_window.py
+++ b/src/roster_window.py
@@ -94,8 +94,16 @@ class RosterWindow:
 		statuss = ['offline', 'connecting', 'online', 'chat',
 			'away', 'xa', 'dnd', 'invisible']
 		status = statuss[gajim.connections[account].connected]
-		model.append(None, (self.jabber_state_images[status], account,
-				'account', account, account, False))
+
+		tls_pixbuf = None
+		if self.plugin.con_types.has_key(account) and\
+			(self.plugin.con_types[account] == 'tls' or\
+			self.plugin.con_types[account] == 'ssl'):
+			tls_pixbuf = self.window.render_icon(gtk.STOCK_DIALOG_AUTHENTICATION,
+				gtk.ICON_SIZE_MENU, 'foo')
+
+		model.append(None, [self.jabber_state_images[status], account,
+			'account', account, account, False, tls_pixbuf])
 
 	def remove_newly_added(self, jid, account):
 		if jid in self.newly_added[account]:
@@ -126,7 +134,7 @@ class RosterWindow:
 			if not iterG:
 				IterAcct = self.get_account_iter(account)
 				iterG = model.append(IterAcct, 
-					(self.jabber_state_images['closed'], g, 'group', g, account, False))
+		[self.jabber_state_images['closed'], g, 'group', g, account, False, None])
 			if not self.groups[account].has_key(g): #It can probably never append
 				if account + g in self.collapsed_rows:
 					ishidden = False
@@ -141,8 +149,8 @@ class RosterWindow:
 			if g == 'Transports':
 				typestr = 'agent'
 
-			model.append(iterG, (self.jabber_state_images[user.show], user.name,
-					typestr, user.jid, account, False))
+			model.append(iterG, [self.jabber_state_images[user.show], user.name,
+					typestr, user.jid, account, False, None]) # FIXME None --> avatar
 			
 			if self.groups[account][g]['expand']:
 				self.tree.expand_row(model.get_path(iterG),
@@ -244,6 +252,7 @@ class RosterWindow:
 		for iter in iters:
 			model.set_value(iter, 0, img)
 			model.set_value(iter, 1, name)
+			#FIXME: add avatar
 
 	def join_gc_room(self, account, room_jid, nick, password):
 		if room_jid in self.plugin.windows[account]['gc']:
@@ -976,7 +985,7 @@ _('If "%s" accepts this request you will know his status.') %jid).get_response()
 			type = model.get_value(iter, 2)
 			if type == 'user' or type == 'group':
 				path = model.get_path(iter)
-				model.set_value(iter, 5, True)
+				model.set_value(iter, 5, True) # editable -> True
 				self.tree.set_cursor(path, self.tree.get_column(0), True)
 		if event.keyval == gtk.keysyms.Delete:
 			treeselection = self.tree.get_selection()
@@ -1690,6 +1699,30 @@ _('If "%s" accepts this request you will know his status.') %jid).get_response()
 				gajim.config.get_per('themes', theme, 'contactfont'))
 			renderer.set_property('xpad', 8)
 
+	def fill_secondary_pixbuf_rederer(self, column, renderer, model, iter, data=None):
+		'''When a row is added, set properties for secondary renderer (avatar or tls)'''
+		theme = gajim.config.get('roster_theme')
+		if model.get_value(iter, 2) == 'account':
+			renderer.set_property('cell-background', 
+				gajim.config.get_per('themes', theme, 'accountbgcolor'))
+			renderer.set_property('xalign', 0)
+		elif model.get_value(iter, 2) == 'group':
+			renderer.set_property('cell-background', 
+				gajim.config.get_per('themes', theme, 'groupbgcolor'))
+			#renderer.set_property('xalign', 0.5)
+		else:
+			jid = model.get_value(iter, 3)
+			account = model.get_value(iter, 4)
+			if jid in self.newly_added[account]:
+				renderer.set_property('cell-background', '#adc3c6')
+			elif jid in self.to_be_removed[account]:
+				renderer.set_property('cell-background', '#ab6161')
+			else:
+				renderer.set_property('cell-background', 
+					gajim.config.get_per('themes', theme, 'contactbgcolor'))
+			renderer.set_property('xalign', 0)
+		#renderer.set_property('width', 20)
+
 	def get_show(self, luser):
 		prio = luser[0].priority
 		show = luser[0].show
@@ -1838,9 +1871,9 @@ _('If "%s" accepts this request you will know his status.') %jid).get_response()
 		self.regroup = 0
 		self.regroup = gajim.config.get('mergeaccounts')
 		if gajim.config.get('saveposition'):
-			self.window.move(gajim.config.get('x-position'), \
+			self.window.move(gajim.config.get('x-position'),
 				gajim.config.get('y-position'))
-			self.window.resize(gajim.config.get('width'), \
+			self.window.resize(gajim.config.get('width'),
 				gajim.config.get('height'))
 
 		self.groups = {}
@@ -1855,13 +1888,14 @@ _('If "%s" accepts this request you will know his status.') %jid).get_response()
 			self.groups[a] = {}
 			self.newly_added[a] = []
 			self.to_be_removed[a] = []
-		#(icon, name, type, jid, account, editable)
-		model = gtk.TreeStore(gtk.Image, str, str, str, str, bool)
+		#(icon, name, type, jid, account, editable, secondary_pixbuf)
+		model = gtk.TreeStore(gtk.Image, str, str, str, str, bool, gtk.gdk.Pixbuf)
 		model.set_sort_func(1, self.compareIters)
 		model.set_sort_column_id(1, gtk.SORT_ASCENDING)
 		self.tree.set_model(model)
 		self.make_jabber_state_images()
-		self.transports_state_images = { 'aim': {}, 'gadugadu': {}, 'irc': {}, 'icq': {}, 'msn': {}, 'sms': {}, 'yahoo': {} }
+		self.transports_state_images = { 'aim': {}, 'gadugadu': {}, 'irc': {},
+			'icq': {}, 'msn': {}, 'sms': {}, 'yahoo': {} }
 		
 		path = os.path.join(gajim.DATA_DIR, 'iconsets/transports')
 		folders = os.listdir(path)
@@ -1869,8 +1903,8 @@ _('If "%s" accepts this request you will know his status.') %jid).get_response()
 			if transport == '.svn':
 				continue
 			folder = os.path.join(path, transport)
-			self.transports_state_images[transport] = self.load_iconset(folder + \
-				'/16x16/')
+			self.transports_state_images[transport] = self.load_iconset(
+				folder +	'/16x16/')
 
 		liststore = gtk.ListStore(str, gtk.Image, str)
 		self.status_combobox = self.xml.get_widget('status_combobox')
@@ -1897,18 +1931,27 @@ _('If "%s" accepts this request you will know his status.') %jid).get_response()
 		
 		#this col has two cells: first one img, second one text
 		col = gtk.TreeViewColumn()
-		render_pixbuf = cell_renderer_image.CellRendererImage()
-		col.pack_start(render_pixbuf, expand = False)
-		col.add_attribute(render_pixbuf, 'image', 0)
-		col.set_cell_data_func(render_pixbuf, self.iconCellDataFunc, None)
+		
+		render_image = cell_renderer_image.CellRendererImage() # show img or +-
+		col.pack_start(render_image, expand = False)
+		col.add_attribute(render_image, 'image', 0)
+		col.set_cell_data_func(render_image, self.iconCellDataFunc, None)
 
-		render_text = gtk.CellRendererText()
+		render_text = gtk.CellRendererText() # contact or group or account name
 		render_text.connect('edited', self.on_cell_edited)
 		render_text.connect('editing-canceled', self.on_editing_canceled)
 		col.pack_start(render_text, expand = True)
 		col.add_attribute(render_text, 'text', 1)
 		col.add_attribute(render_text, 'editable', 5)
 		col.set_cell_data_func(render_text, self.nameCellDataFunc, None)
+
+		
+		render_pixbuf = gtk.CellRendererPixbuf() # tls or avatar img
+		col.pack_start(render_pixbuf, expand = False)
+		col.add_attribute(render_pixbuf, 'pixbuf', 6)
+		col.set_cell_data_func(render_pixbuf, self.fill_secondary_pixbuf_rederer,
+			None)
+
 		self.tree.append_column(col)
 		
 		#do not show gtk arrows workaround
-- 
GitLab