changeset 14047:c5bfede33622

[gaim-migrate @ 16660] A couple of minor adjustments, memory leak fixes. And request-ui is almost complete now. committer: Tailor Script <tailor@pidgin.im>
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Mon, 07 Aug 2006 02:15:58 +0000
parents eb1a7d176149
children 9c4bec886220
files console/gntblist.c console/gntconv.c console/gntrequest.c console/libgnt/gntcombobox.c console/libgnt/gnttree.h console/libgnt/test/combo.c
diffstat 6 files changed, 238 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/console/gntblist.c	Sun Aug 06 23:47:34 2006 +0000
+++ b/console/gntblist.c	Mon Aug 07 02:15:58 2006 +0000
@@ -61,7 +61,7 @@
 static void add_chat(GaimChat *chat, GGBlist *ggblist);
 static void add_node(GaimBlistNode *node, GGBlist *ggblist);
 static void draw_tooltip(GGBlist *ggblist);
-static void remove_typing_cb(gpointer null);
+static gboolean remove_typing_cb(gpointer null);
 static void remove_peripherals(GGBlist *ggblist);
 static const char * get_display_name(GaimBlistNode *node);
 
@@ -873,7 +873,7 @@
 	return;
 }
 
-static void
+static gboolean
 remove_typing_cb(gpointer null)
 {
 	GaimSavedStatus *current;
@@ -887,7 +887,7 @@
 
 	newmessage = gnt_entry_get_text(GNT_ENTRY(ggblist->statustext));
 	item = gnt_combo_box_get_selected_data(GNT_COMBO_BOX(ggblist->status));
-	g_return_if_fail(item->type == STATUS_PRIMITIVE);
+	g_return_val_if_fail(item->type == STATUS_PRIMITIVE, FALSE);
 	newprim = item->u.prim;
 
 	if (newprim != prim || ((message && !newmessage) ||
@@ -908,6 +908,7 @@
 	gnt_box_give_focus_to_child(GNT_BOX(ggblist->window), ggblist->tree);
 	g_source_remove(ggblist->typing);
 	ggblist->typing = 0;
+	return FALSE;
 }
 
 static void
@@ -932,7 +933,7 @@
 static gboolean
 status_text_changed(GntEntry *entry, const char *text, gpointer null)
 {
-	if (text[0] == 27 && ggblist->typing == 0)
+	if ((text[0] == 27 || (text[0] == '\t' && text[1] == '\0')) && ggblist->typing == 0)
 		return FALSE;
 
 	g_source_remove(ggblist->typing);
--- a/console/gntconv.c	Sun Aug 06 23:47:34 2006 +0000
+++ b/console/gntconv.c	Mon Aug 07 02:15:58 2006 +0000
@@ -107,17 +107,20 @@
 		}
 		else
 		{
+			char *escape = g_markup_escape_text(text, -1);
 			switch (gaim_conversation_get_type(ggconv->conv))
 			{
 				case GAIM_CONV_TYPE_IM:
-					gaim_conv_im_send_with_flags(GAIM_CONV_IM(ggconv->conv), text, GAIM_MESSAGE_SEND);
+					gaim_conv_im_send_with_flags(GAIM_CONV_IM(ggconv->conv), escape, GAIM_MESSAGE_SEND);
 					break;
 				case GAIM_CONV_TYPE_CHAT:
-					gaim_conv_chat_send(GAIM_CONV_CHAT(ggconv->conv), text);
+					gaim_conv_chat_send(GAIM_CONV_CHAT(ggconv->conv), escape);
 					break;
 				default:
+					g_free(escape);
 					g_return_val_if_reached(FALSE);
 			}
+			g_free(escape);
 		}
 		gnt_entry_clear(GNT_ENTRY(ggconv->entry));
 		return TRUE;
--- a/console/gntrequest.c	Sun Aug 06 23:47:34 2006 +0000
+++ b/console/gntrequest.c	Mon Aug 07 02:15:58 2006 +0000
@@ -1,15 +1,19 @@
 #include <gnt.h>
 #include <gntbox.h>
 #include <gntbutton.h>
+#include <gntcheckbox.h>
 #include <gntcombobox.h>
 #include <gntentry.h>
 #include <gntlabel.h>
+#include <gntline.h>
+#include <gnttree.h>
 
+#include "gntgaim.h"
 #include "gntrequest.h"
 
 static GntWidget *
 setup_request_window(const char *title, const char *primary,
-		const char *secondary)
+		const char *secondary, GaimRequestType type)
 {
 	GntWidget *window;
 
@@ -24,6 +28,9 @@
 	if (secondary)
 		gnt_box_add_widget(GNT_BOX(window), gnt_label_new(secondary));
 
+	g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gaim_request_close),
+			GINT_TO_POINTER(type));
+
 	return window;
 }
 
