1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * gedit-preferences-dialog.c
4 * This file is part of gedit
5 *
6 * Copyright (C) 2001-2005 Paolo Maggi
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "config.h"
23
24 #include "gedit-preferences-dialog.h"
25
26 #include <glib/gi18n.h>
27 #include <glib/gstdio.h>
28 #include <tepl/tepl.h>
29 #include <libpeas-gtk/peas-gtk.h>
30
31 #include "gedit-debug.h"
32 #include "gedit-dirs.h"
33 #include "gedit-settings.h"
34
35 /*
36 * gedit-preferences dialog is a singleton since we don't
37 * want two dialogs showing an inconsistent state of the
38 * preferences.
39 * When gedit_show_preferences_dialog is called and there
40 * is already a prefs dialog dialog open, it is reparented
41 * and shown.
42 */
43
44 static GtkWidget *preferences_dialog = NULL;
45
46 #define GEDIT_SCHEME_ROW_ID_KEY "gedit-scheme-row-id"
47
48 #define GEDIT_TYPE_PREFERENCES_DIALOG (gedit_preferences_dialog_get_type())
49
50 G_DECLARE_FINAL_TYPE (GeditPreferencesDialog, gedit_preferences_dialog, GEDIT, PREFERENCES_DIALOG, GtkWindow)
51
52 enum
53 {
54 ID_COLUMN = 0,
55 NAME_COLUMN,
56 DESC_COLUMN,
57 NUM_COLUMNS
58 };
59
60 enum
61 {
62 CLOSE,
63 LAST_SIGNAL
64 };
65
66 static guint signals[LAST_SIGNAL];
67
68 struct _GeditPreferencesDialog
69 {
70 GtkWindow parent_instance;
71
72 GSettings *editor;
73 GSettings *uisettings; /* unfortunately our settings are split for historical reasons */
74
75 GtkWidget *notebook;
76
77 /* Font */
78 GtkWidget *default_font_checkbutton;
79 GtkWidget *font_button;
80 GtkWidget *font_grid;
81
82 /* Style Scheme */
83 GtkWidget *schemes_list;
84 GtkWidget *install_scheme_button;
85 GtkWidget *uninstall_scheme_button;
86 GtkWidget *schemes_toolbar;
87 GtkFileChooserNative *
88 install_scheme_file_chooser;
89
90 /* Tabs */
91 GtkWidget *tabs_width_spinbutton;
92 GtkWidget *insert_spaces_checkbutton;
93
94 /* Auto indentation */
95 GtkWidget *auto_indent_checkbutton;
96
97 /* Text Wrapping */
98 GtkWidget *wrap_text_checkbutton;
99 GtkWidget *split_checkbutton;
100
101 /* File Saving */
102 GtkWidget *backup_copy_checkbutton;
103 GtkWidget *auto_save_checkbutton;
104 GtkWidget *auto_save_spinbutton;
105
106 GtkWidget *display_line_numbers_checkbutton;
107 GtkWidget *display_statusbar_checkbutton;
108 GtkWidget *display_grid_checkbutton;
109
110 /* Right margin */
111 GtkWidget *right_margin_checkbutton;
112 GtkWidget *right_margin_position_grid;
113 GtkWidget *right_margin_position_spinbutton;
114
115 /* Highlighting */
116 GtkWidget *highlight_current_line_checkbutton;
117 GtkWidget *bracket_matching_checkbutton;
118
119 /* Plugin manager */
120 GtkWidget *plugin_manager;
121 };
122
G_DEFINE_TYPE(GeditPreferencesDialog,gedit_preferences_dialog,GTK_TYPE_WINDOW)123 G_DEFINE_TYPE (GeditPreferencesDialog, gedit_preferences_dialog, GTK_TYPE_WINDOW)
124
125 static void
126 gedit_preferences_dialog_dispose (GObject *object)
127 {
128 GeditPreferencesDialog *dlg = GEDIT_PREFERENCES_DIALOG (object);
129
130 g_clear_object (&dlg->editor);
131 g_clear_object (&dlg->uisettings);
132
133 G_OBJECT_CLASS (gedit_preferences_dialog_parent_class)->dispose (object);
134 }
135
136 static void
gedit_preferences_dialog_close(GeditPreferencesDialog * dialog)137 gedit_preferences_dialog_close (GeditPreferencesDialog *dialog)
138 {
139 gtk_window_close (GTK_WINDOW (dialog));
140 }
141
142 static void
gedit_preferences_dialog_class_init(GeditPreferencesDialogClass * klass)143 gedit_preferences_dialog_class_init (GeditPreferencesDialogClass *klass)
144 {
145 GObjectClass *object_class = G_OBJECT_CLASS (klass);
146 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
147 GtkBindingSet *binding_set;
148
149 /* Otherwise libpeas-gtk might not be linked */
150 g_type_ensure (PEAS_GTK_TYPE_PLUGIN_MANAGER);
151
152 object_class->dispose = gedit_preferences_dialog_dispose;
153
154 signals[CLOSE] =
155 g_signal_new_class_handler ("close",
156 G_TYPE_FROM_CLASS (klass),
157 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
158 G_CALLBACK (gedit_preferences_dialog_close),
159 NULL, NULL, NULL,
160 G_TYPE_NONE,
161 0);
162
163 binding_set = gtk_binding_set_by_class (klass);
164 gtk_binding_entry_add_signal (binding_set, GDK_KEY_Escape, 0, "close", 0);
165
166 /* Bind class to template */
167 gtk_widget_class_set_template_from_resource (widget_class,
168 "/org/gnome/gedit/ui/gedit-preferences-dialog.ui");
169 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, notebook);
170 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, display_line_numbers_checkbutton);
171 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, display_statusbar_checkbutton);
172 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, display_grid_checkbutton);
173 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, right_margin_checkbutton);
174 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, right_margin_position_grid);
175 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, right_margin_position_spinbutton);
176 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, highlight_current_line_checkbutton);
177 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, bracket_matching_checkbutton);
178 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, wrap_text_checkbutton);
179 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, split_checkbutton);
180 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, tabs_width_spinbutton);
181 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, insert_spaces_checkbutton);
182 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, auto_indent_checkbutton);
183 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, backup_copy_checkbutton);
184 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, auto_save_checkbutton);
185 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, auto_save_spinbutton);
186 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, default_font_checkbutton);
187 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, font_button);
188 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, font_grid);
189 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, schemes_list);
190 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, install_scheme_button);
191 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, uninstall_scheme_button);
192 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, schemes_toolbar);
193 gtk_widget_class_bind_template_child (widget_class, GeditPreferencesDialog, plugin_manager);
194 }
195
196 static void
setup_editor_page(GeditPreferencesDialog * dlg)197 setup_editor_page (GeditPreferencesDialog *dlg)
198 {
199 gedit_debug (DEBUG_PREFS);
200
201 /* Connect signal */
202 g_settings_bind (dlg->editor,
203 GEDIT_SETTINGS_TABS_SIZE,
204 dlg->tabs_width_spinbutton,
205 "value",
206 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
207 g_settings_bind (dlg->editor,
208 GEDIT_SETTINGS_INSERT_SPACES,
209 dlg->insert_spaces_checkbutton,
210 "active",
211 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
212 g_settings_bind (dlg->editor,
213 GEDIT_SETTINGS_AUTO_INDENT,
214 dlg->auto_indent_checkbutton,
215 "active",
216 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
217 g_settings_bind (dlg->editor,
218 GEDIT_SETTINGS_CREATE_BACKUP_COPY,
219 dlg->backup_copy_checkbutton,
220 "active",
221 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
222 g_settings_bind (dlg->editor,
223 GEDIT_SETTINGS_BRACKET_MATCHING,
224 dlg->bracket_matching_checkbutton,
225 "active",
226 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
227 g_settings_bind (dlg->editor,
228 GEDIT_SETTINGS_AUTO_SAVE_INTERVAL,
229 dlg->auto_save_spinbutton,
230 "value",
231 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
232 g_settings_bind (dlg->editor,
233 GEDIT_SETTINGS_AUTO_SAVE,
234 dlg->auto_save_spinbutton,
235 "sensitive",
236 G_SETTINGS_BIND_GET);
237 g_settings_bind (dlg->editor,
238 GEDIT_SETTINGS_AUTO_SAVE,
239 dlg->auto_save_checkbutton,
240 "active",
241 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
242 }
243
244 static void
wrap_mode_checkbutton_toggled(GtkToggleButton * button,GeditPreferencesDialog * dlg)245 wrap_mode_checkbutton_toggled (GtkToggleButton *button,
246 GeditPreferencesDialog *dlg)
247 {
248 GtkWrapMode mode;
249
250 if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dlg->wrap_text_checkbutton)))
251 {
252 mode = GTK_WRAP_NONE;
253
254 gtk_widget_set_sensitive (dlg->split_checkbutton,
255 FALSE);
256 gtk_toggle_button_set_inconsistent (
257 GTK_TOGGLE_BUTTON (dlg->split_checkbutton), TRUE);
258 }
259 else
260 {
261 gtk_widget_set_sensitive (dlg->split_checkbutton,
262 TRUE);
263
264 gtk_toggle_button_set_inconsistent (
265 GTK_TOGGLE_BUTTON (dlg->split_checkbutton), FALSE);
266
267
268 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dlg->split_checkbutton)))
269 {
270 g_settings_set_enum (dlg->editor,
271 GEDIT_SETTINGS_WRAP_LAST_SPLIT_MODE,
272 GTK_WRAP_WORD);
273
274 mode = GTK_WRAP_WORD;
275 }
276 else
277 {
278 g_settings_set_enum (dlg->editor,
279 GEDIT_SETTINGS_WRAP_LAST_SPLIT_MODE,
280 GTK_WRAP_CHAR);
281
282 mode = GTK_WRAP_CHAR;
283 }
284 }
285
286 g_settings_set_enum (dlg->editor,
287 GEDIT_SETTINGS_WRAP_MODE,
288 mode);
289 }
290
291 static void
grid_checkbutton_toggled(GtkToggleButton * button,GeditPreferencesDialog * dlg)292 grid_checkbutton_toggled (GtkToggleButton *button,
293 GeditPreferencesDialog *dlg)
294 {
295 GtkSourceBackgroundPatternType background_type;
296
297 background_type = gtk_toggle_button_get_active (button) ?
298 GTK_SOURCE_BACKGROUND_PATTERN_TYPE_GRID :
299 GTK_SOURCE_BACKGROUND_PATTERN_TYPE_NONE;
300 g_settings_set_enum (dlg->editor,
301 GEDIT_SETTINGS_BACKGROUND_PATTERN,
302 background_type);
303 }
304
305 static void
setup_view_page(GeditPreferencesDialog * dlg)306 setup_view_page (GeditPreferencesDialog *dlg)
307 {
308 GtkWrapMode wrap_mode;
309 GtkWrapMode last_split_mode;
310 GtkSourceBackgroundPatternType background_pattern;
311 gboolean display_right_margin;
312 guint right_margin_position;
313
314 gedit_debug (DEBUG_PREFS);
315
316 /* Get values */
317 display_right_margin = g_settings_get_boolean (dlg->editor,
318 GEDIT_SETTINGS_DISPLAY_RIGHT_MARGIN);
319 g_settings_get (dlg->editor, GEDIT_SETTINGS_RIGHT_MARGIN_POSITION,
320 "u", &right_margin_position);
321 background_pattern = g_settings_get_enum (dlg->editor,
322 GEDIT_SETTINGS_BACKGROUND_PATTERN);
323
324 wrap_mode = g_settings_get_enum (dlg->editor,
325 GEDIT_SETTINGS_WRAP_MODE);
326
327 /* Set initial state */
328 switch (wrap_mode)
329 {
330 case GTK_WRAP_WORD:
331 gtk_toggle_button_set_active (
332 GTK_TOGGLE_BUTTON (dlg->wrap_text_checkbutton), TRUE);
333 gtk_toggle_button_set_active (
334 GTK_TOGGLE_BUTTON (dlg->split_checkbutton), TRUE);
335
336 g_settings_set_enum (dlg->editor,
337 GEDIT_SETTINGS_WRAP_LAST_SPLIT_MODE,
338 GTK_WRAP_WORD);
339 break;
340 case GTK_WRAP_CHAR:
341 gtk_toggle_button_set_active (
342 GTK_TOGGLE_BUTTON (dlg->wrap_text_checkbutton), TRUE);
343 gtk_toggle_button_set_active (
344 GTK_TOGGLE_BUTTON (dlg->split_checkbutton), FALSE);
345
346 g_settings_set_enum (dlg->editor,
347 GEDIT_SETTINGS_WRAP_LAST_SPLIT_MODE,
348 GTK_WRAP_CHAR);
349 break;
350 default:
351 gtk_toggle_button_set_active (
352 GTK_TOGGLE_BUTTON (dlg->wrap_text_checkbutton), FALSE);
353
354 last_split_mode = g_settings_get_enum (dlg->editor,
355 GEDIT_SETTINGS_WRAP_LAST_SPLIT_MODE);
356 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->split_checkbutton),
357 last_split_mode == GTK_WRAP_WORD);
358
359 gtk_toggle_button_set_inconsistent (
360 GTK_TOGGLE_BUTTON (dlg->split_checkbutton), TRUE);
361 }
362
363 gtk_toggle_button_set_active (
364 GTK_TOGGLE_BUTTON (dlg->right_margin_checkbutton),
365 display_right_margin);
366 gtk_toggle_button_set_active (
367 GTK_TOGGLE_BUTTON (dlg->display_grid_checkbutton),
368 background_pattern == GTK_SOURCE_BACKGROUND_PATTERN_TYPE_GRID);
369
370 /* Set widgets sensitivity */
371 gtk_widget_set_sensitive (dlg->split_checkbutton,
372 (wrap_mode != GTK_WRAP_NONE));
373
374 g_settings_bind (dlg->editor,
375 GEDIT_SETTINGS_DISPLAY_LINE_NUMBERS,
376 dlg->display_line_numbers_checkbutton,
377 "active",
378 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
379 g_settings_bind (dlg->editor,
380 GEDIT_SETTINGS_HIGHLIGHT_CURRENT_LINE,
381 dlg->highlight_current_line_checkbutton,
382 "active",
383 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
384 g_settings_bind (dlg->uisettings,
385 GEDIT_SETTINGS_STATUSBAR_VISIBLE,
386 dlg->display_statusbar_checkbutton,
387 "active",
388 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
389 g_settings_bind (dlg->editor,
390 GEDIT_SETTINGS_DISPLAY_RIGHT_MARGIN,
391 dlg->right_margin_checkbutton,
392 "active",
393 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
394 g_settings_bind (dlg->editor,
395 GEDIT_SETTINGS_DISPLAY_RIGHT_MARGIN,
396 dlg->right_margin_position_grid,
397 "sensitive",
398 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
399 g_settings_bind (dlg->editor,
400 GEDIT_SETTINGS_RIGHT_MARGIN_POSITION,
401 dlg->right_margin_position_spinbutton,
402 "value",
403 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
404 g_settings_bind (dlg->editor,
405 GEDIT_SETTINGS_AUTO_SAVE_INTERVAL,
406 dlg->auto_save_spinbutton,
407 "value",
408 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
409 g_signal_connect (dlg->wrap_text_checkbutton,
410 "toggled",
411 G_CALLBACK (wrap_mode_checkbutton_toggled),
412 dlg);
413 g_signal_connect (dlg->split_checkbutton,
414 "toggled",
415 G_CALLBACK (wrap_mode_checkbutton_toggled),
416 dlg);
417 g_signal_connect (dlg->display_grid_checkbutton,
418 "toggled",
419 G_CALLBACK (grid_checkbutton_toggled),
420 dlg);
421 }
422
423 static void
setup_font_colors_page_font_section(GeditPreferencesDialog * dlg)424 setup_font_colors_page_font_section (GeditPreferencesDialog *dlg)
425 {
426 GeditSettings *settings;
427 gchar *system_font = NULL;
428 gchar *label;
429
430 gedit_debug (DEBUG_PREFS);
431
432 gtk_widget_set_tooltip_text (dlg->font_button,
433 _("Click on this button to select the font to be used by the editor"));
434
435 /* Get values */
436 settings = _gedit_settings_get_singleton ();
437 system_font = _gedit_settings_get_system_font (settings);
438
439 label = g_strdup_printf(_("_Use the system fixed width font (%s)"),
440 system_font);
441 gtk_button_set_label (GTK_BUTTON (dlg->default_font_checkbutton),
442 label);
443 g_free (system_font);
444 g_free (label);
445
446 /* Bind settings */
447 g_settings_bind (dlg->editor,
448 GEDIT_SETTINGS_USE_DEFAULT_FONT,
449 dlg->default_font_checkbutton,
450 "active",
451 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
452 g_settings_bind (dlg->editor,
453 GEDIT_SETTINGS_USE_DEFAULT_FONT,
454 dlg->font_grid,
455 "sensitive",
456 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET | G_SETTINGS_BIND_INVERT_BOOLEAN);
457 g_settings_bind (dlg->editor,
458 GEDIT_SETTINGS_EDITOR_FONT,
459 dlg->font_button,
460 "font-name",
461 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
462 }
463
464 static void
update_style_scheme_buttons_sensisitivity(GeditPreferencesDialog * dlg)465 update_style_scheme_buttons_sensisitivity (GeditPreferencesDialog *dlg)
466 {
467 GtkSourceStyleScheme *selected_style_scheme;
468 gboolean editable = FALSE;
469
470 selected_style_scheme = gtk_source_style_scheme_chooser_get_style_scheme (GTK_SOURCE_STYLE_SCHEME_CHOOSER (dlg->schemes_list));
471
472 if (selected_style_scheme != NULL)
473 {
474 const gchar *filename;
475
476 filename = gtk_source_style_scheme_get_filename (selected_style_scheme);
477 if (filename != NULL)
478 {
479 editable = g_str_has_prefix (filename, gedit_dirs_get_user_styles_dir ());
480 }
481 }
482
483 gtk_widget_set_sensitive (dlg->uninstall_scheme_button, editable);
484 }
485
486 static void
style_scheme_notify_cb(GtkSourceStyleSchemeChooser * chooser,GParamSpec * pspec,GeditPreferencesDialog * dlg)487 style_scheme_notify_cb (GtkSourceStyleSchemeChooser *chooser,
488 GParamSpec *pspec,
489 GeditPreferencesDialog *dlg)
490 {
491 update_style_scheme_buttons_sensisitivity (dlg);
492 }
493
494 static GFile *
get_user_style_scheme_destination_file(GFile * src_file)495 get_user_style_scheme_destination_file (GFile *src_file)
496 {
497 gchar *basename;
498 const gchar *styles_dir;
499 GFile *dest_file;
500
501 basename = g_file_get_basename (src_file);
502 g_return_val_if_fail (basename != NULL, NULL);
503
504 styles_dir = gedit_dirs_get_user_styles_dir ();
505 dest_file = g_file_new_build_filename (styles_dir, basename, NULL);
506
507 g_free (basename);
508 return dest_file;
509 }
510
511 /* Returns: whether @src_file has been correctly copied to @dest_file. */
512 static gboolean
copy_file(GFile * src_file,GFile * dest_file,GError ** error)513 copy_file (GFile *src_file,
514 GFile *dest_file,
515 GError **error)
516 {
517 if (g_file_equal (src_file, dest_file))
518 {
519 return FALSE;
520 }
521
522 if (!tepl_utils_create_parent_directories (dest_file, NULL, error))
523 {
524 return FALSE;
525 }
526
527 return g_file_copy (src_file,
528 dest_file,
529 G_FILE_COPY_OVERWRITE | G_FILE_COPY_TARGET_DEFAULT_PERMS,
530 NULL, /* cancellable */
531 NULL, NULL, /* progress callback */
532 error);
533 }
534
535 /* Get the style scheme ID of @user_style_scheme_file if it has been correctly
536 * installed and @user_style_scheme_file is a valid style scheme file.
537 */
538 static const gchar *
get_style_scheme_id_after_installing_user_style_scheme(GFile * user_style_scheme_file)539 get_style_scheme_id_after_installing_user_style_scheme (GFile *user_style_scheme_file)
540 {
541 GtkSourceStyleSchemeManager *manager;
542 const gchar * const *scheme_ids;
543 gint i;
544
545 manager = gtk_source_style_scheme_manager_get_default ();
546 gtk_source_style_scheme_manager_force_rescan (manager);
547
548 scheme_ids = gtk_source_style_scheme_manager_get_scheme_ids (manager);
549
550 for (i = 0; scheme_ids != NULL && scheme_ids[i] != NULL; i++)
551 {
552 const gchar *cur_scheme_id = scheme_ids[i];
553 GtkSourceStyleScheme *scheme;
554 const gchar *filename;
555 GFile *scheme_file;
556
557 scheme = gtk_source_style_scheme_manager_get_scheme (manager, cur_scheme_id);
558 filename = gtk_source_style_scheme_get_filename (scheme);
559 if (filename == NULL)
560 {
561 continue;
562 }
563
564 scheme_file = g_file_new_for_path (filename);
565 if (g_file_equal (scheme_file, user_style_scheme_file))
566 {
567 g_object_unref (scheme_file);
568 return cur_scheme_id;
569 }
570
571 g_object_unref (scheme_file);
572 }
573
574 return NULL;
575 }
576
577 /* Returns: (nullable): the installed style scheme ID, or %NULL on failure. */
578 static const gchar *
install_style_scheme(GFile * src_file,GError ** error)579 install_style_scheme (GFile *src_file,
580 GError **error)
581 {
582 GFile *dest_file;
583 gboolean copied;
584 const gchar *installed_style_scheme_id = NULL;
585 GError *my_error = NULL;
586
587 g_return_val_if_fail (G_IS_FILE (src_file), NULL);
588 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
589
590 dest_file = get_user_style_scheme_destination_file (src_file);
591 g_return_val_if_fail (dest_file != NULL, NULL);
592
593 copied = copy_file (src_file, dest_file, &my_error);
594 if (my_error != NULL)
595 {
596 g_propagate_error (error, my_error);
597 g_object_unref (dest_file);
598 return NULL;
599 }
600
601 installed_style_scheme_id = get_style_scheme_id_after_installing_user_style_scheme (dest_file);
602
603 if (installed_style_scheme_id == NULL && copied)
604 {
605 /* The style scheme has not been correctly installed. */
606 g_file_delete (dest_file, NULL, &my_error);
607 if (my_error != NULL)
608 {
609 gchar *dest_file_parse_name = g_file_get_parse_name (dest_file);
610
611 g_warning ("Failed to delete the file “%s”: %s",
612 dest_file_parse_name,
613 my_error->message);
614
615 g_free (dest_file_parse_name);
616 g_clear_error (&my_error);
617 }
618 }
619
620 g_object_unref (dest_file);
621 return installed_style_scheme_id;
622 }
623
624 /*
625 * uninstall_style_scheme:
626 * @scheme: a #GtkSourceStyleScheme
627 *
628 * Uninstall a user scheme.
629 *
630 * Returns: %TRUE on success, %FALSE otherwise.
631 */
632 static gboolean
uninstall_style_scheme(GtkSourceStyleScheme * scheme)633 uninstall_style_scheme (GtkSourceStyleScheme *scheme)
634 {
635 GtkSourceStyleSchemeManager *manager;
636 const gchar *filename;
637
638 g_return_val_if_fail (GTK_SOURCE_IS_STYLE_SCHEME (scheme), FALSE);
639
640 manager = gtk_source_style_scheme_manager_get_default ();
641
642 filename = gtk_source_style_scheme_get_filename (scheme);
643 if (filename == NULL)
644 return FALSE;
645
646 if (g_unlink (filename) == -1)
647 return FALSE;
648
649 /* Reload the available style schemes */
650 gtk_source_style_scheme_manager_force_rescan (manager);
651
652 return TRUE;
653 }
654
655 static void
add_scheme_chooser_response_cb(GtkFileChooserNative * chooser,gint response_id,GeditPreferencesDialog * dialog)656 add_scheme_chooser_response_cb (GtkFileChooserNative *chooser,
657 gint response_id,
658 GeditPreferencesDialog *dialog)
659 {
660 GFile *file;
661 const gchar *scheme_id;
662 GeditSettings *settings;
663 GSettings *editor_settings;
664 GError *error = NULL;
665
666 if (response_id != GTK_RESPONSE_ACCEPT)
667 {
668 return;
669 }
670
671 file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (chooser));
672 if (file == NULL)
673 {
674 return;
675 }
676
677 scheme_id = install_style_scheme (file, &error);
678 g_object_unref (file);
679
680 if (scheme_id == NULL)
681 {
682 if (error != NULL)
683 {
684 tepl_utils_show_warning_dialog (GTK_WINDOW (dialog),
685 _("The selected color scheme cannot be installed: %s"),
686 error->message);
687 }
688 else
689 {
690 tepl_utils_show_warning_dialog (GTK_WINDOW (dialog),
691 _("The selected color scheme cannot be installed."));
692 }
693
694 g_clear_error (&error);
695 return;
696 }
697
698 settings = _gedit_settings_get_singleton ();
699 editor_settings = _gedit_settings_peek_editor_settings (settings);
700 g_settings_set_string (editor_settings, GEDIT_SETTINGS_SCHEME, scheme_id);
701 }
702
703 static void
install_scheme_clicked(GtkButton * button,GeditPreferencesDialog * dialog)704 install_scheme_clicked (GtkButton *button,
705 GeditPreferencesDialog *dialog)
706 {
707 GtkFileChooserNative *chooser;
708 GtkFileFilter *scheme_filter;
709 GtkFileFilter *all_filter;
710
711 if (dialog->install_scheme_file_chooser != NULL)
712 {
713 gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog->install_scheme_file_chooser));
714 return;
715 }
716
717 chooser = gtk_file_chooser_native_new (_("Add Color Scheme"),
718 GTK_WINDOW (dialog),
719 GTK_FILE_CHOOSER_ACTION_OPEN,
720 _("_Add Scheme"),
721 _("_Cancel"));
722
723 /* Filters */
724 scheme_filter = gtk_file_filter_new ();
725 gtk_file_filter_set_name (scheme_filter, _("Color Scheme Files"));
726 gtk_file_filter_add_pattern (scheme_filter, "*.xml");
727 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), scheme_filter);
728
729 all_filter = gtk_file_filter_new ();
730 gtk_file_filter_set_name (all_filter, _("All Files"));
731 gtk_file_filter_add_pattern (all_filter, "*");
732 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), all_filter);
733
734 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (chooser), scheme_filter);
735
736 g_signal_connect (chooser,
737 "response",
738 G_CALLBACK (add_scheme_chooser_response_cb),
739 dialog);
740
741 g_set_weak_pointer (&dialog->install_scheme_file_chooser, chooser);
742
743 gtk_native_dialog_show (GTK_NATIVE_DIALOG (chooser));
744 }
745
746 static void
uninstall_scheme_clicked(GtkButton * button,GeditPreferencesDialog * dlg)747 uninstall_scheme_clicked (GtkButton *button,
748 GeditPreferencesDialog *dlg)
749 {
750 GtkSourceStyleScheme *scheme;
751 GtkSourceStyleScheme *new_selected_scheme;
752
753 scheme = gtk_source_style_scheme_chooser_get_style_scheme (GTK_SOURCE_STYLE_SCHEME_CHOOSER (dlg->schemes_list));
754
755 if (scheme == NULL)
756 {
757 return;
758 }
759
760 if (!uninstall_style_scheme (scheme))
761 {
762 tepl_utils_show_warning_dialog (GTK_WINDOW (dlg),
763 _("Could not remove color scheme “%s”."),
764 gtk_source_style_scheme_get_name (scheme));
765 return;
766 }
767
768 new_selected_scheme = gtk_source_style_scheme_chooser_get_style_scheme (GTK_SOURCE_STYLE_SCHEME_CHOOSER (dlg->schemes_list));
769 if (new_selected_scheme == NULL)
770 {
771 GeditSettings *settings;
772 GSettings *editor_settings;
773
774 settings = _gedit_settings_get_singleton ();
775 editor_settings = _gedit_settings_peek_editor_settings (settings);
776
777 g_settings_reset (editor_settings, GEDIT_SETTINGS_SCHEME);
778 }
779 }
780
781 static void
setup_font_colors_page_style_scheme_section(GeditPreferencesDialog * dlg)782 setup_font_colors_page_style_scheme_section (GeditPreferencesDialog *dlg)
783 {
784 GtkStyleContext *context;
785 GeditSettings *settings;
786 GSettings *editor_settings;
787
788 gedit_debug (DEBUG_PREFS);
789
790 /* junction between the schemes list and the toolbar */
791 context = gtk_widget_get_style_context (dlg->schemes_list);
792 gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
793 context = gtk_widget_get_style_context (dlg->schemes_toolbar);
794 gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
795
796 /* Connect signals */
797 g_signal_connect (dlg->schemes_list,
798 "notify::style-scheme",
799 G_CALLBACK (style_scheme_notify_cb),
800 dlg);
801 g_signal_connect (dlg->install_scheme_button,
802 "clicked",
803 G_CALLBACK (install_scheme_clicked),
804 dlg);
805 g_signal_connect (dlg->uninstall_scheme_button,
806 "clicked",
807 G_CALLBACK (uninstall_scheme_clicked),
808 dlg);
809
810 settings = _gedit_settings_get_singleton ();
811 editor_settings = _gedit_settings_peek_editor_settings (settings);
812 g_settings_bind (editor_settings, GEDIT_SETTINGS_SCHEME,
813 dlg->schemes_list, "tepl-style-scheme-id",
814 G_SETTINGS_BIND_DEFAULT);
815
816 update_style_scheme_buttons_sensisitivity (dlg);
817 }
818
819 static void
setup_font_colors_page(GeditPreferencesDialog * dlg)820 setup_font_colors_page (GeditPreferencesDialog *dlg)
821 {
822 setup_font_colors_page_font_section (dlg);
823 setup_font_colors_page_style_scheme_section (dlg);
824 }
825
826 static void
setup_plugins_page(GeditPreferencesDialog * dlg)827 setup_plugins_page (GeditPreferencesDialog *dlg)
828 {
829 gtk_widget_show_all (dlg->plugin_manager);
830 }
831
832 static void
gedit_preferences_dialog_init(GeditPreferencesDialog * dlg)833 gedit_preferences_dialog_init (GeditPreferencesDialog *dlg)
834 {
835 gedit_debug (DEBUG_PREFS);
836
837 dlg->editor = g_settings_new ("org.gnome.gedit.preferences.editor");
838 dlg->uisettings = g_settings_new ("org.gnome.gedit.preferences.ui");
839
840 gtk_widget_init_template (GTK_WIDGET (dlg));
841
842 setup_editor_page (dlg);
843 setup_view_page (dlg);
844 setup_font_colors_page (dlg);
845 setup_plugins_page (dlg);
846 }
847
848 void
gedit_show_preferences_dialog(GeditWindow * parent)849 gedit_show_preferences_dialog (GeditWindow *parent)
850 {
851 gedit_debug (DEBUG_PREFS);
852
853 if (preferences_dialog == NULL)
854 {
855 preferences_dialog = GTK_WIDGET (g_object_new (GEDIT_TYPE_PREFERENCES_DIALOG,
856 "application", g_application_get_default (),
857 NULL));
858 g_signal_connect (preferences_dialog,
859 "destroy",
860 G_CALLBACK (gtk_widget_destroyed),
861 &preferences_dialog);
862 }
863
864 if (GTK_WINDOW (parent) != gtk_window_get_transient_for (GTK_WINDOW (preferences_dialog)))
865 {
866 gtk_window_set_transient_for (GTK_WINDOW (preferences_dialog),
867 GTK_WINDOW (parent));
868 }
869
870 gtk_window_present (GTK_WINDOW (preferences_dialog));
871 }
872
873 /* ex:set ts=8 noet: */
874