changeset 19123:576edd9c4f72

propagate from branch 'im.pidgin.pidgin' (head 96be2c6bb0b910f823a48bf0ffc247135df4a988) to branch 'im.pidgin.soc.2007.finchfeat' (head 2a7598789162e259bfd3ba6cfa189a024137c675)
author Eric Polino <aluink@pidgin.im>
date Fri, 29 Jun 2007 12:45:08 +0000
parents 6dded98d1c80 (current diff) caa25e0ff358 (diff)
children 7e0379a41a44
files finch/gntdebug.c finch/gntrequest.c finch/libgnt/gntmain.c finch/libgnt/gntstyle.c finch/libgnt/gntstyle.h finch/libgnt/gntwidget.c pidgin/sounds/Makefile.am pidgin/sounds/Makefile.mingw pidgin/sounds/alert.wav pidgin/sounds/login.wav pidgin/sounds/logout.wav pidgin/sounds/receive.wav pidgin/sounds/send.wav
diffstat 34 files changed, 751 insertions(+), 139 deletions(-) [+]
line wrap: on
line diff
--- a/finch/finch.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/finch/finch.c	Fri Jun 29 12:45:08 2007 +0000
@@ -381,10 +381,12 @@
 {
 	signal(SIGPIPE, SIG_IGN);
 
+	g_set_application_name(_("Finch"));
+
 	/* Initialize the libpurple stuff */
 	if (!init_libpurple(argc, argv))
 		return 0;
-
+ 
 	purple_blist_show();
 	gnt_main();
 
--- a/finch/gntaccount.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/finch/gntaccount.c	Fri Jun 29 12:45:08 2007 +0000
@@ -645,8 +645,10 @@
 	GList *iter;
 	GntWidget *box, *button;
 
-	if (accounts.window)
+	if (accounts.window) {
+		gnt_window_present(accounts.window);
 		return;
+	}
 
 	accounts.window = gnt_vbox_new(FALSE);
 	gnt_box_set_toplevel(GNT_BOX(accounts.window), TRUE);
--- a/finch/gntblist.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/finch/gntblist.c	Fri Jun 29 12:45:08 2007 +0000
@@ -1260,7 +1260,7 @@
 }
 
 static void