@@ -35,7 +42,7 @@
 	const char *text;
 	gpointer callback;
 
-	box = gnt_hbox_new(TRUE);
+	box = gnt_hbox_new(FALSE);
 
 	va_start(list, data);
 
@@ -79,7 +86,7 @@
 {
 	GntWidget *window, *box, *entry;
 
-	window = setup_request_window(title, primary, secondary);
+	window = setup_request_window(title, primary, secondary, GAIM_REQUEST_INPUT);
 
 	entry = gnt_entry_new(default_value);
 	if (masked)
@@ -131,7 +138,7 @@
 	const char *text;
 	int val;
 
-	window = setup_request_window(title, primary, secondary);
+	window = setup_request_window(title, primary, secondary, GAIM_REQUEST_CHOICE);
 
 	combo = gnt_combo_box_new();
 	gnt_box_add_widget(GNT_BOX(window), combo);
@@ -173,7 +180,7 @@
 	GntWidget *window, *box, *button;
 	int i;
 
-	window = setup_request_window(title, primary, secondary);
+	window = setup_request_window(title, primary, secondary, GAIM_REQUEST_ACTION);
 
 	box = gnt_hbox_new(TRUE);
 	gnt_box_add_widget(GNT_BOX(window), box);
@@ -196,12 +203,212 @@
 	return window;
 }
 
