changeset 32571:1ad958b14c63

Replace GtkOptionMenu with a GtkComboBox in the preferences dropdowns for GTK+ 2.4 and up.
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Fri, 10 Apr 2009 04:55:52 +0000
parents d1f097ee5030
children c40a3b9c90af
files pidgin/gtkprefs.c
diffstat 1 files changed, 132 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/pidgin/gtkprefs.c	Thu Apr 09 04:21:12 2009 +0000
+++ b/pidgin/gtkprefs.c	Fri Apr 10 04:55:52 2009 +0000
@@ -164,14 +164,52 @@
 	return pidgin_add_widget_to_vbox(GTK_BOX(page), title, sg, entry, TRUE, NULL);
 }
 
+/* TODO: Maybe move this up somewheres... */
+enum {
+	PREF_DROPDOWN_TEXT,
+	PREF_DROPDOWN_VALUE,
+	PREF_DROPDOWN_COUNT
+};
 
 static void
 dropdown_set(GObject *w, const char *key)
 {
 	const char *str_value;
 	int int_value;
+	gboolean bool_value;
 	PurplePrefType type;
 
+#if GTK_CHECK_VERSION(2,4,0)
+	GtkTreeIter iter;
+	GtkTreeModel *tree_model;
+
+	tree_model = gtk_combo_box_get_model(GTK_COMBO_BOX(w));
+	gtk_combo_box_get_active_iter(GTK_COMBO_BOX(w), &iter);
+
+	type = GPOINTER_TO_INT(g_object_get_data(w, "type"));
+
+	if (type == PURPLE_PREF_INT) {
+		gtk_tree_model_get(tree_model, &iter,
+		                   PREF_DROPDOWN_VALUE, &int_value,
+		                   -1);
+
+		purple_prefs_set_int(key, int_value);
+	}
+	else if (type == PURPLE_PREF_STRING) {
+		gtk_tree_model_get(tree_model, &iter,
+		                   PREF_DROPDOWN_VALUE, &str_value,
+		                   -1);
+
+		purple_prefs_set_string(key, str_value);
+	}
+	else if (type == PURPLE_PREF_BOOLEAN) {
+		gtk_tree_model_get(tree_model, &iter,
+		                   PREF_DROPDOWN_VALUE, &bool_value,
+		                   -1);
+
+		purple_prefs_set_bool(key, bool_value);
+	}
+#else
 	type = GPOINTER_TO_INT(g_object_get_data(w, "type"));
 
 	if (type == PURPLE_PREF_INT) {
@@ -185,64 +223,129 @@
 		purple_prefs_set_string(key, str_value);
 	}
 	else if (type == PURPLE_PREF_BOOLEAN) {
-		purple_prefs_set_bool(key,
-				GPOINTER_TO_INT(g_object_get_data(w, "value")));
+		bool_value = (gboolean)GPOINTER_TO_INT(g_object_get_data(w, "value"));
+		purple_prefs_set_bool(key, bool_value);
 	}
+#endif
 }
 
 GtkWidget *
 pidgin_prefs_dropdown_from_list(GtkWidget *box, const gchar *title,
 		PurplePrefType type, const char *key, GList *menuitems)
 {
-	GtkWidget  *dropdown, *opt, *menu;
+	GtkWidget  *dropdown;
 	GtkWidget  *label = NULL;
 	gchar      *text;
 	const char *stored_str = NULL;
 	int         stored_int = 0;
+	gboolean    stored_bool = FALSE;
 	int         int_value  = 0;
 	const char *str_value  = NULL;
+	gboolean    bool_value = FALSE;
+#if GTK_CHECK_VERSION(2,4,0)
+	GtkListStore *store;
+	GtkTreeIter iter;
+	GtkTreeIter active;
+	GtkCellRenderer *renderer;
+
+	g_return_val_if_fail(menuitems != NULL, NULL);
+
+	if (type == PURPLE_PREF_INT) {
+		store = gtk_list_store_new(PREF_DROPDOWN_COUNT, G_TYPE_STRING, G_TYPE_INT);
+		stored_int = purple_prefs_get_int(key);
+	} else if (type == PURPLE_PREF_STRING) {
+		store = gtk_list_store_new(PREF_DROPDOWN_COUNT, G_TYPE_STRING, G_TYPE_STRING);
+		stored_str = purple_prefs_get_string(key);
+	} else if (type == PURPLE_PREF_BOOLEAN) {
+		store = gtk_list_store_new(PREF_DROPDOWN_COUNT, G_TYPE_STRING, G_TYPE_BOOLEAN);
+		stored_bool = purple_prefs_get_bool(key);
+	}
+
+	dropdown = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
+	g_object_set_data(G_OBJECT(dropdown), "type", GINT_TO_POINTER(type));
+
+	while (menuitems != NULL && (text = (char *)menuitems->data) != NULL) {
+		menuitems = g_list_next(menuitems);
+		g_return_val_if_fail(menuitems != NULL, NULL);
+
+		gtk_list_store_append(store, &iter);
+		gtk_list_store_set(store, &iter,
+		                   PREF_DROPDOWN_TEXT, text,
+		                   -1);
+
+		if (type == PURPLE_PREF_INT) {
+			int_value = GPOINTER_TO_INT(menuitems->data);
+			gtk_list_store_set(store, &iter,
+			                   PREF_DROPDOWN_VALUE, int_value,
+			                   -1);
+		}
+		else if (type == PURPLE_PREF_STRING) {
+			str_value = (const char *)menuitems->data;
+			gtk_list_store_set(store, &iter,
+			                   PREF_DROPDOWN_VALUE, str_value,
+			                   -1);
+		}
+		else if (type == PURPLE_PREF_BOOLEAN) {
+			bool_value = (gboolean)GPOINTER_TO_INT(menuitems->data);
+			gtk_list_store_set(store, &iter,
+			                   PREF_DROPDOWN_VALUE, bool_value,
+			                   -1);
+		}
+
+		if ((type == PURPLE_PREF_INT && stored_int == int_value) ||
+			(type == PURPLE_PREF_STRING && stored_str != NULL &&
+			 !strcmp(stored_str, str_value)) ||
+			(type == PURPLE_PREF_BOOLEAN &&
+			 (stored_bool == bool_value))) {
+
+			active = iter;
+		}
+
+		menuitems = g_list_next(menuitems);
+	}
+
+	renderer = gtk_cell_renderer_text_new();
+	gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(dropdown), renderer, TRUE);
+	gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(dropdown), renderer,
+	                               "text", 0,
+	                               NULL);
+
+	gtk_combo_box_set_active_iter(GTK_COMBO_BOX(dropdown), &active);
+
+	g_signal_connect(G_OBJECT(dropdown), "changed",
+	                 G_CALLBACK(dropdown_set), (char *)key);
+
+#else
+	GtkWidget  *opt, *menu;
 	int         o = 0;
 
 	g_return_val_if_fail(menuitems != NULL, NULL);
 
