pidgin/prefs/pidginprefs.c

changeset 41154
862153de4f30
parent 41144
910bdda75c74
child 41188
c29d5bd28346
--- a/pidgin/prefs/pidginprefs.c	Thu Oct 28 23:26:57 2021 -0500
+++ b/pidgin/prefs/pidginprefs.c	Thu Oct 28 23:43:20 2021 -0500
@@ -38,13 +38,11 @@
 #include "gtkconv.h"
 #include "gtkdialogs.h"
 #include "gtksavedstatuses.h"
-#include "gtkstatus-icon-theme.h"
 #include "gtkutils.h"
 #include "pidgincore.h"
 #include "pidgindebug.h"
 #include "pidgingdkpixbuf.h"
 #include "pidginprefs.h"
-#include "pidginstock.h"
 #ifdef USE_VV
 #include <gst/video/videooverlay.h>
 #ifdef GDK_WINDOWING_WIN32
@@ -64,12 +62,6 @@
 /* 25MB */
 #define PREFS_MAX_DOWNLOADED_THEME_SIZE 26214400
 
-struct theme_info {
-	gchar *type;
-	gchar *extension;
-	gchar *original_name;
-};
-
 typedef struct _PidginPrefCombo PidginPrefCombo;
 
 typedef void (*PidginPrefsBindDropdownCallback)(GtkComboBox *combo_box,
@@ -176,12 +168,6 @@
 		GtkWidget *startup_label;
 	} away;
 
-	/* Themes page */
-	struct {
-		SoupSession *session;
-		GtkWidget *status;
-	} theme;
-
 #ifdef USE_VV
 	/* Voice/Video page */
 	struct {
@@ -210,12 +196,6 @@
 /* Main dialog */
 static PidginPrefsWindow *prefs = NULL;
 
-/* Themes page */
-static GtkWidget *prefs_status_themes_combo_box;
-
-/* These exist outside the lifetime of the prefs dialog */
-static GtkListStore *prefs_status_icon_themes;
-
 /*
  * PROTOTYPES
  */
@@ -797,505 +777,13 @@
 
 	purple_notify_close_with_handle(prefs);
 
-	g_clear_object(&prefs->theme.session);
-
 	/* Unregister callbacks. */
 	purple_prefs_disconnect_by_handle(prefs);
 
-	/* NULL-ify globals */
-	prefs_status_themes_combo_box = NULL;
-
 	g_free(prefs->proxy.gnome_program_path);
 	prefs = NULL;
 }
 