-tooltip_for_buddy(PurpleBuddy *buddy, GString *str)
+tooltip_for_buddy(PurpleBuddy *buddy, GString *str, gboolean full)
 {
 	PurplePlugin *prpl;
 	PurplePluginProtocolInfo *prpl_info;
@@ -1273,7 +1273,7 @@
 
 	account = purple_buddy_get_account(buddy);
 
-	if (g_utf8_collate(purple_buddy_get_name(buddy), alias))
+	if (!full || g_utf8_collate(purple_buddy_get_name(buddy), alias))
 		purple_notify_user_info_add_pair(user_info, _("Nickname"), alias);
 
 	tmp = g_strdup_printf("%s (%s)",
@@ -1285,7 +1285,7 @@
 	prpl = purple_find_prpl(purple_account_get_protocol_id(account));
 	prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
 	if (prpl_info && prpl_info->tooltip_text) {
-		prpl_info->tooltip_text(buddy, user_info, TRUE);
+		prpl_info->tooltip_text(buddy, user_info, full);
 	}
 
 	if (purple_prefs_get_bool("/finch/blist/idletime")) {
@@ -1357,7 +1357,7 @@
 		const char *name = purple_buddy_get_name(pr);
 
 		title = g_strdup(name);
-		tooltip_for_buddy(pr, str);
+		tooltip_for_buddy(pr, str, TRUE);
 		for (node = node->child; node; node = node->next) {
 			PurpleBuddy *buddy = (PurpleBuddy*)node;
 			if (offline) {
@@ -1372,11 +1372,11 @@
 			if (!showoffline && !PURPLE_BUDDY_IS_ONLINE(buddy))
 				continue;
 			str = g_string_append(str, "\n----------\n");
-			tooltip_for_buddy(buddy, str);
+			tooltip_for_buddy(buddy, str, FALSE);
 		}
 	} else if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
 		PurpleBuddy *buddy = (PurpleBuddy *)node;
-		tooltip_for_buddy(buddy, str);
+		tooltip_for_buddy(buddy, str, TRUE);
 		title = g_strdup(purple_buddy_get_name(buddy));
 		if (!PURPLE_BUDDY_IS_ONLINE((PurpleBuddy*)node))
 			lastseen = purple_blist_node_get_int(node, "last_seen");
@@ -1422,9 +1422,10 @@
 
 	str = make_sure_text_fits(str);
 	gnt_util_get_text_bound(str->str, &w, &h);
-	h = MAX(2, h);
+	h = MAX(1, h);
 	tv = gnt_text_view_new();
 	gnt_widget_set_size(tv, w + 1, h);
+	gnt_text_view_set_flag(GNT_TEXT_VIEW(tv), GNT_TEXT_VIEW_NO_SCROLL);
 	gnt_box_add_widget(GNT_BOX(box), tv);
 
 	gnt_widget_set_position(box, x, y);
@@ -2249,8 +2250,10 @@
 {
 	if (ggblist == NULL)
 		new_list(list);
-	else if (ggblist->window)
+	else if (ggblist->window) {
+		gnt_window_present(ggblist->window);
 		return;
+	}
 
 	ggblist->window = gnt_vwindow_new(FALSE);
 	gnt_widget_set_name(ggblist->window, "buddylist");
--- a/finch/gntdebug.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/finch/gntdebug.c	Fri Jun 29 12:45:08 2007 +0000
@@ -221,56 +221,59 @@
 
 void finch_debug_window_show()
 {
+	GntWidget *wid, *box;
+
 	debug.paused = FALSE;
-	if (debug.window == NULL)
-	{
-		GntWidget *wid, *box;
-		debug.window = gnt_vbox_new(FALSE);
-		gnt_box_set_toplevel(GNT_BOX(debug.window), TRUE);
-		gnt_box_set_title(GNT_BOX(debug.window), _("Debug Window"));
-		gnt_box_set_pad(GNT_BOX(debug.window), 0);
-		gnt_box_set_alignment(GNT_BOX(debug.window), GNT_ALIGN_MID);
+	if (debug.window) {
+		gnt_window_present(debug.window);
+		return;
+	}
 
-		debug.tview = gnt_text_view_new();
-		gnt_box_add_widget(GNT_BOX(debug.window), debug.tview);
-		gnt_widget_set_size(debug.tview,
-				purple_prefs_get_int(PREF_ROOT "/size/width"),
-				purple_prefs_get_int(PREF_ROOT "/size/height"));
-		g_signal_connect(G_OBJECT(debug.tview), "size_changed", G_CALLBACK(size_changed_cb), NULL);
+	debug.window = gnt_vbox_new(FALSE);
+	gnt_box_set_toplevel(GNT_BOX(debug.window), TRUE);
+	gnt_box_set_title(GNT_BOX(debug.window), _("Debug Window"));
+	gnt_box_set_pad(GNT_BOX(debug.window), 0);
+	gnt_box_set_alignment(GNT_BOX(debug.window), GNT_ALIGN_MID);
 
-		gnt_box_add_widget(GNT_BOX(debug.window), gnt_line_new(FALSE));
+	debug.tview = gnt_text_view_new();
+	gnt_box_add_widget(GNT_BOX(debug.window), debug.tview);
+	gnt_widget_set_size(debug.tview,
+			purple_prefs_get_int(PREF_ROOT "/size/width"),
+			purple_prefs_get_int(PREF_ROOT "/size/height"));
+	g_signal_connect(G_OBJECT(debug.tview), "size_changed", G_CALLBACK(size_changed_cb), NULL);
 
-		box = gnt_hbox_new(FALSE);
-		gnt_box_set_alignment(GNT_BOX(box), GNT_ALIGN_MID);
-		gnt_box_set_fill(GNT_BOX(box), FALSE);
+	gnt_box_add_widget(GNT_BOX(debug.window), gnt_line_new(FALSE));
+
+	box = gnt_hbox_new(FALSE);
+	gnt_box_set_alignment(GNT_BOX(box), GNT_ALIGN_MID);
+	gnt_box_set_fill(GNT_BOX(box), FALSE);
 
-		/* XXX: Setting the GROW_Y for the following widgets don't make sense. But right now
-		 * it's necessary to make the width of the debug window resizable ... like I said,
-		 * it doesn't make sense. The bug is likely in the packing in gntbox.c.
-		 */
-		wid = gnt_button_new(_("Clear"));
-		g_signal_connect(G_OBJECT(wid), "activate", G_CALLBACK(clear_debug_win), debug.tview);
-		GNT_WIDGET_SET_FLAGS(wid, GNT_WIDGET_GROW_Y);
-		gnt_box_add_widget(GNT_BOX(box), wid);
-
-		debug.search = gnt_entry_new(purple_prefs_get_string(PREF_ROOT "/filter"));
-		gnt_box_add_widget(GNT_BOX(box), gnt_label_new(_("Filter: ")));
-		gnt_box_add_widget(GNT_BOX(box), debug.search);
-		g_signal_connect(G_OBJECT(debug.search), "text_changed", G_CALLBACK(update_filter_string), NULL);
+	/* XXX: Setting the GROW_Y for the following widgets don't make sense. But right now
+	 * it's necessary to make the width of the debug window resizable ... like I said,
+	 * it doesn't make sense. The bug is likely in the packing in gntbox.c.
+	 */
+	wid = gnt_button_new(_("Clear"));
+	g_signal_connect(G_OBJECT(wid), "activate", G_CALLBACK(clear_debug_win), debug.tview);
+	GNT_WIDGET_SET_FLAGS(wid, GNT_WIDGET_GROW_Y);
+	gnt_box_add_widget(GNT_BOX(box), wid);
 
-		wid = gnt_check_box_new(_("Pause"));
-		g_signal_connect(G_OBJECT(wid), "toggled", G_CALLBACK(toggle_pause), NULL);
-		GNT_WIDGET_SET_FLAGS(wid, GNT_WIDGET_GROW_Y);
-		gnt_box_add_widget(GNT_BOX(box), wid);
+	debug.search = gnt_entry_new(purple_prefs_get_string(PREF_ROOT "/filter"));
+	gnt_box_add_widget(GNT_BOX(box), gnt_label_new(_("Filter: ")));
+	gnt_box_add_widget(GNT_BOX(box), debug.search);
+	g_signal_connect(G_OBJECT(debug.search), "text_changed", G_CALLBACK(update_filter_string), NULL);
 
-		gnt_box_add_widget(GNT_BOX(debug.window), box);
-		GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_GROW_Y);
+	wid = gnt_check_box_new(_("Pause"));
+	g_signal_connect(G_OBJECT(wid), "toggled", G_CALLBACK(toggle_pause), NULL);
+	GNT_WIDGET_SET_FLAGS(wid, GNT_WIDGET_GROW_Y);
+	gnt_box_add_widget(GNT_BOX(box), wid);
 
-		gnt_widget_set_name(debug.window, "debug-window");
+	gnt_box_add_widget(GNT_BOX(debug.window), box);
+	GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_GROW_Y);
 
-		g_signal_connect(G_OBJECT(debug.window), "destroy", G_CALLBACK(reset_debug_win), NULL);
-		gnt_text_view_attach_scroll_widget(GNT_TEXT_VIEW(debug.tview), debug.window);
-	}
+	gnt_widget_set_name(debug.window, "debug-window");
+
+	g_signal_connect(G_OBJECT(debug.window), "destroy", G_CALLBACK(reset_debug_win), NULL);
+	gnt_text_view_attach_scroll_widget(GNT_TEXT_VIEW(debug.tview), debug.window);
 
 	gnt_widget_show(debug.window);
 }
--- a/finch/gntft.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/finch/gntft.c	Fri Jun 29 12:45:08 2007 +0000
@@ -262,6 +262,8 @@
 {
 	if (xfer_dialog == NULL)
 		finch_xfer_dialog_new();
+	else
+		gnt_window_present(xfer_dialog->window);
 }
 
 void
--- a/finch/gntnotify.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/finch/gntnotify.c	Fri Jun 29 12:45:08 2007 +0000
@@ -304,7 +304,7 @@
 	PurpleAccount *account = g_object_get_data(G_OBJECT(widget), "notify-account");
 	gpointer data = g_object_get_data(G_OBJECT(widget), "notify-data");
 
-	list = gnt_tree_get_selection_text_list(GNT_TREE(widget));
+	list = gnt_tree_get_selection_text_list(GNT_TREE(g_object_get_data(G_OBJECT(widget), "notify-tree")));
 
 	b->callback(purple_account_get_connection(account), list, data);
 	g_list_foreach(list, (GFunc)g_free, NULL);
@@ -335,23 +335,31 @@
 {
 	GntWidget *window, *tree, *box, *button;
 	GList *iter;
+	int columns, i;
 
 	window = gnt_vbox_new(FALSE);
 	gnt_box_set_toplevel(GNT_BOX(window), TRUE);
 	gnt_box_set_title(GNT_BOX(window), title);
-	gnt_box_set_fill(GNT_BOX(window), FALSE);
+	gnt_box_set_fill(GNT_BOX(window), TRUE);
 	gnt_box_set_pad(GNT_BOX(window), 0);
 	gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID);
 
-	gnt_box_add_widget(GNT_BOX(window),
+	if (primary)
+		gnt_box_add_widget(GNT_BOX(window),
 			gnt_label_new_with_format(primary, GNT_TEXT_FLAG_BOLD));
-	gnt_box_add_widget(GNT_BOX(window),
+	if (secondary)
+		gnt_box_add_widget(GNT_BOX(window),
 			gnt_label_new_with_format(secondary, GNT_TEXT_FLAG_NORMAL));
 
-	tree = gnt_tree_new_with_columns(g_list_length(results->columns));
+	columns = purple_notify_searchresults_get_columns_count(results);
+	tree = gnt_tree_new_with_columns(columns);
 	gnt_tree_set_show_title(GNT_TREE(tree), TRUE);
 	gnt_box_add_widget(GNT_BOX(window), tree);
 
+	for (i = 0; i < columns; i++)
+		gnt_tree_set_column_title(GNT_TREE(tree), i, 
+				purple_notify_searchresults_column_get_title(results, i));
+
 	box = gnt_hbox_new(TRUE);
 
 	for (iter = results->buttons; iter; iter = iter->next)
@@ -389,7 +397,8 @@
 		button = gnt_button_new(text);
 		g_object_set_data(G_OBJECT(button), "notify-account", purple_connection_get_account(gc));
 		g_object_set_data(G_OBJECT(button), "notify-data", data);
-		g_signal_connect_swapped(G_OBJECT(button), "activate",
+		g_object_set_data(G_OBJECT(button), "notify-tree", tree);
+		g_signal_connect(G_OBJECT(button), "activate",
 				G_CALLBACK(notify_button_activated), b);
 
 		gnt_box_add_widget(GNT_BOX(box), button);
--- a/finch/gntplugin.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/finch/gntplugin.c	Fri Jun 29 12:45:08 2007 +0000
@@ -242,8 +242,10 @@
 	GList *iter;
 	GList *seen;
 
-	if (plugins.window)
+	if (plugins.window) {
+		gnt_window_present(plugins.window);
 		return;
+	}
 
 	purple_plugins_probe(G_MODULE_SUFFIX);
 
--- a/finch/gntpounce.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/finch/gntpounce.c	Fri Jun 29 12:45:08 2007 +0000
@@ -672,6 +672,7 @@
 	GntWidget *win;
 
 	if (pounces_manager != NULL) {
+		gnt_window_present(pounces_manager->window);
 		return;
 	}
 
--- a/finch/gntprefs.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/finch/gntprefs.c	Fri Jun 29 12:45:08 2007 +0000
@@ -30,9 +30,16 @@
 #include "gntprefs.h"
 #include "gntrequest.h"
 
+#include "gnt.h"
+#include "gntwidget.h"
+
 #include <string.h>
 
-static GList *freestrings;  /* strings to be freed when the pref-window is closed */
+static struct {
+	GList *freestrings;  /* strings to be freed when the pref-window is closed */
+	gboolean showing;
+	GntWidget *window;
+} pref_request;
 
 void finch_prefs_init()
 {
@@ -98,7 +105,7 @@
 		str = g_strdup_printf("%ld", purple_savedstatus_get_creation_time(iter->data));
 		list = g_list_append(list, (char*)purple_savedstatus_get_title(iter->data));
 		list = g_list_append(list, str);
-		freestrings = g_list_prepend(freestrings, str);
+		pref_request.freestrings = g_list_prepend(pref_request.freestrings, str);
 	}
 	return list;
 }
@@ -190,22 +197,22 @@
 	{PURPLE_PREF_NONE, NULL, NULL, NULL},
 };
 
-/* XXX: Translate after the freeze */
 static Prefs idle[] =
 {
-	{PURPLE_PREF_STRING, "/purple/away/idle_reporting", "Report Idle time", get_idle_options},
-	{PURPLE_PREF_BOOLEAN, "/purple/away/away_when_idle", "Change status when idle", NULL},
-	{PURPLE_PREF_INT, "/purple/away/mins_before_away", "Minutes before changing status", NULL},
-	{PURPLE_PREF_INT, "/purple/savedstatus/idleaway", "Change status to", get_status_titles},
+	{PURPLE_PREF_STRING, "/purple/away/idle_reporting", N_("Report Idle time"), get_idle_options},
+	{PURPLE_PREF_BOOLEAN, "/purple/away/away_when_idle", N_("Change status when idle"), NULL},
+	{PURPLE_PREF_INT, "/purple/away/mins_before_away", N_("Minutes before changing status"), NULL},
+	{PURPLE_PREF_INT, "/purple/savedstatus/idleaway", N_("Change status to"), get_status_titles},
 	{PURPLE_PREF_NONE, NULL, NULL, NULL},
 };
 
 static void
 free_strings()
 {
-	g_list_foreach(freestrings, (GFunc)g_free, NULL);
-	g_list_free(freestrings);
-	freestrings = NULL;
+	g_list_foreach(pref_request.freestrings, (GFunc)g_free, NULL);
+	g_list_free(pref_request.freestrings);
+	pref_request.freestrings = NULL;
+	pref_request.showing = FALSE;
 }
 
 static void
@@ -236,6 +243,11 @@
 {
 	PurpleRequestFields *fields;
 
+	if (pref_request.showing) {
+		gnt_window_present(pref_request.window);
+		return;
+	}
+
 	fields = purple_request_fields_new();
 
 	add_pref_group(fields, _("Buddy List"), blist);
@@ -243,7 +255,8 @@
 	add_pref_group(fields, _("Logging"), logging);
 	add_pref_group(fields, _("Idle"), idle);
 
-	purple_request_fields(NULL, _("Preferences"), NULL, NULL, fields,
+	pref_request.showing = TRUE;
+	pref_request.window = purple_request_fields(NULL, _("Preferences"), NULL, NULL, fields,
 			_("Save"), G_CALLBACK(save_cb), _("Cancel"), free_strings,
 			NULL, NULL, NULL,
 			NULL);
--- a/finch/gntrequest.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/finch/gntrequest.c	Fri Jun 29 12:45:08 2007 +0000
@@ -67,8 +67,35 @@
 	return window;
 }
 
+/**
+ * If the window is closed by the wm (ie, without triggering any of
+ * the buttons, then do some default callback.
+ */
+static void
+setup_default_callback(GntWidget *window, gpointer default_cb, gpointer data)
+{
+	g_object_set_data(G_OBJECT(window), "default-callback", default_cb);
+	g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(default_cb), data);
+}
+
+static void
+action_performed(GntWidget *button, gpointer data)
+{
+	g_signal_handlers_disconnect_matched(data, G_SIGNAL_MATCH_FUNC,
+			0, 0, NULL,
+			g_object_get_data(data, "default-callback"),
+			 NULL);
+}
+
+/**
+ * window: this is the window
+ * userdata: the userdata to pass to the primary callbacks
+ * cb: the callback
+ * data: data for the callback
+ * (text, primary-callback) pairs, ended by a NULL
+ */
 static GntWidget *
-setup_button_box(gpointer userdata, gpointer cb, gpointer data, ...)
+setup_button_box(GntWidget *win, gpointer userdata, gpointer cb, gpointer data, ...)
 {
 	GntWidget *box, *button;
 	va_list list;
@@ -86,6 +113,7 @@
 		gnt_box_add_widget(GNT_BOX(box), button);
 		g_object_set_data(G_OBJECT(button), "activate-callback", callback);
 		g_object_set_data(G_OBJECT(button), "activate-userdata", userdata);
+		g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(action_performed), win);
 		g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(cb), data);
 	}
 
@@ -127,10 +155,11 @@
 		gnt_entry_set_masked(GNT_ENTRY(entry), TRUE);
 	gnt_box_add_widget(GNT_BOX(window), entry);
 
-	box = setup_button_box(user_data, notify_input_cb, entry,
+	box = setup_button_box(window, user_data, notify_input_cb, entry,
 			ok_text, ok_cb, cancel_text, cancel_cb, NULL);
 	gnt_box_add_widget(GNT_BOX(window), box);
 
+	setup_default_callback(window, cancel_cb, user_data);
 	gnt_widget_show(window);
 
 	return window;
@@ -189,10 +218,11 @@
 	}
 	gnt_combo_box_set_selected(GNT_COMBO_BOX(combo), GINT_TO_POINTER(default_value + 1));
 
-	box = setup_button_box(user_data, request_choice_cb, combo,
+	box = setup_button_box(window, user_data, request_choice_cb, combo,
 			ok_text, ok_cb, cancel_text, cancel_cb, NULL);
 	gnt_box_add_widget(GNT_BOX(window), box);
 
+	setup_default_callback(window, cancel_cb, user_data);
 	gnt_widget_show(window);
 	
 	return window;
@@ -538,10 +568,11 @@
 	}
 	gnt_box_add_widget(GNT_BOX(window), box);
 
-	box = setup_button_box(userdata, request_fields_cb, allfields,
+	box = setup_button_box(window, userdata, request_fields_cb, allfields,
 			ok, ok_cb, cancel, cancel_cb, NULL);
 	gnt_box_add_widget(GNT_BOX(window), box);
 
+	setup_default_callback(window, cancel_cb, userdata);
 	gnt_widget_show(window);
 
 	g_object_set_data(G_OBJECT(window), "fields", allfields);
--- a/finch/gntstatus.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/finch/gntstatus.c	Fri Jun 29 12:45:08 2007 +0000
@@ -163,8 +163,10 @@
 void finch_savedstatus_show_all()
 {
 	GntWidget *window, *tree, *box, *button;
-	if (statuses.window)
+	if (statuses.window) {
+		gnt_window_present(statuses.window);
 		return;
+	}
 
 	statuses.window = window = gnt_vbox_new(FALSE);
 	gnt_box_set_toplevel(GNT_BOX(window), TRUE);
--- a/finch/libgnt/Makefile.am	Fri Jun 29 02:58:27 2007 +0000
+++ b/finch/libgnt/Makefile.am	Fri Jun 29 12:45:08 2007 +0000
@@ -26,6 +26,7 @@
 	gntmenu.c \
 	gntmenuitem.c \
 	gntmenuitemcheck.c \
+	gntslider.c \
 	gntstyle.c \
 	gnttextview.c \
 	gnttree.c \
@@ -53,6 +54,7 @@
 	gntmenu.h \
 	gntmenuitem.h \
 	gntmenuitemcheck.h \
+	gntslider.h \
 	gntstyle.h \
 	gnttextview.h \
 	gnttree.h \
--- a/finch/libgnt/gntentry.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/finch/libgnt/gntentry.c	Fri Jun 29 12:45:08 2007 +0000
@@ -179,7 +179,7 @@
 
 	stop = gnt_util_onscreen_width(entry->scroll, entry->end);
 	if (stop < widget->priv.width)
-		whline(widget->window, ENTRY_CHAR, widget->priv.width - stop);
+		mvwhline(widget->window, 0, stop, ENTRY_CHAR, widget->priv.width - stop);
 
 	if (focus)
 		mvwchgat(widget->window, 0, gnt_util_onscreen_width(entry->scroll, entry->cursor),
--- a/finch/libgnt/gntlabel.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/finch/libgnt/gntlabel.c	Fri Jun 29 12:45:08 2007 +0000
@@ -138,8 +138,7 @@
 
 	if (GNT_WIDGET(label)->window)
 	{
-		gnt_widget_hide(GNT_WIDGET(label));
-		gnt_label_size_request(GNT_WIDGET(label));
+		werase(GNT_WIDGET(label)->window);
 		gnt_widget_draw(GNT_WIDGET(label));
 	}
 }
--- a/finch/libgnt/gntmain.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/finch/libgnt/gntmain.c	Fri Jun 29 12:45:08 2007 +0000
@@ -494,8 +494,12 @@
  * Stuff for 'window management' *
  *********************************/
 
-void gnt_window_present(GntWidget *window) {
-	gnt_wm_raise_window(wm, window);
+void gnt_window_present(GntWidget *window)
+{
+	if (wm->event_stack)
+		gnt_wm_raise_window(wm, window);
+	else
+		gnt_widget_set_urgent(window);
 }
 
 void gnt_screen_occupy(GntWidget *widget)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/finch/libgnt/gntslider.c	Fri Jun 29 12:45:08 2007 +0000
@@ -0,0 +1,273 @@
+/**
+ * GNT - The GLib Ncurses Toolkit
+ *
+ * GNT is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "gntcolors.h"
+#include "gntkeys.h"
+#include "gntslider.h"
+#include "gntstyle.h"
+
+enum
+{
+	SIG_VALUE_CHANGED,
+	SIGS,
+};
+
+static guint signals[SIGS] = { 0 };
+
+static GntWidgetClass *parent_class = NULL;
+
+/* returns TRUE if the value was changed */
+static gboolean
+sanitize_value(GntSlider *slider)
+{
+	if (slider->current < slider->min)
+		slider->current = slider->min;
+	else if (slider->current > slider->max)
+		slider->current = slider->max;
+	else
+		return FALSE;
+	return TRUE;
+}
+
+static void
+redraw_slider(GntSlider *slider)
+{
+	GntWidget *widget = GNT_WIDGET(slider);
+	if (GNT_WIDGET_IS_FLAG_SET(widget, GNT_WIDGET_MAPPED))
+		gnt_widget_draw(widget);
+}
+
+static void
+slider_value_changed(GntSlider *slider)
+{
+	g_signal_emit(slider, signals[SIG_VALUE_CHANGED], 0, slider->current);
+}
+
+static void
+gnt_slider_draw(GntWidget *widget)
+{
+	GntSlider *slider = GNT_SLIDER(widget);
+	int attr = 0;
+	int position, size = 0;
+
+	if (slider->vertical)
+		mvwvline(widget->window, 0, 0, ACS_VLINE | COLOR_PAIR(GNT_COLOR_NORMAL),
+				(size = widget->priv.height));
+	else
+		mvwhline(widget->window, 0, 0, ACS_HLINE | COLOR_PAIR(GNT_COLOR_NORMAL),
+				(size = widget->priv.width));
+
+	if (gnt_widget_has_focus(widget))
+		attr |= GNT_COLOR_HIGHLIGHT;
+	else
+		attr |= GNT_COLOR_HIGHLIGHT_D;
+
+	if (slider->max != slider->min)
+		position = ((size - 1) * (slider->current - slider->min)) / (slider->max - slider->min);
+	else
+		position = 0;
+	mvwaddch(widget->window,
+			slider->vertical ? (size - position - 1) : 0,
+			slider->vertical ? 0 : position,
+			ACS_BLOCK | COLOR_PAIR(attr));
+}
+
+static void
+gnt_slider_size_request(GntWidget *widget)
+{
+	if (GNT_SLIDER(widget)->vertical) {
+		widget->priv.width = 1;
+		widget->priv.height = 5;
+	} else {
+		widget->priv.width = 5;
+		widget->priv.height = 1;
+	}
+}
+
+static void
+gnt_slider_map(GntWidget *widget)
+{
+	if (widget->priv.width == 0 || widget->priv.height == 0)
+		gnt_widget_size_request(widget);
+	GNTDEBUG;
+}
+
+static gboolean
+step_back(GntBindable *bindable, GList *null)
+{
+	GntSlider *slider = GNT_SLIDER(bindable);
+	if (slider->current <= slider->min)
+		return FALSE;
+	slider->current -= slider->step;
+	sanitize_value(slider);
+	redraw_slider(slider);
+	slider_value_changed(slider);
+	return TRUE;
+}
+
+static gboolean
+step_forward(GntBindable *bindable, GList *list)
+{
+	GntSlider *slider = GNT_SLIDER(bindable);
+	if (slider->current >= slider->max)
+		return FALSE;
+	slider->current += slider->step;
+	sanitize_value(slider);
+	redraw_slider(slider);
+	slider_value_changed(slider);
+	return TRUE;
+}
+
+static void
+gnt_slider_class_init(GntSliderClass *klass)
+{
+	GntBindableClass *bindable = GNT_BINDABLE_CLASS(klass);
+	parent_class = GNT_WIDGET_CLASS(klass);
+	parent_class->draw = gnt_slider_draw;
+	parent_class->map = gnt_slider_map;
+	parent_class->size_request = gnt_slider_size_request;
+
+	klass->changed = NULL;
+
+	signals[SIG_VALUE_CHANGED] =
+		g_signal_new("changed",
+		             G_TYPE_FROM_CLASS(klass),
+		             G_SIGNAL_RUN_LAST,
+		             G_STRUCT_OFFSET(GntSliderClass, changed),
+		             NULL, NULL,
+		             g_cclosure_marshal_VOID__INT,
+		             G_TYPE_NONE, 1, G_TYPE_INT);
+
+	gnt_bindable_class_register_action(bindable, "step-backward", step_back, GNT_KEY_LEFT, NULL);
+	gnt_bindable_register_binding(bindable, "step-backward", GNT_KEY_DOWN, NULL);
+	gnt_bindable_class_register_action(bindable, "step-forward", step_forward, GNT_KEY_RIGHT, NULL);
+	gnt_bindable_register_binding(bindable, "step-forward", GNT_KEY_UP, NULL);
+
+	/* XXX: how would home/end work? */
+
+	gnt_style_read_actions(G_OBJECT_CLASS_TYPE(klass), GNT_BINDABLE_CLASS(klass));
+}
+
+static void
+gnt_slider_init(GTypeInstance *instance, gpointer class)
+{
+	GntWidget *widget = GNT_WIDGET(instance);
+	GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_SHADOW | GNT_WIDGET_NO_BORDER | GNT_WIDGET_CAN_TAKE_FOCUS);
+	widget->priv.minw = 1;
+	widget->priv.minh = 1;
+	GNTDEBUG;
+}
+
+/******************************************************************************
+ * GntSlider API
+ *****************************************************************************/
+GType
+gnt_slider_get_gtype(void)
+{
+	static GType type = 0;
+
+	if(type == 0)
+	{
+		static const GTypeInfo info = {
+			sizeof(GntSliderClass),
+			NULL,                   /* base_init        */
+			NULL,                   /* base_finalize    */
+			(GClassInitFunc)gnt_slider_class_init,
+			NULL,                   /* class_finalize   */
+			NULL,                   /* class_data       */
+			sizeof(GntSlider),
+			0,                      /* n_preallocs      */
+			gnt_slider_init,        /* instance_init    */
+			NULL                    /* value_table      */
+		};
+
+		type = g_type_register_static(GNT_TYPE_WIDGET,
+		                              "GntSlider",
+		                              &info, 0);
+	}
+
+	return type;
+}
+
+GntWidget *gnt_slider_new(gboolean vertical, int max, int min)
+{
+	GntWidget *widget = g_object_new(GNT_TYPE_SLIDER, NULL);
+	GntSlider *slider = GNT_SLIDER(widget);
+
+	slider->vertical = vertical;
+
+	if (vertical) {
+		GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_GROW_Y);
+	} else {
+		GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_GROW_X);
+	}
+
+	gnt_slider_set_range(slider, max, min);
+	slider->step = 1;
+
+	return widget;
+}
+
+void gnt_slider_set_value(GntSlider *slider, int value)
+{
+	if (slider->current == value)
+		return;
+	slider->current = value;
+	sanitize_value(slider);
+	redraw_slider(slider);
+	slider_value_changed(slider);
+}
+
+int gnt_slider_advance_step(GntSlider *slider, int steps)
+{
+	slider->current += steps * slider->step;
+	sanitize_value(slider);
+	redraw_slider(slider);
+	slider_value_changed(slider);
+	return slider->current;
+}
+
+void gnt_slider_set_step(GntSlider *slider, int step)
+{
+	slider->step = step;
+}
+
+void gnt_slider_set_range(GntSlider *slider, int max, int min)
+{
+	slider->max = MAX(max, min);
+	slider->min = MIN(max, min);
+	sanitize_value(slider);
+}
+
+static void
+update_label(GntSlider *slider, int current_value, GntLabel *label)
+{
+	char value[256];
+	g_snprintf(value, sizeof(value), "%d/%d", current_value, slider->max);
+	gnt_label_set_text(label, value);
+}
+
+void gnt_slider_reflect_label(GntSlider *slider, GntLabel *label)
+{
+	g_signal_connect(G_OBJECT(slider), "changed", G_CALLBACK(update_label), label);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/finch/libgnt/gntslider.h	Fri Jun 29 12:45:08 2007 +0000
@@ -0,0 +1,139 @@
+/**
+ * @file gntslider.h Slider API
+ * @ingroup gnt
+ */
+/*
+ * GNT - The GLib Ncurses Toolkit
+ *
+ * GNT is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef GNT_SLIDER_H
+#define GNT_SLIDER_H
+
+#include "gntwidget.h"
+#include "gnt.h"
+#include "gntlabel.h"
+
+#define GNT_TYPE_SLIDER             (gnt_slider_get_gtype())
+#define GNT_SLIDER(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj), GNT_TYPE_SLIDER, GntSlider))
+#define GNT_SLIDER_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass), GNT_TYPE_SLIDER, GntSliderClass))
+#define GNT_IS_SLIDER(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj), GNT_TYPE_SLIDER))
+#define GNT_IS_SLIDER_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass), GNT_TYPE_SLIDER))
+#define GNT_SLIDER_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS((obj), GNT_TYPE_SLIDER, GntSliderClass))
+
+#define GNT_SLIDER_FLAGS(obj)                (GNT_SLIDER(obj)->priv.flags)
+#define GNT_SLIDER_SET_FLAGS(obj, flags)     (GNT_SLIDER_FLAGS(obj) |= flags)
+#define GNT_SLIDER_UNSET_FLAGS(obj, flags)   (GNT_SLIDER_FLAGS(obj) &= ~(flags))
+
+typedef struct _GntSlider			GntSlider;
+typedef struct _GntSliderPriv		GntSliderPriv;
+typedef struct _GntSliderClass		GntSliderClass;
+
+struct _GntSlider
+{
+	GntWidget parent;
+
+	gboolean vertical;
+
+	int max;        /* maximum value */
+	int min;        /* minimum value */
+	int step;       /* amount to change at each step */
+	int current;    /* current value */
+};
+
+struct _GntSliderClass
+{
+	GntWidgetClass parent;
+
+	void (*changed)(GntSlider *slider, int);
+	void (*gnt_reserved1)(void);
+	void (*gnt_reserved2)(void);
+	void (*gnt_reserved3)(void);
+	void (*gnt_reserved4)(void);
+};
+
+G_BEGIN_DECLS
+
+/**
+ * @return The GType for GntSlider
+ */
+GType gnt_slider_get_gtype(void);
+
+#define gnt_hslider_new(max, min) gnt_slider_new(FALSE, max, min)
+#define gnt_vslider_new(max, min) gnt_slider_new(TRUE, max, min)
+
+/**
+ * Create a new slider.
+ *
+ * @param orient A vertical slider is created if @c TRUE, otherwise the slider is horizontal.
+ * @param max    The maximum value for the slider
+ * @param min    The minimum value for the slider
+ *
+ * @return  The newly created slider
+ */
+GntWidget * gnt_slider_new(gboolean orient, int max, int min);
+
+/**
+ * Set the range of the slider.
+ *
+ * @param slider  The slider
+ * @param max     The maximum value
+ * @param min     The minimum value
+ */
+void gnt_slider_set_range(GntSlider *slider, int max, int min);
+
+/**
+ * Sets the amount of change at each step.
+ * 
+ * @param slider  The slider
+ * @param step    The amount for each ste
+ */
+void gnt_slider_set_step(GntSlider *slider, int step);
+
+/**
+ * Advance the slider forward or backward.
+ *
+ * @param slider   The slider
+ * @param steps    The number of amounts to change, positive to change
+ *                 forward, negative to change backward
+ *
+ * @return   The value of the slider after the change
+ */
+int gnt_slider_advance_step(GntSlider *slider, int steps);
+
+/**
+ * Set the current value for the slider.
+ *
+ * @param slider  The slider
+ * @param value   The current value
+ */
+void gnt_slider_set_value(GntSlider *slider, int value);
+
+/**
+ * Update a label with the value of the slider whenever the value changes.
+ *
+ * @param slider   The slider
+ * @param label    The label to update
+ */
+void gnt_slider_reflect_label(GntSlider *slider, GntLabel *label);
+
+G_END_DECLS
+
+#endif /* GNT_SLIDER_H */
--- a/finch/libgnt/gntstyle.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/finch/libgnt/gntstyle.c	Fri Jun 29 12:45:08 2007 +0000
@@ -46,7 +46,7 @@
 	return str_styles[style];
 }
 