+static void
+request_fields_cb(GntWidget *button, GaimRequestFields *fields)
+{
+	GaimRequestFieldsCb callback = g_object_get_data(G_OBJECT(button), "activate-callback");
+	gpointer data = g_object_get_data(G_OBJECT(button), "activate-userdata");
+	GList *list;
+
+	/* Update the data of the fields. GtkGaim does this differently. Instead of
+	 * updating the fields at the end like here, it updates the appropriate field
+	 * instantly whenever a change is made. That allows it to make sure the
+	 * 'required' fields are entered before the user can hit OK. It's not the case
+	 * here, althought it can be done. I am not honouring the 'required' fields
+	 * for the moment. */
+	for (list = gaim_request_fields_get_groups(fields); list; list = list->next)
+	{
+		GaimRequestFieldGroup *group = list->data;
+		GList *fields = gaim_request_field_group_get_fields(group);
+		
+		for (; fields ; fields = fields->next)
+		{
+			GaimRequestField *field = fields->data;
+			GaimRequestFieldType type = gaim_request_field_get_type(field);
+			if (type == GAIM_REQUEST_FIELD_BOOLEAN)
+			{
+				GntWidget *check = field->ui_data;
+				gboolean value = gnt_check_box_get_checked(GNT_CHECK_BOX(check));
+				gaim_request_field_bool_set_value(field, value);
+			}
+			else if (type == GAIM_REQUEST_FIELD_STRING)
+			{
+				GntWidget *entry = field->ui_data;
+				gaim_request_field_string_set_value(field, gnt_entry_get_text(GNT_ENTRY(entry)));
+			}
+			else if (type == GAIM_REQUEST_FIELD_INTEGER)
+			{
+				GntWidget *entry = field->ui_data;
+				const char *text = gnt_entry_get_text(GNT_ENTRY(entry));
+				int value = (text && *text) ? atoi(text) : 0;
+				gaim_request_field_int_set_value(field, value);
+			}
+			else if (type == GAIM_REQUEST_FIELD_CHOICE)
+			{
+				GntWidget *combo = field->ui_data;;
+				int id = GPOINTER_TO_INT(gnt_combo_box_get_selected_data(GNT_COMBO_BOX(combo)));
+				gaim_request_field_choice_set_value(field, id);
+			}
+			else if (type == GAIM_REQUEST_FIELD_LIST)
+			{
+				GntWidget *tree = field->ui_data;
+				gpointer data = gnt_tree_get_selection_data(GNT_TREE(tree));
+				GList *list = g_list_append(NULL, data);   /* XXX: Update when multi-select is allowed */
+				gaim_request_field_list_set_selected(field, list);
+				g_list_free(list);
+			}
+			else if (type == GAIM_REQUEST_FIELD_ACCOUNT)
+			{
+			}
+		}
+	}
+
+	if (callback)
+		callback(data, fields);
+
+	while (button->parent)
+		button = button->parent;
+
+	gaim_request_close(GAIM_REQUEST_FIELDS, button);
+}
+
+static void *
+gg_request_fields(const char *title, const char *primary,
+		const char *secondary, GaimRequestFields *fields,
+		const char *ok, GCallback ok_cb,
+		const char *cancel, GCallback cancel_cb,
+		void *userdata)
+{
+	GntWidget *window, *box;
+	GList *list;
+
+	window = setup_request_window(title, primary, secondary, GAIM_REQUEST_FIELDS);
+
+	/* This is how it's going to work: the request-groups are going to be
+	 * stacked vertically one after the other. A GntLine will be separating
+	 * the groups. */
+	box = gnt_vbox_new(FALSE);
+	gnt_box_set_pad(GNT_BOX(box), 0);
+	gnt_box_set_fill(GNT_BOX(box), TRUE);
+	for (list = gaim_request_fields_get_groups(fields); list; list = list->next)
+	{
+		GaimRequestFieldGroup *group = list->data;
+		GList *fields = gaim_request_field_group_get_fields(group);
+		GntWidget *hbox;
+		
+		/* XXX: Do something with the title, perhaps add a bold label  */
+
+		for (; fields ; fields = fields->next)
+		{
+			GaimRequestField *field = fields->data;
+			GaimRequestFieldType type = gaim_request_field_get_type(field);
+			const char *label = gaim_request_field_get_label(field);
+				
+			hbox = gnt_hbox_new(FALSE);
+			gnt_box_set_pad(GNT_BOX(hbox), 0);
+			gnt_box_add_widget(GNT_BOX(box), hbox);
+			
+			if (type != GAIM_REQUEST_FIELD_BOOLEAN)
+				gnt_box_add_widget(GNT_BOX(hbox), gnt_label_new(label));
+
+			if (type == GAIM_REQUEST_FIELD_BOOLEAN)
+			{
+				GntWidget *check = gnt_check_box_new(label);
+				gnt_check_box_set_checked(GNT_CHECK_BOX(check),
+						gaim_request_field_bool_get_default_value(field));
+				gnt_box_add_widget(GNT_BOX(hbox), check);
+				field->ui_data = check;
+			}
+			else if (type == GAIM_REQUEST_FIELD_STRING)
+			{
+				GntWidget *entry = gnt_entry_new(
+							gaim_request_field_string_get_default_value(field));
+				gnt_entry_set_masked(GNT_ENTRY(entry),
+						gaim_request_field_string_is_masked(field));
+				gnt_box_add_widget(GNT_BOX(hbox), entry);
+				field->ui_data = entry;
+			}
+			else if (type == GAIM_REQUEST_FIELD_INTEGER)
+			{
+				GntWidget *entry = gnt_entry_new(
+							gaim_request_field_string_get_default_value(field));
+				gnt_entry_set_flag(GNT_ENTRY(entry), GNT_ENTRY_FLAG_INT);
+				gnt_box_add_widget(GNT_BOX(hbox), entry);
+				field->ui_data = entry;
+			}
+			else if (type == GAIM_REQUEST_FIELD_CHOICE)
+			{
+				int id;
+				const GList *list;
+				GntWidget *combo = gnt_combo_box_new();
+				gnt_box_add_widget(GNT_BOX(hbox), combo);
+				field->ui_data = combo;
+
+				list = gaim_request_field_choice_get_labels(field);
+				for (id = 1; list; list = list->next, id++)
+				{
+					gnt_combo_box_add_data(GNT_COMBO_BOX(combo),
+							GINT_TO_POINTER(id), list->data);
+				}
+				gnt_combo_box_set_selected(GNT_COMBO_BOX(combo),
+						GINT_TO_POINTER(gaim_request_field_choice_get_default_value(field)));
+			}
+			else if (type == GAIM_REQUEST_FIELD_LIST)
+			{
+				/* XXX: Yet to allow multi-select, because the feature is absent in GntTree */
+				const GList *list;
+				GntWidget *tree = gnt_tree_new();
+				gnt_box_add_widget(GNT_BOX(hbox), tree);
+				field->ui_data = tree;
+
+				list = gaim_request_field_list_get_items(field);
+				for (; list; list = list->next)
+				{
+					const char *text = list->data;
+					gpointer key = gaim_request_field_list_get_data(field, text);
+					gnt_tree_add_row_after(GNT_TREE(tree), key,
+							gnt_tree_create_row(GNT_TREE(tree), text), NULL, NULL);
+					if (gaim_request_field_list_is_selected(field, text))
+						gnt_tree_set_selected(GNT_TREE(tree), key);
+				}
+			}
+#if 0
+			else if (type == GAIM_REQUEST_FIELD_ACCOUNT)
+			{
+				/* XXX: remember to set the field->ui_data */
+			}
+#endif
+			else
+			{
+				gnt_box_add_widget(GNT_BOX(hbox),
+						gnt_label_new_with_format(_("Not implemented yet."),
+							GNT_TEXT_FLAG_BOLD));
+			}
+			if (fields->next)
+				gnt_box_add_widget(GNT_BOX(box), gnt_hline_new());
+		}
+	}
+	gnt_box_add_widget(GNT_BOX(window), box);
+
+	box = setup_button_box(userdata, request_fields_cb, fields,
+			ok, ok_cb, cancel, cancel_cb, NULL);
+	gnt_box_add_widget(GNT_BOX(window), box);
+
+	gnt_widget_show(window);
+	
+	
+	return window;
+}
+
 static GaimRequestUiOps uiops =
 {
 	.request_input = gg_request_input,
 	.close_request = gg_close_request,
 	.request_choice = gg_request_choice,
 	.request_action = gg_request_action,
+	.request_fields = gg_request_fields,
+	.request_file = NULL,                  /* No plans for these */
+	.request_folder = NULL
 };
 
 GaimRequestUiOps *gg_request_get_ui_ops()
