diff options
Diffstat (limited to '')
-rw-r--r-- | app/dialogs/preferences-dialog.c | 3409 |
1 files changed, 3409 insertions, 0 deletions
diff --git a/app/dialogs/preferences-dialog.c b/app/dialogs/preferences-dialog.c new file mode 100644 index 0000000..cde1576 --- /dev/null +++ b/app/dialogs/preferences-dialog.c @@ -0,0 +1,3409 @@ +/* GIMP - The GNU Image Manipulation Program + * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include "config.h" + +#include <string.h> + +#include <gegl.h> +#include <gtk/gtk.h> + +#include "libgimpmath/gimpmath.h" +#include "libgimpbase/gimpbase.h" +#include "libgimpconfig/gimpconfig.h" +#include "libgimpwidgets/gimpwidgets.h" + +#include "dialogs-types.h" + +#include "gimp-version.h" + +#include "config/gimprc.h" + +#include "core/gimp.h" +#include "core/gimptemplate.h" + +#include "plug-in/gimppluginmanager.h" + +#include "widgets/gimpaction-history.h" +#include "widgets/gimpcolorpanel.h" +#include "widgets/gimpcontainercombobox.h" +#include "widgets/gimpcontainerview.h" +#include "widgets/gimpcontrollerlist.h" +#include "widgets/gimpdevices.h" +#include "widgets/gimpdialogfactory.h" +#include "widgets/gimpgrideditor.h" +#include "widgets/gimphelp.h" +#include "widgets/gimphelp-ids.h" +#include "widgets/gimpiconsizescale.h" +#include "widgets/gimplanguagecombobox.h" +#include "widgets/gimpmessagebox.h" +#include "widgets/gimpmessagedialog.h" +#include "widgets/gimppluginview.h" +#include "widgets/gimpprefsbox.h" +#include "widgets/gimppropwidgets.h" +#include "widgets/gimpstrokeeditor.h" +#include "widgets/gimptemplateeditor.h" +#include "widgets/gimptooleditor.h" +#include "widgets/gimpwidgets-utils.h" + +#include "menus/menus.h" + +#include "tools/gimp-tools.h" + +#include "gui/session.h" +#include "gui/icon-themes.h" +#include "gui/themes.h" + +#include "preferences-dialog.h" +#include "preferences-dialog-utils.h" +#include "resolution-calibrate-dialog.h" + +#include "gimp-intl.h" + + +#define RESPONSE_RESET 1 + + +/* preferences local functions */ + +static GtkWidget * prefs_dialog_new (Gimp *gimp, + GimpConfig *config); +static void prefs_config_notify (GObject *config, + GParamSpec *param_spec, + GObject *config_copy); +static void prefs_config_copy_notify (GObject *config_copy, + GParamSpec *param_spec, + GObject *config); +static void prefs_response (GtkWidget *widget, + gint response_id, + GtkWidget *dialog); + +static void prefs_message (GtkMessageType type, + gboolean destroy, + const gchar *message); + +static void prefs_color_management_reset (GtkWidget *widget, + GObject *config); +static void prefs_dialog_defaults_reset (GtkWidget *widget, + GObject *config); +static void prefs_folders_reset (GtkWidget *widget, + GObject *config); +static void prefs_path_reset (GtkWidget *widget, + GObject *config); + +static void prefs_import_raw_procedure_callback (GtkWidget *widget, + GObject *config); +static void prefs_resolution_source_callback (GtkWidget *widget, + GObject *config); +static void prefs_resolution_calibrate_callback (GtkWidget *widget, + GtkWidget *entry); +static void prefs_input_devices_dialog (GtkWidget *widget, + Gimp *gimp); +static void prefs_keyboard_shortcuts_dialog (GtkWidget *widget, + Gimp *gimp); +static void prefs_menus_save_callback (GtkWidget *widget, + Gimp *gimp); +static void prefs_menus_clear_callback (GtkWidget *widget, + Gimp *gimp); +static void prefs_menus_remove_callback (GtkWidget *widget, + Gimp *gimp); +static void prefs_session_save_callback (GtkWidget *widget, + Gimp *gimp); +static void prefs_session_clear_callback (GtkWidget *widget, + Gimp *gimp); +static void prefs_devices_save_callback (GtkWidget *widget, + Gimp *gimp); +static void prefs_devices_clear_callback (GtkWidget *widget, + Gimp *gimp); +static void prefs_search_clear_callback (GtkWidget *widget, + Gimp *gimp); +static void prefs_tool_options_save_callback (GtkWidget *widget, + Gimp *gimp); +static void prefs_tool_options_clear_callback (GtkWidget *widget, + Gimp *gimp); +static void prefs_help_language_change_callback (GtkComboBox *combo, + Gimp *gimp); +static void prefs_help_language_change_callback2 (GtkComboBox *combo, + GtkContainer *box); + + +/* private variables */ + +static GtkWidget *prefs_dialog = NULL; +static GtkWidget *tool_editor = NULL; + + +/* public function */ + +GtkWidget * +preferences_dialog_create (Gimp *gimp) +{ + GimpConfig *config; + GimpConfig *config_copy; + GimpConfig *config_orig; + + g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL); + + if (prefs_dialog) + return prefs_dialog; + + /* turn off autosaving while the prefs dialog is open */ + gimp_rc_set_autosave (GIMP_RC (gimp->edit_config), FALSE); + + config = GIMP_CONFIG (gimp->edit_config); + config_copy = gimp_config_duplicate (config); + config_orig = gimp_config_duplicate (config); + + g_signal_connect_object (config, "notify", + G_CALLBACK (prefs_config_notify), + config_copy, 0); + g_signal_connect_object (config_copy, "notify", + G_CALLBACK (prefs_config_copy_notify), + config, 0); + + prefs_dialog = prefs_dialog_new (gimp, config_copy); + + g_object_add_weak_pointer (G_OBJECT (prefs_dialog), + (gpointer) &prefs_dialog); + + g_object_set_data (G_OBJECT (prefs_dialog), "gimp", gimp); + + g_object_set_data_full (G_OBJECT (prefs_dialog), "config-copy", config_copy, + (GDestroyNotify) g_object_unref); + g_object_set_data_full (G_OBJECT (prefs_dialog), "config-orig", config_orig, + (GDestroyNotify) g_object_unref); + + return prefs_dialog; +} + + +/* private functions */ + +static void +prefs_config_notify (GObject *config, + GParamSpec *param_spec, + GObject *config_copy) +{ + GValue global_value = G_VALUE_INIT; + GValue copy_value = G_VALUE_INIT; + + g_value_init (&global_value, param_spec->value_type); + g_value_init (©_value, param_spec->value_type); + + g_object_get_property (config, param_spec->name, &global_value); + g_object_get_property (config_copy, param_spec->name, ©_value); + + if (g_param_values_cmp (param_spec, &global_value, ©_value)) + { + g_signal_handlers_block_by_func (config_copy, + prefs_config_copy_notify, + config); + + g_object_set_property (config_copy, param_spec->name, &global_value); + + g_signal_handlers_unblock_by_func (config_copy, + prefs_config_copy_notify, + config); + } + + g_value_unset (&global_value); + g_value_unset (©_value); +} + +static void +prefs_config_copy_notify (GObject *config_copy, + GParamSpec *param_spec, + GObject *config) +{ + GValue copy_value = G_VALUE_INIT; + GValue global_value = G_VALUE_INIT; + + g_value_init (©_value, param_spec->value_type); + g_value_init (&global_value, param_spec->value_type); + + g_object_get_property (config_copy, param_spec->name, ©_value); + g_object_get_property (config, param_spec->name, &global_value); + + if (g_param_values_cmp (param_spec, ©_value, &global_value)) + { + if (param_spec->flags & GIMP_CONFIG_PARAM_CONFIRM) + { +#ifdef GIMP_CONFIG_DEBUG + g_print ("NOT Applying prefs change of '%s' to edit_config " + "because it needs confirmation\n", + param_spec->name); +#endif + } + else + { +#ifdef GIMP_CONFIG_DEBUG + g_print ("Applying prefs change of '%s' to edit_config\n", + param_spec->name); +#endif + g_signal_handlers_block_by_func (config, + prefs_config_notify, + config_copy); + + g_object_set_property (config, param_spec->name, ©_value); + + g_signal_handlers_unblock_by_func (config, + prefs_config_notify, + config_copy); + } + } + + g_value_unset (©_value); + g_value_unset (&global_value); +} + +static void +prefs_response (GtkWidget *widget, + gint response_id, + GtkWidget *dialog) +{ + Gimp *gimp = g_object_get_data (G_OBJECT (dialog), "gimp"); + + switch (response_id) + { + case RESPONSE_RESET: + { + GtkWidget *confirm; + + confirm = gimp_message_dialog_new (_("Reset All Preferences"), + GIMP_ICON_DIALOG_QUESTION, + dialog, + GTK_DIALOG_MODAL | + GTK_DIALOG_DESTROY_WITH_PARENT, + gimp_standard_help_func, NULL, + + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("_Reset"), GTK_RESPONSE_OK, + + NULL); + + gtk_dialog_set_alternative_button_order (GTK_DIALOG (confirm), + GTK_RESPONSE_OK, + GTK_RESPONSE_CANCEL, + -1); + + gimp_message_box_set_primary_text (GIMP_MESSAGE_DIALOG (confirm)->box, + _("Do you really want to reset all " + "preferences to default values?")); + + if (gimp_dialog_run (GIMP_DIALOG (confirm)) == GTK_RESPONSE_OK) + { + GimpConfig *config_copy; + + config_copy = g_object_get_data (G_OBJECT (dialog), "config-copy"); + + gimp_config_reset (config_copy); + gimp_rc_load_system (GIMP_RC (config_copy)); + + /* don't use the default value if there is no help browser */ + if (! gimp_help_browser_is_installed (gimp)) + { + g_object_set (config_copy, + "help-browser", GIMP_HELP_BROWSER_WEB_BROWSER, + NULL); + } + } + + gtk_widget_destroy (confirm); + + return; + } + break; + + case GTK_RESPONSE_OK: + { + GObject *config_copy; + GList *restart_diff; + GList *confirm_diff; + GList *list; + + config_copy = g_object_get_data (G_OBJECT (dialog), "config-copy"); + + /* destroy config_orig */ + g_object_set_data (G_OBJECT (dialog), "config-orig", NULL); + + gtk_widget_set_sensitive (GTK_WIDGET (dialog), FALSE); + + confirm_diff = gimp_config_diff (G_OBJECT (gimp->edit_config), + config_copy, + GIMP_CONFIG_PARAM_CONFIRM); + + g_object_freeze_notify (G_OBJECT (gimp->edit_config)); + + for (list = confirm_diff; list; list = g_list_next (list)) + { + GParamSpec *param_spec = list->data; + GValue value = G_VALUE_INIT; + + g_value_init (&value, param_spec->value_type); + + g_object_get_property (config_copy, + param_spec->name, &value); + g_object_set_property (G_OBJECT (gimp->edit_config), + param_spec->name, &value); + + g_value_unset (&value); + } + + g_object_thaw_notify (G_OBJECT (gimp->edit_config)); + + g_list_free (confirm_diff); + + gimp_rc_save (GIMP_RC (gimp->edit_config)); + + /* spit out a solely informational warning about changed values + * which need restart + */ + restart_diff = gimp_config_diff (G_OBJECT (gimp->edit_config), + G_OBJECT (gimp->config), + GIMP_CONFIG_PARAM_RESTART); + + if (restart_diff) + { + GString *string; + + string = g_string_new (_("You will have to restart GIMP for " + "the following changes to take effect:")); + g_string_append (string, "\n\n"); + + for (list = restart_diff; list; list = g_list_next (list)) + { + GParamSpec *param_spec = list->data; + + g_string_append_printf (string, "%s\n", param_spec->name); + } + + prefs_message (GTK_MESSAGE_INFO, FALSE, string->str); + + g_string_free (string, TRUE); + } + + g_list_free (restart_diff); + } + break; + + default: + { + GObject *config_orig; + GList *diff; + GList *list; + + config_orig = g_object_get_data (G_OBJECT (dialog), "config-orig"); + + /* destroy config_copy */ + g_object_set_data (G_OBJECT (dialog), "config-copy", NULL); + + gtk_widget_set_sensitive (GTK_WIDGET (dialog), FALSE); + + diff = gimp_config_diff (G_OBJECT (gimp->edit_config), + config_orig, + GIMP_CONFIG_PARAM_SERIALIZE); + + g_object_freeze_notify (G_OBJECT (gimp->edit_config)); + + for (list = diff; list; list = g_list_next (list)) + { + GParamSpec *param_spec = list->data; + GValue value = G_VALUE_INIT; + + g_value_init (&value, param_spec->value_type); + + g_object_get_property (config_orig, + param_spec->name, &value); + g_object_set_property (G_OBJECT (gimp->edit_config), + param_spec->name, &value); + + g_value_unset (&value); + } + + gimp_tool_editor_revert_changes (GIMP_TOOL_EDITOR (tool_editor)); + + g_object_thaw_notify (G_OBJECT (gimp->edit_config)); + + g_list_free (diff); + } + + tool_editor = NULL; + } + + /* enable autosaving again */ + gimp_rc_set_autosave (GIMP_RC (gimp->edit_config), TRUE); + + gtk_widget_destroy (dialog); +} + +static void +prefs_color_management_reset (GtkWidget *widget, + GObject *config) +{ + GimpCoreConfig *core_config = GIMP_CORE_CONFIG (config); + + gimp_config_reset (GIMP_CONFIG (core_config->color_management)); + gimp_config_reset_property (config, "color-profile-policy"); + gimp_config_reset_property (config, "filter-tool-show-color-options"); +} + +static void +prefs_dialog_defaults_reset (GtkWidget *widget, + GObject *config) +{ + GParamSpec **pspecs; + guint n_pspecs; + guint i; + + pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (config), + &n_pspecs); + + g_object_freeze_notify (config); + + for (i = 0; i < n_pspecs; i++) + { + GParamSpec *pspec = pspecs[i]; + + if (pspec->owner_type == GIMP_TYPE_DIALOG_CONFIG) + gimp_config_reset_property (config, pspec->name); + } + + gimp_config_reset_property (config, "filter-tool-max-recent"); + gimp_config_reset_property (config, "filter-tool-use-last-settings"); + gimp_config_reset_property (config, "filter-tool-show-color-options"); + + g_object_thaw_notify (config); + + g_free (pspecs); +} + +static void +prefs_folders_reset (GtkWidget *widget, + GObject *config) +{ + gimp_config_reset_property (config, "temp-path"); + gimp_config_reset_property (config, "swap-path"); +} + +static void +prefs_path_reset (GtkWidget *widget, + GObject *config) +{ + const gchar *path_property; + const gchar *writable_property; + + path_property = g_object_get_data (G_OBJECT (widget), "path"); + writable_property = g_object_get_data (G_OBJECT (widget), "path-writable"); + + gimp_config_reset_property (config, path_property); + + if (writable_property) + gimp_config_reset_property (config, writable_property); +} + +static void +prefs_template_select_callback (GimpContainerView *view, + GimpTemplate *template, + gpointer insert_data, + GimpTemplate *edit_template) +{ + if (template) + { + /* make sure the resolution values are copied first (see bug #546924) */ + gimp_config_sync (G_OBJECT (template), G_OBJECT (edit_template), + GIMP_TEMPLATE_PARAM_COPY_FIRST); + gimp_config_sync (G_OBJECT (template), G_OBJECT (edit_template), + 0); + } +} + +static void +prefs_import_raw_procedure_callback (GtkWidget *widget, + GObject *config) +{ + gchar *raw_plug_in; + + raw_plug_in = gimp_plug_in_view_get_plug_in (GIMP_PLUG_IN_VIEW (widget)); + + g_object_set (config, + "import-raw-plug-in", raw_plug_in, + NULL); + + g_free (raw_plug_in); +} + +static void +prefs_resolution_source_callback (GtkWidget *widget, + GObject *config) +{ + gdouble xres; + gdouble yres; + gboolean from_gdk; + + from_gdk = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); + + if (from_gdk) + { + gimp_get_monitor_resolution (gtk_widget_get_screen (widget), + gimp_widget_get_monitor (widget), + &xres, &yres); + } + else + { + GimpSizeEntry *entry = g_object_get_data (G_OBJECT (widget), + "monitor_resolution_sizeentry"); + + g_return_if_fail (GIMP_IS_SIZE_ENTRY (entry)); + + xres = gimp_size_entry_get_refval (entry, 0); + yres = gimp_size_entry_get_refval (entry, 1); + } + + g_object_set (config, + "monitor-xresolution", xres, + "monitor-yresolution", yres, + "monitor-resolution-from-windowing-system", from_gdk, + NULL); +} + +static void +prefs_resolution_calibrate_callback (GtkWidget *widget, + GtkWidget *entry) +{ + GtkWidget *dialog; + GtkWidget *prefs_box; + const gchar *icon_name; + + dialog = gtk_widget_get_toplevel (entry); + + prefs_box = g_object_get_data (G_OBJECT (dialog), "prefs-box"); + icon_name = gimp_prefs_box_get_current_icon_name (GIMP_PREFS_BOX (prefs_box)); + + resolution_calibrate_dialog (entry, icon_name); +} + +static void +prefs_input_devices_dialog (GtkWidget *widget, + Gimp *gimp) +{ + gimp_dialog_factory_dialog_raise (gimp_dialog_factory_get_singleton (), + gtk_widget_get_screen (widget), + gimp_widget_get_monitor (widget), + "gimp-input-devices-dialog", 0); +} + +static void +prefs_keyboard_shortcuts_dialog (GtkWidget *widget, + Gimp *gimp) +{ + gimp_dialog_factory_dialog_raise (gimp_dialog_factory_get_singleton (), + gtk_widget_get_screen (widget), + gimp_widget_get_monitor (widget), + "gimp-keyboard-shortcuts-dialog", 0); +} + +static void +prefs_menus_save_callback (GtkWidget *widget, + Gimp *gimp) +{ + GtkWidget *clear_button; + + menus_save (gimp, TRUE); + + clear_button = g_object_get_data (G_OBJECT (widget), "clear-button"); + + if (clear_button) + gtk_widget_set_sensitive (clear_button, TRUE); +} + +static void +prefs_menus_clear_callback (GtkWidget *widget, + Gimp *gimp) +{ + GError *error = NULL; + + if (! menus_clear (gimp, &error)) + { + prefs_message (GTK_MESSAGE_ERROR, TRUE, error->message); + g_clear_error (&error); + } + else + { + gtk_widget_set_sensitive (widget, FALSE); + + prefs_message (GTK_MESSAGE_INFO, TRUE, + _("Your keyboard shortcuts will be reset to " + "default values the next time you start GIMP.")); + } +} + +static void +prefs_menus_remove_callback (GtkWidget *widget, + Gimp *gimp) +{ + GtkWidget *dialog; + + dialog = gimp_message_dialog_new (_("Remove all Keyboard Shortcuts"), + GIMP_ICON_DIALOG_QUESTION, + gtk_widget_get_toplevel (widget), + GTK_DIALOG_MODAL | + GTK_DIALOG_DESTROY_WITH_PARENT, + gimp_standard_help_func, NULL, + + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("Cl_ear"), GTK_RESPONSE_OK, + + NULL); + + gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), + GTK_RESPONSE_OK, + GTK_RESPONSE_CANCEL, + -1); + + g_signal_connect_object (gtk_widget_get_toplevel (widget), "unmap", + G_CALLBACK (gtk_widget_destroy), + dialog, G_CONNECT_SWAPPED); + + gimp_message_box_set_primary_text (GIMP_MESSAGE_DIALOG (dialog)->box, + _("Do you really want to remove all " + "keyboard shortcuts from all menus?")); + + if (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK) + { + menus_remove (gimp); + } + + gtk_widget_destroy (dialog); +} + +static void +prefs_session_save_callback (GtkWidget *widget, + Gimp *gimp) +{ + GtkWidget *clear_button; + + session_save (gimp, TRUE); + + clear_button = g_object_get_data (G_OBJECT (widget), "clear-button"); + + if (clear_button) + gtk_widget_set_sensitive (clear_button, TRUE); +} + +static void +prefs_session_clear_callback (GtkWidget *widget, + Gimp *gimp) +{ + GError *error = NULL; + + if (! session_clear (gimp, &error)) + { + prefs_message (GTK_MESSAGE_ERROR, TRUE, error->message); + g_clear_error (&error); + } + else + { + gtk_widget_set_sensitive (widget, FALSE); + + prefs_message (GTK_MESSAGE_INFO, TRUE, + _("Your window setup will be reset to " + "default values the next time you start GIMP.")); + } +} + +static void +prefs_devices_save_callback (GtkWidget *widget, + Gimp *gimp) +{ + GtkWidget *clear_button; + + gimp_devices_save (gimp, TRUE); + + clear_button = g_object_get_data (G_OBJECT (widget), "clear-button"); + + if (clear_button) + gtk_widget_set_sensitive (clear_button, TRUE); +} + +static void +prefs_devices_clear_callback (GtkWidget *widget, + Gimp *gimp) +{ + GError *error = NULL; + + if (! gimp_devices_clear (gimp, &error)) + { + prefs_message (GTK_MESSAGE_ERROR, TRUE, error->message); + g_clear_error (&error); + } + else + { + gtk_widget_set_sensitive (widget, FALSE); + + prefs_message (GTK_MESSAGE_INFO, TRUE, + _("Your input device settings will be reset to " + "default values the next time you start GIMP.")); + } +} + +static void +prefs_search_clear_callback (GtkWidget *widget, + Gimp *gimp) +{ + gimp_action_history_clear (gimp); +} + +static void +prefs_tool_options_save_callback (GtkWidget *widget, + Gimp *gimp) +{ + GtkWidget *clear_button; + + gimp_tools_save (gimp, TRUE, TRUE); + + clear_button = g_object_get_data (G_OBJECT (widget), "clear-button"); + + if (clear_button) + gtk_widget_set_sensitive (clear_button, TRUE); +} + +static void +prefs_tool_options_clear_callback (GtkWidget *widget, + Gimp *gimp) +{ + GError *error = NULL; + + if (! gimp_tools_clear (gimp, &error)) + { + prefs_message (GTK_MESSAGE_ERROR, TRUE, error->message); + g_clear_error (&error); + } + else + { + gtk_widget_set_sensitive (widget, FALSE); + + prefs_message (GTK_MESSAGE_INFO, TRUE, + _("Your tool options will be reset to " + "default values the next time you start GIMP.")); + } +} + +static void +prefs_help_language_change_callback (GtkComboBox *combo, + Gimp *gimp) +{ + gchar *help_locales = NULL; + gchar *code; + + code = gimp_language_combo_box_get_code (GIMP_LANGUAGE_COMBO_BOX (combo)); + if (code && g_strcmp0 ("", code) != 0) + { + help_locales = g_strdup_printf ("%s:", code); + } + g_object_set (gimp->config, + "help-locales", help_locales? help_locales : "", + NULL); + g_free (code); + if (help_locales) + g_free (help_locales); +} + +static void +prefs_help_language_change_callback2 (GtkComboBox *combo, + GtkContainer *box) +{ + Gimp *gimp; + GtkLabel *label = NULL; + GtkImage *icon = NULL; + GList *children; + GList *iter; + const gchar *text; + const gchar *icon_name; + + gimp = g_object_get_data (G_OBJECT (box), "gimp"); + children = gtk_container_get_children (box); + for (iter = children; iter; iter = iter->next) + { + if (GTK_IS_LABEL (iter->data)) + { + label = iter->data; + } + else if (GTK_IS_IMAGE (iter->data)) + { + icon = iter->data; + } + } + if (gimp_help_user_manual_is_installed (gimp)) + { + text = _("There's a local installation of the user manual."); + icon_name = GIMP_ICON_DIALOG_INFORMATION; + } + else + { + text = _("The user manual is not installed locally."); + icon_name = GIMP_ICON_DIALOG_WARNING; + } + if (label) + { + gtk_label_set_text (label, text); + } + if (icon) + { + gtk_image_set_from_icon_name (icon, icon_name, + GTK_ICON_SIZE_BUTTON); + } + + g_list_free (children); +} + +static void +prefs_format_string_select_callback (GtkTreeSelection *sel, + GtkEntry *entry) +{ + GtkTreeModel *model; + GtkTreeIter iter; + + if (gtk_tree_selection_get_selected (sel, &model, &iter)) + { + GValue val = G_VALUE_INIT; + + gtk_tree_model_get_value (model, &iter, 1, &val); + gtk_entry_set_text (entry, g_value_get_string (&val)); + g_value_unset (&val); + } +} + +static void +prefs_theme_select_callback (GtkTreeSelection *sel, + Gimp *gimp) +{ + GtkTreeModel *model; + GtkTreeIter iter; + + if (gtk_tree_selection_get_selected (sel, &model, &iter)) + { + GValue val = G_VALUE_INIT; + + gtk_tree_model_get_value (model, &iter, 0, &val); + g_object_set_property (G_OBJECT (gimp->config), "theme", &val); + g_value_unset (&val); + } +} + +static void +prefs_theme_reload_callback (GtkWidget *button, + Gimp *gimp) +{ + g_object_notify (G_OBJECT (gimp->config), "theme"); +} + +static void +prefs_icon_theme_select_callback (GtkTreeSelection *sel, + Gimp *gimp) +{ + GtkTreeModel *model; + GtkTreeIter iter; + + if (gtk_tree_selection_get_selected (sel, &model, &iter)) + { + GValue val = G_VALUE_INIT; + + gtk_tree_model_get_value (model, &iter, 1, &val); + g_object_set_property (G_OBJECT (gimp->config), "icon-theme", &val); + g_value_unset (&val); + } +} + +static void +prefs_canvas_padding_color_changed (GtkWidget *button, + GtkWidget *combo) +{ + gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (combo), + GIMP_CANVAS_PADDING_MODE_CUSTOM); +} + +static void +prefs_display_options_frame_add (Gimp *gimp, + GObject *object, + const gchar *label, + GtkContainer *parent) +{ + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *checks_vbox; + GtkWidget *table; + GtkWidget *combo; + GtkWidget *button; + + vbox = prefs_frame_new (label, parent, FALSE); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + + checks_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2); + gtk_box_pack_start (GTK_BOX (hbox), checks_vbox, TRUE, TRUE, 0); + gtk_widget_show (checks_vbox); + + prefs_check_button_add (object, "show-selection", + _("Show s_election"), + GTK_BOX (checks_vbox)); + prefs_check_button_add (object, "show-layer-boundary", + _("Show _layer boundary"), + GTK_BOX (checks_vbox)); + prefs_check_button_add (object, "show-canvas-boundary", + _("Show can_vas boundary"), + GTK_BOX (checks_vbox)); + prefs_check_button_add (object, "show-guides", + _("Show _guides"), + GTK_BOX (checks_vbox)); + prefs_check_button_add (object, "show-grid", + _("Show gri_d"), + GTK_BOX (checks_vbox)); + prefs_check_button_add (object, "show-sample-points", + _("Show _sample points"), + GTK_BOX (checks_vbox)); + + checks_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2); + gtk_box_pack_start (GTK_BOX (hbox), checks_vbox, TRUE, TRUE, 0); + gtk_widget_show (checks_vbox); + +#ifndef GDK_WINDOWING_QUARTZ + prefs_check_button_add (object, "show-menubar", + _("Show _menubar"), + GTK_BOX (checks_vbox)); +#endif /* !GDK_WINDOWING_QUARTZ */ + prefs_check_button_add (object, "show-rulers", + _("Show _rulers"), + GTK_BOX (checks_vbox)); + prefs_check_button_add (object, "show-scrollbars", + _("Show scroll_bars"), + GTK_BOX (checks_vbox)); + prefs_check_button_add (object, "show-statusbar", + _("Show s_tatusbar"), + GTK_BOX (checks_vbox)); + + table = prefs_table_new (2, GTK_CONTAINER (vbox)); + + combo = prefs_enum_combo_box_add (object, "padding-mode", 0, 0, + _("Canvas _padding mode:"), + GTK_TABLE (table), 0, + NULL); + + button = prefs_color_button_add (object, "padding-color", + _("Custom p_adding color:"), + _("Select Custom Canvas Padding Color"), + GTK_TABLE (table), 1, NULL, + gimp_get_user_context (gimp)); + + g_signal_connect (button, "color-changed", + G_CALLBACK (prefs_canvas_padding_color_changed), + combo); + + prefs_check_button_add (object, "padding-in-show-all", + _("_Keep canvas padding in \"Show All\" mode"), + GTK_BOX (vbox)); +} + +static void +prefs_behavior_options_frame_add (Gimp *gimp, + GObject *object, + const gchar *label, + GtkContainer *parent) +{ + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *checks_vbox; + + vbox = prefs_frame_new (label, parent, FALSE); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + + checks_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2); + gtk_box_pack_start (GTK_BOX (hbox), checks_vbox, TRUE, TRUE, 0); + gtk_widget_show (checks_vbox); + + prefs_check_button_add (object, "snap-to-guides", + _("Snap to _Guides"), + GTK_BOX (checks_vbox)); + prefs_check_button_add (object, "snap-to-grid", + _("S_nap to Grid"), + GTK_BOX (checks_vbox)); + + checks_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2); + gtk_box_pack_start (GTK_BOX (hbox), checks_vbox, TRUE, TRUE, 0); + gtk_widget_show (checks_vbox); + + prefs_check_button_add (object, "snap-to-canvas", + _("Snap to Canvas _Edges"), + GTK_BOX (checks_vbox)); + prefs_check_button_add (object, "snap-to-path", + _("Snap to _Active Path"), + GTK_BOX (checks_vbox)); +} + +static void +prefs_help_func (const gchar *help_id, + gpointer help_data) +{ + GtkWidget *prefs_box; + + prefs_box = g_object_get_data (G_OBJECT (help_data), "prefs-box"); + + help_id = gimp_prefs_box_get_current_help_id (GIMP_PREFS_BOX (prefs_box)); + + gimp_standard_help_func (help_id, NULL); +} + +static void +prefs_message (GtkMessageType type, + gboolean destroy_with_parent, + const gchar *message) +{ + GtkWidget *dialog; + + dialog = gtk_message_dialog_new (GTK_WINDOW (prefs_dialog), + destroy_with_parent ? + GTK_DIALOG_DESTROY_WITH_PARENT : 0, + type, GTK_BUTTONS_OK, + "%s", message); + + gtk_dialog_run (GTK_DIALOG (dialog)); + + gtk_widget_destroy (dialog); +} + +static GtkWidget * +prefs_dialog_new (Gimp *gimp, + GimpConfig *config) +{ + GtkWidget *dialog; + GtkTreeIter top_iter; + GtkTreeIter child_iter; + + GtkWidget *prefs_box; + GtkSizeGroup *size_group = NULL; + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *vbox2; + GtkWidget *vbox3; + GtkWidget *button; + GtkWidget *button2; + GtkWidget *table; + GtkWidget *label; + GtkWidget *entry; + GtkWidget *calibrate_button; + GSList *group; + GtkWidget *separator; + GtkWidget *editor; + gint i; + + GObject *object; + GimpCoreConfig *core_config; + GimpDisplayConfig *display_config; + GList *manuals; + + g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL); + g_return_val_if_fail (GIMP_IS_CONFIG (config), NULL); + + object = G_OBJECT (config); + core_config = GIMP_CORE_CONFIG (config); + display_config = GIMP_DISPLAY_CONFIG (config); + + dialog = gimp_dialog_new (_("Preferences"), "gimp-preferences", + NULL, 0, + prefs_help_func, + GIMP_HELP_PREFS_DIALOG, + + _("_Reset"), RESPONSE_RESET, + _("_Cancel"), GTK_RESPONSE_CANCEL, + _("_OK"), GTK_RESPONSE_OK, + + NULL); + + gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), + RESPONSE_RESET, + GTK_RESPONSE_OK, + GTK_RESPONSE_CANCEL, + -1); + + g_signal_connect (dialog, "response", + G_CALLBACK (prefs_response), + dialog); + + /* The prefs box */ + prefs_box = gimp_prefs_box_new (); + gtk_container_set_border_width (GTK_CONTAINER (prefs_box), 12); + gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), + prefs_box, TRUE, TRUE, 0); + gtk_widget_show (prefs_box); + + g_object_set_data (G_OBJECT (dialog), "prefs-box", prefs_box); + + + /**********************/ + /* System Resources */ + /**********************/ + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + "gimp-prefs-system-resources", + _("System Resources"), + _("System Resources"), + GIMP_HELP_PREFS_SYSTEM_RESOURCES, + NULL, + &top_iter); + gimp_prefs_box_set_page_scrollable (GIMP_PREFS_BOX (prefs_box), vbox, TRUE); + + size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + + vbox2 = prefs_frame_new (_("Resource Consumption"), + GTK_CONTAINER (vbox), FALSE); + +#ifdef ENABLE_MP + table = prefs_table_new (6, GTK_CONTAINER (vbox2)); +#else + table = prefs_table_new (5, GTK_CONTAINER (vbox2)); +#endif /* ENABLE_MP */ + + prefs_spin_button_add (object, "undo-levels", 1.0, 5.0, 0, + _("Minimal number of _undo levels:"), + GTK_TABLE (table), 0, size_group); + prefs_memsize_entry_add (object, "undo-size", + _("Maximum undo _memory:"), + GTK_TABLE (table), 1, size_group); + prefs_memsize_entry_add (object, "tile-cache-size", + _("Tile cache _size:"), + GTK_TABLE (table), 2, size_group); + prefs_memsize_entry_add (object, "max-new-image-size", + _("Maximum _new image size:"), + GTK_TABLE (table), 3, size_group); + + prefs_compression_combo_box_add (object, "swap-compression", + _("S_wap compression:"), + GTK_TABLE (table), 4, size_group); + +#ifdef ENABLE_MP + prefs_spin_button_add (object, "num-processors", 1.0, 4.0, 0, + _("Number of _threads to use:"), + GTK_TABLE (table), 5, size_group); +#endif /* ENABLE_MP */ + + /* Internet access */ +#ifdef CHECK_UPDATE + if (gimp_version_check_update ()) + { + vbox2 = prefs_frame_new (_("Network access"), GTK_CONTAINER (vbox), + FALSE); + + prefs_check_button_add (object, "check-updates", + _("Check for updates (requires internet)"), + GTK_BOX (vbox2)); + } +#endif + + /* Image Thumbnails */ + vbox2 = prefs_frame_new (_("Image Thumbnails"), GTK_CONTAINER (vbox), FALSE); + + table = prefs_table_new (2, GTK_CONTAINER (vbox2)); + + prefs_enum_combo_box_add (object, "thumbnail-size", 0, 0, + _("Size of _thumbnails:"), + GTK_TABLE (table), 0, size_group); + + prefs_memsize_entry_add (object, "thumbnail-filesize-limit", + _("Maximum _filesize for thumbnailing:"), + GTK_TABLE (table), 1, size_group); + + /* Document History */ + vbox2 = prefs_frame_new (_("Document History"), GTK_CONTAINER (vbox), FALSE); + + prefs_check_button_add (object, "save-document-history", + _("_Keep record of used files in the Recent Documents list"), + GTK_BOX (vbox2)); + + g_clear_object (&size_group); + + + /***************/ + /* Debugging */ + /***************/ + /* No debugging preferences are needed on win32. Either GIMP has been + * built with DrMinGW support (HAVE_EXCHNDL) or not. If it has, then + * the backtracing is enabled and can't be disabled. It assume it will + * work only upon a crash. + */ +#ifndef G_OS_WIN32 + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + "gimp-wilber-eek", /* TODO: icon needed. */ + _("Debugging"), + _("Debugging"), + GIMP_HELP_PREFS_DEBUGGING, + NULL, + &top_iter); + + hbox = g_object_new (GIMP_TYPE_HINT_BOX, + "icon-name", GIMP_ICON_DIALOG_WARNING, + "hint", _("We hope you will never need these " + "settings, but as all software, GIMP " + "has bugs, and crashes can occur. If it " + "happens, you can help us by reporting " + "bugs."), + NULL); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + + vbox2 = prefs_frame_new (_("Bug Reporting"), + GTK_CONTAINER (vbox), FALSE); + + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + button = prefs_enum_combo_box_add (object, "debug-policy", 0, 0, + _("Debug _policy:"), + GTK_TABLE (table), 0, NULL); + + /* Check existence of gdb or lldb to activate the preference, as a + * good hint of its prerequisite, unless backtrace() API exists, in + * which case the feature is always available. + */ + hbox = NULL; + if (! gimp_stack_trace_available (TRUE)) + { +#ifndef HAVE_EXECINFO_H + hbox = prefs_hint_box_new (GIMP_ICON_DIALOG_WARNING, + _("This feature requires \"gdb\" or \"lldb\" installed on your system.")); + gtk_widget_set_sensitive (button, FALSE); +#else + hbox = prefs_hint_box_new (GIMP_ICON_DIALOG_WARNING, + _("This feature is more efficient with \"gdb\" or \"lldb\" installed on your system.")); +#endif /* ! HAVE_EXECINFO_H */ + } + if (hbox) + gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0); + +#endif /* ! G_OS_WIN32 */ + + /**********************/ + /* Color Management */ + /**********************/ + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + "gimp-prefs-color-management", + _("Color Management"), + _("Color Management"), + GIMP_HELP_PREFS_COLOR_MANAGEMENT, + NULL, + &top_iter); + + gimp_prefs_box_set_page_scrollable (GIMP_PREFS_BOX (prefs_box), vbox, TRUE); + + button = gimp_prefs_box_set_page_resettable (GIMP_PREFS_BOX (prefs_box), + vbox, + _("R_eset Color Management")); + g_signal_connect (button, "clicked", + G_CALLBACK (prefs_color_management_reset), + config); + + { + GObject *color_config = G_OBJECT (core_config->color_management); + GtkListStore *store; + gchar *filename; + gint row = 0; + + filename = gimp_personal_rc_file ("profilerc"); + store = gimp_color_profile_store_new (filename); + g_free (filename); + + gimp_color_profile_store_add_file (GIMP_COLOR_PROFILE_STORE (store), + NULL, NULL); + + size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + + table = prefs_table_new (1, GTK_CONTAINER (vbox)); + + prefs_enum_combo_box_add (color_config, "mode", 0, 0, + _("Image display _mode:"), + GTK_TABLE (table), row++, NULL); + + /* Color Managed Display */ + vbox2 = prefs_frame_new (_("Color Managed Display"), GTK_CONTAINER (vbox), + FALSE); + + table = prefs_table_new (4, GTK_CONTAINER (vbox2)); + row = 0; + + prefs_profile_combo_box_add (color_config, + "display-profile", + store, + _("Select Monitor Color Profile"), + _("_Monitor profile:"), + GTK_TABLE (table), row++, size_group, + object, "color-profile-path"); + + button = gimp_prop_check_button_new (color_config, + "display-profile-from-gdk", + _("_Try to use the system monitor " + "profile")); + gtk_table_attach_defaults (GTK_TABLE (table), + button, 1, 2, row, row + 1); + gtk_widget_show (button); + row++; + + prefs_enum_combo_box_add (color_config, + "display-rendering-intent", 0, 0, + _("_Rendering intent:"), + GTK_TABLE (table), row++, size_group); + + button = gimp_prop_check_button_new (color_config, + "display-use-black-point-compensation", + _("Use _black point compensation")); + gtk_table_attach_defaults (GTK_TABLE (table), + button, 1, 2, row, row + 1); + gtk_widget_show (button); + row++; + + prefs_boolean_combo_box_add (color_config, + "display-optimize", + _("Speed"), + _("Precision / Color Fidelity"), + _("_Optimize image display for:"), + GTK_TABLE (table), row++, size_group); + + /* Print Simulation (Soft-proofing) */ + vbox2 = prefs_frame_new (_("Soft-Proofing"), + GTK_CONTAINER (vbox), + FALSE); + + table = prefs_table_new (4, GTK_CONTAINER (vbox2)); + row = 0; + + prefs_profile_combo_box_add (color_config, + "printer-profile", + store, + _("Select Soft-Proofing Color Profile"), + _("_Soft-proofing profile:"), + GTK_TABLE (table), row++, size_group, + object, "color-profile-path"); + + prefs_enum_combo_box_add (color_config, + "simulation-rendering-intent", 0, 0, + _("Re_ndering intent:"), + GTK_TABLE (table), row++, size_group); + + button = gimp_prop_check_button_new (color_config, + "simulation-use-black-point-compensation", + _("Use black _point compensation")); + gtk_table_attach_defaults (GTK_TABLE (table), + button, 1, 2, row, row + 1); + gtk_widget_show (button); + row++; + + prefs_boolean_combo_box_add (color_config, + "simulation-optimize", + _("Speed"), + _("Precision / Color Fidelity"), + _("O_ptimize soft-proofing for:"), + GTK_TABLE (table), row++, size_group); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_table_attach_defaults (GTK_TABLE (table), hbox, 1, 2, row, row + 1); + gtk_widget_show (hbox); + row++; + + button = gimp_prop_check_button_new (color_config, "simulation-gamut-check", + _("Mar_k out of gamut colors")); + gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); + gtk_widget_show (button); + + button = gimp_prop_color_button_new (color_config, "out-of-gamut-color", + _("Select Warning Color"), + PREFS_COLOR_BUTTON_WIDTH, + PREFS_COLOR_BUTTON_HEIGHT, + GIMP_COLOR_AREA_FLAT); + gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); + gtk_widget_show (button); + + gimp_color_panel_set_context (GIMP_COLOR_PANEL (button), + gimp_get_user_context (gimp)); + + /* Preferred profiles */ + vbox2 = prefs_frame_new (_("Preferred Profiles"), GTK_CONTAINER (vbox), + FALSE); + + table = prefs_table_new (3, GTK_CONTAINER (vbox2)); + row = 0; + + prefs_profile_combo_box_add (color_config, + "rgb-profile", + store, + _("Select Preferred RGB Color Profile"), + _("_RGB profile:"), + GTK_TABLE (table), row++, size_group, + object, "color-profile-path"); + + prefs_profile_combo_box_add (color_config, + "gray-profile", + store, + _("Select Preferred Grayscale Color Profile"), + _("_Grayscale profile:"), + GTK_TABLE (table), row++, size_group, + object, "color-profile-path"); + + prefs_profile_combo_box_add (color_config, + "cmyk-profile", + store, + _("Select CMYK Color Profile"), + _("_CMYK profile:"), + GTK_TABLE (table), row++, size_group, + object, "color-profile-path"); + + /* Policies */ + vbox2 = prefs_frame_new (_("Policies"), GTK_CONTAINER (vbox), + FALSE); + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + button = prefs_enum_combo_box_add (object, "color-profile-policy", 0, 0, + _("_File Open behaviour:"), + GTK_TABLE (table), 0, size_group); + + /* Filter Dialogs */ + vbox2 = prefs_frame_new (_("Filter Dialogs"), GTK_CONTAINER (vbox), + FALSE); + + button = prefs_check_button_add (object, "filter-tool-show-color-options", + _("Show _advanced color options"), + GTK_BOX (vbox2)); + + g_clear_object (&size_group); + + g_object_unref (store); + } + + + /***************************/ + /* Image Import / Export */ + /***************************/ + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + "gimp-prefs-import-export", + _("Image Import & Export"), + _("Image Import & Export"), + GIMP_HELP_PREFS_IMPORT_EXPORT, + NULL, + &top_iter); + + gimp_prefs_box_set_page_scrollable (GIMP_PREFS_BOX (prefs_box), vbox, TRUE); + + size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + + /* Import Policies */ + vbox2 = prefs_frame_new (_("Import Policies"), + GTK_CONTAINER (vbox), FALSE); + + button = prefs_check_button_add (object, "import-promote-float", + _("Promote imported images to " + "_floating point precision"), + GTK_BOX (vbox2)); + + vbox3 = prefs_frame_new (NULL, GTK_CONTAINER (vbox2), FALSE); + g_object_bind_property (button, "active", + vbox3, "sensitive", + G_BINDING_SYNC_CREATE); + button = prefs_check_button_add (object, "import-promote-dither", + _("_Dither images when promoting to " + "floating point"), + GTK_BOX (vbox3)); + + button = prefs_check_button_add (object, "import-add-alpha", + _("_Add an alpha channel to imported images"), + GTK_BOX (vbox2)); + + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + button = prefs_enum_combo_box_add (object, "color-profile-policy", 0, 0, + _("Color _profile policy:"), + GTK_TABLE (table), 0, size_group); + + /* Export Policies */ + vbox2 = prefs_frame_new (_("Export Policies"), + GTK_CONTAINER (vbox), FALSE); + + button = prefs_check_button_add (object, "export-color-profile", + _("Export the i_mage's color profile by default"), + GTK_BOX (vbox2)); + button = prefs_check_button_add (object, "export-metadata-exif", + /* Translators: label for + * configuration option (checkbox). + * It determines how file export + * plug-ins handle Exif by default. + */ + _("Export _Exif metadata by default when available"), + GTK_BOX (vbox2)); + button = prefs_check_button_add (object, "export-metadata-xmp", + /* Translators: label for + * configuration option (checkbox). + * It determines how file export + * plug-ins handle XMP by default. + */ + _("Export _XMP metadata by default when available"), + GTK_BOX (vbox2)); + button = prefs_check_button_add (object, "export-metadata-iptc", + /* Translators: label for + * configuration option (checkbox). + * It determines how file export + * plug-ins handle IPTC by default. + */ + _("Export _IPTC metadata by default when available"), + GTK_BOX (vbox2)); + hbox = prefs_hint_box_new (GIMP_ICON_DIALOG_WARNING, + _("Metadata can contain sensitive information.")); + gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0); + + /* Export File Type */ + vbox2 = prefs_frame_new (_("Export File Type"), GTK_CONTAINER (vbox), FALSE); + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + prefs_enum_combo_box_add (object, "export-file-type", 0, 0, + _("Default export file t_ype:"), + GTK_TABLE (table), 0, size_group); + + /* Raw Image Importer */ + vbox2 = prefs_frame_new (_("Raw Image Importer"), + GTK_CONTAINER (vbox), TRUE); + + { + GtkWidget *scrolled_window; + GtkWidget *view; + + scrolled_window = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), + GTK_SHADOW_IN); + gtk_box_pack_start (GTK_BOX (vbox2), scrolled_window, TRUE, TRUE, 0); + gtk_widget_show (scrolled_window); + + view = gimp_plug_in_view_new (gimp->plug_in_manager->display_raw_load_procs); + gimp_plug_in_view_set_plug_in (GIMP_PLUG_IN_VIEW (view), + core_config->import_raw_plug_in); + gtk_container_add (GTK_CONTAINER (scrolled_window), view); + gtk_widget_show (view); + + g_signal_connect (view, "changed", + G_CALLBACK (prefs_import_raw_procedure_callback), + config); + } + + g_clear_object (&size_group); + + + /****************/ + /* Playground */ + /****************/ + if (gimp->show_playground) + { + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + "gimp-prefs-playground", + _("Experimental Playground"), + _("Playground"), + GIMP_HELP_PREFS_PLAYGROUND, + NULL, + &top_iter); + + hbox = g_object_new (GIMP_TYPE_HINT_BOX, + "icon-name", GIMP_ICON_DIALOG_WARNING, + "hint", _("These features are unfinished, buggy " + "and may crash GIMP. It is unadvised to " + "use them unless you really know what " + "you are doing or you intend to contribute " + "patches."), + NULL); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + + /* Hardware Acceleration */ + vbox2 = prefs_frame_new (_("Hardware Acceleration"), GTK_CONTAINER (vbox), + FALSE); + + hbox = prefs_hint_box_new (GIMP_ICON_DIALOG_WARNING, + _("OpenCL drivers and support are experimental, " + "expect slowdowns and possible crashes " + "(please report).")); + gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0); + + prefs_check_button_add (object, "use-opencl", + _("Use O_penCL"), + GTK_BOX (vbox2)); + + /* Very unstable tools */ + vbox2 = prefs_frame_new (_("Insane Options"), + GTK_CONTAINER (vbox), FALSE); + + button = prefs_check_button_add (object, "playground-npd-tool", + _("_N-Point Deformation tool"), + GTK_BOX (vbox2)); + button = prefs_check_button_add (object, "playground-seamless-clone-tool", + _("_Seamless Clone tool"), + GTK_BOX (vbox2)); + } + + + /******************/ + /* Tool Options */ + /******************/ + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + "gimp-prefs-tool-options", + C_("preferences", "Tool Options"), + C_("preferences", "Tool Options"), + GIMP_HELP_PREFS_TOOL_OPTIONS, + NULL, + &top_iter); + gimp_prefs_box_set_page_scrollable (GIMP_PREFS_BOX (prefs_box), vbox, TRUE); + + size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + + /* General */ + vbox2 = prefs_frame_new (_("General"), GTK_CONTAINER (vbox), FALSE); + + prefs_check_button_add (object, "edit-non-visible", + _("Allow _editing on non-visible layers"), + GTK_BOX (vbox2)); + + prefs_check_button_add (object, "save-tool-options", + _("_Save tool options on exit"), + GTK_BOX (vbox2)); + + button = prefs_button_add (GIMP_ICON_DOCUMENT_SAVE, + _("Save Tool Options _Now"), + GTK_BOX (vbox2)); + g_signal_connect (button, "clicked", + G_CALLBACK (prefs_tool_options_save_callback), + gimp); + + button2 = prefs_button_add (GIMP_ICON_RESET, + _("_Reset Saved Tool Options to " + "Default Values"), + GTK_BOX (vbox2)); + g_signal_connect (button2, "clicked", + G_CALLBACK (prefs_tool_options_clear_callback), + gimp); + + g_object_set_data (G_OBJECT (button), "clear-button", button2); + + /* Scaling */ + vbox2 = prefs_frame_new (_("Scaling"), GTK_CONTAINER (vbox), FALSE); + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + prefs_enum_combo_box_add (object, "interpolation-type", 0, 0, + _("Default _interpolation:"), + GTK_TABLE (table), 0, size_group); + + g_object_unref (size_group); + + size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + + /* Global Brush, Pattern, ... */ + vbox2 = prefs_frame_new (_("Paint Options Shared Between Tools"), + GTK_CONTAINER (vbox), FALSE); + + prefs_check_button_add_with_icon (object, "global-brush", + _("_Brush"), GIMP_ICON_BRUSH, + GTK_BOX (vbox2), size_group); + prefs_check_button_add_with_icon (object, "global-dynamics", + _("_Dynamics"), GIMP_ICON_DYNAMICS, + GTK_BOX (vbox2), size_group); + prefs_check_button_add_with_icon (object, "global-pattern", + _("_Pattern"), GIMP_ICON_PATTERN, + GTK_BOX (vbox2), size_group); + prefs_check_button_add_with_icon (object, "global-gradient", + _("_Gradient"), GIMP_ICON_GRADIENT, + GTK_BOX (vbox2), size_group); + + /* Move Tool */ + vbox2 = prefs_frame_new (_("Move Tool"), + GTK_CONTAINER (vbox), FALSE); + + prefs_check_button_add_with_icon (object, "move-tool-changes-active", + _("Set _layer or path as active"), + GIMP_ICON_TOOL_MOVE, + GTK_BOX (vbox2), size_group); + + g_clear_object (&size_group); + + + /*******************/ + /* Default Image */ + /*******************/ + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + "gimp-prefs-new-image", + _("Default New Image"), + _("Default Image"), + GIMP_HELP_PREFS_NEW_IMAGE, + NULL, + &top_iter); + + gimp_prefs_box_set_page_scrollable (GIMP_PREFS_BOX (prefs_box), vbox, TRUE); + + table = prefs_table_new (1, GTK_CONTAINER (vbox)); + + { + GtkWidget *combo; + + combo = gimp_container_combo_box_new (gimp->templates, + gimp_get_user_context (gimp), + 16, 0); + gimp_table_attach_aligned (GTK_TABLE (table), 0, 0, + _("_Template:"), 0.0, 0.5, + combo, 1, FALSE); + + gimp_container_view_select_item (GIMP_CONTAINER_VIEW (combo), NULL); + + g_signal_connect (combo, "select-item", + G_CALLBACK (prefs_template_select_callback), + core_config->default_image); + } + + editor = gimp_template_editor_new (core_config->default_image, gimp, FALSE); + gimp_template_editor_show_advanced (GIMP_TEMPLATE_EDITOR (editor), TRUE); + gtk_box_pack_start (GTK_BOX (vbox), editor, FALSE, FALSE, 0); + gtk_widget_show (editor); + + /* Quick Mask Color */ + vbox2 = prefs_frame_new (_("Quick Mask"), GTK_CONTAINER (vbox), FALSE); + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + prefs_color_button_add (object, "quick-mask-color", + _("Quick Mask color:"), + _("Set the default Quick Mask color"), + GTK_TABLE (table), 0, NULL, + gimp_get_user_context (gimp)); + + + /**********************************/ + /* Default Image / Default Grid */ + /**********************************/ + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + "gimp-prefs-default-grid", + _("Default Image Grid"), + _("Default Grid"), + GIMP_HELP_PREFS_DEFAULT_GRID, + &top_iter, + &child_iter); + gimp_prefs_box_set_page_scrollable (GIMP_PREFS_BOX (prefs_box), vbox, TRUE); + + /* Grid */ + editor = gimp_grid_editor_new (core_config->default_grid, + gimp_get_user_context (gimp), + gimp_template_get_resolution_x (core_config->default_image), + gimp_template_get_resolution_y (core_config->default_image)); + gtk_box_pack_start (GTK_BOX (vbox), editor, TRUE, TRUE, 0); + gtk_widget_show (editor); + + + /***************/ + /* Interface */ + /***************/ + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + "gimp-prefs-interface", + _("User Interface"), + _("Interface"), + GIMP_HELP_PREFS_INTERFACE, + NULL, + &top_iter); + gimp_prefs_box_set_page_scrollable (GIMP_PREFS_BOX (prefs_box), vbox, TRUE); + + /* Language */ + + /* Only add the language entry if the iso-codes package is available. */ +#ifdef HAVE_ISO_CODES + vbox2 = prefs_frame_new (_("Language"), GTK_CONTAINER (vbox), FALSE); + + prefs_language_combo_box_add (object, "language", GTK_BOX (vbox2)); +#endif + + /* Style */ + vbox2 = prefs_frame_new (_("Style"), GTK_CONTAINER (vbox), FALSE); + + button = prefs_check_button_add (object, "compact-sliders", + _("Use co_mpact sliders"), + GTK_BOX (vbox2)); + + /* Previews */ + vbox2 = prefs_frame_new (_("Previews"), GTK_CONTAINER (vbox), FALSE); + + button = prefs_check_button_add (object, "layer-previews", + _("_Enable layer & channel previews"), + GTK_BOX (vbox2)); + + vbox3 = prefs_frame_new (NULL, GTK_CONTAINER (vbox2), FALSE); + g_object_bind_property (button, "active", + vbox3, "sensitive", + G_BINDING_SYNC_CREATE); + button = prefs_check_button_add (object, "group-layer-previews", + _("Enable layer _group previews"), + GTK_BOX (vbox3)); + + table = prefs_table_new (3, GTK_CONTAINER (vbox2)); + + prefs_enum_combo_box_add (object, "layer-preview-size", 0, 0, + _("_Default layer & channel preview size:"), + GTK_TABLE (table), 0, NULL); + prefs_enum_combo_box_add (object, "undo-preview-size", 0, 0, + _("_Undo preview size:"), + GTK_TABLE (table), 1, NULL); + prefs_enum_combo_box_add (object, "navigation-preview-size", 0, 0, + _("Na_vigation preview size:"), + GTK_TABLE (table), 2, NULL); + + /* Keyboard Shortcuts */ + vbox2 = prefs_frame_new (_("Keyboard Shortcuts"), + GTK_CONTAINER (vbox), FALSE); + + prefs_check_button_add (object, "can-change-accels", + _("_Use dynamic keyboard shortcuts"), + GTK_BOX (vbox2)); + + button = prefs_button_add (GIMP_ICON_PREFERENCES_SYSTEM, + _("Configure _Keyboard Shortcuts..."), + GTK_BOX (vbox2)); + g_signal_connect (button, "clicked", + G_CALLBACK (prefs_keyboard_shortcuts_dialog), + gimp); + + prefs_check_button_add (object, "save-accels", + _("_Save keyboard shortcuts on exit"), + GTK_BOX (vbox2)); + + button = prefs_button_add (GIMP_ICON_DOCUMENT_SAVE, + _("Save Keyboard Shortcuts _Now"), + GTK_BOX (vbox2)); + g_signal_connect (button, "clicked", + G_CALLBACK (prefs_menus_save_callback), + gimp); + + button2 = prefs_button_add (GIMP_ICON_RESET, + _("_Reset Keyboard Shortcuts to Default Values"), + GTK_BOX (vbox2)); + g_signal_connect (button2, "clicked", + G_CALLBACK (prefs_menus_clear_callback), + gimp); + + g_object_set_data (G_OBJECT (button), "clear-button", button2); + + button = prefs_button_add (GIMP_ICON_EDIT_CLEAR, + _("Remove _All Keyboard Shortcuts"), + GTK_BOX (vbox2)); + g_signal_connect (button, "clicked", + G_CALLBACK (prefs_menus_remove_callback), + gimp); + + + /***********************/ + /* Interface / Theme */ + /***********************/ + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + "gimp-prefs-theme", + _("Theme"), + _("Theme"), + GIMP_HELP_PREFS_THEME, + &top_iter, + &child_iter); + + vbox2 = prefs_frame_new (_("Select Theme"), GTK_CONTAINER (vbox), TRUE); + + { + 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); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), + GTK_SHADOW_IN); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_box_pack_start (GTK_BOX (vbox2), scrolled_win, TRUE, TRUE, 0); + gtk_widget_show (scrolled_win); + + 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_container_add (GTK_CONTAINER (scrolled_win), view); + gtk_widget_show (view); + + g_object_unref (list_store); + + 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)); + + themes = themes_list_themes (gimp, &n_themes); + + for (i = 0; i < n_themes; i++) + { + GtkTreeIter iter; + GFile *theme_dir = themes_get_theme_dir (gimp, themes[i]); + + gtk_list_store_append (list_store, &iter); + gtk_list_store_set (list_store, &iter, + 0, themes[i], + 1, gimp_file_get_utf8_name (theme_dir), + -1); + + if (GIMP_GUI_CONFIG (object)->theme && + ! strcmp (GIMP_GUI_CONFIG (object)->theme, themes[i])) + { + GtkTreePath *path; + + path = gtk_tree_model_get_path (GTK_TREE_MODEL (list_store), &iter); + + gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE); + gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (view), path, + NULL, FALSE, 0.0, 0.0); + + gtk_tree_path_free (path); + } + } + + g_strfreev (themes); + + g_signal_connect (sel, "changed", + G_CALLBACK (prefs_theme_select_callback), + gimp); + } + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + + button = prefs_button_add (GIMP_ICON_VIEW_REFRESH, + _("Reload C_urrent Theme"), + GTK_BOX (hbox)); + g_signal_connect (button, "clicked", + G_CALLBACK (prefs_theme_reload_callback), + gimp); + + + /****************************/ + /* Interface / Icon Theme */ + /****************************/ + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + "gimp-prefs-icon-theme", + _("Icon Theme"), + _("Icon Theme"), + GIMP_HELP_PREFS_ICON_THEME, + &top_iter, + &child_iter); + + vbox2 = prefs_frame_new (_("Select an Icon Theme"), GTK_CONTAINER (vbox), TRUE); + + { + GtkWidget *scrolled_win; + GtkWidget *icon_size_scale; + GtkListStore *list_store; + GtkWidget *view; + GtkTreeSelection *sel; + gchar **icon_themes; + gint n_icon_themes; + gint i; + + scrolled_win = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_set_size_request (scrolled_win, -1, 80); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), + GTK_SHADOW_IN); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_box_pack_start (GTK_BOX (vbox2), scrolled_win, TRUE, TRUE, 0); + gtk_widget_show (scrolled_win); + + list_store = gtk_list_store_new (3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING); + + view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store)); + gtk_container_add (GTK_CONTAINER (scrolled_win), view); + gtk_widget_show (view); + + g_object_unref (list_store); + + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), 0, + NULL, + gtk_cell_renderer_pixbuf_new (), + "pixbuf", 0, + NULL); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), 1, + _("Icon Theme"), + gtk_cell_renderer_text_new (), + "text", 1, + NULL); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (view), 2, + _("Folder"), + gtk_cell_renderer_text_new (), + "text", 2, + NULL); + + sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); + + icon_themes = icon_themes_list_themes (gimp, &n_icon_themes); + + for (i = 0; i < n_icon_themes; i++) + { + GtkTreeIter iter; + GFile *icon_theme_dir = icon_themes_get_theme_dir (gimp, icon_themes[i]); + GFile *icon_theme_search_path = g_file_get_parent (icon_theme_dir); + GtkIconTheme *theme; + gchar *example; + GdkPixbuf *pixbuf; + + theme = gtk_icon_theme_new (); + gtk_icon_theme_prepend_search_path (theme, gimp_file_get_utf8_name(icon_theme_search_path)); + g_object_unref (icon_theme_search_path); + gtk_icon_theme_set_custom_theme (theme, icon_themes[i]); + + example = gtk_icon_theme_get_example_icon_name (theme); + if (! example) + { + /* If the icon theme didn't explicitly specify an example + * icon, try "gimp-wilber". + */ + example = g_strdup ("gimp-wilber"); + } + pixbuf = gtk_icon_theme_load_icon (theme, example, 16, 0, NULL); + + gtk_list_store_append (list_store, &iter); + gtk_list_store_set (list_store, &iter, + 0, pixbuf, + 1, icon_themes[i], + 2, gimp_file_get_utf8_name (icon_theme_dir), + -1); + g_object_unref (theme); + g_object_unref (pixbuf); + g_free (example); + + if (GIMP_GUI_CONFIG (object)->icon_theme && + ! strcmp (GIMP_GUI_CONFIG (object)->icon_theme, icon_themes[i])) + { + GtkTreePath *path; + + path = gtk_tree_model_get_path (GTK_TREE_MODEL (list_store), &iter); + + gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE); + gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (view), path, + NULL, FALSE, 0.0, 0.0); + + gtk_tree_path_free (path); + } + } + + g_strfreev (icon_themes); + + g_signal_connect (sel, "changed", + G_CALLBACK (prefs_icon_theme_select_callback), + gimp); + + icon_size_scale = gimp_icon_size_scale_new (gimp); + gtk_box_pack_start (GTK_BOX (vbox), icon_size_scale, FALSE, FALSE, 0); + gtk_widget_show (icon_size_scale); + } + + + /*************************/ + /* Interface / Toolbox */ + /*************************/ + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + "gimp-prefs-toolbox", + _("Toolbox"), + _("Toolbox"), + GIMP_HELP_PREFS_TOOLBOX, + &top_iter, + &child_iter); + + size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + + /* Appearance */ + vbox2 = prefs_frame_new (_("Appearance"), + GTK_CONTAINER (vbox), FALSE); + + prefs_check_button_add_with_icon (object, "toolbox-wilber", + _("Show GIMP _logo (drag-and-drop target)"), + GIMP_ICON_WILBER, + GTK_BOX (vbox2), size_group); + prefs_check_button_add_with_icon (object, "toolbox-color-area", + _("Show _foreground & background color"), + GIMP_ICON_COLORS_DEFAULT, + GTK_BOX (vbox2), size_group); + prefs_check_button_add_with_icon (object, "toolbox-foo-area", + _("Show active _brush, pattern & gradient"), + GIMP_ICON_BRUSH, + GTK_BOX (vbox2), size_group); + prefs_check_button_add_with_icon (object, "toolbox-image-area", + _("Show active _image"), + GIMP_ICON_IMAGE, + GTK_BOX (vbox2), size_group); + + separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL); + gtk_box_pack_start (GTK_BOX (vbox2), separator, FALSE, FALSE, 0); + gtk_widget_show (separator); + + button = prefs_check_button_add_with_icon (object, "toolbox-groups", + _("Use tool _groups"), + NULL, + GTK_BOX (vbox2), size_group); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); + gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + + label = gtk_label_new (NULL); + gtk_misc_set_padding (GTK_MISC (label), 2, 2); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + gtk_widget_show (label); + + gtk_size_group_add_widget (size_group, label); + + vbox3 = prefs_frame_new (NULL, GTK_CONTAINER (hbox), TRUE); + g_object_bind_property (button, "active", + vbox3, "sensitive", + G_BINDING_SYNC_CREATE); + + table = prefs_table_new (1, GTK_CONTAINER (vbox3)); + + prefs_enum_combo_box_add (object, "toolbox-group-menu-mode", 0, 0, + _("_Menu mode:"), + GTK_TABLE (table), 0, + NULL); + + g_clear_object (&size_group); + + /* Tool Editor */ + vbox2 = prefs_frame_new (_("Tools Configuration"), + GTK_CONTAINER (vbox), TRUE); + tool_editor = gimp_tool_editor_new (gimp->tool_item_list, gimp->user_context, + GIMP_VIEW_SIZE_SMALL, 1); + + gtk_box_pack_start (GTK_BOX (vbox2), tool_editor, TRUE, TRUE, 0); + gtk_widget_show (tool_editor); + + + /*********************************/ + /* Interface / Dialog Defaults */ + /*********************************/ + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + /* FIXME need an icon */ + "gimp-prefs-controllers", + _("Dialog Defaults"), + _("Dialog Defaults"), + GIMP_HELP_PREFS_DIALOG_DEFAULTS, + &top_iter, + &child_iter); + + gimp_prefs_box_set_page_scrollable (GIMP_PREFS_BOX (prefs_box), vbox, TRUE); + + button = gimp_prefs_box_set_page_resettable (GIMP_PREFS_BOX (prefs_box), + vbox, + _("Reset Dialog _Defaults")); + g_signal_connect (button, "clicked", + G_CALLBACK (prefs_dialog_defaults_reset), + config); + + size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + + /* Color profile import dialog */ + vbox2 = prefs_frame_new (_("Color Profile Import Dialog"), GTK_CONTAINER (vbox), + FALSE); + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + button = prefs_enum_combo_box_add (object, "color-profile-policy", 0, 0, + _("Color profile policy:"), + GTK_TABLE (table), 0, size_group); + + /* All color profile chooser dialogs */ + vbox2 = prefs_frame_new (_("Color Profile File Dialogs"), GTK_CONTAINER (vbox), + FALSE); + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + prefs_file_chooser_button_add (object, "color-profile-path", + _("Profile folder:"), + _("Select Default Folder for Color Profiles"), + GTK_TABLE (table), 0, size_group); + + /* Convert to Color Profile Dialog */ + vbox2 = prefs_frame_new (_("Convert to Color Profile Dialog"), + GTK_CONTAINER (vbox), FALSE); + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + prefs_enum_combo_box_add (object, "image-convert-profile-intent", 0, 0, + _("Rendering intent:"), + GTK_TABLE (table), 0, size_group); + + prefs_check_button_add (object, "image-convert-profile-black-point-compensation", + _("Black point compensation"), + GTK_BOX (vbox2)); + + /* Convert Precision Dialog */ + vbox2 = prefs_frame_new (_("Precision Conversion Dialog"), + GTK_CONTAINER (vbox), FALSE); + table = prefs_table_new (3, GTK_CONTAINER (vbox2)); + + prefs_enum_combo_box_add (object, + "image-convert-precision-layer-dither-method", + 0, 0, + _("Dither layers:"), + GTK_TABLE (table), 0, size_group); + prefs_enum_combo_box_add (object, + "image-convert-precision-text-layer-dither-method", + 0, 0, + _("Dither text layers:"), + GTK_TABLE (table), 1, size_group); + prefs_enum_combo_box_add (object, + "image-convert-precision-channel-dither-method", + 0, 0, + _("Dither channels/masks:"), + GTK_TABLE (table), 2, size_group); + + /* Convert Indexed Dialog */ + vbox2 = prefs_frame_new (_("Indexed Conversion Dialog"), + GTK_CONTAINER (vbox), FALSE); + table = prefs_table_new (2, GTK_CONTAINER (vbox2)); + + prefs_enum_combo_box_add (object, "image-convert-indexed-palette-type", 0, 0, + _("Colormap:"), + GTK_TABLE (table), 0, size_group); + prefs_spin_button_add (object, "image-convert-indexed-max-colors", 1.0, 8.0, 0, + _("Maximum number of colors:"), + GTK_TABLE (table), 1, size_group); + + prefs_check_button_add (object, "image-convert-indexed-remove-duplicates", + _("Remove unused and duplicate colors " + "from colormap"), + GTK_BOX (vbox2)); + + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + prefs_enum_combo_box_add (object, "image-convert-indexed-dither-type", 0, 0, + _("Color dithering:"), + GTK_TABLE (table), 0, size_group); + + prefs_check_button_add (object, "image-convert-indexed-dither-alpha", + _("Enable dithering of transparency"), + GTK_BOX (vbox2)); + prefs_check_button_add (object, "image-convert-indexed-dither-text-layers", + _("Enable dithering of text layers"), + GTK_BOX (vbox2)); + + /* Filter Dialogs */ + vbox2 = prefs_frame_new (_("Filter Dialogs"), + GTK_CONTAINER (vbox), FALSE); + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + prefs_spin_button_add (object, "filter-tool-max-recent", 1.0, 8.0, 0, + _("Keep recent settings:"), + GTK_TABLE (table), 1, size_group); + + button = prefs_check_button_add (object, "filter-tool-use-last-settings", + _("Default to the last used settings"), + GTK_BOX (vbox2)); + button = prefs_check_button_add (object, "filter-tool-show-color-options", + _("Show advanced color options"), + GTK_BOX (vbox2)); + + /* Canvas Size Dialog */ + vbox2 = prefs_frame_new (_("Canvas Size Dialog"), + GTK_CONTAINER (vbox), FALSE); + table = prefs_table_new (2, GTK_CONTAINER (vbox2)); + + prefs_enum_combo_box_add (object, "image-resize-fill-type", 0, 0, + _("Fill with:"), + GTK_TABLE (table), 0, size_group); + prefs_enum_combo_box_add (object, "image-resize-layer-set", 0, 0, + _("Resize layers:"), + GTK_TABLE (table), 1, size_group); + + prefs_check_button_add (object, "image-resize-resize-text-layers", + _("Resize text layers"), + GTK_BOX (vbox2)); + + /* New Layer Dialog */ + vbox2 = prefs_frame_new (_("New Layer Dialog"), + GTK_CONTAINER (vbox), FALSE); + table = prefs_table_new (2, GTK_CONTAINER (vbox2)); + + prefs_entry_add (object, "layer-new-name", + _("Layer name:"), + GTK_TABLE (table), 0, size_group); + + prefs_enum_combo_box_add (object, "layer-new-fill-type", 0, 0, + _("Fill type:"), + GTK_TABLE (table), 1, size_group); + + /* Layer Boundary Size Dialog */ + vbox2 = prefs_frame_new (_("Layer Boundary Size Dialog"), + GTK_CONTAINER (vbox), FALSE); + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + prefs_enum_combo_box_add (object, "layer-resize-fill-type", 0, 0, + _("Fill with:"), + GTK_TABLE (table), 0, size_group); + + /* Add Layer Mask Dialog */ + vbox2 = prefs_frame_new (_("Add Layer Mask Dialog"), + GTK_CONTAINER (vbox), FALSE); + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + prefs_enum_combo_box_add (object, "layer-add-mask-type", 0, 0, + _("Layer mask type:"), + GTK_TABLE (table), 0, size_group); + + prefs_check_button_add (object, "layer-add-mask-invert", + _("Invert mask"), + GTK_BOX (vbox2)); + + /* Merge Layers Dialog */ + vbox2 = prefs_frame_new (_("Merge Layers Dialog"), + GTK_CONTAINER (vbox), FALSE); + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + prefs_enum_combo_box_add (object, "layer-merge-type", + GIMP_EXPAND_AS_NECESSARY, + GIMP_CLIP_TO_BOTTOM_LAYER, + _("Merged layer size:"), + GTK_TABLE (table), 0, size_group); + + prefs_check_button_add (object, "layer-merge-active-group-only", + _("Merge within active group only"), + GTK_BOX (vbox2)); + prefs_check_button_add (object, "layer-merge-discard-invisible", + _("Discard invisible layers"), + GTK_BOX (vbox2)); + + /* New Channel Dialog */ + vbox2 = prefs_frame_new (_("New Channel Dialog"), + GTK_CONTAINER (vbox), FALSE); + table = prefs_table_new (2, GTK_CONTAINER (vbox2)); + + prefs_entry_add (object, "channel-new-name", + _("Channel name:"), + GTK_TABLE (table), 0, size_group); + + prefs_color_button_add (object, "channel-new-color", + _("Color and opacity:"), + _("Default New Channel Color and Opacity"), + GTK_TABLE (table), 1, size_group, + gimp_get_user_context (gimp)); + + /* New Path Dialog */ + vbox2 = prefs_frame_new (_("New Path Dialog"), + GTK_CONTAINER (vbox), FALSE); + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + prefs_entry_add (object, "path-new-name", + _("Path name:"), + GTK_TABLE (table), 0, size_group); + + /* Export Path Dialog */ + vbox2 = prefs_frame_new (_("Export Paths Dialog"), + GTK_CONTAINER (vbox), FALSE); + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + prefs_file_chooser_button_add (object, "path-export-path", + _("Export folder:"), + _("Select Default Folder for Exporting Paths"), + GTK_TABLE (table), 0, size_group); + + prefs_check_button_add (object, "path-export-active-only", + _("Export the active path only"), + GTK_BOX (vbox2)); + + /* Import Path Dialog */ + vbox2 = prefs_frame_new (_("Import Paths Dialog"), + GTK_CONTAINER (vbox), FALSE); + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + prefs_file_chooser_button_add (object, "path-import-path", + _("Import folder:"), + _("Select Default Folder for Importing Paths"), + GTK_TABLE (table), 0, size_group); + + prefs_check_button_add (object, "path-import-merge", + _("Merge imported paths"), + GTK_BOX (vbox2)); + prefs_check_button_add (object, "path-import-scale", + _("Scale imported paths"), + GTK_BOX (vbox2)); + + /* Feather Selection Dialog */ + vbox2 = prefs_frame_new (_("Feather Selection Dialog"), + GTK_CONTAINER (vbox), FALSE); + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + prefs_spin_button_add (object, "selection-feather-radius", 1.0, 10.0, 2, + _("Feather radius:"), + GTK_TABLE (table), 0, size_group); + + prefs_check_button_add (object, "selection-feather-edge-lock", + _("Selected areas continue outside the image"), + GTK_BOX (vbox2)); + + /* Grow Selection Dialog */ + vbox2 = prefs_frame_new (_("Grow Selection Dialog"), + GTK_CONTAINER (vbox), FALSE); + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + prefs_spin_button_add (object, "selection-grow-radius", 1.0, 10.0, 0, + _("Grow radius:"), + GTK_TABLE (table), 0, size_group); + + /* Shrink Selection Dialog */ + vbox2 = prefs_frame_new (_("Shrink Selection Dialog"), + GTK_CONTAINER (vbox), FALSE); + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + prefs_spin_button_add (object, "selection-shrink-radius", 1.0, 10.0, 0, + _("Shrink radius:"), + GTK_TABLE (table), 0, size_group); + + prefs_check_button_add (object, "selection-shrink-edge-lock", + _("Selected areas continue outside the image"), + GTK_BOX (vbox2)); + + /* Border Selection Dialog */ + vbox2 = prefs_frame_new (_("Border Selection Dialog"), + GTK_CONTAINER (vbox), FALSE); + table = prefs_table_new (2, GTK_CONTAINER (vbox2)); + + prefs_spin_button_add (object, "selection-border-radius", 1.0, 10.0, 0, + _("Border radius:"), + GTK_TABLE (table), 0, size_group); + + prefs_enum_combo_box_add (object, "selection-border-style", 0, 0, + _("Border style:"), + GTK_TABLE (table), 1, size_group); + + prefs_check_button_add (object, "selection-border-edge-lock", + _("Selected areas continue outside the image"), + GTK_BOX (vbox2)); + + /* Fill Options Dialog */ + vbox2 = prefs_frame_new (_("Fill Selection Outline & Fill Path Dialogs"), + GTK_CONTAINER (vbox), FALSE); + + table = gimp_fill_editor_new (GIMP_DIALOG_CONFIG (object)->fill_options, + FALSE); + gtk_box_pack_start (GTK_BOX (vbox2), table, FALSE, FALSE, 0); + gtk_widget_show (table); + + /* Stroke Options Dialog */ + vbox2 = prefs_frame_new (_("Stroke Selection & Stroke Path Dialogs"), + GTK_CONTAINER (vbox), FALSE); + + /* The stroke line width physical values could be based on either the + * x or y resolution, some average, or whatever which makes a bit of + * sense. There is no perfect answer. The actual stroke dialog though + * uses the y resolution on the opened image. So using the y resolution + * of the default image seems like the best compromise in the preferences. + */ + table = gimp_stroke_editor_new (GIMP_DIALOG_CONFIG (object)->stroke_options, + gimp_template_get_resolution_y (core_config->default_image), + FALSE); + gtk_box_pack_start (GTK_BOX (vbox2), table, FALSE, FALSE, 0); + gtk_widget_show (table); + + g_clear_object (&size_group); + + + /*****************************/ + /* Interface / Help System */ + /*****************************/ + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + "gimp-prefs-help-system", + _("Help System"), + _("Help System"), + GIMP_HELP_PREFS_HELP, + &top_iter, + &child_iter); + + size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + + /* General */ + vbox2 = prefs_frame_new (_("General"), GTK_CONTAINER (vbox), FALSE); + + prefs_check_button_add (object, "show-tooltips", + _("Show _tooltips"), + GTK_BOX (vbox2)); + prefs_check_button_add (object, "show-help-button", + _("Show help _buttons"), + GTK_BOX (vbox2)); + + table = prefs_table_new (3, GTK_CONTAINER (vbox2)); + button = prefs_boolean_combo_box_add (object, "user-manual-online", + _("Use the online version"), + _("Use a locally installed copy"), + _("U_ser manual:"), + GTK_TABLE (table), 0, size_group); + gimp_help_set_help_data (button, NULL, NULL); + + manuals = gimp_help_get_installed_languages (); + entry = NULL; + if (manuals != NULL) + { + gchar *help_locales = NULL; + + entry = gimp_language_combo_box_new (TRUE, + _("User interface language")); + + g_object_get (config, "help-locales", &help_locales, NULL); + if (help_locales && strlen (help_locales)) + { + gchar *sep; + + sep = strchr (help_locales, ':'); + if (sep) + *sep = '\0'; + } + if (help_locales) + { + gimp_language_combo_box_set_code (GIMP_LANGUAGE_COMBO_BOX (entry), + help_locales); + g_free (help_locales); + } + else + { + gimp_language_combo_box_set_code (GIMP_LANGUAGE_COMBO_BOX (entry), + ""); + } + g_signal_connect (entry, "changed", + G_CALLBACK (prefs_help_language_change_callback), + gimp); + gtk_table_attach_defaults (GTK_TABLE (table), entry, 1, 2, 1, 2); + gtk_widget_show (entry); + } + + if (gimp_help_user_manual_is_installed (gimp)) + { + hbox = prefs_hint_box_new (GIMP_ICON_DIALOG_INFORMATION, + _("There's a local installation " + "of the user manual.")); + } + else + { + hbox = prefs_hint_box_new (GIMP_ICON_DIALOG_WARNING, + _("The user manual is not installed " + "locally.")); + } + if (manuals) + { + g_object_set_data (G_OBJECT (hbox), "gimp", gimp); + g_signal_connect (entry, "changed", + G_CALLBACK (prefs_help_language_change_callback2), + hbox); + g_list_free_full (manuals, g_free); + } + + gtk_table_attach_defaults (GTK_TABLE (table), hbox, 1, 2, 2, 3); + gtk_widget_show (hbox); + + /* Help Browser */ +#ifdef HAVE_WEBKIT + /* If there is no webkit available, assume we are on a platform + * that doesn't use the help browser, so don't bother showing + * the combo. + */ + vbox2 = prefs_frame_new (_("Help Browser"), GTK_CONTAINER (vbox), FALSE); + + if (gimp_help_browser_is_installed (gimp)) + { + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + button = prefs_enum_combo_box_add (object, "help-browser", 0, 0, + _("H_elp browser to use:"), + GTK_TABLE (table), 0, size_group); + } + else + { + hbox = prefs_hint_box_new (GIMP_ICON_DIALOG_WARNING, + _("The GIMP help browser doesn't seem to " + "be installed. Using the web browser " + "instead.")); + gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + + g_object_set (config, + "help-browser", GIMP_HELP_BROWSER_WEB_BROWSER, + NULL); + } +#else + g_object_set (config, + "help-browser", GIMP_HELP_BROWSER_WEB_BROWSER, + NULL); +#endif /* HAVE_WEBKIT */ + + /* Action Search */ + vbox2 = prefs_frame_new (_("Action Search"), GTK_CONTAINER (vbox), FALSE); + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + prefs_check_button_add (object, "search-show-unavailable-actions", + _("Show _unavailable actions"), + GTK_BOX (vbox2)); + prefs_spin_button_add (object, "action-history-size", 1.0, 10.0, 0, + _("_Maximum History Size:"), + GTK_TABLE (table), 0, size_group); + + button = prefs_button_add (GIMP_ICON_SHRED, + _("C_lear Action History"), + GTK_BOX (vbox2)); + g_signal_connect (button, "clicked", + G_CALLBACK (prefs_search_clear_callback), + gimp); + + g_clear_object (&size_group); + + + /*************************/ + /* Interface / Display */ + /*************************/ + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + "gimp-prefs-display", + _("Display"), + _("Display"), + GIMP_HELP_PREFS_DISPLAY, + &top_iter, + &child_iter); + gimp_prefs_box_set_page_scrollable (GIMP_PREFS_BOX (prefs_box), vbox, TRUE); + + size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + + /* Transparency */ + vbox2 = prefs_frame_new (_("Transparency"), GTK_CONTAINER (vbox), FALSE); + table = prefs_table_new (2, GTK_CONTAINER (vbox2)); + + prefs_enum_combo_box_add (object, "transparency-type", 0, 0, + _("_Check style:"), + GTK_TABLE (table), 0, size_group); + prefs_enum_combo_box_add (object, "transparency-size", 0, 0, + _("Check _size:"), + GTK_TABLE (table), 1, size_group); + + vbox2 = prefs_frame_new (_("Monitor Resolution"), + GTK_CONTAINER (vbox), FALSE); + + { + gchar *pixels_per_unit = g_strconcat (_("Pixels"), "/%s", NULL); + + entry = gimp_prop_coordinates_new (object, + "monitor-xresolution", + "monitor-yresolution", + NULL, + pixels_per_unit, + GIMP_SIZE_ENTRY_UPDATE_RESOLUTION, + 0.0, 0.0, + TRUE); + + g_free (pixels_per_unit); + } + + gtk_table_set_col_spacings (GTK_TABLE (entry), 2); + gtk_table_set_row_spacings (GTK_TABLE (entry), 2); + + gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (entry), + _("Horizontal"), 0, 1, 0.0); + gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (entry), + _("Vertical"), 0, 2, 0.0); + gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (entry), + _("ppi"), 1, 4, 0.0); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + + gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 24); + gtk_widget_show (entry); + gtk_widget_set_sensitive (entry, ! display_config->monitor_res_from_gdk); + + group = NULL; + + { + gdouble xres; + gdouble yres; + gchar *str; + + gimp_get_monitor_resolution (gdk_screen_get_default (), /* FIXME monitor */ + 0, /* FIXME monitor */ + &xres, &yres); + + str = g_strdup_printf (_("_Detect automatically (currently %d × %d ppi)"), + ROUND (xres), ROUND (yres)); + + button = gtk_radio_button_new_with_mnemonic (group, str); + + g_free (str); + } + + group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)); + gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0); + gtk_widget_show (button); + + g_object_set_data (G_OBJECT (button), "monitor_resolution_sizeentry", entry); + + g_signal_connect (button, "toggled", + G_CALLBACK (prefs_resolution_source_callback), + config); + + button = gtk_radio_button_new_with_mnemonic (group, _("_Enter manually")); + group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)); + gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0); + gtk_widget_show (button); + + gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + + if (! display_config->monitor_res_from_gdk) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 0); + gtk_widget_show (hbox); + + calibrate_button = gtk_button_new_with_mnemonic (_("C_alibrate...")); + label = gtk_bin_get_child (GTK_BIN (calibrate_button)); + gtk_misc_set_padding (GTK_MISC (label), 4, 0); + gtk_box_pack_start (GTK_BOX (hbox), calibrate_button, FALSE, FALSE, 0); + gtk_widget_show (calibrate_button); + gtk_widget_set_sensitive (calibrate_button, + ! display_config->monitor_res_from_gdk); + + g_object_bind_property (button, "active", + entry, "sensitive", + G_BINDING_SYNC_CREATE); + g_object_bind_property (button, "active", + calibrate_button, "sensitive", + G_BINDING_SYNC_CREATE); + + g_signal_connect (calibrate_button, "clicked", + G_CALLBACK (prefs_resolution_calibrate_callback), + entry); + + g_clear_object (&size_group); + + + /***********************************/ + /* Interface / Window Management */ + /***********************************/ + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + "gimp-prefs-window-management", + _("Window Management"), + _("Window Management"), + GIMP_HELP_PREFS_WINDOW_MANAGEMENT, + &top_iter, + &child_iter); + + vbox2 = prefs_frame_new (_("Window Manager Hints"), + GTK_CONTAINER (vbox), FALSE); + + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + prefs_enum_combo_box_add (object, "dock-window-hint", 0, 0, + _("Hint for _docks and toolbox:"), + GTK_TABLE (table), 1, NULL); + + vbox2 = prefs_frame_new (_("Focus"), + GTK_CONTAINER (vbox), FALSE); + + prefs_check_button_add (object, "activate-on-focus", + _("Activate the _focused image"), + GTK_BOX (vbox2)); + + /* Window Positions */ + vbox2 = prefs_frame_new (_("Window Positions"), GTK_CONTAINER (vbox), FALSE); + + prefs_check_button_add (object, "save-session-info", + _("_Save window positions on exit"), + GTK_BOX (vbox2)); + prefs_check_button_add (object, "restore-monitor", + _("Open windows on the same _monitor they were open before"), + GTK_BOX (vbox2)); + + button = prefs_button_add (GIMP_ICON_DOCUMENT_SAVE, + _("Save Window Positions _Now"), + GTK_BOX (vbox2)); + g_signal_connect (button, "clicked", + G_CALLBACK (prefs_session_save_callback), + gimp); + + button2 = prefs_button_add (GIMP_ICON_RESET, + _("_Reset Saved Window Positions to " + "Default Values"), + GTK_BOX (vbox2)); + g_signal_connect (button2, "clicked", + G_CALLBACK (prefs_session_clear_callback), + gimp); + + g_object_set_data (G_OBJECT (button), "clear-button", button2); + + + /*******************/ + /* Image Windows */ + /*******************/ + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + "gimp-prefs-image-windows", + _("Image Windows"), + _("Image Windows"), + GIMP_HELP_PREFS_IMAGE_WINDOW, + NULL, + &top_iter); + gimp_prefs_box_set_page_scrollable (GIMP_PREFS_BOX (prefs_box), vbox, TRUE); + + size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + + /* General */ + vbox2 = prefs_frame_new (_("General"), GTK_CONTAINER (vbox), FALSE); + + prefs_check_button_add (object, "default-show-all", + _("Use \"Show _all\" by default"), + GTK_BOX (vbox2)); + + prefs_check_button_add (object, "default-dot-for-dot", + _("Use \"_Dot for dot\" by default"), + GTK_BOX (vbox2)); + + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + prefs_spin_button_add (object, "marching-ants-speed", 1.0, 10.0, 0, + _("Marching ants s_peed:"), + GTK_TABLE (table), 0, size_group); + + /* Zoom & Resize Behavior */ + vbox2 = prefs_frame_new (_("Zoom & Resize Behavior"), + GTK_CONTAINER (vbox), FALSE); + + prefs_check_button_add (object, "resize-windows-on-zoom", + _("Resize window on _zoom"), + GTK_BOX (vbox2)); + prefs_check_button_add (object, "resize-windows-on-resize", + _("Resize window on image _size change"), + GTK_BOX (vbox2)); + + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + prefs_boolean_combo_box_add (object, "initial-zoom-to-fit", + _("Show entire image"), + "1:1", + _("Initial zoom _ratio:"), + GTK_TABLE (table), 0, size_group); + + /* Space Bar */ + vbox2 = prefs_frame_new (_("Space Bar"), + GTK_CONTAINER (vbox), FALSE); + + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + prefs_enum_combo_box_add (object, "space-bar-action", 0, 0, + _("_While space bar is pressed:"), + GTK_TABLE (table), 0, size_group); + + /* Mouse Pointers */ + vbox2 = prefs_frame_new (_("Mouse Pointers"), + GTK_CONTAINER (vbox), FALSE); + + button = prefs_check_button_add (object, "show-brush-outline", + _("Show _brush outline"), + GTK_BOX (vbox2)); + + vbox3 = prefs_frame_new (NULL, GTK_CONTAINER (vbox2), FALSE); + g_object_bind_property (button, "active", + vbox3, "sensitive", + G_BINDING_SYNC_CREATE); + prefs_check_button_add (object, "snap-brush-outline", + _("S_nap brush outline to stroke"), + GTK_BOX (vbox3)); + + prefs_check_button_add (object, "show-paint-tool-cursor", + _("Show pointer for paint _tools"), + GTK_BOX (vbox2)); + + table = prefs_table_new (2, GTK_CONTAINER (vbox2)); + + prefs_enum_combo_box_add (object, "cursor-mode", 0, 0, + _("Pointer _mode:"), + GTK_TABLE (table), 0, size_group); + prefs_enum_combo_box_add (object, "cursor-handedness", 0, 0, + _("Pointer _handedness:"), + GTK_TABLE (table), 1, NULL); + + g_clear_object (&size_group); + + + /********************************/ + /* Image Windows / Appearance */ + /********************************/ + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + "gimp-prefs-image-windows-appearance", + _("Image Window Appearance"), + _("Appearance"), + GIMP_HELP_PREFS_IMAGE_WINDOW_APPEARANCE, + &top_iter, + &child_iter); + + gimp_prefs_box_set_page_scrollable (GIMP_PREFS_BOX (prefs_box), vbox, TRUE); + + prefs_display_options_frame_add (gimp, + G_OBJECT (display_config->default_view), + _("Default Appearance in Normal Mode"), + GTK_CONTAINER (vbox)); + + prefs_display_options_frame_add (gimp, + G_OBJECT (display_config->default_fullscreen_view), + _("Default Appearance in Fullscreen Mode"), + GTK_CONTAINER (vbox)); + + + /****************************************************/ + /* Image Windows / Image Title & Statusbar Format */ + /****************************************************/ + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + "gimp-prefs-image-title", + _("Image Title & Statusbar Format"), + _("Title & Status"), + GIMP_HELP_PREFS_IMAGE_WINDOW_TITLE, + &top_iter, + &child_iter); + + { + const gchar *format_strings[] = + { + NULL, + NULL, + "%f-%p.%i (%t) %z%%", + "%f-%p.%i (%t) %d:%s", + "%f-%p.%i (%t) %wx%h", + "%f-%p-%i (%t) %wx%h (%xx%y)" + }; + + const gchar *format_names[] = + { + N_("Current format"), + N_("Default format"), + N_("Show zoom percentage"), + N_("Show zoom ratio"), + N_("Show image size"), + N_("Show drawable size") + }; + + struct + { + gchar *current_setting; + const gchar *default_setting; + const gchar *title; + const gchar *property_name; + } + formats[] = + { + { NULL, GIMP_CONFIG_DEFAULT_IMAGE_TITLE_FORMAT, + N_("Image Title Format"), "image-title-format" }, + { NULL, GIMP_CONFIG_DEFAULT_IMAGE_STATUS_FORMAT, + N_("Image Statusbar Format"), "image-status-format" } + }; + + gint format; + + gimp_assert (G_N_ELEMENTS (format_strings) == G_N_ELEMENTS (format_names)); + + formats[0].current_setting = display_config->image_title_format; + formats[1].current_setting = display_config->image_status_format; + + for (format = 0; format < G_N_ELEMENTS (formats); format++) + { + GtkWidget *scrolled_win; + GtkListStore *list_store; + GtkWidget *view; + GtkTreeSelection *sel; + gint i; + + format_strings[0] = formats[format].current_setting; + format_strings[1] = formats[format].default_setting; + + vbox2 = prefs_frame_new (gettext (formats[format].title), + GTK_CONTAINER (vbox), TRUE); + + entry = gimp_prop_entry_new (object, formats[format].property_name, 0); + gtk_box_pack_start (GTK_BOX (vbox2), entry, FALSE, FALSE, 0); + gtk_widget_show (entry); + + scrolled_win = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), + GTK_SHADOW_IN); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_box_pack_start (GTK_BOX (vbox2), scrolled_win, TRUE, TRUE, 0); + gtk_widget_show (scrolled_win); + + 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); + + 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)); + + 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, gettext (format_names[i]), + 1, format_strings[i], + -1); + + if (i == 0) + gtk_tree_selection_select_iter (sel, &iter); + } + + g_signal_connect (sel, "changed", + G_CALLBACK (prefs_format_string_select_callback), + entry); + } + } + + + /******************************/ + /* Image Windows / Snapping */ + /******************************/ + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + "gimp-prefs-image-windows-snapping", + _("Image Window Snapping Behavior"), + _("Snapping"), + GIMP_HELP_PREFS_IMAGE_WINDOW_SNAPPING, + &top_iter, + &child_iter); + + prefs_behavior_options_frame_add (gimp, + G_OBJECT (display_config->default_view), + _("Default Behavior in Normal Mode"), + GTK_CONTAINER (vbox)); + prefs_behavior_options_frame_add (gimp, + G_OBJECT (display_config->default_fullscreen_view), + _("Default Behavior in Fullscreen Mode"), + GTK_CONTAINER (vbox)); + + /* Snapping Distance */ + vbox2 = prefs_frame_new (_("General"), + GTK_CONTAINER (vbox), FALSE); + table = prefs_table_new (1, GTK_CONTAINER (vbox2)); + + prefs_spin_button_add (object, "snap-distance", 1.0, 5.0, 0, + _("_Snapping distance:"), + GTK_TABLE (table), 0, NULL); + + + /*******************/ + /* Input Devices */ + /*******************/ + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + "gimp-prefs-input-devices", + _("Input Devices"), + _("Input Devices"), + GIMP_HELP_PREFS_INPUT_DEVICES, + NULL, + &top_iter); + + /* Extended Input Devices */ + vbox2 = prefs_frame_new (_("Extended Input Devices"), + GTK_CONTAINER (vbox), FALSE); + + prefs_check_button_add (object, "devices-share-tool", + _("S_hare tool and tool options between input devices"), + GTK_BOX (vbox2)); + + button = prefs_button_add (GIMP_ICON_PREFERENCES_SYSTEM, + _("Configure E_xtended Input Devices..."), + GTK_BOX (vbox2)); + g_signal_connect (button, "clicked", + G_CALLBACK (prefs_input_devices_dialog), + gimp); + + prefs_check_button_add (object, "save-device-status", + _("_Save input device settings on exit"), + GTK_BOX (vbox2)); + + button = prefs_button_add (GIMP_ICON_DOCUMENT_SAVE, + _("Save Input Device Settings _Now"), + GTK_BOX (vbox2)); + g_signal_connect (button, "clicked", + G_CALLBACK (prefs_devices_save_callback), + gimp); + + button2 = prefs_button_add (GIMP_ICON_RESET, + _("_Reset Saved Input Device Settings to " + "Default Values"), + GTK_BOX (vbox2)); + g_signal_connect (button2, "clicked", + G_CALLBACK (prefs_devices_clear_callback), + gimp); + + g_object_set_data (G_OBJECT (button), "clear-button", button2); + + + /****************************/ + /* Additional Controllers */ + /****************************/ + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + "gimp-prefs-controllers", + _("Additional Input Controllers"), + _("Input Controllers"), + GIMP_HELP_PREFS_INPUT_CONTROLLERS, + &top_iter, + &child_iter); + + vbox2 = gimp_controller_list_new (gimp); + gtk_box_pack_start (GTK_BOX (vbox), vbox2, TRUE, TRUE, 0); + gtk_widget_show (vbox2); + + + /*************/ + /* Folders */ + /*************/ + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + "gimp-prefs-folders", + _("Folders"), + _("Folders"), + GIMP_HELP_PREFS_FOLDERS, + NULL, + &top_iter); + + button = gimp_prefs_box_set_page_resettable (GIMP_PREFS_BOX (prefs_box), + vbox, + _("Reset _Folders")); + g_signal_connect (button, "clicked", + G_CALLBACK (prefs_folders_reset), + config); + + { + static const struct + { + const gchar *property_name; + const gchar *label; + const gchar *dialog_title; + } + dirs[] = + { + { + "temp-path", + N_("_Temporary folder:"), + N_("Select Folder for Temporary Files") + }, + { + "swap-path", + N_("_Swap folder:"), + N_("Select Swap Folder") + } + }; + + table = prefs_table_new (G_N_ELEMENTS (dirs) + 1, GTK_CONTAINER (vbox)); + + for (i = 0; i < G_N_ELEMENTS (dirs); i++) + { + prefs_file_chooser_button_add (object, dirs[i].property_name, + gettext (dirs[i].label), + gettext (dirs[i].dialog_title), + GTK_TABLE (table), i, NULL); + } + } + + + /*********************/ + /* Folders / <paths> */ + /*********************/ + { + static const struct + { + const gchar *tree_label; + const gchar *label; + const gchar *icon; + const gchar *help_data; + const gchar *reset_label; + const gchar *fs_label; + const gchar *path_property_name; + const gchar *writable_property_name; + } + paths[] = + { + { N_("Brushes"), N_("Brush Folders"), + "folders-brushes", + GIMP_HELP_PREFS_FOLDERS_BRUSHES, + N_("Reset Brush _Folders"), + N_("Select Brush Folders"), + "brush-path", "brush-path-writable" }, + { N_("Dynamics"), N_("Dynamics Folders"), + "folders-dynamics", + GIMP_HELP_PREFS_FOLDERS_DYNAMICS, + N_("Reset Dynamics _Folders"), + N_("Select Dynamics Folders"), + "dynamics-path", "dynamics-path-writable" }, + { N_("Patterns"), N_("Pattern Folders"), + "folders-patterns", + GIMP_HELP_PREFS_FOLDERS_PATTERNS, + N_("Reset Pattern _Folders"), + N_("Select Pattern Folders"), + "pattern-path", "pattern-path-writable" }, + { N_("Palettes"), N_("Palette Folders"), + "folders-palettes", + GIMP_HELP_PREFS_FOLDERS_PALETTES, + N_("Reset Palette _Folders"), + N_("Select Palette Folders"), + "palette-path", "palette-path-writable" }, + { N_("Gradients"), N_("Gradient Folders"), + "folders-gradients", + GIMP_HELP_PREFS_FOLDERS_GRADIENTS, + N_("Reset Gradient _Folders"), + N_("Select Gradient Folders"), + "gradient-path", "gradient-path-writable" }, + { N_("Fonts"), N_("Font Folders"), + "folders-fonts", + GIMP_HELP_PREFS_FOLDERS_FONTS, + N_("Reset Font _Folders"), + N_("Select Font Folders"), + "font-path", NULL }, + { N_("Tool Presets"), N_("Tool Preset Folders"), + "folders-tool-presets", + GIMP_HELP_PREFS_FOLDERS_TOOL_PRESETS, + N_("Reset Tool Preset _Folders"), + N_("Select Tool Preset Folders"), + "tool-preset-path", "tool-preset-path-writable" }, + { N_("MyPaint Brushes"), N_("MyPaint Brush Folders"), + "folders-mypaint-brushes", + GIMP_HELP_PREFS_FOLDERS_MYPAINT_BRUSHES, + N_("Reset MyPaint Brush _Folders"), + N_("Select MyPaint Brush Folders"), + "mypaint-brush-path", "mypaint-brush-path-writable" }, + { N_("Plug-ins"), N_("Plug-in Folders"), + "folders-plug-ins", + GIMP_HELP_PREFS_FOLDERS_PLUG_INS, + N_("Reset plug-in _Folders"), + N_("Select plug-in Folders"), + "plug-in-path", NULL }, + { N_("Scripts"), N_("Script-Fu Folders"), + "folders-scripts", + GIMP_HELP_PREFS_FOLDERS_SCRIPTS, + N_("Reset Script-Fu _Folders"), + N_("Select Script-Fu Folders"), + "script-fu-path", NULL }, + { N_("Modules"), N_("Module Folders"), + "folders-modules", + GIMP_HELP_PREFS_FOLDERS_MODULES, + N_("Reset Module _Folders"), + N_("Select Module Folders"), + "module-path", NULL }, + { N_("Interpreters"), N_("Interpreter Folders"), + "folders-interp", + GIMP_HELP_PREFS_FOLDERS_INTERPRETERS, + N_("Reset Interpreter _Folders"), + N_("Select Interpreter Folders"), + "interpreter-path", NULL }, + { N_("Environment"), N_("Environment Folders"), + "folders-environ", + GIMP_HELP_PREFS_FOLDERS_ENVIRONMENT, + N_("Reset Environment _Folders"), + N_("Select Environment Folders"), + "environ-path", NULL }, + { N_("Themes"), N_("Theme Folders"), + "folders-themes", + GIMP_HELP_PREFS_FOLDERS_THEMES, + N_("Reset Theme _Folders"), + N_("Select Theme Folders"), + "theme-path", NULL }, + { N_("Icon Themes"), N_("Icon Theme Folders"), + "folders-icon-themes", + GIMP_HELP_PREFS_FOLDERS_ICON_THEMES, + N_("Reset Icon Theme _Folders"), + N_("Select Icon Theme Folders"), + "icon-theme-path", NULL } + }; + + for (i = 0; i < G_N_ELEMENTS (paths); i++) + { + GtkWidget *editor; + gchar *icon_name; + + icon_name = g_strconcat ("gimp-prefs-", paths[i].icon, NULL); + vbox = gimp_prefs_box_add_page (GIMP_PREFS_BOX (prefs_box), + icon_name, + gettext (paths[i].label), + gettext (paths[i].tree_label), + paths[i].help_data, + &top_iter, + &child_iter); + g_free (icon_name); + + button = gimp_prefs_box_set_page_resettable (GIMP_PREFS_BOX (prefs_box), + vbox, + gettext (paths[i].reset_label)); + g_object_set_data (G_OBJECT (button), "path", + (gpointer) paths[i].path_property_name); + g_object_set_data (G_OBJECT (button), "path-writable", + (gpointer) paths[i].writable_property_name); + g_signal_connect (button, "clicked", + G_CALLBACK (prefs_path_reset), + config); + + editor = gimp_prop_path_editor_new (object, + paths[i].path_property_name, + paths[i].writable_property_name, + gettext (paths[i].fs_label)); + gtk_box_pack_start (GTK_BOX (vbox), editor, TRUE, TRUE, 0); + gtk_widget_show (editor); + } + } + + { + GtkWidget *tv; + GtkTreeModel *model; + GtkTreePath *path; + + tv = gimp_prefs_box_get_tree_view (GIMP_PREFS_BOX (prefs_box)); + gtk_tree_view_expand_all (GTK_TREE_VIEW (tv)); + + /* collapse the Folders subtree */ + model = gtk_tree_view_get_model (GTK_TREE_VIEW (tv)); + path = gtk_tree_model_get_path (model, &top_iter); + gtk_tree_view_collapse_row (GTK_TREE_VIEW (tv), path); + gtk_tree_path_free (path); + } + + return dialog; +} |