-#if 0 /* GTK_CHECK_VERSION(2,4,0) */
-	if(type == PURPLE_PREF_INT)
-		model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT);
-	else if(type == PURPLE_PREF_STRING)
-		model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
-	dropdown = gtk_combo_box_new_with_model(model);
-#else
 	dropdown = gtk_option_menu_new();
 	menu = gtk_menu_new();
-#endif
 
 	if (type == PURPLE_PREF_INT)
 		stored_int = purple_prefs_get_int(key);
 	else if (type == PURPLE_PREF_STRING)
 		stored_str = purple_prefs_get_string(key);
-
-	while (menuitems != NULL && (text = (char *) menuitems->data) != NULL) {
+	else if (type == PURPLE_PREF_BOOLEAN)
+		stored_bool = purple_prefs_get_bool(key);
+
+	while (menuitems != NULL && (text = (char *)menuitems->data) != NULL) {
 		menuitems = g_list_next(menuitems);
 		g_return_val_if_fail(menuitems != NULL, NULL);
 
 		opt = gtk_menu_item_new_with_label(text);
 
 		g_object_set_data(G_OBJECT(opt), "type", GINT_TO_POINTER(type));
-
-		if (type == PURPLE_PREF_INT) {
+		g_object_set_data(G_OBJECT(opt), "value", menuitems->data);
+
+		if (type == PURPLE_PREF_INT)
 			int_value = GPOINTER_TO_INT(menuitems->data);
-			g_object_set_data(G_OBJECT(opt), "value",
-							  GINT_TO_POINTER(int_value));
-		}
-		else if (type == PURPLE_PREF_STRING) {
+		else if (type == PURPLE_PREF_STRING)
 			str_value = (const char *)menuitems->data;
-
-			g_object_set_data(G_OBJECT(opt), "value", (char *)str_value);
-		}
-		else if (type == PURPLE_PREF_BOOLEAN) {
-			g_object_set_data(G_OBJECT(opt), "value",
-					menuitems->data);
-		}
+		else if (type == PURPLE_PREF_BOOLEAN)
+			bool_value = (gboolean)GPOINTER_TO_INT(menuitems->data);
 
 		g_signal_connect(G_OBJECT(opt), "activate",
 						 G_CALLBACK(dropdown_set), (char *)key);
@@ -254,7 +357,7 @@
 			(type == PURPLE_PREF_STRING && stored_str != NULL &&
 			 !strcmp(stored_str, str_value)) ||
 			(type == PURPLE_PREF_BOOLEAN &&
-			 (purple_prefs_get_bool(key) == GPOINTER_TO_INT(menuitems->data)))) {
+			 (stored_bool == bool_value))) {
 
 			gtk_menu_set_active(GTK_MENU(menu), o);
 		}
@@ -266,6 +369,8 @@
 
 	gtk_option_menu_set_menu(GTK_OPTION_MENU(dropdown), menu);
 
+#endif
+
 	pidgin_add_widget_to_vbox(GTK_BOX(box), title, NULL, dropdown, FALSE, &label);
 
 	return label;