-const char *gnt_style_get_from_name(const char *group, const char *key)
+char *gnt_style_get_from_name(const char *group, const char *key)
 {
 #if GLIB_CHECK_VERSION(2,6,0)
 	return g_key_file_get_value(gkfile, group, key, NULL);
--- a/finch/libgnt/gntstyle.h	Fri Jun 29 02:58:27 2007 +0000
+++ b/finch/libgnt/gntstyle.h	Fri Jun 29 12:45:08 2007 +0000
@@ -45,7 +45,7 @@
 
 const char *gnt_style_get(GntStyle style);
 
-const char *gnt_style_get_from_name(const char *group, const char *key);
+char *gnt_style_get_from_name(const char *group, const char *key);
 
 /**
  * 
--- a/finch/libgnt/gnttextview.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/finch/libgnt/gnttextview.c	Fri Jun 29 12:45:08 2007 +0000
@@ -65,6 +65,7 @@
 	int i = 0;
 	GList *lines;
 	int rows, scrcol;
+	gboolean has_scroll = !(view->flags & GNT_TEXT_VIEW_NO_SCROLL);
 
 	wbkgd(widget->window, COLOR_PAIR(GNT_COLOR_NORMAL));
 	werase(widget->window);
@@ -111,12 +112,12 @@
 			*end = back;
 		}
 		wattroff(widget->window, A_UNDERLINE | A_BLINK | A_REVERSE);
-		whline(widget->window, ' ', widget->priv.width - line->length - 1);
+		whline(widget->window, ' ', widget->priv.width - line->length - has_scroll);
 	}
 
 	scrcol = widget->priv.width - 1;
 	rows = widget->priv.height - 2;
-	if (rows > 0)
+	if (has_scroll && rows > 0)
 	{
 		int total = g_list_length(g_list_first(view->list));
 		int showing, position, up, down;
@@ -143,11 +144,13 @@
 				ACS_CKBOARD | COLOR_PAIR(GNT_COLOR_HIGHLIGHT_D), showing);
 	}
 
-	mvwaddch(widget->window, 0, scrcol,
-			(lines ? ACS_UARROW : ' ') | COLOR_PAIR(GNT_COLOR_HIGHLIGHT_D));
-	mvwaddch(widget->window, widget->priv.height - 1, scrcol,
-			((view->list && view->list->prev) ? ACS_DARROW : ' ') |
-				COLOR_PAIR(GNT_COLOR_HIGHLIGHT_D));
+	if (has_scroll) {
+		mvwaddch(widget->window, 0, scrcol,
+				(lines ? ACS_UARROW : ' ') | COLOR_PAIR(GNT_COLOR_HIGHLIGHT_D));
+		mvwaddch(widget->window, widget->priv.height - 1, scrcol,
+				((view->list && view->list->prev) ? ACS_DARROW : ' ') |
+					COLOR_PAIR(GNT_COLOR_HIGHLIGHT_D));
+	}
 
 	GNTDEBUG;
 }
@@ -483,6 +486,8 @@
 	GList *list = view->list;
 	GntTextLine *line;
 	int len;
+	gboolean has_scroll = !(view->flags & GNT_TEXT_VIEW_NO_SCROLL);
+	gboolean wrap_word = !(view->flags & GNT_TEXT_VIEW_WRAP_CHAR);
 
 	if (text == NULL || *text == '\0')
 		return;
@@ -519,7 +524,7 @@
 		}
 
 		line = view->list->data;
-		if (line->length == widget->priv.width - 1) {
+		if (line->length == widget->priv.width - has_scroll) {
 			/* The last added line was exactly the same width as the widget */
 			line = g_new0(GntTextLine, 1);
 			line->soft = TRUE;
@@ -528,15 +533,15 @@
 
 		if ((end = strchr(start, '\r')) != NULL ||
 			(end = strchr(start, '\n')) != NULL) {
-			len = gnt_util_onscreen_width(start, end - 1);
-			if (len >= widget->priv.width - line->length - 1) {
+			len = gnt_util_onscreen_width(start, end - has_scroll);
+			if (len >= widget->priv.width - line->length - has_scroll) {
 				end = NULL;
 			}
 		}
 
 		if (end == NULL)
 			end = gnt_util_onscreen_width_to_pointer(start,
-					widget->priv.width - line->length - 1, &len);
+					widget->priv.width - line->length - has_scroll, &len);
 
 		/* Try to append to the previous segment if possible */
 		if (line->segments) {
@@ -554,7 +559,7 @@
 		}
 
 		oldl = line;
-		if (*end && *end != '\n' && *end != '\r') {
+		if (wrap_word && *end && *end != '\n' && *end != '\r') {
 			const char *tmp = end;
 			while (end && *end != '\n' && *end != '\r' && !g_ascii_isspace(*end)) {
 				end = g_utf8_find_prev_char(seg->start + view->string->str, end);
@@ -783,3 +788,8 @@
 	g_signal_connect(G_OBJECT(widget), "key_pressed", G_CALLBACK(scroll_tv), view);
 }
 
+void gnt_text_view_set_flag(GntTextView *view, GntTextViewFlag flag)
+{
+	view->flags |= flag;
+}
+
--- a/finch/libgnt/gnttextview.h	Fri Jun 29 02:58:27 2007 +0000
+++ b/finch/libgnt/gnttextview.h	Fri Jun 29 12:45:08 2007 +0000
@@ -47,6 +47,11 @@
 typedef struct _GntTextViewPriv		GntTextViewPriv;
 typedef struct _GntTextViewClass		GntTextViewClass;
 
+typedef enum {
+	GNT_TEXT_VIEW_NO_SCROLL     = 1 << 0,
+	GNT_TEXT_VIEW_WRAP_CHAR     = 1 << 1,
+} GntTextViewFlag;
+
 struct _GntTextView
 {
 	GntWidget parent;
@@ -55,6 +60,7 @@
 	GList *list;        /* List of GntTextLine */
 
 	GList *tags;       /* A list of tags */
+	GntTextViewFlag flags;
 };
 
 typedef enum
@@ -177,6 +183,14 @@
  */
 void gnt_text_view_attach_scroll_widget(GntTextView *view, GntWidget *widget);
 
+/**
+ * Set a GntTextViewFlag for the textview widget.
+ *
+ * @param view  The textview widget
+ * @param flag  The flag to set
+ */
+void gnt_text_view_set_flag(GntTextView *view, GntTextViewFlag flag);
+
 G_END_DECLS
 
 #endif /* GNT_TEXT_VIEW_H */
--- a/finch/libgnt/gnttree.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/finch/libgnt/gnttree.c	Fri Jun 29 12:45:08 2007 +0000
@@ -1526,6 +1526,12 @@
 	tree->columns[col].width = width;
 }
 
+void gnt_tree_set_column_title(GntTree *tree, int index, const char *title)
+{
+	g_free(tree->columns[index].title);
+	tree->columns[index].title = g_strdup(title);
+}
+
 void gnt_tree_set_column_titles(GntTree *tree, ...)
 {
 	int i;
--- a/finch/libgnt/gnttree.h	Fri Jun 29 02:58:27 2007 +0000
+++ b/finch/libgnt/gnttree.h	Fri Jun 29 12:45:08 2007 +0000
@@ -302,6 +302,15 @@
 void gnt_tree_set_col_width(GntTree *tree, int col, int width);
 
 /**
+ * Set the title for a column.
+ *
+ * @param tree   The tree
+ * @param index  The index of the column
+ * @param title  The title for the column
+ */
+void gnt_tree_set_column_title(GntTree *tree, int index, const char *title);
+
+/**
  * 
  * @param tree
  */
--- a/finch/libgnt/gntwidget.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/finch/libgnt/gntwidget.c	Fri Jun 29 12:45:08 2007 +0000
@@ -389,7 +389,7 @@
 
 	g_signal_emit(widget, signals[SIG_DRAW], 0);
 	gnt_widget_queue_update(widget);
-	GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_DRAWING);
+	GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_DRAWING | GNT_WIDGET_INVISIBLE);
 }
 
 gboolean
