changeset 17776:cf6b7aeae062

Need help reflecting selected smiley theme after remove
author Gabriel Schulhof <nix@go-nix.ca>
date Fri, 01 Jun 2007 21:22:46 +0000
parents fcf61e3be189
children 7055885b1b70 693990fbbf48
files pidgin/gtkprefs.c pidgin/gtkthemes.c pidgin/gtkthemes.h
diffstat 3 files changed, 131 insertions(+), 151 deletions(-) [+]
line wrap: on
line diff
--- a/pidgin/gtkprefs.c	Wed May 30 21:05:04 2007 +0000
+++ b/pidgin/gtkprefs.c	Fri Jun 01 21:22:46 2007 +0000
@@ -60,7 +60,7 @@
 
 static GtkWidget *sound_entry = NULL;
 static GtkListStore *smiley_theme_store = NULL;
-static GtkWidget *smiley_theme_tree_view = NULL;
+static GtkTreeSelection *smiley_theme_sel = NULL;
 static GtkWidget *prefs_proxy_frame = NULL;
 
 static GtkWidget *prefs = NULL;
@@ -369,23 +369,19 @@
 	struct smiley_theme *new_theme, *old_theme;
 	GtkWidget *remove_button = g_object_get_data(G_OBJECT(sel), "remove_button");
 
-	if (!gtk_tree_selection_get_selected(sel, &model, &iter))
+	if (!gtk_tree_selection_get_selected(sel, &model, &iter)) {
+		gtk_widget_set_sensitive(remove_button, FALSE);
 		return;
+	}
 
 	old_theme = current_smiley_theme;
 	val.g_type = 0;
 	gtk_tree_model_get_value(model, &iter, 3, &val);
 	path = gtk_tree_model_get_path(model, &iter);
 	themename = g_value_get_string(&val);
+	purple_prefs_set_string(PIDGIN_PREFS_ROOT "/smileys/theme", themename);
 
-	/*
-	 * Disallow removal of the "none" theme - note that there's a double check, so even if
-	 * the button is not disabled here, the "none" theme still won't be removed when its clicked.
-	 */
-	if (remove_button)
-		gtk_widget_set_sensitive(remove_button, strcmp(themename, "none"));
-
-	purple_prefs_set_string(PIDGIN_PREFS_ROOT "/smileys/theme", themename);
+	gtk_widget_set_sensitive(remove_button, strcmp(themename, "none"));
 	g_value_unset (&val);
 
 	/* current_smiley_theme is set in callback for the above pref change */
@@ -523,18 +519,12 @@
 #endif
 	g_free(destdir);
 
-	if ((theme_rowref = theme_refresh_theme_list()) != NULL) {
-		GtkTreeIter itr;
-		GtkTreePath *tp = NULL;
-		GtkTreeSelection *sel = NULL;
+	theme_rowref = theme_refresh_theme_list();
+	if (theme_rowref != NULL) {
+		GtkTreePath *tp = gtk_tree_row_reference_get_path(theme_rowref);
 
-		if ((sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(smiley_theme_tree_view))) != NULL) {
-			if ((tp = gtk_tree_row_reference_get_path(theme_rowref)) != NULL) {
-				if (gtk_tree_model_get_iter(GTK_TREE_MODEL(smiley_theme_store), &itr, tp))
-					gtk_tree_selection_select_iter(sel, &itr);
-				gtk_tree_path_free(tp);
-			}
-		}
+		if(tp)
+			gtk_tree_selection_select_path(smiley_theme_sel, tp);
 		gtk_tree_row_reference_free(theme_rowref);
 	}
 }
@@ -640,90 +630,59 @@
 	return ret;
 }
 
-static void request_theme_file_name_cb (gpointer data, char *theme_file_name)
+static void
+request_theme_file_name_cb (gpointer data, char *theme_file_name)
 {
 	theme_install_theme (theme_file_name, NULL) ;
 }
 
 static void
-add_theme_button_clicked_cb(GtkWidget *button, gpointer null)
+add_theme_button_clicked_cb (GtkWidget *widget, gpointer null)
 {
-	purple_request_file (NULL, _("Install Theme"), NULL, FALSE, (GCallback)request_theme_file_name_cb, NULL, NULL, NULL, NULL, NULL) ;
+	purple_request_file (NULL, "Install Theme", NULL, FALSE, (GCallback)request_theme_file_name_cb, NULL, NULL, NULL, NULL, NULL) ;
 }
 
 static void
