show contact status if tabbed and more than one tabs in the tab itself. this is more HIG and ergonomic cause we know the status of a contact without clicking on it. Also this design is followed by Gossip, Gaim and many others IM clients that do tabbedUI
This commit is contained in:
		
							parent
							
								
									543ad45eb4
								
							
						
					
					
						commit
						68b0672437
					
				
					 3 changed files with 128 additions and 60 deletions
				
			
		
							
								
								
									
										41
									
								
								src/chat.py
									
										
									
									
									
								
							
							
						
						
									
										41
									
								
								src/chat.py
									
										
									
									
									
								
							|  | @ -108,9 +108,11 @@ class Chat: | |||
| 			start = '[' + str(self.nb_unread[jid]) + '] ' | ||||
| 		elif self.nb_unread[jid] == 1: | ||||
| 			start = '* ' | ||||
| 
 | ||||
| 		child = self.childs[jid] | ||||
| 		tab_label = self.notebook.get_tab_label(child).get_children()[0] | ||||
| 		tab_label.set_text(start + self.names[jid]) | ||||
| 		children = self.notebook.get_tab_label(child).get_children() | ||||
| 		nickname = children[1] | ||||
| 		nickname.set_text(start + self.names[jid]) | ||||
| 
 | ||||
| 	def on_window_destroy(self, widget, kind): #kind is 'chats' or 'gc' | ||||
| 		#clean self.plugin.windows[self.account][kind] | ||||
|  | @ -176,10 +178,18 @@ class Chat: | |||
| 				self.show_title() | ||||
| 				if self.plugin.systray_enabled: | ||||
| 					self.plugin.systray.remove_jid(new_jid, self.account) | ||||
| 		 | ||||
| 		nontabbed_status_image = self.xmls[jid].get_widget( | ||||
| 																	'nontabbed_status_image') | ||||
| 		if len(self.xmls) > 1: | ||||
| 			nontabbed_status_image.hide() | ||||
| 		else: | ||||
| 			nontabbed_status_image.show() | ||||
| 		 | ||||
| 		conversation_textview.grab_focus() | ||||
| 
 | ||||
| 	def active_tab(self, jid): | ||||
| 		self.notebook.set_current_page(\ | ||||
| 			self.notebook.page_num(self.childs[jid])) | ||||
| 	def set_active_tab(self, jid): | ||||
| 		self.notebook.set_current_page( self.notebook.page_num(self.childs[jid]) ) | ||||
| 
 | ||||
| 	def remove_tab(self, jid, kind): #kind is 'chats' or 'gc' | ||||
| 		if len(self.xmls) == 1: | ||||
|  | @ -193,8 +203,11 @@ class Chat: | |||
| 		if self.print_time_timeout_id.has_key(jid): | ||||
| 			gobject.source_remove(self.print_time_timeout_id[jid]) | ||||
| 			del self.print_time_timeout_id[jid] | ||||
| 		self.notebook.remove_page(\ | ||||
| 			self.notebook.page_num(self.childs[jid])) | ||||
| 		self.notebook.remove_page(self.notebook.page_num(self.childs[jid])) | ||||
| 		if len(self.xmls) == 2: | ||||
| 			# one that remains and one that we'll remove, 1 tab remains | ||||
| 			self.notebook.set_show_tabs(False) | ||||
| 
 | ||||
| 		del self.plugin.windows[self.account][kind][jid] | ||||
| 		del self.nb_unread[jid] | ||||
| 		del self.last_message_time[jid] | ||||
|  | @ -202,8 +215,6 @@ class Chat: | |||
| 		del self.tagIn[jid] | ||||
| 		del self.tagOut[jid] | ||||
| 		del self.tagStatus[jid] | ||||
| 		if len(self.xmls) == 1: | ||||
| 			self.notebook.set_show_tabs(False) | ||||
| 		self.show_title() | ||||
| 
 | ||||
