diff options
Diffstat (limited to 'capplets/theme-switcher/gnome-theme-manager.c')
-rw-r--r-- | capplets/theme-switcher/gnome-theme-manager.c | 1494 |
1 files changed, 0 insertions, 1494 deletions
diff --git a/capplets/theme-switcher/gnome-theme-manager.c b/capplets/theme-switcher/gnome-theme-manager.c deleted file mode 100644 index 5a747cfa1..000000000 --- a/capplets/theme-switcher/gnome-theme-manager.c +++ /dev/null @@ -1,1494 +0,0 @@ -/* This program was written under the GPL by Jonathan Blandford <jrb@gnome.org> - */ - -#include <config.h> - -#include <string.h> -#include <gconf/gconf-client.h> -#include <glade/glade.h> -#include <libgnomevfs/gnome-vfs-async-ops.h> -#include <libgnomevfs/gnome-vfs-ops.h> -#include <libgnomevfs/gnome-vfs-utils.h> - -#include <libwindow-settings/gnome-wm-manager.h> - -#include "gnome-theme-info.h" -#include "gnome-theme-save.h" -#include "capplet-util.h" -#include "activate-settings-daemon.h" -#include "gconf-property-editor.h" -#include "file-transfer-dialog.h" -#include "gnome-theme-manager.h" -#include "gnome-theme-details.h" -#include "gnome-theme-installer.h" -#include <theme-thumbnail.h> -#include <gnome-theme-apply.h> - - -#define MAX_ELEMENTS_BEFORE_SCROLLING 3 - -/* Events: There are two types of change events we worry about. The first is - * when the theme settings change. In this case, we can quickly update the UI - * to reflect. The other is when the themes themselves change. - * - * The code in gnome-theme-manager.c will update the main dialog and proxy the - * update notifications for the details dialog. - */ - -enum -{ - META_THEME_NAME_COLUMN = THEME_NAME_COLUMN, - META_THEME_ID_COLUMN = THEME_ID_COLUMN, - META_THEME_FLAG_COLUMN = THEME_FLAG_COLUMN, - META_THEME_PIXBUF_COLUMN, - META_N_COLUMNS -}; - -GtkTargetEntry drop_types[] = -{ - {"text/uri-list", 0, TARGET_URI_LIST}, - {"_NETSCAPE_URL", 0, TARGET_NS_URL} -}; - -gint n_drop_types = sizeof (drop_types) / sizeof (GtkTargetEntry); - -static gboolean setting_model = FALSE; -static guint update_settings_from_gconf_idle_id = 0; -static guint theme_changed_idle_id = 0; -static guint pixbuf_idle_id = 0; -static gboolean loading_themes; -static gboolean reload_themes; -static gboolean initial_meta_theme_set = FALSE; -static GdkPixbuf *default_image = NULL; -static GdkPixbuf *broken_image = NULL; -static gboolean themes_loaded = FALSE; -static gboolean reverted = FALSE; - -static GnomeThemeMetaInfo custom_meta_theme_info; -static GnomeThemeMetaInfo initial_meta_theme_info; - -const char *meta_theme_default_name = NULL; -const char *gtk_theme_default_name = NULL; -const char *window_theme_default_name = NULL; -const char *icon_theme_default_name = NULL; - - -/* Function Prototypes */ -static void add_pixbuf_idle (void); -static void load_meta_themes (GtkTreeView *tree_view, - GList *meta_theme_list); -static void meta_theme_setup_info (GnomeThemeMetaInfo *meta_theme_info, - GladeXML *dialog); -static void meta_theme_selection_changed (GtkTreeSelection *selection, - GladeXML *dialog); -static void update_themes_from_disk (GladeXML *dialog); -static void update_settings_from_gconf (void); -static void gtk_theme_key_changed (GConfClient *client, - guint cnxn_id, - GConfEntry *entry, - gpointer user_data); -static void window_settings_changed (GnomeWindowManager *window_manager, - GladeXML *dialog); -static void icon_key_changed (GConfClient *client, - guint cnxn_id, - GConfEntry *entry, - gpointer user_data); -static void font_key_changed (GConfClient *client, - guint cnxn_id, - GConfEntry *entry, - gpointer user_data); -static void theme_changed_func (gpointer uri, - gpointer user_data); -static void cb_dialog_response (GtkDialog *dialog, - gint response_id); -static void setup_meta_tree_view (GtkTreeView *tree_view, - GCallback changed_callback, - GladeXML *dialog); -static void setup_dialog (GladeXML *dialog); - - -typedef struct { - gchar *theme_id; - GtkTreeModel *model; - gboolean cancelled; -} PixbufAsyncData; - -static void -pixbuf_async_func (GdkPixbuf *pixbuf, - gpointer data) -{ - PixbufAsyncData *pixbuf_async_data = data; - gchar *theme_id; - GtkTreeModel *model; - GtkTreeIter iter; - gboolean valid; - - theme_id = pixbuf_async_data->theme_id; - model = pixbuf_async_data->model; - - for (valid = gtk_tree_model_get_iter_first (model, &iter); - valid; - valid = gtk_tree_model_iter_next (model, &iter)) - { - gchar *test_theme_id; - gtk_tree_model_get (model, &iter, - META_THEME_ID_COLUMN, &test_theme_id, - -1); - if (theme_id && test_theme_id && !strcmp (theme_id, test_theme_id)) - { - gtk_list_store_set (GTK_LIST_STORE (model), &iter, - META_THEME_PIXBUF_COLUMN, pixbuf ? pixbuf : broken_image, - -1); - g_free (test_theme_id); - break; - } - g_free (test_theme_id); - } - - add_pixbuf_idle (); -} - -static void -pixbuf_async_data_free (gpointer data) -{ - PixbufAsyncData *pixbuf_async_data = data; - - g_object_unref (pixbuf_async_data->model); - g_free (pixbuf_async_data->theme_id); - g_free (pixbuf_async_data); -} - -static gboolean -pixbuf_idle_func (gpointer data) -{ - GladeXML *dialog; - GtkWidget *tree_view; - GtkTreeModel *model; - GtkTreeIter iter; - gboolean valid; - - pixbuf_idle_id = 0; - - if (reload_themes) { - GladeXML *dialog; - - reload_themes = FALSE; - loading_themes = FALSE; - - dialog = gnome_theme_manager_get_theme_dialog (); - update_themes_from_disk (dialog); - return FALSE; - } - - dialog = gnome_theme_manager_get_theme_dialog (); - tree_view = WID ("meta_theme_treeview"); - model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view)); - - for (valid = gtk_tree_model_get_iter_first (model, &iter); - valid; - valid = gtk_tree_model_iter_next (model, &iter)) - { - GdkPixbuf *pixbuf = NULL; - gchar *theme_id = NULL; - - gtk_tree_model_get (model, &iter, - META_THEME_PIXBUF_COLUMN, &pixbuf, - -1); - if (pixbuf == default_image) - { - PixbufAsyncData *pixbuf_async_data; - GnomeThemeMetaInfo *meta_theme_info; - - gtk_tree_model_get (model, &iter, - META_THEME_ID_COLUMN, &theme_id, - -1); - if (theme_id == NULL) - { - meta_theme_info = &custom_meta_theme_info; - } - else - { - meta_theme_info = gnome_theme_meta_info_find (theme_id); - } - - /* We should always have a metatheme file */ - g_assert (meta_theme_info); - - pixbuf_async_data = g_new (PixbufAsyncData, 1); - pixbuf_async_data->theme_id = theme_id; - pixbuf_async_data->model = model; - pixbuf_async_data->cancelled = FALSE; - g_object_ref (model); - generate_theme_thumbnail_async (meta_theme_info, - pixbuf_async_func, - pixbuf_async_data, - pixbuf_async_data_free); - - return FALSE; - } - } - - /* If we're done loading all the main themes, lets initialize the details - * dialog if it hasn't been done yet. If it has, then this call is harmless. - */ - gnome_theme_details_init (); - loading_themes = FALSE; - - if (reload_themes) { - GladeXML *dialog; - - reload_themes = FALSE; - loading_themes = FALSE; - - dialog = gnome_theme_manager_get_theme_dialog (); - update_themes_from_disk (dialog); - } - - return FALSE; -} - -/* FIXME: we need a way to cancel the pixbuf loading if we get a theme updating - * during the pixbuf generation. - */ -static void -add_pixbuf_idle (void) -{ - if (pixbuf_idle_id) - return; - - pixbuf_idle_id = g_idle_add_full (G_PRIORITY_LOW, - pixbuf_idle_func, - NULL, NULL); -} - -static gint -sort_meta_theme_list_func (gconstpointer a, - gconstpointer b) -{ - const GnomeThemeMetaInfo *a_meta_theme_info = a; - const GnomeThemeMetaInfo *b_meta_theme_info = b; - guint a_flag = 0; - guint b_flag = 0; - - g_assert (a_meta_theme_info->name); - g_assert (b_meta_theme_info->name); - - if (meta_theme_default_name && strcmp (meta_theme_default_name, a_meta_theme_info->name) == 0) - a_flag |= THEME_FLAG_DEFAULT; - if (meta_theme_default_name && strcmp (meta_theme_default_name, b_meta_theme_info->name) == 0) - b_flag |= THEME_FLAG_DEFAULT; - - return gnome_theme_manager_sort_func (a_meta_theme_info->readable_name, - b_meta_theme_info->readable_name, - a_flag, - b_flag); -} - - -/* Loads up a list of GnomeThemeMetaInfo. - */ -static void -load_meta_themes (GtkTreeView *tree_view, - GList *meta_theme_list) -{ - GList *list; - GtkTreeModel *model; - GtkWidget *swindow; - GtkTreeIter iter; - gchar *name; - gboolean valid; - guint flag; - gint i = 0; - GConfClient *client; - gchar *current_gtk_theme; - gchar *current_window_theme; - gchar *current_icon_theme; - GnomeWindowManager *window_manager; - GnomeWMSettings wm_settings; - static gboolean first_time = TRUE; - - swindow = GTK_WIDGET (tree_view)->parent; - model = gtk_tree_view_get_model (tree_view); - g_assert (model); - - setting_model = TRUE; - - client = gconf_client_get_default (); - - current_gtk_theme = gconf_client_get_string (client, GTK_THEME_KEY, NULL); - current_icon_theme = gconf_client_get_string (client, ICON_THEME_KEY, NULL); - g_object_unref (client); - - window_manager = gnome_wm_manager_get_current (gdk_display_get_default_screen (gdk_display_get_default ())); - wm_settings.flags = GNOME_WM_SETTING_THEME; - - if (window_manager) - { - gnome_window_manager_get_settings (window_manager, &wm_settings); - current_window_theme = g_strdup (wm_settings.theme); - } - else - current_window_theme = g_strdup (window_theme_default_name); - - /* FIXME: What do we really do when there is no theme? */ - if (current_icon_theme == NULL) - current_icon_theme = g_strdup (icon_theme_default_name); - if (current_gtk_theme == NULL) - current_gtk_theme = g_strdup (gtk_theme_default_name); - - /* handle first time */ - if (first_time) - { - for (list = meta_theme_list; list; list = list->next) - { - GnomeThemeMetaInfo *theme_info = list->data; - - if ((theme_info->gtk_theme_name && !strcmp (theme_info->gtk_theme_name, gtk_theme_default_name)) && - (theme_info->metacity_theme_name && !strcmp (theme_info->metacity_theme_name, window_theme_default_name)) && - (theme_info->icon_theme_name && !strcmp (theme_info->icon_theme_name, icon_theme_default_name))) - { - meta_theme_default_name = g_strdup (theme_info->name); - break; - } - } - } - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow), - GTK_POLICY_NEVER, GTK_POLICY_NEVER); - gtk_widget_set_usize (swindow, -1, -1); - - /* Sort meta_theme_list to be in the same order of the current data. This way - * we can walk through them together. */ - meta_theme_list = g_list_sort (meta_theme_list, sort_meta_theme_list_func); - list = meta_theme_list; - valid = gtk_tree_model_get_iter_first (model, &iter); - - while (valid || list != NULL) - { - GnomeThemeMetaInfo *list_meta_theme_info = NULL; - GnomeThemeMetaInfo *model_meta_theme_info = NULL; - gchar *blurb; - gboolean list_is_default = FALSE; - GdkPixbuf *pixbuf = NULL; - gboolean delete_it = FALSE; - gboolean set_it = FALSE; - GtkTreeIter iter_to_set; - - /* Check info on the list */ - if (list) - { - list_meta_theme_info = list->data; - if (meta_theme_default_name && strcmp (meta_theme_default_name, list_meta_theme_info->name) == 0) - list_is_default = TRUE; - else - list_is_default = FALSE; - } - - if (valid) - { - gtk_tree_model_get (model, &iter, - META_THEME_ID_COLUMN, &name, - META_THEME_FLAG_COLUMN, &flag, - -1); - if (name) - { - model_meta_theme_info = gnome_theme_meta_info_find (name); - g_free (name); - - /* The theme was removed, and we haven't removed it from the list yet. */ - if (model_meta_theme_info == NULL) - { - delete_it = TRUE; - goto end_of_loop; - } - } - } - - /* start comparing values */ - if (list && valid) - { - gint compare_val; - - if (flag & THEME_FLAG_CUSTOM) - { - /* We can always skip the custom row, as it's never in the list */ - valid = gtk_tree_model_iter_next (model, &iter); - i++; - goto end_of_loop; - } - - compare_val = gnome_theme_manager_sort_func (model_meta_theme_info->readable_name, list_meta_theme_info->readable_name, - flag, list_is_default ? THEME_FLAG_DEFAULT : 0); - - if (compare_val < 0) - { - delete_it = TRUE; - goto end_of_loop; - } - else if (compare_val == 0) - { - set_it = TRUE; - iter_to_set = iter; - valid = gtk_tree_model_iter_next (model, &iter); - } - else - { - /* we insert a new item */ - set_it = TRUE; - gtk_list_store_insert_before (GTK_LIST_STORE (model), &iter_to_set, &iter); - } - } - else if (list) - { - /* we append a new item */ - set_it = TRUE; - gtk_list_store_append (GTK_LIST_STORE (model), &iter_to_set); - } - else if (valid) - { - /* It's a dead item. */ - delete_it = TRUE; - } - - end_of_loop: - if (delete_it) - { - GtkTreeIter iter_to_remove; - iter_to_remove = iter; - valid = gtk_tree_model_iter_next (model, &iter); - gtk_list_store_remove (GTK_LIST_STORE (model), &iter_to_remove); - } - if (set_it) - { - /* We reset the blurb in case it has changed */ - blurb = g_markup_printf_escaped ("<span size=\"larger\" weight=\"bold\">%s</span>\n%s", - list_meta_theme_info->readable_name, list_meta_theme_info->comment); - - if (i <= MAX_ELEMENTS_BEFORE_SCROLLING) { - pixbuf = generate_theme_thumbnail (list_meta_theme_info, FALSE); - if (pixbuf == NULL) - pixbuf = broken_image; - } else { - pixbuf = default_image; - } - - gtk_list_store_set (GTK_LIST_STORE (model), &iter_to_set, - META_THEME_PIXBUF_COLUMN, pixbuf, - META_THEME_NAME_COLUMN, blurb, - META_THEME_ID_COLUMN, list_meta_theme_info->name, - META_THEME_FLAG_COLUMN, list_is_default ? THEME_FLAG_DEFAULT : 0, - -1); - g_free (blurb); - - list = list->next; - i++; - } - if (i == MAX_ELEMENTS_BEFORE_SCROLLING) - { - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - } - } - - add_pixbuf_idle (); - - g_free (current_gtk_theme); - g_free (current_icon_theme); - g_free (current_window_theme); - first_time = FALSE; - setting_model = FALSE; -} - -static void -meta_theme_setup_info (GnomeThemeMetaInfo *meta_theme_info, - GladeXML *dialog) -{ - GtkWidget *notebook; - - notebook = WID ("meta_theme_notebook"); - - if (meta_theme_info == NULL) - { - gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 0); - } - else - { - if (meta_theme_info->application_font != NULL) - { - if (meta_theme_info->background_image != NULL) - gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 3); - else - gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 1); - } - else - { - if (meta_theme_info->background_image != NULL) - gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 2); - else - gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 0); - } - } -} - -static void -meta_theme_selection_changed (GtkTreeSelection *selection, - GladeXML *dialog) -{ - GnomeThemeMetaInfo *meta_theme_info; - GtkTreeIter iter; - gchar *meta_theme_name; - GtkTreeModel *model; - gchar *current_gtk_theme; - gchar *current_window_theme; - gchar *current_icon_theme; - GConfClient *client; - GnomeWindowManager *window_manager; - GnomeWMSettings wm_settings; - - if (gtk_tree_selection_get_selected (selection, &model, &iter)) - { - gtk_tree_model_get (model, &iter, - META_THEME_ID_COLUMN, &meta_theme_name, - -1); - } - else - { - /* I probably just added a row. */ - return; - } - - if (meta_theme_name) - { - meta_theme_info = gnome_theme_meta_info_find (meta_theme_name); - g_free (meta_theme_name); - } - else - { - meta_theme_info = &custom_meta_theme_info; - } - meta_theme_setup_info (meta_theme_info, dialog); - - if (setting_model) - return; - - if (meta_theme_info) - gnome_meta_theme_set (meta_theme_info); - - if (!themes_loaded) { - client = gconf_client_get_default (); - - /* Get the settings */ - current_gtk_theme = gconf_client_get_string (client, GTK_THEME_KEY, NULL); - current_icon_theme = gconf_client_get_string (client, ICON_THEME_KEY, NULL); - g_object_unref (client); - - window_manager = gnome_wm_manager_get_current (gdk_display_get_default_screen (gdk_display_get_default ())); - wm_settings.flags = GNOME_WM_SETTING_THEME; - if (window_manager) { - gnome_window_manager_get_settings (window_manager, &wm_settings); - current_window_theme = g_strdup (wm_settings.theme); - } else - current_window_theme = g_strdup (""); - - initial_meta_theme_info.name = g_strdup ("__Initial Theme__"); - initial_meta_theme_info.gtk_theme_name = g_strdup (current_gtk_theme); - initial_meta_theme_info.metacity_theme_name = g_strdup (current_window_theme); - initial_meta_theme_info.icon_theme_name = g_strdup (current_icon_theme); - themes_loaded = TRUE; - } else { - if (!reverted) { - gtk_widget_set_sensitive(WID("meta_theme_revert_button"),TRUE); - } else { - reverted = FALSE; - } - } -} - -/* This function will adjust the list to reflect the current theme - * situation. It is called after the themes change on disk. Currently, it - * recreates the entire list. - */ -static void -update_themes_from_disk (GladeXML *dialog) -{ - GList *theme_list; - - if (loading_themes) { - reload_themes = TRUE; - return; - } - - loading_themes = TRUE; - - theme_list = gnome_theme_meta_info_find_all (); - gtk_widget_show (WID ("meta_theme_hbox")); - load_meta_themes (GTK_TREE_VIEW (WID ("meta_theme_treeview")), theme_list); - g_list_free (theme_list); - - update_settings_from_gconf (); -} - -static void -add_custom_row_to_meta_theme (const gchar *current_gtk_theme, - const gchar *current_window_theme, - const gchar *current_icon_theme, - gboolean select) -{ - GladeXML *dialog; - GtkWidget *tree_view; - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter iter; - gboolean valid; - gchar *blurb; - GdkPixbuf *pixbuf; - - dialog = gnome_theme_manager_get_theme_dialog (); - tree_view = WID ("meta_theme_treeview"); - model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view)); - - g_free (custom_meta_theme_info.gtk_theme_name); - custom_meta_theme_info.gtk_theme_name = g_strdup (current_gtk_theme); - g_free (custom_meta_theme_info.metacity_theme_name); - custom_meta_theme_info.metacity_theme_name = g_strdup (current_window_theme); - g_free (custom_meta_theme_info.icon_theme_name); - custom_meta_theme_info.icon_theme_name = g_strdup (current_icon_theme); - g_free (custom_meta_theme_info.name); - custom_meta_theme_info.name = g_strdup ("__Custom Theme__"); - - for (valid = gtk_tree_model_get_iter_first (model, &iter); - valid; - valid = gtk_tree_model_iter_next (model, &iter)) - { - guint theme_flags = 0; - - gtk_tree_model_get (model, &iter, - META_THEME_FLAG_COLUMN, &theme_flags, - -1); - if (theme_flags & THEME_FLAG_CUSTOM) - break; - - } - - /* if we found a custom row and broke out of the list above, valid will be - * TRUE. If we didn't, we need to add a new iter. - */ - if (!valid) - gtk_list_store_prepend (GTK_LIST_STORE (model), &iter); - - /* set the values of the Custom theme. */ - blurb = g_markup_printf_escaped ("<span size=\"larger\" weight=\"bold\">%s</span>\n%s", - _("Custom theme"), _("You can save this theme by pressing the Save Theme button.")); - - /* Invalidate the cache because the custom theme has potentially changed */ - /* Commented out because it does odd things */ - /*theme_thumbnail_invalidate_cache (&custom_meta_theme_info);*/ - - pixbuf = generate_theme_thumbnail (&custom_meta_theme_info, TRUE); - if (pixbuf == NULL) - pixbuf = default_image; - gtk_list_store_set (GTK_LIST_STORE (model), &iter, - META_THEME_PIXBUF_COLUMN, pixbuf, - META_THEME_NAME_COLUMN, blurb, - META_THEME_FLAG_COLUMN, THEME_FLAG_CUSTOM, - -1); - - gtk_widget_set_sensitive (WID ("meta_theme_save_button"), TRUE); - path = gtk_tree_model_get_path (model, &iter); - if (select) - gtk_tree_view_set_cursor (GTK_TREE_VIEW (tree_view), path, NULL, FALSE); - gtk_tree_path_free (path); - g_free (blurb); -} - -static void -remove_custom_row_from_meta_theme (void) -{ - GladeXML *dialog; - GtkWidget *tree_view; - GtkTreeModel *model; - GtkTreeIter iter; - GtkTreeIter next_iter; - gboolean valid; - - dialog = gnome_theme_manager_get_theme_dialog (); - tree_view = WID ("meta_theme_treeview"); - model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view)); - - valid = gtk_tree_model_get_iter_first (model, &iter); - while (valid) - { - guint theme_flags = 0; - - next_iter = iter; - valid = gtk_tree_model_iter_next (model, &next_iter); - - gtk_tree_model_get (model, &iter, - META_THEME_FLAG_COLUMN, &theme_flags, - -1); - - if (theme_flags & THEME_FLAG_CUSTOM) - { - gtk_list_store_remove (GTK_LIST_STORE (model), &iter); - } - iter = next_iter; - } - g_free (custom_meta_theme_info.gtk_theme_name); - g_free (custom_meta_theme_info.metacity_theme_name); - g_free (custom_meta_theme_info.icon_theme_name); - g_free (custom_meta_theme_info.name); - - gtk_widget_set_sensitive (WID ("meta_theme_save_button"), FALSE); - - custom_meta_theme_info.gtk_theme_name = NULL; - custom_meta_theme_info.metacity_theme_name = NULL; - custom_meta_theme_info.icon_theme_name = NULL; - custom_meta_theme_info.name = NULL; -} - -gboolean -themes_equal (GnomeThemeMetaInfo *a, GnomeThemeMetaInfo *b) -{ - if (!a->gtk_theme_name || - !b->gtk_theme_name || - strcmp (a->gtk_theme_name, b->gtk_theme_name)) - return FALSE; - if (!a->metacity_theme_name || - !b->metacity_theme_name || - strcmp (a->metacity_theme_name, b->metacity_theme_name)) - return FALSE; - if (!a->icon_theme_name || - !b->icon_theme_name || - strcmp (a->icon_theme_name, b->icon_theme_name)) - return FALSE; - return TRUE; -} - - -/* Sets the list to point to the current theme. Also creates the 'Custom Theme' - * field if needed */ -static gboolean -update_settings_from_gconf_idle (gpointer data) -{ - GConfClient *client; - gchar *current_gtk_theme; - gchar *current_window_theme; - gchar *current_icon_theme; - GnomeWindowManager *window_manager; - GnomeWMSettings wm_settings; - GtkWidget *tree_view; - GtkTreeModel *model; - GtkTreeIter iter; - GladeXML *dialog; - gboolean valid; - gboolean current_theme_saved; - gboolean initial_theme_saved; - static gboolean first_time_run = TRUE; - - client = gconf_client_get_default (); - - /* Get the settings */ - current_gtk_theme = gconf_client_get_string (client, GTK_THEME_KEY, NULL); - current_icon_theme = gconf_client_get_string (client, ICON_THEME_KEY, NULL); - g_object_unref (client); - - window_manager = gnome_wm_manager_get_current (gdk_display_get_default_screen (gdk_display_get_default ())); - wm_settings.flags = GNOME_WM_SETTING_THEME; - if (window_manager) { - gnome_window_manager_get_settings (window_manager, &wm_settings); - current_window_theme = g_strdup (wm_settings.theme); - } else - current_window_theme = g_strdup (""); - - /* True if the current or initial theme has a meta theme that it matches. */ - current_theme_saved = FALSE; - initial_theme_saved = FALSE; - - /* Walk the tree looking for the current one. */ - dialog = gnome_theme_manager_get_theme_dialog (); - tree_view = WID ("meta_theme_treeview"); - g_assert (tree_view); - model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view)); - - for (valid = gtk_tree_model_get_iter_first (model, &iter); - valid; - valid = gtk_tree_model_iter_next (model, &iter)) - { - gchar *row_theme_id = NULL; - guint row_theme_flags = 0; - GnomeThemeMetaInfo *meta_theme_info; - - gtk_tree_model_get (model, &iter, - META_THEME_ID_COLUMN, &row_theme_id, - META_THEME_FLAG_COLUMN, &row_theme_flags, - -1); - - if (row_theme_id) { - meta_theme_info = gnome_theme_meta_info_find (row_theme_id); - } - else { - continue; - } - g_free (row_theme_id); - if (row_theme_flags & THEME_FLAG_CUSTOM) { - continue; - } - - if (initial_meta_theme_set && themes_equal (&initial_meta_theme_info, meta_theme_info)) - initial_theme_saved = TRUE; - if (! strcmp (current_gtk_theme, meta_theme_info->gtk_theme_name) && - (window_manager == NULL || - ! strcmp (current_window_theme, meta_theme_info->metacity_theme_name)) && - ! strcmp (current_icon_theme, meta_theme_info->icon_theme_name)) - { - GtkTreePath *path; - GtkTreePath *cursor_path; - gboolean cursor_same = FALSE; - - gtk_tree_view_get_cursor (GTK_TREE_VIEW (tree_view), &cursor_path, NULL); - path = gtk_tree_model_get_path (model, &iter); - if (cursor_path && gtk_tree_path_compare (path, cursor_path) == 0) - cursor_same = TRUE; - - gtk_tree_path_free (cursor_path); - - if (!cursor_same) - { - gtk_tree_view_set_cursor (GTK_TREE_VIEW (tree_view), path, NULL, FALSE); - } - gtk_tree_path_free (path); - current_theme_saved = TRUE; - - break; - } - } - - if (!current_theme_saved && first_time_run) - { - initial_meta_theme_set = TRUE; - initial_meta_theme_info.name = g_strdup ("__Initial Theme__"); - initial_meta_theme_info.gtk_theme_name = g_strdup (current_gtk_theme); - initial_meta_theme_info.metacity_theme_name = g_strdup (current_window_theme); - initial_meta_theme_info.icon_theme_name = g_strdup (current_icon_theme); - } - first_time_run = FALSE; - - - if (!current_theme_saved) - { - add_custom_row_to_meta_theme (current_gtk_theme, - current_window_theme, - current_icon_theme, - TRUE); - } - else if (initial_meta_theme_set && !initial_theme_saved) - { - add_custom_row_to_meta_theme (initial_meta_theme_info.gtk_theme_name, - initial_meta_theme_info.metacity_theme_name, - initial_meta_theme_info.icon_theme_name, - FALSE); - } - else - { - remove_custom_row_from_meta_theme (); - } - g_free (current_gtk_theme); - g_free (current_window_theme); - g_free (current_icon_theme); - update_settings_from_gconf_idle_id = 0; - return FALSE; -} - -void -update_settings_from_gconf (void) -{ - if (update_settings_from_gconf_idle_id != 0) - return; - update_settings_from_gconf_idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, - update_settings_from_gconf_idle, - NULL, NULL); -} - -static void -gtk_theme_key_changed (GConfClient *client, - guint cnxn_id, - GConfEntry *entry, - gpointer user_data) -{ - if (strcmp (entry->key, GTK_THEME_KEY)) - return; - - update_settings_from_gconf (); - gnome_theme_details_update_from_gconf (); -} - -static void -window_settings_changed (GnomeWindowManager *window_manager, - GladeXML *dialog) -{ - static gchar *window_theme = NULL; - GnomeWMSettings wm_settings; - - wm_settings.flags = GNOME_WM_SETTING_THEME; - gnome_window_manager_get_settings (window_manager, &wm_settings); - if (window_theme == NULL || strcmp (wm_settings.theme, window_theme) != 0) - { - g_free (window_theme); - window_theme = g_strdup (wm_settings.theme); - } - else - return; - - update_settings_from_gconf (); - gnome_theme_details_update_from_gconf (); -} - -static void -update_font_button_state (GladeXML *dialog) -{ - GConfClient *client = gconf_client_get_default (); - GtkTreeSelection *selection; - GtkTreeModel *model; - GtkTreeIter iter; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (WID ("meta_theme_treeview"))); - - if (gtk_tree_selection_get_selected (selection, &model, &iter)) - { - GnomeThemeMetaInfo *meta_theme_info; - char *meta_theme_name, *str; - - gtk_tree_model_get (model, &iter, - META_THEME_ID_COLUMN, &meta_theme_name, - -1); - if (!meta_theme_name) - return; - - meta_theme_info = gnome_theme_meta_info_find (meta_theme_name); - - g_assert (meta_theme_info); - g_free (meta_theme_name); - - str = gconf_client_get_string (client, FONT_KEY, NULL); - - if (meta_theme_info->application_font != NULL && str != NULL && - strcmp (meta_theme_info->application_font, str) == 0) - { - gtk_widget_set_sensitive (WID ("meta_theme_font1_button"), FALSE); - gtk_widget_set_sensitive (WID ("meta_theme_font2_button"), FALSE); - } - else - { - gtk_widget_set_sensitive (WID ("meta_theme_font1_button"), TRUE); - gtk_widget_set_sensitive (WID ("meta_theme_font2_button"), TRUE); - } - - g_free (str); - } - g_object_unref (client); -} - -static void -font_key_changed (GConfClient *client, - guint cnxn_id, - GConfEntry *entry, - gpointer user_data) -{ - GladeXML *dialog = user_data; - - update_font_button_state (dialog); -} - -static void -icon_key_changed (GConfClient *client, - guint cnxn_id, - GConfEntry *entry, - gpointer user_data) -{ - if (strcmp (entry->key, ICON_THEME_KEY)) - return; - - update_settings_from_gconf (); - gnome_theme_details_update_from_gconf (); -} - -static gboolean -theme_changed_idle (gpointer data) -{ - GladeXML *dialog; - dialog = gnome_theme_manager_get_theme_dialog (); - - update_themes_from_disk (dialog); - gnome_theme_details_reread_themes_from_disk (); - gtk_widget_grab_focus (WID ("meta_theme_treeview")); - theme_changed_idle_id = 0; - return FALSE; -} - -/* FIXME: We want a more sophisticated theme_changed func sometime */ -static void -theme_changed_func (gpointer uri, - gpointer user_data) -{ - if (theme_changed_idle_id != 0) - return; - theme_changed_idle_id = - g_idle_add_full (G_PRIORITY_HIGH_IDLE, - theme_changed_idle, - NULL, NULL); -} - -static void -cb_dialog_response (GtkDialog *dialog, gint response_id) -{ - if (response_id == GTK_RESPONSE_HELP) - capplet_help (GTK_WINDOW (dialog), "user-guide.xml", "goscustdesk-12"); - else - gtk_main_quit (); -} - -static void -setup_meta_tree_view (GtkTreeView *tree_view, - GCallback changed_callback, - GladeXML *dialog) -{ - GtkTreeModel *model; - GtkTreeSelection *selection; - GtkCellRenderer *renderer; - - renderer = g_object_new (GTK_TYPE_CELL_RENDERER_PIXBUF, - "xpad", 4, - "ypad", 4, - NULL); - - gtk_tree_view_insert_column_with_attributes (tree_view, - -1, NULL, - renderer, - "pixbuf", META_THEME_PIXBUF_COLUMN, - NULL); - renderer = gtk_cell_renderer_text_new (); - gtk_tree_view_insert_column_with_attributes (tree_view, - -1, NULL, - renderer, - "markup", META_THEME_NAME_COLUMN, - NULL); - - model = (GtkTreeModel *) gtk_list_store_new (META_N_COLUMNS, - G_TYPE_STRING, /* META_THEME_NAME_COLUMN */ - G_TYPE_STRING, /* META_THEME_ID_COLUMN */ - G_TYPE_UINT, /* META_THEME_FLAG_COLUMN */ - GDK_TYPE_PIXBUF); /* META_THEME_PIXBUF_COLUMN */ - gtk_tree_view_set_model (tree_view, model); - selection = gtk_tree_view_get_selection (tree_view); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); - g_signal_connect (G_OBJECT (selection), "changed", changed_callback, dialog); -} - - -static void -gnome_meta_theme_installer_run_cb (GtkWidget *button, - GtkWidget *parent_window) -{ - gnome_theme_installer_run (parent_window, NULL); -} - - -static void -gnome_theme_save_clicked (GtkWidget *button, - gpointer data) -{ - GladeXML *dialog; - - dialog = gnome_theme_manager_get_theme_dialog (); - - gnome_theme_save_show_dialog (WID ("theme_dialog"), &custom_meta_theme_info); -} - -static void -apply_font_clicked (GtkWidget *button, - gpointer data) -{ - GladeXML *dialog = data; - GConfClient *client; - GtkTreeSelection *selection; - GtkTreeModel *model; - GtkTreeIter iter; - - client = gconf_client_get_default (); - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (WID ("meta_theme_treeview"))); - - if (gtk_tree_selection_get_selected (selection, &model, &iter)) - { - GnomeThemeMetaInfo *meta_theme_info; - char *meta_theme_name; - - gtk_tree_model_get (model, &iter, - META_THEME_ID_COLUMN, &meta_theme_name, - -1); - meta_theme_info = gnome_theme_meta_info_find (meta_theme_name); - - g_assert (meta_theme_info); - g_free (meta_theme_name); - - gconf_client_set_string (client, FONT_KEY, meta_theme_info->application_font, NULL); - } - g_object_unref (client); -} - -static void -revert_theme_clicked (GtkWidget *button, - gpointer data) -{ - GladeXML *dialog; - - gnome_meta_theme_set(&initial_meta_theme_info); - - dialog = gnome_theme_manager_get_theme_dialog (); - gtk_widget_set_sensitive(WID("meta_theme_revert_button"), FALSE); - reverted = TRUE; -} - -static void -setup_dialog (GladeXML *dialog) -{ - GConfClient *client; - GtkWidget *parent, *widget; - GnomeWindowManager *window_manager; - GtkSizeGroup *size_group; - - default_image = gdk_pixbuf_new_from_file(GNOMECC_DATA_DIR "/pixmaps/theme-thumbnailing.png", NULL); - broken_image = gdk_pixbuf_new_from_file(GNOMECC_DATA_DIR "/pixmaps/theme-thumbnailing.png", NULL); - - client = gconf_client_get_default (); - - window_manager = gnome_wm_manager_get_current (gdk_display_get_default_screen (gdk_display_get_default ())); - - parent = WID ("theme_dialog"); - - size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); - gtk_size_group_add_widget (size_group, WID ("meta_theme_details_button")); - gtk_size_group_add_widget (size_group, WID ("meta_theme_install_button")); - gtk_size_group_add_widget (size_group, WID ("meta_theme_save_button")); - gtk_size_group_add_widget (size_group, WID ("meta_theme_font1_button")); - gtk_size_group_add_widget (size_group, WID ("meta_theme_background1_button")); - gtk_size_group_add_widget (size_group, WID ("meta_theme_font2_button")); - gtk_size_group_add_widget (size_group, WID ("meta_theme_background2_button")); - gtk_size_group_add_widget (size_group, WID ("meta_theme_revert_button")); - g_object_unref (size_group); - - gtk_widget_set_sensitive(WID("meta_theme_revert_button"),FALSE); - - g_signal_connect (G_OBJECT (WID ("meta_theme_install_button")), "clicked", G_CALLBACK (gnome_meta_theme_installer_run_cb), parent); - - g_signal_connect (G_OBJECT (WID ("meta_theme_details_button")), "clicked", gnome_theme_details_show, NULL); - - g_signal_connect (G_OBJECT (WID ("meta_theme_font1_button")), "clicked", G_CALLBACK (apply_font_clicked), dialog); - - g_signal_connect (G_OBJECT (WID ("meta_theme_revert_button")), "clicked", G_CALLBACK (revert_theme_clicked),NULL); - - setup_meta_tree_view (GTK_TREE_VIEW (WID ("meta_theme_treeview")), - (GCallback) meta_theme_selection_changed, - dialog); - - gconf_client_add_dir (client, "/desktop/gnome/interface", GCONF_CLIENT_PRELOAD_ONELEVEL, NULL); - - gconf_client_notify_add (client, - GTK_THEME_KEY, - (GConfClientNotifyFunc) >k_theme_key_changed, - dialog, NULL, NULL); - gconf_client_notify_add (client, - ICON_THEME_KEY, - (GConfClientNotifyFunc) &icon_key_changed, - dialog, NULL, NULL); - - gconf_client_notify_add (client, - FONT_KEY, - (GConfClientNotifyFunc) &font_key_changed, - dialog, NULL, NULL); - g_object_unref (client); - - if (window_manager) - g_signal_connect (G_OBJECT (window_manager), - "settings_changed", - (GCallback) window_settings_changed, dialog); - - update_themes_from_disk (dialog); - gtk_widget_grab_focus (WID ("meta_theme_treeview")); - gnome_theme_info_register_theme_change (theme_changed_func, dialog); - - - - widget = WID ("meta_theme_save_button"); - g_signal_connect (G_OBJECT (widget), "clicked", G_CALLBACK (gnome_theme_save_clicked), NULL); - - -/* - g_signal_connect (G_OBJECT (WID ("install_dialog")), "response", - G_CALLBACK (install_dialog_response), dialog); - */ - - g_signal_connect (G_OBJECT (parent), "response", G_CALLBACK (cb_dialog_response), NULL); - - gtk_drag_dest_set (parent, GTK_DEST_DEFAULT_ALL, - drop_types, n_drop_types, - GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_MOVE); - g_signal_connect (G_OBJECT (parent), "drag-motion", G_CALLBACK (gnome_theme_manager_drag_motion_cb), NULL); - g_signal_connect (G_OBJECT (parent), "drag-leave", G_CALLBACK (gnome_theme_manager_drag_leave_cb), NULL); - g_signal_connect (G_OBJECT (parent), "drag-data-received",G_CALLBACK (gnome_theme_manager_drag_data_received_cb), NULL); - - capplet_set_icon (parent, "gnome-settings-theme"); - - update_font_button_state (dialog); - gtk_widget_show (parent); - -} - -/* Non static functions */ -GladeXML * -gnome_theme_manager_get_theme_dialog (void) -{ - static GladeXML *dialog = NULL; - - if (dialog == NULL) - dialog = glade_xml_new (GLADEDIR "/theme-properties.glade", NULL, NULL); - - return dialog; -} - -gint -gnome_theme_manager_sort_func (const gchar *a_str, - const gchar *b_str, - guint a_flag, - guint b_flag) -{ - gint retval; - gint agreater = FALSE, bgreater = FALSE; - - if (a_flag & THEME_FLAG_CUSTOM) - agreater = TRUE; - if (b_flag & THEME_FLAG_CUSTOM) - bgreater = TRUE; - - if (agreater && !bgreater) - return -1; - if (!agreater && bgreater) - return 1; - - if (a_flag & THEME_FLAG_DEFAULT) - agreater = TRUE; - if (b_flag & THEME_FLAG_DEFAULT) - bgreater = TRUE; - - if (agreater && !bgreater) - return -1; - if (!agreater && bgreater) - return 1; - - retval = g_utf8_collate (a_str?a_str:"", - b_str?b_str:""); - - return retval; -} - -/* Starts nautilus on the themes directory*/ -void -gnome_theme_manager_show_manage_themes (GtkWidget *button, gpointer data) -{ - gchar *path, *command; - GnomeVFSURI *uri; - - path = g_strdup_printf ("%s/.themes", g_get_home_dir ()); - uri = gnome_vfs_uri_new (path); - - if (!gnome_vfs_uri_exists (uri)) { - /* Create the directory */ - gnome_vfs_make_directory_for_uri (uri, 0775); - } - gnome_vfs_uri_unref (uri); - - command = g_strdup_printf ("nautilus --no-desktop %s", path); - g_free (path); - - g_spawn_command_line_async (command, NULL); - g_free (command); -} - -/* Starts nautilus on the icon themes directory*/ -void -gnome_theme_manager_icon_show_manage_themes (GtkWidget *button, gpointer data) -{ - gchar *path, *command; - GnomeVFSURI *uri; - - path = g_strdup_printf ("%s/.icons", g_get_home_dir ()); - uri = gnome_vfs_uri_new (path); - - if (!gnome_vfs_uri_exists (uri)) { - /* Create the directory */ - gnome_vfs_make_directory_for_uri (uri, 0775); - } - gnome_vfs_uri_unref (uri); - - command = g_strdup_printf ("nautilus --no-desktop %s", path); - g_free (path); - - g_spawn_command_line_async (command, NULL); - g_free (command); -} - -/* Show the nautilus themes window */ -void -gnome_theme_manager_window_show_manage_themes (GtkWidget *button, gpointer data) -{ - gchar *path, *command; - GnomeVFSURI *uri; - GnomeWindowManager *wm; - - wm = gnome_wm_manager_get_current (gdk_display_get_default_screen (gdk_display_get_default ())); - - path = gnome_window_manager_get_user_theme_folder (wm); - g_object_unref (G_OBJECT (wm)); - - uri = gnome_vfs_uri_new (path); - - if (!gnome_vfs_uri_exists (uri)) { - /* Create the directory */ - gnome_vfs_make_directory_for_uri (uri, 0775); - } - gnome_vfs_uri_unref (uri); - - - command = g_strdup_printf ("nautilus --no-desktop %s", path); - g_free (path); - - g_spawn_command_line_async (command, NULL); - g_free (command); -} - -/* Callback issued during drag movements */ -gboolean -gnome_theme_manager_drag_motion_cb (GtkWidget *widget, GdkDragContext *context, - gint x, gint y, guint time, gpointer data) -{ - return FALSE; -} - -/* Callback issued during drag leaves */ -void -gnome_theme_manager_drag_leave_cb (GtkWidget *widget, GdkDragContext *context, - guint time, gpointer data) -{ - gtk_widget_queue_draw (widget); -} - -/* Callback issued on actual drops. Attempts to load the file dropped. */ -void -gnome_theme_manager_drag_data_received_cb (GtkWidget *widget, GdkDragContext *context, - gint x, gint y, - GtkSelectionData *selection_data, - guint info, guint time, gpointer data) -{ - GList *uris; - gchar *filename = NULL; - - if (!(info == TARGET_URI_LIST || info == TARGET_NS_URL)) - return; - - uris = gnome_vfs_uri_list_parse ((gchar *) selection_data->data); - if (uris != NULL && uris->data != NULL) { - GnomeVFSURI *uri = (GnomeVFSURI *) uris->data; - - if (gnome_vfs_uri_is_local (uri)) - filename = gnome_vfs_unescape_string ( - gnome_vfs_uri_get_path (uri), - G_DIR_SEPARATOR_S); - else - filename = gnome_vfs_unescape_string ( - gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_NONE), - G_DIR_SEPARATOR_S); - - gnome_vfs_uri_list_unref (uris); - } - - gnome_theme_installer_run (widget, filename); - g_free (filename); -} - - -static gchar * -get_default_string_from_key (const char *key) -{ - GConfClient *client; - GConfValue *value; - GError *error = NULL; - gchar *str = NULL; - - client = gconf_client_get_default (); - value = gconf_client_get_default_from_schema (client, key, &error); - g_object_unref (client); - - if (error) - { - g_clear_error (&error); - return NULL; - } - - if (value) - { - if (value->type == GCONF_VALUE_STRING) - str = gconf_value_to_string (value); - gconf_value_free (value); - } - - return str; -} - -int -main (int argc, char *argv[]) -{ - GladeXML *dialog; - - /* We need to do this before we initialize anything else */ - theme_thumbnail_factory_init (argc, argv); - - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - textdomain (GETTEXT_PACKAGE); - - gnome_program_init ("gnome-theme-manager", VERSION, - LIBGNOMEUI_MODULE, argc, argv, - GNOME_PARAM_APP_DATADIR, GNOMECC_DATA_DIR, - NULL); - - gtk_theme_default_name = get_default_string_from_key (GTK_THEME_KEY); - window_theme_default_name = get_default_string_from_key (METACITY_THEME_KEY); - icon_theme_default_name = get_default_string_from_key (ICON_THEME_KEY); - - if (gtk_theme_default_name == NULL || - window_theme_default_name == NULL || - icon_theme_default_name == NULL) - { - GtkWidget *msg_dialog; - - msg_dialog = gtk_message_dialog_new (NULL, - GTK_DIALOG_MODAL, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - _("The default theme schemas could not be found on your system. This means that you probably don't have metacity installed, or that your gconf is configured incorrectly.")); - gtk_dialog_run (GTK_DIALOG (msg_dialog)); - gtk_widget_destroy (msg_dialog); - exit (0); - } - - gnome_theme_init (NULL); - - gnome_wm_manager_init (); - activate_settings_daemon (); - - dialog = gnome_theme_manager_get_theme_dialog (); - - setup_dialog (dialog); - - gtk_main (); - - return 0; -} |