diff pidgin/gtkconv.c @ 27766:056fb36a5770

propagate from branch 'im.pidgin.pidgin' (head 7a8f58fc7611c332a05ed1c1b8417be24c9cf981) to branch 'im.pidgin.pidgin.yaz' (head 9937b0516237dfce73c86fd0407e37b0619e3037)
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Wed, 20 Feb 2008 06:56:39 +0000
parents 36036b9489fe ed6de6a3604f
children 969a2aeae461
line wrap: on
line diff
--- a/pidgin/gtkconv.c	Wed Feb 20 05:07:09 2008 +0000
+++ b/pidgin/gtkconv.c	Wed Feb 20 06:56:39 2008 +0000
@@ -114,6 +114,10 @@
 static GdkColor *nick_colors = NULL;
 static guint nbr_nick_colors;
 
+/* yaz. If you want to use shortcut keys that may conflict with
+   inputmethods, change this to 1. */
+#define ENABLE_SHORTCUT 0
+
 typedef struct {
 	GtkWidget *window;
 
@@ -269,6 +273,43 @@
 	return FALSE;
 }
 
+static gboolean
+size_allocate_cb(GtkWidget *w, GtkAllocation *allocation, PidginConversation *gtkconv)
+{
+	PurpleConversation *conv = gtkconv->active_conv;
+
+	if (!GTK_WIDGET_VISIBLE(w))
+		return FALSE;
+
+	if (!PIDGIN_IS_PIDGIN_CONVERSATION(conv))
+		return FALSE;
+	if (gtkconv->auto_resize) {
+		return FALSE;
+	}
+
+	if (gdk_window_get_state(gtkconv->win->window->window) & GDK_WINDOW_STATE_MAXIMIZED) {
+		return FALSE;
+	}
+
+	/* I find that I resize the window when it has a bunch of conversations in it, mostly so that the
+	 * tab bar will fit, but then I don't want new windows taking up the entire screen.  I check to see
+	 * if there is only one conversation in the window.  This way we'll be setting new windows to the
+	 * size of the last resized new window. */
+	/* I think that the above justification is not the majority, and that the new tab resizing should
+	 * negate it anyway.  --luke */
+	if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
+	{
+		if (w == gtkconv->lower_hbox)
+			purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/im/entry_height", allocation->height);
+	}
+	else if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
+	{
+		if (w == gtkconv->lower_hbox)
+			purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/chat/entry_height", allocation->height);
+	}
+	return FALSE;
+}
+
 static void
 default_formatize(PidginConversation *c)
 {
@@ -418,6 +459,18 @@
 	gtkconv->send_history = g_list_prepend(first, NULL);
 }
 
