Show overridden keybindings in bold for prefs dialog tree
[geany-mirror.git] / src / prefs.c
blob993d4829985cfb5197773c2254254f66de8a2dc9
1 /*
2 * prefs.c - this file is part of Geany, a fast and lightweight IDE
4 * Copyright 2005-2011 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
5 * Copyright 2006-2011 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.
23 * @file prefs.h
24 * Preferences dialog.
28 * Preferences dialog support functions.
29 * New 'simple' prefs should use Stash code in keyfile.c - init_pref_groups().
32 #include <stdlib.h>
33 #include <string.h>
34 #include <gdk/gdkkeysyms.h>
36 #include "geany.h"
38 #include "prefs.h"
39 #include "support.h"
40 #include "dialogs.h"
41 #include "ui_utils.h"
42 #include "utils.h"
43 #include "sciwrappers.h"
44 #include "document.h"
45 #include "documentprivate.h"
46 #include "msgwindow.h"
47 #include "keyfile.h"
48 #include "keybindings.h"
49 #include "encodings.h"
50 #include "project.h"
51 #include "editor.h"
52 #include "main.h"
53 #include "sidebar.h"
54 #include "printing.h"
55 #include "geanywraplabel.h"
56 #include "templates.h"
57 #include "search.h"
58 #include "toolbar.h"
59 #include "tools.h"
60 #include "stash.h"
61 #include "keyfile.h"
62 #include "filetypes.h"
63 #include "win32.h"
65 #ifdef HAVE_VTE
66 # include "vte.h"
67 #endif
70 GeanyPrefs prefs;
71 GeanyToolPrefs tool_prefs;
74 /* keybinding globals, should be put in a struct */
75 static GtkTreeIter g_iter;
76 static GtkTreeStore *store = NULL;
77 static GtkTreeView *tree = NULL;
78 static GtkWidget *dialog_label;
79 static gboolean edited = FALSE;
81 static GtkTreeView *various_treeview = NULL;
83 static void kb_cell_edited_cb(GtkCellRendererText *cellrenderertext, gchar *path, gchar *new_text, gpointer user_data);
84 static gboolean kb_grab_key_dialog_key_press_cb(GtkWidget *dialog, GdkEventKey *event, gpointer user_data);
85 static void kb_grab_key_dialog_response_cb(GtkWidget *dialog, gint response, gpointer user_data);
86 static gboolean kb_find_duplicate(GtkWidget *parent, GtkTreeIter *old_iter,
87 guint key, GdkModifierType mods, const gchar *shortcut);
88 static void on_toolbar_show_toggled(GtkToggleButton *togglebutton, gpointer user_data);
89 static void on_show_notebook_tabs_toggled(GtkToggleButton *togglebutton, gpointer user_data);
90 static void on_enable_plugins_toggled(GtkToggleButton *togglebutton, gpointer user_data);
91 static void on_use_folding_toggled(GtkToggleButton *togglebutton, gpointer user_data);
92 static void on_open_encoding_toggled(GtkToggleButton *togglebutton, gpointer user_data);
93 static void on_sidebar_visible_toggled(GtkToggleButton *togglebutton, gpointer user_data);
94 static void on_prefs_print_radio_button_toggled(GtkToggleButton *togglebutton, gpointer user_data);
95 static void on_prefs_print_page_header_toggled(GtkToggleButton *togglebutton, gpointer user_data);
96 static void open_preferences_help(void);
99 typedef enum PrefCallbackAction
101 PREF_DISPLAY,
102 PREF_UPDATE
104 PrefCallbackAction;
107 /* Synchronize Stash settings with widgets (see keyfile.c - init_pref_groups()). */
108 static void prefs_action(PrefCallbackAction action)
110 StashGroup *group;
111 guint i;
113 foreach_ptr_array(group, i, pref_groups)
115 switch (action)
117 case PREF_DISPLAY:
118 stash_group_display(group, ui_widgets.prefs_dialog);
119 break;
120 case PREF_UPDATE:
121 stash_group_update(group, ui_widgets.prefs_dialog);
122 break;
126 switch (action)
128 case PREF_DISPLAY:
129 stash_tree_display(various_treeview);
130 break;
131 case PREF_UPDATE:
132 stash_tree_update(various_treeview);
133 break;
138 enum
140 KB_TREE_ACTION,
141 KB_TREE_SHORTCUT,
142 KB_TREE_INDEX,
143 KB_TREE_EDITABLE,
144 KB_TREE_WEIGHT,
145 KB_TREE_COLUMNS
149 static void kb_tree_view_change_button_clicked_cb(GtkWidget *button, gpointer data)
151 GtkTreeModel *model;
152 GtkTreeSelection *selection;
153 gchar *name;
155 selection = gtk_tree_view_get_selection(tree);
156 if (gtk_tree_selection_get_selected(selection, &model, &g_iter))
158 if (gtk_tree_model_iter_has_child(model, &g_iter))
159 { /* double click on a section to expand or collapse it */
160 GtkTreePath *path = gtk_tree_model_get_path(model, &g_iter);
162 if (gtk_tree_view_row_expanded(tree, path))
163 gtk_tree_view_collapse_row(tree, path);
164 else
165 gtk_tree_view_expand_row(tree, path, FALSE);
167 gtk_tree_path_free(path);
168 return;
171 gtk_tree_model_get(model, &g_iter, KB_TREE_ACTION, &name, -1);
172 if (name != NULL)
174 GtkWidget *dialog;
175 GtkWidget *label;
176 gchar *str;
178 dialog = gtk_dialog_new_with_buttons(_("Grab Key"), GTK_WINDOW(ui_widgets.prefs_dialog),
179 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
180 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
181 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
183 str = g_strdup_printf(
184 _("Press the combination of the keys you want to use for \"%s\"."), name);
185 label = gtk_label_new(str);
186 gtk_misc_set_padding(GTK_MISC(label), 5, 10);
187 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
189 dialog_label = gtk_label_new("");
190 gtk_misc_set_padding(GTK_MISC(dialog_label), 5, 10);
191 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), dialog_label);
193 g_signal_connect(dialog, "key-press-event",
194 G_CALLBACK(kb_grab_key_dialog_key_press_cb), NULL);
195 g_signal_connect(dialog, "response", G_CALLBACK(kb_grab_key_dialog_response_cb), NULL);
197 gtk_widget_show_all(dialog);
198 g_free(str);
199 g_free(name);
205 static void kb_expand_collapse_cb(GtkWidget *item, gpointer user_data)
207 if (user_data != NULL)
208 gtk_tree_view_expand_all(tree);
209 else
210 gtk_tree_view_collapse_all(tree);
214 static void kb_show_popup_menu(GtkWidget *widget, GdkEventButton *event)
216 GtkWidget *item;
217 static GtkWidget *menu = NULL;
218 guint button;
219 guint32 event_time;
221 if (menu == NULL)
223 menu = gtk_menu_new();
225 item = ui_image_menu_item_new(GTK_STOCK_ADD, _("_Expand All"));
226 gtk_widget_show(item);
227 gtk_container_add(GTK_CONTAINER(menu), item);
228 g_signal_connect(item, "activate", G_CALLBACK(kb_expand_collapse_cb), GINT_TO_POINTER(TRUE));
230 item = ui_image_menu_item_new(GTK_STOCK_REMOVE, _("_Collapse All"));
231 gtk_widget_show(item);
232 gtk_container_add(GTK_CONTAINER(menu), item);
233 g_signal_connect(item, "activate", G_CALLBACK(kb_expand_collapse_cb), NULL);
235 gtk_menu_attach_to_widget(GTK_MENU(menu), widget, NULL);
238 if (event != NULL)
240 button = event->button;
241 event_time = event->time;
243 else
245 button = 0;
246 event_time = gtk_get_current_event_time();
249 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, button, event_time);
253 static gboolean kb_popup_menu_cb(GtkWidget *widget, gpointer data)
255 kb_show_popup_menu(widget, NULL);
256 return TRUE;
260 static gboolean kb_tree_view_button_press_event_cb(GtkWidget *widget, GdkEventButton *event,
261 gpointer user_data)
263 if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
265 kb_show_popup_menu(widget, event);
266 return TRUE;
268 else if (event->type == GDK_2BUTTON_PRESS)
270 kb_tree_view_change_button_clicked_cb(NULL, NULL);
271 return TRUE;
273 return FALSE;
277 static void kb_init_tree(void)
279 GtkCellRenderer *renderer;
280 GtkTreeViewColumn *column;
282 tree = GTK_TREE_VIEW(ui_lookup_widget(ui_widgets.prefs_dialog, "treeview7"));
284 store = gtk_tree_store_new(KB_TREE_COLUMNS,
285 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_BOOLEAN, G_TYPE_INT);
286 gtk_tree_view_set_model(GTK_TREE_VIEW(tree), GTK_TREE_MODEL(store));
287 g_object_unref(store);
289 renderer = gtk_cell_renderer_text_new();
290 column = gtk_tree_view_column_new_with_attributes(_("Action"), renderer,
291 "text", KB_TREE_ACTION, "weight", KB_TREE_WEIGHT, NULL);
292 gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
294 renderer = gtk_cell_renderer_text_new();
295 column = gtk_tree_view_column_new_with_attributes(_("Shortcut"), renderer,
296 "text", KB_TREE_SHORTCUT, "editable", KB_TREE_EDITABLE,
297 "weight", KB_TREE_WEIGHT, NULL);
298 gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
300 /* set policy settings for the scrolled window around the treeview again, because glade
301 * doesn't keep the settings */
302 gtk_scrolled_window_set_policy(
303 GTK_SCROLLED_WINDOW(ui_lookup_widget(ui_widgets.prefs_dialog, "scrolledwindow8")),
304 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
306 g_signal_connect(renderer, "edited", G_CALLBACK(kb_cell_edited_cb), NULL);
307 g_signal_connect(tree, "button-press-event", G_CALLBACK(kb_tree_view_button_press_event_cb), NULL);
308 g_signal_connect(tree, "popup-menu", G_CALLBACK(kb_popup_menu_cb), NULL);
309 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "button2"), "clicked",
310 G_CALLBACK(kb_tree_view_change_button_clicked_cb), NULL);
314 static void kb_init(void)
316 GtkTreeIter parent, iter;
317 gsize g, i;
318 gchar *key_string, *label;
319 GeanyKeyGroup *group;
320 GeanyKeyBinding *kb;
322 if (store == NULL)
323 kb_init_tree();
325 foreach_ptr_array(group, g, keybinding_groups)
327 gtk_tree_store_append(store, &parent, NULL);
328 gtk_tree_store_set(store, &parent, KB_TREE_ACTION, group->label,
329 KB_TREE_INDEX, g, -1);
331 foreach_ptr_array(kb, i, group->key_items)
333 label = keybindings_get_label(kb);
334 key_string = gtk_accelerator_name(kb->key, kb->mods);
335 gtk_tree_store_append(store, &iter, &parent);
336 gtk_tree_store_set(store, &iter, KB_TREE_ACTION, label,
337 KB_TREE_SHORTCUT, key_string, KB_TREE_EDITABLE, TRUE,
338 KB_TREE_INDEX, kb->id, -1);
339 if (kb->key != kb->default_key || kb->mods != kb->default_mods)
340 gtk_tree_store_set(store, &iter, KB_TREE_WEIGHT, PANGO_WEIGHT_BOLD, -1);
341 g_free(key_string);
342 g_free(label);
345 gtk_tree_view_expand_all(GTK_TREE_VIEW(tree));
349 /* note: new 'simple' prefs should use Stash code in keyfile.c */
350 static void prefs_init_dialog(void)
352 GtkWidget *widget;
353 GdkColor *color;
355 /* Synchronize with Stash settings */
356 prefs_action(PREF_DISPLAY);
358 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "label_project_indent_warning");
359 ui_widget_show_hide(widget, app->project != NULL);
361 /* General settings */
362 /* startup */
363 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_load_session");
364 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.load_session);
366 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_project_session");
367 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), project_prefs.project_session);
369 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_project_file_in_basedir");
370 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), project_prefs.project_file_in_basedir);
372 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_save_win_pos");
373 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.save_winpos);
375 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ask_for_quit");
376 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.confirm_exit);
378 /* behaviour */
379 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_beep");
380 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.beep_on_errors);
382 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_switch_pages");
383 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.switch_to_status);
385 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_suppress_status_msgs");
386 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.suppress_status_messages);
388 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_auto_focus");
389 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.auto_focus);
391 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_native_windows_dialogs");
392 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
393 interface_prefs.use_native_windows_dialogs);
395 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_contextaction");
396 gtk_entry_set_text(GTK_ENTRY(widget), tool_prefs.context_action_cmd);
398 project_setup_prefs(); /* project files path */
401 /* Interface settings */
402 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_sidebar_visible");
403 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), ui_prefs.sidebar_visible);
404 on_sidebar_visible_toggled(GTK_TOGGLE_BUTTON(widget), NULL);
406 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_symbol");
407 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), interface_prefs.sidebar_symbol_visible);
409 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_openfiles");
410 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), interface_prefs.sidebar_openfiles_visible);
412 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "tagbar_font");
413 gtk_font_button_set_font_name(GTK_FONT_BUTTON(widget), interface_prefs.tagbar_font);
415 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "msgwin_font");
416 gtk_font_button_set_font_name(GTK_FONT_BUTTON(widget), interface_prefs.msgwin_font);
418 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "editor_font");
419 gtk_font_button_set_font_name(GTK_FONT_BUTTON(widget), interface_prefs.editor_font);
421 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_long_line");
422 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), editor_prefs.long_line_column);
424 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_long_line");
425 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.long_line_enabled);
427 switch (editor_prefs.long_line_type)
429 case 0: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_long_line_line"); break;
430 case 1: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_long_line_background"); break;
432 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
434 color = g_new0(GdkColor, 1);
435 gdk_color_parse(editor_prefs.long_line_color, color);
436 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "long_line_color");
437 gtk_color_button_set_color(GTK_COLOR_BUTTON(widget), color);
438 g_free(color);
440 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_notebook_tabs");
441 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), interface_prefs.show_notebook_tabs);
442 /* disable following setting if notebook tabs are hidden */
443 on_show_notebook_tabs_toggled(GTK_TOGGLE_BUTTON(
444 ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_notebook_tabs")), NULL);
446 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_tab_cross");
447 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.show_tab_cross);
449 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_editor");
450 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), interface_prefs.tab_pos_editor);
452 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_msgwin");
453 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), interface_prefs.tab_pos_msgwin);
455 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_sidebar");
456 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), interface_prefs.tab_pos_sidebar);
458 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_statusbar_visible");
459 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), interface_prefs.statusbar_visible);
462 /* Toolbar settings */
463 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_show");
464 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), toolbar_prefs.visible);
465 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_in_menu");
466 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), toolbar_prefs.append_to_menu);
468 switch (toolbar_prefs.icon_style)
470 case 0: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_image"); break;
471 case 1: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_text"); break;
472 default: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_imagetext"); break;
474 if (toolbar_prefs.use_gtk_default_style)
475 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_style_default");
476 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
478 switch (toolbar_prefs.icon_size)
480 case GTK_ICON_SIZE_LARGE_TOOLBAR:
481 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_large"); break;
482 case GTK_ICON_SIZE_SMALL_TOOLBAR:
483 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_small"); break;
484 default: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_verysmall"); break;
486 if (toolbar_prefs.use_gtk_default_icon)
487 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_icon_default");
488 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
490 /* disable elements if toolbar is hidden */
491 on_toolbar_show_toggled(GTK_TOGGLE_BUTTON(
492 ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_show")), NULL);
495 /* Files settings */
496 if (file_prefs.tab_order_ltr)
497 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_tab_right");
498 else
499 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_tab_left");
500 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
502 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_tab_beside");
503 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.tab_order_beside);
505 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_new_encoding");
506 /* luckily the index of the combo box items match the index of the encodings array */
507 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), file_prefs.default_new_encoding);
509 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_open_encoding");
510 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
511 (file_prefs.default_open_encoding >= 0) ? TRUE : FALSE);
512 on_open_encoding_toggled(GTK_TOGGLE_BUTTON(widget), NULL);
514 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_open_encoding");
515 if (file_prefs.default_open_encoding >= 0)
517 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), file_prefs.default_open_encoding);
519 else
520 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), GEANY_ENCODING_UTF_8);
522 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_eol");
523 if (file_prefs.default_eol_character >= 0 && file_prefs.default_eol_character < 3)
525 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), file_prefs.default_eol_character);
527 else
528 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), GEANY_DEFAULT_EOL_CHARACTER);
530 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_trailing_spaces");
531 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.strip_trailing_spaces);
533 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_new_line");
534 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.final_new_line);
536 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ensure_convert_new_lines");
537 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.ensure_convert_new_lines);
539 /* Editor settings */
540 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_toggle_mark");
541 gtk_entry_set_text(GTK_ENTRY(widget), editor_prefs.comment_toggle_mark);
543 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_replace_tabs");
544 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.replace_tabs);
546 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_indent");
547 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_indent_guide);
549 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_white_space");
550 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_white_space);
552 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_end");
553 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_line_endings);
555 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_numbers");
556 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_linenumber_margin);
558 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_markers_margin");
559 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_markers_margin);
561 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_stop_at_last_line");
562 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.scroll_stop_at_last_line);
564 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_wrapping");
565 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.line_wrapping);
567 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_complete_snippets");
568 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.complete_snippets);
570 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_xmltag");
571 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.auto_close_xml_tags);
573 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_folding");
574 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.folding);
576 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_unfold_children");
577 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.unfold_all_children);
578 on_use_folding_toggled(GTK_TOGGLE_BUTTON(
579 ui_lookup_widget(ui_widgets.prefs_dialog, "check_folding")), NULL);
581 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_disable_dnd");
582 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.disable_dnd);
584 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_smart_home");
585 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.smart_home_key);
587 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_newline_strip");
588 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.newline_strip);
590 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_indicators");
591 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.use_indicators);
593 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_auto_multiline");
594 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.auto_continue_multiline);
596 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_symbol_auto_completion");
597 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.auto_complete_symbols);
599 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_symbollistheight");
600 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), editor_prefs.symbolcompletion_max_height);
602 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_symbol_complete_chars");
603 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), editor_prefs.symbolcompletion_min_chars);
605 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_line_break");
606 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), editor_prefs.line_break_column);
608 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_parenthesis");
609 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
610 (editor_prefs.autoclose_chars & GEANY_AC_PARENTHESIS));
612 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_cbracket");
613 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
614 (editor_prefs.autoclose_chars & GEANY_AC_CBRACKET));
616 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_sbracket");
617 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
618 (editor_prefs.autoclose_chars & GEANY_AC_SBRACKET));
620 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_squote");
621 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
622 (editor_prefs.autoclose_chars & GEANY_AC_SQUOTE));
624 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_dquote");
625 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
626 (editor_prefs.autoclose_chars & GEANY_AC_DQUOTE));
628 /* Tools Settings */
630 if (tool_prefs.term_cmd)
631 gtk_entry_set_text(GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_term")), tool_prefs.term_cmd);
633 if (tool_prefs.browser_cmd)
634 gtk_entry_set_text(GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_browser")), tool_prefs.browser_cmd);
636 if (tool_prefs.grep_cmd)
637 gtk_entry_set_text(GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_grep")), tool_prefs.grep_cmd);
640 /* Template settings */
641 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_developer");
642 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.developer);
644 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_company");
645 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.company);
647 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_mail");
648 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.mail);
650 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_initial");
651 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.initials);
653 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_version");
654 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.version);
656 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_year");
657 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.year_format);
659 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_date");
660 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.date_format);
662 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_datetime");
663 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.datetime_format);
666 /* Keybindings */
667 kb_init();
669 /* Printing */
671 GtkWidget *widget_gtk = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_print_gtk");
672 if (printing_prefs.use_gtk_printing)
673 widget = widget_gtk;
674 else
675 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_print_external");
677 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
679 on_prefs_print_radio_button_toggled(GTK_TOGGLE_BUTTON(widget_gtk), NULL);
681 if (printing_prefs.external_print_cmd)
682 gtk_entry_set_text(
683 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_external_cmd")),
684 printing_prefs.external_print_cmd);
686 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_linenumbers");
687 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), printing_prefs.print_line_numbers);
689 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pagenumbers");
690 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), printing_prefs.print_page_numbers);
692 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pageheader");
693 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), printing_prefs.print_page_header);
694 on_prefs_print_page_header_toggled(GTK_TOGGLE_BUTTON(widget), NULL);
696 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_basename");
697 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), printing_prefs.page_header_basename);
699 if (printing_prefs.page_header_datefmt)
700 gtk_entry_set_text(
701 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_dateformat")),
702 printing_prefs.page_header_datefmt);
705 #ifndef HAVE_PLUGINS
706 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_plugins"), FALSE);
707 #endif
708 on_enable_plugins_toggled(GTK_TOGGLE_BUTTON( ui_lookup_widget(ui_widgets.prefs_dialog, "check_plugins")), NULL);
710 #ifdef HAVE_VTE
711 /* make VTE switch visible only when VTE is compiled in, it is hidden by default */
712 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_vte");
713 gtk_widget_show(widget);
714 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vte_info.load_vte);
716 /* VTE settings */
717 if (vte_info.have_vte)
719 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "font_term");
720 gtk_font_button_set_font_name(GTK_FONT_BUTTON(widget), vc->font);
722 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "color_fore");
723 gtk_color_button_set_color(GTK_COLOR_BUTTON(widget), vc->colour_fore);
725 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "color_back");
726 gtk_color_button_set_color(GTK_COLOR_BUTTON(widget), vc->colour_back);
728 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_scrollback");
729 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), vc->scrollback_lines);
731 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_shell");
732 gtk_entry_set_text(GTK_ENTRY(widget), vc->shell);
734 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_key");
735 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->scroll_on_key);
737 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_out");
738 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->scroll_on_out);
740 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_enable_bash_keys");
741 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->enable_bash_keys);
743 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ignore_menu_key");
744 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->ignore_menu_bar_accel);
746 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_follow_path");
747 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->follow_path);
749 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_run_in_vte");
750 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->run_in_vte);
752 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_skip_script");
753 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->skip_run_script);
755 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_cursor_blinks");
756 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->cursor_blinks);
758 #endif
762 /* note: uses group index, not group id, unlike keybindings_lookup_item(). */
763 static GeanyKeyBinding *kb_index(guint gidx, guint kid)
765 GeanyKeyGroup *group;
767 group = g_ptr_array_index(keybinding_groups, gidx);
768 return keybindings_get_item(group, kid);
772 /* read the treeview shortcut fields into keybindings */
773 static void kb_update(void)
775 GtkTreeModel *model = GTK_TREE_MODEL(store);
776 GtkTreeIter child, parent;
777 guint gid = 0;
779 /* get first parent */
780 if (! gtk_tree_model_iter_children(model, &parent, NULL))
781 return;
783 /* foreach parent */
784 while (TRUE)
786 /* get first child */
787 if (! gtk_tree_model_iter_children(model, &child, &parent))
788 return;
790 /* foreach child */
791 while (TRUE)
793 guint kid;
794 gchar *str;
795 guint key;
796 GdkModifierType mods;
797 GeanyKeyBinding *kb;
799 gtk_tree_model_get(model, &child, KB_TREE_INDEX, &kid, KB_TREE_SHORTCUT, &str, -1);
800 gtk_accelerator_parse(str, &key, &mods);
801 g_free(str);
802 kb = kb_index(gid, kid);
803 if (kb->key != key || kb->mods != mods)
804 keybindings_update_combo(kb, key, mods);
806 if (! gtk_tree_model_iter_next(model, &child))
807 break;
809 if (! gtk_tree_model_iter_next(model, &parent))
810 return;
811 gid++;
817 * callbacks
819 /* note: new 'simple' prefs should use Stash code in keyfile.c */
820 static void
821 on_prefs_dialog_response(GtkDialog *dialog, gint response, gpointer user_data)
823 if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY)
825 GtkWidget *widget;
826 guint i;
827 gboolean autoclose_brackets[5];
828 gboolean old_invert_all = interface_prefs.highlighting_invert_all;
829 gboolean old_sidebar_pos = interface_prefs.sidebar_pos;
830 GeanyDocument *doc = document_get_current();
832 /* Synchronize Stash settings */
833 prefs_action(PREF_UPDATE);
835 if (interface_prefs.highlighting_invert_all != old_invert_all)
836 filetypes_reload();
838 if (interface_prefs.sidebar_pos != old_sidebar_pos)
839 ui_swap_sidebar_pos();
841 /* General settings */
842 /* startup */
843 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_load_session");
844 prefs.load_session = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
846 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_project_session");
847 project_prefs.project_session = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
849 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_project_file_in_basedir");
850 project_prefs.project_file_in_basedir = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
852 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_save_win_pos");
853 prefs.save_winpos = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
855 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ask_for_quit");
856 prefs.confirm_exit = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
858 /* behaviour */
859 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_beep");
860 prefs.beep_on_errors = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
862 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_switch_pages");
863 prefs.switch_to_status = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
865 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_suppress_status_msgs");
866 prefs.suppress_status_messages = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
868 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_auto_focus");
869 prefs.auto_focus = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
871 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_native_windows_dialogs");
872 interface_prefs.use_native_windows_dialogs =
873 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
875 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_contextaction");
876 g_free(tool_prefs.context_action_cmd);
877 tool_prefs.context_action_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
879 project_apply_prefs(); /* project file path */
882 /* Interface settings */
883 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_sidebar_visible");
884 ui_prefs.sidebar_visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
886 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_symbol");
887 interface_prefs.sidebar_symbol_visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
889 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_openfiles");
890 interface_prefs.sidebar_openfiles_visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
892 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_long_line");
893 editor_prefs.long_line_enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
895 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_long_line_line");
896 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
897 editor_prefs.long_line_type = 0;
898 else
899 /* now only the "background" radio remains */
900 editor_prefs.long_line_type = 1;
902 if (editor_prefs.long_line_column == 0)
903 editor_prefs.long_line_enabled = FALSE;
905 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_notebook_tabs");
906 interface_prefs.show_notebook_tabs = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
908 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_tab_cross");
909 file_prefs.show_tab_cross = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
911 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_editor");
912 interface_prefs.tab_pos_editor = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
914 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_msgwin");
915 interface_prefs.tab_pos_msgwin = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
917 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_sidebar");
918 interface_prefs.tab_pos_sidebar = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
920 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_statusbar_visible");
921 interface_prefs.statusbar_visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
924 /* Toolbar settings */
925 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_show");
926 toolbar_prefs.visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
927 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_in_menu");
928 toolbar_prefs.append_to_menu = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
930 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_style_default");
931 toolbar_prefs.use_gtk_default_style = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
932 if (! toolbar_prefs.use_gtk_default_style)
934 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_imagetext");
935 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
936 toolbar_prefs.icon_style = 2;
937 else
939 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_image");
940 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
941 toolbar_prefs.icon_style = 0;
942 else
943 /* now only the text only radio remains, so set text only */
944 toolbar_prefs.icon_style = 1;
948 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_icon_default");
949 toolbar_prefs.use_gtk_default_icon = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
950 if (! toolbar_prefs.use_gtk_default_icon)
951 { toolbar_prefs.icon_size = GTK_ICON_SIZE_LARGE_TOOLBAR;
952 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_large");
953 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
954 toolbar_prefs.icon_size = GTK_ICON_SIZE_LARGE_TOOLBAR;
955 else
957 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_small");
958 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
959 toolbar_prefs.icon_size = GTK_ICON_SIZE_SMALL_TOOLBAR;
960 else
961 toolbar_prefs.icon_size = GTK_ICON_SIZE_MENU;
965 /* Files settings */
966 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_tab_right");
967 file_prefs.tab_order_ltr = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
969 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_tab_beside");
970 file_prefs.tab_order_beside = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
972 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_new_encoding");
973 file_prefs.default_new_encoding = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
975 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_open_encoding");
976 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
978 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_open_encoding");
979 file_prefs.default_open_encoding = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
981 else
982 file_prefs.default_open_encoding = -1;
984 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_eol");
985 file_prefs.default_eol_character = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
987 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_trailing_spaces");
988 file_prefs.strip_trailing_spaces = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
990 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_new_line");
991 file_prefs.final_new_line = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
993 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ensure_convert_new_lines");
994 file_prefs.ensure_convert_new_lines = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
996 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_replace_tabs");
997 file_prefs.replace_tabs = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1000 /* Editor settings */
1001 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_toggle_mark");
1002 SETPTR(editor_prefs.comment_toggle_mark,
1003 gtk_editable_get_chars(GTK_EDITABLE(widget), 0, -1));
1005 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_long_line");
1006 /* note: use stash for new code - it updates spin buttons itself */
1007 gtk_spin_button_update(GTK_SPIN_BUTTON(widget));
1008 editor_prefs.long_line_column = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
1010 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_folding");
1011 editor_prefs.folding = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1012 ui_update_fold_items();
1014 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_unfold_children");
1015 editor_prefs.unfold_all_children = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1017 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_indent");
1018 editor_prefs.show_indent_guide = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1020 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_white_space");
1021 editor_prefs.show_white_space = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1023 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_end");
1024 editor_prefs.show_line_endings = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1026 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_numbers");
1027 editor_prefs.show_linenumber_margin = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1029 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_markers_margin");
1030 editor_prefs.show_markers_margin = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1032 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_stop_at_last_line");
1033 editor_prefs.scroll_stop_at_last_line = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1035 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_wrapping");
1036 editor_prefs.line_wrapping = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1038 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_complete_snippets");
1039 editor_prefs.complete_snippets = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1041 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_xmltag");
1042 editor_prefs.auto_close_xml_tags = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1044 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_indicators");
1045 editor_prefs.use_indicators = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1047 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_disable_dnd");
1048 editor_prefs.disable_dnd = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1050 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_smart_home");
1051 editor_prefs.smart_home_key = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1053 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_newline_strip");
1054 editor_prefs.newline_strip = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1056 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_auto_multiline");
1057 editor_prefs.auto_continue_multiline = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1059 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_symbol_auto_completion");
1060 editor_prefs.auto_complete_symbols = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1062 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_symbol_complete_chars");
1063 gtk_spin_button_update(GTK_SPIN_BUTTON(widget));
1064 editor_prefs.symbolcompletion_min_chars = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
1066 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_symbollistheight");
1067 gtk_spin_button_update(GTK_SPIN_BUTTON(widget));
1068 editor_prefs.symbolcompletion_max_height = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
1070 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_line_break");
1071 gtk_spin_button_update(GTK_SPIN_BUTTON(widget));
1072 editor_prefs.line_break_column = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
1074 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_parenthesis");
1075 autoclose_brackets[0] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1077 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_cbracket");
1078 autoclose_brackets[1] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1080 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_sbracket");
1081 autoclose_brackets[2] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1083 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_squote");
1084 autoclose_brackets[3] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1086 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_dquote");
1087 autoclose_brackets[4] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1089 editor_prefs.autoclose_chars =
1090 (autoclose_brackets[0] ? GEANY_AC_PARENTHESIS : 0u)
1091 | (autoclose_brackets[1] ? GEANY_AC_CBRACKET : 0u)
1092 | (autoclose_brackets[2] ? GEANY_AC_SBRACKET : 0u)
1093 | (autoclose_brackets[3] ? GEANY_AC_SQUOTE : 0u)
1094 | (autoclose_brackets[4] ? GEANY_AC_DQUOTE : 0u);
1096 /* Tools Settings */
1098 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_term");
1099 g_free(tool_prefs.term_cmd);
1100 tool_prefs.term_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1102 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_browser");
1103 g_free(tool_prefs.browser_cmd);
1104 tool_prefs.browser_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1106 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_grep");
1107 g_free(tool_prefs.grep_cmd);
1108 tool_prefs.grep_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1111 /* Template settings */
1112 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_developer");
1113 g_free(template_prefs.developer);
1114 template_prefs.developer = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1116 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_company");
1117 g_free(template_prefs.company);
1118 template_prefs.company = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1120 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_mail");
1121 g_free(template_prefs.mail);
1122 template_prefs.mail = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1124 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_initial");
1125 g_free(template_prefs.initials);
1126 template_prefs.initials = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1128 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_version");
1129 g_free(template_prefs.version);
1130 template_prefs.version = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1132 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_year");
1133 g_free(template_prefs.year_format);
1134 template_prefs.year_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1136 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_date");
1137 g_free(template_prefs.date_format);
1138 template_prefs.date_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1140 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_datetime");
1141 g_free(template_prefs.datetime_format);
1142 template_prefs.datetime_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1145 /* Keybindings */
1146 if (edited)
1148 kb_update();
1149 tools_create_insert_custom_command_menu_items();
1150 keybindings_write_to_file();
1153 /* Printing */
1154 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_print_gtk");
1155 printing_prefs.use_gtk_printing = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1157 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_external_cmd");
1158 g_free(printing_prefs.external_print_cmd);
1159 printing_prefs.external_print_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1161 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_linenumbers");
1162 printing_prefs.print_line_numbers = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1164 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pagenumbers");
1165 printing_prefs.print_page_numbers = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1167 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pageheader");
1168 printing_prefs.print_page_header = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1170 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_basename");
1171 printing_prefs.page_header_basename = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1173 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_dateformat");
1174 g_free(printing_prefs.page_header_datefmt);
1175 printing_prefs.page_header_datefmt = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1178 #ifdef HAVE_VTE
1179 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_vte");
1180 vte_info.load_vte = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1182 /* VTE settings */
1183 if (vte_info.have_vte)
1185 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_scrollback");
1186 gtk_spin_button_update(GTK_SPIN_BUTTON(widget));
1187 vc->scrollback_lines = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
1189 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_shell");
1190 g_free(vc->shell);
1191 vc->shell = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1193 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_key");
1194 vc->scroll_on_key = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1196 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_out");
1197 vc->scroll_on_out = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1199 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_enable_bash_keys");
1200 vc->enable_bash_keys = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1202 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ignore_menu_key");
1203 vc->ignore_menu_bar_accel = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1205 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_follow_path");
1206 vc->follow_path = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1208 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_run_in_vte");
1209 vc->run_in_vte = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1211 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_skip_script");
1212 vc->skip_run_script = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1214 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_cursor_blinks");
1215 vc->cursor_blinks = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1217 vte_apply_user_settings();
1219 #endif
1221 /* apply the changes made */
1222 ui_statusbar_showhide(interface_prefs.statusbar_visible);
1223 sidebar_openfiles_update_all(); /* to update if full path setting has changed */
1224 toolbar_apply_settings();
1225 toolbar_update_ui();
1226 toolbar_show_hide();
1227 ui_sidebar_show_hide();
1228 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(main_widgets.notebook), interface_prefs.show_notebook_tabs);
1230 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(main_widgets.notebook), interface_prefs.tab_pos_editor);
1231 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(msgwindow.notebook), interface_prefs.tab_pos_msgwin);
1232 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(main_widgets.sidebar_notebook), interface_prefs.tab_pos_sidebar);
1234 /* re-colourise all open documents, if tab width or long line settings have changed */
1235 for (i = 0; i < documents_array->len; i++)
1237 if (documents[i]->is_valid)
1239 editor_apply_update_prefs(documents[i]->editor);
1240 if (! editor_prefs.folding)
1241 editor_unfold_all(documents[i]->editor);
1244 ui_document_show_hide(NULL);
1245 ui_update_view_editor_menu_items();
1247 /* various preferences */
1248 ui_save_buttons_toggle((doc != NULL) ? doc->changed : FALSE);
1249 msgwin_show_hide_tabs();
1250 ui_update_statusbar(doc, -1);
1252 /* store all settings */
1253 configuration_save();
1256 if (response == GTK_RESPONSE_HELP)
1258 open_preferences_help();
1260 else if (response != GTK_RESPONSE_APPLY)
1262 gtk_tree_store_clear(store);
1263 gtk_widget_hide(GTK_WIDGET(dialog));
1268 static void on_color_button_choose_cb(GtkColorButton *widget, gpointer user_data)
1270 GdkColor color;
1272 gtk_color_button_get_color(widget, &color);
1273 SETPTR(editor_prefs.long_line_color, utils_get_hex_from_color(&color));
1277 static void on_prefs_font_choosed(GtkFontButton *widget, gpointer user_data)
1279 const gchar *fontbtn = gtk_font_button_get_font_name(widget);
1280 guint i;
1282 switch (GPOINTER_TO_INT(user_data))
1284 case 1:
1286 if (strcmp(fontbtn, interface_prefs.tagbar_font) == 0)
1287 break;
1289 SETPTR(interface_prefs.tagbar_font, g_strdup(fontbtn));
1290 for (i = 0; i < documents_array->len; i++)
1292 GeanyDocument *doc = documents[i];
1294 if (documents[i]->is_valid && GTK_IS_WIDGET(doc->priv->tag_tree))
1295 ui_widget_modify_font_from_string(doc->priv->tag_tree,
1296 interface_prefs.tagbar_font);
1298 if (GTK_IS_WIDGET(tv.default_tag_tree))
1299 ui_widget_modify_font_from_string(tv.default_tag_tree, interface_prefs.tagbar_font);
1300 ui_widget_modify_font_from_string(tv.tree_openfiles, interface_prefs.tagbar_font);
1301 break;
1303 case 2:
1305 if (strcmp(fontbtn, interface_prefs.msgwin_font) == 0)
1306 break;
1307 SETPTR(interface_prefs.msgwin_font, g_strdup(fontbtn));
1308 ui_widget_modify_font_from_string(msgwindow.tree_compiler, interface_prefs.msgwin_font);
1309 ui_widget_modify_font_from_string(msgwindow.tree_msg, interface_prefs.msgwin_font);
1310 ui_widget_modify_font_from_string(msgwindow.tree_status, interface_prefs.msgwin_font);
1311 ui_widget_modify_font_from_string(msgwindow.scribble, interface_prefs.msgwin_font);
1312 break;
1314 case 3:
1316 ui_set_editor_font(fontbtn);
1317 break;
1323 static void kb_change_iter_shortcut(GtkTreeIter *iter, const gchar *new_text)
1325 guint lkey;
1326 GdkModifierType lmods;
1328 gtk_accelerator_parse(new_text, &lkey, &lmods);
1330 if (kb_find_duplicate(ui_widgets.prefs_dialog, iter, lkey, lmods, new_text))
1331 return;
1333 /* set the values here, because of the above check, setting it in
1334 * gtk_accelerator_parse would return a wrong key combination if it is duplicate */
1335 gtk_tree_store_set(store, iter, KB_TREE_SHORTCUT, new_text, -1);
1337 edited = TRUE;
1341 static void kb_cell_edited_cb(GtkCellRendererText *cellrenderertext,
1342 gchar *path, gchar *new_text, gpointer user_data)
1344 if (path != NULL && new_text != NULL)
1346 GtkTreeIter iter;
1348 gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store), &iter, path);
1349 if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(store), &iter))
1350 return; /* ignore group items */
1352 kb_change_iter_shortcut(&iter, new_text);
1357 static gboolean kb_grab_key_dialog_key_press_cb(GtkWidget *dialog, GdkEventKey *event, gpointer user_data)
1359 gchar *str;
1360 guint state;
1362 state = event->state & gtk_accelerator_get_default_mod_mask();
1364 if (event->keyval == GDK_Escape)
1365 return FALSE; /* close the dialog, don't allow escape when detecting keybindings. */
1367 str = gtk_accelerator_name(event->keyval, state);
1369 gtk_label_set_text(GTK_LABEL(dialog_label), str);
1370 g_free(str);
1372 return TRUE;
1376 static void kb_grab_key_dialog_response_cb(GtkWidget *dialog, gint response, G_GNUC_UNUSED gpointer iter)
1378 if (response == GTK_RESPONSE_ACCEPT)
1380 const gchar *new_text = gtk_label_get_text(GTK_LABEL(dialog_label));
1382 kb_change_iter_shortcut(&g_iter, new_text);
1384 gtk_widget_destroy(dialog);
1388 /* test if the entered key combination is already used
1389 * returns true if cancelling duplicate */
1390 static gboolean kb_find_duplicate(GtkWidget *parent, GtkTreeIter *old_iter,
1391 guint key, GdkModifierType mods, const gchar *shortcut)
1393 GtkTreeModel *model = GTK_TREE_MODEL(store);
1394 GtkTreeIter parent_iter;
1395 gchar *kb_str;
1396 guint kb_key;
1397 GdkModifierType kb_mods;
1399 /* allow duplicate if there is no key combination */
1400 if (key == 0 && mods == 0)
1401 return FALSE;
1403 /* don't check if the new keybinding is the same as the old one */
1404 gtk_tree_model_get(model, old_iter, KB_TREE_SHORTCUT, &kb_str, -1);
1405 if (kb_str)
1407 gtk_accelerator_parse(kb_str, &kb_key, &kb_mods);
1408 g_free(kb_str);
1409 if (key == kb_key && mods == kb_mods)
1410 return FALSE;
1413 if (! gtk_tree_model_get_iter_first(model, &parent_iter))
1414 return FALSE;
1415 do /* foreach top level */
1417 GtkTreeIter iter;
1419 if (! gtk_tree_model_iter_children(model, &iter, &parent_iter))
1420 continue;
1421 do /* foreach children */
1424 gtk_tree_model_get(model, &iter, KB_TREE_SHORTCUT, &kb_str, -1);
1425 if (! kb_str)
1426 continue;
1428 gtk_accelerator_parse(kb_str, &kb_key, &kb_mods);
1429 g_free(kb_str);
1430 /* search another item with the same key and modifiers */
1431 if (kb_key == key && kb_mods == mods)
1433 gchar *label;
1434 gint ret;
1436 gtk_tree_model_get(model, &iter, KB_TREE_ACTION, &label, -1);
1437 ret = dialogs_show_prompt(parent,
1438 _("_Allow"), GTK_RESPONSE_APPLY,
1439 GTK_STOCK_CANCEL, GTK_RESPONSE_NO,
1440 _("_Override"), GTK_RESPONSE_YES,
1441 _("Override that keybinding?"),
1442 _("The combination '%s' is already used for \"%s\"."),
1443 shortcut, label);
1445 g_free(label);
1447 if (ret == GTK_RESPONSE_YES)
1449 gtk_tree_store_set(store, &iter, KB_TREE_SHORTCUT, NULL, -1); /* clear shortcut */
1450 /* carry on looking for other duplicates if overriding */
1451 continue;
1453 return ret == GTK_RESPONSE_NO;
1456 while (gtk_tree_model_iter_next(model, &iter));
1458 while (gtk_tree_model_iter_next(model, &parent_iter));
1460 return FALSE;
1464 static void on_toolbar_show_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1466 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1468 gtk_widget_set_sensitive(
1469 ui_lookup_widget(ui_widgets.prefs_dialog, "frame_toolbar_style"), sens);
1470 gtk_widget_set_sensitive(
1471 ui_lookup_widget(ui_widgets.prefs_dialog, "frame_toolbar_icon"), sens);
1472 gtk_widget_set_sensitive(
1473 ui_lookup_widget(ui_widgets.prefs_dialog, "button_customize_toolbar"), sens);
1474 gtk_widget_set_sensitive(
1475 ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_in_menu"), sens);
1479 static void on_show_notebook_tabs_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1481 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1483 /* tab placement only enabled when tabs are visible */
1484 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_editor"), sens);
1485 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_tab_cross"), sens);
1489 static void on_use_folding_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1491 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1493 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_unfold_children"), sens);
1497 static void on_enable_plugins_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1499 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1501 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "extra_plugin_path_entry"), sens);
1502 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "extra_plugin_path_button"), sens);
1506 static void on_open_encoding_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1508 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1510 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "eventbox3"), sens);
1511 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "label_open_encoding"), sens);
1515 static void on_sidebar_visible_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1517 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1519 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_openfiles"), sens);
1520 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_symbol"), sens);
1524 static void on_prefs_print_radio_button_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1526 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1528 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox29"), sens);
1529 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "hbox9"), ! sens);
1533 static void on_prefs_print_page_header_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1535 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1537 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_basename"), sens);
1538 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_dateformat"), sens);
1542 static void open_preferences_help(void)
1544 gchar *uri;
1545 const gchar *label, *suffix = NULL;
1546 GtkNotebook *notebook = GTK_NOTEBOOK(
1547 ui_lookup_widget(ui_widgets.prefs_dialog, "notebook2"));
1548 gint page_nr = gtk_notebook_get_current_page(notebook);
1549 GtkWidget *page = gtk_notebook_get_nth_page(notebook, page_nr);
1551 label = gtk_notebook_get_tab_label_text(notebook, page);
1553 /* TODO Find a better way to map the current notebook page to the
1554 * corresponding chapter in the documentation, comparing translatable
1555 * strings is easy to break. Maybe attach an identifying string to the
1556 * tab label object. */
1557 if (utils_str_equal(label, _("General")))
1558 suffix = "#general-startup-preferences";
1559 else if (utils_str_equal(label, _("Interface")))
1560 suffix = "#interface-preferences";
1561 else if (utils_str_equal(label, _("Toolbar")))
1562 suffix = "#toolbar-preferences";
1563 else if (utils_str_equal(label, _("Editor")))
1564 suffix = "#editor-features-preferences";
1565 else if (utils_str_equal(label, _("Files")))
1566 suffix = "#files-preferences";
1567 else if (utils_str_equal(label, _("Tools")))
1568 suffix = "#tools-preferences";
1569 else if (utils_str_equal(label, _("Templates")))
1570 suffix = "#template-preferences";
1571 else if (utils_str_equal(label, _("Keybindings")))
1572 suffix = "#keybinding-preferences";
1573 else if (utils_str_equal(label, _("Printing")))
1574 suffix = "#printing-preferences";
1575 else if (utils_str_equal(label, _("Various")))
1576 suffix = "#various-preferences";
1577 else if (utils_str_equal(label, _("Terminal")))
1578 suffix = "#terminal-vte-preferences";
1580 uri = utils_get_help_url(suffix);
1581 utils_open_browser(uri);
1582 g_free(uri);
1586 static gboolean prefs_dialog_key_press_response_cb(GtkWidget *dialog, GdkEventKey *event,
1587 gpointer data)
1589 GeanyKeyBinding *kb = keybindings_lookup_item(GEANY_KEY_GROUP_HELP, GEANY_KEYS_HELP_HELP);
1591 if (keybindings_check_event(event, kb))
1593 open_preferences_help();
1594 return TRUE;
1596 return FALSE;
1600 static void list_store_append_text(GtkListStore *list, const gchar *text)
1602 GtkTreeIter iter;
1604 gtk_list_store_append(list, &iter);
1605 gtk_list_store_set(list, &iter, 0, text, -1);
1609 void prefs_show_dialog(void)
1611 if (ui_widgets.prefs_dialog == NULL)
1613 GtkListStore *encoding_list, *eol_list;
1614 GtkWidget *label;
1615 guint i;
1616 gchar *encoding_string;
1617 GdkPixbuf *pb;
1619 ui_widgets.prefs_dialog = create_prefs_dialog();
1620 gtk_widget_set_name(ui_widgets.prefs_dialog, "GeanyPrefsDialog");
1621 gtk_window_set_transient_for(GTK_WINDOW(ui_widgets.prefs_dialog), GTK_WINDOW(main_widgets.window));
1622 pb = ui_new_pixbuf_from_inline(GEANY_IMAGE_LOGO);
1623 gtk_window_set_icon(GTK_WINDOW(ui_widgets.prefs_dialog), pb);
1624 g_object_unref(pb); /* free our reference */
1626 /* init the file encoding combo boxes */
1627 encoding_list = ui_builder_get_object("encoding_list");
1628 for (i = 0; i < GEANY_ENCODINGS_MAX; i++)
1630 encoding_string = encodings_to_string(&encodings[i]);
1631 list_store_append_text(encoding_list, encoding_string);
1632 g_free(encoding_string);
1635 /* init the eol character combo box */
1636 eol_list = ui_builder_get_object("eol_list");
1637 list_store_append_text(eol_list, utils_get_eol_name(SC_EOL_CRLF));
1638 list_store_append_text(eol_list, utils_get_eol_name(SC_EOL_CR));
1639 list_store_append_text(eol_list, utils_get_eol_name(SC_EOL_LF));
1641 /* add manually GeanyWrapLabels because they can't be added with Glade */
1642 /* page Tools */
1643 label = geany_wrap_label_new(_("Enter tool paths below. Tools you do not need can be left blank."));
1644 gtk_widget_show(label);
1645 gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox33")),
1646 label, FALSE, TRUE, 5);
1647 /* page Templates */
1648 label = geany_wrap_label_new(_("Set the information to be used in templates. See the documentation for details."));
1649 gtk_widget_show(label);
1650 gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox31")),
1651 label, FALSE, TRUE, 5);
1652 /* page Keybindings */
1653 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."));
1654 gtk_widget_show(label);
1655 gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox32")),
1656 label, FALSE, TRUE, 5);
1657 /* page Editor->Indentation */
1658 label = geany_wrap_label_new(_("<i>Warning: these settings are overridden by the current project. See <b>Project->Properties</b>.</i>"));
1659 gtk_widget_show(label);
1660 gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
1661 gtk_misc_set_padding(GTK_MISC(label), 6, 0);
1662 gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog,
1663 "label_project_indent_warning")), label, FALSE, TRUE, 5);
1665 /* add the clear icon to GtkEntry widgets in the dialog */
1667 const gchar *names[] = {
1668 "startup_path_entry",
1669 "project_file_path_entry",
1670 "extra_plugin_path_entry",
1671 "entry_toggle_mark",
1672 /* "entry_com_make", */
1673 "entry_com_term",
1674 "entry_browser",
1675 "entry_grep",
1676 "entry_contextaction",
1677 "entry_template_developer",
1678 "entry_template_initial",
1679 "entry_template_mail",
1680 "entry_template_company",
1681 "entry_template_version",
1682 "entry_template_year",
1683 "entry_template_date",
1684 "entry_template_datetime",
1685 "entry_print_external_cmd",
1686 "entry_print_dateformat"};
1687 const gchar **name;
1689 foreach_c_array(name, names, G_N_ELEMENTS(names))
1690 ui_entry_add_clear_icon(GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, *name)));
1693 /* page Various */
1694 various_treeview = GTK_TREE_VIEW(ui_lookup_widget(ui_widgets.prefs_dialog,
1695 "various_treeview"));
1696 stash_tree_setup(pref_groups, various_treeview);
1698 #ifdef HAVE_VTE
1699 vte_append_preferences_tab();
1700 #endif
1702 #ifndef G_OS_WIN32
1703 gtk_widget_hide(ui_lookup_widget(ui_widgets.prefs_dialog, "check_native_windows_dialogs"));
1704 #endif
1705 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "startup_path_button"), NULL,
1706 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "startup_path_entry")));
1707 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "extra_plugin_path_button"), NULL,
1708 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "extra_plugin_path_entry")));
1710 g_signal_connect(ui_widgets.prefs_dialog, "response",
1711 G_CALLBACK(on_prefs_dialog_response), NULL);
1712 g_signal_connect(ui_widgets.prefs_dialog, "delete-event",
1713 G_CALLBACK(gtk_widget_hide_on_delete), NULL);
1715 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "tagbar_font"),
1716 "font-set", G_CALLBACK(on_prefs_font_choosed), GINT_TO_POINTER(1));
1717 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "msgwin_font"),
1718 "font-set", G_CALLBACK(on_prefs_font_choosed), GINT_TO_POINTER(2));
1719 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "editor_font"),
1720 "font-set", G_CALLBACK(on_prefs_font_choosed), GINT_TO_POINTER(3));
1721 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "long_line_color"),
1722 "color-set", G_CALLBACK(on_color_button_choose_cb), NULL);
1723 /* file chooser buttons in the tools tab */
1724 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_term"),
1725 NULL,
1726 GTK_FILE_CHOOSER_ACTION_OPEN,
1727 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_term")));
1728 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_browser"),
1729 NULL,
1730 GTK_FILE_CHOOSER_ACTION_OPEN,
1731 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_browser")));
1732 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_grep"),
1733 NULL,
1734 GTK_FILE_CHOOSER_ACTION_OPEN,
1735 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_grep")));
1737 /* tools commands */
1738 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_contextaction"),
1739 NULL,
1740 GTK_FILE_CHOOSER_ACTION_OPEN,
1741 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_contextaction")));
1743 /* printing */
1744 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_print_external_cmd"),
1745 NULL,
1746 GTK_FILE_CHOOSER_ACTION_OPEN,
1747 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_external_cmd")));
1749 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "radio_print_gtk"),
1750 "toggled", G_CALLBACK(on_prefs_print_radio_button_toggled), NULL);
1751 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pageheader"),
1752 "toggled", G_CALLBACK(on_prefs_print_page_header_toggled), NULL);
1754 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_plugins"),
1755 "toggled", G_CALLBACK(on_enable_plugins_toggled), NULL);
1756 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_show"),
1757 "toggled", G_CALLBACK(on_toolbar_show_toggled), NULL);
1758 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_notebook_tabs"),
1759 "toggled", G_CALLBACK(on_show_notebook_tabs_toggled), NULL);
1760 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_folding"),
1761 "toggled", G_CALLBACK(on_use_folding_toggled), NULL);
1762 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_open_encoding"),
1763 "toggled", G_CALLBACK(on_open_encoding_toggled), NULL);
1764 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_sidebar_visible"),
1765 "toggled", G_CALLBACK(on_sidebar_visible_toggled), NULL);
1767 g_signal_connect(ui_widgets.prefs_dialog,
1768 "key-press-event", G_CALLBACK(prefs_dialog_key_press_response_cb), NULL);
1771 prefs_init_dialog();
1772 gtk_window_present(GTK_WINDOW(ui_widgets.prefs_dialog));