diff --git a/ChangeLog b/ChangeLog index 244d10fd20..b4dbec2e66 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2003-11-12 Michael Natterer + + Use the correct GTK+ APIs for setting and changing the theme: + + * app/gui/themes.c (themes_apply_theme): don't call gtk_rc_parse() + but write a new config file "~/.gimp-1.3/themerc" which includes + both the theme's and the user's gtkrc files. + + (themes_init): use gtk_rc_add_default_file() to make themerc known + to GTK+. + + (themes_theme_change_notify): don't fiddle with toplevel windows + manually but simply call gtk_rc_reparse_all() after writing the + new themerc. + + * libgimp/gimpui.c (gimp_ui_init): use gtk_rc_add_default_file() + instead of gtk_rc_parse(). + + * app/gui/preferences-dialog.c: cleaned up / beautified the theme + selector. Added a "Reload Current Theme" button. Simplified + GtkTreeView column inserting all over the place. + + (prefs_response): destroy the preferences dialog later so we don't + crash when cancelling a theme change on "Cancel" (workaround for + bug #126808). + + * app/gui/module-browser.c (module_browser_new): column inserting + simplification. + 2003-11-12 Sven Neumann * app/gui/color-notebook.c (color_notebook_new): added a default diff --git a/app/dialogs/module-dialog.c b/app/dialogs/module-dialog.c index bd2562b824..74aaa2aa7f 100644 --- a/app/dialogs/module-dialog.c +++ b/app/dialogs/module-dialog.c @@ -171,12 +171,11 @@ module_browser_new (Gimp *gimp) gtk_tree_view_append_column (GTK_TREE_VIEW (tv), col); - rend = gtk_cell_renderer_text_new (); - col = gtk_tree_view_column_new_with_attributes (_("Module Path"), rend, - "text", PATH_COLUMN, - NULL); - - gtk_tree_view_append_column (GTK_TREE_VIEW (tv), col); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tv), 1, + _("Module Path"), + gtk_cell_renderer_text_new (), + "text", PATH_COLUMN, + NULL); gtk_container_add (GTK_CONTAINER (listbox), tv); gtk_widget_show (tv); diff --git a/app/dialogs/preferences-dialog.c b/app/dialogs/preferences-dialog.c index 85f79fd528..47016be7d4 100644 --- a/app/dialogs/preferences-dialog.c +++ b/app/dialogs/preferences-dialog.c @@ -223,9 +223,10 @@ prefs_response (GtkWidget *widget, config_copy = g_object_get_data (G_OBJECT (dialog), "config-copy"); - g_object_ref (config_copy); + /* destroy config_orig */ + g_object_set_data (G_OBJECT (dialog), "config-orig", NULL); - gtk_widget_destroy (dialog); /* destroys config_orig */ + gtk_widget_set_sensitive (GTK_WIDGET (dialog), FALSE); confirm_diff = gimp_config_diff (GIMP_CONFIG (gimp->edit_config), config_copy, @@ -253,7 +254,6 @@ prefs_response (GtkWidget *widget, g_object_thaw_notify (G_OBJECT (gimp->edit_config)); g_list_free (confirm_diff); - g_object_unref (config_copy); gimp_rc_save (GIMP_RC (gimp->edit_config)); @@ -297,9 +297,10 @@ prefs_response (GtkWidget *widget, config_orig = g_object_get_data (G_OBJECT (dialog), "config-orig"); - g_object_ref (config_orig); + /* destroy config_copy */ + g_object_set_data (G_OBJECT (dialog), "config-copy", NULL); - gtk_widget_destroy (dialog); /* destroys config_copy */ + gtk_widget_set_sensitive (GTK_WIDGET (dialog), FALSE); diff = gimp_config_diff (GIMP_CONFIG (gimp->edit_config), config_orig, GIMP_PARAM_SERIALIZE); @@ -328,11 +329,12 @@ prefs_response (GtkWidget *widget, g_object_thaw_notify (G_OBJECT (gimp->edit_config)); g_list_free (diff); - g_object_unref (config_orig); /* enable autosaving again */ gimp_rc_set_autosave (GIMP_RC (gimp->edit_config), TRUE); } + + gtk_widget_destroy (dialog); } static void @@ -588,6 +590,13 @@ prefs_theme_select_callback (GtkTreeSelection *sel, } } +static void +prefs_theme_reload_callback (GtkWidget *button, + Gimp *gimp) +{ + g_object_notify (G_OBJECT (gimp->config), "theme"); +} + static GtkWidget * prefs_frame_new (const gchar *label, GtkContainer *parent, @@ -1202,19 +1211,16 @@ prefs_dialog_new (Gimp *gimp, GTK_BOX (vbox2)); /* Themes */ - vbox2 = prefs_frame_new (_("Themes"), GTK_CONTAINER (vbox), FALSE); + vbox2 = prefs_frame_new (_("Select Theme"), GTK_CONTAINER (vbox), FALSE); { - GtkListStore *list_store; - GtkWidget *view; - GtkWidget *scrolled_win; - GtkCellRenderer *rend; - GtkTreeViewColumn *col; - GtkTreeIter iter; - GtkTreeSelection *sel; - gchar **themes; - gint n_themes; - gint i; + GtkWidget *scrolled_win; + GtkListStore *list_store; + GtkWidget *view; + GtkTreeSelection *sel; + gchar **themes; + gint n_themes; + gint i; scrolled_win = gtk_scrolled_window_new (NULL, NULL); gtk_widget_set_size_request (scrolled_win, -1, 80); @@ -1226,20 +1232,24 @@ prefs_dialog_new (Gimp *gimp, gtk_box_pack_start (GTK_BOX (vbox2), scrolled_win, TRUE, TRUE, 0); gtk_widget_show (scrolled_win); - list_store = gtk_list_store_new (1, G_TYPE_STRING); + list_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store)); - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE); gtk_container_add (GTK_CONTAINER (scrolled_win), view); gtk_widget_show (view); g_object_unref (list_store); - rend = gtk_cell_renderer_text_new (); - col = gtk_tree_view_column_new_with_attributes (NULL, rend, - "text", 0, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (view), col); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), 0, + _("Theme"), + gtk_cell_renderer_text_new (), + "text", 0, + NULL); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), 1, + _("Folder"), + gtk_cell_renderer_text_new (), + "text", 1, + NULL); sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); @@ -1247,9 +1257,12 @@ prefs_dialog_new (Gimp *gimp, for (i = 0; i < n_themes; i++) { + GtkTreeIter iter; + gtk_list_store_append (list_store, &iter); gtk_list_store_set (list_store, &iter, 0, themes[i], + 1, themes_get_theme_dir (gimp, themes[i]), -1); if (GIMP_GUI_CONFIG (object)->theme && @@ -1267,6 +1280,19 @@ prefs_dialog_new (Gimp *gimp, gimp); } + hbox = gtk_hbox_new (FALSE, 4); + gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + + button = gtk_button_new_with_mnemonic (_("Reload C_urrent Theme")); + gtk_misc_set_padding (GTK_MISC (GTK_BIN (button)->child), 4, 0); + gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); + gtk_widget_show (button); + + g_signal_connect (button, "clicked", + G_CALLBACK (prefs_theme_reload_callback), + gimp); + /*****************************/ /* Interface / Help System */ @@ -1528,15 +1554,12 @@ prefs_dialog_new (Gimp *gimp, for (format = 0; format < G_N_ELEMENTS (formats); format++) { - GtkListStore *list_store; - GtkWidget *view; - GtkWidget *scrolled_win; - GtkWidget *entry; - GtkCellRenderer *rend; - GtkTreeViewColumn *col; - GtkTreeIter iter; - GtkTreeSelection *sel; - gint i; + GtkWidget *scrolled_win; + GtkListStore *list_store; + GtkWidget *view; + GtkWidget *entry; + GtkTreeSelection *sel; + gint i; format_strings[0] = formats[format].current_setting; @@ -1565,25 +1588,23 @@ prefs_dialog_new (Gimp *gimp, g_object_unref (list_store); - rend = gtk_cell_renderer_text_new (); - col = gtk_tree_view_column_new_with_attributes (NULL, rend, - "text", 0, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (view), col); - - rend = gtk_cell_renderer_text_new (); - col = gtk_tree_view_column_new_with_attributes (NULL, rend, - "text", 1, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (view), col); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), 0, + NULL, + gtk_cell_renderer_text_new (), + "text", 0, + NULL); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), 1, + NULL, + gtk_cell_renderer_text_new (), + "text", 1, + NULL); sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); - g_signal_connect (sel, "changed", - G_CALLBACK (prefs_format_string_select_callback), - entry); for (i = 0; i < G_N_ELEMENTS (format_strings); i++) { + GtkTreeIter iter; + gtk_list_store_append (list_store, &iter); gtk_list_store_set (list_store, &iter, 0, format_names[i], @@ -1593,6 +1614,10 @@ prefs_dialog_new (Gimp *gimp, if (i == 0) gtk_tree_selection_select_iter (sel, &iter); } + + g_signal_connect (sel, "changed", + G_CALLBACK (prefs_format_string_select_callback), + entry); } } diff --git a/app/gui/module-browser.c b/app/gui/module-browser.c index bd2562b824..74aaa2aa7f 100644 --- a/app/gui/module-browser.c +++ b/app/gui/module-browser.c @@ -171,12 +171,11 @@ module_browser_new (Gimp *gimp) gtk_tree_view_append_column (GTK_TREE_VIEW (tv), col); - rend = gtk_cell_renderer_text_new (); - col = gtk_tree_view_column_new_with_attributes (_("Module Path"), rend, - "text", PATH_COLUMN, - NULL); - - gtk_tree_view_append_column (GTK_TREE_VIEW (tv), col); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tv), 1, + _("Module Path"), + gtk_cell_renderer_text_new (), + "text", PATH_COLUMN, + NULL); gtk_container_add (GTK_CONTAINER (listbox), tv); gtk_widget_show (tv); diff --git a/app/gui/preferences-dialog.c b/app/gui/preferences-dialog.c index 85f79fd528..47016be7d4 100644 --- a/app/gui/preferences-dialog.c +++ b/app/gui/preferences-dialog.c @@ -223,9 +223,10 @@ prefs_response (GtkWidget *widget, config_copy = g_object_get_data (G_OBJECT (dialog), "config-copy"); - g_object_ref (config_copy); + /* destroy config_orig */ + g_object_set_data (G_OBJECT (dialog), "config-orig", NULL); - gtk_widget_destroy (dialog); /* destroys config_orig */ + gtk_widget_set_sensitive (GTK_WIDGET (dialog), FALSE); confirm_diff = gimp_config_diff (GIMP_CONFIG (gimp->edit_config), config_copy, @@ -253,7 +254,6 @@ prefs_response (GtkWidget *widget, g_object_thaw_notify (G_OBJECT (gimp->edit_config)); g_list_free (confirm_diff); - g_object_unref (config_copy); gimp_rc_save (GIMP_RC (gimp->edit_config)); @@ -297,9 +297,10 @@ prefs_response (GtkWidget *widget, config_orig = g_object_get_data (G_OBJECT (dialog), "config-orig"); - g_object_ref (config_orig); + /* destroy config_copy */ + g_object_set_data (G_OBJECT (dialog), "config-copy", NULL); - gtk_widget_destroy (dialog); /* destroys config_copy */ + gtk_widget_set_sensitive (GTK_WIDGET (dialog), FALSE); diff = gimp_config_diff (GIMP_CONFIG (gimp->edit_config), config_orig, GIMP_PARAM_SERIALIZE); @@ -328,11 +329,12 @@ prefs_response (GtkWidget *widget, g_object_thaw_notify (G_OBJECT (gimp->edit_config)); g_list_free (diff); - g_object_unref (config_orig); /* enable autosaving again */ gimp_rc_set_autosave (GIMP_RC (gimp->edit_config), TRUE); } + + gtk_widget_destroy (dialog); } static void @@ -588,6 +590,13 @@ prefs_theme_select_callback (GtkTreeSelection *sel, } } +static void +prefs_theme_reload_callback (GtkWidget *button, + Gimp *gimp) +{ + g_object_notify (G_OBJECT (gimp->config), "theme"); +} + static GtkWidget * prefs_frame_new (const gchar *label, GtkContainer *parent, @@ -1202,19 +1211,16 @@ prefs_dialog_new (Gimp *gimp, GTK_BOX (vbox2)); /* Themes */ - vbox2 = prefs_frame_new (_("Themes"), GTK_CONTAINER (vbox), FALSE); + vbox2 = prefs_frame_new (_("Select Theme"), GTK_CONTAINER (vbox), FALSE); { - GtkListStore *list_store; - GtkWidget *view; - GtkWidget *scrolled_win; - GtkCellRenderer *rend; - GtkTreeViewColumn *col; - GtkTreeIter iter; - GtkTreeSelection *sel; - gchar **themes; - gint n_themes; - gint i; + GtkWidget *scrolled_win; + GtkListStore *list_store; + GtkWidget *view; + GtkTreeSelection *sel; + gchar **themes; + gint n_themes; + gint i; scrolled_win = gtk_scrolled_window_new (NULL, NULL); gtk_widget_set_size_request (scrolled_win, -1, 80); @@ -1226,20 +1232,24 @@ prefs_dialog_new (Gimp *gimp, gtk_box_pack_start (GTK_BOX (vbox2), scrolled_win, TRUE, TRUE, 0); gtk_widget_show (scrolled_win); - list_store = gtk_list_store_new (1, G_TYPE_STRING); + list_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING); view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store)); - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE); gtk_container_add (GTK_CONTAINER (scrolled_win), view); gtk_widget_show (view); g_object_unref (list_store); - rend = gtk_cell_renderer_text_new (); - col = gtk_tree_view_column_new_with_attributes (NULL, rend, - "text", 0, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (view), col); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), 0, + _("Theme"), + gtk_cell_renderer_text_new (), + "text", 0, + NULL); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), 1, + _("Folder"), + gtk_cell_renderer_text_new (), + "text", 1, + NULL); sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); @@ -1247,9 +1257,12 @@ prefs_dialog_new (Gimp *gimp, for (i = 0; i < n_themes; i++) { + GtkTreeIter iter; + gtk_list_store_append (list_store, &iter); gtk_list_store_set (list_store, &iter, 0, themes[i], + 1, themes_get_theme_dir (gimp, themes[i]), -1); if (GIMP_GUI_CONFIG (object)->theme && @@ -1267,6 +1280,19 @@ prefs_dialog_new (Gimp *gimp, gimp); } + hbox = gtk_hbox_new (FALSE, 4); + gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + + button = gtk_button_new_with_mnemonic (_("Reload C_urrent Theme")); + gtk_misc_set_padding (GTK_MISC (GTK_BIN (button)->child), 4, 0); + gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); + gtk_widget_show (button); + + g_signal_connect (button, "clicked", + G_CALLBACK (prefs_theme_reload_callback), + gimp); + /*****************************/ /* Interface / Help System */ @@ -1528,15 +1554,12 @@ prefs_dialog_new (Gimp *gimp, for (format = 0; format < G_N_ELEMENTS (formats); format++) { - GtkListStore *list_store; - GtkWidget *view; - GtkWidget *scrolled_win; - GtkWidget *entry; - GtkCellRenderer *rend; - GtkTreeViewColumn *col; - GtkTreeIter iter; - GtkTreeSelection *sel; - gint i; + GtkWidget *scrolled_win; + GtkListStore *list_store; + GtkWidget *view; + GtkWidget *entry; + GtkTreeSelection *sel; + gint i; format_strings[0] = formats[format].current_setting; @@ -1565,25 +1588,23 @@ prefs_dialog_new (Gimp *gimp, g_object_unref (list_store); - rend = gtk_cell_renderer_text_new (); - col = gtk_tree_view_column_new_with_attributes (NULL, rend, - "text", 0, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (view), col); - - rend = gtk_cell_renderer_text_new (); - col = gtk_tree_view_column_new_with_attributes (NULL, rend, - "text", 1, - NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (view), col); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), 0, + NULL, + gtk_cell_renderer_text_new (), + "text", 0, + NULL); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), 1, + NULL, + gtk_cell_renderer_text_new (), + "text", 1, + NULL); sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); - g_signal_connect (sel, "changed", - G_CALLBACK (prefs_format_string_select_callback), - entry); for (i = 0; i < G_N_ELEMENTS (format_strings); i++) { + GtkTreeIter iter; + gtk_list_store_append (list_store, &iter); gtk_list_store_set (list_store, &iter, 0, format_names[i], @@ -1593,6 +1614,10 @@ prefs_dialog_new (Gimp *gimp, if (i == 0) gtk_tree_selection_select_iter (sel, &iter); } + + g_signal_connect (sel, "changed", + G_CALLBACK (prefs_format_string_select_callback), + entry); } } diff --git a/app/gui/themes.c b/app/gui/themes.c index dfd20b2beb..ea51c4ac9c 100644 --- a/app/gui/themes.c +++ b/app/gui/themes.c @@ -18,6 +18,8 @@ #include "config.h" +#include + #include #include "libgimpbase/gimpbase.h" @@ -57,6 +59,7 @@ void themes_init (Gimp *gimp) { GimpGuiConfig *config; + gchar *themerc; g_return_if_fail (GIMP_IS_GIMP (gimp)); @@ -83,6 +86,10 @@ themes_init (Gimp *gimp) themes_apply_theme (gimp, config->theme); + themerc = gimp_personal_rc_file ("themerc"); + gtk_rc_add_default_file (themerc); + g_free (themerc); + g_signal_connect (config, "notify::theme", G_CALLBACK (themes_theme_change_notify), gimp); @@ -148,7 +155,10 @@ themes_apply_theme (Gimp *gimp, const gchar *theme_name) { const gchar *theme_dir; - gchar *gtkrc; + gchar *gtkrc_theme; + gchar *gtkrc_user; + gchar *themerc; + FILE *file; g_return_if_fail (GIMP_IS_GIMP (gimp)); @@ -156,29 +166,48 @@ themes_apply_theme (Gimp *gimp, if (theme_dir) { - gtkrc = g_build_filename (theme_dir, "gtkrc", NULL); + gtkrc_theme = g_build_filename (theme_dir, "gtkrc", NULL); } else { /* get the hardcoded default theme gtkrc */ - gtkrc = g_strdup (gimp_gtkrc ()); + gtkrc_theme = g_strdup (gimp_gtkrc ()); } - if (gimp->be_verbose) - g_print (_("Parsing '%s'\n"), gtkrc); + gtkrc_user = gimp_personal_rc_file ("gtkrc"); - gtk_rc_parse (gtkrc); - g_free (gtkrc); - - /* parse the user gtkrc */ - - gtkrc = gimp_personal_rc_file ("gtkrc"); + themerc = gimp_personal_rc_file ("themerc"); if (gimp->be_verbose) - g_print (_("Parsing '%s'\n"), gtkrc); + g_print (_("Writing '%s'\n"), themerc); - gtk_rc_parse (gtkrc); - g_free (gtkrc); + file = fopen (themerc, "w"); + + if (! file) + { + g_message ("Can't open themerc"); + goto cleanup; + } + + fprintf (file, + "# GIMP themerc\n" + "#\n" + "# This file is written on GIMP startup and on every theme change.\n" + "# It is NOT supposed to be edited manually. Edit your personal\n" + "# gtkrc file instead (%s).\n" + "\n" + "include \"%s\"\n" + "include \"%s\"\n" + "\n" + "# end of themerc\n", + gtkrc_user, gtkrc_theme, gtkrc_user); + + fclose (file); + + cleanup: + g_free (gtkrc_theme); + g_free (gtkrc_user); + g_free (themerc); } @@ -216,18 +245,7 @@ themes_theme_change_notify (GimpGuiConfig *config, GParamSpec *pspec, Gimp *gimp) { - GList *list, *toplevels; - themes_apply_theme (gimp, config->theme); - toplevels = gtk_window_list_toplevels (); - g_list_foreach (toplevels, (GFunc) g_object_ref, NULL); - - for (list = toplevels; list; list = list->next) - { - gtk_widget_reset_rc_styles (list->data); - g_object_unref (list->data); - } - - g_list_free (toplevels); + gtk_rc_reparse_all (); } diff --git a/libgimp/gimpui.c b/libgimp/gimpui.c index 2c1c8af7fc..9e75060ad4 100644 --- a/libgimp/gimpui.c +++ b/libgimp/gimpui.c @@ -69,8 +69,7 @@ gimp_ui_init (const gchar *prog_name, const gchar *display_name; gint argc; gchar **argv; - gchar *theme_dir; - gchar *gtkrc; + gchar *themerc; GdkScreen *screen; g_return_if_fail (prog_name != NULL); @@ -102,25 +101,9 @@ gimp_ui_init (const gchar *prog_name, gtk_init (&argc, &argv); - theme_dir = gimp_get_theme_dir (); - - if (theme_dir) - { - gtkrc = g_build_filename (theme_dir, "gtkrc", NULL); - g_free (theme_dir); - } - else - { - /* get the hardcoded default theme gtkrc */ - gtkrc = g_strdup (gimp_gtkrc ()); - } - - gtk_rc_parse (gtkrc); - g_free (gtkrc); - - gtkrc = gimp_personal_rc_file ("gtkrc"); - gtk_rc_parse (gtkrc); - g_free (gtkrc); + themerc = gimp_personal_rc_file ("themerc"); + gtk_rc_add_default_file (themerc); + g_free (themerc); gdk_rgb_set_min_colors (gimp_min_colors ()); gdk_rgb_set_install (gimp_install_cmap ());