Create branch for 0.19.1 release (copied from 0.19).
[geany-mirror.git] / src / prefs.c
blob5332598a888bf48e003fcd10fa8347519cdd39af
1 /*
2 * prefs.c - this file is part of Geany, a fast and lightweight IDE
4 * Copyright 2005-2010 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
5 * Copyright 2006-2010 Nick Treleaven <nick(dot)treleaven(at)btinternet(dot)com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 * $Id$
25 * @file prefs.h
26 * Preferences dialog.
30 * Preferences dialog support functions.
31 * New prefs should use Stash code in keyfile.c - init_pref_groups().
34 #include <stdlib.h>
35 #include <string.h>
36 #include <gdk/gdkkeysyms.h>
38 #include "geany.h"
40 #include "prefs.h"
41 #include "support.h"
42 #include "dialogs.h"
43 #include "ui_utils.h"
44 #include "utils.h"
45 #include "sciwrappers.h"
46 #include "document.h"
47 #include "documentprivate.h"
48 #include "msgwindow.h"
49 #include "keyfile.h"
50 #include "keybindings.h"
51 #include "interface.h"
52 #include "encodings.h"
53 #include "project.h"
54 #include "editor.h"
55 #include "main.h"
56 #include "sidebar.h"
57 #include "printing.h"
58 #include "geanywraplabel.h"
59 #include "templates.h"
60 #include "search.h"
61 #include "toolbar.h"
62 #include "stash.h"
63 #include "keyfile.h"
64 #include "filetypes.h"
65 #include "win32.h"
67 #ifdef HAVE_VTE
68 # include "vte.h"
69 #endif
73 GeanyPrefs prefs;
74 GeanyToolPrefs tool_prefs;
77 static gchar *dialog_key_name;
78 static GtkTreeIter g_iter;
79 static GtkTreeStore *store = NULL;
80 static GtkTreeView *tree = NULL;
81 static GtkWidget *dialog_label;
82 static gboolean edited = FALSE;
84 static void kb_cell_edited_cb(GtkCellRendererText *cellrenderertext, gchar *path, gchar *new_text, gpointer user_data);
85 static gboolean kb_keytype_dialog_response_cb(GtkWidget *dialog, GdkEventKey *event, gpointer user_data);
86 static void kb_dialog_response_cb(GtkWidget *dialog, gint response, gpointer user_data);
87 static gboolean kb_find_duplicate(GtkWidget *parent, GeanyKeyBinding *search_kb,
88 guint key, GdkModifierType mods, const gchar *action);
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);
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;
128 enum
130 KB_TREE_ACTION,
131 KB_TREE_SHORTCUT,
132 KB_TREE_INDEX
136 static void kb_tree_view_change_button_clicked_cb(GtkWidget *button, gpointer data)
138 GtkTreeModel *model;
139 GtkTreeSelection *selection;
140 gchar *name;
142 selection = gtk_tree_view_get_selection(tree);
143 if (gtk_tree_selection_get_selected(selection, &model, &g_iter))
145 if (gtk_tree_model_iter_has_child(model, &g_iter))
146 { /* double click on a section to expand or collapse it */
147 GtkTreePath *path = gtk_tree_model_get_path(model, &g_iter);
149 if (gtk_tree_view_row_expanded(tree, path))
150 gtk_tree_view_collapse_row(tree, path);
151 else
152 gtk_tree_view_expand_row(tree, path, FALSE);
154 gtk_tree_path_free(path);
155 return;
158 gtk_tree_model_get(model, &g_iter, KB_TREE_ACTION, &name, -1);
159 if (name != NULL)
161 GtkWidget *dialog;
162 GtkWidget *label;
163 gchar *str;
165 dialog = gtk_dialog_new_with_buttons(_("Grab Key"), GTK_WINDOW(ui_widgets.prefs_dialog),
166 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
167 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
168 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
170 str = g_strdup_printf(
171 _("Press the combination of the keys you want to use for \"%s\"."), name);
172 label = gtk_label_new(str);
173 gtk_misc_set_padding(GTK_MISC(label), 5, 10);
174 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label);
176 dialog_label = gtk_label_new("");
177 gtk_misc_set_padding(GTK_MISC(dialog_label), 5, 10);
178 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), dialog_label);
180 g_signal_connect(dialog, "key-press-event",
181 G_CALLBACK(kb_keytype_dialog_response_cb), NULL);
182 g_signal_connect(dialog, "response", G_CALLBACK(kb_dialog_response_cb), NULL);
184 /* copy name to global variable to hold it, will be freed in on_dialog_response() */
185 dialog_key_name = g_strdup(name);
187 gtk_widget_show_all(dialog);
188 g_free(str);
189 g_free(name);
195 static void kb_expand_collapse_cb(GtkWidget *item, gpointer user_data)
197 if (user_data != NULL)
198 gtk_tree_view_expand_all(tree);
199 else
200 gtk_tree_view_collapse_all(tree);
204 static void kb_show_popup_menu(GtkWidget *widget, GdkEventButton *event)
206 GtkWidget *item;
207 static GtkWidget *menu = NULL;
208 gint button, event_time;
210 if (menu == NULL)
212 menu = gtk_menu_new();
214 item = ui_image_menu_item_new(GTK_STOCK_ADD, _("_Expand All"));
215 gtk_widget_show(item);
216 gtk_container_add(GTK_CONTAINER(menu), item);
217 g_signal_connect(item, "activate", G_CALLBACK(kb_expand_collapse_cb), GINT_TO_POINTER(TRUE));
219 item = ui_image_menu_item_new(GTK_STOCK_REMOVE, _("_Collapse All"));
220 gtk_widget_show(item);
221 gtk_container_add(GTK_CONTAINER(menu), item);
222 g_signal_connect(item, "activate", G_CALLBACK(kb_expand_collapse_cb), NULL);
224 gtk_menu_attach_to_widget(GTK_MENU(menu), widget, NULL);
227 if (event != NULL)
229 button = event->button;
230 event_time = event->time;
232 else
234 button = 0;
235 event_time = gtk_get_current_event_time();
238 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, button, event_time);
242 static gboolean kb_popup_menu_cb(GtkWidget *widget, gpointer data)
244 kb_show_popup_menu(widget, NULL);
245 return TRUE;
249 static gboolean kb_tree_view_button_press_event_cb(GtkWidget *widget, GdkEventButton *event,
250 gpointer user_data)
252 if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
254 kb_show_popup_menu(widget, event);
255 return TRUE;
257 else if (event->type == GDK_2BUTTON_PRESS)
259 kb_tree_view_change_button_clicked_cb(NULL, NULL);
260 return TRUE;
262 return FALSE;
266 static void kb_init_tree(void)
268 GtkCellRenderer *renderer;
269 GtkTreeViewColumn *column;
271 tree = GTK_TREE_VIEW(ui_lookup_widget(ui_widgets.prefs_dialog, "treeview7"));
273 store = gtk_tree_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT);
274 gtk_tree_view_set_model(GTK_TREE_VIEW(tree), GTK_TREE_MODEL(store));
275 g_object_unref(store);
277 renderer = gtk_cell_renderer_text_new();
278 column = gtk_tree_view_column_new_with_attributes(_("Action"), renderer, "text", KB_TREE_ACTION, NULL);
279 gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
281 renderer = gtk_cell_renderer_text_new();
282 g_object_set(renderer, "editable", TRUE, NULL);
283 column = gtk_tree_view_column_new_with_attributes(_("Shortcut"), renderer, "text", KB_TREE_SHORTCUT, NULL);
284 gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
286 /* set policy settings for the scollwedwindow around the treeview again, because glade
287 * doesn't keep the settings */
288 gtk_scrolled_window_set_policy(
289 GTK_SCROLLED_WINDOW(ui_lookup_widget(ui_widgets.prefs_dialog, "scrolledwindow8")),
290 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
292 g_signal_connect(renderer, "edited", G_CALLBACK(kb_cell_edited_cb), NULL);
293 g_signal_connect(tree, "button-press-event", G_CALLBACK(kb_tree_view_button_press_event_cb), NULL);
294 g_signal_connect(tree, "popup-menu", G_CALLBACK(kb_popup_menu_cb), NULL);
295 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "button2"), "clicked",
296 G_CALLBACK(kb_tree_view_change_button_clicked_cb), NULL);
300 static void kb_init(void)
302 GtkTreeIter parent, iter;
303 gsize g, i;
304 gchar *key_string, *label;
305 GeanyKeyGroup *group;
306 GeanyKeyBinding *kb;
308 if (store == NULL)
309 kb_init_tree();
311 for (g = 0; g < keybinding_groups->len; g++)
313 group = g_ptr_array_index(keybinding_groups, g);
315 gtk_tree_store_append(store, &parent, NULL);
316 gtk_tree_store_set(store, &parent, KB_TREE_ACTION, group->label,
317 KB_TREE_INDEX, g, -1);
319 for (i = 0; i < group->count; i++)
321 kb = &group->keys[i];
323 label = keybindings_get_label(kb);
324 key_string = gtk_accelerator_name(kb->key, kb->mods);
325 gtk_tree_store_append(store, &iter, &parent);
326 gtk_tree_store_set(store, &iter, KB_TREE_ACTION, label,
327 KB_TREE_SHORTCUT, key_string, KB_TREE_INDEX, i, -1);
328 g_free(key_string);
329 g_free(label);
332 gtk_tree_view_expand_all(GTK_TREE_VIEW(tree));
336 /* note: new prefs should use Stash code in keyfile.c */
337 static void prefs_init_dialog(void)
339 GtkWidget *widget;
340 GdkColor *color;
342 /* Synchronize with Stash settings */
343 prefs_action(PREF_DISPLAY);
345 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "label_project_indent_warning");
346 ui_widget_show_hide(widget, app->project != NULL);
348 /* General settings */
349 /* startup */
350 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_load_session");
351 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.load_session);
353 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_project_session");
354 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), project_prefs.project_session);
356 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_project_file_in_basedir");
357 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), project_prefs.project_file_in_basedir);
359 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_save_win_pos");
360 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.save_winpos);
362 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ask_for_quit");
363 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.confirm_exit);
365 /* behaviour */
366 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_beep");
367 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.beep_on_errors);
369 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_switch_pages");
370 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.switch_to_status);
372 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_suppress_status_msgs");
373 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.suppress_status_messages);
375 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_auto_focus");
376 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), prefs.auto_focus);
378 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_native_windows_dialogs");
379 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
380 interface_prefs.use_native_windows_dialogs);
382 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_contextaction");
383 gtk_entry_set_text(GTK_ENTRY(widget), tool_prefs.context_action_cmd);
385 project_setup_prefs(); /* project files path */
388 /* Interface settings */
389 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_sidebar_visible");
390 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), ui_prefs.sidebar_visible);
391 on_sidebar_visible_toggled(GTK_TOGGLE_BUTTON(widget), NULL);
393 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_symbol");
394 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), interface_prefs.sidebar_symbol_visible);
396 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_openfiles");
397 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), interface_prefs.sidebar_openfiles_visible);
399 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "tagbar_font");
400 gtk_font_button_set_font_name(GTK_FONT_BUTTON(widget), interface_prefs.tagbar_font);
402 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "msgwin_font");
403 gtk_font_button_set_font_name(GTK_FONT_BUTTON(widget), interface_prefs.msgwin_font);
405 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "editor_font");
406 gtk_font_button_set_font_name(GTK_FONT_BUTTON(widget), interface_prefs.editor_font);
408 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_long_line");
409 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), editor_prefs.long_line_global_column);
411 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_long_line");
412 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.long_line_global_enabled);
414 switch (editor_prefs.long_line_global_type)
416 case 0: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_long_line_line"); break;
417 case 1: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_long_line_background"); break;
419 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
421 color = g_new0(GdkColor, 1);
422 gdk_color_parse(editor_prefs.long_line_color, color);
423 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "long_line_color");
424 gtk_color_button_set_color(GTK_COLOR_BUTTON(widget), color);
425 g_free(color);
427 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_notebook_tabs");
428 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), interface_prefs.show_notebook_tabs);
429 /* disable following setting if notebook tabs are hidden */
430 on_show_notebook_tabs_toggled(GTK_TOGGLE_BUTTON(
431 ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_notebook_tabs")), NULL);
433 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_tab_cross");
434 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.show_tab_cross);
436 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_editor");
437 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), interface_prefs.tab_pos_editor);
439 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_msgwin");
440 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), interface_prefs.tab_pos_msgwin);
442 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_sidebar");
443 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), interface_prefs.tab_pos_sidebar);
445 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_statusbar_visible");
446 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), interface_prefs.statusbar_visible);
449 /* Toolbar settings */
450 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_show");
451 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), toolbar_prefs.visible);
452 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_in_menu");
453 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), toolbar_prefs.append_to_menu);
455 switch (toolbar_prefs.icon_style)
457 case 0: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_image"); break;
458 case 1: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_text"); break;
459 default: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_imagetext"); break;
461 if (toolbar_prefs.use_gtk_default_style)
462 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_style_default");
463 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
465 switch (toolbar_prefs.icon_size)
467 case GTK_ICON_SIZE_LARGE_TOOLBAR:
468 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_large"); break;
469 case GTK_ICON_SIZE_SMALL_TOOLBAR:
470 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_small"); break;
471 default: widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_verysmall"); break;
473 if (toolbar_prefs.use_gtk_default_icon)
474 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_icon_default");
475 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
477 /* disable elements if toolbar is hidden */
478 on_toolbar_show_toggled(GTK_TOGGLE_BUTTON(
479 ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_show")), NULL);
482 /* Files settings */
483 if (file_prefs.tab_order_ltr)
484 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_tab_right");
485 else
486 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_tab_left");
487 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
489 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_tab_beside");
490 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.tab_order_beside);
492 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_new_encoding");
493 /* luckily the index of the combo box items match the index of the encodings array */
494 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), file_prefs.default_new_encoding);
496 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_open_encoding");
497 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
498 (file_prefs.default_open_encoding >= 0) ? TRUE : FALSE);
499 on_open_encoding_toggled(GTK_TOGGLE_BUTTON(widget), NULL);
501 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_open_encoding");
502 if (file_prefs.default_open_encoding >= 0)
504 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), file_prefs.default_open_encoding);
506 else
507 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), GEANY_ENCODING_UTF_8);
509 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_eol");
510 if (file_prefs.default_eol_character >= 0 && file_prefs.default_eol_character < 3)
512 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), file_prefs.default_eol_character);
514 else
515 gtk_combo_box_set_active(GTK_COMBO_BOX(widget), GEANY_DEFAULT_EOL_CHARACTER);
517 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_trailing_spaces");
518 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.strip_trailing_spaces);
520 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_new_line");
521 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.final_new_line);
523 /* Editor settings */
524 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_toggle_mark");
525 gtk_entry_set_text(GTK_ENTRY(widget), editor_prefs.comment_toggle_mark);
527 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_replace_tabs");
528 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), file_prefs.replace_tabs);
530 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_indent");
531 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_indent_guide);
533 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_white_space");
534 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_white_space);
536 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_end");
537 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_line_endings);
539 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_numbers");
540 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_linenumber_margin);
542 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_markers_margin");
543 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.show_markers_margin);
545 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_stop_at_last_line");
546 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.scroll_stop_at_last_line);
548 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_wrapping");
549 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.line_wrapping);
551 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_complete_snippets");
552 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.complete_snippets);
554 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_xmltag");
555 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.auto_close_xml_tags);
557 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_folding");
558 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.folding);
560 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_unfold_children");
561 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.unfold_all_children);
562 on_use_folding_toggled(GTK_TOGGLE_BUTTON(
563 ui_lookup_widget(ui_widgets.prefs_dialog, "check_folding")), NULL);
565 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_disable_dnd");
566 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.disable_dnd);
568 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_smart_home");
569 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.smart_home_key);
571 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_newline_strip");
572 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.newline_strip);
574 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_indicators");
575 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.use_indicators);
577 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_auto_multiline");
578 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.auto_continue_multiline);
580 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_symbol_auto_completion");
581 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), editor_prefs.auto_complete_symbols);
583 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_symbollistheight");
584 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), editor_prefs.symbolcompletion_max_height);
586 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_symbol_complete_chars");
587 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), editor_prefs.symbolcompletion_min_chars);
589 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_line_break");
590 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), editor_prefs.line_break_column);
592 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_parenthesis");
593 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
594 (editor_prefs.autoclose_chars & GEANY_AC_PARENTHESIS));
596 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_cbracket");
597 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
598 (editor_prefs.autoclose_chars & GEANY_AC_CBRACKET));
600 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_sbracket");
601 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
602 (editor_prefs.autoclose_chars & GEANY_AC_SBRACKET));
604 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_squote");
605 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
606 (editor_prefs.autoclose_chars & GEANY_AC_SQUOTE));
608 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_dquote");
609 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
610 (editor_prefs.autoclose_chars & GEANY_AC_DQUOTE));
612 /* Tools Settings */
614 if (tool_prefs.term_cmd)
615 gtk_entry_set_text(GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_term")), tool_prefs.term_cmd);
617 if (tool_prefs.browser_cmd)
618 gtk_entry_set_text(GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_browser")), tool_prefs.browser_cmd);
620 if (tool_prefs.grep_cmd)
621 gtk_entry_set_text(GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_grep")), tool_prefs.grep_cmd);
624 /* Template settings */
625 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_developer");
626 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.developer);
628 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_company");
629 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.company);
631 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_mail");
632 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.mail);
634 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_initial");
635 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.initials);
637 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_version");
638 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.version);
640 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_year");
641 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.year_format);
643 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_date");
644 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.date_format);
646 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_datetime");
647 gtk_entry_set_text(GTK_ENTRY(widget), template_prefs.datetime_format);
650 /* Keybindings */
651 kb_init();
653 /* Printing */
655 GtkWidget *widget_gtk = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_print_gtk");
656 if (printing_prefs.use_gtk_printing)
657 widget = widget_gtk;
658 else
659 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_print_external");
661 #if GTK_CHECK_VERSION(2, 10, 0)
662 if (gtk_check_version(2, 10, 0) != NULL)
663 #endif
665 gtk_widget_set_sensitive(widget_gtk, FALSE); /* disable the whole option block */
666 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_print_external");
668 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
670 on_prefs_print_radio_button_toggled(GTK_TOGGLE_BUTTON(widget_gtk), NULL);
672 if (printing_prefs.external_print_cmd)
673 gtk_entry_set_text(
674 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_external_cmd")),
675 printing_prefs.external_print_cmd);
677 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_linenumbers");
678 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), printing_prefs.print_line_numbers);
680 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pagenumbers");
681 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), printing_prefs.print_page_numbers);
683 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pageheader");
684 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), printing_prefs.print_page_header);
685 on_prefs_print_page_header_toggled(GTK_TOGGLE_BUTTON(widget), NULL);
687 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_basename");
688 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), printing_prefs.page_header_basename);
690 if (printing_prefs.page_header_datefmt)
691 gtk_entry_set_text(
692 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_dateformat")),
693 printing_prefs.page_header_datefmt);
696 #ifndef HAVE_PLUGINS
697 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_plugins"), FALSE);
698 #endif
699 on_enable_plugins_toggled(GTK_TOGGLE_BUTTON( ui_lookup_widget(ui_widgets.prefs_dialog, "check_plugins")), NULL);
701 #ifdef HAVE_VTE
702 /* make VTE switch visible only when VTE is compiled in, it is hidden by default */
703 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_vte");
704 gtk_widget_show(widget);
705 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vte_info.load_vte);
707 /* VTE settings */
708 if (vte_info.have_vte)
710 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "font_term");
711 gtk_font_button_set_font_name(GTK_FONT_BUTTON(widget), vc->font);
713 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "color_fore");
714 gtk_color_button_set_color(GTK_COLOR_BUTTON(widget), vc->colour_fore);
716 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "color_back");
717 gtk_color_button_set_color(GTK_COLOR_BUTTON(widget), vc->colour_back);
719 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_scrollback");
720 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), vc->scrollback_lines);
722 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_shell");
723 gtk_entry_set_text(GTK_ENTRY(widget), vc->shell);
725 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_key");
726 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->scroll_on_key);
728 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_out");
729 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->scroll_on_out);
731 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_enable_bash_keys");
732 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->enable_bash_keys);
734 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ignore_menu_key");
735 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->ignore_menu_bar_accel);
737 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_follow_path");
738 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->follow_path);
740 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_run_in_vte");
741 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->run_in_vte);
743 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_skip_script");
744 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->skip_run_script);
746 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_cursor_blinks");
747 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), vc->cursor_blinks);
749 #endif
754 * callbacks
756 /* note: new prefs should use Stash code in keyfile.c */
757 static void
758 on_prefs_button_clicked(GtkDialog *dialog, gint response, gpointer user_data)
760 if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY)
762 GtkWidget *widget;
763 guint i;
764 guint autoclose_brackets[5];
765 gboolean old_invert_all = interface_prefs.highlighting_invert_all;
766 gboolean old_sidebar_pos = interface_prefs.sidebar_pos;
768 /* Synchronize Stash settings */
769 prefs_action(PREF_UPDATE);
771 if (interface_prefs.highlighting_invert_all != old_invert_all)
772 filetypes_reload();
774 if (interface_prefs.sidebar_pos != old_sidebar_pos)
775 ui_swap_sidebar_pos();
777 /* General settings */
778 /* startup */
779 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_load_session");
780 prefs.load_session = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
782 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_project_session");
783 project_prefs.project_session = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
785 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_project_file_in_basedir");
786 project_prefs.project_file_in_basedir = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
788 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_save_win_pos");
789 prefs.save_winpos = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
791 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ask_for_quit");
792 prefs.confirm_exit = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
794 /* behaviour */
795 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_beep");
796 prefs.beep_on_errors = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
798 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_switch_pages");
799 prefs.switch_to_status = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
801 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_suppress_status_msgs");
802 prefs.suppress_status_messages = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
804 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_auto_focus");
805 prefs.auto_focus = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
807 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_native_windows_dialogs");
808 interface_prefs.use_native_windows_dialogs =
809 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
811 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_contextaction");
812 g_free(tool_prefs.context_action_cmd);
813 tool_prefs.context_action_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
815 project_apply_prefs(); /* project file path */
818 /* Interface settings */
819 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_sidebar_visible");
820 ui_prefs.sidebar_visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
822 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_symbol");
823 interface_prefs.sidebar_symbol_visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
825 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_openfiles");
826 interface_prefs.sidebar_openfiles_visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
828 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_long_line");
829 editor_prefs.long_line_global_enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
831 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_long_line_line");
832 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
833 editor_prefs.long_line_global_type = 0;
834 else
835 /* now only the "background" radio remains */
836 editor_prefs.long_line_global_type = 1;
838 if (editor_prefs.long_line_global_column == 0)
839 editor_prefs.long_line_global_enabled = FALSE;
841 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_notebook_tabs");
842 interface_prefs.show_notebook_tabs = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
844 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_tab_cross");
845 file_prefs.show_tab_cross = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
847 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_editor");
848 interface_prefs.tab_pos_editor = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
850 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_msgwin");
851 interface_prefs.tab_pos_msgwin = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
853 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_sidebar");
854 interface_prefs.tab_pos_sidebar = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
856 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_statusbar_visible");
857 interface_prefs.statusbar_visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
860 /* Toolbar settings */
861 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_show");
862 toolbar_prefs.visible = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
863 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_in_menu");
864 toolbar_prefs.append_to_menu = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
866 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_style_default");
867 toolbar_prefs.use_gtk_default_style = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
868 if (! toolbar_prefs.use_gtk_default_style)
870 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_imagetext");
871 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
872 toolbar_prefs.icon_style = 2;
873 else
875 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_image");
876 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
877 toolbar_prefs.icon_style = 0;
878 else
879 /* now only the text only radio remains, so set text only */
880 toolbar_prefs.icon_style = 1;
884 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_icon_default");
885 toolbar_prefs.use_gtk_default_icon = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
886 if (! toolbar_prefs.use_gtk_default_icon)
887 { toolbar_prefs.icon_size = GTK_ICON_SIZE_LARGE_TOOLBAR;
888 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_large");
889 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
890 toolbar_prefs.icon_size = GTK_ICON_SIZE_LARGE_TOOLBAR;
891 else
893 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_toolbar_small");
894 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
895 toolbar_prefs.icon_size = GTK_ICON_SIZE_SMALL_TOOLBAR;
896 else
897 toolbar_prefs.icon_size = GTK_ICON_SIZE_MENU;
901 /* Files settings */
902 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_tab_right");
903 file_prefs.tab_order_ltr = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
905 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_tab_beside");
906 file_prefs.tab_order_beside = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
908 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_new_encoding");
909 file_prefs.default_new_encoding = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
911 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_open_encoding");
912 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
914 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_open_encoding");
915 file_prefs.default_open_encoding = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
917 else
918 file_prefs.default_open_encoding = -1;
920 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_eol");
921 file_prefs.default_eol_character = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
923 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_trailing_spaces");
924 file_prefs.strip_trailing_spaces = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
926 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_new_line");
927 file_prefs.final_new_line = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
929 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_replace_tabs");
930 file_prefs.replace_tabs = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
933 /* Editor settings */
934 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_toggle_mark");
935 setptr(editor_prefs.comment_toggle_mark,
936 gtk_editable_get_chars(GTK_EDITABLE(widget), 0, -1));
938 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_long_line");
939 /* note: use stash for new code - it updates spin buttons itself */
940 gtk_spin_button_update(GTK_SPIN_BUTTON(widget));
941 editor_prefs.long_line_global_column = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
943 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_folding");
944 editor_prefs.folding = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
945 ui_update_fold_items();
947 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_unfold_children");
948 editor_prefs.unfold_all_children = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
950 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_indent");
951 editor_prefs.show_indent_guide = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
953 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_white_space");
954 editor_prefs.show_white_space = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
956 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_end");
957 editor_prefs.show_line_endings = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
959 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_numbers");
960 editor_prefs.show_linenumber_margin = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
962 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_markers_margin");
963 editor_prefs.show_markers_margin = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
965 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_stop_at_last_line");
966 editor_prefs.scroll_stop_at_last_line = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
968 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_line_wrapping");
969 editor_prefs.line_wrapping = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
971 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_complete_snippets");
972 editor_prefs.complete_snippets = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
974 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_xmltag");
975 editor_prefs.auto_close_xml_tags = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
977 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_indicators");
978 editor_prefs.use_indicators = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
980 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_disable_dnd");
981 editor_prefs.disable_dnd = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
983 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_smart_home");
984 editor_prefs.smart_home_key = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
986 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_newline_strip");
987 editor_prefs.newline_strip = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
989 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_auto_multiline");
990 editor_prefs.auto_continue_multiline = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
992 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_symbol_auto_completion");
993 editor_prefs.auto_complete_symbols = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
995 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_symbol_complete_chars");
996 gtk_spin_button_update(GTK_SPIN_BUTTON(widget));
997 editor_prefs.symbolcompletion_min_chars = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
999 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_symbollistheight");
1000 gtk_spin_button_update(GTK_SPIN_BUTTON(widget));
1001 editor_prefs.symbolcompletion_max_height = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
1003 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_line_break");
1004 gtk_spin_button_update(GTK_SPIN_BUTTON(widget));
1005 editor_prefs.line_break_column = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
1007 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_parenthesis");
1008 autoclose_brackets[0] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1010 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_cbracket");
1011 autoclose_brackets[1] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1013 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_sbracket");
1014 autoclose_brackets[2] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1016 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_squote");
1017 autoclose_brackets[3] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1019 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_autoclose_dquote");
1020 autoclose_brackets[4] = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1022 editor_prefs.autoclose_chars =
1023 (autoclose_brackets[0] ? GEANY_AC_PARENTHESIS : 0)
1024 | (autoclose_brackets[1] ? GEANY_AC_CBRACKET : 0)
1025 | (autoclose_brackets[2] ? GEANY_AC_SBRACKET : 0)
1026 | (autoclose_brackets[3] ? GEANY_AC_SQUOTE : 0)
1027 | (autoclose_brackets[4] ? GEANY_AC_DQUOTE : 0);
1029 /* Tools Settings */
1031 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_term");
1032 g_free(tool_prefs.term_cmd);
1033 tool_prefs.term_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1035 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_browser");
1036 g_free(tool_prefs.browser_cmd);
1037 tool_prefs.browser_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1039 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_grep");
1040 g_free(tool_prefs.grep_cmd);
1041 tool_prefs.grep_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1044 /* Template settings */
1045 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_developer");
1046 g_free(template_prefs.developer);
1047 template_prefs.developer = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1049 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_company");
1050 g_free(template_prefs.company);
1051 template_prefs.company = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1053 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_mail");
1054 g_free(template_prefs.mail);
1055 template_prefs.mail = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1057 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_initial");
1058 g_free(template_prefs.initials);
1059 template_prefs.initials = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1061 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_version");
1062 g_free(template_prefs.version);
1063 template_prefs.version = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1065 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_year");
1066 g_free(template_prefs.year_format);
1067 template_prefs.year_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1069 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_date");
1070 g_free(template_prefs.date_format);
1071 template_prefs.date_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1073 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_template_datetime");
1074 g_free(template_prefs.datetime_format);
1075 template_prefs.datetime_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1078 /* Keybindings */
1079 if (edited)
1080 keybindings_write_to_file();
1083 /* Printing */
1084 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "radio_print_gtk");
1085 printing_prefs.use_gtk_printing = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1087 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_external_cmd");
1088 g_free(printing_prefs.external_print_cmd);
1089 printing_prefs.external_print_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1091 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_linenumbers");
1092 printing_prefs.print_line_numbers = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1094 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pagenumbers");
1095 printing_prefs.print_page_numbers = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1097 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pageheader");
1098 printing_prefs.print_page_header = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1100 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_basename");
1101 printing_prefs.page_header_basename = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1103 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_dateformat");
1104 g_free(printing_prefs.page_header_datefmt);
1105 printing_prefs.page_header_datefmt = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1108 #ifdef HAVE_VTE
1109 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_vte");
1110 vte_info.load_vte = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1112 /* VTE settings */
1113 if (vte_info.have_vte)
1115 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "spin_scrollback");
1116 gtk_spin_button_update(GTK_SPIN_BUTTON(widget));
1117 vc->scrollback_lines = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
1119 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "entry_shell");
1120 g_free(vc->shell);
1121 vc->shell = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
1123 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_key");
1124 vc->scroll_on_key = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1126 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_scroll_out");
1127 vc->scroll_on_out = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1129 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_enable_bash_keys");
1130 vc->enable_bash_keys = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1132 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_ignore_menu_key");
1133 vc->ignore_menu_bar_accel = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1135 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_follow_path");
1136 vc->follow_path = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1138 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_run_in_vte");
1139 vc->run_in_vte = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1141 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_skip_script");
1142 vc->skip_run_script = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1144 widget = ui_lookup_widget(ui_widgets.prefs_dialog, "check_cursor_blinks");
1145 vc->cursor_blinks = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
1147 vte_apply_user_settings();
1149 #endif
1151 /* apply the changes made */
1152 ui_statusbar_showhide(interface_prefs.statusbar_visible);
1153 sidebar_openfiles_update_all(); /* to update if full path setting has changed */
1154 toolbar_apply_settings();
1155 toolbar_update_ui();
1156 toolbar_show_hide();
1157 ui_sidebar_show_hide();
1158 gtk_notebook_set_show_tabs(GTK_NOTEBOOK(main_widgets.notebook), interface_prefs.show_notebook_tabs);
1160 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(main_widgets.notebook), interface_prefs.tab_pos_editor);
1161 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(msgwindow.notebook), interface_prefs.tab_pos_msgwin);
1162 gtk_notebook_set_tab_pos(GTK_NOTEBOOK(main_widgets.sidebar_notebook), interface_prefs.tab_pos_sidebar);
1164 /* re-colourise all open documents, if tab width or long line settings have changed */
1165 for (i = 0; i < documents_array->len; i++)
1167 if (documents[i]->is_valid)
1169 editor_apply_update_prefs(documents[i]->editor);
1170 if (! editor_prefs.folding)
1171 editor_unfold_all(documents[i]->editor);
1174 ui_document_show_hide(NULL);
1175 ui_update_view_editor_menu_items();
1177 /* store all settings */
1178 configuration_save();
1181 if (response != GTK_RESPONSE_APPLY)
1183 gtk_tree_store_clear(store);
1184 gtk_widget_hide(GTK_WIDGET(dialog));
1189 static void on_color_button_choose_cb(GtkColorButton *widget, gpointer user_data)
1191 GdkColor color;
1193 gtk_color_button_get_color(widget, &color);
1194 setptr(editor_prefs.long_line_color, utils_get_hex_from_color(&color));
1198 static void on_prefs_font_choosed(GtkFontButton *widget, gpointer user_data)
1200 const gchar *fontbtn = gtk_font_button_get_font_name(widget);
1201 guint i;
1203 switch (GPOINTER_TO_INT(user_data))
1205 case 1:
1207 if (strcmp(fontbtn, interface_prefs.tagbar_font) == 0)
1208 break;
1210 setptr(interface_prefs.tagbar_font, g_strdup(fontbtn));
1211 for (i = 0; i < documents_array->len; i++)
1213 GeanyDocument *doc = documents[i];
1215 if (documents[i]->is_valid && GTK_IS_WIDGET(doc->priv->tag_tree))
1216 ui_widget_modify_font_from_string(doc->priv->tag_tree,
1217 interface_prefs.tagbar_font);
1219 if (GTK_IS_WIDGET(tv.default_tag_tree))
1220 ui_widget_modify_font_from_string(tv.default_tag_tree, interface_prefs.tagbar_font);
1221 ui_widget_modify_font_from_string(tv.tree_openfiles, interface_prefs.tagbar_font);
1222 break;
1224 case 2:
1226 if (strcmp(fontbtn, interface_prefs.msgwin_font) == 0)
1227 break;
1228 setptr(interface_prefs.msgwin_font, g_strdup(fontbtn));
1229 ui_widget_modify_font_from_string(msgwindow.tree_compiler, interface_prefs.msgwin_font);
1230 ui_widget_modify_font_from_string(msgwindow.tree_msg, interface_prefs.msgwin_font);
1231 ui_widget_modify_font_from_string(msgwindow.tree_status, interface_prefs.msgwin_font);
1232 ui_widget_modify_font_from_string(msgwindow.scribble, interface_prefs.msgwin_font);
1233 break;
1235 case 3:
1237 ui_set_editor_font(fontbtn);
1238 break;
1244 static GeanyKeyBinding *kb_lookup_kb_from_iter(G_GNUC_UNUSED GtkTreeModel *model, GtkTreeIter *iter)
1246 guint group_idx, keybinding_idx;
1247 GtkTreeIter parent;
1249 /* get kb index */
1250 gtk_tree_model_get(GTK_TREE_MODEL(store), iter, KB_TREE_INDEX, &keybinding_idx, -1);
1252 /* lookup the parent to get group index */
1253 gtk_tree_model_iter_parent(GTK_TREE_MODEL(store), &parent, iter);
1254 gtk_tree_model_get(GTK_TREE_MODEL(store), &parent, KB_TREE_INDEX, &group_idx, -1);
1256 return keybindings_lookup_item(group_idx, keybinding_idx);
1260 static void kb_cell_edited_cb(GtkCellRendererText *cellrenderertext, gchar *path, gchar *new_text, gpointer user_data)
1262 if (path != NULL && new_text != NULL)
1264 GtkTreeIter iter;
1265 guint lkey;
1266 GdkModifierType lmods;
1267 GeanyKeyBinding *kb;
1269 gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store), &iter, path);
1270 if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(store), &iter))
1271 return; /* ignore group items */
1273 gtk_accelerator_parse(new_text, &lkey, &lmods);
1275 kb = kb_lookup_kb_from_iter(GTK_TREE_MODEL(store), &iter);
1277 if (kb_find_duplicate(ui_widgets.prefs_dialog, kb, lkey, lmods, new_text))
1278 return;
1280 /* set the values here, because of the above check, setting it in
1281 * gtk_accelerator_parse would return a wrong key combination if it is duplicate */
1282 keybindings_update_combo(kb, lkey, lmods);
1284 gtk_tree_store_set(store, &iter, KB_TREE_SHORTCUT, new_text, -1);
1286 edited = TRUE;
1291 static gboolean kb_keytype_dialog_response_cb(GtkWidget *dialog, GdkEventKey *event, gpointer user_data)
1293 gchar *str;
1294 gint state;
1296 state = event->state & gtk_accelerator_get_default_mod_mask();
1298 if (event->keyval == GDK_Escape)
1299 return FALSE; /* close the dialog, don't allow escape when detecting keybindings. */
1301 str = gtk_accelerator_name(event->keyval, state);
1303 gtk_label_set_text(GTK_LABEL(dialog_label), str);
1304 g_free(str);
1306 return TRUE;
1310 static void kb_dialog_response_cb(GtkWidget *dialog, gint response, G_GNUC_UNUSED gpointer iter)
1312 if (response == GTK_RESPONSE_ACCEPT)
1314 guint lkey;
1315 GdkModifierType lmods;
1316 GeanyKeyBinding *kb;
1318 kb = kb_lookup_kb_from_iter(GTK_TREE_MODEL(store), &g_iter);
1320 gtk_accelerator_parse(gtk_label_get_text(GTK_LABEL(dialog_label)), &lkey, &lmods);
1322 if (kb_find_duplicate(dialog, kb, lkey, lmods, gtk_label_get_text(GTK_LABEL(dialog_label))))
1323 return;
1325 /* set the values here, because of the above check, setting it in
1326 * gtk_accelerator_parse would return a wrong key combination if it is duplicate */
1327 keybindings_update_combo(kb, lkey, lmods);
1329 gtk_tree_store_set(store, &g_iter,
1330 KB_TREE_SHORTCUT, gtk_label_get_text(GTK_LABEL(dialog_label)), -1);
1332 g_free(dialog_key_name);
1333 dialog_key_name = NULL;
1335 edited = TRUE;
1337 gtk_widget_destroy(dialog);
1341 /* Look for a (1st-level) child of parent whose KB_TREE_INDEX matches i,
1342 * setting iter to point to the node if found.
1343 * If parent is NULL, look for a parent node whose KB_TREE_INDEX matches i. */
1344 static gboolean kb_find_child_iter(GtkTreeIter *parent, guint i, GtkTreeIter *iter)
1346 GtkTreeModel *model = GTK_TREE_MODEL(store);
1347 guint idx;
1349 /* get first child of parent */
1350 if (! gtk_tree_model_iter_children(model, iter, parent))
1351 return FALSE;
1353 while (TRUE) /* foreach child */
1355 gtk_tree_model_get(model, iter, KB_TREE_INDEX, &idx, -1);
1356 if (idx == i)
1357 return TRUE;
1358 if (! gtk_tree_model_iter_next(model, iter))
1359 return FALSE; /* no more children */
1364 static void kb_clear_tree_shortcut(gsize group_id, gsize keybinding_id)
1366 GtkTreeIter parent;
1367 GtkTreeIter child;
1369 /* find parent kb group */
1370 if (! kb_find_child_iter(NULL, group_id, &parent))
1371 return;
1373 /* find child kb node*/
1374 if (! kb_find_child_iter(&parent, keybinding_id, &child))
1375 return;
1377 gtk_tree_store_set(store, &child, KB_TREE_SHORTCUT, NULL, -1); /* clear shortcut */
1381 /* test if the entered key combination is already used
1382 * returns true if cancelling duplicate */
1383 static gboolean kb_find_duplicate(GtkWidget *parent, GeanyKeyBinding *search_kb,
1384 guint key, GdkModifierType mods, const gchar *action)
1386 gsize g, i;
1388 /* allow duplicate if there is no key combination */
1389 if (key == 0 && mods == 0)
1390 return FALSE;
1392 for (g = 0; g < keybinding_groups->len; g++)
1394 GeanyKeyGroup *group = g_ptr_array_index(keybinding_groups, g);
1396 for (i = 0; i < group->count; i++)
1398 GeanyKeyBinding *keys = group->keys;
1399 GeanyKeyBinding *kb = &keys[i];
1401 /* search another item with the same key,
1402 * but don't search the key we're looking for keys[idx] */
1403 if (kb->key == key && kb->mods == mods
1404 && ! (kb->key == search_kb->key && kb->mods == search_kb->mods))
1406 gchar *label = keybindings_get_label(kb);
1407 gint ret = dialogs_show_prompt(parent,
1408 _("_Allow"), GTK_RESPONSE_APPLY,
1409 GTK_STOCK_CANCEL, GTK_RESPONSE_NO,
1410 _("_Override"), GTK_RESPONSE_YES,
1411 _("Override that keybinding?"),
1412 _("The combination '%s' is already used for \"%s\"."),
1413 action, label);
1415 g_free(label);
1417 if (ret == GTK_RESPONSE_YES)
1419 keybindings_update_combo(kb, 0, 0);
1420 kb_clear_tree_shortcut(g, i);
1421 /* carry on looking for other duplicates if overriding */
1422 continue;
1424 return ret == GTK_RESPONSE_NO;
1428 return FALSE;
1432 static void on_toolbar_show_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1434 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1436 gtk_widget_set_sensitive(
1437 ui_lookup_widget(ui_widgets.prefs_dialog, "frame_toolbar_style"), sens);
1438 gtk_widget_set_sensitive(
1439 ui_lookup_widget(ui_widgets.prefs_dialog, "frame_toolbar_icon"), sens);
1440 gtk_widget_set_sensitive(
1441 ui_lookup_widget(ui_widgets.prefs_dialog, "button_customize_toolbar"), sens);
1442 gtk_widget_set_sensitive(
1443 ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_in_menu"), sens);
1447 static void on_show_notebook_tabs_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1449 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1451 /* tab placement only enabled when tabs are visible */
1452 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "combo_tab_editor"), sens);
1453 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_tab_cross"), sens);
1457 static void on_use_folding_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1459 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1461 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_unfold_children"), sens);
1465 static void on_enable_plugins_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1467 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1469 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "extra_plugin_path_entry"), sens);
1470 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "extra_plugin_path_button"), sens);
1474 static void on_open_encoding_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1476 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1478 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "eventbox3"), sens);
1479 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "label_open_encoding"), sens);
1483 static void on_sidebar_visible_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1485 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1487 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_openfiles"), sens);
1488 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_list_symbol"), sens);
1492 static void on_prefs_print_radio_button_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1494 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1496 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox29"), sens);
1497 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "hbox9"), ! sens);
1501 static void on_prefs_print_page_header_toggled(GtkToggleButton *togglebutton, gpointer user_data)
1503 gboolean sens = gtk_toggle_button_get_active(togglebutton);
1505 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_basename"), sens);
1506 gtk_widget_set_sensitive(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_dateformat"), sens);
1510 static void open_preferences_help(void)
1512 gchar *uri;
1513 const gchar *label, *suffix = NULL;
1514 GtkNotebook *notebook = GTK_NOTEBOOK(
1515 ui_lookup_widget(ui_widgets.prefs_dialog, "notebook2"));
1516 gint page_nr = gtk_notebook_get_current_page(notebook);
1517 GtkWidget *page = gtk_notebook_get_nth_page(notebook, page_nr);
1519 label = gtk_notebook_get_tab_label_text(notebook, page);
1521 /* TODO Find a better way to map the current notebook page to the
1522 * corresponding chapter in the documentation, comparing translatable
1523 * strings is easy to break. Maybe attach an identifying string to the
1524 * tab label object. */
1525 if (utils_str_equal(label, _("General")))
1526 suffix = "#general-startup-preferences";
1527 else if (utils_str_equal(label, _("Interface")))
1528 suffix = "#interface-preferences";
1529 else if (utils_str_equal(label, _("Toolbar")))
1530 suffix = "#toolbar-preferences";
1531 else if (utils_str_equal(label, _("Editor")))
1532 suffix = "#editor-features-preferences";
1533 else if (utils_str_equal(label, _("Files")))
1534 suffix = "#files-preferences";
1535 else if (utils_str_equal(label, _("Tools")))
1536 suffix = "#tools-preferences";
1537 else if (utils_str_equal(label, _("Templates")))
1538 suffix = "#template-preferences";
1539 else if (utils_str_equal(label, _("Keybindings")))
1540 suffix = "#keybinding-preferences";
1541 else if (utils_str_equal(label, _("Printing")))
1542 suffix = "#printing-preferences";
1543 else if (utils_str_equal(label, _("Terminal")))
1544 suffix = "#terminal-vte-preferences";
1546 uri = utils_get_help_url(suffix);
1547 utils_open_browser(uri);
1548 g_free(uri);
1552 static gboolean prefs_dialog_key_press_response_cb(GtkWidget *dialog, GdkEventKey *event,
1553 gpointer data)
1555 gint group, keybinding;
1557 if (keybindings_check_event(event, &group, &keybinding) != NULL)
1559 if (group == GEANY_KEY_GROUP_HELP && keybinding == GEANY_KEYS_HELP_HELP)
1561 open_preferences_help();
1562 return TRUE;
1565 return FALSE;
1569 static gboolean prefs_dialog_button_press_event_cb(GtkWidget *dialog, GdkEventButton *event,
1570 gpointer data)
1572 if (event->button == 1)
1574 open_preferences_help();
1575 return TRUE;
1577 return FALSE;
1581 void prefs_show_dialog(void)
1583 if (ui_widgets.prefs_dialog == NULL)
1585 GtkWidget *combo_new, *combo_open, *combo_eol;
1586 GtkWidget *label;
1587 guint i;
1588 gchar *encoding_string;
1589 GdkPixbuf *pb;
1591 ui_widgets.prefs_dialog = create_prefs_dialog();
1592 gtk_widget_set_name(ui_widgets.prefs_dialog, "GeanyPrefsDialog");
1593 gtk_window_set_transient_for(GTK_WINDOW(ui_widgets.prefs_dialog), GTK_WINDOW(main_widgets.window));
1594 pb = ui_new_pixbuf_from_inline(GEANY_IMAGE_LOGO);
1595 gtk_window_set_icon(GTK_WINDOW(ui_widgets.prefs_dialog), pb);
1596 g_object_unref(pb); /* free our reference */
1598 /* init the default file encoding combo box */
1599 combo_new = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_new_encoding");
1600 combo_open = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_open_encoding");
1601 gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(combo_new), 3);
1602 gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(combo_open), 3);
1603 for (i = 0; i < GEANY_ENCODINGS_MAX; i++)
1605 encoding_string = encodings_to_string(&encodings[i]);
1606 gtk_combo_box_append_text(GTK_COMBO_BOX(combo_new), encoding_string);
1607 gtk_combo_box_append_text(GTK_COMBO_BOX(combo_open), encoding_string);
1608 g_free(encoding_string);
1611 /* init the eol character combo box */
1612 combo_eol = ui_lookup_widget(ui_widgets.prefs_dialog, "combo_eol");
1613 gtk_combo_box_append_text(GTK_COMBO_BOX(combo_eol), utils_get_eol_name(SC_EOL_CRLF));
1614 gtk_combo_box_append_text(GTK_COMBO_BOX(combo_eol), utils_get_eol_name(SC_EOL_CR));
1615 gtk_combo_box_append_text(GTK_COMBO_BOX(combo_eol), utils_get_eol_name(SC_EOL_LF));
1617 /* add manually GeanyWrapLabels because they can't be added with Glade */
1618 /* page Tools */
1619 label = geany_wrap_label_new(_("Enter tool paths below. Tools you do not need can be left blank."));
1620 gtk_widget_show(label);
1621 gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox33")),
1622 label, FALSE, TRUE, 5);
1623 /* page Templates */
1624 label = geany_wrap_label_new(_("Set the information to be used in templates. See the documentation for details."));
1625 gtk_widget_show(label);
1626 gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox31")),
1627 label, FALSE, TRUE, 5);
1628 label = geany_wrap_label_new(_("<i>Notice: For all changes you make here to take effect, you need to restart Geany or force the reload of the settings using Tools->Reload Configuration.</i>"));
1629 gtk_widget_show(label);
1630 gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
1631 gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox9")),
1632 label, FALSE, TRUE, 5);
1633 /* page Keybindings */
1634 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."));
1635 gtk_widget_show(label);
1636 gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox32")),
1637 label, FALSE, TRUE, 5);
1638 /* page Printing */
1639 label = geany_wrap_label_new(_("<i>Notice: Native GTK printing is only available if Geany was built against GTK 2.10 (or above) <b>and</b> Geany is running with GTK 2.10 (or above).</i>"));
1640 gtk_widget_show(label);
1641 gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
1642 gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog, "vbox27")),
1643 label, FALSE, TRUE, 5);
1644 /* page Editor->Indentation */
1645 label = geany_wrap_label_new(_("<i>Warning: these settings are overridden by the current project. See <b>Project->Properties</b>.</i>"));
1646 gtk_widget_show(label);
1647 gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
1648 gtk_misc_set_padding(GTK_MISC(label), 6, 0);
1649 gtk_box_pack_start(GTK_BOX(ui_lookup_widget(ui_widgets.prefs_dialog,
1650 "label_project_indent_warning")), label, FALSE, TRUE, 5);
1652 /* add the clear icon to GtkEntry widgets in the dialog */
1654 const gchar *names[] = {
1655 "startup_path_entry",
1656 "project_file_path_entry",
1657 "extra_plugin_path_entry",
1658 "entry_toggle_mark",
1659 /* "entry_com_make", */
1660 "entry_com_term",
1661 "entry_browser",
1662 "entry_grep",
1663 "entry_contextaction",
1664 "entry_template_developer",
1665 "entry_template_initial",
1666 "entry_template_mail",
1667 "entry_template_company",
1668 "entry_template_version",
1669 "entry_template_year",
1670 "entry_template_date",
1671 "entry_template_datetime",
1672 "entry_print_external_cmd",
1673 "entry_print_dateformat"};
1674 const gchar **name;
1676 foreach_c_array(name, names, G_N_ELEMENTS(names))
1677 ui_entry_add_clear_icon(GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, *name)));
1680 #ifdef HAVE_VTE
1681 vte_append_preferences_tab();
1682 #endif
1684 #ifndef G_OS_WIN32
1685 gtk_widget_hide(ui_lookup_widget(ui_widgets.prefs_dialog, "check_native_windows_dialogs"));
1686 #endif
1687 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "startup_path_button"), NULL,
1688 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "startup_path_entry")));
1689 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "extra_plugin_path_button"), NULL,
1690 GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "extra_plugin_path_entry")));
1692 g_signal_connect(ui_widgets.prefs_dialog, "response",
1693 G_CALLBACK(on_prefs_button_clicked), NULL);
1694 g_signal_connect(ui_widgets.prefs_dialog, "delete-event",
1695 G_CALLBACK(gtk_widget_hide_on_delete), NULL);
1697 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "tagbar_font"),
1698 "font-set", G_CALLBACK(on_prefs_font_choosed), GINT_TO_POINTER(1));
1699 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "msgwin_font"),
1700 "font-set", G_CALLBACK(on_prefs_font_choosed), GINT_TO_POINTER(2));
1701 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "editor_font"),
1702 "font-set", G_CALLBACK(on_prefs_font_choosed), GINT_TO_POINTER(3));
1703 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "long_line_color"),
1704 "color-set", G_CALLBACK(on_color_button_choose_cb), NULL);
1705 /* file chooser buttons in the tools tab */
1706 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_term"),
1707 NULL,
1708 GTK_FILE_CHOOSER_ACTION_OPEN,
1709 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_com_term")));
1710 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_browser"),
1711 NULL,
1712 GTK_FILE_CHOOSER_ACTION_OPEN,
1713 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_browser")));
1714 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_grep"),
1715 NULL,
1716 GTK_FILE_CHOOSER_ACTION_OPEN,
1717 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_grep")));
1719 /* tools commands */
1720 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_contextaction"),
1721 NULL,
1722 GTK_FILE_CHOOSER_ACTION_OPEN,
1723 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_contextaction")));
1725 /* printing */
1726 ui_setup_open_button_callback(ui_lookup_widget(ui_widgets.prefs_dialog, "button_print_external_cmd"),
1727 NULL,
1728 GTK_FILE_CHOOSER_ACTION_OPEN,
1729 GTK_ENTRY(ui_lookup_widget(ui_widgets.prefs_dialog, "entry_print_external_cmd")));
1731 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "radio_print_gtk"),
1732 "toggled", G_CALLBACK(on_prefs_print_radio_button_toggled), NULL);
1733 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_print_pageheader"),
1734 "toggled", G_CALLBACK(on_prefs_print_page_header_toggled), NULL);
1736 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_plugins"),
1737 "toggled", G_CALLBACK(on_enable_plugins_toggled), NULL);
1738 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_toolbar_show"),
1739 "toggled", G_CALLBACK(on_toolbar_show_toggled), NULL);
1740 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_show_notebook_tabs"),
1741 "toggled", G_CALLBACK(on_show_notebook_tabs_toggled), NULL);
1742 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_folding"),
1743 "toggled", G_CALLBACK(on_use_folding_toggled), NULL);
1744 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_open_encoding"),
1745 "toggled", G_CALLBACK(on_open_encoding_toggled), NULL);
1746 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "check_sidebar_visible"),
1747 "toggled", G_CALLBACK(on_sidebar_visible_toggled), NULL);
1749 g_signal_connect(ui_lookup_widget(ui_widgets.prefs_dialog, "button_help"),
1750 "button-press-event", G_CALLBACK(prefs_dialog_button_press_event_cb), NULL);
1751 g_signal_connect(ui_widgets.prefs_dialog,
1752 "key-press-event", G_CALLBACK(prefs_dialog_key_press_response_cb), NULL);
1755 prefs_init_dialog();
1756 gtk_window_present(GTK_WINDOW(ui_widgets.prefs_dialog));