Install ILexer.h as well
[geany-mirror.git] / src / prefs.c
blob68e6648fd4e4fd0d4f908c312988ed3d9a56fa3e
1 /*
2 * prefs.c - this file is part of Geany, a fast and lightweight IDE
4 * Copyright 2005-2010 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
5 * Copyright 2006-2010 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 * $Id$
25 * @file prefs.h
26 * Preferences dialog.
30 * Preferences dialog support functions.
31 * New 'simple' prefs should use Stash code in keyfile.c - init_pref_groups().
34 #include <stdlib.h>
35 #include <string.h>
36 #include <gdk/gdkkeysyms.h>
38 #include "geany.h"
40 #include "prefs.h"
41 #include "support.h"
42 #include "dialogs.h"
43 #include "ui_utils.h"
44 #include "utils.h"
45 #include "sciwrappers.h"
46 #include "document.h"
47 #include "documentprivate.h"
48 #include "msgwindow.h"
49 #include "keyfile.h"
50 #include "keybindings.h"
51 #include "interface.h"
52 #include "encodings.h"
53 #include "project.h"
54 #include "editor.h"
55 #include "main.h"
56 #include "sidebar.h"
57 #include "printing.h"
58 #include "geanywraplabel.h"
59 #include "templates.h"
60 #include "search.h"
61 #include "toolbar.h"
62 #include "stash.h"
63 #include "keyfile.h"
64 #include "filetypes.h"
65 #include "win32.h"
67 #ifdef HAVE_VTE
68 # include "vte.h"
69 #endif
72 GeanyPrefs prefs;
73 GeanyToolPrefs tool_prefs;
76 static GtkTreeIter g_iter;
77 static GtkTreeStore *store = NULL;
78 static GtkTreeView *tree = NULL;
79 static GtkWidget *dialog_label;
80 static gboolean edited = FALSE;
82 static void kb_cell_edited_cb(GtkCellRendererText *cellrenderertext, gchar *path, gchar *new_text, gpointer user_data);
83 static gboolean kb_grab_key_dialog_key_press_cb(GtkWidget *dialog, GdkEventKey *event, gpointer user_data);
84 static void kb_grab_key_dialog_response_cb(GtkWidget *dialog, gint response, gpointer user_data);
85 static gboolean kb_find_duplicate(GtkWidget *parent, GeanyKeyBinding *search_kb,
86 guint key, GdkModifierType mods, const gchar *shortcut);
87 static void on_toolbar_show_toggled(GtkToggleButton *togglebutton, gpointer user_data);
88 static void on_show_notebook_tabs_toggled(GtkToggleButton *togglebutton, gpointer user_data);
89 static void on_enable_plugins_toggled(GtkToggleButton *togglebutton, gpointer user_data);
90 static void on_use_folding_toggled(GtkToggleButton *togglebutton, gpointer user_data);
91 static void on_open_encoding_toggled(GtkToggleButton *togglebutton, gpointer user_data);
92 static void on_sidebar_visible_toggled(GtkToggleButton *togglebutton, gpointer user_data);
93 static void on_prefs_print_radio_button_toggled(GtkToggleButton *togglebutton, gpointer user_data);
94 static void on_prefs_print_page_header_toggled(GtkToggleButton *togglebutton, gpointer user_data);
97 typedef enum PrefCallbackAction
99 PREF_DISPLAY,
100 PREF_UPDATE
102 PrefCallbackAction;
105 /* Synchronize Stash settings with widgets (see keyfile.c - init_pref_groups()). */
106 static void prefs_action(PrefCallbackAction action)
108 StashGroup *group;
109 guint i;
111 foreach_ptr_array(group, i, pref_groups)
113 switch (action)
115 case PREF_DISPLAY:
116 stash_group_display(group, ui_widgets.prefs_dialog);
117 break;
118 case PREF_UPDATE:
119 stash_group_update(group, ui_widgets.prefs_dialog);
120 break;
126 enum
128 KB_TREE_ACTION,
129 KB_TREE_SHORTCUT,
130 KB_TREE_INDEX
134 static void kb_tree_view_change_button_clicked_cb(GtkWidget *button, gpointer data)
136 GtkTreeModel *model;
137 GtkTreeSelection *selection;
138 gchar *name;
140 selection = gtk_tree_view_get_selection(tree);
141 if (gtk_tree_selection_get_selected(selection, &model, &g_iter))
143 if (gtk_tree_model_iter_has_child(model, &g_iter))
144 { /* double click on a section to expand or collapse it */
145 GtkTreePath *path = gtk_tree_model_get_path(model, &g_iter);
147 if (gtk_tree_view_row_expanded(tree, path))
148 gtk_tree_view_collapse_row(tree, path);
149 else
150 gtk_tree_view_expand_row(tree, path, FALSE);
152 gtk_tree_path_free(path);
153 return;
156 gtk_tree_model_get(model, &g_iter, KB_TREE_ACTION, &name, -1);
157 if (name != NULL)
159 GtkWidget *dialog;
160 GtkWidget *label;
161 gchar *str;
163 dialog = gtk_dialog_new_with_buttons(_("Grab Key"), GTK_WINDOW(ui_widgets.prefs_dialog),
164 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
165 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
166 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
168 str = g_strdup_printf(
169 _("Press the combination of the keys you want to use for \"%s\"."), name);
170 label = gtk_label_new(str);
171 gtk_misc_set_padding(GTK_MISC(label), 5, 10);
172 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
174 dialog_label = gtk_label_new("");
175 gtk_misc_set_padding(GTK_MISC(dialog_label), 5, 10);
176 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), dialog_label);
178 g_signal_connect(dialog, "key-press-event",
179 G_CALLBACK(kb_grab_key_dialog_key_press_cb), NULL);
180 g_signal_connect(dialog, "response", G_CALLBACK(kb_grab_key_dialog_response_cb), NULL);
182 gtk_widget_show_all(dialog);
183 g_free(str);
184 g_free(name);
190 static void kb_expand_collapse_cb(GtkWidget *item, gpointer user_data)
192 if (user_data != NULL)
193 gtk_tree_view_expand_all(tree);
194 else
195 gtk_tree_view_collapse_all(tree);
199 static void kb_show_popup_menu(GtkWidget *widget, GdkEventButton *event)
201 GtkWidget *item;
202 static GtkWidget *menu = NULL;
203 gint button, event_time;
205 if (menu == NULL)
207 menu = gtk_menu_new();
209 item = ui_image_menu_item_new(GTK_STOCK_ADD, _("_Expand All"));
210 gtk_widget_show(item);
211 gtk_container_add(GTK_CONTAINER(menu), item);
212 g_signal_connect(item, "activate", G_CALLBACK(kb_expand_collapse_cb), GINT_TO_POINTER(TRUE));
214 item = ui_image_menu_item_new(GTK_STOCK_REMOVE, _("_Collapse All"));
215 gtk_widget_show(item);
216 gtk_container_add(GTK_CONTAINER(menu), item);
217 g_signal_connect(item, "activate", G_CALLBACK(kb_expand_collapse_cb), NULL);
219 gtk_menu_attach_to_widget(GTK_MENU(menu), widget, NULL);
222 if (event != NULL)
224 button = event->button;
225 event_time = event->time;
227 else
229 button = 0;
230 event_time = gtk_get_current_event_time();
233 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, button, event_time);
237 static gboolean kb_popup_menu_cb(GtkWidget *widget, gpointer data)
239 kb_show_popup_menu(widget, NULL);
240 return TRUE;
244 static gboolean kb_tree_view_button_press_event_cb(GtkWidget *widget, GdkEventButton *event,
245 gpointer user_data)
247 if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
249 kb_show_popup_menu(widget, event);
250 return TRUE;
252 else if (event->type == GDK_2BUTTON_PRESS)
254 kb_tree_view_change_button_clicked_cb(NULL, NULL);
255 return TRUE;
257 return FALSE;
261 static void kb_init_tree(void)
263 GtkCellRenderer *renderer;
264 GtkTreeViewColumn *column;
266 tree = GTK_TREE_VIEW(ui_lookup_widget(ui_widgets.prefs_dialog, "treeview7"));
268 store = gtk_tree_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT);
269 gtk_tree_view_set_model(GTK_TREE_VIEW(tree), GTK_TREE_MODEL(store));
270 g_object_unref(store);
272 renderer = gtk_cell_renderer_text_new();
273 column = gtk_tree_view_column_new_with_attributes(_("Action"), renderer, "text", KB_TREE_ACTION, NULL);
274 gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
276 renderer = gtk_cell_renderer_text_new();
277 g_object_set(renderer, "editable", TRUE, NULL);
278 column = gtk_tree_view_column_new_with_attributes(_("Shortcut"), renderer, "text", KB_TREE_SHORTCUT, NULL);
279 gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
281 /* set policy settings for the scrolled window around the treeview again, because glade
282 * doesn't keep the settings */
283 gtk_scrolled_window_set_policy(
284 GTK_SCROLLED_WINDOW(ui_lookup_widget(ui_widgets.prefs_dialog, "scrolledwindow8")),
285 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
287 g_signal_connect(renderer, "edited", G_CALLBACK(kb_cell_edited_cb), NULL);
288 g_signal_connect(tree, "button-press-event", G_CALLBACK(kb_tree_view_button_press_event_cb), NULL);
289 g_signal_connect(tree, "popup-menu", G_CALLBACK(kb_popup_menu_cb), NULL);
290 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "button2"), "clicked",
291 G_CALLBACK(kb_tree_view_change_button_clicked_cb), NULL);
295 static void kb_init(void)
297 GtkTreeIter parent, iter;
298 gsize g, i;
299 gchar *key_string, *label;
300 GeanyKeyGroup *group;
301 GeanyKeyBinding *kb;
303 if (store == NULL)
304 kb_init_tree();
306 foreach_ptr_array(group, g, keybinding_groups)
308 gtk_tree_store_append(store, &parent, NULL);
309 gtk_tree_store_set(store, &parent, KB_TREE_ACTION, group->label,
310 KB_TREE_INDEX, g, -1);
312 foreach_ptr_array(kb, i, group->key_items)
314 label = keybindings_get_label(kb);
315 key_string = gtk_accelerator_name(kb->key, kb->mods);
316 gtk_tree_store_append(store, &iter, &parent);
317 gtk_tree_store_set(store, &iter, KB_TREE_ACTION, label,
318 KB_TREE_SHORTCUT, key_string, KB_TREE_INDEX, kb->id, -1);
319 g_free(key_string);
320 g_free(label);
323 gtk_tree_view_expand_all(GTK_TREE_VIEW(tree));
327 /* note: new 'simple' prefs should use Stash code in keyfile.c */
328 static void prefs_init_dialog(void)
330 GtkWidget *widget;
331 GdkColor *color;
333 /* Synchronize with Stash settings */
334 prefs_action(PREF_DISPLAY);
336 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "label_project_indent_warning");
337 ui_widget_show_hide(widget, app->project != NULL);
339 /* General settings */
340 /* startup */
341 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_load_session");
342 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.load_session);
344 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_project_session");
345 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), project_prefs.project_session);
347 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_project_file_in_basedir");
348 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), project_prefs.project_file_in_basedir);
350 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_save_win_pos");
351 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.save_winpos);
353 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ask_for_quit");
354 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.confirm_exit);
356 /* behaviour */
357 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_beep");
358 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.beep_on_errors);
360 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_switch_pages");
361 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.switch_to_status);
363 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_suppress_status_msgs");
364 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.suppress_status_messages);
366 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_auto_focus");
367 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.auto_focus);
369 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_native_windows_dialogs");
370 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
371 interface_prefs.use_native_windows_dialogs);
373 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_contextaction");
374 gtk_entry_set_text(GTK_ENTRY(widget), tool_prefs.context_action_cmd);
376 project_setup_prefs(); /* project files path */
379 /* Interface settings */
380 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_sidebar_visible");
381 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), ui_prefs.sidebar_visible);
382 on_sidebar_visible_toggled(GTK_TOGGLE_BUTTON(widget), NULL);
384 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_symbol");
385 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), interface_prefs.sidebar_symbol_visible);
387 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_openfiles");
388 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), interface_prefs.sidebar_openfiles_visible);
390 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "tagbar_font");
391 gtk_font_button_set_font_name(GTK_FONT_BUTTON(widget), interface_prefs.tagbar_font);
393 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "msgwin_font");
394 gtk_font_button_set_font_name(GTK_FONT_BUTTON(widget), interface_prefs.msgwin_font);
396 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "editor_font");
397 gtk_font_button_set_font_name(GTK_FONT_BUTTON(widget), interface_prefs.editor_font);
399 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_long_line");
400 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), editor_prefs.long_line_global_column);
402 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_long_line");
403 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.long_line_global_enabled);
405 switch (editor_prefs.long_line_global_type)
407 case 0: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_long_line_line"); break;
408 case 1: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_long_line_background"); break;
410 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
412 color = g_new0(GdkColor, 1);
413 gdk_color_parse(editor_prefs.long_line_color, color);
414 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "long_line_color");
415 gtk_color_button_set_color(GTK_COLOR_BUTTON(widget), color);
416 g_free(color);
418 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_notebook_tabs");
419 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), interface_prefs.show_notebook_tabs);
420 /* disable following setting if notebook tabs are hidden */
421 on_show_notebook_tabs_toggled(GTK_TOGGLE_BUTTON(
422 ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_notebook_tabs")), NULL);
424 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_tab_cross");
425 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.show_tab_cross);
427 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_editor");
428 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), interface_prefs.tab_pos_editor);
430 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_msgwin");
431 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), interface_prefs.tab_pos_msgwin);
433 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_sidebar");
434 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), interface_prefs.tab_pos_sidebar);
436 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_statusbar_visible");
437 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), interface_prefs.statusbar_visible);
440 /* Toolbar settings */
441 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_show");
442 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), toolbar_prefs.visible);
443 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_in_menu");
444 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), toolbar_prefs.append_to_menu);
446 switch (toolbar_prefs.icon_style)
448 case 0: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_image"); break;
449 case 1: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_text"); break;
450 default: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_imagetext"); break;
452 if (toolbar_prefs.use_gtk_default_style)
453 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_style_default");
454 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
456 switch (toolbar_prefs.icon_size)
458 case GTK_ICON_SIZE_LARGE_TOOLBAR:
459 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_large"); break;
460 case GTK_ICON_SIZE_SMALL_TOOLBAR:
461 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_small"); break;
462 default: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_verysmall"); break;
464 if (toolbar_prefs.use_gtk_default_icon)
465 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_icon_default");
466 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
468 /* disable elements if toolbar is hidden */
469 on_toolbar_show_toggled(GTK_TOGGLE_BUTTON(
470 ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_show")), NULL);
473 /* Files settings */
474 if (file_prefs.tab_order_ltr)
475 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_tab_right");
476 else
477 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_tab_left");
478 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
480 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_tab_beside");
481 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.tab_order_beside);
483 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_new_encoding");
484 /* luckily the index of the combo box items match the index of the encodings array */
485 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), file_prefs.default_new_encoding);
487 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_open_encoding");
488 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
489 (file_prefs.default_open_encoding >= 0) ? TRUE : FALSE);
490 on_open_encoding_toggled(GTK_TOGGLE_BUTTON(widget), NULL);
492 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_open_encoding");
493 if (file_prefs.default_open_encoding >= 0)
495 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), file_prefs.default_open_encoding);
497 else
498 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), GEANY_ENCODING_UTF_8);
500 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_eol");
501 if (file_prefs.default_eol_character >= 0 && file_prefs.default_eol_character < 3)
503 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), file_prefs.default_eol_character);
505 else
506 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), GEANY_DEFAULT_EOL_CHARACTER);
508 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_trailing_spaces");
509 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.strip_trailing_spaces);
511 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_new_line");
512 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.final_new_line);
514 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ensure_convert_new_lines");
515 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.ensure_convert_new_lines);
517 /* Editor settings */
518 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_toggle_mark");
519 gtk_entry_set_text(GTK_ENTRY(widget), editor_prefs.comment_toggle_mark);
521 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_replace_tabs");
522 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.replace_tabs);
524 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_indent");
525 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_indent_guide);
527 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_white_space");
528 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_white_space);
530 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_end");
531 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_line_endings);
533 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_numbers");
534 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_linenumber_margin);
536 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_markers_margin");
537 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_markers_margin);
539 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_stop_at_last_line");
540 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.scroll_stop_at_last_line);
542 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_wrapping");
543 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.line_wrapping);
545 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_complete_snippets");
546 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.complete_snippets);
548 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_xmltag");
549 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.auto_close_xml_tags);
551 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_folding");
552 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.folding);
554 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_unfold_children");
555 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.unfold_all_children);
556 on_use_folding_toggled(GTK_TOGGLE_BUTTON(
557 ui_lookup_widget(ui_widgets.prefs_dialog, "check_folding")), NULL);
559 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_disable_dnd");
560 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.disable_dnd);
562 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_smart_home");
563 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.smart_home_key);
565 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_newline_strip");
566 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.newline_strip);
568 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_indicators");
569 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.use_indicators);
571 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_auto_multiline");
572 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.auto_continue_multiline);
574 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_symbol_auto_completion");
575 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.auto_complete_symbols);
577 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_symbollistheight");
578 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), editor_prefs.symbolcompletion_max_height);
580 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_symbol_complete_chars");
581 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), editor_prefs.symbolcompletion_min_chars);
583 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_line_break");
584 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), editor_prefs.line_break_column);
586 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_parenthesis");
587 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
588 (editor_prefs.autoclose_chars & GEANY_AC_PARENTHESIS));
590 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_cbracket");
591 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
592 (editor_prefs.autoclose_chars & GEANY_AC_CBRACKET));
594 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_sbracket");
595 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
596 (editor_prefs.autoclose_chars & GEANY_AC_SBRACKET));
598 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_squote");
599 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
600 (editor_prefs.autoclose_chars & GEANY_AC_SQUOTE));
602 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_dquote");
603 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
604 (editor_prefs.autoclose_chars & GEANY_AC_DQUOTE));
606 /* Tools Settings */
608 if (tool_prefs.term_cmd)
609 gtk_entry_set_text(GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_term")), tool_prefs.term_cmd);
611 if (tool_prefs.browser_cmd)
612 gtk_entry_set_text(GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_browser")), tool_prefs.browser_cmd);
614 if (tool_prefs.grep_cmd)
615 gtk_entry_set_text(GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_grep")), tool_prefs.grep_cmd);
618 /* Template settings */
619 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_developer");
620 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.developer);
622 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_company");
623 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.company);
625 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_mail");
626 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.mail);
628 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_initial");
629 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.initials);
631 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_version");
632 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.version);
634 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_year");
635 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.year_format);
637 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_date");
638 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.date_format);
640 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_datetime");
641 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.datetime_format);
644 /* Keybindings */
645 kb_init();
647 /* Printing */
649 GtkWidget *widget_gtk = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_print_gtk");
650 if (printing_prefs.use_gtk_printing)
651 widget = widget_gtk;
652 else
653 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_print_external");
655 #if GTK_CHECK_VERSION(2, 10, 0)
656 if (gtk_check_version(2, 10, 0) != NULL)
657 #endif
659 gtk_widget_set_sensitive(widget_gtk, FALSE); /* disable the whole option block */
660 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_print_external");
662 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
664 on_prefs_print_radio_button_toggled(GTK_TOGGLE_BUTTON(widget_gtk), NULL);
666 if (printing_prefs.external_print_cmd)
667 gtk_entry_set_text(
668 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_external_cmd")),
669 printing_prefs.external_print_cmd);
671 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_linenumbers");
672 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), printing_prefs.print_line_numbers);
674 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pagenumbers");
675 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), printing_prefs.print_page_numbers);
677 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pageheader");
678 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), printing_prefs.print_page_header);
679 on_prefs_print_page_header_toggled(GTK_TOGGLE_BUTTON(widget), NULL);
681 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_basename");
682 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), printing_prefs.page_header_basename);
684 if (printing_prefs.page_header_datefmt)
685 gtk_entry_set_text(
686 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_dateformat")),
687 printing_prefs.page_header_datefmt);
690 #ifndef HAVE_PLUGINS
691 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_plugins"), FALSE);
692 #endif
693 on_enable_plugins_toggled(GTK_TOGGLE_BUTTON( ui_lookup_widget(ui_widgets.prefs_dialog, "check_plugins")), NULL);
695 #ifdef HAVE_VTE
696 /* make VTE switch visible only when VTE is compiled in, it is hidden by default */
697 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_vte");
698 gtk_widget_show(widget);
699 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vte_info.load_vte);
701 /* VTE settings */
702 if (vte_info.have_vte)
704 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "font_term");
705 gtk_font_button_set_font_name(GTK_FONT_BUTTON(widget), vc->font);
707 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "color_fore");
708 gtk_color_button_set_color(GTK_COLOR_BUTTON(widget), vc->colour_fore);
710 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "color_back");
711 gtk_color_button_set_color(GTK_COLOR_BUTTON(widget), vc->colour_back);
713 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_scrollback");
714 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), vc->scrollback_lines);
716 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_shell");
717 gtk_entry_set_text(GTK_ENTRY(widget), vc->shell);
719 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_key");
720 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->scroll_on_key);
722 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_out");
723 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->scroll_on_out);
725 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_enable_bash_keys");
726 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->enable_bash_keys);
728 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ignore_menu_key");
729 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->ignore_menu_bar_accel);
731 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_follow_path");
732 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->follow_path);
734 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_run_in_vte");
735 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->run_in_vte);
737 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_skip_script");
738 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->skip_run_script);
740 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_cursor_blinks");
741 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->cursor_blinks);
743 #endif
747 /* read the treeview shortcut fields into keybindings */
748 static void kb_update(void)
750 GtkTreeModel *model = GTK_TREE_MODEL(store);
751 GtkTreeIter child, parent;
752 guint gid = 0;
754 /* get first parent */
755 if (! gtk_tree_model_iter_children(model, &parent, NULL))
756 return;
758 /* foreach parent */
759 while (TRUE)
761 /* get first child */
762 if (! gtk_tree_model_iter_children(model, &child, &parent))
763 return;
765 /* foreach child */
766 while (TRUE)
768 guint kid;
769 gchar *str;
770 guint key;
771 GdkModifierType mods;
772 GeanyKeyBinding *kb;
774 gtk_tree_model_get(model, &child, KB_TREE_INDEX, &kid, KB_TREE_SHORTCUT, &str, -1);
775 gtk_accelerator_parse(str, &key, &mods);
776 g_free(str);
777 kb = keybindings_lookup_item(gid, kid);
778 if (kb->key != key || kb->mods != mods)
779 keybindings_update_combo(kb, key, mods);
781 if (! gtk_tree_model_iter_next(model, &child))
782 break;
784 if (! gtk_tree_model_iter_next(model, &parent))
785 return;
786 gid++;
792 * callbacks
794 /* note: new 'simple' prefs should use Stash code in keyfile.c */
795 static void
796 on_prefs_dialog_response(GtkDialog *dialog, gint response, gpointer user_data)
798 if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY)
800 GtkWidget *widget;
801 guint i;
802 guint autoclose_brackets[5];
803 gboolean old_invert_all = interface_prefs.highlighting_invert_all;
804 gboolean old_sidebar_pos = interface_prefs.sidebar_pos;
806 /* Synchronize Stash settings */
807 prefs_action(PREF_UPDATE);
809 if (interface_prefs.highlighting_invert_all != old_invert_all)
810 filetypes_reload();
812 if (interface_prefs.sidebar_pos != old_sidebar_pos)
813 ui_swap_sidebar_pos();
815 /* General settings */
816 /* startup */
817 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_load_session");
818 prefs.load_session = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
820 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_project_session");
821 project_prefs.project_session = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
823 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_project_file_in_basedir");
824 project_prefs.project_file_in_basedir = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
826 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_save_win_pos");
827 prefs.save_winpos = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
829 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ask_for_quit");
830 prefs.confirm_exit = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
832 /* behaviour */
833 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_beep");
834 prefs.beep_on_errors = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
836 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_switch_pages");
837 prefs.switch_to_status = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
839 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_suppress_status_msgs");
840 prefs.suppress_status_messages = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
842 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_auto_focus");
843 prefs.auto_focus = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
845 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_native_windows_dialogs");
846 interface_prefs.use_native_windows_dialogs =
847 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
849 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_contextaction");
850 g_free(tool_prefs.context_action_cmd);
851 tool_prefs.context_action_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
853 project_apply_prefs(); /* project file path */
856 /* Interface settings */
857 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_sidebar_visible");
858 ui_prefs.sidebar_visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
860 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_symbol");
861 interface_prefs.sidebar_symbol_visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
863 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_openfiles");
864 interface_prefs.sidebar_openfiles_visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
866 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_long_line");
867 editor_prefs.long_line_global_enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
869 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_long_line_line");
870 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
871 editor_prefs.long_line_global_type = 0;
872 else
873 /* now only the "background" radio remains */
874 editor_prefs.long_line_global_type = 1;
876 if (editor_prefs.long_line_global_column == 0)
877 editor_prefs.long_line_global_enabled = FALSE;
879 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_notebook_tabs");
880 interface_prefs.show_notebook_tabs = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
882 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_tab_cross");
883 file_prefs.show_tab_cross = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
885 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_editor");
886 interface_prefs.tab_pos_editor = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
888 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_msgwin");
889 interface_prefs.tab_pos_msgwin = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
891 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_sidebar");
892 interface_prefs.tab_pos_sidebar = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
894 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_statusbar_visible");
895 interface_prefs.statusbar_visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
898 /* Toolbar settings */
899 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_show");
900 toolbar_prefs.visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
901 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_in_menu");
902 toolbar_prefs.append_to_menu = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
904 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_style_default");
905 toolbar_prefs.use_gtk_default_style = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
906 if (! toolbar_prefs.use_gtk_default_style)
908 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_imagetext");
909 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
910 toolbar_prefs.icon_style = 2;
911 else
913 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_image");
914 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
915 toolbar_prefs.icon_style = 0;
916 else
917 /* now only the text only radio remains, so set text only */
918 toolbar_prefs.icon_style = 1;
922 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_icon_default");
923 toolbar_prefs.use_gtk_default_icon = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
924 if (! toolbar_prefs.use_gtk_default_icon)
925 { toolbar_prefs.icon_size = GTK_ICON_SIZE_LARGE_TOOLBAR;
926 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_large");
927 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
928 toolbar_prefs.icon_size = GTK_ICON_SIZE_LARGE_TOOLBAR;
929 else
931 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_small");
932 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
933 toolbar_prefs.icon_size = GTK_ICON_SIZE_SMALL_TOOLBAR;
934 else
935 toolbar_prefs.icon_size = GTK_ICON_SIZE_MENU;
939 /* Files settings */
940 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_tab_right");
941 file_prefs.tab_order_ltr = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
943 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_tab_beside");
944 file_prefs.tab_order_beside = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
946 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_new_encoding");
947 file_prefs.default_new_encoding = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
949 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_open_encoding");
950 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
952 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_open_encoding");
953 file_prefs.default_open_encoding = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
955 else
956 file_prefs.default_open_encoding = -1;
958 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_eol");
959 file_prefs.default_eol_character = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
961 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_trailing_spaces");
962 file_prefs.strip_trailing_spaces = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
964 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_new_line");
965 file_prefs.final_new_line = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
967 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ensure_convert_new_lines");
968 file_prefs.ensure_convert_new_lines = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
970 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_replace_tabs");
971 file_prefs.replace_tabs = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
974 /* Editor settings */
975 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_toggle_mark");
976 setptr(editor_prefs.comment_toggle_mark,
977 gtk_editable_get_chars(GTK_EDITABLE(widget), 0, -1));
979 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_long_line");
980 /* note: use stash for new code - it updates spin buttons itself */
981 gtk_spin_button_update(GTK_SPIN_BUTTON(widget));
982 editor_prefs.long_line_global_column = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
984 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_folding");
985 editor_prefs.folding = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
986 ui_update_fold_items();
988 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_unfold_children");
989 editor_prefs.unfold_all_children = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
991 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_indent");
992 editor_prefs.show_indent_guide = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
994 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_white_space");
995 editor_prefs.show_white_space = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
997 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_end");
998 editor_prefs.show_line_endings = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1000 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_numbers");
1001 editor_prefs.show_linenumber_margin = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1003 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_markers_margin");
1004 editor_prefs.show_markers_margin = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1006 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_stop_at_last_line");
1007 editor_prefs.scroll_stop_at_last_line = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1009 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_wrapping");
1010 editor_prefs.line_wrapping = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1012 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_complete_snippets");
1013 editor_prefs.complete_snippets = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1015 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_xmltag");
1016 editor_prefs.auto_close_xml_tags = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1018 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_indicators");
1019 editor_prefs.use_indicators = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1021 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_disable_dnd");
1022 editor_prefs.disable_dnd = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1024 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_smart_home");
1025 editor_prefs.smart_home_key = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1027 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_newline_strip");
1028 editor_prefs.newline_strip = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1030 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_auto_multiline");
1031 editor_prefs.auto_continue_multiline = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1033 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_symbol_auto_completion");
1034 editor_prefs.auto_complete_symbols = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1036 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_symbol_complete_chars");
1037 gtk_spin_button_update(GTK_SPIN_BUTTON(widget));
1038 editor_prefs.symbolcompletion_min_chars = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
1040 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_symbollistheight");
1041 gtk_spin_button_update(GTK_SPIN_BUTTON(widget));
1042 editor_prefs.symbolcompletion_max_height = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
1044 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_line_break");
1045 gtk_spin_button_update(GTK_SPIN_BUTTON(widget));
1046 editor_prefs.line_break_column = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
1048 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_parenthesis");
1049 autoclose_brackets[0] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1051 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_cbracket");
1052 autoclose_brackets[1] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1054 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_sbracket");
1055 autoclose_brackets[2] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1057 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_squote");
1058 autoclose_brackets[3] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1060 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_dquote");
1061 autoclose_brackets[4] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1063 editor_prefs.autoclose_chars =
1064 (autoclose_brackets[0] ? GEANY_AC_PARENTHESIS : 0)
1065 | (autoclose_brackets[1] ? GEANY_AC_CBRACKET : 0)
1066 | (autoclose_brackets[2] ? GEANY_AC_SBRACKET : 0)
1067 | (autoclose_brackets[3] ? GEANY_AC_SQUOTE : 0)
1068 | (autoclose_brackets[4] ? GEANY_AC_DQUOTE : 0);
1070 /* Tools Settings */
1072 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_term");
1073 g_free(tool_prefs.term_cmd);
1074 tool_prefs.term_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1076 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_browser");
1077 g_free(tool_prefs.browser_cmd);
1078 tool_prefs.browser_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1080 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_grep");
1081 g_free(tool_prefs.grep_cmd);
1082 tool_prefs.grep_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1085 /* Template settings */
1086 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_developer");
1087 g_free(template_prefs.developer);
1088 template_prefs.developer = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1090 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_company");
1091 g_free(template_prefs.company);
1092 template_prefs.company = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1094 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_mail");
1095 g_free(template_prefs.mail);
1096 template_prefs.mail = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1098 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_initial");
1099 g_free(template_prefs.initials);
1100 template_prefs.initials = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1102 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_version");
1103 g_free(template_prefs.version);
1104 template_prefs.version = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1106 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_year");
1107 g_free(template_prefs.year_format);
1108 template_prefs.year_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1110 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_date");
1111 g_free(template_prefs.date_format);
1112 template_prefs.date_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1114 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_datetime");
1115 g_free(template_prefs.datetime_format);
1116 template_prefs.datetime_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1119 /* Keybindings */
1120 if (edited)
1122 kb_update();
1123 keybindings_write_to_file();
1126 /* Printing */
1127 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_print_gtk");
1128 printing_prefs.use_gtk_printing = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1130 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_external_cmd");
1131 g_free(printing_prefs.external_print_cmd);
1132 printing_prefs.external_print_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1134 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_linenumbers");
1135 printing_prefs.print_line_numbers = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1137 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pagenumbers");
1138 printing_prefs.print_page_numbers = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1140 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pageheader");
1141 printing_prefs.print_page_header = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1143 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_basename");
1144 printing_prefs.page_header_basename = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1146 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_dateformat");
1147 g_free(printing_prefs.page_header_datefmt);
1148 printing_prefs.page_header_datefmt = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1151 #ifdef HAVE_VTE
1152 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_vte");
1153 vte_info.load_vte = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1155 /* VTE settings */
1156 if (vte_info.have_vte)
1158 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_scrollback");
1159 gtk_spin_button_update(GTK_SPIN_BUTTON(widget));
1160 vc->scrollback_lines = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
1162 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_shell");
1163 g_free(vc->shell);
1164 vc->shell = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1166 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_key");
1167 vc->scroll_on_key = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1169 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_out");
1170 vc->scroll_on_out = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1172 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_enable_bash_keys");
1173 vc->enable_bash_keys = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1175 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ignore_menu_key");
1176 vc->ignore_menu_bar_accel = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1178 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_follow_path");
1179 vc->follow_path = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1181 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_run_in_vte");
1182 vc->run_in_vte = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1184 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_skip_script");
1185 vc->skip_run_script = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1187 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_cursor_blinks");
1188 vc->cursor_blinks = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1190 vte_apply_user_settings();
1192 #endif
1194 /* apply the changes made */
1195 ui_statusbar_showhide(interface_prefs.statusbar_visible);
1196 sidebar_openfiles_update_all(); /* to update if full path setting has changed */
1197 toolbar_apply_settings();
1198 toolbar_update_ui();
1199 toolbar_show_hide();
1200 ui_sidebar_show_hide();
1201 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(main_widgets.notebook), interface_prefs.show_notebook_tabs);
1203 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(main_widgets.notebook), interface_prefs.tab_pos_editor);
1204 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(msgwindow.notebook), interface_prefs.tab_pos_msgwin);
1205 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(main_widgets.sidebar_notebook), interface_prefs.tab_pos_sidebar);
1207 /* re-colourise all open documents, if tab width or long line settings have changed */
1208 for (i = 0; i < documents_array->len; i++)
1210 if (documents[i]->is_valid)
1212 editor_apply_update_prefs(documents[i]->editor);
1213 if (! editor_prefs.folding)
1214 editor_unfold_all(documents[i]->editor);
1217 ui_document_show_hide(NULL);
1218 ui_update_view_editor_menu_items();
1220 /* store all settings */
1221 configuration_save();
1224 if (response != GTK_RESPONSE_APPLY)
1226 gtk_tree_store_clear(store);
1227 gtk_widget_hide(GTK_WIDGET(dialog));
1232 static void on_color_button_choose_cb(GtkColorButton *widget, gpointer user_data)
1234 GdkColor color;
1236 gtk_color_button_get_color(widget, &color);
1237 setptr(editor_prefs.long_line_color, utils_get_hex_from_color(&color));
1241 static void on_prefs_font_choosed(GtkFontButton *widget, gpointer user_data)
1243 const gchar *fontbtn = gtk_font_button_get_font_name(widget);
1244 guint i;
1246 switch (GPOINTER_TO_INT(user_data))
1248 case 1:
1250 if (strcmp(fontbtn, interface_prefs.tagbar_font) == 0)
1251 break;
1253 setptr(interface_prefs.tagbar_font, g_strdup(fontbtn));
1254 for (i = 0; i < documents_array->len; i++)
1256 GeanyDocument *doc = documents[i];
1258 if (documents[i]->is_valid && GTK_IS_WIDGET(doc->priv->tag_tree))
1259 ui_widget_modify_font_from_string(doc->priv->tag_tree,
1260 interface_prefs.tagbar_font);
1262 if (GTK_IS_WIDGET(tv.default_tag_tree))
1263 ui_widget_modify_font_from_string(tv.default_tag_tree, interface_prefs.tagbar_font);
1264 ui_widget_modify_font_from_string(tv.tree_openfiles, interface_prefs.tagbar_font);
1265 break;
1267 case 2:
1269 if (strcmp(fontbtn, interface_prefs.msgwin_font) == 0)
1270 break;
1271 setptr(interface_prefs.msgwin_font, g_strdup(fontbtn));
1272 ui_widget_modify_font_from_string(msgwindow.tree_compiler, interface_prefs.msgwin_font);
1273 ui_widget_modify_font_from_string(msgwindow.tree_msg, interface_prefs.msgwin_font);
1274 ui_widget_modify_font_from_string(msgwindow.tree_status, interface_prefs.msgwin_font);
1275 ui_widget_modify_font_from_string(msgwindow.scribble, interface_prefs.msgwin_font);
1276 break;
1278 case 3:
1280 ui_set_editor_font(fontbtn);
1281 break;
1287 static GeanyKeyBinding *kb_lookup_kb_from_iter(G_GNUC_UNUSED GtkTreeModel *model, GtkTreeIter *iter)
1289 guint group_idx, keybinding_idx;
1290 GtkTreeIter parent;
1292 /* get kb index */
1293 gtk_tree_model_get(GTK_TREE_MODEL(store), iter, KB_TREE_INDEX, &keybinding_idx, -1);
1295 /* lookup the parent to get group index */
1296 gtk_tree_model_iter_parent(GTK_TREE_MODEL(store), &parent, iter);
1297 gtk_tree_model_get(GTK_TREE_MODEL(store), &parent, KB_TREE_INDEX, &group_idx, -1);
1299 return keybindings_lookup_item(group_idx, keybinding_idx);
1303 static void kb_change_iter_shortcut(GtkTreeIter *iter, const gchar *new_text)
1305 guint lkey;
1306 GdkModifierType lmods;
1307 GeanyKeyBinding *kb;
1309 gtk_accelerator_parse(new_text, &lkey, &lmods);
1311 kb = kb_lookup_kb_from_iter(GTK_TREE_MODEL(store), iter);
1313 if (kb_find_duplicate(ui_widgets.prefs_dialog, kb, lkey, lmods, new_text))
1314 return;
1316 /* set the values here, because of the above check, setting it in
1317 * gtk_accelerator_parse would return a wrong key combination if it is duplicate */
1318 gtk_tree_store_set(store, iter, KB_TREE_SHORTCUT, new_text, -1);
1320 edited = TRUE;
1324 static void kb_cell_edited_cb(GtkCellRendererText *cellrenderertext,
1325 gchar *path, gchar *new_text, gpointer user_data)
1327 if (path != NULL && new_text != NULL)
1329 GtkTreeIter iter;
1331 gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store), &iter, path);
1332 if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(store), &iter))
1333 return; /* ignore group items */
1335 kb_change_iter_shortcut(&iter, new_text);
1340 static gboolean kb_grab_key_dialog_key_press_cb(GtkWidget *dialog, GdkEventKey *event, gpointer user_data)
1342 gchar *str;
1343 gint state;
1345 state = event->state & gtk_accelerator_get_default_mod_mask();
1347 if (event->keyval == GDK_Escape)
1348 return FALSE; /* close the dialog, don't allow escape when detecting keybindings. */
1350 str = gtk_accelerator_name(event->keyval, state);
1352 gtk_label_set_text(GTK_LABEL(dialog_label), str);
1353 g_free(str);
1355 return TRUE;
1359 static void kb_grab_key_dialog_response_cb(GtkWidget *dialog, gint response, G_GNUC_UNUSED gpointer iter)
1361 if (response == GTK_RESPONSE_ACCEPT)
1363 const gchar *new_text = gtk_label_get_text(GTK_LABEL(dialog_label));
1365 kb_change_iter_shortcut(&g_iter, new_text);
1367 gtk_widget_destroy(dialog);
1371 /* Look for a (1st-level) child of parent whose KB_TREE_INDEX matches i,
1372 * setting iter to point to the node if found.
1373 * If parent is NULL, look for a parent node whose KB_TREE_INDEX matches i. */
1374 static gboolean kb_find_child_iter(GtkTreeIter *parent, guint i, GtkTreeIter *iter)
1376 GtkTreeModel *model = GTK_TREE_MODEL(store);
1377 guint idx;
1379 /* get first child of parent */
1380 if (! gtk_tree_model_iter_children(model, iter, parent))
1381 return FALSE;
1383 while (TRUE) /* foreach child */
1385 gtk_tree_model_get(model, iter, KB_TREE_INDEX, &idx, -1);
1386 if (idx == i)
1387 return TRUE;
1388 if (! gtk_tree_model_iter_next(model, iter))
1389 return FALSE; /* no more children */
1394 static void kb_clear_tree_shortcut(gsize group_id, gsize keybinding_id)
1396 GtkTreeIter parent;
1397 GtkTreeIter child;
1399 /* find parent kb group */
1400 if (! kb_find_child_iter(NULL, group_id, &parent))
1401 return;
1403 /* find child kb node*/
1404 if (! kb_find_child_iter(&parent, keybinding_id, &child))
1405 return;
1407 gtk_tree_store_set(store, &child, KB_TREE_SHORTCUT, NULL, -1); /* clear shortcut */
1411 /* test if the entered key combination is already used
1412 * returns true if cancelling duplicate */
1413 static gboolean kb_find_duplicate(GtkWidget *parent, GeanyKeyBinding *search_kb,
1414 guint key, GdkModifierType mods, const gchar *shortcut)
1416 gsize g, i;
1417 GeanyKeyGroup *group;
1418 GeanyKeyBinding *kb;
1420 /* allow duplicate if there is no key combination */
1421 if (key == 0 && mods == 0)
1422 return FALSE;
1424 foreach_ptr_array(group, g, keybinding_groups)
1426 foreach_ptr_array(kb, i, group->key_items)
1428 /* search another item with the same key,
1429 * but don't search the key we're looking for(!) */
1430 if (kb->key == key && kb->mods == mods
1431 && ! (kb->key == search_kb->key && kb->mods == search_kb->mods))
1433 gchar *label = keybindings_get_label(kb);
1434 gint ret = dialogs_show_prompt(parent,
1435 _("_Allow"), GTK_RESPONSE_APPLY,
1436 GTK_STOCK_CANCEL, GTK_RESPONSE_NO,
1437 _("_Override"), GTK_RESPONSE_YES,
1438 _("Override that keybinding?"),
1439 _("The combination '%s' is already used for \"%s\"."),
1440 shortcut, label);
1442 g_free(label);
1444 if (ret == GTK_RESPONSE_YES)
1446 kb_clear_tree_shortcut(g, kb->id);
1447 /* carry on looking for other duplicates if overriding */
1448 continue;
1450 return ret == GTK_RESPONSE_NO;
1454 return FALSE;
1458 static void on_toolbar_show_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1460 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1462 gtk_widget_set_sensitive(
1463 ui_lookup_widget(ui_widgets.prefs_dialog, "frame_toolbar_style"), sens);
1464 gtk_widget_set_sensitive(
1465 ui_lookup_widget(ui_widgets.prefs_dialog, "frame_toolbar_icon"), sens);
1466 gtk_widget_set_sensitive(
1467 ui_lookup_widget(ui_widgets.prefs_dialog, "button_customize_toolbar"), sens);
1468 gtk_widget_set_sensitive(
1469 ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_in_menu"), sens);
1473 static void on_show_notebook_tabs_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1475 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1477 /* tab placement only enabled when tabs are visible */
1478 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_editor"), sens);
1479 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_tab_cross"), sens);
1483 static void on_use_folding_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1485 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1487 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_unfold_children"), sens);
1491 static void on_enable_plugins_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1493 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1495 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "extra_plugin_path_entry"), sens);
1496 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "extra_plugin_path_button"), sens);
1500 static void on_open_encoding_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1502 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1504 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "eventbox3"), sens);
1505 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "label_open_encoding"), sens);
1509 static void on_sidebar_visible_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1511 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1513 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_openfiles"), sens);
1514 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_symbol"), sens);
1518 static void on_prefs_print_radio_button_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1520 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1522 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox29"), sens);
1523 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "hbox9"), ! sens);
1527 static void on_prefs_print_page_header_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1529 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1531 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_basename"), sens);
1532 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_dateformat"), sens);
1536 static void open_preferences_help(void)
1538 gchar *uri;
1539 const gchar *label, *suffix = NULL;
1540 GtkNotebook *notebook = GTK_NOTEBOOK(
1541 ui_lookup_widget(ui_widgets.prefs_dialog, "notebook2"));
1542 gint page_nr = gtk_notebook_get_current_page(notebook);
1543 GtkWidget *page = gtk_notebook_get_nth_page(notebook, page_nr);
1545 label = gtk_notebook_get_tab_label_text(notebook, page);
1547 /* TODO Find a better way to map the current notebook page to the
1548 * corresponding chapter in the documentation, comparing translatable
1549 * strings is easy to break. Maybe attach an identifying string to the
1550 * tab label object. */
1551 if (utils_str_equal(label, _("General")))
1552 suffix = "#general-startup-preferences";
1553 else if (utils_str_equal(label, _("Interface")))
1554 suffix = "#interface-preferences";
1555 else if (utils_str_equal(label, _("Toolbar")))
1556 suffix = "#toolbar-preferences";
1557 else if (utils_str_equal(label, _("Editor")))
1558 suffix = "#editor-features-preferences";
1559 else if (utils_str_equal(label, _("Files")))
1560 suffix = "#files-preferences";
1561 else if (utils_str_equal(label, _("Tools")))
1562 suffix = "#tools-preferences";
1563 else if (utils_str_equal(label, _("Templates")))
1564 suffix = "#template-preferences";
1565 else if (utils_str_equal(label, _("Keybindings")))
1566 suffix = "#keybinding-preferences";
1567 else if (utils_str_equal(label, _("Printing")))
1568 suffix = "#printing-preferences";
1569 else if (utils_str_equal(label, _("Terminal")))
1570 suffix = "#terminal-vte-preferences";
1572 uri = utils_get_help_url(suffix);
1573 utils_open_browser(uri);
1574 g_free(uri);
1578 static gboolean prefs_dialog_key_press_response_cb(GtkWidget *dialog, GdkEventKey *event,
1579 gpointer data)
1581 GeanyKeyBinding *kb = keybindings_lookup_item(GEANY_KEY_GROUP_HELP, GEANY_KEYS_HELP_HELP);
1583 if (keybindings_check_event(event, kb))
1585 open_preferences_help();
1586 return TRUE;
1588 return FALSE;
1592 static gboolean prefs_dialog_button_press_event_cb(GtkWidget *dialog, GdkEventButton *event,
1593 gpointer data)
1595 if (event->button == 1)
1597 open_preferences_help();
1598 return TRUE;
1600 return FALSE;
1604 void prefs_show_dialog(void)
1606 if (ui_widgets.prefs_dialog == NULL)
1608 GtkWidget *combo_new, *combo_open, *combo_eol;
1609 GtkWidget *label;
1610 guint i;
1611 gchar *encoding_string;
1612 GdkPixbuf *pb;
1614 ui_widgets.prefs_dialog = create_prefs_dialog();
1615 gtk_widget_set_name(ui_widgets.prefs_dialog, "GeanyPrefsDialog");
1616 gtk_window_set_transient_for(GTK_WINDOW(ui_widgets.prefs_dialog), GTK_WINDOW(main_widgets.window));
1617 pb = ui_new_pixbuf_from_inline(GEANY_IMAGE_LOGO);
1618 gtk_window_set_icon(GTK_WINDOW(ui_widgets.prefs_dialog), pb);
1619 g_object_unref(pb); /* free our reference */
1621 /* init the default file encoding combo box */
1622 combo_new = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_new_encoding");
1623 combo_open = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_open_encoding");
1624 gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(combo_new), 3);
1625 gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(combo_open), 3);
1626 for (i = 0; i < GEANY_ENCODINGS_MAX; i++)
1628 encoding_string = encodings_to_string(&encodings[i]);
1629 gtk_combo_box_append_text(GTK_COMBO_BOX(combo_new), encoding_string);
1630 gtk_combo_box_append_text(GTK_COMBO_BOX(combo_open), encoding_string);
1631 g_free(encoding_string);
1634 /* init the eol character combo box */
1635 combo_eol = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_eol");
1636 gtk_combo_box_append_text(GTK_COMBO_BOX(combo_eol), utils_get_eol_name(SC_EOL_CRLF));
1637 gtk_combo_box_append_text(GTK_COMBO_BOX(combo_eol), utils_get_eol_name(SC_EOL_CR));
1638 gtk_combo_box_append_text(GTK_COMBO_BOX(combo_eol), utils_get_eol_name(SC_EOL_LF));
1640 /* add manually GeanyWrapLabels because they can't be added with Glade */
1641 /* page Tools */
1642 label = geany_wrap_label_new(_("Enter tool paths below. Tools you do not need can be left blank."));
1643 gtk_widget_show(label);
1644 gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox33")),
1645 label, FALSE, TRUE, 5);
1646 /* page Templates */
1647 label = geany_wrap_label_new(_("Set the information to be used in templates. See the documentation for details."));
1648 gtk_widget_show(label);
1649 gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox31")),
1650 label, FALSE, TRUE, 5);
1651 label = geany_wrap_label_new(_("<i>Notice: For all changes you make here to take effect, you need to restart Geany or force the reload of the settings using Tools->Reload Configuration.</i>"));
1652 gtk_widget_show(label);
1653 gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
1654 gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox9")),
1655 label, FALSE, TRUE, 5);
1656 /* page Keybindings */
1657 label = geany_wrap_label_new(_("Here you can change keyboard shortcuts for various actions. Select one and press the Change button to enter a new shortcut, or double click on an action to edit the string representation of the shortcut directly."));
1658 gtk_widget_show(label);
1659 gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox32")),
1660 label, FALSE, TRUE, 5);
1661 /* page Printing */
1662 label = geany_wrap_label_new(_("<i>Notice: Native GTK printing is only available if Geany was built against GTK 2.10 (or above) <b>and</b> Geany is running with GTK 2.10 (or above).</i>"));
1663 gtk_widget_show(label);
1664 gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
1665 gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox27")),
1666 label, FALSE, TRUE, 5);
1667 /* page Editor->Indentation */
1668 label = geany_wrap_label_new(_("<i>Warning: these settings are overridden by the current project. See <b>Project->Properties</b>.</i>"));
1669 gtk_widget_show(label);
1670 gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
1671 gtk_misc_set_padding(GTK_MISC(label), 6, 0);
1672 gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog,
1673 "label_project_indent_warning")), label, FALSE, TRUE, 5);
1675 /* add the clear icon to GtkEntry widgets in the dialog */
1677 const gchar *names[] = {
1678 "startup_path_entry",
1679 "project_file_path_entry",
1680 "extra_plugin_path_entry",
1681 "entry_toggle_mark",
1682 /* "entry_com_make", */
1683 "entry_com_term",
1684 "entry_browser",
1685 "entry_grep",
1686 "entry_contextaction",
1687 "entry_template_developer",
1688 "entry_template_initial",
1689 "entry_template_mail",
1690 "entry_template_company",
1691 "entry_template_version",
1692 "entry_template_year",
1693 "entry_template_date",
1694 "entry_template_datetime",
1695 "entry_print_external_cmd",
1696 "entry_print_dateformat"};
1697 const gchar **name;
1699 foreach_c_array(name, names, G_N_ELEMENTS(names))
1700 ui_entry_add_clear_icon(GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, *name)));
1703 #ifdef HAVE_VTE
1704 vte_append_preferences_tab();
1705 #endif
1707 #ifndef G_OS_WIN32
1708 gtk_widget_hide(ui_lookup_widget(ui_widgets.prefs_dialog, "check_native_windows_dialogs"));
1709 #endif
1710 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "startup_path_button"), NULL,
1711 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "startup_path_entry")));
1712 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "extra_plugin_path_button"), NULL,
1713 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "extra_plugin_path_entry")));
1715 g_signal_connect(ui_widgets.prefs_dialog, "response",
1716 G_CALLBACK(on_prefs_dialog_response), NULL);
1717 g_signal_connect(ui_widgets.prefs_dialog, "delete-event",
1718 G_CALLBACK(gtk_widget_hide_on_delete), NULL);
1720 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "tagbar_font"),
1721 "font-set", G_CALLBACK(on_prefs_font_choosed), GINT_TO_POINTER(1));
1722 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "msgwin_font"),
1723 "font-set", G_CALLBACK(on_prefs_font_choosed), GINT_TO_POINTER(2));
1724 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "editor_font"),
1725 "font-set", G_CALLBACK(on_prefs_font_choosed), GINT_TO_POINTER(3));
1726 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "long_line_color"),
1727 "color-set", G_CALLBACK(on_color_button_choose_cb), NULL);
1728 /* file chooser buttons in the tools tab */
1729 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_term"),
1730 NULL,
1731 GTK_FILE_CHOOSER_ACTION_OPEN,
1732 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_term")));
1733 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_browser"),
1734 NULL,
1735 GTK_FILE_CHOOSER_ACTION_OPEN,
1736 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_browser")));
1737 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_grep"),
1738 NULL,
1739 GTK_FILE_CHOOSER_ACTION_OPEN,
1740 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_grep")));
1742 /* tools commands */
1743 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_contextaction"),
1744 NULL,
1745 GTK_FILE_CHOOSER_ACTION_OPEN,
1746 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_contextaction")));
1748 /* printing */
1749 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_print_external_cmd"),
1750 NULL,
1751 GTK_FILE_CHOOSER_ACTION_OPEN,
1752 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_external_cmd")));
1754 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "radio_print_gtk"),
1755 "toggled", G_CALLBACK(on_prefs_print_radio_button_toggled), NULL);
1756 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pageheader"),
1757 "toggled", G_CALLBACK(on_prefs_print_page_header_toggled), NULL);
1759 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_plugins"),
1760 "toggled", G_CALLBACK(on_enable_plugins_toggled), NULL);
1761 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_show"),
1762 "toggled", G_CALLBACK(on_toolbar_show_toggled), NULL);
1763 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_notebook_tabs"),
1764 "toggled", G_CALLBACK(on_show_notebook_tabs_toggled), NULL);
1765 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_folding"),
1766 "toggled", G_CALLBACK(on_use_folding_toggled), NULL);
1767 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_open_encoding"),
1768 "toggled", G_CALLBACK(on_open_encoding_toggled), NULL);
1769 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_sidebar_visible"),
1770 "toggled", G_CALLBACK(on_sidebar_visible_toggled), NULL);
1772 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "button_help"),
1773 "button-press-event", G_CALLBACK(prefs_dialog_button_press_event_cb), NULL);
1774 g_signal_connect(ui_widgets.prefs_dialog,
1775 "key-press-event", G_CALLBACK(prefs_dialog_key_press_response_cb), NULL);
1778 prefs_init_dialog();
1779 gtk_window_present(GTK_WINDOW(ui_widgets.prefs_dialog));