--- a/console/libgnt/gntcombobox.c	Sun Aug 06 23:47:34 2006 +0000
+++ b/console/libgnt/gntcombobox.c	Mon Aug 07 02:15:58 2006 +0000
@@ -41,14 +41,12 @@
 	
 	if (box->dropdown)
 	{
-		text = (char *)gnt_tree_get_selection_text(GNT_TREE(box->dropdown));
+		text = gnt_tree_get_selection_text(GNT_TREE(box->dropdown));
 		box->selected = gnt_tree_get_selection_data(GNT_TREE(box->dropdown));
 	}
 
 	if (text == NULL)
-		text = "";
-
-	text = g_strdup(text);
+		text = g_strdup(text);
 
 	if (gnt_widget_has_focus(widget))
 		type = GNT_COLOR_HIGHLIGHT;
@@ -102,6 +100,7 @@
 				case '\t':
 					set_selection(box, gnt_tree_get_selection_data(GNT_TREE(box->dropdown)));
 				case 27:
+					gnt_tree_set_selected(GNT_TREE(box->dropdown), box->selected);
 					gnt_widget_hide(box->dropdown->parent);
 					return TRUE;
 					break;
@@ -118,18 +117,18 @@
 					strcmp(text + 1, GNT_KEY_DOWN) == 0)
 			{
 				GntWidget *parent = box->dropdown->parent;
-				gnt_widget_set_size(box->dropdown, widget->priv.width, 9);
-				gnt_widget_set_position(parent,
-						widget->priv.x, widget->priv.y + widget->priv.height - 1);
+				int height = g_list_length(GNT_TREE(box->dropdown)->list);
+				int y = widget->priv.y + widget->priv.height - 1;
+				gnt_widget_set_size(box->dropdown, widget->priv.width, height + 2);
+
+				if (y + height + 2 >= getmaxy(stdscr))
+					y = widget->priv.y - height - 1;
+				gnt_widget_set_position(parent, widget->priv.x, y);
 				if (parent->window)
 				{
-					if (mvwin(parent->window, widget->priv.y + widget->priv.height - 1,
-								widget->priv.x) == ERR)
-						mvwin(parent->window,
-							widget->priv.y - 9 + 1, widget->priv.x);
+					mvwin(parent->window, y, widget->priv.x);
 				}
 
-				GNT_WIDGET_SET_FLAGS(parent, GNT_WIDGET_TRANSIENT);
 				gnt_widget_draw(parent);
 				return TRUE;
 			}
@@ -192,7 +191,7 @@
 	combo->dropdown = gnt_tree_new();
 
 	box = gnt_box_new(FALSE, FALSE);
-	GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_NO_SHADOW | GNT_WIDGET_NO_BORDER);
+	GNT_WIDGET_SET_FLAGS(box, GNT_WIDGET_NO_SHADOW | GNT_WIDGET_NO_BORDER | GNT_WIDGET_TRANSIENT);
 	gnt_box_set_pad(GNT_BOX(box), 0);
 	gnt_box_add_widget(GNT_BOX(box), combo->dropdown);
 	
--- a/console/libgnt/gnttree.h	Sun Aug 06 23:47:34 2006 +0000
+++ b/console/libgnt/gnttree.h	Mon Aug 07 02:15:58 2006 +0000
@@ -78,6 +78,7 @@
 
 gpointer gnt_tree_get_selection_data(GntTree *tree);
 
+/* Returned string needs to be freed */
 char *gnt_tree_get_selection_text(GntTree *tree);
 
 GList *gnt_tree_get_selection_text_list(GntTree *tree);
--- a/console/libgnt/test/combo.c	Sun Aug 06 23:47:34 2006 +0000
+++ b/console/libgnt/test/combo.c	Mon Aug 07 02:15:58 2006 +0000
@@ -46,6 +46,9 @@
 	gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "4", "4");
 	gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "5", "5");
 	gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "6", "6");
+	gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "7", "7");
+	gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "8", "8");
+	gnt_combo_box_add_data(GNT_COMBO_BOX(combo), "9", "9");
 
 	gnt_box_add_widget(GNT_BOX(hbox), gnt_label_new("Select"));
 	gnt_box_add_widget(GNT_BOX(hbox), combo);