-static gchar *
-get_theme_markup(const char *name, gboolean custom, const char *author,
-				 const char *description)
-{
-
-	return g_strdup_printf("<b>%s</b>%s%s%s%s\n<span foreground='dim grey'>%s</span>",
-						   name, custom ? " " : "", custom ? _("(Custom)") : "",
-						   author != NULL ? " - " : "", author != NULL ? author : "",
-						   description != NULL ? description : "");
-}
-
-/* adds the themes to the theme list from the manager so they can be displayed in prefs */
-static void
-prefs_themes_sort(PurpleTheme *theme)
-{
-	GdkPixbuf *pixbuf = NULL;
-	GtkTreeIter iter;
-	gchar *image_full = NULL, *markup;
-	const gchar *name, *author, *description;
-
-	if (PIDGIN_IS_STATUS_ICON_THEME(theme)){
-		GtkListStore *store;
-
-		store = prefs_status_icon_themes;
-
-		image_full = purple_theme_get_image_full(theme);
-		if (image_full != NULL){
-			pixbuf = pidgin_pixbuf_new_from_file_at_scale(image_full, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE);
-			g_free(image_full);
-		} else
-			pixbuf = NULL;
-
-		name = purple_theme_get_name(theme);
-		author = purple_theme_get_author(theme);
-		description = purple_theme_get_description(theme);
-
-		markup = get_theme_markup(name, FALSE, author, description);
-
-		gtk_list_store_append(store, &iter);
-		gtk_list_store_set(store, &iter, 0, pixbuf, 1, markup, 2, name, -1);
-
-		g_free(markup);
-		if (pixbuf != NULL)
-			g_object_unref(G_OBJECT(pixbuf));
-
-	}
-}
-
-static void
-prefs_set_active_theme_combo(GtkWidget *combo_box, GtkListStore *store, const gchar *current_theme)
-{
-	GtkTreeIter iter;
-	gchar *theme = NULL;
-	gboolean unset = TRUE;
-
-	if (current_theme && *current_theme && gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter)) {
-		do {
-			gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 2, &theme, -1);
-
-			if (purple_strequal(current_theme, theme)) {
-				gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo_box), &iter);
-				unset = FALSE;
-			}
-
-			g_free(theme);
-		} while (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter));
-	}
-
-	if (unset)
-		gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), 0);
-}
-
-static void
-prefs_themes_refresh(void)
-{
-	GdkPixbuf *pixbuf = NULL;
-	gchar *tmp;
-	GtkTreeIter iter;
-
-	/* refresh the list of themes in the manager */
-	purple_theme_manager_refresh();
-
-	tmp = g_build_filename(PURPLE_DATADIR, "icons", "hicolor", "32x32",
-		"apps", "im.pidgin.Pidgin3.png", NULL);
-	pixbuf = pidgin_pixbuf_new_from_file_at_scale(tmp, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE);
-	g_free(tmp);
-
-	/* status icon themes */
-	gtk_list_store_clear(prefs_status_icon_themes);
-	gtk_list_store_append(prefs_status_icon_themes, &iter);
-	tmp = get_theme_markup(_("Default"), FALSE, _("Penguin Pimps"),
-		_("The default Pidgin status icon theme"));
-	gtk_list_store_set(prefs_status_icon_themes, &iter, 0, pixbuf, 1, tmp, 2, "", -1);
-	g_free(tmp);
-	if (pixbuf)
-		g_object_unref(G_OBJECT(pixbuf));
-
-	purple_theme_manager_for_each_theme(prefs_themes_sort);
-
-	/* set active */
-	prefs_set_active_theme_combo(prefs_status_themes_combo_box, prefs_status_icon_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/status/icon-theme"));
-}
-
-/* init all the theme variables so that the themes can be sorted later and used by pref pages */
-static void
-prefs_themes_init(void)
-{
-	prefs_status_icon_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
-}
-
-/*
- * prefs_theme_find_theme:
- * @path: A directory containing a theme.  The theme could be at the
- *        top level of this directory or in any subdirectory thereof.
- * @type: The type of theme to load.  The loader for this theme type
- *        will be used and this loader will determine what constitutes a
- *        "theme."
- *
- * Attempt to load the given directory as a theme.  If we are unable to
- * open the path as a theme then we recurse into path and attempt to
- * load each subdirectory that we encounter.
- *
- * Returns: A new reference to a #PurpleTheme.
- */
-static PurpleTheme *
-prefs_theme_find_theme(const gchar *path, const gchar *type)
-{
-	PurpleTheme *theme = purple_theme_manager_load_theme(path, type);
-	GDir *dir = g_dir_open(path, 0, NULL);
-	const gchar *next;
-
-	while (!PURPLE_IS_THEME(theme) && (next = g_dir_read_name(dir))) {
-		gchar *next_path = g_build_filename(path, next, NULL);
-
-		if (g_file_test(next_path, G_FILE_TEST_IS_DIR))
-			theme = prefs_theme_find_theme(next_path, type);
-
-		g_free(next_path);
-	}
-
-	g_dir_close(dir);
-
-	return theme;
-}
-
-/* Eww. Seriously ewww. But thanks, grim! This is taken from guifications2 */
-static gboolean
-purple_theme_file_copy(const gchar *source, const gchar *destination)
-{
-	FILE *src, *dest;
-	gint chr = EOF;
-
-	if(!(src = g_fopen(source, "rb")))
-		return FALSE;
-	if(!(dest = g_fopen(destination, "wb"))) {
-		fclose(src);
-		return FALSE;
-	}
-
-	while((chr = fgetc(src)) != EOF) {
-		fputc(chr, dest);
-	}
-
-	fclose(dest);
-	fclose(src);
-
-	return TRUE;
-}
-
-static void
-free_theme_info(struct theme_info *info)
-{
-	if (info != NULL) {
-		g_free(info->type);
-		g_free(info->extension);
-		g_free(info->original_name);
-		g_free(info);
-	}
-}
-
-/* installs a theme, info is freed by function */
-static void
-theme_install_theme(char *path, struct theme_info *info)
-{
-	gchar *destdir;
-	const char *tail;
-	gboolean is_archive;
-	PurpleTheme *theme = NULL;
-
-	if (info == NULL)
-		return;
-
-	/* check the extension */
-	tail = info->extension ? info->extension : strrchr(path, '.');
-
-	if (!tail) {
-		free_theme_info(info);
-		return;
-	}
-
-	is_archive = !g_ascii_strcasecmp(tail, ".gz") || !g_ascii_strcasecmp(tail, ".tgz");
-
-	/* Just to be safe */
-	g_strchomp(path);
-
-	destdir = g_build_filename(purple_data_dir(), "themes", "temp", NULL);
-
-	/* We'll check this just to make sure. This also lets us do something different on
-	 * other platforms, if need be */
-	if (is_archive) {
-#ifndef _WIN32
-		gchar *path_escaped = g_shell_quote(path);
-		gchar *destdir_escaped = g_shell_quote(destdir);
-		gchar *command;
-
-		if (!g_file_test(destdir, G_FILE_TEST_IS_DIR)) {
-			g_mkdir_with_parents(destdir, S_IRUSR | S_IWUSR | S_IXUSR);
-		}
-
-		command = g_strdup_printf("tar > /dev/null xzf %s -C %s", path_escaped, destdir_escaped);
-		g_free(path_escaped);
-		g_free(destdir_escaped);
-
-		/* Fire! */
-		if (system(command)) {
-			purple_notify_error(NULL, NULL, _("Theme failed to unpack."), NULL, NULL);
-			g_free(command);
-			g_free(destdir);
-			free_theme_info(info);
-			return;
-		}
-		g_free(command);
-#else
-		if (!winpidgin_gz_untar(path, destdir)) {
-			purple_notify_error(NULL, NULL, _("Theme failed to unpack."), NULL, NULL);
-			g_free(destdir);
-			free_theme_info(info);
-			return;
-		}
-#endif
-	}
-
-	if (is_archive) {
-		theme = prefs_theme_find_theme(destdir, info->type);
-
-		if (PURPLE_IS_THEME(theme)) {
-			/* create the location for the theme */
-			gchar *theme_dest = g_build_filename(purple_data_dir(), "themes",
-			                                     purple_theme_get_name(theme),
-			                                     "purple", info->type, NULL);
-
-			if (!g_file_test(theme_dest, G_FILE_TEST_IS_DIR)) {
-				g_mkdir_with_parents(theme_dest, S_IRUSR | S_IWUSR | S_IXUSR);
-			}
-
-			g_free(theme_dest);
-			theme_dest = g_build_filename(purple_data_dir(), "themes",
-			                              purple_theme_get_name(theme),
-			                              "purple", info->type, NULL);
-
-			/* move the entire directory to new location */
-			if (g_rename(purple_theme_get_dir(theme), theme_dest)) {
-				purple_debug_error("gtkprefs", "Error renaming %s to %s: "
-						"%s\n", purple_theme_get_dir(theme), theme_dest,
-						g_strerror(errno));
-			}
-
-			g_free(theme_dest);
-			if (g_remove(destdir) != 0) {
-				purple_debug_error("gtkprefs",
-					"couldn't remove temp (dest) path\n");
-			}
-			g_object_unref(theme);
-
-			prefs_themes_refresh();
-
-		} else {
-			/* something was wrong with the theme archive */
-			g_unlink(destdir);
-			purple_notify_error(NULL, NULL, _("Theme failed to load."), NULL, NULL);
-		}
-
-	} else { /* just a single file so copy it to a new temp directory and attempt to load it*/
-		gchar *temp_path, *temp_file;
-
-		temp_path = g_build_filename(purple_data_dir(), "themes", "temp",
-		                             "sub_folder", NULL);
-
-		if (info->original_name != NULL) {
-			/* name was changed from the original (probably a dnd) change it back before loading */
-			temp_file = g_build_filename(temp_path, info->original_name, NULL);
-
-		} else {
-			gchar *source_name = g_path_get_basename(path);
-			temp_file = g_build_filename(temp_path, source_name, NULL);
-			g_free(source_name);
-		}
-
-		if (!g_file_test(temp_path, G_FILE_TEST_IS_DIR)) {
-			g_mkdir_with_parents(temp_path, S_IRUSR | S_IWUSR | S_IXUSR);
-		}
-
-		if (purple_theme_file_copy(path, temp_file)) {
-			/* find the theme, could be in subfolder */
-			theme = prefs_theme_find_theme(temp_path, info->type);
-
-			if (PURPLE_IS_THEME(theme)) {
-				gchar *theme_dest =
-				        g_build_filename(purple_data_dir(), "themes",
-				                         purple_theme_get_name(theme), "purple",
-				                         info->type, NULL);
-
-				if(!g_file_test(theme_dest, G_FILE_TEST_IS_DIR)) {
-					g_mkdir_with_parents(theme_dest, S_IRUSR | S_IWUSR | S_IXUSR);
-				}
-
-				if (g_rename(purple_theme_get_dir(theme), theme_dest)) {
-					purple_debug_error("gtkprefs", "Error renaming %s to %s: "
-							"%s\n", purple_theme_get_dir(theme), theme_dest,
-							g_strerror(errno));
-				}
-
-				g_free(theme_dest);
-				g_object_unref(theme);
-
-				prefs_themes_refresh();
-			} else {
-				if (g_remove(temp_path) != 0) {
-					purple_debug_error("gtkprefs",
-						"couldn't remove temp path");
-				}
-				purple_notify_error(NULL, NULL, _("Theme failed to load."), NULL, NULL);
-			}
-		} else {
-			purple_notify_error(NULL, NULL, _("Theme failed to copy."), NULL, NULL);
-		}
-
-		g_free(temp_file);
-		g_free(temp_path);
-	}
-
-	g_free(destdir);
-	free_theme_info(info);
-}
-
-static void
-theme_got_url(G_GNUC_UNUSED SoupSession *session, SoupMessage *msg,
-              gpointer _info)
-{
-	struct theme_info *info = _info;
-	FILE *f;
-	gchar *path;
-	size_t wc;
-
-	if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code)) {
-		free_theme_info(info);
-		return;
-	}
-
-	f = purple_mkstemp(&path, TRUE);
-	wc = fwrite(msg->response_body->data, msg->response_body->length, 1, f);
-	if (wc != 1) {
-		purple_debug_warning("theme_got_url", "Unable to write theme data.\n");
-		fclose(f);
-		g_unlink(path);
-		g_free(path);
-		free_theme_info(info);
-		return;
-	}
-	fclose(f);
-
-	theme_install_theme(path, info);
-
-	g_unlink(path);
-	g_free(path);
-}
-
-static void
-theme_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
-		GtkSelectionData *sd, guint info, guint t, gpointer user_data)
-{
-	gchar *name = g_strchomp((gchar *)gtk_selection_data_get_data(sd));
-
-	if ((gtk_selection_data_get_length(sd) >= 0)
-	 && (gtk_selection_data_get_format(sd) == 8)) {
-		/* Well, it looks like the drag event was cool.
-		 * Let's do something with it */
-		gchar *temp;
-		struct theme_info *info =  g_new0(struct theme_info, 1);
-		info->type = g_strdup((gchar *)user_data);
-		info->extension = g_strdup(g_strrstr(name,"."));
-		temp = g_strrstr(name, "/");
-		info->original_name = temp ? g_strdup(++temp) : NULL;
-
-		if (!g_ascii_strncasecmp(name, "file://", 7)) {
-			GError *converr = NULL;
-			gchar *tmp;
-			/* It looks like we're dealing with a local file. Let's
-			 * just untar it in the right place */
-			if(!(tmp = g_filename_from_uri(name, NULL, &converr))) {
-				purple_debug_error("theme dnd", "%s",
-				                   converr ? converr->message :
-				                   "g_filename_from_uri error");
-				free_theme_info(info);
-				return;
-			}
-			theme_install_theme(tmp, info);
-			g_free(tmp);
-		} else if (!g_ascii_strncasecmp(name, "http://", 7) ||
-			!g_ascii_strncasecmp(name, "https://", 8)) {
-			/* Oo, a web drag and drop. This is where things
-			 * will start to get interesting */
-			SoupMessage *msg;
-
-			if (prefs->theme.session == NULL) {
-				prefs->theme.session = soup_session_new();
-			}
-
-			soup_session_abort(prefs->theme.session);
-
-			msg = soup_message_new("GET", name);
-			// purple_http_request_set_max_len(msg, PREFS_MAX_DOWNLOADED_THEME_SIZE);
-			soup_session_queue_message(prefs->theme.session, msg, theme_got_url,
-			                           info);
-		} else
-			free_theme_info(info);
-
-		gtk_drag_finish(dc, TRUE, FALSE, t);
-	}
-
-	gtk_drag_finish(dc, FALSE, FALSE, t);
-}
-
-/* builds a theme combo box from a list store with columns: icon preview, markup, theme name */
-static void
-prefs_build_theme_combo_box(GtkWidget *combo_box, GtkListStore *store,
-                            const char *current_theme, const char *type)
-{
-	GtkTargetEntry te[3] = {
-		{"text/plain", 0, 0},
-		{"text/uri-list", 0, 1},
-		{"STRING", 0, 2}
-	};
-
-	g_return_if_fail(store != NULL && current_theme != NULL);
-
-	gtk_combo_box_set_model(GTK_COMBO_BOX(combo_box),
-	                        GTK_TREE_MODEL(store));
-
-	gtk_drag_dest_set(combo_box, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, te,
-					sizeof(te) / sizeof(GtkTargetEntry) , GDK_ACTION_COPY | GDK_ACTION_MOVE);
-
-	g_signal_connect(G_OBJECT(combo_box), "drag_data_received", G_CALLBACK(theme_dnd_recv), (gpointer) type);
-}
-
-/* sets the current icon theme */
-static void
-prefs_set_status_icon_theme_cb(GtkComboBox *combo_box, gpointer user_data)
-{
-	PidginStatusIconTheme *theme = NULL;
-	GtkTreeIter iter;
-	gchar *name = NULL;
-
-	if(gtk_combo_box_get_active_iter(combo_box, &iter)) {
-
-		gtk_tree_model_get(GTK_TREE_MODEL(prefs_status_icon_themes), &iter, 2, &name, -1);
-
-		if(!name || *name)
-			theme = PIDGIN_STATUS_ICON_THEME(purple_theme_manager_find_theme(name, "status-icon"));
-
-		g_free(name);
-
-		pidgin_stock_load_status_icon_theme(theme);
-		pidgin_blist_refresh(purple_blist_get_default());
-	}
-}
-
-static void
-bind_theme_page(PidginPrefsWindow *win)
-{
-	/* Status Icon Themes */
-	prefs_build_theme_combo_box(win->theme.status, prefs_status_icon_themes,
-	                            PIDGIN_PREFS_ROOT "/status/icon-theme",
-	                            "icon");
-	prefs_status_themes_combo_box = win->theme.status;
-}
-
 static void
 formatting_toggle_cb(TalkatuActionGroup *ag, GAction *action, const gchar *name, gpointer data)
 {
@@ -2270,7 +1758,6 @@
 	bind_network_page(win);
 	bind_proxy_page(win);
 	bind_away_page(win);
-	bind_theme_page(win);
 #ifdef USE_VV
 	vv = vv_page(win);
 	gtk_container_add_with_properties(GTK_CONTAINER(stack), vv, "name",
@@ -2452,12 +1939,6 @@
 			widget_class, PidginPrefsWindow, away.startup_hbox);
 	gtk_widget_class_bind_template_child(
 			widget_class, PidginPrefsWindow, away.startup_label);
-
-	/* Themes page */
-	gtk_widget_class_bind_template_child(
-			widget_class, PidginPrefsWindow, theme.status);
-	gtk_widget_class_bind_template_callback(widget_class,
-			prefs_set_status_icon_theme_cb);
 }
 
 static void
@@ -2473,9 +1954,6 @@
 	gtk_widget_init_template(GTK_WIDGET(win));
 
 	prefs_stack_init(win);
-
-	/* Refresh the list of themes before showing the preferences window */
-	prefs_themes_refresh();
 }
 
 void
@@ -2505,9 +1983,6 @@
 	purple_prefs_add_path(PIDGIN_PREFS_ROOT "/filelocations/last_open_folder", "");
 	purple_prefs_add_path(PIDGIN_PREFS_ROOT "/filelocations/last_icon_folder", "");
 
-	/* Themes */
-	prefs_themes_init();
-
 #ifdef USE_VV
 	/* Voice/Video */
 	purple_prefs_add_none(PIDGIN_PREFS_ROOT "/vvconfig");

mercurial