From 52aec436713a6e51aa962c15e95062051f1cafce Mon Sep 17 00:00:00 2001 From: Jonathan Blandford Date: Thu, 18 Apr 2002 23:36:45 +0000 Subject: [PATCH] handle new theme-changing code, and sort code. Thu Apr 18 17:56:12 2002 Thu Apr 18 19:35:42 2002 Jonathan Blandford * gnome-font-and-theme-properties.c (setup_dialog): handle new theme-changing code, and sort code. Thu Apr 18 17:56:12 2002 Jonathan Blandford * gnome-keybinding-properties.c (theme_changed_func): handle new theme-changeing code. Thu Apr 18 17:56:25 2002 Jonathan Blandford * theme-common.c: Notify when the theme changes. --- capplets/common/ChangeLog | 4 + capplets/common/theme-common.c | 257 ++++++++++++------ capplets/common/theme-common.h | 12 +- capplets/keybindings/ChangeLog | 5 + .../keybindings/gnome-keybinding-properties.c | 79 +++--- capplets/theme-switcher/ChangeLog | 5 + .../gnome-font-and-theme-properties.c | 31 ++- 7 files changed, 268 insertions(+), 125 deletions(-) diff --git a/capplets/common/ChangeLog b/capplets/common/ChangeLog index 6248a0812..ad6ce3090 100644 --- a/capplets/common/ChangeLog +++ b/capplets/common/ChangeLog @@ -1,3 +1,7 @@ +Thu Apr 18 17:56:25 2002 Jonathan Blandford + + * theme-common.c: Notify when the theme changes. + 2002-04-18 Jody Goldberg * activate-settings-daemon.c (static) : message dialogs must have diff --git a/capplets/common/theme-common.c b/capplets/common/theme-common.c index d2a42a4ae..f21efff1d 100644 --- a/capplets/common/theme-common.c +++ b/capplets/common/theme-common.c @@ -8,128 +8,213 @@ #include #include #include +#include #include "theme-common.h" -static GList * -themes_common_list_add_dir (GList *list, - const char *dirname) +static void theme_info_free (ThemeInfo *info); + +typedef struct _ThemeCallbackData { + GFunc func; + gpointer data; +} ThemeCallbackData; + +GList *theme_list = NULL; +GList *callbacks = NULL; +const gchar *suffix = "gtk-2.0"; +const gchar *key_suffix = "gtk-2.0-key"; + + +static ThemeInfo * +find_theme_info_by_dir (const gchar *theme_dir) +{ + GList *list; + + for (list = theme_list; list; list = list->next) + { + ThemeInfo *info = list->data; + + if (! strcmp (info->path, theme_dir)) + return info; + } + + return NULL; +} + +static void +update_theme_dir (const gchar *theme_dir) +{ + ThemeInfo *info = NULL; + gboolean changed = FALSE; + gboolean has_gtk = FALSE; + gboolean has_keybinding = FALSE; + + gchar *tmp; + + tmp = g_build_filename (theme_dir, suffix, NULL); + if (g_file_test (tmp, G_FILE_TEST_IS_DIR)) + { + has_gtk = TRUE; + } + g_free (tmp); + + tmp = g_build_filename (theme_dir, key_suffix, NULL); + if (g_file_test (tmp, G_FILE_TEST_IS_DIR)) + { + has_keybinding = TRUE; + } + g_free (tmp); + + info = find_theme_info_by_dir (theme_dir); + + if (info) + { + if (!has_gtk && ! has_keybinding) + { + theme_list = g_list_remove (theme_list, info); + theme_info_free (info); + changed = TRUE; + } + else if ((info->has_keybinding != has_keybinding) || + (info->has_gtk != has_gtk)) + { + info->has_keybinding = has_keybinding; + info->has_gtk = has_gtk; + changed = TRUE; + } + } + else + { + if (has_gtk || has_keybinding) + { + info = g_new0 (ThemeInfo, 1); + info->path = g_strdup (theme_dir); + info->name = g_strdup (strrchr (theme_dir, '/') + 1); + info->has_gtk = has_gtk; + info->has_keybinding = has_keybinding; + + theme_list = g_list_prepend (theme_list, info); + changed = TRUE; + } + } + if (changed) + { + GList *list; + + for (list = callbacks; list; list = list->next) + { + ThemeCallbackData *callback_data = list->data; + + (* callback_data->func) ((gpointer)theme_dir, callback_data->data); + } + } + +} + +static void +top_theme_dir_changed_callback (GnomeVFSMonitorHandle *handle, + const gchar *monitor_uri, + const gchar *info_uri, + GnomeVFSMonitorEventType event_type, + gpointer user_data) +{ + switch (event_type) + { + case GNOME_VFS_MONITOR_EVENT_CHANGED: + case GNOME_VFS_MONITOR_EVENT_CREATED: + case GNOME_VFS_MONITOR_EVENT_DELETED: + if (!strncmp (info_uri, "file://", strlen ("file://"))) + update_theme_dir (info_uri + strlen ("file://")); + else + update_theme_dir (info_uri); + break; + default: + break; + } +} + +static void +themes_common_list_add_dir (const char *dirname) +{ + GnomeVFSMonitorHandle *handle = NULL; DIR *dir; struct dirent *de; - const gchar *suffix = "gtk-2.0"; - const gchar *key_suffix = "gtk-2.0-key"; - g_return_val_if_fail (dirname != NULL, list); + g_return_if_fail (dirname != NULL); dir = opendir (dirname); + + gnome_vfs_monitor_add (&handle, + dirname, + GNOME_VFS_MONITOR_DIRECTORY, + top_theme_dir_changed_callback, + NULL); + + if (!dir) - return list; + return; while ((de = readdir (dir))) { char *tmp; - ThemeInfo *info = NULL; if (de->d_name[0] == '.') continue; - tmp = g_build_filename (dirname, de->d_name, suffix, NULL); - if (g_file_test (tmp, G_FILE_TEST_IS_DIR)) - { - info = g_new0 (ThemeInfo, 1); - info->path = g_build_filename (dirname, de->d_name, NULL); - info->name = g_strdup (de->d_name); - - info->has_gtk = TRUE; - } + tmp = g_build_filename (dirname, de->d_name, NULL); + update_theme_dir (tmp); g_free (tmp); - - tmp = g_build_filename (dirname, de->d_name, key_suffix, NULL); - if (g_file_test (tmp, G_FILE_TEST_IS_DIR)) - { - if (info == NULL) - { - info = g_new0 (ThemeInfo, 1); - info->path = g_build_filename (dirname, de->d_name, NULL); - info->name = g_strdup (de->d_name); - } - info->has_keybinding = TRUE; - } - g_free (tmp); - if (info) - list = g_list_prepend (list, info); } closedir (dir); +} - return list; + +void +theme_common_init (void) +{ + static gboolean initted = FALSE; + gchar *dir; + + if (initted) + return; + initted = TRUE; + + dir = g_build_filename (g_get_home_dir (), ".themes", NULL); + themes_common_list_add_dir (dir); + g_free (dir); + + dir = gtk_rc_get_theme_dir (); + themes_common_list_add_dir (dir); + g_free (dir); } GList * theme_common_get_list (void) { - gchar *dir; - GList *theme_list = NULL; - - dir = g_build_filename (g_get_home_dir (), ".themes", NULL); - theme_list = themes_common_list_add_dir (theme_list, dir); - g_free (dir); - - dir = gtk_rc_get_theme_dir (); - theme_list = themes_common_list_add_dir (theme_list, dir); - g_free (dir); - + theme_common_init (); return theme_list; } void -theme_common_list_free (GList *list) +theme_common_register_theme_change (GFunc func, + gpointer data) { - if (list == NULL) - return; + ThemeCallbackData *callback_data; - g_list_foreach (list, g_free, NULL); - g_list_free (list); + callback_data = g_new0 (ThemeCallbackData, 1); + + callback_data->func = func; + callback_data->data = data; + + callbacks = g_list_prepend (callbacks, callback_data); } - static void -theme_dir_changed_callback (GnomeVFSMonitorHandle *handle, - const gchar *monitor_uri, - const gchar *info_uri, - GnomeVFSMonitorEventType event_type, - gpointer user_data) +theme_info_free (ThemeInfo *info) { - g_print ("%s\n", monitor_uri); - g_closure_invoke ((GClosure *) user_data, NULL, 0, NULL, NULL); + g_free (info->path); + g_free (info->name); + g_free (info); } -void -theme_common_register_theme_change (GCallback func, - gpointer data) -{ - GnomeVFSResult result; - GnomeVFSMonitorHandle *handle = NULL; - gchar *text_uri; - GClosure *closure; - /* We're unlikely to ever need to cancel this with the control center */ - - closure = g_cclosure_new (func, data, NULL); - text_uri = g_build_filename (g_get_home_dir (), ".themes", NULL); - - gnome_vfs_monitor_add (&handle, - text_uri, - GNOME_VFS_MONITOR_DIRECTORY, - theme_dir_changed_callback, - closure); - g_free (text_uri); - - text_uri = gtk_rc_get_theme_dir (); - gnome_vfs_monitor_add (&handle, - text_uri, - GNOME_VFS_MONITOR_DIRECTORY, - theme_dir_changed_callback, - closure); - g_free (text_uri); - -} diff --git a/capplets/common/theme-common.h b/capplets/common/theme-common.h index 24e264f77..0ce52f165 100644 --- a/capplets/common/theme-common.h +++ b/capplets/common/theme-common.h @@ -9,14 +9,16 @@ struct _ThemeInfo { gchar *path; gchar *name; - gboolean has_gtk; - gboolean has_keybinding; + guint has_gtk : 1; + guint has_keybinding : 1; + guint user_writable : 1; }; +void theme_common_init (void); GList *theme_common_get_list (void); -void theme_common_list_free (GList *list); -void theme_common_register_theme_change (GCallback func, - gpointer data); +void theme_common_register_theme_change (GFunc func, + gpointer data); + #endif /* THEME_COMMON_H */ diff --git a/capplets/keybindings/ChangeLog b/capplets/keybindings/ChangeLog index 05b609895..25ec0684e 100644 --- a/capplets/keybindings/ChangeLog +++ b/capplets/keybindings/ChangeLog @@ -1,3 +1,8 @@ +Thu Apr 18 17:56:12 2002 Jonathan Blandford + + * gnome-keybinding-properties.c (theme_changed_func): handle new + theme-changeing code. + 2002-04-11 Jacob Berkman * Makefile.am (EXTRA_DIST): add pixmap diff --git a/capplets/keybindings/gnome-keybinding-properties.c b/capplets/keybindings/gnome-keybinding-properties.c index dfba65513..0c4ee4a91 100644 --- a/capplets/keybindings/gnome-keybinding-properties.c +++ b/capplets/keybindings/gnome-keybinding-properties.c @@ -495,6 +495,50 @@ accel_edited_callback (GtkCellRendererText *cell, gtk_tree_path_free (path); } + +static void +theme_changed_func (gpointer uri, + GladeXML *dialog) +{ + GConfClient *client; + GtkWidget *omenu; + GtkWidget *menu; + GtkWidget *menu_item; + GConfEntry *entry; + GList *key_theme_list; + GList *list; + + client = gconf_client_get_default (); + key_theme_list = theme_common_get_list (); + + omenu = WID ("key_theme_omenu"); + menu = gtk_menu_new (); + for (list = key_theme_list; list; list = list->next) + { + ThemeInfo *info = list->data; + + if (! info->has_keybinding) + continue; + + menu_item = make_key_theme_menu_item (info->name); + if (!strcmp (info->name, "Default")) + /* Put default first, always */ + gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item); + else + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); + } + + gtk_widget_show (menu); + gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu); + + /* Initialize the option menu */ + entry = gconf_client_get_entry (client, + KEY_THEME_KEY, + NULL, TRUE, NULL); + + key_theme_changed (client, 0, entry, omenu); +} + static void setup_dialog (GladeXML *dialog) { @@ -534,42 +578,13 @@ setup_dialog (GladeXML *dialog) } else { - GtkWidget *omenu; - GtkWidget *menu; - GtkWidget *menu_item; - GConfEntry *entry; - - omenu = WID ("key_theme_omenu"); - menu = gtk_menu_new (); - for (list = key_theme_list; list; list = list->next) - { - ThemeInfo *info = list->data; - - if (! info->has_keybinding) - continue; - - menu_item = make_key_theme_menu_item (info->name); - if (!strcmp (info->name, "Default")) - /* Put default first, always */ - gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item); - else - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); - } - - gtk_widget_show (menu); - gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu); - + theme_changed_func (NULL, dialog); + theme_common_register_theme_change ((GFunc) theme_changed_func, dialog); gconf_client_add_dir (client, "/desktop/gnome/interface", GCONF_CLIENT_PRELOAD_ONELEVEL, NULL); gconf_client_notify_add (client, KEY_THEME_KEY, (GConfClientNotifyFunc) &key_theme_changed, - omenu, NULL, NULL); - /* Initialize the option menu */ - entry = gconf_client_get_entry (client, - KEY_THEME_KEY, - NULL, TRUE, NULL); - - key_theme_changed (client, 0, entry, omenu); + WID ("key_theme_omenu"), NULL, NULL); } diff --git a/capplets/theme-switcher/ChangeLog b/capplets/theme-switcher/ChangeLog index 9669d9f0a..bee644e26 100644 --- a/capplets/theme-switcher/ChangeLog +++ b/capplets/theme-switcher/ChangeLog @@ -1,3 +1,8 @@ +Thu Apr 18 19:35:42 2002 Jonathan Blandford + + * gnome-font-and-theme-properties.c (setup_dialog): handle new + theme-changing code, and sort code. + 2002-04-12 jacob berkman * gnome-font-and-theme-properties.c (create_dialog): get the glade diff --git a/capplets/theme-switcher/gnome-font-and-theme-properties.c b/capplets/theme-switcher/gnome-font-and-theme-properties.c index fed0d24a4..dbdbc52b0 100644 --- a/capplets/theme-switcher/gnome-font-and-theme-properties.c +++ b/capplets/theme-switcher/gnome-font-and-theme-properties.c @@ -171,9 +171,34 @@ theme_key_changed (GConfClient *client, static void -theme_changed_func (gpointer data) +theme_changed_func (gpointer uri, + gpointer user_data) { - g_print ("boo\n"); + read_themes ((GladeXML *)user_data); +} + +static gint +sort_func (GtkTreeModel *model, + GtkTreeIter *a, + GtkTreeIter *b, + gpointer user_data) +{ + gchar *a_str = NULL; + gchar *b_str = NULL; + + gtk_tree_model_get (model, a, 0, &a_str, -1); + gtk_tree_model_get (model, b, 0, &b_str, -1); + + if (a_str == NULL) a_str = g_strdup (""); + if (b_str == NULL) b_str = g_strdup (""); + + g_print ("comparing %s to %s\n", a_str, b_str); + if (!strcmp (a_str, "Default")) + return -1; + if (!strcmp (b_str, "Default")) + return 1; + + return g_utf8_collate (a_str, b_str); } static void @@ -199,6 +224,8 @@ setup_dialog (GladeXML *dialog) dialog, NULL, NULL); model = (GtkTreeModel *) gtk_list_store_new (N_COLUMNS, G_TYPE_STRING); + gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (model), 0, sort_func, NULL, NULL); + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), 0, GTK_SORT_ASCENDING); gtk_tree_view_set_model (GTK_TREE_VIEW (WID ("theme_treeview")), model); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (WID ("theme_treeview"))); gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);