--- a/finch/libgnt/wms/irssi.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/finch/libgnt/wms/irssi.c	Fri Jun 29 12:45:08 2007 +0000
@@ -274,7 +274,7 @@
 
 void gntwm_init(GntWM **wm)
 {
-	const char *style = NULL;
+	char *style = NULL;
 	Irssi *irssi;
 
 	irssi = g_object_new(TYPE_IRSSI, NULL);
@@ -282,9 +282,11 @@
 
 	style = gnt_style_get_from_name("irssi", "split-v");
 	irssi->vert = style ? atoi(style) : 1;
+	g_free(style);
 
 	style = gnt_style_get_from_name("irssi", "split-h");
 	irssi->horiz = style ? atoi(style) : 1;
+	g_free(style);
 
 	irssi->vert = MAX(irssi->vert, 1);
 	irssi->horiz = MAX(irssi->horiz, 1);
--- a/libpurple/protocols/jabber/jabber.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/libpurple/protocols/jabber/jabber.c	Fri Jun 29 12:45:08 2007 +0000
@@ -1369,11 +1369,13 @@
 	field = purple_request_field_string_new("password1", _("Password"),
 			"", FALSE);
 	purple_request_field_string_set_masked(field, TRUE);
+	purple_request_field_set_required(field, TRUE);
 	purple_request_field_group_add_field(group, field);
 
 	field = purple_request_field_string_new("password2", _("Password (again)"),
 			"", FALSE);
 	purple_request_field_string_set_masked(field, TRUE);
+	purple_request_field_set_required(field, TRUE);
 	purple_request_field_group_add_field(group, field);
 
 	purple_request_fields(js->gc, _("Change XMPP Password"),
--- a/libpurple/protocols/jabber/presence.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/libpurple/protocols/jabber/presence.c	Fri Jun 29 12:45:08 2007 +0000
@@ -558,7 +558,6 @@
 			jabber_buddy_remove_resource(jb, jid->resource);
 			if((conv = jabber_find_unnormalized_conv(from, js->gc->account)))
 				purple_conversation_set_name(conv, buddy_name);
-	printf("Removed resource\n");
 
 		} else {
 			jbr = jabber_buddy_track_resource(jb, jid->resource, priority,
--- a/libpurple/request.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/libpurple/request.c	Fri Jun 29 12:45:08 2007 +0000
@@ -150,7 +150,8 @@
 		switch (purple_request_field_get_type(field))
 		{
 			case PURPLE_REQUEST_FIELD_STRING:
-				if (purple_request_field_string_get_value(field) == NULL)
+				if (purple_request_field_string_get_value(field) == NULL ||
+				    *(purple_request_field_string_get_value(field)) == '\0')
 					return FALSE;
 
 				break;
--- a/pidgin/gtkblist.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/pidgin/gtkblist.c	Fri Jun 29 12:45:08 2007 +0000
@@ -3116,6 +3116,15 @@
 	} else if(PURPLE_BLIST_NODE_IS_BUDDY(node)) {
 		buddy = (PurpleBuddy*)node;
 		gtkbuddynode = node->ui_data;
+		p = purple_buddy_get_presence(buddy);
+		if (purple_presence_is_status_primitive_active(p, PURPLE_STATUS_MOBILE)) {
+			path = g_build_filename(DATADIR, "pixmaps", "pidgin", "emblems", 
+						"16", "mobile.png", NULL);
+			ret = gdk_pixbuf_new_from_file(path, NULL);
+			g_free(path);
+			return ret;
+		}
+
 		if (((struct _pidgin_blist_node*)(node->parent->ui_data))->contact_expanded)
 			return pidgin_create_prpl_icon(((PurpleBuddy*)node)->account, PIDGIN_PRPL_ICON_SMALL);
 	} else if(PURPLE_BLIST_NODE_IS_CHAT(node)) {
@@ -4911,10 +4920,17 @@
 	gboolean selected;
 	char group_count[12] = "";
 	char *mark, *esc;
+	PurpleBlistNode *selected_node = NULL;
+	GtkTreeIter iter;
 
 	group = (PurpleGroup*)gnode;
 	textcolor = gtkblist->treeview->style->fg[GTK_STATE_ACTIVE];
-	selected = gtkblist ? (gtkblist->selected_node == gnode) : FALSE;
+        
+	if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkblist->treeview)), NULL, &iter)) {
+		gtk_tree_model_get(GTK_TREE_MODEL(gtkblist->treemodel), &iter,
+				NODE_COLUMN, &selected_node, -1);
+	}
+	selected = (gnode == selected_node);
 
 	if (!expanded) {
 		g_snprintf(group_count, sizeof(group_count), " (%d/%d)",
--- a/pidgin/gtkconv.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/pidgin/gtkconv.c	Fri Jun 29 12:45:08 2007 +0000
@@ -256,19 +256,11 @@
 	 * negate it anyway.  --luke */
 	if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_IM)
 	{
-		if (w == gtkconv->imhtml) {
-			purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/im/default_width", allocation->width);
-			purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/im/default_height", allocation->height);
-		}
 		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->imhtml) {
-			purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_width", allocation->width);
-			purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_height", allocation->height);
-		}
 		if (w == gtkconv->lower_hbox)
 			purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/chat/entry_height", allocation->height);
 	}