+static void
+reset_default_size(PidginConversation *gtkconv)
+{
+	PurpleConversation *conv = gtkconv->active_conv;
+	if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
+		gtk_widget_set_size_request(gtkconv->lower_hbox, -1,
+					    purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/entry_height"));
+	else
+		gtk_widget_set_size_request(gtkconv->lower_hbox, -1,
+					    purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/entry_height"));
+}
+
 static gboolean
 check_for_and_do_command(PurpleConversation *conv)
 {
@@ -534,6 +587,7 @@
 
 	if (check_for_and_do_command(conv)) {
 		if (gtkconv->entry_growing) {
+			reset_default_size(gtkconv);
 			gtkconv->entry_growing = FALSE;
 		}
 		gtk_imhtml_clear(GTK_IMHTML(gtkconv->entry));
@@ -593,6 +647,7 @@
 
 	gtk_imhtml_clear(GTK_IMHTML(gtkconv->entry));
 	if (gtkconv->entry_growing) {
+		reset_default_size(gtkconv);
 		gtkconv->entry_growing = FALSE;
 	}
 	gtkconv_set_unseen(gtkconv, PIDGIN_UNSEEN_NONE);
@@ -2945,20 +3000,33 @@
 
 	{ "/Conversation/sep0", NULL, NULL, 0, "<Separator>", NULL },
 
+#if ENABLE_SHORTCUT
 	{ N_("/Conversation/_Find..."), NULL, menu_find_cb, 0,
 			"<StockItem>", GTK_STOCK_FIND },
+#else
+	{ N_("/Conversation/_Find..."), NULL, menu_find_cb, 0,
+      "<Item>", NULL },
+#endif
 	{ N_("/Conversation/View _Log"), NULL, menu_view_log_cb, 0, "<Item>", NULL },
 	{ N_("/Conversation/_Save As..."), NULL, menu_save_as_cb, 0,
 			"<StockItem>", GTK_STOCK_SAVE_AS },
+#if ENABLE_SHORTCUT
 	{ N_("/Conversation/Clea_r Scrollback"), "<CTL>L", menu_clear_cb, 0, "<StockItem>", GTK_STOCK_CLEAR },
-
+#else
+	{ N_("/Conversation/Clea_r Scrollback"), NULL, menu_clear_cb, 0, "<Item>", NULL },
+#endif
 	{ "/Conversation/sep1", NULL, NULL, 0, "<Separator>", NULL },
 
 	{ N_("/Conversation/Se_nd File..."), NULL, menu_send_file_cb, 0, "<StockItem>", PIDGIN_STOCK_TOOLBAR_SEND_FILE },
 	{ N_("/Conversation/Add Buddy _Pounce..."), NULL, menu_add_pounce_cb,
 			0, "<Item>", NULL },
+#if ENABLE_SHORTCUT
 	{ N_("/Conversation/_Get Info"), "<CTL>O", menu_get_info_cb, 0,
 			"<StockItem>", PIDGIN_STOCK_TOOLBAR_USER_INFO },
+#else
+	{ N_("/Conversation/_Get Info"), NULL, menu_get_info_cb, 0,
+			"<StockItem>", PIDGIN_STOCK_TOOLBAR_USER_INFO },
+#endif
 	{ N_("/Conversation/In_vite..."), NULL, menu_invite_cb, 0,
 			"<Item>", NULL },
 	{ N_("/Conversation/M_ore"), NULL, NULL, 0, "<Branch>", NULL },
@@ -3644,7 +3712,11 @@
 		gtk_widget_destroy(win->menu.send_to);
 
 	/* Build the Send To menu */
+#if ENABLE_SHORTCUT
 	win->menu.send_to = gtk_menu_item_new_with_mnemonic(_("S_end To"));
+#else
+	win->menu.send_to = gtk_menu_item_new_with_mnemonic(_("Send To")); //to free Alt-s. intentional. --yaz
+#endif
 	gtk_widget_show(win->menu.send_to);
 
 	menu = gtk_menu_new();
@@ -4118,6 +4190,7 @@
 	PidginChatPane *gtkchat;
 	char *new_topic;
 	const char *current_topic;
+	char dummy[] = "No Topic";
 
 	gc      = purple_conversation_get_gc(conv);
 
@@ -4137,7 +4210,7 @@
 		return;
 	}
 
-	gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text), current_topic);
+	gtk_entry_set_text(GTK_ENTRY(gtkchat->topic_text), current_topic ? current_topic : dummy);
 	prpl_info->set_chat_topic(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)),
 			new_topic);
 
@@ -4368,7 +4441,7 @@
 	gtk_menu_shell_insert(GTK_MENU_SHELL(menu), menuitem, 1);
 }
 
-static gboolean resize_imhtml_cb(PidginConversation *gtkconv)
+static void resize_imhtml_cb(PidginConversation *gtkconv)
 {
 	GtkTextBuffer *buffer;
 	GtkTextIter iter;
@@ -4406,12 +4479,18 @@
 
 	diff = height - gtkconv->entry->allocation.height;
 
-	gtk_widget_size_request(gtkconv->lower_hbox, &sr);
-	gtkconv->entry_growing = TRUE;
-
-	gtk_widget_set_size_request(gtkconv->lower_hbox, -1,
-		diff + gtkconv->lower_hbox->allocation.height);
-	return FALSE;
+	if (diff > 0) {
+		gtk_widget_size_request(gtkconv->lower_hbox, &sr);
+		gtkconv->entry_growing = TRUE;
+
+		/* uncomment this to auto resize even after the user manually
+		   resizes
+		gtk_paned_set_position(GTK_PANED(gtkconv->lower_hbox->parent->parent),
+			-1);
+		*/
+		gtk_widget_set_size_request(gtkconv->lower_hbox, -1,
+			diff + gtkconv->lower_hbox->allocation.height);
+	}
 }
 
 static void