| 	def new_tab(self, jid): | ||||
|  | @ -252,15 +263,20 @@ class Chat: | |||
| 		tag.set_property('underline', pango.UNDERLINE_SINGLE) | ||||
| 		 | ||||
| 		self.xmls[jid].signal_autoconnect(self) | ||||
| 		conversation_scrolledwindow = self.xmls[jid].\ | ||||
| 			get_widget('conversation_scrolledwindow') | ||||
| 		conversation_scrolledwindow.get_vadjustment().connect('value-changed', \ | ||||
| 		conversation_scrolledwindow = self.xmls[jid].get_widget( | ||||
| 															'conversation_scrolledwindow') | ||||
| 		conversation_scrolledwindow.get_vadjustment().connect('value-changed', | ||||
| 			self.on_conversation_vadjustment_value_changed) | ||||
| 		 | ||||
| 		child = self.childs[jid] | ||||
| 		self.notebook.append_page(child) | ||||
| 		nontabbed_status_image = self.xmls[jid].get_widget( | ||||
| 																	'nontabbed_status_image') | ||||
| 		if len(self.xmls) > 1: | ||||
| 			self.notebook.set_show_tabs(True) | ||||
| 			nontabbed_status_image.hide() | ||||
| 		else: | ||||
| 			nontabbed_status_image.show() | ||||
| 
 | ||||
| 		xm = gtk.glade.XML(GTKGUI_GLADE, 'tab_hbox', APP) | ||||
| 		tab_hbox = xm.get_widget('tab_hbox') | ||||
|  | @ -288,6 +304,7 @@ class Chat: | |||
| 				message_textview = self.xmls[jid].get_widget('message_textview') | ||||
| 				if not message_textview.is_focus(): | ||||
| 					message_textview.grab_focus() | ||||
| 				#FIXME: isn't it on_chat_notebook_key_press enough for this?? | ||||
| 				message_textview.emit('key_press_event', event) | ||||
| 				 | ||||
| 	def on_chat_notebook_key_press_event(self, widget, event): | ||||
|  |  | |||
							
								
								
									
										114
									
								
								src/gtkgui.glade
									
										
									
									
									
								
							
							
						
						
									
										114
									
								
								src/gtkgui.glade
									
										
									
									
									
								
							|  | @ -8425,7 +8425,7 @@ Custom</property> | |||
| 
 | ||||
|       <child> | ||||
| 	<widget class="GtkVBox" id="vbox36"> | ||||
| 	  <property name="border_width">4</property> | ||||
| 	  <property name="border_width">5</property> | ||||
| 	  <property name="visible">True</property> | ||||
| 	  <property name="homogeneous">False</property> | ||||
| 	  <property name="spacing">5</property> | ||||
|  | @ -8439,7 +8439,7 @@ Custom</property> | |||
| 	      <property name="justify">GTK_JUSTIFY_LEFT</property> | ||||
| 	      <property name="wrap">False</property> | ||||
| 	      <property name="selectable">False</property> | ||||
| 	      <property name="xalign">0.019999999553</property> | ||||
| 	      <property name="xalign">0</property> | ||||
| 	      <property name="yalign">0.5</property> | ||||
| 	      <property name="xpad">0</property> | ||||
| 	      <property name="ypad">0</property> | ||||
|  | @ -8496,7 +8496,7 @@ Custom</property> | |||
| 	      <property name="justify">GTK_JUSTIFY_LEFT</property> | ||||
| 	      <property name="wrap">False</property> | ||||
| 	      <property name="selectable">False</property> | ||||
| 	      <property name="xalign">0.019999999553</property> | ||||
| 	      <property name="xalign">0</property> | ||||
| 	      <property name="yalign">0.5</property> | ||||
| 	      <property name="xpad">0</property> | ||||
| 	      <property name="ypad">0</property> | ||||
|  | @ -8565,11 +8565,10 @@ Custom</property> | |||
| 	  <property name="border_width">5</property> | ||||
| 	  <property name="visible">True</property> | ||||
| 	  <property name="homogeneous">False</property> | ||||
| 	  <property name="spacing">0</property> | ||||
| 	  <property name="spacing">1</property> | ||||
| 
 | ||||
| 	  <child> | ||||
| 	    <widget class="GtkHBox" id="hbox2921"> | ||||
| 	      <property name="border_width">5</property> | ||||
| 	    <widget class="GtkHBox" id="actions_hbox"> | ||||
| 	      <property name="visible">True</property> | ||||
| 	      <property name="homogeneous">False</property> | ||||
| 	      <property name="spacing">5</property> | ||||
|  | @ -8578,7 +8577,7 @@ Custom</property> | |||
| 		<widget class="GtkButton" id="history_button"> | ||||
| 		  <property name="visible">True</property> | ||||
| 		  <property name="tooltip" translatable="yes">Click to see past conversations with this contact</property> | ||||
| 		  <property name="relief">GTK_RELIEF_NORMAL</property> | ||||
| 		  <property name="relief">GTK_RELIEF_NONE</property> | ||||
| 		  <property name="focus_on_click">True</property> | ||||
| 		  <signal name="clicked" handler="on_history_button_clicked" last_modification_time="Wed, 02 Mar 2005 17:03:17 GMT"/> | ||||
| 
 | ||||
|  | @ -8655,7 +8654,7 @@ Custom</property> | |||
| 		  <property name="tooltip" translatable="yes">Click to clear conversation (won't delete it from history)</property> | ||||
| 		  <property name="label">gtk-clear</property> | ||||
| 		  <property name="use_stock">True</property> | ||||
| 		  <property name="relief">GTK_RELIEF_NORMAL</property> | ||||
| 		  <property name="relief">GTK_RELIEF_NONE</property> | ||||
| 		  <property name="focus_on_click">True</property> | ||||
| 		  <signal name="clicked" handler="on_clear_button_clicked" last_modification_time="Wed, 02 Mar 2005 17:03:09 GMT"/> | ||||
| 		</widget> | ||||
|  | @ -8667,8 +8666,7 @@ Custom</property> | |||
| 	      </child> | ||||
| 
 | ||||
| 	      <child> | ||||
| 		<widget class="GtkImage" id="status_image"> | ||||
| 		  <property name="visible">True</property> | ||||
| 		<widget class="GtkImage" id="nontabbed_status_image"> | ||||
| 		  <property name="stock">gtk-no</property> | ||||
| 		  <property name="icon_size">4</property> | ||||
| 		  <property name="xalign">0.5</property> | ||||
|  | @ -8729,7 +8727,7 @@ Custom</property> | |||
| 		    </widget> | ||||
| 		    <packing> | ||||
| 		      <property name="x">0</property> | ||||
| 		      <property name="y">0</property> | ||||
| 		      <property name="y">2</property> | ||||
| 		    </packing> | ||||
| 		  </child> | ||||
| 		</widget> | ||||
|  | @ -8755,6 +8753,7 @@ Custom</property> | |||
| 	      <child> | ||||
| 		<widget class="GtkScrolledWindow" id="conversation_scrolledwindow"> | ||||
| 		  <property name="visible">True</property> | ||||
| 		  <property name="can_focus">True</property> | ||||
| 		  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> | ||||
| 		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> | ||||
| 		  <property name="shadow_type">GTK_SHADOW_IN</property> | ||||
|  | @ -8763,6 +8762,7 @@ Custom</property> | |||
| 		  <child> | ||||
| 		    <widget class="GtkTextView" id="conversation_textview"> | ||||
| 		      <property name="visible">True</property> | ||||
| 		      <property name="can_focus">True</property> | ||||
| 		      <property name="editable">False</property> | ||||
| 		      <property name="overwrite">False</property> | ||||
| 		      <property name="accepts_tab">True</property> | ||||
|  | @ -8789,35 +8789,62 @@ Custom</property> | |||
| 	      </child> | ||||
| 
 | ||||
| 	      <child> | ||||
| 		<widget class="GtkScrolledWindow" id="scrolledwindow31"> | ||||
| 		  <property name="height_request">55</property> | ||||
| 		<widget class="GtkHBox" id="hbox2957"> | ||||
| 		  <property name="visible">True</property> | ||||
| 		  <property name="can_focus">True</property> | ||||
| 		  <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> | ||||
| 		  <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> | ||||
| 		  <property name="shadow_type">GTK_SHADOW_IN</property> | ||||
| 		  <property name="window_placement">GTK_CORNER_TOP_LEFT</property> | ||||
| 		  <property name="homogeneous">False</property> | ||||
| 		  <property name="spacing">0</property> | ||||
| 
 | ||||
| 		  <child> | ||||
| 		    <widget class="GtkTextView" id="message_textview"> | ||||
| 		    <widget class="GtkImage" id="avatar_image"> | ||||
| 		      <property name="xalign">0.5</property> | ||||
| 		      <property name="yalign">0.5</property> | ||||
| 		      <property name="xpad">0</property> | ||||
| 		      <property name="ypad">0</property> | ||||
| 		    </widget> | ||||
| 		    <packing> | ||||
| 		      <property name="padding">0</property> | ||||
| 		      <property name="expand">False</property> | ||||
| 		      <property name="fill">False</property> | ||||
| 		    </packing> | ||||
| 		  </child> | ||||
| 
 | ||||
| 		  <child> | ||||
| 		    <widget class="GtkScrolledWindow" id="scrolledwindow31"> | ||||
| 		      <property name="height_request">55</property> | ||||
| 		      <property name="visible">True</property> | ||||
| 		      <property name="can_focus">True</property> | ||||
| 		      <property name="has_focus">True</property> | ||||
| 		      <property name="editable">True</property> | ||||
| 		      <property name="overwrite">False</property> | ||||
| 		      <property name="accepts_tab">True</property> | ||||
| 		      <property name="justification">GTK_JUSTIFY_LEFT</property> | ||||
| 		      <property name="wrap_mode">GTK_WRAP_WORD</property> | ||||
| 		      <property name="cursor_visible">True</property> | ||||
| 		      <property name="pixels_above_lines">0</property> | ||||
| 		      <property name="pixels_below_lines">0</property> | ||||
| 		      <property name="pixels_inside_wrap">0</property> | ||||
| 		      <property name="left_margin">0</property> | ||||
| 		      <property name="right_margin">0</property> | ||||
| 		      <property name="indent">0</property> | ||||
| 		      <property name="text" translatable="yes"></property> | ||||
| 		      <signal name="key_press_event" handler="on_message_textview_key_press_event" last_modification_time="Wed, 02 Mar 2005 21:05:35 GMT"/> | ||||
| 		      <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property> | ||||
| 		      <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property> | ||||
| 		      <property name="shadow_type">GTK_SHADOW_IN</property> | ||||
| 		      <property name="window_placement">GTK_CORNER_TOP_LEFT</property> | ||||
| 
 | ||||
| 		      <child> | ||||
| 			<widget class="GtkTextView" id="message_textview"> | ||||
| 			  <property name="visible">True</property> | ||||
| 			  <property name="can_focus">True</property> | ||||
| 			  <property name="has_focus">True</property> | ||||
| 			  <property name="editable">True</property> | ||||
| 			  <property name="overwrite">False</property> | ||||
| 			  <property name="accepts_tab">True</property> | ||||
| 			  <property name="justification">GTK_JUSTIFY_LEFT</property> | ||||
| 			  <property name="wrap_mode">GTK_WRAP_WORD</property> | ||||
| 			  <property name="cursor_visible">True</property> | ||||
| 			  <property name="pixels_above_lines">0</property> | ||||
| 			  <property name="pixels_below_lines">0</property> | ||||
| 			  <property name="pixels_inside_wrap">0</property> | ||||
| 			  <property name="left_margin">0</property> | ||||
| 			  <property name="right_margin">0</property> | ||||
| 			  <property name="indent">0</property> | ||||
| 			  <property name="text" translatable="yes"></property> | ||||
| 			  <signal name="key_press_event" handler="on_message_textview_key_press_event" last_modification_time="Wed, 02 Mar 2005 21:05:35 GMT"/> | ||||
| 			</widget> | ||||
| 		      </child> | ||||
| 		    </widget> | ||||
| 		    <packing> | ||||
| 		      <property name="padding">0</property> | ||||
| 		      <property name="expand">True</property> | ||||
| 		      <property name="fill">True</property> | ||||
| 		    </packing> | ||||
| 		  </child> | ||||
| 		</widget> | ||||
| 		<packing> | ||||
|  | @ -8843,7 +8870,24 @@ Custom</property> | |||
| 	<widget class="GtkHBox" id="tab_hbox"> | ||||
| 	  <property name="visible">True</property> | ||||
| 	  <property name="homogeneous">False</property> | ||||
| 	  <property name="spacing">3</property> | ||||
| 	  <property name="spacing">5</property> | ||||
| 
 | ||||
| 	  <child> | ||||
| 	    <widget class="GtkImage" id="status_image"> | ||||
| 	      <property name="visible">True</property> | ||||
| 	      <property name="stock">gtk-no</property> | ||||
| 	      <property name="icon_size">4</property> | ||||
| 	      <property name="xalign">0.5</property> | ||||
| 	      <property name="yalign">0.5</property> | ||||
| 	      <property name="xpad">0</property> | ||||
| 	      <property name="ypad">0</property> | ||||
| 	    </widget> | ||||
| 	    <packing> | ||||
| 	      <property name="padding">0</property> | ||||
| 	      <property name="expand">True</property> | ||||
| 	      <property name="fill">True</property> | ||||
| 	    </packing> | ||||
| 	  </child> | ||||
| 
 | ||||
| 	  <child> | ||||
| 	    <widget class="GtkLabel" id="label221"> | ||||
|  |  | |||
|  | @ -72,13 +72,7 @@ class Tabbed_chat_window(chat.Chat): | |||
| 		"""draw the widgets in a tab (status_image, contact_button ...) | ||||
| 		according to the the information in the user variable""" | ||||
| 		jid = user.jid | ||||
| 		status_image = self.xmls[jid].get_widget('status_image') | ||||
| 		state_images = self.plugin.roster.get_appropriate_state_images(jid) | ||||
| 		image = state_images[user.show] | ||||
| 		if image.get_storage_type() == gtk.IMAGE_ANIMATION: | ||||
| 			status_image.set_from_animation(image.get_animation()) | ||||
| 		elif image.get_storage_type() == gtk.IMAGE_PIXBUF: | ||||
| 			status_image.set_from_pixbuf(image.get_pixbuf()) | ||||
| 		self.set_state_image(jid) | ||||
| 		contact_button = self.xmls[jid].get_widget('contact_button') | ||||
| 		contact_button.set_use_underline(False) | ||||
| 		contact_button.set_label(user.name + ' <' + jid + '>') | ||||
|  | @ -95,14 +89,18 @@ class Tabbed_chat_window(chat.Chat): | |||
| 			if u.priority > prio: | ||||
| 				prio = u.priority | ||||
| 				show = u.show | ||||
| 		child = self.childs[jid] | ||||
| 		status_image = self.notebook.get_tab_label(child).get_children()[0] | ||||
| 		state_images = self.plugin.roster.get_appropriate_state_images(jid) | ||||
| 		image = state_images[show] | ||||
| 		non_tabbed_status_image = self.xmls[jid].get_widget( | ||||
| 																	'nontabbed_status_image') | ||||
| 		if image.get_storage_type() == gtk.IMAGE_ANIMATION: | ||||
| 			self.xmls[jid].get_widget('status_image').\ | ||||
| 				set_from_animation(image.get_animation()) | ||||
| 			non_tabbed_status_image.set_from_animation(image.get_animation()) | ||||
| 			status_image.set_from_animation(image.get_animation()) | ||||
| 		elif image.get_storage_type() == gtk.IMAGE_PIXBUF: | ||||
| 			self.xmls[jid].get_widget('status_image').\ | ||||
| 				set_from_pixbuf(image.get_pixbuf()) | ||||
| 			non_tabbed_status_image.set_from_pixbuf(image.get_pixbuf()) | ||||
| 			status_image.set_from_pixbuf(image.get_pixbuf()) | ||||
| 
 | ||||
| 	def on_tabbed_chat_window_delete_event(self, widget, event): | ||||
| 		"""close window""" | ||||
|  | @ -123,7 +121,7 @@ class Tabbed_chat_window(chat.Chat): | |||
| 		chat.Chat.on_chat_notebook_key_press_event(self, widget, event) | ||||
| 
 | ||||
| 	def on_clear_button_clicked(self, widget): | ||||
| 		"""When clear button is pressed : | ||||
| 		"""When clear button is pressed: | ||||
| 		clear the conversation""" | ||||
| 		jid = self.get_active_jid() | ||||
| 		conversation_buffer = self.xmls[jid].get_widget('conversation_textview').\ | ||||
|  | @ -147,6 +145,14 @@ class Tabbed_chat_window(chat.Chat): | |||
| 		chat.Chat.remove_tab(self, jid, 'chats') | ||||
| 		if len(self.xmls) > 0: | ||||
| 			del self.users[jid] | ||||
| 		 | ||||
| 		jid = self.get_active_jid() # get the new active jid | ||||
| 		nontabbed_status_image = self.xmls[jid].get_widget( | ||||
| 																	'nontabbed_status_image') | ||||
| 		if len(self.xmls) > 1: | ||||
| 			nontabbed_status_image.hide() | ||||
| 		else: | ||||
| 			nontabbed_status_image.show() | ||||
| 
 | ||||
| 	def new_user(self, user): | ||||
| 		self.names[user.jid] = user.name | ||||
|  | @ -168,7 +174,8 @@ class Tabbed_chat_window(chat.Chat): | |||
| 			self.print_time_timeout(user.jid) | ||||
| 			self.print_time_timeout_id[user.jid] = gobject.timeout_add(300000, \ | ||||
| 				self.print_time_timeout, user.jid) | ||||
| 		self.childs[user.jid].show_all() | ||||
| 		#FIXME: why show if already visible from glade? | ||||
| 		#self.childs[user.jid].show_all()  | ||||
| 
 | ||||
| 	def on_message_textview_key_press_event(self, widget, event): | ||||
| 		"""When a key is pressed: | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue