1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * pluma-preferences-dialog.c
4  * This file is part of pluma
5  *
6  * Copyright (C) 2001-2005 Paolo Maggi
7  * Copyright (C) 2012-2021 MATE Developers
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  */
24 
25 /*
26  * Modified by the pluma Team, 2001-2003. See the AUTHORS file for a
27  * list of people on the pluma Team.
28  * See the ChangeLog files for a list of changes.
29  *
30  * $Id$
31  */
32 
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
36 
37 #include <stdio.h>
38 #include <string.h>
39 
40 #include <glib/gi18n.h>
41 #include <gtk/gtk.h>
42 #include <gtksourceview/gtksource.h>
43 #include <libpeas-gtk/peas-gtk-plugin-manager.h>
44 
45 #include "pluma-preferences-dialog.h"
46 #include "pluma-utils.h"
47 #include "pluma-debug.h"
48 #include "pluma-document.h"
49 #include "pluma-style-scheme-manager.h"
50 #include "pluma-help.h"
51 #include "pluma-dirs.h"
52 #include "pluma-settings.h"
53 #include "pluma-utils.h"
54 
55 /*
56  * pluma-preferences dialog is a singleton since we don't
57  * want two dialogs showing an inconsistent state of the
58  * preferences.
59  * When pluma_show_preferences_dialog is called and there
60  * is already a prefs dialog dialog open, it is reparented
61  * and shown.
62  */
63 
64 static GtkWidget *preferences_dialog = NULL;
65 
66 enum
67 {
68 	ID_COLUMN = 0,
69 	NAME_COLUMN,
70 	DESC_COLUMN,
71 	NUM_COLUMNS
72 };
73 
74 typedef enum
75 {
76 	DRAW_NONE = 0,
77 	DRAW_TRAILING = 1,
78 	DRAW_ALL = 2
79 } DrawSpacesSettings;
80 
81 struct _PlumaPreferencesDialogPrivate
82 {
83 	GSettings	*editor_settings;
84 
85 	GtkWidget	*notebook;
86 
87 	/* Font */
88 	GtkWidget	*default_font_checkbutton;
89 	GtkWidget	*font_button;
90 	GtkWidget	*font_hbox;
91 
92 	/* Style Scheme */
93 	GtkListStore	*schemes_treeview_model;
94 	GtkWidget	*schemes_treeview;
95 	GtkWidget	*install_scheme_button;
96 	GtkWidget	*uninstall_scheme_button;
97 
98 	GtkWidget	*install_scheme_file_schooser;
99 
100 	/* Tabs */
101 	GtkWidget	*tabs_width_spinbutton;
102 	GtkWidget	*insert_spaces_checkbutton;
103 	GtkWidget	*tabs_width_hbox;
104 
105 	/* Auto indentation */
106 	GtkWidget	*auto_indent_checkbutton;
107 
108 	/* Draw spaces... */
109 	GtkWidget       *draw_spaces_checkbutton;
110 	GtkWidget       *draw_trailing_spaces_checkbutton;
111 	GtkWidget       *draw_tabs_checkbutton;
112 	GtkWidget       *draw_trailing_tabs_checkbutton;
113 	GtkWidget       *draw_newlines_checkbutton;
114 
115 	/* Text Wrapping */
116 	GtkWidget	*wrap_text_checkbutton;
117 	GtkWidget	*split_checkbutton;
118 
119 	/* File Saving */
120 	GtkWidget	*backup_copy_checkbutton;
121 	GtkWidget	*auto_save_checkbutton;
122 	GtkWidget	*auto_save_spinbutton;
123 
124 	/* Line numbers */
125 	GtkWidget	*display_line_numbers_checkbutton;
126 
127 	/* Highlight current line */
128 	GtkWidget	*highlight_current_line_checkbutton;
129 
130 	/* Highlight matching bracket */
131 	GtkWidget	*bracket_matching_checkbutton;
132 
133 	/* Display grid pattern */
134 	GtkWidget       *display_grid_checkbutton;
135 
136 	/* Display overview map */
137 	GtkWidget	*display_overview_map_checkbutton;
138 
139 	/* Right margin */
140 	GtkWidget	*right_margin_checkbutton;
141 	GtkWidget	*right_margin_position_spinbutton;
142 
143 	/* Plugins manager */
144 	GtkWidget	*plugin_manager_place_holder;
145 };
146 
G_DEFINE_TYPE_WITH_PRIVATE(PlumaPreferencesDialog,pluma_preferences_dialog,GTK_TYPE_DIALOG)147 G_DEFINE_TYPE_WITH_PRIVATE (PlumaPreferencesDialog, pluma_preferences_dialog, GTK_TYPE_DIALOG)
148 
149 static void
150 pluma_preferences_dialog_dispose (GObject *object)
151 {
152 	PlumaPreferencesDialog *dlg = PLUMA_PREFERENCES_DIALOG (object);
153 
154 	g_clear_object (&dlg->priv->editor_settings);
155 
156 	G_OBJECT_CLASS (pluma_preferences_dialog_parent_class)->dispose (object);
157 }
158 
159 static void
pluma_preferences_dialog_class_init(PlumaPreferencesDialogClass * klass)160 pluma_preferences_dialog_class_init (PlumaPreferencesDialogClass *klass)
161 {
162 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
163 
164 	object_class->dispose = pluma_preferences_dialog_dispose;
165 }
166 
167 static void
dialog_response_handler(GtkDialog * dlg,gint res_id)168 dialog_response_handler (GtkDialog *dlg,
169 			 gint       res_id)
170 {
171 	pluma_debug (DEBUG_PREFS);
172 
173 	switch (res_id)
174 	{
175 		case GTK_RESPONSE_HELP:
176 			pluma_help_display (GTK_WINDOW (dlg),
177 					    NULL,
178 					    "pluma-prefs");
179 
180 			g_signal_stop_emission_by_name (dlg, "response");
181 
182 			break;
183 
184 		default:
185 			gtk_widget_destroy (GTK_WIDGET(dlg));
186 	}
187 }
188 
189 static void
on_auto_save_changed(GSettings * settings,const gchar * key,PlumaPreferencesDialog * dlg)190 on_auto_save_changed (GSettings              *settings,
191                       const gchar            *key,
192                       PlumaPreferencesDialog *dlg)
193 {
194 	gboolean value;
195 	value = g_settings_get_boolean (settings, key);
196 	gtk_widget_set_sensitive (dlg->priv->auto_save_spinbutton, value);
197 }
198 
199 static void
draw_spaces_checkbutton_toggled(GtkToggleButton * button,PlumaPreferencesDialog * dlg)200 draw_spaces_checkbutton_toggled (GtkToggleButton        *button,
201                                  PlumaPreferencesDialog *dlg)
202 {
203 	DrawSpacesSettings setting;
204 
205 	pluma_debug (DEBUG_PREFS);
206 
207 	g_return_if_fail (button == GTK_TOGGLE_BUTTON (dlg->priv->draw_spaces_checkbutton));
208 
209 	if (gtk_toggle_button_get_active (button))
210 		setting = DRAW_ALL;
211 	else
212 		setting = DRAW_NONE;
213 
214 	g_settings_set_enum (dlg->priv->editor_settings, PLUMA_SETTINGS_DRAWER_SPACE, setting);
215 
216 #ifdef GTK_SOURCE_VERSION_3_24
217 	if (setting == DRAW_NONE)
218 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->draw_trailing_spaces_checkbutton), FALSE);
219 
220 	gtk_widget_set_sensitive (GTK_WIDGET (dlg->priv->draw_trailing_spaces_checkbutton), setting > DRAW_NONE);
221 	gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (dlg->priv->draw_trailing_spaces_checkbutton), setting == DRAW_NONE);
222 #endif
223 }
224 
225 static void
draw_trailing_spaces_checkbutton_toggled(GtkToggleButton * button,PlumaPreferencesDialog * dlg)226 draw_trailing_spaces_checkbutton_toggled (GtkToggleButton        *button,
227                                           PlumaPreferencesDialog *dlg)
228 {
229 	pluma_debug (DEBUG_PREFS);
230 
231 	g_return_if_fail (button == GTK_TOGGLE_BUTTON (dlg->priv->draw_trailing_spaces_checkbutton));
232 
233 	if (gtk_toggle_button_get_active (button))
234 		g_settings_set_enum (dlg->priv->editor_settings,
235 				     PLUMA_SETTINGS_DRAWER_SPACE,
236 				     DRAW_TRAILING);
237 	else
238 	{
239 		gint draw_spaces = g_settings_get_enum (dlg->priv->editor_settings,
240 						        PLUMA_SETTINGS_DRAWER_SPACE);
241 
242 		if (draw_spaces)
243 			g_settings_set_enum (dlg->priv->editor_settings,
244 					     PLUMA_SETTINGS_DRAWER_SPACE,
245 					     DRAW_ALL);
246 		else
247 			g_settings_set_enum (dlg->priv->editor_settings,
248 					     PLUMA_SETTINGS_DRAWER_SPACE,
249 					     DRAW_NONE);
250 	}
251 }
252 
253 static void
draw_tabs_checkbutton_toggled(GtkToggleButton * button,PlumaPreferencesDialog * dlg)254 draw_tabs_checkbutton_toggled (GtkToggleButton        *button,
255                                PlumaPreferencesDialog *dlg)
256 {
257 	DrawSpacesSettings setting;
258 	pluma_debug (DEBUG_PREFS);
259 
260 	g_return_if_fail (button == GTK_TOGGLE_BUTTON(dlg->priv->draw_tabs_checkbutton));
261 
262 	if (gtk_toggle_button_get_active (button))
263 		setting = DRAW_ALL;
264 	else
265 		setting = DRAW_NONE;
266 
267 	g_settings_set_enum (dlg->priv->editor_settings,
268 			     PLUMA_SETTINGS_DRAWER_TAB,
269 			     setting);
270 #ifdef GTK_SOURCE_VERSION_3_24
271 	if (setting == DRAW_NONE)
272 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->draw_trailing_tabs_checkbutton), FALSE);
273 
274 	gtk_widget_set_sensitive (GTK_WIDGET(dlg->priv->draw_trailing_tabs_checkbutton), setting > DRAW_NONE);
275 	gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON(dlg->priv->draw_trailing_tabs_checkbutton), setting == DRAW_NONE);
276 #endif
277 }
278 
279 static void
draw_trailing_tabs_checkbutton_toggled(GtkToggleButton * button,PlumaPreferencesDialog * dlg)280 draw_trailing_tabs_checkbutton_toggled (GtkToggleButton        *button,
281                                         PlumaPreferencesDialog *dlg)
282 {
283 	pluma_debug (DEBUG_PREFS);
284 
285 	g_return_if_fail (button == GTK_TOGGLE_BUTTON (dlg->priv->draw_trailing_tabs_checkbutton));
286 
287 	if (gtk_toggle_button_get_active (button))
288 		g_settings_set_enum (dlg->priv->editor_settings,
289 				     PLUMA_SETTINGS_DRAWER_TAB,
290 				     DRAW_TRAILING);
291 	else
292 	{
293 		gint draw_tabs = g_settings_get_enum (dlg->priv->editor_settings,
294 						     PLUMA_SETTINGS_DRAWER_TAB);
295 
296 		if (draw_tabs)
297 			g_settings_set_enum (dlg->priv->editor_settings,
298 					     PLUMA_SETTINGS_DRAWER_TAB,
299 					     DRAW_ALL);
300 		else
301 			g_settings_set_enum (dlg->priv->editor_settings,
302 					     PLUMA_SETTINGS_DRAWER_TAB,
303 					     DRAW_NONE);
304 	}
305 }
306 
307 static void
setup_editor_page(PlumaPreferencesDialog * dlg)308 setup_editor_page (PlumaPreferencesDialog *dlg)
309 {
310 	gboolean auto_save;
311 
312 	pluma_debug (DEBUG_PREFS);
313 
314 	/* Get values */
315 	auto_save = g_settings_get_boolean (dlg->priv->editor_settings,
316 					    PLUMA_SETTINGS_AUTO_SAVE);
317 
318 	gtk_widget_set_sensitive (dlg->priv->auto_save_spinbutton,
319 				  auto_save);
320 
321 	g_settings_bind (dlg->priv->editor_settings,
322 			 PLUMA_SETTINGS_TABS_SIZE,
323 			 dlg->priv->tabs_width_spinbutton,
324 			 "value",
325 			 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
326 	g_settings_bind (dlg->priv->editor_settings,
327 			 PLUMA_SETTINGS_INSERT_SPACES,
328 			 dlg->priv->insert_spaces_checkbutton,
329 			 "active",
330 			 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
331 	g_settings_bind (dlg->priv->editor_settings,
332 			 PLUMA_SETTINGS_AUTO_INDENT,
333 			 dlg->priv->auto_indent_checkbutton,
334 			 "active",
335 			 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
336 	g_settings_bind (dlg->priv->editor_settings,
337 			 PLUMA_SETTINGS_CREATE_BACKUP_COPY,
338 			 dlg->priv->backup_copy_checkbutton,
339 			 "active",
340 			 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
341 	g_settings_bind (dlg->priv->editor_settings,
342 			 PLUMA_SETTINGS_BRACKET_MATCHING,
343 			 dlg->priv->bracket_matching_checkbutton,
344 			 "active",
345 			 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
346 	g_settings_bind (dlg->priv->editor_settings,
347 			 PLUMA_SETTINGS_AUTO_SAVE,
348 			 dlg->priv->auto_save_checkbutton,
349 			 "active",
350 			 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
351 	g_settings_bind (dlg->priv->editor_settings,
352 			 PLUMA_SETTINGS_AUTO_SAVE_INTERVAL,
353 			 dlg->priv->auto_save_spinbutton,
354 			 "value",
355 			 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET | G_SETTINGS_BIND_NO_SENSITIVITY);
356 	g_settings_bind (dlg->priv->editor_settings,
357 			 PLUMA_SETTINGS_DRAWER_NEWLINE,
358 			 dlg->priv->draw_newlines_checkbutton,
359 			 "active",
360 			 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
361 
362 	g_signal_connect (dlg->priv->editor_settings,
363 			  "changed::auto-save",
364 			  G_CALLBACK (on_auto_save_changed),
365 			  dlg);
366 
367 	gint draw_spaces = g_settings_get_enum (dlg->priv->editor_settings, PLUMA_SETTINGS_DRAWER_SPACE);
368 	gint draw_tabs = g_settings_get_enum (dlg->priv->editor_settings, PLUMA_SETTINGS_DRAWER_TAB);
369 
370 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->draw_spaces_checkbutton),
371 				      draw_spaces > DRAW_NONE);
372 #ifdef GTK_SOURCE_VERSION_3_24
373 	gtk_widget_set_sensitive (GTK_WIDGET (dlg->priv->draw_trailing_spaces_checkbutton), draw_spaces > DRAW_NONE);
374 	gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (dlg->priv->draw_trailing_spaces_checkbutton), draw_spaces == DRAW_NONE);
375 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->draw_trailing_spaces_checkbutton), draw_spaces == DRAW_TRAILING);
376 #else
377 	gtk_widget_set_sensitive (GTK_WIDGET (dlg->priv->draw_trailing_spaces_checkbutton), FALSE);
378 	gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (dlg->priv->draw_trailing_spaces_checkbutton), TRUE);
379 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->draw_trailing_spaces_checkbutton), FALSE);
380 #endif
381 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->draw_tabs_checkbutton), draw_tabs > DRAW_NONE);
382 #ifdef GTK_SOURCE_VERSION_3_24
383 	gtk_widget_set_sensitive (GTK_WIDGET (dlg->priv->draw_trailing_tabs_checkbutton), draw_tabs > DRAW_NONE);
384 	gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (dlg->priv->draw_trailing_tabs_checkbutton), draw_tabs == DRAW_NONE);
385 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->draw_trailing_tabs_checkbutton), draw_tabs == DRAW_TRAILING);
386 #else
387 	gtk_widget_set_sensitive (GTK_WIDGET (dlg->priv->draw_trailing_tabs_checkbutton), FALSE);
388 	gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (dlg->priv->draw_trailing_tabs_checkbutton), FALSE);
389 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->draw_trailing_tabs_checkbutton), FALSE);
390 #endif
391 
392 	g_signal_connect (dlg->priv->draw_spaces_checkbutton,
393 	                  "toggled",
394 	                  G_CALLBACK (draw_spaces_checkbutton_toggled),
395 	                  dlg);
396 	g_signal_connect (dlg->priv->draw_trailing_spaces_checkbutton,
397 	                  "toggled",
398 	                  G_CALLBACK (draw_trailing_spaces_checkbutton_toggled),
399 	                  dlg);
400 	g_signal_connect (dlg->priv->draw_tabs_checkbutton,
401 	                  "toggled",
402 	                  G_CALLBACK (draw_tabs_checkbutton_toggled),
403 	                  dlg);
404 	g_signal_connect (dlg->priv->draw_trailing_tabs_checkbutton,
405 	                  "toggled",
406 	                  G_CALLBACK (draw_trailing_tabs_checkbutton_toggled),
407 	                  dlg);
408 }
409 
410 static gboolean split_button_state = TRUE;
411 
412 static void
wrap_mode_checkbutton_toggled(GtkToggleButton * button,PlumaPreferencesDialog * dlg)413 wrap_mode_checkbutton_toggled (GtkToggleButton        *button,
414 			       PlumaPreferencesDialog *dlg)
415 {
416 	GtkWrapMode mode;
417 
418 	if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dlg->priv->wrap_text_checkbutton)))
419 	{
420 		mode = GTK_WRAP_NONE;
421 
422 		gtk_widget_set_sensitive (dlg->priv->split_checkbutton, FALSE);
423 
424 		gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), TRUE);
425 	}
426 	else
427 	{
428 		gtk_widget_set_sensitive (dlg->priv->split_checkbutton, TRUE);
429 
430 		gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), FALSE);
431 
432 		if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton)))
433 		{
434 			split_button_state = TRUE;
435 
436 			mode = GTK_WRAP_WORD;
437 		}
438 		else
439 		{
440 			split_button_state = FALSE;
441 
442 			mode = GTK_WRAP_CHAR;
443 		}
444 	}
445 
446 	pluma_settings_set_wrap_mode (dlg->priv->editor_settings,
447 				      PLUMA_SETTINGS_WRAP_MODE,
448 				      mode);
449 }
450 
451 static void
right_margin_checkbutton_toggled(GtkToggleButton * button,PlumaPreferencesDialog * dlg)452 right_margin_checkbutton_toggled (GtkToggleButton        *button,
453 				  PlumaPreferencesDialog *dlg)
454 {
455 	gboolean active;
456 
457 	g_return_if_fail (button == GTK_TOGGLE_BUTTON (dlg->priv->right_margin_checkbutton));
458 
459 	active = gtk_toggle_button_get_active (button);
460 
461 	g_settings_set_boolean (dlg->priv->editor_settings, PLUMA_SETTINGS_DISPLAY_RIGHT_MARGIN,
462 				active);
463 
464 
465 	gtk_widget_set_sensitive (dlg->priv->right_margin_position_spinbutton,
466 				  active);
467 }
468 
469 static void
grid_checkbutton_toggled(GtkToggleButton * button,PlumaPreferencesDialog * dlg)470 grid_checkbutton_toggled (GtkToggleButton        *button,
471                           PlumaPreferencesDialog *dlg)
472 {
473 	GtkSourceBackgroundPatternType background_type;
474 
475 	background_type = gtk_toggle_button_get_active (button) ?
476 	                  GTK_SOURCE_BACKGROUND_PATTERN_TYPE_GRID :
477 		          GTK_SOURCE_BACKGROUND_PATTERN_TYPE_NONE;
478 	g_settings_set_enum (dlg->priv->editor_settings,
479 	                     PLUMA_SETTINGS_BACKGROUND_PATTERN,
480 	                     background_type);
481 }
482 
483 static void
setup_view_page(PlumaPreferencesDialog * dlg)484 setup_view_page (PlumaPreferencesDialog *dlg)
485 {
486 	GtkWrapMode wrap_mode;
487 	GtkSourceBackgroundPatternType background_pattern;
488 	gboolean display_right_margin;
489 
490 	pluma_debug (DEBUG_PREFS);
491 
492 	/* Get values */
493 	display_right_margin = g_settings_get_boolean (dlg->priv->editor_settings,
494 						       PLUMA_SETTINGS_DISPLAY_RIGHT_MARGIN);
495 
496 	/* Set initial state */
497 	wrap_mode = pluma_settings_get_wrap_mode (dlg->priv->editor_settings,
498 						  PLUMA_SETTINGS_WRAP_MODE);
499 
500 	background_pattern = g_settings_get_enum (dlg->priv->editor_settings,
501 	                                          PLUMA_SETTINGS_BACKGROUND_PATTERN);
502 
503 	switch (wrap_mode)
504 	{
505 		case GTK_WRAP_WORD:
506 			gtk_toggle_button_set_active (
507 				GTK_TOGGLE_BUTTON (dlg->priv->wrap_text_checkbutton), TRUE);
508 			gtk_toggle_button_set_active (
509 				GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), TRUE);
510 			break;
511 		case GTK_WRAP_CHAR:
512 			gtk_toggle_button_set_active (
513 				GTK_TOGGLE_BUTTON (dlg->priv->wrap_text_checkbutton), TRUE);
514 			gtk_toggle_button_set_active (
515 				GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), FALSE);
516 			break;
517 		default:
518 			gtk_toggle_button_set_active (
519 				GTK_TOGGLE_BUTTON (dlg->priv->wrap_text_checkbutton), FALSE);
520 			gtk_toggle_button_set_active (
521 				GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), split_button_state);
522 			gtk_toggle_button_set_inconsistent (
523 				GTK_TOGGLE_BUTTON (dlg->priv->split_checkbutton), TRUE);
524 
525 	}
526 
527 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->right_margin_checkbutton),
528 				      display_right_margin);
529 
530 	gtk_toggle_button_set_active (
531 		GTK_TOGGLE_BUTTON (dlg->priv->display_grid_checkbutton),
532 		background_pattern == GTK_SOURCE_BACKGROUND_PATTERN_TYPE_GRID);
533 
534 	/* Set widgets sensitivity */
535 	gtk_widget_set_sensitive (dlg->priv->split_checkbutton, (wrap_mode != GTK_WRAP_NONE));
536 
537 	gtk_widget_set_sensitive (dlg->priv->right_margin_position_spinbutton, display_right_margin);
538 
539 	g_settings_bind (dlg->priv->editor_settings,
540 			 PLUMA_SETTINGS_DISPLAY_LINE_NUMBERS,
541 			 dlg->priv->display_line_numbers_checkbutton,
542 			 "active",
543 			 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
544 	g_settings_bind (dlg->priv->editor_settings,
545 			 PLUMA_SETTINGS_HIGHLIGHT_CURRENT_LINE,
546 			 dlg->priv->highlight_current_line_checkbutton,
547 			 "active",
548 			 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
549 	g_settings_bind (dlg->priv->editor_settings,
550 			 PLUMA_SETTINGS_RIGHT_MARGIN_POSITION,
551 			 dlg->priv->right_margin_position_spinbutton,
552 			 "value",
553 			 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET | G_SETTINGS_BIND_NO_SENSITIVITY);
554 	g_settings_bind (dlg->priv->editor_settings,
555 			 PLUMA_SETTINGS_DISPLAY_OVERVIEW_MAP,
556 			 dlg->priv->display_overview_map_checkbutton,
557 			 "active",
558 			 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
559 
560 	g_signal_connect (dlg->priv->wrap_text_checkbutton,
561 			  "toggled",
562 			  G_CALLBACK (wrap_mode_checkbutton_toggled),
563 			  dlg);
564 	g_signal_connect (dlg->priv->split_checkbutton,
565 			  "toggled",
566 			  G_CALLBACK (wrap_mode_checkbutton_toggled),
567 			  dlg);
568 	g_signal_connect (dlg->priv->right_margin_checkbutton,
569 			  "toggled",
570 			  G_CALLBACK (right_margin_checkbutton_toggled),
571 			  dlg);
572 	g_signal_connect (dlg->priv->display_grid_checkbutton,
573 			  "toggled",
574 			  G_CALLBACK (grid_checkbutton_toggled),
575 			  dlg);
576 }
577 
578 static void
on_use_default_font_changed(GSettings * settings,const gchar * key,PlumaPreferencesDialog * dlg)579 on_use_default_font_changed (GSettings              *settings,
580                              const gchar            *key,
581                              PlumaPreferencesDialog *dlg)
582 {
583 	gboolean value;
584 
585 	pluma_debug (DEBUG_PREFS);
586 
587 	value = g_settings_get_boolean (settings, key);
588 
589 	gtk_widget_set_sensitive (dlg->priv->font_hbox, !value);
590 }
591 
592 static void
setup_font_colors_page_font_section(PlumaPreferencesDialog * dlg)593 setup_font_colors_page_font_section (PlumaPreferencesDialog *dlg)
594 {
595 	PlumaSettings *settings;
596 	gboolean use_default_font;
597 	gchar *system_font = NULL;
598 	gchar *label;
599 
600 	pluma_debug (DEBUG_PREFS);
601 
602 	gtk_widget_set_tooltip_text (dlg->priv->font_button,
603 			 _("Click on this button to select the font to be used by the editor"));
604 
605 	pluma_utils_set_atk_relation (dlg->priv->font_button,
606 				      dlg->priv->default_font_checkbutton,
607 				      ATK_RELATION_CONTROLLED_BY);
608 	pluma_utils_set_atk_relation (dlg->priv->default_font_checkbutton,
609 				      dlg->priv->font_button,
610 				      ATK_RELATION_CONTROLLER_FOR);
611 
612 	/* Get values */
613 	settings = _pluma_settings_get_singleton ();
614 	system_font = pluma_settings_get_system_font (settings);
615 	use_default_font = g_settings_get_boolean (dlg->priv->editor_settings,
616 						   PLUMA_SETTINGS_USE_DEFAULT_FONT);
617 
618 	label = g_strdup_printf(_("_Use the system fixed width font (%s)"), system_font);
619 	gtk_button_set_label (GTK_BUTTON (dlg->priv->default_font_checkbutton),
620 			      label);
621 	g_free (system_font);
622 	g_free (label);
623 
624 	/* read current config and setup initial state */
625 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dlg->priv->default_font_checkbutton),
626 				      use_default_font);
627 
628 	/* Connect signals */
629 	g_signal_connect (dlg->priv->editor_settings,
630 			  "changed::use-default-font",
631 			  G_CALLBACK (on_use_default_font_changed),
632 			  dlg);
633 	g_settings_bind (dlg->priv->editor_settings,
634 			 PLUMA_SETTINGS_USE_DEFAULT_FONT,
635 			 dlg->priv->default_font_checkbutton,
636 			 "active",
637 			 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
638 	g_settings_bind (dlg->priv->editor_settings,
639 			 PLUMA_SETTINGS_EDITOR_FONT,
640 			 dlg->priv->font_button,
641 			 "font-name",
642 			 G_SETTINGS_BIND_GET | G_SETTINGS_BIND_SET);
643 
644 	/* Set initial widget sensitivity */
645 	gtk_widget_set_sensitive (dlg->priv->font_hbox, !use_default_font);
646 }
647 
648 static void
set_buttons_sensisitivity_according_to_scheme(PlumaPreferencesDialog * dlg,const gchar * scheme_id)649 set_buttons_sensisitivity_according_to_scheme (PlumaPreferencesDialog *dlg,
650 					       const gchar            *scheme_id)
651 {
652 	gboolean editable;
653 
654 	editable = (scheme_id != NULL) &&
655 	           _pluma_style_scheme_manager_scheme_is_pluma_user_scheme (
656 						pluma_get_style_scheme_manager (),
657 						scheme_id);
658 
659 	gtk_widget_set_sensitive (dlg->priv->uninstall_scheme_button, editable);
660 }
661 
662 static void
style_scheme_changed(GtkWidget * treeview,PlumaPreferencesDialog * dlg)663 style_scheme_changed (GtkWidget              *treeview,
664 		      PlumaPreferencesDialog *dlg)
665 {
666 	GtkTreePath *path;
667 	GtkTreeIter iter;
668 	gchar *id;
669 
670 	gtk_tree_view_get_cursor (GTK_TREE_VIEW (dlg->priv->schemes_treeview), &path, NULL);
671 	gtk_tree_model_get_iter (GTK_TREE_MODEL (dlg->priv->schemes_treeview_model),
672 				 &iter, path);
673 	gtk_tree_path_free (path);
674 	gtk_tree_model_get (GTK_TREE_MODEL (dlg->priv->schemes_treeview_model),
675 			    &iter, ID_COLUMN, &id, -1);
676 
677 	g_settings_set_string (dlg->priv->editor_settings, PLUMA_SETTINGS_COLOR_SCHEME, id);
678 
679 	set_buttons_sensisitivity_according_to_scheme (dlg, id);
680 
681 	g_free (id);
682 }
683 
684 static const gchar *
ensure_color_scheme_id(PlumaPreferencesDialog * dlg,const gchar * id)685 ensure_color_scheme_id (PlumaPreferencesDialog *dlg,
686                         const gchar            *id)
687 {
688 	GtkSourceStyleScheme *scheme = NULL;
689 	GtkSourceStyleSchemeManager *manager = pluma_get_style_scheme_manager ();
690 
691 	if (id == NULL)
692 	{
693 		gchar *pref_id;
694 
695 		pref_id = g_settings_get_string (dlg->priv->editor_settings,
696 						 PLUMA_SETTINGS_COLOR_SCHEME);
697 
698 		scheme = gtk_source_style_scheme_manager_get_scheme (manager,
699 								     pref_id);
700 		g_free (pref_id);
701 	}
702 	else
703 	{
704 		scheme = gtk_source_style_scheme_manager_get_scheme (manager,
705 								     id);
706 	}
707 
708 	if (scheme == NULL)
709 	{
710 		/* Fall-back to classic style scheme */
711 		scheme = gtk_source_style_scheme_manager_get_scheme (manager,
712 								     "classic");
713 	}
714 
715 	if (scheme == NULL)
716 	{
717 		/* Cannot determine default style scheme -> broken GtkSourceView installation */
718 		return NULL;
719 	}
720 
721 	return 	gtk_source_style_scheme_get_id (scheme);
722 }
723 
724 /* If def_id is NULL, use the default scheme as returned by
725  * pluma_style_scheme_manager_get_default_scheme. If this one returns NULL
726  * use the first available scheme as default */
727 static const gchar *
populate_color_scheme_list(PlumaPreferencesDialog * dlg,const gchar * def_id)728 populate_color_scheme_list (PlumaPreferencesDialog *dlg, const gchar *def_id)
729 {
730 	GSList *schemes;
731 	GSList *l;
732 
733 	gtk_list_store_clear (dlg->priv->schemes_treeview_model);
734 
735 	def_id = ensure_color_scheme_id (dlg, def_id);
736 	if (def_id == NULL)
737 	{
738 		g_warning ("Cannot build the list of available color schemes.\n"
739 		           "Please check your GtkSourceView installation.");
740 		return NULL;
741 	}
742 
743 	schemes = pluma_style_scheme_manager_list_schemes_sorted (pluma_get_style_scheme_manager ());
744 	l = schemes;
745 	while (l != NULL)
746 	{
747 		GtkSourceStyleScheme *scheme;
748 		const gchar *id;
749 		const gchar *name;
750 		const gchar *description;
751 		GtkTreeIter iter;
752 
753 		scheme = GTK_SOURCE_STYLE_SCHEME (l->data);
754 
755 		id = gtk_source_style_scheme_get_id (scheme);
756 		name = gtk_source_style_scheme_get_name (scheme);
757 		description = gtk_source_style_scheme_get_description (scheme);
758 
759 		gtk_list_store_append (dlg->priv->schemes_treeview_model, &iter);
760 		gtk_list_store_set (dlg->priv->schemes_treeview_model,
761 				    &iter,
762 				    ID_COLUMN, id,
763 				    NAME_COLUMN, name,
764 				    DESC_COLUMN, description,
765 				    -1);
766 
767 		g_return_val_if_fail (def_id != NULL, NULL);
768 		if (strcmp (id, def_id) == 0)
769 		{
770 			GtkTreeSelection *selection;
771 
772 			selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->priv->schemes_treeview));
773 			gtk_tree_selection_select_iter (selection, &iter);
774 		}
775 
776 		l = g_slist_next (l);
777 	}
778 
779 	g_slist_free (schemes);
780 
781 	return def_id;
782 }
783 
784 static void
add_scheme_chooser_response_cb(GtkDialog * chooser,gint res_id,PlumaPreferencesDialog * dlg)785 add_scheme_chooser_response_cb (GtkDialog              *chooser,
786 				gint                    res_id,
787 				PlumaPreferencesDialog *dlg)
788 {
789 	gchar* filename;
790 	const gchar *scheme_id;
791 
792 	if (res_id != GTK_RESPONSE_ACCEPT)
793 	{
794 		gtk_widget_hide (GTK_WIDGET (chooser));
795 		return;
796 	}
797 
798 	filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser));
799 	if (filename == NULL)
800 		return;
801 
802 	gtk_widget_hide (GTK_WIDGET (chooser));
803 
804 	scheme_id = _pluma_style_scheme_manager_install_scheme (
805 					pluma_get_style_scheme_manager (),
806 					filename);
807 	g_free (filename);
808 
809 	if (scheme_id == NULL)
810 	{
811 		pluma_warning (GTK_WINDOW (dlg),
812 			       _("The selected color scheme cannot be installed."));
813 
814 		return;
815 	}
816 
817 	g_settings_set_string (dlg->priv->editor_settings, PLUMA_SETTINGS_COLOR_SCHEME,
818 			       scheme_id);
819 
820 	scheme_id = populate_color_scheme_list (dlg, scheme_id);
821 
822 	set_buttons_sensisitivity_according_to_scheme (dlg, scheme_id);
823 }
824 
825 static GtkWidget *
scheme_file_chooser_dialog_new_valist(const gchar * title,GtkWindow * parent,GtkFileChooserAction action,const gchar * first_button_text,va_list varargs)826 scheme_file_chooser_dialog_new_valist (const gchar          *title,
827 				       GtkWindow            *parent,
828 				       GtkFileChooserAction  action,
829 				       const gchar          *first_button_text,
830 				       va_list               varargs)
831 {
832 	GtkWidget *result;
833 	const char *button_text = first_button_text;
834 	gint response_id;
835 
836 	result = g_object_new (GTK_TYPE_FILE_CHOOSER_DIALOG,
837 			       "title", title,
838 			       "action", action,
839 			       NULL);
840 
841 	if (parent)
842 		gtk_window_set_transient_for (GTK_WINDOW (result), parent);
843 
844 	while (button_text)
845 		{
846 			response_id = va_arg (varargs, gint);
847 
848 			if (g_strcmp0 (button_text, "process-stop") == 0)
849 				pluma_dialog_add_button (GTK_DIALOG (result), _("_Cancel"), button_text, response_id);
850 			else
851 				gtk_dialog_add_button (GTK_DIALOG (result), button_text, response_id);
852 
853 			button_text = va_arg (varargs, const gchar *);
854 		}
855 
856 	return result;
857 }
858 
859 static GtkWidget *
scheme_file_chooser_dialog_new(const gchar * title,GtkWindow * parent,GtkFileChooserAction action,const gchar * first_button_text,...)860 scheme_file_chooser_dialog_new (const gchar          *title,
861 				GtkWindow            *parent,
862 				GtkFileChooserAction  action,
863 				const gchar          *first_button_text,
864 				...)
865 {
866 	GtkWidget *result;
867 	va_list varargs;
868 
869 	va_start (varargs, first_button_text);
870 	result = scheme_file_chooser_dialog_new_valist (title, parent, action,
871 							first_button_text,
872 							varargs);
873 	va_end (varargs);
874 
875 	return result;
876 }
877 
878 static void
install_scheme_clicked(GtkButton * button,PlumaPreferencesDialog * dlg)879 install_scheme_clicked (GtkButton              *button,
880 			PlumaPreferencesDialog *dlg)
881 {
882 	GtkWidget      *chooser;
883 	GtkFileFilter  *filter;
884 
885 	if (dlg->priv->install_scheme_file_schooser != NULL) {
886 		gtk_window_present (GTK_WINDOW (dlg->priv->install_scheme_file_schooser));
887 		gtk_widget_grab_focus (dlg->priv->install_scheme_file_schooser);
888 		return;
889 	}
890 
891 	chooser = scheme_file_chooser_dialog_new (_("Add Scheme"),
892 						  GTK_WINDOW (dlg),
893 						  GTK_FILE_CHOOSER_ACTION_OPEN,
894 						  "process-stop", GTK_RESPONSE_CANCEL,
895 						  NULL);
896 
897 	pluma_dialog_add_button (GTK_DIALOG (chooser),
898 				 _("A_dd Scheme"),
899 				 "list-add",
900 				 GTK_RESPONSE_ACCEPT);
901 
902 	gtk_window_set_destroy_with_parent (GTK_WINDOW (chooser), TRUE);
903 
904 	/* Filters */
905 	filter = gtk_file_filter_new ();
906 	gtk_file_filter_set_name (filter, _("Color Scheme Files"));
907 	gtk_file_filter_add_pattern (filter, "*.xml");
908 	gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
909 
910 	gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (chooser), filter);
911 
912 	filter = gtk_file_filter_new ();
913 	gtk_file_filter_set_name (filter, _("All Files"));
914 	gtk_file_filter_add_pattern (filter, "*");
915 	gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
916 
917 	gtk_dialog_set_default_response (GTK_DIALOG (chooser), GTK_RESPONSE_ACCEPT);
918 
919 	g_signal_connect (chooser,
920 			  "response",
921 			  G_CALLBACK (add_scheme_chooser_response_cb),
922 			  dlg);
923 
924 	dlg->priv->install_scheme_file_schooser = chooser;
925 
926 	g_object_add_weak_pointer (G_OBJECT (chooser),
927 				   (gpointer) &dlg->priv->install_scheme_file_schooser);
928 
929 	gtk_widget_show (chooser);
930 }
931 
932 static void
uninstall_scheme_clicked(GtkButton * button,PlumaPreferencesDialog * dlg)933 uninstall_scheme_clicked (GtkButton              *button,
934 			  PlumaPreferencesDialog *dlg)
935 {
936 	GtkTreeSelection *selection;
937 	GtkTreeModel *model;
938 	GtkTreeIter iter;
939 
940 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->priv->schemes_treeview));
941 	model = GTK_TREE_MODEL (dlg->priv->schemes_treeview_model);
942 
943 	if (gtk_tree_selection_get_selected (selection,
944 					     &model,
945 					     &iter))
946 	{
947 		gchar *id;
948 		gchar *name;
949 
950 		gtk_tree_model_get (model, &iter,
951 				    ID_COLUMN, &id,
952 				    NAME_COLUMN, &name,
953 				    -1);
954 
955 		if (!_pluma_style_scheme_manager_uninstall_scheme (pluma_get_style_scheme_manager (), id))
956 		{
957 			pluma_warning (GTK_WINDOW (dlg),
958 				       _("Could not remove color scheme \"%s\"."),
959 				       name);
960 		}
961 		else
962 		{
963 			const gchar *real_new_id;
964 			gchar *new_id = NULL;
965 			GtkTreePath *path;
966 			GtkTreeIter new_iter;
967 			gboolean new_iter_set = FALSE;
968 
969 			/* If the removed style scheme is the last of the list,
970 			 * set as new default style scheme the previous one,
971 			 * otherwise set the next one.
972 			 * To make this possible, we need to get the id of the
973 			 * new default style scheme before re-populating the list.
974 			 * Fall back to "classic" if it is not possible to get
975 			 * the id
976 			 */
977 			path = gtk_tree_model_get_path (model, &iter);
978 
979 			/* Try to move to the next path */
980 			gtk_tree_path_next (path);
981 			if (!gtk_tree_model_get_iter (model, &new_iter, path))
982 			{
983 				/* It seems the removed style scheme was the
984 				 * last of the list. Try to move to the
985 				 * previous one */
986 				gtk_tree_path_free (path);
987 
988 				path = gtk_tree_model_get_path (model, &iter);
989 
990 				gtk_tree_path_prev (path);
991 				if (gtk_tree_model_get_iter (model, &new_iter, path))
992 					new_iter_set = TRUE;
993 			}
994 			else
995 				new_iter_set = TRUE;
996 
997 			gtk_tree_path_free (path);
998 
999 			if (new_iter_set)
1000 				gtk_tree_model_get (model, &new_iter,
1001 						    ID_COLUMN, &new_id,
1002 						    -1);
1003 
1004 			real_new_id = populate_color_scheme_list (dlg, new_id);
1005 			g_free (new_id);
1006 
1007 			set_buttons_sensisitivity_according_to_scheme (dlg, real_new_id);
1008 
1009 			if (real_new_id != NULL)
1010 			{
1011 				g_settings_set_string (dlg->priv->editor_settings,
1012 						       PLUMA_SETTINGS_COLOR_SCHEME,
1013 						       real_new_id);
1014 			}
1015 
1016 		}
1017 
1018 		g_free (id);
1019 		g_free (name);
1020 	}
1021 }
1022 
1023 static void
scheme_description_cell_data_func(GtkTreeViewColumn * column,GtkCellRenderer * renderer,GtkTreeModel * model,GtkTreeIter * iter,gpointer data)1024 scheme_description_cell_data_func (GtkTreeViewColumn *column,
1025 				   GtkCellRenderer   *renderer,
1026 				   GtkTreeModel      *model,
1027 				   GtkTreeIter       *iter,
1028 				   gpointer           data)
1029 {
1030 	gchar *name;
1031 	gchar *desc;
1032 	gchar *text;
1033 
1034 	gtk_tree_model_get (model, iter,
1035 			    NAME_COLUMN, &name,
1036 			    DESC_COLUMN, &desc,
1037 			    -1);
1038 
1039 	if (desc != NULL)
1040 	{
1041 		text = g_markup_printf_escaped ("<b>%s</b> - %s",
1042 						name,
1043 						desc);
1044 	}
1045 	else
1046 	{
1047 		text = g_markup_printf_escaped ("<b>%s</b>",
1048 						name);
1049 	}
1050 
1051 	g_free (name);
1052 	g_free (desc);
1053 
1054 	g_object_set (G_OBJECT (renderer),
1055 		      "markup",
1056 		      text,
1057 		      NULL);
1058 
1059 	g_free (text);
1060 }
1061 
1062 static void
setup_font_colors_page_style_scheme_section(PlumaPreferencesDialog * dlg)1063 setup_font_colors_page_style_scheme_section (PlumaPreferencesDialog *dlg)
1064 {
1065 	GtkCellRenderer *renderer;
1066 	GtkTreeViewColumn *column;
1067 	GtkTreeSelection *selection;
1068 	const gchar *def_id;
1069 
1070 	pluma_debug (DEBUG_PREFS);
1071 
1072 	/* Create GtkListStore for styles & setup treeview. */
1073 	dlg->priv->schemes_treeview_model = gtk_list_store_new (NUM_COLUMNS,
1074 								G_TYPE_STRING,
1075 								G_TYPE_STRING,
1076 								G_TYPE_STRING,
1077 								G_TYPE_STRING);
1078 
1079 	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (dlg->priv->schemes_treeview_model),
1080 					      0,
1081 					      GTK_SORT_ASCENDING);
1082 	gtk_tree_view_set_model (GTK_TREE_VIEW (dlg->priv->schemes_treeview),
1083 				 GTK_TREE_MODEL (dlg->priv->schemes_treeview_model));
1084 
1085 	column = gtk_tree_view_column_new ();
1086 
1087 	renderer = gtk_cell_renderer_text_new ();
1088 	g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
1089 	gtk_tree_view_column_pack_start (column, renderer, TRUE);
1090 	gtk_tree_view_column_set_cell_data_func (column,
1091 						 renderer,
1092 						 scheme_description_cell_data_func,
1093 						 dlg,
1094 						 NULL);
1095 
1096 	gtk_tree_view_append_column (GTK_TREE_VIEW (dlg->priv->schemes_treeview),
1097 				     column);
1098 
1099 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dlg->priv->schemes_treeview));
1100 	gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
1101 
1102 	def_id = populate_color_scheme_list (dlg, NULL);
1103 
1104 	gtk_button_set_image (GTK_BUTTON (dlg->priv->uninstall_scheme_button),
1105 			      gtk_image_new_from_icon_name ("list-remove", GTK_ICON_SIZE_BUTTON));
1106 
1107 	/* Connect signals */
1108 	g_signal_connect (dlg->priv->schemes_treeview,
1109 			  "cursor-changed",
1110 			  G_CALLBACK (style_scheme_changed),
1111 			  dlg);
1112 	g_signal_connect (dlg->priv->install_scheme_button,
1113 			  "clicked",
1114 			  G_CALLBACK (install_scheme_clicked),
1115 			  dlg);
1116 	g_signal_connect (dlg->priv->uninstall_scheme_button,
1117 			  "clicked",
1118 			  G_CALLBACK (uninstall_scheme_clicked),
1119 			  dlg);
1120 
1121 	/* Set initial widget sensitivity */
1122 	set_buttons_sensisitivity_according_to_scheme (dlg, def_id);
1123 }
1124 
1125 static void
setup_font_colors_page(PlumaPreferencesDialog * dlg)1126 setup_font_colors_page (PlumaPreferencesDialog *dlg)
1127 {
1128 	setup_font_colors_page_font_section (dlg);
1129 	setup_font_colors_page_style_scheme_section (dlg);
1130 }
1131 
1132 static void
setup_plugins_page(PlumaPreferencesDialog * dlg)1133 setup_plugins_page (PlumaPreferencesDialog *dlg)
1134 {
1135 	GtkWidget *page_content;
1136 
1137 	pluma_debug (DEBUG_PREFS);
1138 
1139 	page_content = peas_gtk_plugin_manager_new (NULL);
1140 	g_return_if_fail (page_content != NULL);
1141 
1142 	gtk_box_pack_start (GTK_BOX (dlg->priv->plugin_manager_place_holder),
1143 			    page_content,
1144 			    TRUE,
1145 			    TRUE,
1146 			    0);
1147 
1148 	gtk_widget_show_all (page_content);
1149 }
1150 
1151 static gboolean
on_notebook_scroll_event(GtkWidget * widget,GdkEventScroll * event)1152 on_notebook_scroll_event (GtkWidget        *widget,
1153                           GdkEventScroll   *event)
1154 
1155 {
1156     GtkNotebook *notebook = GTK_NOTEBOOK (widget);
1157     GtkWidget *child, *event_widget, *action_widget;
1158 
1159     child = gtk_notebook_get_nth_page (notebook, gtk_notebook_get_current_page (notebook));
1160     if (child == NULL)
1161         return FALSE;
1162 
1163     event_widget = gtk_get_event_widget ((GdkEvent*) event);
1164 
1165     /* Ignore scroll events from the content of the page */
1166     if (event_widget == NULL || event_widget == child || gtk_widget_is_ancestor (event_widget, child))
1167         return FALSE;
1168 
1169     /* And also from the action widgets */
1170     action_widget = gtk_notebook_get_action_widget (notebook, GTK_PACK_START);
1171     if (event_widget == action_widget || (action_widget != NULL && gtk_widget_is_ancestor (event_widget, action_widget)))
1172         return FALSE;
1173 
1174     action_widget = gtk_notebook_get_action_widget (notebook, GTK_PACK_END);
1175     if (event_widget == action_widget || (action_widget != NULL && gtk_widget_is_ancestor (event_widget, action_widget)))
1176         return FALSE;
1177 
1178     switch (event->direction) {
1179         case GDK_SCROLL_RIGHT:
1180         case GDK_SCROLL_DOWN:
1181             gtk_notebook_next_page (notebook);
1182             break;
1183         case GDK_SCROLL_LEFT:
1184         case GDK_SCROLL_UP:
1185             gtk_notebook_prev_page (notebook);
1186             break;
1187         case GDK_SCROLL_SMOOTH:
1188             switch (gtk_notebook_get_tab_pos (notebook)) {
1189                 case GTK_POS_LEFT:
1190                 case GTK_POS_RIGHT:
1191                     if (event->delta_y > 0)
1192                         gtk_notebook_next_page (notebook);
1193                     else if (event->delta_y < 0)
1194                         gtk_notebook_prev_page (notebook);
1195                     break;
1196                 case GTK_POS_TOP:
1197                 case GTK_POS_BOTTOM:
1198                     if (event->delta_x > 0)
1199                         gtk_notebook_next_page (notebook);
1200                     else if (event->delta_x < 0)
1201                         gtk_notebook_prev_page (notebook);
1202                     break;
1203             }
1204             break;
1205     }
1206 
1207     return TRUE;
1208 }
1209 
1210 static void
pluma_preferences_dialog_init(PlumaPreferencesDialog * dlg)1211 pluma_preferences_dialog_init (PlumaPreferencesDialog *dlg)
1212 {
1213 	GtkWidget *error_widget;
1214 	gboolean ret;
1215 	gchar *root_objects[] = {
1216 		"notebook",
1217 		"adjustment1",
1218 		"adjustment2",
1219 		"adjustment3",
1220 		"install_scheme_image",
1221 		NULL
1222 	};
1223 
1224 	pluma_debug (DEBUG_PREFS);
1225 
1226 	dlg->priv = pluma_preferences_dialog_get_instance_private (dlg);
1227 
1228 	dlg->priv->editor_settings = g_settings_new (PLUMA_SCHEMA_ID);
1229 
1230 	pluma_dialog_add_button (GTK_DIALOG (dlg), _("_Close"), "window-close", GTK_RESPONSE_CLOSE);
1231 	pluma_dialog_add_button (GTK_DIALOG (dlg), _("_Help"), "help-browser", GTK_RESPONSE_HELP);
1232 
1233 	gtk_window_set_title (GTK_WINDOW (dlg), _("Pluma Preferences"));
1234 	gtk_window_set_resizable (GTK_WINDOW (dlg), FALSE);
1235 	gtk_window_set_destroy_with_parent (GTK_WINDOW (dlg), TRUE);
1236 
1237 	/* HIG defaults */
1238 	gtk_container_set_border_width (GTK_CONTAINER (dlg), 5);
1239 	gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))), 2); /* 2 * 5 + 2 = 12 */
1240 
1241 	g_signal_connect (dlg,
1242 			  "response",
1243 			  G_CALLBACK (dialog_response_handler),
1244 			  NULL);
1245 
1246 	ret = pluma_utils_get_ui_objects (PLUMA_DATADIR "/ui/pluma-preferences-dialog.ui",
1247 		root_objects,
1248 		&error_widget,
1249 
1250 		"notebook", &dlg->priv->notebook,
1251 
1252 		"display_line_numbers_checkbutton", &dlg->priv->display_line_numbers_checkbutton,
1253 		"highlight_current_line_checkbutton", &dlg->priv->highlight_current_line_checkbutton,
1254 		"bracket_matching_checkbutton", &dlg->priv->bracket_matching_checkbutton,
1255 		"display_overview_map_checkbutton", &dlg->priv->display_overview_map_checkbutton,
1256 		"display_grid_checkbutton", &dlg->priv->display_grid_checkbutton,
1257 		"wrap_text_checkbutton", &dlg->priv->wrap_text_checkbutton,
1258 		"split_checkbutton", &dlg->priv->split_checkbutton,
1259 
1260 		"right_margin_checkbutton", &dlg->priv->right_margin_checkbutton,
1261 		"right_margin_position_spinbutton", &dlg->priv->right_margin_position_spinbutton,
1262 
1263 		"tabs_width_spinbutton", &dlg->priv->tabs_width_spinbutton,
1264 		"tabs_width_hbox", &dlg->priv->tabs_width_hbox,
1265 		"insert_spaces_checkbutton", &dlg->priv->insert_spaces_checkbutton,
1266 
1267 		"auto_indent_checkbutton", &dlg->priv->auto_indent_checkbutton,
1268 
1269 		"draw_spaces_checkbutton", &dlg->priv->draw_spaces_checkbutton,
1270 		"draw_trailing_spaces_checkbutton", &dlg->priv->draw_trailing_spaces_checkbutton,
1271 		"draw_tabs_checkbutton", &dlg->priv->draw_tabs_checkbutton,
1272 		"draw_trailing_tabs_checkbutton", &dlg->priv->draw_trailing_tabs_checkbutton,
1273 		"draw_newlines_checkbutton", &dlg->priv->draw_newlines_checkbutton,
1274 
1275 		"backup_copy_checkbutton", &dlg->priv->backup_copy_checkbutton,
1276 		"auto_save_checkbutton", &dlg->priv->auto_save_checkbutton,
1277 		"auto_save_spinbutton", &dlg->priv->auto_save_spinbutton,
1278 
1279 		"default_font_checkbutton", &dlg->priv->default_font_checkbutton,
1280 		"font_button", &dlg->priv->font_button,
1281 		"font_hbox", &dlg->priv->font_hbox,
1282 
1283 		"schemes_treeview", &dlg->priv->schemes_treeview,
1284 		"install_scheme_button", &dlg->priv->install_scheme_button,
1285 		"uninstall_scheme_button", &dlg->priv->uninstall_scheme_button,
1286 
1287 		"plugin_manager_place_holder", &dlg->priv->plugin_manager_place_holder,
1288 
1289 		NULL);
1290 
1291 	if (!ret)
1292 	{
1293 		gtk_widget_show (error_widget);
1294 
1295 		gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))),
1296 		                    error_widget,
1297 		                    TRUE, TRUE, 0);
1298 
1299 		return;
1300 	}
1301 
1302 	gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dlg))),
1303 			    dlg->priv->notebook, FALSE, FALSE, 0);
1304 	g_object_unref (dlg->priv->notebook);
1305 	gtk_container_set_border_width (GTK_CONTAINER (dlg->priv->notebook), 5);
1306 
1307 	gtk_widget_add_events (dlg->priv->notebook, GDK_SCROLL_MASK);
1308 	g_signal_connect (dlg->priv->notebook,
1309 			  "scroll-event",
1310 			  G_CALLBACK (on_notebook_scroll_event),
1311 			  NULL);
1312 
1313 	setup_editor_page (dlg);
1314 	setup_view_page (dlg);
1315 	setup_font_colors_page (dlg);
1316 	setup_plugins_page (dlg);
1317 }
1318 
1319 void
pluma_show_preferences_dialog(PlumaWindow * parent)1320 pluma_show_preferences_dialog (PlumaWindow *parent)
1321 {
1322 	pluma_debug (DEBUG_PREFS);
1323 
1324 	g_return_if_fail (PLUMA_IS_WINDOW (parent));
1325 
1326 	if (preferences_dialog == NULL)
1327 	{
1328 		preferences_dialog = GTK_WIDGET (g_object_new (PLUMA_TYPE_PREFERENCES_DIALOG, NULL));
1329 		g_signal_connect (preferences_dialog,
1330 				  "destroy",
1331 				  G_CALLBACK (gtk_widget_destroyed),
1332 				  &preferences_dialog);
1333 	}
1334 
1335 	if (GTK_WINDOW (parent) != gtk_window_get_transient_for (GTK_WINDOW (preferences_dialog)))
1336 	{
1337 		gtk_window_set_transient_for (GTK_WINDOW (preferences_dialog),
1338 					      GTK_WINDOW (parent));
1339 	}
1340 
1341 	gtk_window_present (GTK_WINDOW (preferences_dialog));
1342 }
1343