pidgin/gtkthemes.c

changeset 18545
5af898e91ec2
parent 18535
360f2b11f562
child 19859
71d37b57eff2
--- a/pidgin/gtkthemes.c	Sat May 26 13:48:41 2007 +0000
+++ b/pidgin/gtkthemes.c	Sun Jul 01 00:55:03 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,79 @@
 	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, *new_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) {
+				new_theme = ((struct smiley_theme *)(NULL == iter->next ? (smiley_themes == iter ? NULL : smiley_themes->data) : iter->next->data));
+				if (new_theme)
+					purple_prefs_set_string(PIDGIN_PREFS_ROOT "/smileys/theme", new_theme->name);
+				else
+					current_smiley_theme = NULL;
+			}
+			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 +139,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,6 +167,32 @@
 	g_hash_table_destroy(already_freed);
 }
 
+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));
+			pidgin_themes_destroy_smiley_theme(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) {
+		struct smiley_theme *smile = g_slist_last(smiley_themes)->data;
+		pidgin_themes_load_smiley_theme(smile->path, TRUE);
+	}
+}
+
 void pidgin_themes_load_smiley_theme(const char *file, gboolean load)
 {
 	FILE *f = g_fopen(file, "r");
@@ -146,11 +247,14 @@
 				list->next = child;
 			else
 				theme->list = child;
+			/* Reverse the Smiley list since it was built in reverse order for efficiency reasons */
+			if (list != NULL)
+				list->smileys = g_slist_reverse(list->smileys);
 			list = child;
 		} else if (!g_ascii_strncasecmp(i, "Name=", strlen("Name="))) {
 			int len;
 			g_free(theme->name);
-			theme->name = g_strdup(i+ strlen("Name="));
+			theme->name = g_strdup(i + strlen("Name="));
 			len = strlen(theme->name);
 			theme->name[len-1] = 0;
 			if(len > 2 && theme->name[len-2] == '\r')
@@ -201,14 +305,16 @@
 
 			}
 
-			/* Reverse the Smiley list since it was built in reverse order for efficiency reasons */
-			list->smileys = g_slist_reverse(list->smileys);
 
 			if (!have_used_sfile)
 				g_free(sfile);
 		}
 	}
 
+	/* Reverse the Smiley list since it was built in reverse order for efficiency reasons */
+	if (list != NULL)
+		list->smileys = g_slist_reverse(list->smileys);
+
 	g_free(dirname);
 	fclose(f);
 
@@ -216,14 +322,6 @@
 		purple_debug_error("gtkthemes", "Invalid file format, not loading smiley theme from '%s'\n", file);
 
 		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);
-
 		return;
 	}
 
@@ -235,7 +333,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) {
@@ -253,10 +351,12 @@
 {
 	GDir *dir;
 	const gchar *file;
-	gchar *path;
+	gchar *path, *test_path;
 	int l;
+	char* probedirs[3];
 
-	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;
@@ -264,14 +364,18 @@
 		dir = g_dir_open(probedirs[l], 0, NULL);
 		if (dir) {
 			while ((file = g_dir_read_name(dir))) {
-				path = g_build_filename(probedirs[l], file, "theme", NULL);
+				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);
 
-				/* 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);
+					/* 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);
 			}
 			g_dir_close(dir);
 		} else if (l == 1) {
@@ -279,6 +383,11 @@
 		}
 		g_free(probedirs[l]);
 	}
+
+	if (!current_smiley_theme && smiley_themes) {
+		struct smiley_theme *smile = smiley_themes->data;
+		pidgin_themes_load_smiley_theme(smile->path, TRUE);
+	}
 }
 
 GSList *pidgin_themes_get_proto_smileys(const char *id) {
@@ -328,5 +437,4 @@
 		struct smiley_theme *smile = smiley_themes->data;
 		pidgin_themes_load_smiley_theme(smile->path, TRUE);
 	}
-
 }

mercurial