@@ -1749,6 +1741,9 @@
 
 	gtk_tree_selection_select_path(GTK_TREE_SELECTION(
 			gtk_tree_view_get_selection(GTK_TREE_VIEW(gtkchat->list))), path);
+	gtk_tree_view_set_cursor(GTK_TREE_VIEW(gtkchat->list),
+							 path, NULL, FALSE); 
+	gtk_widget_grab_focus(GTK_WIDGET(gtkchat->list));
 
 	gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path);
 	gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, CHAT_USERS_NAME_COLUMN, &who, -1);
@@ -4477,15 +4472,6 @@
 	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(imhtml_sw),
 	                               imhtml_sw_hscroll, GTK_POLICY_ALWAYS);
 
-	gtk_widget_set_size_request(gtkconv->imhtml,
-			chat ? purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_width") :
-			purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_width"),
-			chat ? purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/chat/default_height") :
-			purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_height"));
-
-	g_signal_connect(G_OBJECT(gtkconv->imhtml), "size-allocate",
-	                 G_CALLBACK(size_allocate_cb), gtkconv);
-
 	g_signal_connect_after(G_OBJECT(gtkconv->imhtml), "button_press_event",
 	                       G_CALLBACK(entry_stop_rclick_cb), NULL);
 	g_signal_connect(G_OBJECT(gtkconv->imhtml), "key_press_event",
@@ -6208,8 +6194,9 @@
 			const char *topic = purple_conv_chat_get_topic(chat);
 			markup = g_strdup_printf("%s%s<span color='%s' size='smaller'>%s</span>",
 						purple_conversation_get_title(conv),
+						topic ? "\n" : "",
 						pidgin_get_dim_grey_string(gtkconv->infopane),
-						topic ? "\n" : "", topic ? topic : "");
+						topic ? topic : "");
 		}
 		gtk_list_store_set(gtkconv->infopane_model, &(gtkconv->infopane_iter),
 				TEXT_COLUMN, markup, -1);
