diff options
Diffstat (limited to 'src/profile-editor.c')
-rw-r--r-- | src/profile-editor.c | 921 |
1 files changed, 921 insertions, 0 deletions
diff --git a/src/profile-editor.c b/src/profile-editor.c new file mode 100644 index 0000000..6ac0b34 --- /dev/null +++ b/src/profile-editor.c @@ -0,0 +1,921 @@ +/* + * Copyright © 2002 Havoc Pennington + * Copyright © 2002 Mathias Hasselmann + * Copyright © 2008 Christian Persch + * + * Mate-terminal 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. + * + * Mate-terminal 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 <http://www.gnu.org/licenses/>. + */ + +#include <config.h> + +#include <string.h> +#include <math.h> + +#include <glib.h> +#include <gio/gio.h> + +#include "terminal-intl.h" +#include "profile-editor.h" +#include "terminal-util.h" + +typedef struct _TerminalColorScheme TerminalColorScheme; + +struct _TerminalColorScheme +{ + const char *name; + const GdkColor foreground; + const GdkColor background; +}; + +static const TerminalColorScheme color_schemes[] = { + { N_("Black on light yellow"), + { 0, 0x0000, 0x0000, 0x0000 }, { 0, 0xFFFF, 0xFFFF, 0xDDDD } }, + { N_("Black on white"), + { 0, 0x0000, 0x0000, 0x0000 }, { 0, 0xFFFF, 0xFFFF, 0xFFFF } }, + { N_("Gray on black"), + { 0, 0xAAAA, 0xAAAA, 0xAAAA }, { 0, 0x0000, 0x0000, 0x0000 } }, + { N_("Green on black"), + { 0, 0x0000, 0xFFFF, 0x0000 }, { 0, 0x0000, 0x0000, 0x0000 } }, + { N_("White on black"), + { 0, 0xFFFF, 0xFFFF, 0xFFFF }, { 0, 0x0000, 0x0000, 0x0000 } } +}; + +static void profile_forgotten_cb (TerminalProfile *profile, + GtkWidget *editor); + +static void profile_notify_sensitivity_cb (TerminalProfile *profile, + GParamSpec *pspec, + GtkWidget *editor); + +static void profile_colors_notify_scheme_combo_cb (TerminalProfile *profile, + GParamSpec *pspec, + GtkComboBox *combo); + +static void profile_palette_notify_scheme_combo_cb (TerminalProfile *profile, + GParamSpec *pspec, + GtkComboBox *combo); + +static void profile_palette_notify_colorpickers_cb (TerminalProfile *profile, + GParamSpec *pspec, + GtkWidget *editor); + +static GtkWidget* +profile_editor_get_widget (GtkWidget *editor, + const char *widget_name) +{ + GtkBuilder *builder; + + builder = g_object_get_data (G_OBJECT (editor), "builder"); + g_assert (builder != NULL); + + return (GtkWidget *) gtk_builder_get_object (builder, widget_name); +} + +static void +widget_and_labels_set_sensitive (GtkWidget *widget, gboolean sensitive) +{ + GList *labels, *i; + + labels = gtk_widget_list_mnemonic_labels (widget); + for (i = labels; i; i = i->next) + { + gtk_widget_set_sensitive (GTK_WIDGET (i->data), sensitive); + } + g_list_free (labels); + + gtk_widget_set_sensitive (widget, sensitive); +} + +static void +profile_forgotten_cb (TerminalProfile *profile, + GtkWidget *editor) +{ + gtk_widget_destroy (editor); +} + +static void +profile_notify_sensitivity_cb (TerminalProfile *profile, + GParamSpec *pspec, + GtkWidget *editor) +{ + TerminalBackgroundType bg_type; + const char *prop_name; + + if (pspec) + prop_name = pspec->name; + else + prop_name = NULL; + +#define SET_SENSITIVE(name, setting) widget_and_labels_set_sensitive (profile_editor_get_widget (editor, name), setting) + + if (!prop_name || + prop_name == I_(TERMINAL_PROFILE_USE_CUSTOM_COMMAND) || + prop_name == I_(TERMINAL_PROFILE_CUSTOM_COMMAND)) + { + gboolean use_custom_command_locked = terminal_profile_property_locked (profile, TERMINAL_PROFILE_USE_CUSTOM_COMMAND); + SET_SENSITIVE ("use-custom-command-checkbutton", !use_custom_command_locked); + SET_SENSITIVE ("custom-command-box", + terminal_profile_get_property_boolean (profile, TERMINAL_PROFILE_USE_CUSTOM_COMMAND) && + !terminal_profile_property_locked (profile, TERMINAL_PROFILE_CUSTOM_COMMAND)); + } + + if (!prop_name || prop_name == I_(TERMINAL_PROFILE_BACKGROUND_TYPE)) + { + gboolean bg_type_locked = terminal_profile_property_locked (profile, TERMINAL_PROFILE_BACKGROUND_TYPE); + SET_SENSITIVE ("solid-radiobutton", !bg_type_locked); + SET_SENSITIVE ("image-radiobutton", !bg_type_locked); + SET_SENSITIVE ("transparent-radiobutton", !bg_type_locked); + + bg_type = terminal_profile_get_property_enum (profile, TERMINAL_PROFILE_BACKGROUND_TYPE); + if (bg_type == TERMINAL_BACKGROUND_IMAGE) + { + SET_SENSITIVE ("background-image-filechooser", !terminal_profile_property_locked (profile, TERMINAL_PROFILE_BACKGROUND_IMAGE_FILE)); + SET_SENSITIVE ("scroll-background-checkbutton", !terminal_profile_property_locked (profile, TERMINAL_PROFILE_SCROLL_BACKGROUND)); + SET_SENSITIVE ("darken-background-vbox", !terminal_profile_property_locked (profile, TERMINAL_PROFILE_BACKGROUND_DARKNESS)); + } + else if (bg_type == TERMINAL_BACKGROUND_TRANSPARENT) + { + SET_SENSITIVE ("background-image-filechooser", FALSE); + SET_SENSITIVE ("scroll-background-checkbutton", FALSE); + SET_SENSITIVE ("darken-background-vbox", !terminal_profile_property_locked (profile, TERMINAL_PROFILE_BACKGROUND_DARKNESS)); + } + else + { + SET_SENSITIVE ("background-image-filechooser", FALSE); + SET_SENSITIVE ("scroll-background-checkbutton", FALSE); + SET_SENSITIVE ("darken-background-vbox", FALSE); + } + } + + if (!prop_name || + prop_name == I_(TERMINAL_PROFILE_USE_SYSTEM_FONT) || + prop_name == I_(TERMINAL_PROFILE_FONT)) + { + SET_SENSITIVE ("font-hbox", + !terminal_profile_get_property_boolean (profile, TERMINAL_PROFILE_USE_SYSTEM_FONT) && + !terminal_profile_property_locked (profile, TERMINAL_PROFILE_FONT)); + SET_SENSITIVE ("system-font-checkbutton", + !terminal_profile_property_locked (profile, TERMINAL_PROFILE_USE_SYSTEM_FONT)); + } + + if (!prop_name || + prop_name == I_(TERMINAL_PROFILE_FOREGROUND_COLOR) || + prop_name == I_(TERMINAL_PROFILE_BACKGROUND_COLOR) || + prop_name == I_(TERMINAL_PROFILE_BOLD_COLOR) || + prop_name == I_(TERMINAL_PROFILE_BOLD_COLOR_SAME_AS_FG) || + prop_name == I_(TERMINAL_PROFILE_USE_THEME_COLORS)) + { + gboolean bg_locked, use_theme_colors, fg_locked; + + use_theme_colors = terminal_profile_get_property_boolean (profile, TERMINAL_PROFILE_USE_THEME_COLORS); + fg_locked = terminal_profile_property_locked (profile, TERMINAL_PROFILE_FOREGROUND_COLOR); + bg_locked = terminal_profile_property_locked (profile, TERMINAL_PROFILE_BACKGROUND_COLOR); + + SET_SENSITIVE ("foreground-colorpicker", !use_theme_colors && !fg_locked); + SET_SENSITIVE ("foreground-colorpicker-label", !use_theme_colors && !fg_locked); + SET_SENSITIVE ("background-colorpicker", !use_theme_colors && !bg_locked); + SET_SENSITIVE ("background-colorpicker-label", !use_theme_colors && !bg_locked); + SET_SENSITIVE ("color-scheme-combobox", !use_theme_colors && !fg_locked && !bg_locked); + SET_SENSITIVE ("color-scheme-combobox-label", !use_theme_colors && !fg_locked && !bg_locked); + } + + if (!prop_name || + prop_name == I_(TERMINAL_PROFILE_BOLD_COLOR) || + prop_name == I_(TERMINAL_PROFILE_BOLD_COLOR_SAME_AS_FG) || + prop_name == I_(TERMINAL_PROFILE_USE_THEME_COLORS)) + { + gboolean bold_locked, bold_same_as_fg_locked, bold_same_as_fg, use_theme_colors; + + use_theme_colors = terminal_profile_get_property_boolean (profile, TERMINAL_PROFILE_USE_THEME_COLORS); + bold_locked = terminal_profile_property_locked (profile, TERMINAL_PROFILE_BOLD_COLOR); + bold_same_as_fg_locked = terminal_profile_property_locked (profile, TERMINAL_PROFILE_BOLD_COLOR_SAME_AS_FG); + bold_same_as_fg = terminal_profile_get_property_boolean (profile, TERMINAL_PROFILE_BOLD_COLOR_SAME_AS_FG); + + SET_SENSITIVE ("bold-color-same-as-fg-checkbox", !use_theme_colors && !bold_same_as_fg_locked); + SET_SENSITIVE ("bold-colorpicker", !use_theme_colors && !bold_locked && !bold_same_as_fg); + SET_SENSITIVE ("bold-colorpicker-label", !use_theme_colors && ((!bold_same_as_fg && !bold_locked) || !bold_same_as_fg_locked)); + } + + if (!prop_name || prop_name == I_(TERMINAL_PROFILE_VISIBLE_NAME)) + SET_SENSITIVE ("profile-name-entry", + !terminal_profile_property_locked (profile, TERMINAL_PROFILE_VISIBLE_NAME)); + + if (!prop_name || prop_name == I_(TERMINAL_PROFILE_DEFAULT_SHOW_MENUBAR)) + SET_SENSITIVE ("show-menubar-checkbutton", + !terminal_profile_property_locked (profile, TERMINAL_PROFILE_DEFAULT_SHOW_MENUBAR)); + + if (!prop_name || prop_name == I_(TERMINAL_PROFILE_TITLE)) + SET_SENSITIVE ("title-entry", + !terminal_profile_property_locked (profile, TERMINAL_PROFILE_TITLE)); + + if (!prop_name || prop_name == I_(TERMINAL_PROFILE_TITLE_MODE)) + SET_SENSITIVE ("title-mode-combobox", + !terminal_profile_property_locked (profile, TERMINAL_PROFILE_TITLE_MODE)); + + if (!prop_name || prop_name == I_(TERMINAL_PROFILE_ALLOW_BOLD)) + SET_SENSITIVE ("allow-bold-checkbutton", + !terminal_profile_property_locked (profile, TERMINAL_PROFILE_ALLOW_BOLD)); + + if (!prop_name || prop_name == I_(TERMINAL_PROFILE_SILENT_BELL)) + SET_SENSITIVE ("bell-checkbutton", + !terminal_profile_property_locked (profile, TERMINAL_PROFILE_SILENT_BELL)); + + if (!prop_name || prop_name == I_(TERMINAL_PROFILE_WORD_CHARS)) + SET_SENSITIVE ("word-chars-entry", + !terminal_profile_property_locked (profile, TERMINAL_PROFILE_WORD_CHARS)); + + if (!prop_name || + prop_name == I_(TERMINAL_PROFILE_USE_CUSTOM_DEFAULT_SIZE) || + prop_name == I_(TERMINAL_PROFILE_DEFAULT_SIZE_COLUMNS) || + prop_name == I_(TERMINAL_PROFILE_DEFAULT_SIZE_ROWS)) + { + gboolean use_custom_default_size_locked = terminal_profile_property_locked (profile, TERMINAL_PROFILE_USE_CUSTOM_DEFAULT_SIZE); + gboolean use_custom_default_size = terminal_profile_get_property_boolean (profile, TERMINAL_PROFILE_USE_CUSTOM_DEFAULT_SIZE); + gboolean columns_locked = terminal_profile_property_locked (profile, TERMINAL_PROFILE_DEFAULT_SIZE_COLUMNS); + gboolean rows_locked = terminal_profile_property_locked (profile, TERMINAL_PROFILE_DEFAULT_SIZE_ROWS); + + SET_SENSITIVE ("use-custom-default-size-checkbutton", !use_custom_default_size_locked); + SET_SENSITIVE ("default-size-hbox", use_custom_default_size); + SET_SENSITIVE ("default-size-label", (!columns_locked || !rows_locked)); + SET_SENSITIVE ("default-size-columns-label", !columns_locked); + SET_SENSITIVE ("default-size-columns-spinbutton", !columns_locked); + SET_SENSITIVE ("default-size-rows-label", !rows_locked); + SET_SENSITIVE ("default-size-rows-spinbutton", !rows_locked); + } + + if (!prop_name || prop_name == I_(TERMINAL_PROFILE_SCROLLBAR_POSITION)) + SET_SENSITIVE ("scrollbar-position-combobox", + !terminal_profile_property_locked (profile, TERMINAL_PROFILE_SCROLLBAR_POSITION)); + + if (!prop_name || + prop_name == I_(TERMINAL_PROFILE_SCROLLBACK_LINES) || + prop_name == I_(TERMINAL_PROFILE_SCROLLBACK_UNLIMITED)) + { + gboolean scrollback_lines_locked = terminal_profile_property_locked (profile, TERMINAL_PROFILE_SCROLLBACK_LINES); + gboolean scrollback_unlimited_locked = terminal_profile_property_locked (profile, TERMINAL_PROFILE_SCROLLBACK_UNLIMITED); + gboolean scrollback_unlimited = terminal_profile_get_property_boolean (profile, TERMINAL_PROFILE_SCROLLBACK_UNLIMITED); + + SET_SENSITIVE ("scrollback-label", !scrollback_lines_locked); + SET_SENSITIVE ("scrollback-box", !scrollback_lines_locked && !scrollback_unlimited); + SET_SENSITIVE ("scrollback-unlimited-checkbutton", !scrollback_lines_locked && !scrollback_unlimited_locked); + } + + if (!prop_name || prop_name == I_(TERMINAL_PROFILE_SCROLL_ON_KEYSTROKE)) + SET_SENSITIVE ("scroll-on-keystroke-checkbutton", + !terminal_profile_property_locked (profile, TERMINAL_PROFILE_SCROLL_ON_KEYSTROKE)); + + if (!prop_name || prop_name == I_(TERMINAL_PROFILE_SCROLL_ON_OUTPUT)) + SET_SENSITIVE ("scroll-on-output-checkbutton", + !terminal_profile_property_locked (profile, TERMINAL_PROFILE_SCROLL_ON_OUTPUT)); + + if (!prop_name || prop_name == I_(TERMINAL_PROFILE_EXIT_ACTION)) + SET_SENSITIVE ("exit-action-combobox", + !terminal_profile_property_locked (profile, TERMINAL_PROFILE_EXIT_ACTION)); + + if (!prop_name || prop_name == I_(TERMINAL_PROFILE_LOGIN_SHELL)) + SET_SENSITIVE ("login-shell-checkbutton", + !terminal_profile_property_locked (profile, TERMINAL_PROFILE_LOGIN_SHELL)); + + if (!prop_name || prop_name == I_(TERMINAL_PROFILE_UPDATE_RECORDS)) + SET_SENSITIVE ("update-records-checkbutton", + !terminal_profile_property_locked (profile, TERMINAL_PROFILE_UPDATE_RECORDS)); + + if (!prop_name || prop_name == I_(TERMINAL_PROFILE_PALETTE)) + { + gboolean palette_locked = terminal_profile_property_locked (profile, TERMINAL_PROFILE_PALETTE); + SET_SENSITIVE ("palette-combobox", !palette_locked); + SET_SENSITIVE ("palette-table", !palette_locked); + } + + if (!prop_name || prop_name == I_(TERMINAL_PROFILE_BACKSPACE_BINDING)) + SET_SENSITIVE ("backspace-binding-combobox", + !terminal_profile_property_locked (profile, TERMINAL_PROFILE_BACKSPACE_BINDING)); + + if (!prop_name || prop_name == I_(TERMINAL_PROFILE_DELETE_BINDING)) + SET_SENSITIVE ("delete-binding-combobox", + !terminal_profile_property_locked (profile, TERMINAL_PROFILE_DELETE_BINDING)); + + if (!prop_name || prop_name == I_(TERMINAL_PROFILE_USE_THEME_COLORS)) + SET_SENSITIVE ("use-theme-colors-checkbutton", + !terminal_profile_property_locked (profile, TERMINAL_PROFILE_USE_THEME_COLORS)); + +#undef SET_INSENSITIVE +} + +static void +color_scheme_combo_changed_cb (GtkWidget *combo, + GParamSpec *pspec, + TerminalProfile *profile) +{ + guint i; + + i = gtk_combo_box_get_active (GTK_COMBO_BOX (combo)); + + if (i < G_N_ELEMENTS (color_schemes)) + { + g_signal_handlers_block_by_func (profile, G_CALLBACK (profile_colors_notify_scheme_combo_cb), combo); + g_object_set (profile, + TERMINAL_PROFILE_FOREGROUND_COLOR, &color_schemes[i].foreground, + TERMINAL_PROFILE_BACKGROUND_COLOR, &color_schemes[i].background, + NULL); + g_signal_handlers_unblock_by_func (profile, G_CALLBACK (profile_colors_notify_scheme_combo_cb), combo); + } + else + { + /* "custom" selected, no change */ + } +} + +static void +profile_colors_notify_scheme_combo_cb (TerminalProfile *profile, + GParamSpec *pspec, + GtkComboBox *combo) +{ + const GdkColor *fg, *bg; + guint i; + + fg = terminal_profile_get_property_boxed (profile, TERMINAL_PROFILE_FOREGROUND_COLOR); + bg = terminal_profile_get_property_boxed (profile, TERMINAL_PROFILE_BACKGROUND_COLOR); + + if (fg && bg) + { + for (i = 0; i < G_N_ELEMENTS (color_schemes); ++i) + { + if (gdk_color_equal (fg, &color_schemes[i].foreground) && + gdk_color_equal (bg, &color_schemes[i].background)) + break; + } + } + else + { + i = G_N_ELEMENTS (color_schemes); + } + /* If we didn't find a match, then we get the last combo box item which is "custom" */ + + g_signal_handlers_block_by_func (combo, G_CALLBACK (color_scheme_combo_changed_cb), profile); + gtk_combo_box_set_active (GTK_COMBO_BOX (combo), i); + g_signal_handlers_unblock_by_func (combo, G_CALLBACK (color_scheme_combo_changed_cb), profile); +} + +static void +palette_scheme_combo_changed_cb (GtkComboBox *combo, + GParamSpec *pspec, + TerminalProfile *profile) +{ + int i; + + i = gtk_combo_box_get_active (GTK_COMBO_BOX (combo)); + + g_signal_handlers_block_by_func (profile, G_CALLBACK (profile_colors_notify_scheme_combo_cb), combo); + if (i < TERMINAL_PALETTE_N_BUILTINS) + terminal_profile_set_palette_builtin (profile, i); + else + { + /* "custom" selected, no change */ + } + g_signal_handlers_unblock_by_func (profile, G_CALLBACK (profile_colors_notify_scheme_combo_cb), combo); +} + +static void +profile_palette_notify_scheme_combo_cb (TerminalProfile *profile, + GParamSpec *pspec, + GtkComboBox *combo) +{ + guint i; + + if (!terminal_profile_get_palette_is_builtin (profile, &i)) + /* If we didn't find a match, then we want the last combo + * box item which is "custom" + */ + i = TERMINAL_PALETTE_N_BUILTINS; + + g_signal_handlers_block_by_func (combo, G_CALLBACK (palette_scheme_combo_changed_cb), profile); + gtk_combo_box_set_active (combo, i); + g_signal_handlers_unblock_by_func (combo, G_CALLBACK (palette_scheme_combo_changed_cb), profile); +} + +static void +palette_color_notify_cb (GtkColorButton *button, + GParamSpec *pspec, + TerminalProfile *profile) +{ + GtkWidget *editor; + GdkColor color; + guint i; + + gtk_color_button_get_color (button, &color); + i = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (button), "palette-entry-index")); + + editor = gtk_widget_get_toplevel (GTK_WIDGET (button)); + g_signal_handlers_block_by_func (profile, G_CALLBACK (profile_palette_notify_colorpickers_cb), editor); + terminal_profile_modify_palette_entry (profile, i, &color); + g_signal_handlers_unblock_by_func (profile, G_CALLBACK (profile_palette_notify_colorpickers_cb), editor); +} + +static void +profile_palette_notify_colorpickers_cb (TerminalProfile *profile, + GParamSpec *pspec, + GtkWidget *editor) +{ + GtkWidget *w; + GdkColor colors[TERMINAL_PALETTE_SIZE]; + guint n_colors, i; + + n_colors = G_N_ELEMENTS (colors); + terminal_profile_get_palette (profile, colors, &n_colors); + + n_colors = MIN (n_colors, TERMINAL_PALETTE_SIZE); + for (i = 0; i < n_colors; i++) + { + char name[32]; + GdkColor old_color; + + g_snprintf (name, sizeof (name), "palette-colorpicker-%d", i + 1); + w = profile_editor_get_widget (editor, name); + + gtk_color_button_get_color (GTK_COLOR_BUTTON (w), &old_color); + if (!gdk_color_equal (&old_color, &colors[i])) + { + g_signal_handlers_block_by_func (w, G_CALLBACK (palette_color_notify_cb), profile); + gtk_color_button_set_color (GTK_COLOR_BUTTON (w), &colors[i]); + g_signal_handlers_unblock_by_func (w, G_CALLBACK (palette_color_notify_cb), profile); + } + } +} + +static void +custom_command_entry_changed_cb (GtkEntry *entry) +{ +#if GTK_CHECK_VERSION (2, 16, 0) + const char *command; + GError *error = NULL; + + command = gtk_entry_get_text (entry); + + if (g_shell_parse_argv (command, NULL, NULL, &error)) + { + gtk_entry_set_icon_from_stock (entry, GTK_PACK_END, NULL); + } + else + { + char *tooltip; + + gtk_entry_set_icon_from_stock (entry, GTK_PACK_END, GTK_STOCK_DIALOG_WARNING); + + tooltip = g_strdup_printf (_("Error parsing command: %s"), error->message); + gtk_entry_set_icon_tooltip_text (entry, GTK_PACK_END, tooltip); + g_free (tooltip); + + g_error_free (error); + } +#endif /* GTK+ >= 2.16.0 */ +} + +static void +visible_name_entry_changed_cb (GtkEntry *entry, + GtkWindow *window) +{ + const char *visible_name; + char *text; + + visible_name = gtk_entry_get_text (entry); + + text = g_strdup_printf (_("Editing Profile “%s”"), visible_name); + gtk_window_set_title (window, text); + g_free (text); +} + +static void +reset_compat_defaults_cb (GtkWidget *button, + TerminalProfile *profile) +{ + terminal_profile_reset_property (profile, TERMINAL_PROFILE_DELETE_BINDING); + terminal_profile_reset_property (profile, TERMINAL_PROFILE_BACKSPACE_BINDING); +} + +/* + * initialize widgets + */ + +static void +init_color_scheme_menu (GtkWidget *combo_box) +{ + int i; + + i = G_N_ELEMENTS (color_schemes); + while (i > 0) + { + gtk_combo_box_prepend_text (GTK_COMBO_BOX (combo_box), + _(color_schemes[--i].name)); + } +} + +static char* +format_percent_value (GtkScale *scale, + double val, + void *data) +{ + return g_strdup_printf ("%d%%", (int) (val * 100.0 + 0.5)); +} + +static void +init_background_darkness_scale (GtkWidget *scale) +{ + g_signal_connect (scale, "format-value", + G_CALLBACK (format_percent_value), + NULL); +} + + +static void +editor_response_cb (GtkWidget *editor, + int response, + gpointer use_data) +{ + if (response == GTK_RESPONSE_HELP) + { + terminal_util_show_help ("mate-terminal-prefs", GTK_WINDOW (editor)); + return; + } + + gtk_widget_destroy (editor); +} + +#if 0 +static GdkPixbuf * +create_preview_pixbuf (const gchar *filename) +{ + GdkPixbuf *pixbuf = NULL; + MateThumbnailFactory *thumbs; + const char *mime_type = NULL; + GFile *gfile; + GFileInfo *file_info; + + if (filename == NULL) + return NULL; + + gfile = g_file_new_for_uri (filename); + file_info = g_file_query_info (gfile, + G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, + 0, NULL, NULL); + if (file_info != NULL) + mime_type = g_file_info_get_content_type (file_info); + + g_object_unref (gfile); + + if (mime_type != NULL) + { + thumbs = mate_thumbnail_factory_new (MATE_THUMBNAIL_SIZE_NORMAL); + + pixbuf = mate_thumbnail_factory_generate_thumbnail (thumbs, + filename, + mime_type); + g_object_unref (thumbs); + } + + if (file_info != NULL) + g_object_unref (file_info); + + return pixbuf; +} + +static void +update_image_preview (GtkFileChooser *chooser) +{ + GtkWidget *image; + gchar *file; + + image = gtk_file_chooser_get_preview_widget (GTK_FILE_CHOOSER (chooser)); + file = gtk_file_chooser_get_preview_uri (chooser); + + if (file != NULL) { + + GdkPixbuf *pixbuf = NULL; + + pixbuf = create_preview_pixbuf (file); + g_free (file); + + if (pixbuf != NULL) { + gtk_image_set_from_pixbuf (GTK_IMAGE (image), pixbuf); + g_object_unref (pixbuf); + } + else { + gtk_image_set_from_stock (GTK_IMAGE (image), + "gtk-dialog-question", + GTK_ICON_SIZE_DIALOG); + } + } + gtk_file_chooser_set_preview_widget_active (chooser, file != NULL); +} +#endif + +static void +setup_background_filechooser (GtkWidget *filechooser, + TerminalProfile *profile) +{ + GtkFileFilter *filter; + const char *home_dir; + + filter = gtk_file_filter_new (); + gtk_file_filter_add_pixbuf_formats (filter); + gtk_file_filter_set_name (filter, _("Images")); + gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (filechooser), filter); + + gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (filechooser), TRUE); + + /* Start filechooser in $HOME instead of the current dir of the factory which is "/" */ + home_dir = g_get_home_dir (); + if (home_dir) + gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (filechooser), home_dir); + +#if 0 + GtkWidget *image_preview; + GdkPixbuf *pixbuf = NULL; + + image_preview = gtk_image_new (); + /* FIXMchpe this is bogus */ + pixbuf = create_preview_pixbuf (terminal_profile_get_property_string (profile, TERMINAL_PROFILE_BACKGROUND_IMAGE_FILE)); + if (pixbuf != NULL) + { + gtk_image_set_from_pixbuf (GTK_IMAGE (image_preview), pixbuf); + g_object_unref (pixbuf); + } + else + { + gtk_image_set_from_stock (GTK_IMAGE (image_preview), + "gtk-dialog-question", + GTK_ICON_SIZE_DIALOG); + } + + gtk_file_chooser_set_preview_widget (GTK_FILE_CHOOSER (filechooser), + image_preview); + gtk_file_chooser_set_use_preview_label (GTK_FILE_CHOOSER (filechooser), + FALSE); + gtk_widget_set_size_request (image_preview, 128, -1); + gtk_widget_show (image_preview); + + g_signal_connect (filechooser, "update-preview", + G_CALLBACK (update_image_preview), NULL); +#endif +} + +static void +profile_editor_destroyed (GtkWidget *editor, + TerminalProfile *profile) +{ + g_signal_handlers_disconnect_by_func (profile, G_CALLBACK (profile_forgotten_cb), editor); + g_signal_handlers_disconnect_by_func (profile, G_CALLBACK (profile_notify_sensitivity_cb), editor); + g_signal_handlers_disconnect_matched (profile, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, + G_CALLBACK (profile_colors_notify_scheme_combo_cb), NULL); + g_signal_handlers_disconnect_matched (profile, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, + G_CALLBACK (profile_palette_notify_scheme_combo_cb), NULL); + g_signal_handlers_disconnect_matched (profile, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, + G_CALLBACK (profile_palette_notify_colorpickers_cb), NULL); + + g_object_set_data (G_OBJECT (profile), "editor-window", NULL); + g_object_set_data (G_OBJECT (editor), "builder", NULL); +} + +static void +terminal_profile_editor_focus_widget (GtkWidget *editor, + const char *widget_name) +{ + GtkBuilder *builder; + GtkWidget *widget, *page, *page_parent; + + if (widget_name == NULL) + return; + + builder = g_object_get_data (G_OBJECT (editor), "builder"); + widget = GTK_WIDGET (gtk_builder_get_object (builder, widget_name)); + if (widget == NULL) + return; + + page = widget; + while (page != NULL && + (page_parent = gtk_widget_get_parent (page)) != NULL && + !GTK_IS_NOTEBOOK (page_parent)) + page = page_parent; + + page_parent = gtk_widget_get_parent (page); + if (page != NULL && GTK_IS_NOTEBOOK (page_parent)) { + GtkNotebook *notebook; + + notebook = GTK_NOTEBOOK (page_parent); + gtk_notebook_set_current_page (notebook, gtk_notebook_page_num (notebook, page)); + } + + if (gtk_widget_is_sensitive (widget)) + gtk_widget_grab_focus (widget); +} + +/** + * terminal_profile_edit: + * @profile: a #TerminalProfile + * @transient_parent: a #GtkWindow, or %NULL + * @widget_name: a widget name in the profile editor's UI, or %NULL + * + * Shows the profile editor with @profile, anchored to @transient_parent. + * If @widget_name is non-%NULL, focuses the corresponding widget and + * switches the notebook to its containing page. + */ +void +terminal_profile_edit (TerminalProfile *profile, + GtkWindow *transient_parent, + const char *widget_name) +{ + char *path; + GtkBuilder *builder; + GError *error = NULL; + GtkWidget *editor, *w; + guint i; + + editor = g_object_get_data (G_OBJECT (profile), "editor-window"); + if (editor) + { + terminal_profile_editor_focus_widget (editor, widget_name); + + gtk_window_set_transient_for (GTK_WINDOW (editor), + GTK_WINDOW (transient_parent)); + gtk_window_present (GTK_WINDOW (editor)); + return; + } + + path = g_build_filename (TERM_PKGDATADIR, "profile-preferences.ui", NULL); + builder = gtk_builder_new (); + if (!gtk_builder_add_from_file (builder, path, &error)) { + g_warning ("Failed to load %s: %s\n", path, error->message); + g_error_free (error); + g_free (path); + g_object_unref (builder); + return; + } + g_free (path); + + editor = (GtkWidget *) gtk_builder_get_object (builder, "profile-editor-dialog"); + g_object_set_data_full (G_OBJECT (editor), "builder", + builder, (GDestroyNotify) g_object_unref); + + /* Store the dialogue on the profile, so we can acccess it above to check if + * there's already a profile editor for this profile. + */ + g_object_set_data (G_OBJECT (profile), "editor-window", editor); + + g_signal_connect (editor, "destroy", + G_CALLBACK (profile_editor_destroyed), + profile); + + g_signal_connect (editor, "response", + G_CALLBACK (editor_response_cb), + NULL); + + w = (GtkWidget *) gtk_builder_get_object (builder, "color-scheme-combobox"); + init_color_scheme_menu (w); + + w = (GtkWidget *) gtk_builder_get_object (builder, "darken-background-scale"); + init_background_darkness_scale (w); + + w = (GtkWidget *) gtk_builder_get_object (builder, "background-image-filechooser"); + setup_background_filechooser (w, profile); + + /* Hook up the palette colorpickers and combo box */ + + for (i = 0; i < TERMINAL_PALETTE_SIZE; ++i) + { + char name[32]; + char *text; + + g_snprintf (name, sizeof (name), "palette-colorpicker-%u", i + 1); + w = (GtkWidget *) gtk_builder_get_object (builder, name); + + g_object_set_data (G_OBJECT (w), "palette-entry-index", GUINT_TO_POINTER (i)); + + text = g_strdup_printf (_("Choose Palette Color %d"), i + 1); + gtk_color_button_set_title (GTK_COLOR_BUTTON (w), text); + g_free (text); + + text = g_strdup_printf (_("Palette entry %d"), i + 1); + gtk_widget_set_tooltip_text (w, text); + g_free (text); + + g_signal_connect (w, "notify::color", + G_CALLBACK (palette_color_notify_cb), + profile); + } + + profile_palette_notify_colorpickers_cb (profile, NULL, editor); + g_signal_connect (profile, "notify::" TERMINAL_PROFILE_PALETTE, + G_CALLBACK (profile_palette_notify_colorpickers_cb), + editor); + + w = (GtkWidget *) gtk_builder_get_object (builder, "palette-combobox"); + g_signal_connect (w, "notify::active", + G_CALLBACK (palette_scheme_combo_changed_cb), + profile); + + profile_palette_notify_scheme_combo_cb (profile, NULL, GTK_COMBO_BOX (w)); + g_signal_connect (profile, "notify::" TERMINAL_PROFILE_PALETTE, + G_CALLBACK (profile_palette_notify_scheme_combo_cb), + w); + + /* Hook up the color scheme pickers and combo box */ + w = (GtkWidget *) gtk_builder_get_object (builder, "color-scheme-combobox"); + g_signal_connect (w, "notify::active", + G_CALLBACK (color_scheme_combo_changed_cb), + profile); + + profile_colors_notify_scheme_combo_cb (profile, NULL, GTK_COMBO_BOX (w)); + g_signal_connect (profile, "notify::" TERMINAL_PROFILE_FOREGROUND_COLOR, + G_CALLBACK (profile_colors_notify_scheme_combo_cb), + w); + g_signal_connect (profile, "notify::" TERMINAL_PROFILE_BACKGROUND_COLOR, + G_CALLBACK (profile_colors_notify_scheme_combo_cb), + w); + +#define CONNECT_WITH_FLAGS(name, prop, flags) terminal_util_bind_object_property_to_widget (G_OBJECT (profile), prop, (GtkWidget *) gtk_builder_get_object (builder, name), flags) +#define CONNECT(name, prop) CONNECT_WITH_FLAGS (name, prop, 0) +#define SET_ENUM_VALUE(name, value) g_object_set_data (gtk_builder_get_object (builder, name), "enum-value", GINT_TO_POINTER (value)) + + w = GTK_WIDGET (gtk_builder_get_object (builder, "custom-command-entry")); + custom_command_entry_changed_cb (GTK_ENTRY (w)); + g_signal_connect (w, "changed", + G_CALLBACK (custom_command_entry_changed_cb), NULL); + w = GTK_WIDGET (gtk_builder_get_object (builder, "profile-name-entry")); + g_signal_connect (w, "changed", + G_CALLBACK (visible_name_entry_changed_cb), editor); + + g_signal_connect (gtk_builder_get_object (builder, "reset-compat-defaults-button"), + "clicked", + G_CALLBACK (reset_compat_defaults_cb), + profile); + + SET_ENUM_VALUE ("image-radiobutton", TERMINAL_BACKGROUND_IMAGE); + SET_ENUM_VALUE ("solid-radiobutton", TERMINAL_BACKGROUND_SOLID); + SET_ENUM_VALUE ("transparent-radiobutton", TERMINAL_BACKGROUND_TRANSPARENT); + CONNECT ("allow-bold-checkbutton", TERMINAL_PROFILE_ALLOW_BOLD); + CONNECT ("background-colorpicker", TERMINAL_PROFILE_BACKGROUND_COLOR); + CONNECT ("background-image-filechooser", TERMINAL_PROFILE_BACKGROUND_IMAGE_FILE); + CONNECT ("backspace-binding-combobox", TERMINAL_PROFILE_BACKSPACE_BINDING); + CONNECT ("bold-color-same-as-fg-checkbox", TERMINAL_PROFILE_BOLD_COLOR_SAME_AS_FG); + CONNECT ("bold-colorpicker", TERMINAL_PROFILE_BOLD_COLOR); + CONNECT ("cursor-shape-combobox", TERMINAL_PROFILE_CURSOR_SHAPE); + CONNECT ("custom-command-entry", TERMINAL_PROFILE_CUSTOM_COMMAND); + CONNECT ("darken-background-scale", TERMINAL_PROFILE_BACKGROUND_DARKNESS); + CONNECT ("default-size-columns-spinbutton", TERMINAL_PROFILE_DEFAULT_SIZE_COLUMNS); + CONNECT ("default-size-rows-spinbutton", TERMINAL_PROFILE_DEFAULT_SIZE_ROWS); + CONNECT ("delete-binding-combobox", TERMINAL_PROFILE_DELETE_BINDING); + CONNECT ("exit-action-combobox", TERMINAL_PROFILE_EXIT_ACTION); + CONNECT ("font-selector", TERMINAL_PROFILE_FONT); + CONNECT ("foreground-colorpicker", TERMINAL_PROFILE_FOREGROUND_COLOR); + CONNECT ("image-radiobutton", TERMINAL_PROFILE_BACKGROUND_TYPE); + CONNECT ("login-shell-checkbutton", TERMINAL_PROFILE_LOGIN_SHELL); + CONNECT ("profile-name-entry", TERMINAL_PROFILE_VISIBLE_NAME); + CONNECT ("scrollback-lines-spinbutton", TERMINAL_PROFILE_SCROLLBACK_LINES); + CONNECT ("scrollback-unlimited-checkbutton", TERMINAL_PROFILE_SCROLLBACK_UNLIMITED); + CONNECT ("scroll-background-checkbutton", TERMINAL_PROFILE_SCROLL_BACKGROUND); + CONNECT ("scrollbar-position-combobox", TERMINAL_PROFILE_SCROLLBAR_POSITION); + CONNECT ("scroll-on-keystroke-checkbutton", TERMINAL_PROFILE_SCROLL_ON_KEYSTROKE); + CONNECT ("scroll-on-output-checkbutton", TERMINAL_PROFILE_SCROLL_ON_OUTPUT); + CONNECT ("show-menubar-checkbutton", TERMINAL_PROFILE_DEFAULT_SHOW_MENUBAR); + CONNECT ("solid-radiobutton", TERMINAL_PROFILE_BACKGROUND_TYPE); + CONNECT ("system-font-checkbutton", TERMINAL_PROFILE_USE_SYSTEM_FONT); + CONNECT ("title-entry", TERMINAL_PROFILE_TITLE); + CONNECT ("title-mode-combobox", TERMINAL_PROFILE_TITLE_MODE); + CONNECT ("transparent-radiobutton", TERMINAL_PROFILE_BACKGROUND_TYPE); + CONNECT ("update-records-checkbutton", TERMINAL_PROFILE_UPDATE_RECORDS); + CONNECT ("use-custom-command-checkbutton", TERMINAL_PROFILE_USE_CUSTOM_COMMAND); + CONNECT ("use-custom-default-size-checkbutton", TERMINAL_PROFILE_USE_CUSTOM_DEFAULT_SIZE); + CONNECT ("use-theme-colors-checkbutton", TERMINAL_PROFILE_USE_THEME_COLORS); + CONNECT ("word-chars-entry", TERMINAL_PROFILE_WORD_CHARS); + CONNECT_WITH_FLAGS ("bell-checkbutton", TERMINAL_PROFILE_SILENT_BELL, FLAG_INVERT_BOOL); + +#undef CONNECT +#undef CONNECT_WITH_FLAGS +#undef SET_ENUM_VALUE + + profile_notify_sensitivity_cb (profile, NULL, editor); + g_signal_connect (profile, "notify", + G_CALLBACK (profile_notify_sensitivity_cb), + editor); + g_signal_connect (profile, + "forgotten", + G_CALLBACK (profile_forgotten_cb), + editor); + + terminal_profile_editor_focus_widget (editor, widget_name); + + gtk_window_set_transient_for (GTK_WINDOW (editor), + GTK_WINDOW (transient_parent)); + gtk_window_present (GTK_WINDOW (editor)); +} |