Enforce filetype extension for user tag files
[geany-mirror.git] / src / prefs.c
blob82eb31b611af3df225610dedbb2ea5d9aaf0e4c9
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 GeanyKeyBinding *kb_index(guint gidx, guint kid);
84 static void kb_cell_edited_cb(GtkCellRendererText *cellrenderertext, gchar *path, gchar *new_text, gpointer user_data);
85 static gboolean kb_grab_key_dialog_key_press_cb(GtkWidget *dialog, GdkEventKey *event, gpointer user_data);
86 static void kb_grab_key_dialog_response_cb(GtkWidget *dialog, gint response, gpointer user_data);
87 static gboolean kb_find_duplicate(GtkWidget *parent, GtkTreeIter *old_iter,
88 guint key, GdkModifierType mods, const gchar *shortcut);
89 static void on_toolbar_show_toggled(GtkToggleButton *togglebutton, gpointer user_data);
90 static void on_show_notebook_tabs_toggled(GtkToggleButton *togglebutton, gpointer user_data);
91 static void on_enable_plugins_toggled(GtkToggleButton *togglebutton, gpointer user_data);
92 static void on_use_folding_toggled(GtkToggleButton *togglebutton, gpointer user_data);
93 static void on_open_encoding_toggled(GtkToggleButton *togglebutton, gpointer user_data);
94 static void on_sidebar_visible_toggled(GtkToggleButton *togglebutton, gpointer user_data);
95 static void on_prefs_print_radio_button_toggled(GtkToggleButton *togglebutton, gpointer user_data);
96 static void on_prefs_print_page_header_toggled(GtkToggleButton *togglebutton, gpointer user_data);
97 static void open_preferences_help(void);
100 typedef enum PrefCallbackAction
102 PREF_DISPLAY,
103 PREF_UPDATE
105 PrefCallbackAction;
108 /* Synchronize Stash settings with widgets (see keyfile.c - init_pref_groups()). */
109 static void prefs_action(PrefCallbackAction action)
111 StashGroup *group;
112 guint i;
114 foreach_ptr_array(group, i, pref_groups)
116 switch (action)
118 case PREF_DISPLAY:
119 stash_group_display(group, ui_widgets.prefs_dialog);
120 break;
121 case PREF_UPDATE:
122 stash_group_update(group, ui_widgets.prefs_dialog);
123 break;
127 switch (action)
129 case PREF_DISPLAY:
130 stash_tree_display(various_treeview);
131 break;
132 case PREF_UPDATE:
133 stash_tree_update(various_treeview);
134 break;
139 enum
141 KB_TREE_ACTION,
142 KB_TREE_SHORTCUT,
143 KB_TREE_INDEX,
144 KB_TREE_EDITABLE,
145 KB_TREE_WEIGHT,
146 KB_TREE_COLUMNS
150 static void kb_tree_view_change_button_clicked_cb(GtkWidget *button, gpointer data)
152 GtkTreeModel *model;
153 GtkTreeSelection *selection;
154 gchar *name;
156 selection = gtk_tree_view_get_selection(tree);
157 if (gtk_tree_selection_get_selected(selection, &model, &g_iter))
159 if (gtk_tree_model_iter_has_child(model, &g_iter))
160 { /* double click on a section to expand or collapse it */
161 GtkTreePath *path = gtk_tree_model_get_path(model, &g_iter);
163 if (gtk_tree_view_row_expanded(tree, path))
164 gtk_tree_view_collapse_row(tree, path);
165 else
166 gtk_tree_view_expand_row(tree, path, FALSE);
168 gtk_tree_path_free(path);
169 return;
172 gtk_tree_model_get(model, &g_iter, KB_TREE_ACTION, &name, -1);
173 if (name != NULL)
175 GtkWidget *dialog;
176 GtkWidget *label;
177 gchar *str;
179 dialog = gtk_dialog_new_with_buttons(_("Grab Key"), GTK_WINDOW(ui_widgets.prefs_dialog),
180 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
181 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
182 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
184 str = g_strdup_printf(
185 _("Press the combination of the keys you want to use for \"%s\"."), name);
186 label = gtk_label_new(str);
187 gtk_misc_set_padding(GTK_MISC(label), 5, 10);
188 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
190 dialog_label = gtk_label_new("");
191 gtk_misc_set_padding(GTK_MISC(dialog_label), 5, 10);
192 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), dialog_label);
194 g_signal_connect(dialog, "key-press-event",
195 G_CALLBACK(kb_grab_key_dialog_key_press_cb), NULL);
196 g_signal_connect(dialog, "response", G_CALLBACK(kb_grab_key_dialog_response_cb), NULL);
198 gtk_widget_show_all(dialog);
199 g_free(str);
200 g_free(name);
206 static void kb_expand_collapse_cb(GtkWidget *item, gpointer user_data)
208 if (user_data != NULL)
209 gtk_tree_view_expand_all(tree);
210 else
211 gtk_tree_view_collapse_all(tree);
215 static void kb_show_popup_menu(GtkWidget *widget, GdkEventButton *event)
217 GtkWidget *item;
218 static GtkWidget *menu = NULL;
219 guint button;
220 guint32 event_time;
222 if (menu == NULL)
224 menu = gtk_menu_new();
226 item = ui_image_menu_item_new(GTK_STOCK_ADD, _("_Expand All"));
227 gtk_widget_show(item);
228 gtk_container_add(GTK_CONTAINER(menu), item);
229 g_signal_connect(item, "activate", G_CALLBACK(kb_expand_collapse_cb), GINT_TO_POINTER(TRUE));
231 item = ui_image_menu_item_new(GTK_STOCK_REMOVE, _("_Collapse All"));
232 gtk_widget_show(item);
233 gtk_container_add(GTK_CONTAINER(menu), item);
234 g_signal_connect(item, "activate", G_CALLBACK(kb_expand_collapse_cb), NULL);
236 gtk_menu_attach_to_widget(GTK_MENU(menu), widget, NULL);
239 if (event != NULL)
241 button = event->button;
242 event_time = event->time;
244 else
246 button = 0;
247 event_time = gtk_get_current_event_time();
250 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, button, event_time);
254 static gboolean kb_popup_menu_cb(GtkWidget *widget, gpointer data)
256 kb_show_popup_menu(widget, NULL);
257 return TRUE;
261 static gboolean kb_tree_view_button_press_event_cb(GtkWidget *widget, GdkEventButton *event,
262 gpointer user_data)
264 if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
266 kb_show_popup_menu(widget, event);
267 return TRUE;
269 else if (event->type == GDK_2BUTTON_PRESS)
271 kb_tree_view_change_button_clicked_cb(NULL, NULL);
272 return TRUE;
274 return FALSE;
278 static void kb_init_tree(void)
280 GtkCellRenderer *renderer;
281 GtkTreeViewColumn *column;
283 tree = GTK_TREE_VIEW(ui_lookup_widget(ui_widgets.prefs_dialog, "treeview7"));
285 store = gtk_tree_store_new(KB_TREE_COLUMNS,
286 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_BOOLEAN, G_TYPE_INT);
287 gtk_tree_view_set_model(GTK_TREE_VIEW(tree), GTK_TREE_MODEL(store));
288 g_object_unref(store);
290 renderer = gtk_cell_renderer_text_new();
291 column = gtk_tree_view_column_new_with_attributes(_("Action"), renderer,
292 "text", KB_TREE_ACTION, "weight", KB_TREE_WEIGHT, NULL);
293 gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
295 renderer = gtk_cell_renderer_text_new();
296 column = gtk_tree_view_column_new_with_attributes(_("Shortcut"), renderer,
297 "text", KB_TREE_SHORTCUT, "editable", KB_TREE_EDITABLE,
298 "weight", KB_TREE_WEIGHT, NULL);
299 gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
301 /* set policy settings for the scrolled window around the treeview again, because glade
302 * doesn't keep the settings */
303 gtk_scrolled_window_set_policy(
304 GTK_SCROLLED_WINDOW(ui_lookup_widget(ui_widgets.prefs_dialog, "scrolledwindow8")),
305 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
307 g_signal_connect(renderer, "edited", G_CALLBACK(kb_cell_edited_cb), NULL);
308 g_signal_connect(tree, "button-press-event", G_CALLBACK(kb_tree_view_button_press_event_cb), NULL);
309 g_signal_connect(tree, "popup-menu", G_CALLBACK(kb_popup_menu_cb), NULL);
310 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "button2"), "clicked",
311 G_CALLBACK(kb_tree_view_change_button_clicked_cb), NULL);
315 static void kb_set_shortcut(GtkTreeStore *store, GtkTreeIter *iter,
316 guint key, GdkModifierType mods)
318 gchar *key_string = gtk_accelerator_name(key, mods);
319 GtkTreeIter parent;
320 guint kid, gid;
321 GeanyKeyBinding *kb;
322 gboolean bold;
324 gtk_tree_store_set(store, iter, KB_TREE_SHORTCUT, key_string, -1);
325 g_free(key_string);
327 gtk_tree_model_get(GTK_TREE_MODEL(store), iter, KB_TREE_INDEX, &kid, -1);
328 gtk_tree_model_iter_parent(GTK_TREE_MODEL(store), &parent, iter);
329 gtk_tree_model_get(GTK_TREE_MODEL(store), &parent, KB_TREE_INDEX, &gid, -1);
330 kb = kb_index(gid, kid);
331 bold = key != kb->default_key || mods != kb->default_mods;
332 gtk_tree_store_set(store, iter, KB_TREE_WEIGHT,
333 bold ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, -1);
337 static void kb_init(void)
339 GtkTreeIter parent, iter;
340 gsize g, i;
341 gchar *label;
342 GeanyKeyGroup *group;
343 GeanyKeyBinding *kb;
345 if (store == NULL)
346 kb_init_tree();
348 foreach_ptr_array(group, g, keybinding_groups)
350 gtk_tree_store_append(store, &parent, NULL);
351 gtk_tree_store_set(store, &parent, KB_TREE_ACTION, group->label,
352 KB_TREE_INDEX, g, -1);
354 foreach_ptr_array(kb, i, group->key_items)
356 label = keybindings_get_label(kb);
357 gtk_tree_store_append(store, &iter, &parent);
358 gtk_tree_store_set(store, &iter, KB_TREE_ACTION, label,
359 KB_TREE_EDITABLE, TRUE, KB_TREE_INDEX, kb->id, -1);
360 kb_set_shortcut(store, &iter, kb->key, kb->mods);
361 g_free(label);
364 gtk_tree_view_expand_all(GTK_TREE_VIEW(tree));
368 /* note: new 'simple' prefs should use Stash code in keyfile.c */
369 static void prefs_init_dialog(void)
371 GtkWidget *widget;
372 GdkColor *color;
374 /* Synchronize with Stash settings */
375 prefs_action(PREF_DISPLAY);
377 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "label_project_indent_warning");
378 ui_widget_show_hide(widget, app->project != NULL);
380 /* General settings */
381 /* startup */
382 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_load_session");
383 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.load_session);
385 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_project_session");
386 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), project_prefs.project_session);
388 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_project_file_in_basedir");
389 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), project_prefs.project_file_in_basedir);
391 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_save_win_pos");
392 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.save_winpos);
394 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ask_for_quit");
395 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.confirm_exit);
397 /* behaviour */
398 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_beep");
399 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.beep_on_errors);
401 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_switch_pages");
402 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.switch_to_status);
404 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_suppress_status_msgs");
405 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.suppress_status_messages);
407 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_auto_focus");
408 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.auto_focus);
410 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_native_windows_dialogs");
411 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
412 interface_prefs.use_native_windows_dialogs);
414 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_contextaction");
415 gtk_entry_set_text(GTK_ENTRY(widget), tool_prefs.context_action_cmd);
417 project_setup_prefs(); /* project files path */
420 /* Interface settings */
421 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_sidebar_visible");
422 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), ui_prefs.sidebar_visible);
423 on_sidebar_visible_toggled(GTK_TOGGLE_BUTTON(widget), NULL);
425 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_symbol");
426 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), interface_prefs.sidebar_symbol_visible);
428 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_openfiles");
429 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), interface_prefs.sidebar_openfiles_visible);
431 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "tagbar_font");
432 gtk_font_button_set_font_name(GTK_FONT_BUTTON(widget), interface_prefs.tagbar_font);
434 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "msgwin_font");
435 gtk_font_button_set_font_name(GTK_FONT_BUTTON(widget), interface_prefs.msgwin_font);
437 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "editor_font");
438 gtk_font_button_set_font_name(GTK_FONT_BUTTON(widget), interface_prefs.editor_font);
440 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_long_line");
441 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), editor_prefs.long_line_column);
443 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_long_line");
444 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.long_line_enabled);
446 switch (editor_prefs.long_line_type)
448 case 0: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_long_line_line"); break;
449 case 1: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_long_line_background"); break;
451 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
453 color = g_new0(GdkColor, 1);
454 gdk_color_parse(editor_prefs.long_line_color, color);
455 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "long_line_color");
456 gtk_color_button_set_color(GTK_COLOR_BUTTON(widget), color);
457 g_free(color);
459 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_notebook_tabs");
460 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), interface_prefs.show_notebook_tabs);
461 /* disable following setting if notebook tabs are hidden */
462 on_show_notebook_tabs_toggled(GTK_TOGGLE_BUTTON(
463 ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_notebook_tabs")), NULL);
465 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_tab_cross");
466 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.show_tab_cross);
468 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_editor");
469 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), interface_prefs.tab_pos_editor);
471 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_msgwin");
472 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), interface_prefs.tab_pos_msgwin);
474 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_sidebar");
475 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), interface_prefs.tab_pos_sidebar);
477 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_statusbar_visible");
478 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), interface_prefs.statusbar_visible);
481 /* Toolbar settings */
482 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_show");
483 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), toolbar_prefs.visible);
484 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_in_menu");
485 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), toolbar_prefs.append_to_menu);
487 switch (toolbar_prefs.icon_style)
489 case 0: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_image"); break;
490 case 1: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_text"); break;
491 default: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_imagetext"); break;
493 if (toolbar_prefs.use_gtk_default_style)
494 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_style_default");
495 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
497 switch (toolbar_prefs.icon_size)
499 case GTK_ICON_SIZE_LARGE_TOOLBAR:
500 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_large"); break;
501 case GTK_ICON_SIZE_SMALL_TOOLBAR:
502 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_small"); break;
503 default: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_verysmall"); break;
505 if (toolbar_prefs.use_gtk_default_icon)
506 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_icon_default");
507 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
509 /* disable elements if toolbar is hidden */
510 on_toolbar_show_toggled(GTK_TOGGLE_BUTTON(
511 ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_show")), NULL);
514 /* Files settings */
515 if (file_prefs.tab_order_ltr)
516 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_tab_right");
517 else
518 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_tab_left");
519 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
521 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_tab_beside");
522 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.tab_order_beside);
524 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_new_encoding");
525 /* luckily the index of the combo box items match the index of the encodings array */
526 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), file_prefs.default_new_encoding);
528 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_open_encoding");
529 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
530 (file_prefs.default_open_encoding >= 0) ? TRUE : FALSE);
531 on_open_encoding_toggled(GTK_TOGGLE_BUTTON(widget), NULL);
533 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_open_encoding");
534 if (file_prefs.default_open_encoding >= 0)
536 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), file_prefs.default_open_encoding);
538 else
539 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), GEANY_ENCODING_UTF_8);
541 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_eol");
542 if (file_prefs.default_eol_character >= 0 && file_prefs.default_eol_character < 3)
544 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), file_prefs.default_eol_character);
546 else
547 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), GEANY_DEFAULT_EOL_CHARACTER);
549 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_trailing_spaces");
550 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.strip_trailing_spaces);
552 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_new_line");
553 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.final_new_line);
555 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ensure_convert_new_lines");
556 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.ensure_convert_new_lines);
558 /* Editor settings */
559 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_toggle_mark");
560 gtk_entry_set_text(GTK_ENTRY(widget), editor_prefs.comment_toggle_mark);
562 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_replace_tabs");
563 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.replace_tabs);
565 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_indent");
566 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_indent_guide);
568 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_white_space");
569 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_white_space);
571 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_end");
572 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_line_endings);
574 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_numbers");
575 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_linenumber_margin);
577 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_markers_margin");
578 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_markers_margin);
580 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_stop_at_last_line");
581 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.scroll_stop_at_last_line);
583 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_wrapping");
584 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.line_wrapping);
586 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_complete_snippets");
587 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.complete_snippets);
589 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_xmltag");
590 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.auto_close_xml_tags);
592 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_folding");
593 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.folding);
595 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_unfold_children");
596 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.unfold_all_children);
597 on_use_folding_toggled(GTK_TOGGLE_BUTTON(
598 ui_lookup_widget(ui_widgets.prefs_dialog, "check_folding")), NULL);
600 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_disable_dnd");
601 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.disable_dnd);
603 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_smart_home");
604 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.smart_home_key);
606 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_newline_strip");
607 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.newline_strip);
609 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_indicators");
610 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.use_indicators);
612 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_auto_multiline");
613 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.auto_continue_multiline);
615 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_symbol_auto_completion");
616 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.auto_complete_symbols);
618 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_symbollistheight");
619 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), editor_prefs.symbolcompletion_max_height);
621 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_symbol_complete_chars");
622 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), editor_prefs.symbolcompletion_min_chars);
624 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_line_break");
625 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), editor_prefs.line_break_column);
627 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_parenthesis");
628 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
629 (editor_prefs.autoclose_chars & GEANY_AC_PARENTHESIS));
631 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_cbracket");
632 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
633 (editor_prefs.autoclose_chars & GEANY_AC_CBRACKET));
635 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_sbracket");
636 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
637 (editor_prefs.autoclose_chars & GEANY_AC_SBRACKET));
639 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_squote");
640 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
641 (editor_prefs.autoclose_chars & GEANY_AC_SQUOTE));
643 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_dquote");
644 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
645 (editor_prefs.autoclose_chars & GEANY_AC_DQUOTE));
647 /* Tools Settings */
649 if (tool_prefs.term_cmd)
650 gtk_entry_set_text(GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_term")), tool_prefs.term_cmd);
652 if (tool_prefs.browser_cmd)
653 gtk_entry_set_text(GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_browser")), tool_prefs.browser_cmd);
655 if (tool_prefs.grep_cmd)
656 gtk_entry_set_text(GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_grep")), tool_prefs.grep_cmd);
659 /* Template settings */
660 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_developer");
661 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.developer);
663 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_company");
664 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.company);
666 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_mail");
667 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.mail);
669 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_initial");
670 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.initials);
672 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_version");
673 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.version);
675 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_year");
676 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.year_format);
678 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_date");
679 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.date_format);
681 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_datetime");
682 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.datetime_format);
685 /* Keybindings */
686 kb_init();
688 /* Printing */
690 GtkWidget *widget_gtk = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_print_gtk");
691 if (printing_prefs.use_gtk_printing)
692 widget = widget_gtk;
693 else
694 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_print_external");
696 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
698 on_prefs_print_radio_button_toggled(GTK_TOGGLE_BUTTON(widget_gtk), NULL);
700 if (printing_prefs.external_print_cmd)
701 gtk_entry_set_text(
702 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_external_cmd")),
703 printing_prefs.external_print_cmd);
705 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_linenumbers");
706 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), printing_prefs.print_line_numbers);
708 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pagenumbers");
709 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), printing_prefs.print_page_numbers);
711 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pageheader");
712 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), printing_prefs.print_page_header);
713 on_prefs_print_page_header_toggled(GTK_TOGGLE_BUTTON(widget), NULL);
715 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_basename");
716 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), printing_prefs.page_header_basename);
718 if (printing_prefs.page_header_datefmt)
719 gtk_entry_set_text(
720 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_dateformat")),
721 printing_prefs.page_header_datefmt);
724 #ifndef HAVE_PLUGINS
725 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_plugins"), FALSE);
726 #endif
727 on_enable_plugins_toggled(GTK_TOGGLE_BUTTON( ui_lookup_widget(ui_widgets.prefs_dialog, "check_plugins")), NULL);
729 #ifdef HAVE_VTE
730 /* make VTE switch visible only when VTE is compiled in, it is hidden by default */
731 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_vte");
732 gtk_widget_show(widget);
733 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vte_info.load_vte);
735 /* VTE settings */
736 if (vte_info.have_vte)
738 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "font_term");
739 gtk_font_button_set_font_name(GTK_FONT_BUTTON(widget), vc->font);
741 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "color_fore");
742 gtk_color_button_set_color(GTK_COLOR_BUTTON(widget), vc->colour_fore);
744 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "color_back");
745 gtk_color_button_set_color(GTK_COLOR_BUTTON(widget), vc->colour_back);
747 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_scrollback");
748 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), vc->scrollback_lines);
750 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_shell");
751 gtk_entry_set_text(GTK_ENTRY(widget), vc->shell);
753 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_key");
754 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->scroll_on_key);
756 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_out");
757 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->scroll_on_out);
759 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_enable_bash_keys");
760 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->enable_bash_keys);
762 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ignore_menu_key");
763 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->ignore_menu_bar_accel);
765 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_follow_path");
766 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->follow_path);
768 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_run_in_vte");
769 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->run_in_vte);
771 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_skip_script");
772 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->skip_run_script);
774 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_cursor_blinks");
775 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->cursor_blinks);
777 #endif
781 /* note: uses group index, not group id, unlike keybindings_lookup_item(). */
782 static GeanyKeyBinding *kb_index(guint gidx, guint kid)
784 GeanyKeyGroup *group;
786 group = g_ptr_array_index(keybinding_groups, gidx);
787 return keybindings_get_item(group, kid);
791 /* read the treeview shortcut fields into keybindings */
792 static void kb_update(void)
794 GtkTreeModel *model = GTK_TREE_MODEL(store);
795 GtkTreeIter child, parent;
796 guint gid = 0;
798 /* get first parent */
799 if (! gtk_tree_model_iter_children(model, &parent, NULL))
800 return;
802 /* foreach parent */
803 while (TRUE)
805 /* get first child */
806 if (! gtk_tree_model_iter_children(model, &child, &parent))
807 return;
809 /* foreach child */
810 while (TRUE)
812 guint kid;
813 gchar *str;
814 guint key;
815 GdkModifierType mods;
816 GeanyKeyBinding *kb;
818 gtk_tree_model_get(model, &child, KB_TREE_INDEX, &kid, KB_TREE_SHORTCUT, &str, -1);
819 gtk_accelerator_parse(str, &key, &mods);
820 g_free(str);
821 kb = kb_index(gid, kid);
822 if (kb->key != key || kb->mods != mods)
823 keybindings_update_combo(kb, key, mods);
825 if (! gtk_tree_model_iter_next(model, &child))
826 break;
828 if (! gtk_tree_model_iter_next(model, &parent))
829 return;
830 gid++;
836 * callbacks
838 /* note: new 'simple' prefs should use Stash code in keyfile.c */
839 static void
840 on_prefs_dialog_response(GtkDialog *dialog, gint response, gpointer user_data)
842 if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY)
844 GtkWidget *widget;
845 guint i;
846 gboolean autoclose_brackets[5];
847 gboolean old_invert_all = interface_prefs.highlighting_invert_all;
848 gboolean old_sidebar_pos = interface_prefs.sidebar_pos;
849 GeanyDocument *doc = document_get_current();
851 /* Synchronize Stash settings */
852 prefs_action(PREF_UPDATE);
854 if (interface_prefs.highlighting_invert_all != old_invert_all)
855 filetypes_reload();
857 if (interface_prefs.sidebar_pos != old_sidebar_pos)
858 ui_swap_sidebar_pos();
860 /* General settings */
861 /* startup */
862 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_load_session");
863 prefs.load_session = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
865 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_project_session");
866 project_prefs.project_session = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
868 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_project_file_in_basedir");
869 project_prefs.project_file_in_basedir = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
871 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_save_win_pos");
872 prefs.save_winpos = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
874 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ask_for_quit");
875 prefs.confirm_exit = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
877 /* behaviour */
878 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_beep");
879 prefs.beep_on_errors = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
881 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_switch_pages");
882 prefs.switch_to_status = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
884 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_suppress_status_msgs");
885 prefs.suppress_status_messages = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
887 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_auto_focus");
888 prefs.auto_focus = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
890 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_native_windows_dialogs");
891 interface_prefs.use_native_windows_dialogs =
892 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
894 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_contextaction");
895 g_free(tool_prefs.context_action_cmd);
896 tool_prefs.context_action_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
898 project_apply_prefs(); /* project file path */
901 /* Interface settings */
902 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_sidebar_visible");
903 ui_prefs.sidebar_visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
905 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_symbol");
906 interface_prefs.sidebar_symbol_visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
908 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_openfiles");
909 interface_prefs.sidebar_openfiles_visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
911 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_long_line");
912 editor_prefs.long_line_enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
914 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_long_line_line");
915 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
916 editor_prefs.long_line_type = 0;
917 else
918 /* now only the "background" radio remains */
919 editor_prefs.long_line_type = 1;
921 if (editor_prefs.long_line_column == 0)
922 editor_prefs.long_line_enabled = FALSE;
924 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_notebook_tabs");
925 interface_prefs.show_notebook_tabs = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
927 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_tab_cross");
928 file_prefs.show_tab_cross = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
930 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_editor");
931 interface_prefs.tab_pos_editor = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
933 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_msgwin");
934 interface_prefs.tab_pos_msgwin = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
936 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_sidebar");
937 interface_prefs.tab_pos_sidebar = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
939 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_statusbar_visible");
940 interface_prefs.statusbar_visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
943 /* Toolbar settings */
944 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_show");
945 toolbar_prefs.visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
946 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_in_menu");
947 toolbar_prefs.append_to_menu = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
949 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_style_default");
950 toolbar_prefs.use_gtk_default_style = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
951 if (! toolbar_prefs.use_gtk_default_style)
953 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_imagetext");
954 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
955 toolbar_prefs.icon_style = 2;
956 else
958 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_image");
959 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
960 toolbar_prefs.icon_style = 0;
961 else
962 /* now only the text only radio remains, so set text only */
963 toolbar_prefs.icon_style = 1;
967 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_icon_default");
968 toolbar_prefs.use_gtk_default_icon = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
969 if (! toolbar_prefs.use_gtk_default_icon)
970 { toolbar_prefs.icon_size = GTK_ICON_SIZE_LARGE_TOOLBAR;
971 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_large");
972 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
973 toolbar_prefs.icon_size = GTK_ICON_SIZE_LARGE_TOOLBAR;
974 else
976 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_small");
977 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
978 toolbar_prefs.icon_size = GTK_ICON_SIZE_SMALL_TOOLBAR;
979 else
980 toolbar_prefs.icon_size = GTK_ICON_SIZE_MENU;
984 /* Files settings */
985 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_tab_right");
986 file_prefs.tab_order_ltr = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
988 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_tab_beside");
989 file_prefs.tab_order_beside = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
991 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_new_encoding");
992 file_prefs.default_new_encoding = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
994 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_open_encoding");
995 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
997 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_open_encoding");
998 file_prefs.default_open_encoding = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
1000 else
1001 file_prefs.default_open_encoding = -1;
1003 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_eol");
1004 file_prefs.default_eol_character = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
1006 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_trailing_spaces");
1007 file_prefs.strip_trailing_spaces = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1009 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_new_line");
1010 file_prefs.final_new_line = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1012 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ensure_convert_new_lines");
1013 file_prefs.ensure_convert_new_lines = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1015 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_replace_tabs");
1016 file_prefs.replace_tabs = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1019 /* Editor settings */
1020 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_toggle_mark");
1021 SETPTR(editor_prefs.comment_toggle_mark,
1022 gtk_editable_get_chars(GTK_EDITABLE(widget), 0, -1));
1024 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_long_line");
1025 /* note: use stash for new code - it updates spin buttons itself */
1026 gtk_spin_button_update(GTK_SPIN_BUTTON(widget));
1027 editor_prefs.long_line_column = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
1029 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_folding");
1030 editor_prefs.folding = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1031 ui_update_fold_items();
1033 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_unfold_children");
1034 editor_prefs.unfold_all_children = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1036 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_indent");
1037 editor_prefs.show_indent_guide = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1039 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_white_space");
1040 editor_prefs.show_white_space = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1042 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_end");
1043 editor_prefs.show_line_endings = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1045 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_numbers");
1046 editor_prefs.show_linenumber_margin = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1048 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_markers_margin");
1049 editor_prefs.show_markers_margin = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1051 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_stop_at_last_line");
1052 editor_prefs.scroll_stop_at_last_line = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1054 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_wrapping");
1055 editor_prefs.line_wrapping = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1057 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_complete_snippets");
1058 editor_prefs.complete_snippets = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1060 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_xmltag");
1061 editor_prefs.auto_close_xml_tags = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1063 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_indicators");
1064 editor_prefs.use_indicators = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1066 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_disable_dnd");
1067 editor_prefs.disable_dnd = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1069 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_smart_home");
1070 editor_prefs.smart_home_key = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1072 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_newline_strip");
1073 editor_prefs.newline_strip = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1075 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_auto_multiline");
1076 editor_prefs.auto_continue_multiline = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1078 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_symbol_auto_completion");
1079 editor_prefs.auto_complete_symbols = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1081 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_symbol_complete_chars");
1082 gtk_spin_button_update(GTK_SPIN_BUTTON(widget));
1083 editor_prefs.symbolcompletion_min_chars = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
1085 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_symbollistheight");
1086 gtk_spin_button_update(GTK_SPIN_BUTTON(widget));
1087 editor_prefs.symbolcompletion_max_height = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
1089 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_line_break");
1090 gtk_spin_button_update(GTK_SPIN_BUTTON(widget));
1091 editor_prefs.line_break_column = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
1093 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_parenthesis");
1094 autoclose_brackets[0] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1096 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_cbracket");
1097 autoclose_brackets[1] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1099 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_sbracket");
1100 autoclose_brackets[2] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1102 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_squote");
1103 autoclose_brackets[3] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1105 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_dquote");
1106 autoclose_brackets[4] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1108 editor_prefs.autoclose_chars =
1109 (autoclose_brackets[0] ? GEANY_AC_PARENTHESIS : 0u)
1110 | (autoclose_brackets[1] ? GEANY_AC_CBRACKET : 0u)
1111 | (autoclose_brackets[2] ? GEANY_AC_SBRACKET : 0u)
1112 | (autoclose_brackets[3] ? GEANY_AC_SQUOTE : 0u)
1113 | (autoclose_brackets[4] ? GEANY_AC_DQUOTE : 0u);
1115 /* Tools Settings */
1117 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_term");
1118 g_free(tool_prefs.term_cmd);
1119 tool_prefs.term_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1121 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_browser");
1122 g_free(tool_prefs.browser_cmd);
1123 tool_prefs.browser_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1125 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_grep");
1126 g_free(tool_prefs.grep_cmd);
1127 tool_prefs.grep_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1130 /* Template settings */
1131 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_developer");
1132 g_free(template_prefs.developer);
1133 template_prefs.developer = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1135 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_company");
1136 g_free(template_prefs.company);
1137 template_prefs.company = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1139 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_mail");
1140 g_free(template_prefs.mail);
1141 template_prefs.mail = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1143 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_initial");
1144 g_free(template_prefs.initials);
1145 template_prefs.initials = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1147 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_version");
1148 g_free(template_prefs.version);
1149 template_prefs.version = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1151 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_year");
1152 g_free(template_prefs.year_format);
1153 template_prefs.year_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1155 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_date");
1156 g_free(template_prefs.date_format);
1157 template_prefs.date_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1159 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_datetime");
1160 g_free(template_prefs.datetime_format);
1161 template_prefs.datetime_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1164 /* Keybindings */
1165 if (edited)
1167 kb_update();
1168 tools_create_insert_custom_command_menu_items();
1169 keybindings_write_to_file();
1172 /* Printing */
1173 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_print_gtk");
1174 printing_prefs.use_gtk_printing = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1176 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_external_cmd");
1177 g_free(printing_prefs.external_print_cmd);
1178 printing_prefs.external_print_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1180 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_linenumbers");
1181 printing_prefs.print_line_numbers = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1183 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pagenumbers");
1184 printing_prefs.print_page_numbers = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1186 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pageheader");
1187 printing_prefs.print_page_header = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1189 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_basename");
1190 printing_prefs.page_header_basename = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1192 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_dateformat");
1193 g_free(printing_prefs.page_header_datefmt);
1194 printing_prefs.page_header_datefmt = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1197 #ifdef HAVE_VTE
1198 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_vte");
1199 vte_info.load_vte = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1201 /* VTE settings */
1202 if (vte_info.have_vte)
1204 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_scrollback");
1205 gtk_spin_button_update(GTK_SPIN_BUTTON(widget));
1206 vc->scrollback_lines = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
1208 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_shell");
1209 g_free(vc->shell);
1210 vc->shell = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1212 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_key");
1213 vc->scroll_on_key = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1215 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_out");
1216 vc->scroll_on_out = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1218 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_enable_bash_keys");
1219 vc->enable_bash_keys = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1221 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ignore_menu_key");
1222 vc->ignore_menu_bar_accel = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1224 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_follow_path");
1225 vc->follow_path = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1227 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_run_in_vte");
1228 vc->run_in_vte = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1230 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_skip_script");
1231 vc->skip_run_script = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1233 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_cursor_blinks");
1234 vc->cursor_blinks = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1236 vte_apply_user_settings();
1238 #endif
1240 /* apply the changes made */
1241 ui_statusbar_showhide(interface_prefs.statusbar_visible);
1242 sidebar_openfiles_update_all(); /* to update if full path setting has changed */
1243 toolbar_apply_settings();
1244 toolbar_update_ui();
1245 toolbar_show_hide();
1246 ui_sidebar_show_hide();
1247 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(main_widgets.notebook), interface_prefs.show_notebook_tabs);
1249 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(main_widgets.notebook), interface_prefs.tab_pos_editor);
1250 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(msgwindow.notebook), interface_prefs.tab_pos_msgwin);
1251 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(main_widgets.sidebar_notebook), interface_prefs.tab_pos_sidebar);
1253 /* re-colourise all open documents, if tab width or long line settings have changed */
1254 for (i = 0; i < documents_array->len; i++)
1256 if (documents[i]->is_valid)
1258 editor_apply_update_prefs(documents[i]->editor);
1259 if (! editor_prefs.folding)
1260 editor_unfold_all(documents[i]->editor);
1263 ui_document_show_hide(NULL);
1264 ui_update_view_editor_menu_items();
1266 /* various preferences */
1267 ui_save_buttons_toggle((doc != NULL) ? doc->changed : FALSE);
1268 msgwin_show_hide_tabs();
1269 ui_update_statusbar(doc, -1);
1271 /* store all settings */
1272 configuration_save();
1275 if (response == GTK_RESPONSE_HELP)
1277 open_preferences_help();
1279 else if (response != GTK_RESPONSE_APPLY)
1281 gtk_tree_store_clear(store);
1282 gtk_widget_hide(GTK_WIDGET(dialog));
1287 static void on_color_button_choose_cb(GtkColorButton *widget, gpointer user_data)
1289 GdkColor color;
1291 gtk_color_button_get_color(widget, &color);
1292 SETPTR(editor_prefs.long_line_color, utils_get_hex_from_color(&color));
1296 static void on_prefs_font_choosed(GtkFontButton *widget, gpointer user_data)
1298 const gchar *fontbtn = gtk_font_button_get_font_name(widget);
1299 guint i;
1301 switch (GPOINTER_TO_INT(user_data))
1303 case 1:
1305 if (strcmp(fontbtn, interface_prefs.tagbar_font) == 0)
1306 break;
1308 SETPTR(interface_prefs.tagbar_font, g_strdup(fontbtn));
1309 for (i = 0; i < documents_array->len; i++)
1311 GeanyDocument *doc = documents[i];
1313 if (documents[i]->is_valid && GTK_IS_WIDGET(doc->priv->tag_tree))
1314 ui_widget_modify_font_from_string(doc->priv->tag_tree,
1315 interface_prefs.tagbar_font);
1317 if (GTK_IS_WIDGET(tv.default_tag_tree))
1318 ui_widget_modify_font_from_string(tv.default_tag_tree, interface_prefs.tagbar_font);
1319 ui_widget_modify_font_from_string(tv.tree_openfiles, interface_prefs.tagbar_font);
1320 break;
1322 case 2:
1324 if (strcmp(fontbtn, interface_prefs.msgwin_font) == 0)
1325 break;
1326 SETPTR(interface_prefs.msgwin_font, g_strdup(fontbtn));
1327 ui_widget_modify_font_from_string(msgwindow.tree_compiler, interface_prefs.msgwin_font);
1328 ui_widget_modify_font_from_string(msgwindow.tree_msg, interface_prefs.msgwin_font);
1329 ui_widget_modify_font_from_string(msgwindow.tree_status, interface_prefs.msgwin_font);
1330 ui_widget_modify_font_from_string(msgwindow.scribble, interface_prefs.msgwin_font);
1331 break;
1333 case 3:
1335 ui_set_editor_font(fontbtn);
1336 break;
1342 static void kb_change_iter_shortcut(GtkTreeIter *iter, const gchar *new_text)
1344 guint lkey;
1345 GdkModifierType lmods;
1347 gtk_accelerator_parse(new_text, &lkey, &lmods);
1349 if (kb_find_duplicate(ui_widgets.prefs_dialog, iter, lkey, lmods, new_text))
1350 return;
1352 /* set the values here, because of the above check, setting it in
1353 * gtk_accelerator_parse would return a wrong key combination if it is duplicate */
1354 kb_set_shortcut(store, iter, lkey, lmods);
1356 edited = TRUE;
1360 static void kb_cell_edited_cb(GtkCellRendererText *cellrenderertext,
1361 gchar *path, gchar *new_text, gpointer user_data)
1363 if (path != NULL && new_text != NULL)
1365 GtkTreeIter iter;
1367 gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store), &iter, path);
1368 if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(store), &iter))
1369 return; /* ignore group items */
1371 kb_change_iter_shortcut(&iter, new_text);
1376 static gboolean kb_grab_key_dialog_key_press_cb(GtkWidget *dialog, GdkEventKey *event, gpointer user_data)
1378 gchar *str;
1379 guint state;
1381 state = event->state & gtk_accelerator_get_default_mod_mask();
1383 if (event->keyval == GDK_Escape)
1384 return FALSE; /* close the dialog, don't allow escape when detecting keybindings. */
1386 str = gtk_accelerator_name(event->keyval, state);
1388 gtk_label_set_text(GTK_LABEL(dialog_label), str);
1389 g_free(str);
1391 return TRUE;
1395 static void kb_grab_key_dialog_response_cb(GtkWidget *dialog, gint response, G_GNUC_UNUSED gpointer iter)
1397 if (response == GTK_RESPONSE_ACCEPT)
1399 const gchar *new_text = gtk_label_get_text(GTK_LABEL(dialog_label));
1401 kb_change_iter_shortcut(&g_iter, new_text);
1403 gtk_widget_destroy(dialog);
1407 /* test if the entered key combination is already used
1408 * returns true if cancelling duplicate */
1409 static gboolean kb_find_duplicate(GtkWidget *parent, GtkTreeIter *old_iter,
1410 guint key, GdkModifierType mods, const gchar *shortcut)
1412 GtkTreeModel *model = GTK_TREE_MODEL(store);
1413 GtkTreeIter parent_iter;
1414 gchar *kb_str;
1415 guint kb_key;
1416 GdkModifierType kb_mods;
1418 /* allow duplicate if there is no key combination */
1419 if (key == 0 && mods == 0)
1420 return FALSE;
1422 /* don't check if the new keybinding is the same as the old one */
1423 gtk_tree_model_get(model, old_iter, KB_TREE_SHORTCUT, &kb_str, -1);
1424 if (kb_str)
1426 gtk_accelerator_parse(kb_str, &kb_key, &kb_mods);
1427 g_free(kb_str);
1428 if (key == kb_key && mods == kb_mods)
1429 return FALSE;
1432 if (! gtk_tree_model_get_iter_first(model, &parent_iter))
1433 return FALSE;
1434 do /* foreach top level */
1436 GtkTreeIter iter;
1438 if (! gtk_tree_model_iter_children(model, &iter, &parent_iter))
1439 continue;
1440 do /* foreach children */
1442 gtk_tree_model_get(model, &iter, KB_TREE_SHORTCUT, &kb_str, -1);
1443 if (! kb_str)
1444 continue;
1446 gtk_accelerator_parse(kb_str, &kb_key, &kb_mods);
1447 g_free(kb_str);
1448 /* search another item with the same key and modifiers */
1449 if (kb_key == key && kb_mods == mods)
1451 gchar *label;
1452 gint ret;
1454 gtk_tree_model_get(model, &iter, KB_TREE_ACTION, &label, -1);
1455 ret = dialogs_show_prompt(parent,
1456 _("_Allow"), GTK_RESPONSE_APPLY,
1457 GTK_STOCK_CANCEL, GTK_RESPONSE_NO,
1458 _("_Override"), GTK_RESPONSE_YES,
1459 _("Override that keybinding?"),
1460 _("The combination '%s' is already used for \"%s\"."),
1461 shortcut, label);
1463 g_free(label);
1465 if (ret == GTK_RESPONSE_YES)
1467 kb_set_shortcut(store, &iter, 0, 0); /* clear shortcut */
1468 /* carry on looking for other duplicates if overriding */
1469 continue;
1471 return ret == GTK_RESPONSE_NO;
1474 while (gtk_tree_model_iter_next(model, &iter));
1476 while (gtk_tree_model_iter_next(model, &parent_iter));
1478 return FALSE;
1482 static void on_toolbar_show_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1484 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1486 gtk_widget_set_sensitive(
1487 ui_lookup_widget(ui_widgets.prefs_dialog, "frame_toolbar_style"), sens);
1488 gtk_widget_set_sensitive(
1489 ui_lookup_widget(ui_widgets.prefs_dialog, "frame_toolbar_icon"), sens);
1490 gtk_widget_set_sensitive(
1491 ui_lookup_widget(ui_widgets.prefs_dialog, "button_customize_toolbar"), sens);
1492 gtk_widget_set_sensitive(
1493 ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_in_menu"), sens);
1497 static void on_show_notebook_tabs_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1499 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1501 /* tab placement only enabled when tabs are visible */
1502 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_editor"), sens);
1503 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_tab_cross"), sens);
1507 static void on_use_folding_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1509 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1511 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_unfold_children"), sens);
1515 static void on_enable_plugins_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, "extra_plugin_path_entry"), sens);
1520 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "extra_plugin_path_button"), sens);
1524 static void on_open_encoding_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, "eventbox3"), sens);
1529 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "label_open_encoding"), sens);
1533 static void on_sidebar_visible_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_list_openfiles"), sens);
1538 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_symbol"), sens);
1542 static void on_prefs_print_radio_button_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1544 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1546 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox29"), sens);
1547 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "hbox9"), ! sens);
1551 static void on_prefs_print_page_header_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1553 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1555 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_basename"), sens);
1556 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_dateformat"), sens);
1560 static void open_preferences_help(void)
1562 gchar *uri;
1563 const gchar *label, *suffix = NULL;
1564 GtkNotebook *notebook = GTK_NOTEBOOK(
1565 ui_lookup_widget(ui_widgets.prefs_dialog, "notebook2"));
1566 gint page_nr = gtk_notebook_get_current_page(notebook);
1567 GtkWidget *page = gtk_notebook_get_nth_page(notebook, page_nr);
1569 label = gtk_notebook_get_tab_label_text(notebook, page);
1571 /* TODO Find a better way to map the current notebook page to the
1572 * corresponding chapter in the documentation, comparing translatable
1573 * strings is easy to break. Maybe attach an identifying string to the
1574 * tab label object. */
1575 if (utils_str_equal(label, _("General")))
1576 suffix = "#general-startup-preferences";
1577 else if (utils_str_equal(label, _("Interface")))
1578 suffix = "#interface-preferences";
1579 else if (utils_str_equal(label, _("Toolbar")))
1580 suffix = "#toolbar-preferences";
1581 else if (utils_str_equal(label, _("Editor")))
1582 suffix = "#editor-features-preferences";
1583 else if (utils_str_equal(label, _("Files")))
1584 suffix = "#files-preferences";
1585 else if (utils_str_equal(label, _("Tools")))
1586 suffix = "#tools-preferences";
1587 else if (utils_str_equal(label, _("Templates")))
1588 suffix = "#template-preferences";
1589 else if (utils_str_equal(label, _("Keybindings")))
1590 suffix = "#keybinding-preferences";
1591 else if (utils_str_equal(label, _("Printing")))
1592 suffix = "#printing-preferences";
1593 else if (utils_str_equal(label, _("Various")))
1594 suffix = "#various-preferences";
1595 else if (utils_str_equal(label, _("Terminal")))
1596 suffix = "#terminal-vte-preferences";
1598 uri = utils_get_help_url(suffix);
1599 utils_open_browser(uri);
1600 g_free(uri);
1604 static gboolean prefs_dialog_key_press_response_cb(GtkWidget *dialog, GdkEventKey *event,
1605 gpointer data)
1607 GeanyKeyBinding *kb = keybindings_lookup_item(GEANY_KEY_GROUP_HELP, GEANY_KEYS_HELP_HELP);
1609 if (keybindings_check_event(event, kb))
1611 open_preferences_help();
1612 return TRUE;
1614 return FALSE;
1618 static void list_store_append_text(GtkListStore *list, const gchar *text)
1620 GtkTreeIter iter;
1622 gtk_list_store_append(list, &iter);
1623 gtk_list_store_set(list, &iter, 0, text, -1);
1627 void prefs_show_dialog(void)
1629 if (ui_widgets.prefs_dialog == NULL)
1631 GtkListStore *encoding_list, *eol_list;
1632 GtkWidget *label;
1633 guint i;
1634 gchar *encoding_string;
1635 GdkPixbuf *pb;
1637 ui_widgets.prefs_dialog = create_prefs_dialog();
1638 gtk_widget_set_name(ui_widgets.prefs_dialog, "GeanyPrefsDialog");
1639 gtk_window_set_transient_for(GTK_WINDOW(ui_widgets.prefs_dialog), GTK_WINDOW(main_widgets.window));
1640 pb = ui_new_pixbuf_from_inline(GEANY_IMAGE_LOGO);
1641 gtk_window_set_icon(GTK_WINDOW(ui_widgets.prefs_dialog), pb);
1642 g_object_unref(pb); /* free our reference */
1644 /* init the file encoding combo boxes */
1645 encoding_list = ui_builder_get_object("encoding_list");
1646 for (i = 0; i < GEANY_ENCODINGS_MAX; i++)
1648 encoding_string = encodings_to_string(&encodings[i]);
1649 list_store_append_text(encoding_list, encoding_string);
1650 g_free(encoding_string);
1653 /* init the eol character combo box */
1654 eol_list = ui_builder_get_object("eol_list");
1655 list_store_append_text(eol_list, utils_get_eol_name(SC_EOL_CRLF));
1656 list_store_append_text(eol_list, utils_get_eol_name(SC_EOL_CR));
1657 list_store_append_text(eol_list, utils_get_eol_name(SC_EOL_LF));
1659 /* add manually GeanyWrapLabels because they can't be added with Glade */
1660 /* page Tools */
1661 label = geany_wrap_label_new(_("Enter tool paths below. Tools you do not need can be left blank."));
1662 gtk_widget_show(label);
1663 gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox33")),
1664 label, FALSE, TRUE, 5);
1665 /* page Templates */
1666 label = geany_wrap_label_new(_("Set the information to be used in templates. See the documentation for details."));
1667 gtk_widget_show(label);
1668 gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox31")),
1669 label, FALSE, TRUE, 5);
1670 /* page Keybindings */
1671 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."));
1672 gtk_widget_show(label);
1673 gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox32")),
1674 label, FALSE, TRUE, 5);
1675 /* page Editor->Indentation */
1676 label = geany_wrap_label_new(_("<i>Warning: these settings are overridden by the current project. See <b>Project->Properties</b>.</i>"));
1677 gtk_widget_show(label);
1678 gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
1679 gtk_misc_set_padding(GTK_MISC(label), 6, 0);
1680 gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog,
1681 "label_project_indent_warning")), label, FALSE, TRUE, 5);
1683 /* add the clear icon to GtkEntry widgets in the dialog */
1685 const gchar *names[] = {
1686 "startup_path_entry",
1687 "project_file_path_entry",
1688 "extra_plugin_path_entry",
1689 "entry_toggle_mark",
1690 /* "entry_com_make", */
1691 "entry_com_term",
1692 "entry_browser",
1693 "entry_grep",
1694 "entry_contextaction",
1695 "entry_template_developer",
1696 "entry_template_initial",
1697 "entry_template_mail",
1698 "entry_template_company",
1699 "entry_template_version",
1700 "entry_template_year",
1701 "entry_template_date",
1702 "entry_template_datetime",
1703 "entry_print_external_cmd",
1704 "entry_print_dateformat"};
1705 const gchar **name;
1707 foreach_c_array(name, names, G_N_ELEMENTS(names))
1708 ui_entry_add_clear_icon(GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, *name)));
1711 /* page Various */
1712 various_treeview = GTK_TREE_VIEW(ui_lookup_widget(ui_widgets.prefs_dialog,
1713 "various_treeview"));
1714 stash_tree_setup(pref_groups, various_treeview);
1716 #ifdef HAVE_VTE
1717 vte_append_preferences_tab();
1718 #endif
1720 #ifndef G_OS_WIN32
1721 gtk_widget_hide(ui_lookup_widget(ui_widgets.prefs_dialog, "check_native_windows_dialogs"));
1722 #endif
1723 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "startup_path_button"), NULL,
1724 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "startup_path_entry")));
1725 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "extra_plugin_path_button"), NULL,
1726 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "extra_plugin_path_entry")));
1728 g_signal_connect(ui_widgets.prefs_dialog, "response",
1729 G_CALLBACK(on_prefs_dialog_response), NULL);
1730 g_signal_connect(ui_widgets.prefs_dialog, "delete-event",
1731 G_CALLBACK(gtk_widget_hide_on_delete), NULL);
1733 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "tagbar_font"),
1734 "font-set", G_CALLBACK(on_prefs_font_choosed), GINT_TO_POINTER(1));
1735 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "msgwin_font"),
1736 "font-set", G_CALLBACK(on_prefs_font_choosed), GINT_TO_POINTER(2));
1737 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "editor_font"),
1738 "font-set", G_CALLBACK(on_prefs_font_choosed), GINT_TO_POINTER(3));
1739 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "long_line_color"),
1740 "color-set", G_CALLBACK(on_color_button_choose_cb), NULL);
1741 /* file chooser buttons in the tools tab */
1742 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_term"),
1743 NULL,
1744 GTK_FILE_CHOOSER_ACTION_OPEN,
1745 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_term")));
1746 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_browser"),
1747 NULL,
1748 GTK_FILE_CHOOSER_ACTION_OPEN,
1749 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_browser")));
1750 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_grep"),
1751 NULL,
1752 GTK_FILE_CHOOSER_ACTION_OPEN,
1753 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_grep")));
1755 /* tools commands */
1756 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_contextaction"),
1757 NULL,
1758 GTK_FILE_CHOOSER_ACTION_OPEN,
1759 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_contextaction")));
1761 /* printing */
1762 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_print_external_cmd"),
1763 NULL,
1764 GTK_FILE_CHOOSER_ACTION_OPEN,
1765 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_external_cmd")));
1767 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "radio_print_gtk"),
1768 "toggled", G_CALLBACK(on_prefs_print_radio_button_toggled), NULL);
1769 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pageheader"),
1770 "toggled", G_CALLBACK(on_prefs_print_page_header_toggled), NULL);
1772 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_plugins"),
1773 "toggled", G_CALLBACK(on_enable_plugins_toggled), NULL);
1774 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_show"),
1775 "toggled", G_CALLBACK(on_toolbar_show_toggled), NULL);
1776 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_notebook_tabs"),
1777 "toggled", G_CALLBACK(on_show_notebook_tabs_toggled), NULL);
1778 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_folding"),
1779 "toggled", G_CALLBACK(on_use_folding_toggled), NULL);
1780 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_open_encoding"),
1781 "toggled", G_CALLBACK(on_open_encoding_toggled), NULL);
1782 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_sidebar_visible"),
1783 "toggled", G_CALLBACK(on_sidebar_visible_toggled), NULL);
1785 g_signal_connect(ui_widgets.prefs_dialog,
1786 "key-press-event", G_CALLBACK(prefs_dialog_key_press_response_cb), NULL);
1789 prefs_init_dialog();
1790 gtk_window_present(GTK_WINDOW(ui_widgets.prefs_dialog));