@@ -4603,15 +4682,19 @@
 static GtkWidget *
 setup_common_pane(PidginConversation *gtkconv)
 {
-	GtkWidget *vbox, *frame, *imhtml_sw, *event_box;
+	GtkWidget *paned, *vbox, *frame, *imhtml_sw, *event_box;
 	GtkCellRenderer *rend;
 	GtkTreePath *path;
 	PurpleConversation *conv = gtkconv->active_conv;
 	gboolean chat = (conv->type == PURPLE_CONV_TYPE_CHAT);
 	GtkPolicyType imhtml_sw_hscroll;
 
+	paned = gtk_vpaned_new();
+	gtk_widget_show(paned);
+
 	/* Setup the top part of the pane */
 	vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
+	gtk_paned_pack1(GTK_PANED(paned), vbox, TRUE, TRUE);
 	gtk_widget_show(vbox);
 
 	/* Setup the info pane */
@@ -4704,18 +4787,30 @@
 	g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_release_event",
 	                 G_CALLBACK(refocus_entry_cb), gtkconv);
 
+	/* Setup the bottom half of the conversation window */
+	vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
+	gtk_paned_pack2(GTK_PANED(paned), vbox, FALSE, TRUE);
+	gtk_widget_show(vbox);
+
 	gtkconv->lower_hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
-	gtk_box_pack_start(GTK_BOX(vbox), gtkconv->lower_hbox, FALSE, FALSE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), gtkconv->lower_hbox, TRUE, TRUE, 0);
 	gtk_widget_show(gtkconv->lower_hbox);
 
+	vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
+	gtk_box_pack_end(GTK_BOX(gtkconv->lower_hbox), vbox, TRUE, TRUE, 0);
+	gtk_widget_show(vbox);
+
 	/* Setup the toolbar, entry widget and all signals */
 	frame = pidgin_create_imhtml(TRUE, &gtkconv->entry, &gtkconv->toolbar, NULL);
-	gtk_box_pack_start(GTK_BOX(gtkconv->lower_hbox), frame, TRUE, TRUE, 0);
+	gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
 	gtk_widget_show(frame);
 
 	gtk_widget_set_name(gtkconv->entry, "pidgin_conv_entry");
 	gtk_imhtml_set_protocol_name(GTK_IMHTML(gtkconv->entry),
 			purple_account_get_protocol_name(conv->account));
+	gtk_widget_set_size_request(gtkconv->lower_hbox, -1,
+			chat ? purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/entry_height") :
+			purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/entry_height"));
 
 	g_signal_connect(G_OBJECT(gtkconv->entry), "populate-popup",
 	                 G_CALLBACK(entry_popup_menu_cb), gtkconv);
@@ -4725,6 +4820,8 @@
 	                       G_CALLBACK(send_cb), gtkconv);
 	g_signal_connect_after(G_OBJECT(gtkconv->entry), "button_press_event",
 	                       G_CALLBACK(entry_stop_rclick_cb), NULL);
+	g_signal_connect(G_OBJECT(gtkconv->lower_hbox), "size-allocate",
+	                 G_CALLBACK(size_allocate_cb), gtkconv);
 
 	gtkconv->entry_buffer =
 		gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->entry));
@@ -4747,7 +4844,7 @@
 	default_formatize(gtkconv);
 	g_signal_connect_after(G_OBJECT(gtkconv->entry), "format_function_clear",
 	                       G_CALLBACK(clear_formatting_cb), gtkconv);
-	return vbox;
+	return paned;
 }
 
 static void
@@ -5019,7 +5116,8 @@
 		gtk_widget_show(gtkconv->toolbar);
 	else
 		gtk_widget_hide(gtkconv->toolbar);
-	g_idle_add((GSourceFunc)resize_imhtml_cb, gtkconv);
+
+//	g_idle_add((GSourceFunc)resize_imhtml_cb, gtkconv);
 
 	if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/im/show_buddy_icons"))
 		gtk_widget_show(gtkconv->infopane_hbox);
@@ -6476,6 +6574,9 @@
 		AtkObject *accessibility_obj;
 		/* I think this is a little longer than it needs to be but I'm lazy. */
 		char *style;
+		gboolean ellipsis;
+		int side;
+		char *tab_title = NULL;
 
 		if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
 			im = PURPLE_CONV_IM(conv);
@@ -6563,8 +6664,26 @@
 			style = NULL;
 		}
 