-remove_theme_button_clicked_cb(GtkWidget *button, GtkTreeView *tree_view)
+remove_theme_button_clicked_cb(GtkWidget *button, GtkTreeView *tv)
 {
-	static GtkTreeModel *tm = NULL;
-	static GtkTreeSelection *sel = NULL;
-	static GtkTreeIter itr;
-	static char *theme_path = NULL, *theme_name = NULL, *slash_before_filename = NULL;
-
-	if ((tm = gtk_tree_view_get_model(tree_view)) == NULL) return;
-	if ((sel = gtk_tree_view_get_selection(tree_view)) == NULL) return;
-	if (!gtk_tree_selection_get_selected(sel, NULL, &itr)) return;
-
-	gtk_tree_model_get(tm, &itr, 2, &theme_path, 3, &theme_name, -1);
-
-	if (theme_name) {
-		if (strcmp(theme_name, "none")) {
-			if(theme_path) {
-				if ((slash_before_filename = g_strrstr(theme_path, G_DIR_SEPARATOR_S)) != NULL) {
-					GtkTreeRowReference *theme_rowref;
-					char *dir_file = NULL;
-					GDir *theme_dir = NULL;
+	char *theme_name = NULL, *theme_file = NULL;
+	GtkTreeModel *tm;
+	GtkTreeIter itr;
+	GtkTreeRowReference *trr = NULL;
 
-					*slash_before_filename = 0;
-					if ((theme_dir = g_dir_open(theme_path, 0, NULL)) != NULL) {
-						while((dir_file = (char *)g_dir_read_name(theme_dir)) != NULL) {
-							if ((dir_file = g_strdup_printf ("%s%s%s", theme_path, G_DIR_SEPARATOR_S, dir_file)) != NULL) {
-								g_unlink(dir_file);
-								g_free(dir_file);
-							}
-						}
-
-					g_dir_close(theme_dir);
-					g_rmdir(theme_path);
+	if ((tm = gtk_tree_view_get_model(tv)) == NULL) return;
+	if (!gtk_tree_selection_get_selected(smiley_theme_sel, NULL, &itr)) return;
+	gtk_tree_model_get(tm, &itr, 2, &theme_file, 3, &theme_name, -1);
 
-					/*
-					 * Currently theme_refresh_theme_list() is rigged to remove all smiley themes which have disappeared from disk.
-					 * This is fine, but for the next minor version we should add a
-					 * pidgin_themes_remove_smiley_theme(struct smiley_theme *theme) to gtkthemes.[ch] which will remove an 
-					 * individual theme from the list.
-					 */
-					if (previous_smiley_row)
-						gtk_tree_row_reference_free(previous_smiley_row);
-					previous_smiley_row = NULL;
-					if ((theme_rowref = theme_refresh_theme_list()) != NULL) {
-						GtkTreePath *tp = NULL;
-
-						if ((tp = gtk_tree_row_reference_get_path(theme_rowref)) != NULL) {
-							if (gtk_tree_model_get_iter(tm, &itr, tp))
-								gtk_tree_selection_select_iter(sel, &itr);
-							gtk_tree_path_free(tp);
-						}
-						gtk_tree_row_reference_free(theme_rowref);
-					}
-
-					}
-				}
-			}
+	if(theme_name && strcmp(theme_name, "none")) {
+		if (theme_file) {
+			pidgin_themes_remove_smiley_theme(theme_file);
 		}
 	}
 
+	if ((trr = theme_refresh_theme_list()) != NULL) {
+		GtkTreePath *tp = gtk_tree_row_reference_get_path(trr);
+
+		if (tp) {
+			gtk_tree_selection_select_path(smiley_theme_sel, tp);
+			gtk_tree_path_free(tp);
+		}
+		gtk_tree_row_reference_free(trr);
+	}
+
+	g_free(theme_file);
 	g_free(theme_name);
-	g_free(theme_path);
 }
 
 static GtkWidget *
 theme_page()
 {
+	GtkWidget *add_button, *remove_button;
 	GtkWidget *hbox_buttons;
 	GtkWidget *alignment;
 	GtkWidget *ret;
 	GtkWidget *sw;
 	GtkWidget *view;
-	GtkWidget *add_button, *remove_button;
 	GtkCellRenderer *rend;
 	GtkTreeViewColumn *col;
 	GtkTreeSelection *sel;
@@ -734,7 +693,7 @@
 	ret = gtk_vbox_new(FALSE, PIDGIN_HIG_CAT_SPACE);
 	gtk_container_set_border_width (GTK_CONTAINER (ret), PIDGIN_HIG_BORDER);
 
-	label = gtk_label_new(_("Select a smiley theme that you would like to use from the list below."));
+	label = gtk_label_new(_("Select a smiley theme that you would like to use from the list below. New themes can be installed by dragging and dropping them onto the theme list."));
 
 	gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
 	gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
@@ -752,7 +711,7 @@
 
 	rowref = theme_refresh_theme_list();
 
-	view = smiley_theme_tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL(smiley_theme_store));
+	view = gtk_tree_view_new_with_model (GTK_TREE_MODEL(smiley_theme_store));
 
 	gtk_drag_dest_set(view, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, te,
 					sizeof(te) / sizeof(GtkTargetEntry) , GDK_ACTION_COPY | GDK_ACTION_MOVE);
@@ -760,7 +719,7 @@
 	g_signal_connect(G_OBJECT(view), "drag_data_received", G_CALLBACK(theme_dnd_recv), smiley_theme_store);
 
 	rend = gtk_cell_renderer_pixbuf_new();
-	sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
+	smiley_theme_sel = sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
 
 	/* Custom sort so "none" theme is at top of list */
 	gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(smiley_theme_store),
@@ -786,13 +745,6 @@
 
 	g_signal_connect(G_OBJECT(sel), "changed", G_CALLBACK(smiley_sel), NULL);
 
-	if (rowref) {
-		GtkTreePath *path = gtk_tree_row_reference_get_path(rowref);
-		gtk_tree_row_reference_free(rowref);
-		gtk_tree_selection_select_path(sel, path);
-		gtk_tree_path_free(path);
-	}
-
 	alignment = gtk_alignment_new(1.0, 0.5, 0.0, 1.0);
 	gtk_widget_show(alignment);
 	gtk_box_pack_start(GTK_BOX(ret), alignment, FALSE, TRUE, 0);
@@ -804,22 +756,25 @@
 	add_button = gtk_button_new_from_stock(GTK_STOCK_ADD);
 	gtk_widget_show(add_button);
 	gtk_box_pack_start(GTK_BOX(hbox_buttons), add_button, FALSE, TRUE, 0);
-	g_signal_connect(G_OBJECT(add_button), "clicked", (GCallback)add_theme_button_clicked_cb, NULL);
+	g_signal_connect(G_OBJECT(add_button), "clicked", (GCallback)add_theme_button_clicked_cb, view);
 
 	remove_button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
 	gtk_widget_show(remove_button);
 	gtk_box_pack_start(GTK_BOX(hbox_buttons), remove_button, FALSE, TRUE, 0);
 	g_signal_connect(G_OBJECT(remove_button), "clicked", (GCallback)remove_theme_button_clicked_cb, view);
+	g_object_set_data(G_OBJECT(sel), "remove_button", remove_button);
 
-	g_object_set_data(G_OBJECT(sel), "remove_button", remove_button);
+	if (rowref) {
+		GtkTreePath *path = gtk_tree_row_reference_get_path(rowref);
+		gtk_tree_row_reference_free(rowref);
+		gtk_tree_selection_select_path(sel, path);
+		gtk_tree_path_free(path);
+	}
 
 	gtk_widget_show_all(ret);
 
 	pidgin_set_accessible_label (view, label);
 
-	/* Handle initial selection */
-	smiley_sel(sel, GTK_TREE_MODEL(smiley_theme_store));
-
 	return ret;
 }
 
--- a/pidgin/gtkthemes.c	Wed May 30 21:05:04 2007 +0000
+++ b/pidgin/gtkthemes.c	Fri Jun 01 21:22:46 2007 +0000
@@ -36,6 +36,8 @@
 GSList *smiley_themes = NULL;
 struct smiley_theme *current_smiley_theme;
 
+static void pidgin_themes_destroy_smiley_theme_smileys(struct smiley_theme *theme);
+
 gboolean pidgin_themes_smileys_disabled()
 {
 	if (!current_smiley_theme)
@@ -44,6 +46,73 @@
 	return strcmp(current_smiley_theme->name, "none") == 0;
 }
 
+static void
+pidgin_themes_destroy_smiley_theme(struct smiley_theme *theme) {
+			pidgin_themes_destroy_smiley_theme_smileys(theme);
+
+			g_free(theme->name);
+			g_free(theme->desc);
+			g_free(theme->author);
+			g_free(theme->icon);
+			g_free(theme->path);
+			g_free(theme);
+}
+
+static void pidgin_themes_remove_theme_dir(const char *theme_dir_name)
+{
+	GString *str = NULL;
+	const char *file_name = NULL;
+	GDir *theme_dir = NULL;
+
+	if ((theme_dir = g_dir_open(theme_dir_name, 0, NULL)) != NULL) {
+		if ((str = g_string_new(theme_dir_name)) != NULL) {
+			while ((file_name = g_dir_read_name(theme_dir)) != NULL) {
+				g_string_printf(str, "%s%s%s", theme_dir_name, G_DIR_SEPARATOR_S, file_name);
+				g_unlink(str->str);
+			}
+			g_string_free(str, TRUE);
+		}
+		g_dir_close(theme_dir);
+		g_rmdir(theme_dir_name);
+	}
+}
+
+void pidgin_themes_remove_smiley_theme(const char *file)
+{
+	char *theme_dir = NULL, *last_slash = NULL;
+	g_return_if_fail(NULL != file);
+	
+	if (!g_file_test(file, G_FILE_TEST_EXISTS)) return;
+	if ((theme_dir = g_strdup(file)) == NULL) return ;
+
+	if ((last_slash = g_strrstr(theme_dir, G_DIR_SEPARATOR_S)) != NULL) {
+		GSList *iter = NULL;
+		struct smiley_theme *theme = NULL;
+
+		*last_slash = 0;
+
+		/* Delete files on disk */
+		pidgin_themes_remove_theme_dir(theme_dir);
+
+		/* Find theme in themes list and remove it */
+		for (iter = smiley_themes ; iter ; iter = iter->next) {
+			theme = ((struct smiley_theme *)(iter->data));
+			if (!strcmp(theme->path, file))
+				break ;
+		}
+		if (iter) {
+			if (theme == current_smiley_theme)
+				current_smiley_theme = ((struct smiley_theme *)(NULL == iter->next ? (smiley_themes == iter ? NULL : smiley_themes->data) : iter->next->data));
+			smiley_themes = g_slist_delete_link(smiley_themes, iter);
+
+			/* Destroy theme structure */
+			pidgin_themes_destroy_smiley_theme(theme);
+		}
+	}
+
+	g_free(theme_dir);
+}
+
 void pidgin_themes_smiley_themeize(GtkWidget *imhtml)
 {
 	struct smiley_list *list;
@@ -64,7 +133,7 @@
 }
 
 static void
-pidgin_themes_destroy_smiley_theme(struct smiley_theme *theme)
+pidgin_themes_destroy_smiley_theme_smileys(struct smiley_theme *theme)
 {
 	GHashTable *already_freed;
 	struct smiley_list *wer;
@@ -92,42 +161,6 @@
 	g_hash_table_destroy(already_freed);
 }
 
-static void smiley_theme_free(struct smiley_theme *theme)
-{
-	pidgin_themes_destroy_smiley_theme(theme);
-
-	g_free(theme->name);
-	g_free(theme->desc);
-	g_free(theme->author);
-	g_free(theme->icon);
-	g_free(theme->path);
-	g_free(theme);
-}
-
-static void
-pidgin_smiley_themes_remove_non_existing()
-{
-	static struct smiley_theme *theme = NULL;
-	GSList *iter = NULL;
-
-	if (!smiley_themes) return ;
-
-	for (iter = smiley_themes ; iter ; iter = iter->next) {
-		theme = ((struct smiley_theme *)(iter->data));
-		if (!g_file_test(theme->path, G_FILE_TEST_EXISTS)) {
-			if (theme == current_smiley_theme)
-				current_smiley_theme = ((struct smiley_theme *)(NULL == iter->next ? NULL : iter->next->data));
-			smiley_theme_free(theme);
-			iter->data = NULL;
-		}
-	}
-	/* Remove all elements whose data is NULL */
-	smiley_themes = g_slist_remove_all(smiley_themes, NULL);
-
-	if (!current_smiley_theme && smiley_themes)
-		current_smiley_theme = ((struct smiley_theme *)(g_slist_last(smiley_themes)->data));
-}
-
 void pidgin_themes_load_smiley_theme(const char *file, gboolean load)
 {
 	FILE *f = g_fopen(file, "r");
@@ -251,7 +284,7 @@
 	if (!theme->name || !theme->desc || !theme->author) {
 		purple_debug_error("gtkthemes", "Invalid file format, not loading smiley theme from '%s'\n", file);
 
-		smiley_theme_free(theme);
+		pidgin_themes_destroy_smiley_theme(theme);
 
 		return;
 	}
@@ -264,7 +297,7 @@
 		GList *cnv;
 
 		if (current_smiley_theme)
-			pidgin_themes_destroy_smiley_theme(current_smiley_theme);
+			pidgin_themes_destroy_smiley_theme_smileys(current_smiley_theme);
 		current_smiley_theme = theme;
 
 		for (cnv = purple_get_conversations(); cnv != NULL; cnv = cnv->next) {
@@ -282,12 +315,10 @@
 {
 	GDir *dir;
 	const gchar *file;
-	gchar *path, *test_path;
+	gchar *path;
 	int l;
+
 	char* probedirs[3];
-
-	pidgin_smiley_themes_remove_non_existing();
-
 	probedirs[0] = g_build_filename(DATADIR, "pixmaps", "pidgin", "emotes", NULL);
 	probedirs[1] = g_build_filename(purple_user_dir(), "smileys", NULL);
 	probedirs[2] = 0;
@@ -295,18 +326,14 @@
 		dir = g_dir_open(probedirs[l], 0, NULL);
 		if (dir) {
 			while ((file = g_dir_read_name(dir))) {
-				test_path = g_build_filename(probedirs[l], file, NULL);
-				if (g_file_test(test_path, G_FILE_TEST_IS_DIR)) {
-					path = g_build_filename(probedirs[l], file, "theme", NULL);
+				path = g_build_filename(probedirs[l], file, "theme", NULL);
 
-					/* Here we check to see that the theme has proper syntax.
-					 * We set the second argument to FALSE so that it doesn't load
-					 * the theme yet.
-					 */
-					pidgin_themes_load_smiley_theme(path, FALSE);
-					g_free(path);
-				}
-				g_free(test_path);
+				/* Here we check to see that the theme has proper syntax.
+				 * We set the second argument to FALSE so that it doesn't load
+				 * the theme yet.
+				 */
+				pidgin_themes_load_smiley_theme(path, FALSE);
+				g_free(path);
 			}
 			g_dir_close(dir);
 		} else if (l == 1) {
@@ -314,9 +341,6 @@
 		}
 		g_free(probedirs[l]);
 	}
-
-	if (!current_smiley_theme && smiley_themes)
-		current_smiley_theme = ((struct smiley_theme *)(smiley_themes->data));
 }
 
 GSList *pidgin_themes_get_proto_smileys(const char *id) {
--- a/pidgin/gtkthemes.h	Wed May 30 21:05:04 2007 +0000
+++ b/pidgin/gtkthemes.h	Fri Jun 01 21:22:46 2007 +0000
@@ -49,5 +49,6 @@
 void pidgin_themes_smiley_themeize(GtkWidget *);
 void pidgin_themes_smiley_theme_probe(void);
 void pidgin_themes_load_smiley_theme(const char *file, gboolean load);
+void pidgin_themes_remove_smiley_theme(const char *file);
 GSList *pidgin_themes_get_proto_smileys(const char *id);
 #endif /* _PIDGINDIALOGS_H_ */