@@ -7071,6 +7058,8 @@
 	purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/tabs", TRUE);
 	purple_prefs_add_int(PIDGIN_PREFS_ROOT "/conversations/tab_side", GTK_POS_TOP);
 	purple_prefs_add_int(PIDGIN_PREFS_ROOT "/conversations/scrollback_lines", 4000);
+	purple_prefs_add_int(PIDGIN_PREFS_ROOT "/conversations/x", 0);
+	purple_prefs_add_int(PIDGIN_PREFS_ROOT "/conversations/y", 0);
 
 	purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/conversations/use_theme_font", TRUE);
 	purple_prefs_add_string(PIDGIN_PREFS_ROOT "/conversations/custom_font", "");
@@ -8220,6 +8209,44 @@
 	regenerate_plugins_items(data);
 }
 
+static gboolean gtk_conv_configure_cb(GtkWidget *w, GdkEventConfigure *event, gpointer data) {
+	int x, y;
+	
+	if (GTK_WIDGET_VISIBLE(w))
+		gtk_window_get_position(GTK_WINDOW(w), &x, &y);
+	else
+		return FALSE; /* carry on normally */
+
+	/* Workaround for GTK+ bug # 169811 - "configure_event" is fired
+	* when the window is being maximized */
+	if (gdk_window_get_state(w->window) & GDK_WINDOW_STATE_MAXIMIZED)
+		return FALSE;
+	
+	/* don't save if nothing changed */
+	if (x == purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/x") &&
+	    y == purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/y") &&
+	    event->width  == purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_width") &&
+	    event->height == purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/default_height"))
+		return FALSE; /* carry on normally */
+		
+	/* don't save off-screen positioning */
+	if (x + event->width < 0 ||
+	    y + event->height < 0 ||
+	    x > gdk_screen_width() ||
+	    y > gdk_screen_height())
+		return FALSE; /* carry on normally */
+
+        /* store the position */
+        purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/x",      x);
+	purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/y",      y);
+	purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/im/width",  event->width);
+	purple_prefs_set_int(PIDGIN_PREFS_ROOT "/conversations/im/height", event->height);
+
+	/* continue to handle event normally */
+	return FALSE;
+						
+}
+
 PidginWindow *
 pidgin_conv_window_new()
 {
@@ -8234,7 +8261,8 @@
 
 	/* Create the window. */
 	win->window = pidgin_create_window(NULL, 0, "conversation", TRUE);
-	GTK_WINDOW(win->window)->allow_shrink = TRUE;
+	gtk_window_set_default_size(GTK_WINDOW(win->window), purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/width"),
+							     purple_prefs_get_int(PIDGIN_PREFS_ROOT "/conversations/im/height"));
 
 	if (available_list == NULL) {
 		create_icon_lists(win->window);
@@ -8242,7 +8270,8 @@
 
 	g_signal_connect(G_OBJECT(win->window), "delete_event",
 	                 G_CALLBACK(close_win_cb), win);
-
+	g_signal_connect(G_OBJECT(win->window), "configure_event", 
+			 G_CALLBACK(gtk_conv_configure_cb), NULL);
 	g_signal_connect(G_OBJECT(win->window), "focus_in_event",
 	                 G_CALLBACK(focus_win_cb), win);
 
--- a/pidgin/gtkdialogs.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/pidgin/gtkdialogs.c	Fri Jun 29 12:45:08 2007 +0000
@@ -165,7 +165,7 @@
 	{N_("Japanese"),            "ja", "Takashi Aihana", "aihana@gnome.gr.jp"},
 	{N_("Georgian"),            "ka", N_("Ubuntu Georgian Translators"), "alexander.didebulidze@stusta.mhn.de"},
 	{N_("Kannada"),             "kn", N_("Kannada Translation team"), "translation@sampada.info"},
-	{N_("Korean"),              "ko", "Kyung-uk Son", "vvs740@chol.com"},
+	{N_("Korean"),              "ko", "Sushizang", "sushizang@empal.com"},
 	{N_("Kurdish"),             "ku", "Erdal Ronahi", "erdal.ronahi@gmail.com"},
 	{N_("Kurdish"),             "ku", "Amed Ç. Jiyan", "amedcj@hotmail.com"},
 	{N_("Kurdish"),             "ku", "Rizoyê Xerzî", "rizoxerzi@hotmail.com"},
@@ -230,6 +230,7 @@
 	{N_("Japanese"),            "ja", "Junichi Uekawa", NULL},
 	{N_("Georgian"),            "ka", "Temuri Doghonadze", NULL},
 	{N_("Korean"),              "ko", "Sang-hyun S, A Ho-seok Lee", NULL},
+	{N_("Korean"),              "ko", "Kyeong-uk Son", "hey@gnome.or.kr"},
 	{N_("Lithuanian"),          "lt", "Andrius Štikonas", NULL},
 	{N_("Lithuanian"),          "lt", "Gediminas Čičinskas", NULL},
 	{N_("Macedonian"),          "mk", "Tomislav Markovski", "herrera@users.sf.net"},
--- a/pidgin/gtkmain.c	Fri Jun 29 02:58:27 2007 +0000
+++ b/pidgin/gtkmain.c	Fri Jun 29 12:45:08 2007 +0000
@@ -677,6 +677,8 @@
 		return 1;
 	}
 
+	g_set_application_name(_("Pidgin"));
+
 #ifdef _WIN32
 	winpidgin_init(hint);
 #endif
@@ -855,7 +857,6 @@
 	winpidgin_post_init();
 #endif
 
-	g_set_application_name(_("Pidgin"));
 	gtk_main();
 
 #ifdef HAVE_SIGNAL_H
--- a/po/ChangeLog	Fri Jun 29 02:58:27 2007 +0000
+++ b/po/ChangeLog	Fri Jun 29 12:45:08 2007 +0000
@@ -1,5 +1,8 @@
 Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
 
+version 2.1.0
+	* Korean translation updated (Sushizang)
+
 version 2.0.2
 	* Chinese (Traditional) translation updated (Ambrose C. Li)
 	* English (British) translation updated (Luke Ross)
--- a/po/ko.po	Fri Jun 29 02:58:27 2007 +0000
+++ b/po/ko.po	Fri Jun 29 12:45:08 2007 +0000
@@ -11,7 +11,7 @@
 "Project-Id-Version: gaim 2.0\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2005-10-27 16:12-0400\n"
-"PO-Revision-Date: 2007-05-07 09:18+0900\n"
+"PO-Revision-Date: 2007-06-28 10:48+0900\n"
 "Last-Translator: sushizang <sushizang@empal.com>\n"
 "Language-Team: GTP Korean <gnome-kr-translation@gnome.or.kr>\n"
 "MIME-Version: 1.0\n"
@@ -1388,18 +1388,34 @@
 msgid "Login Options"
 msgstr "로그인 설정"
 
-#: ../gtk/gtkaccount.c:492
-msgid "Local alias:"
-msgstr "별칭:"
+#: ../pidgin/gtkaccount.c:430
+msgid "Pro_tocol:"
+msgstr "프로토콜(_t):"
+
+#: ../pidgin/gtkaccount.c:441
+msgid "Screen _name:"
+msgstr "아이디(_n):"
+
+#: ../pidgin/gtkaccount.c:531
+msgid "_Local alias:"
+msgstr "별칭(_L):"
+
+#: ../pidgin/gtkaccount.c:535
+msgid "Remember pass_word"
+msgstr "비밀번호 저장"
 
 #. Build the user options frame.
 #: ../gtk/gtkaccount.c:554
 msgid "User Options"
 msgstr "사용자 설정"
 
+#: ../pidgin/gtkaccount.c:606
+msgid "New _mail notifications"
+msgstr "새 메일 알림"
+
 #. Buddy icon
-#: ../gtk/gtkaccount.c:572
-msgid "Use this buddy icon for this account:"
+#: ../pidgin/gtkaccount.c:611
+msgid "Use this buddy _icon for this account:"
 msgstr "다음 아이콘 사용:"
 
 #. Build the protocol options frame.
@@ -3906,6 +3922,22 @@
 msgid "F_lash window when IMs are received"
 msgstr "메시지를 받으면 창을 깜빡거림(_L)"
 
+#: ../pidgin/gtkprefs.c:943
+msgid "Font"
+msgstr "글꼴"
+
+#: ../pidgin/gtkprefs.c:945
+msgid "Use document font from _theme"
+msgstr "테마로부터 문서 글꼴 사용(_t)"
+
+#: ../pidgin/gtkprefs.c:947
+msgid "Use font from _theme"
+msgstr "테마로부터 글꼴 사용(_t)"
+
+#: ../pidgin/gtkprefs.c:949
+msgid "Conversation _font:"
+msgstr "대화창 글꼴(_f):"
+
 #: ../gtk/gtkprefs.c:925
 msgid "Default Formatting"
 msgstr "기본 서식"
@@ -4710,7 +4742,7 @@
 #. Not used yet.
 #: ../gtk/plugins/contact_priority.c:66
 msgid "Buddy is mobile"
-msgstr "이동 중인 친구"
+msgstr "휴대 기기 친구"
 
 #: ../gtk/plugins/contact_priority.c:68
 msgid "Buddy is offline"
@@ -9352,7 +9384,7 @@
 
 #: ../libgaim/protocols/msn/msn.c:291
 msgid "Set your mobile phone number."
-msgstr "이동 전화번호를 설정해 주십시오."
+msgstr "휴대 전화번호를 설정해 주십시오."
 
 #: ../libgaim/protocols/msn/msn.c:304
 msgid "Allow MSN Mobile pages?"
@@ -9360,7 +9392,7 @@
 
 #: ../libgaim/protocols/msn/msn.c:305
 msgid "Do you want to allow or disallow people on your buddy list to send you MSN Mobile pages to your cell phone or other mobile device?"
-msgstr "친구가 휴대 전화 등의 모바일 기기에 MSN 모바일 호출을 전송하는 것을 허가하시겠습니까?"
+msgstr "친구가 휴대 전화 등의 휴대용 기기에 MSN 모바일 호출을 전송하는 것을 허가하시겠습니까?"
 
 #: ../libgaim/protocols/msn/msn.c:309
 msgid "Allow"
@@ -9434,11 +9466,11 @@
 
 #: ../libgaim/protocols/msn/msn.c:638
 msgid "Enable/Disable Mobile Devices..."
-msgstr "모바일 기기 사용/사용 안 함..."
+msgstr "휴대용 기기 사용/사용 안 함..."
 
 #: ../libgaim/protocols/msn/msn.c:643
 msgid "Allow/Disallow Mobile Pages..."
-msgstr "모바일 호출 허가/허가 안 함..."
+msgstr "무선 호출 허가/허가 안 함..."
 
 #: ../libgaim/protocols/msn/msn.c:653
 msgid "Open Hotmail Inbox"
@@ -9446,7 +9478,7 @@
 
 #: ../libgaim/protocols/msn/msn.c:677
 msgid "Send to Mobile"
-msgstr "모바일 기기에 전송"
+msgstr "휴대용 기기에 전송"
 
 #: ../libgaim/protocols/msn/msn.c:687
 #: ../libgaim/protocols/novell/novell.c:3443
@@ -9563,11 +9595,11 @@
 
 #: ../libgaim/protocols/msn/msn.c:1602
 msgid "Home Phone"
-msgstr "자택 전화1"
+msgstr "자택 전화"
 
 #: ../libgaim/protocols/msn/msn.c:1603
 msgid "Home Phone 2"
-msgstr "자택 전화2"
+msgstr "자택 전화 2"
 
 #: ../libgaim/protocols/msn/msn.c:1604
 #: ../libgaim/protocols/oscar/oscar.c:3768
@@ -9576,7 +9608,7 @@
 
 #: ../libgaim/protocols/msn/msn.c:1605
 msgid "Personal Mobile"
-msgstr "휴대 전화"
+msgstr "개인 휴대 기기"
 
 #: ../libgaim/protocols/msn/msn.c:1606
 msgid "Home Fax"
@@ -9620,11 +9652,11 @@
 
 #: ../libgaim/protocols/msn/msn.c:1632
 msgid "Work Phone"
-msgstr "회사 전화1"
+msgstr "회사 전화"
 
 #: ../libgaim/protocols/msn/msn.c:1633
 msgid "Work Phone 2"
-msgstr "회사 전화2"
+msgstr "회사 전화 2"
 
 #: ../libgaim/protocols/msn/msn.c:1634
 #: ../libgaim/protocols/oscar/oscar.c:3781
@@ -9633,7 +9665,7 @@
 
 #: ../libgaim/protocols/msn/msn.c:1635
 msgid "Work Mobile"
-msgstr "회사 휴대 전화"
+msgstr "업무 휴대 기기"
 
 #: ../libgaim/protocols/msn/msn.c:1636
 msgid "Work Pager"
@@ -14816,7 +14848,7 @@
 
 #: ../libgaim/status.c:160
 msgid "Mobile"
-msgstr "이동 중"
+msgstr "휴대 기기"
 
 #: ../libgaim/status.c:611
 #, c-format