+		// nosuke's tab width patch
+		side = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/tab_side");
+		side &= ~8; 
+		if ( (side == GTK_POS_LEFT || side == GTK_POS_RIGHT) &&
+		     purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/trim_vertical_tabs") )
+			ellipsis = TRUE;
+		else
+			ellipsis = FALSE;
+
+		if (ellipsis) {
+			tab_title = pidgin_gtk_ellipsis_text(gtkconv->tab_label, title, 60, "...");
+		}
+		else {
+			tab_title = g_strdup(title);
+		}
+
 		gtk_widget_set_name(gtkconv->tab_label, style);
-		gtk_label_set_text(GTK_LABEL(gtkconv->tab_label), title);
+		gtk_label_set_text(GTK_LABEL(gtkconv->tab_label), tab_title);
+		g_free(tab_title); tab_title = NULL;
+
 		gtk_widget_set_state(gtkconv->tab_label, GTK_STATE_ACTIVE);
 
 		if (gtkconv->unseen_state == PIDGIN_UNSEEN_TEXT ||
@@ -6970,6 +7089,24 @@
 	return page_num;
 }
 
+//nosuke
+static void
+trim_vertical_tabs_pref_cb(const char *name, PurplePrefType type,
+						   gconstpointer value, gpointer data)
+{
+	GList *l;
+	PurpleConversation *conv;
+
+	for (l = purple_get_conversations(); l != NULL; l = l->next) {
+		conv = (PurpleConversation *)l->data;
+
+		if (!PIDGIN_IS_PIDGIN_CONVERSATION(conv))
+			continue;
+
+		pidgin_conv_update_fields(conv, PIDGIN_CONV_SET_TITLE);
+	}
+}
+
 static void
 close_on_tabs_pref_cb(const char *name, PurplePrefType type,
 					  gconstpointer value, gpointer data)
@@ -7039,6 +7176,7 @@
 			pidgin_conv_tab_pack(gtkwin, gtkconvs->data);
 		}
 	}
+	trim_vertical_tabs_pref_cb(name, type, value, data);
 }
 
 static void
@@ -7097,7 +7235,7 @@
 		else
 			gtk_widget_hide(gtkconv->toolbar);
 
-		g_idle_add((GSourceFunc)resize_imhtml_cb,gtkconv);
+//		g_idle_add((GSourceFunc)resize_imhtml_cb,gtkconv);
 	}
 }
 
@@ -7600,6 +7738,7 @@
 	purple_prefs_add_none(PIDGIN_PREFS_ROOT "/conversations");
 	purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/use_smooth_scrolling", TRUE);
 	purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/close_on_tabs", TRUE);
+	purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/trim_vertical_tabs", FALSE);
 	purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/send_bold", FALSE);
 	purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/send_italic", FALSE);
 	purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/send_underline", FALSE);
@@ -7653,6 +7792,8 @@
 	/* Connect callbacks. */
 	purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/close_on_tabs",
 								close_on_tabs_pref_cb, NULL);
+	purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/trim_vertical_tabs",
+								  trim_vertical_tabs_pref_cb, NULL);
 	purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/show_timestamps",
 								show_timestamps_pref_cb, NULL);
 	purple_prefs_connect_callback(handle, PIDGIN_PREFS_ROOT "/conversations/show_formatting_toolbar",
@@ -9141,7 +9282,7 @@
 		ptr = gdk_cursor_new(GDK_LEFT_PTR);
 	}
 
-	gtk_label_set_markup(label, "×");
+	gtk_label_set_markup(label, "×");
 	gdk_window_set_cursor(event->window, ptr);
 	return FALSE;
 }
@@ -9154,7 +9295,7 @@
 		hand = gdk_cursor_new(GDK_HAND2);
 	}
 
-	gtk_label_set_markup(label, "<u>×</u>");
+	gtk_label_set_markup(label, "<u>×</u>");
 	gdk_window_set_cursor(event->window, hand);
 	return FALSE;
 }
@@ -9184,7 +9325,7 @@
 	gtk_event_box_set_visible_window(GTK_EVENT_BOX(gtkconv->close), FALSE);
 #endif
 	gtk_widget_set_events(gtkconv->close, GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
-	close_image = gtk_label_new("×");
+	close_image = gtk_label_new("×");
 	g_signal_connect(G_OBJECT(gtkconv->close), "enter-notify-event", G_CALLBACK(close_button_entered_cb), close_image);
 	g_signal_connect(G_OBJECT(gtkconv->close), "leave-notify-event", G_CALLBACK(close_button_left_cb), close_image);
 	gtk_widget_show(close_image);