1 /*
2  * Osmo - a handy personal organizer
3  *
4  * Copyright (C) 2007-2009 Tomasz Maka <pasp@users.sourceforge.net>
5  *               2007-2009 Piotr Maka <silloz@users.sourceforge.net>
6  *
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.
11  *
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.
16  *
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21 
22 #include "backup.h"
23 #include "calendar_preferences_gui.h"
24 #include "contacts_preferences_gui.h"
25 #include "i18n.h"
26 #include "notes.h"
27 #include "notes_preferences_gui.h"
28 #include "options_prefs.h"
29 #include "preferences_gui.h"
30 #include "stock_icons.h"
31 #include "tasks.h"
32 #include "tasks_preferences_gui.h"
33 #include "utils_gui.h"
34 #include "calendar.h"
35 
36 /* ========================================================================== */
37 
38 static void
show_restart_info(GUI * appGUI)39 show_restart_info(GUI *appGUI)
40 {
41 	utl_gui_create_dialog (GTK_MESSAGE_INFO, _("Osmo has to be restarted to take effect."),
42 	                       GTK_WINDOW (appGUI->opt->window));
43 }
44 
45 /* ========================================================================== */
46 
47 static void
checkbutton_clicked_cb(GtkToggleButton * togglebutton,gint * option)48 checkbutton_clicked_cb (GtkToggleButton *togglebutton, gint *option)
49 {
50 	*option = gtk_toggle_button_get_active (togglebutton);
51 }
52 
53 /* ========================================================================== */
54 
55 static void
layout_changed_cb(GtkComboBox * widget,GUI * appGUI)56 layout_changed_cb (GtkComboBox *widget, GUI *appGUI)
57 {
58 	config.gui_layout = gtk_combo_box_get_active (widget);
59 	show_restart_info (appGUI);
60 }
61 
62 /* ========================================================================== */
63 
64 static void
tabs_position_changed_cb(GtkComboBox * widget,GUI * appGUI)65 tabs_position_changed_cb (GtkComboBox *widget, GUI *appGUI)
66 {
67 	GtkWidget *label;
68 	gint angle;
69 
70 	config.tabs_position = gtk_combo_box_get_active (widget);
71 	gtk_notebook_set_tab_pos (GTK_NOTEBOOK (appGUI->notebook), config.tabs_position);
72 
73 	if (config.tabs_position == GTK_POS_LEFT) angle = 90;
74 	else if (config.tabs_position == GTK_POS_RIGHT) angle = -90;
75 	else angle = 0;
76 
77 	label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (appGUI->notebook), GTK_WIDGET (appGUI->cal->vbox));
78 	gtk_label_set_angle (GTK_LABEL (label), angle);
79 
80 #ifdef TASKS_ENABLED
81 	label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (appGUI->notebook), GTK_WIDGET (appGUI->tsk->vbox));
82 	gtk_label_set_angle (GTK_LABEL (label), angle);
83 #endif /* TASKS_ENABLED */
84 
85 #ifdef CONTACTS_ENABLED
86 	label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (appGUI->notebook), GTK_WIDGET (appGUI->cnt->vbox));
87 	gtk_label_set_angle (GTK_LABEL (label), angle);
88 #endif /* CONTACTS_ENABLED */
89 
90 #ifdef NOTES_ENABLED
91 	label = gtk_notebook_get_tab_label (GTK_NOTEBOOK (appGUI->notebook), GTK_WIDGET (appGUI->nte->vbox));
92 	gtk_label_set_angle (GTK_LABEL (label), angle);
93 #endif /* NOTES_ENABLED */
94 }
95 
96 /* ========================================================================== */
97 
98 static void
disable_underline_in_links_changed_cb(GtkToggleButton * togglebutton,GUI * appGUI)99 disable_underline_in_links_changed_cb (GtkToggleButton *togglebutton, GUI *appGUI)
100 {
101 	config.disable_underline_links = gtk_toggle_button_get_active (togglebutton);
102 
103 #ifdef CONTACTS_ENABLED
104 	g_signal_emit_by_name (G_OBJECT (appGUI->cnt->contacts_list_selection), "changed");
105 #endif /* CONTACTS_ENABLED */
106 }
107 
108 /* ========================================================================== */
109 
110 static void
toolbar_exit_button_changed_cb(GtkToggleButton * togglebutton,GUI * appGUI)111 toolbar_exit_button_changed_cb (GtkToggleButton *togglebutton, GUI *appGUI)
112 {
113 	config.toolbar_exit_button = gtk_toggle_button_get_active (togglebutton);
114 
115 	if (config.toolbar_exit_button == TRUE) {
116 		gtk_widget_show (GTK_WIDGET(appGUI->cal->quit_button));
117 	} else {
118 		gtk_widget_hide (GTK_WIDGET(appGUI->cal->quit_button));
119 	}
120 
121 #ifdef CONTACTS_ENABLED
122 	if (config.toolbar_exit_button == TRUE) {
123 		gtk_widget_show (GTK_WIDGET(appGUI->cnt->quit_toolbar_button));
124 	} else {
125 		gtk_widget_hide (GTK_WIDGET(appGUI->cnt->quit_toolbar_button));
126 	}
127 #endif /* CONTACTS_ENABLED */
128 
129 #ifdef NOTES_ENABLED
130 	if (config.toolbar_exit_button == TRUE) {
131 		gtk_widget_show (GTK_WIDGET(appGUI->nte->quit_button));
132 	} else {
133 		gtk_widget_hide (GTK_WIDGET(appGUI->nte->quit_button));
134 	}
135 #endif /* NOTES_ENABLED */
136 
137 #ifdef TASKS_ENABLED
138 	if (config.toolbar_exit_button == TRUE) {
139 		gtk_widget_show (GTK_WIDGET(appGUI->tsk->quit_button));
140 	} else {
141 		gtk_widget_hide (GTK_WIDGET(appGUI->tsk->quit_button));
142 	}
143 #endif /* TASKS_ENABLED */
144 
145 }
146 
147 /* ========================================================================== */
148 
149 static void
create_appearance_section(GtkWidget * appearance_vbox,GUI * appGUI)150 create_appearance_section (GtkWidget *appearance_vbox, GUI *appGUI)
151 {
152 	GtkWidget *table, *label, *combobox, *checkbutton;
153 
154 	table = gtk_grid_new ();
155 	gtk_box_pack_start (GTK_BOX (appearance_vbox), table, FALSE, TRUE, 0);
156 	gtk_grid_set_column_spacing (GTK_GRID (table), 32);
157 	gtk_grid_set_row_spacing (GTK_GRID (table), 8);
158 
159 	label = utl_gui_create_label ("%s:", _("Layout"));
160 	gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1);
161 
162 	combobox = gtk_combo_box_text_new ();
163 	gtk_grid_attach (GTK_GRID (table), combobox, 1, 0, 1, 1);
164 	gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combobox), NULL, _("Vertical"));
165 	gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combobox), NULL, _("Horizontal"));
166 	gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), config.gui_layout);
167 	g_signal_connect (G_OBJECT (combobox), "changed", G_CALLBACK (layout_changed_cb), appGUI);
168 
169 	label = utl_gui_create_label ("%s:", _("Tabs position"));
170 	gtk_grid_attach (GTK_GRID (table), label, 2, 0, 1, 1);
171 
172 	combobox = gtk_combo_box_text_new ();
173 	gtk_grid_attach (GTK_GRID (table), combobox, 3, 0, 1, 1);
174 	gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combobox), NULL, _("Left"));
175 	gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combobox), NULL, _("Right"));
176 	gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combobox), NULL, _("Top"));
177 	gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combobox), NULL, _("Bottom"));
178 	gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), config.tabs_position);
179 	g_signal_connect (G_OBJECT (combobox), "changed", G_CALLBACK (tabs_position_changed_cb), appGUI);
180 
181 	checkbutton = gtk_check_button_new_with_mnemonic (_("Disable underline in links"));
182 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton), config.disable_underline_links);
183 	gtk_grid_attach (GTK_GRID (table), checkbutton, 0, 1, 2, 1);
184 	g_signal_connect (G_OBJECT (checkbutton), "toggled", G_CALLBACK (disable_underline_in_links_changed_cb), appGUI);
185 
186 	checkbutton = gtk_check_button_new_with_mnemonic (_("Show exit button in toolbar"));
187 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton), config.toolbar_exit_button);
188 	gtk_grid_attach (GTK_GRID (table), checkbutton, 2, 1, 2, 1);
189 	g_signal_connect (G_OBJECT (checkbutton), "toggled", G_CALLBACK (toolbar_exit_button_changed_cb), appGUI);
190 }
191 
192 /* ========================================================================== */
193 
194 #if defined(TASKS_ENABLED) || defined(CONTACTS_ENABLED) || defined(NOTES_ENABLED)
195 
196 static void
hide_module_cb(GtkToggleButton * togglebutton,GUI * appGUI)197 hide_module_cb (GtkToggleButton *togglebutton, GUI *appGUI)
198 {
199 	gboolean cal, tsk, nte, cnt;
200 
201 	cal = tsk = nte = cnt = TRUE;
202 
203 	cal = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (appGUI->opt->hide_calendar_checkbutton));
204 
205 #ifdef TASKS_ENABLED
206 	tsk = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (appGUI->opt->hide_tasks_checkbutton));
207 #endif /* TASKS_ENABLED */
208 
209 #ifdef NOTES_ENABLED
210 	nte = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (appGUI->opt->hide_notes_checkbutton));
211 #endif /* NOTES_ENABLED */
212 
213 #ifdef CONTACTS_ENABLED
214 	cnt = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (appGUI->opt->hide_contacts_checkbutton));
215 #endif /* CONTACTS_ENABLED */
216 
217 	if (cal && tsk && nte && cnt) {
218 		utl_gui_create_dialog (GTK_MESSAGE_ERROR, _("At least one module must be visible."),
219 		                       GTK_WINDOW (appGUI->opt->window));
220 		cal = FALSE;
221 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (appGUI->opt->hide_calendar_checkbutton), FALSE);
222 	}
223 
224 	opt_hide_modules (cal, tsk, cnt, nte, TRUE, appGUI);
225 }
226 
227 void
opt_hide_modules(gboolean cal,gboolean tsk,gboolean cnt,gboolean nte,gboolean options,GUI * appGUI)228 opt_hide_modules (gboolean cal, gboolean tsk, gboolean cnt, gboolean nte, gboolean options, GUI *appGUI)
229 {
230 	if (cal && tsk && nte && cnt) {
231 		cal = FALSE;
232 	}
233 
234 	if (cal) {
235 		config.hide_calendar = TRUE;
236 		gtk_widget_hide (GTK_WIDGET (appGUI->cal->vbox));
237 		if (options) gtk_widget_hide (appGUI->opt->calendar);
238 		gtk_widget_hide (appGUI->trayicon_menu_calendar_item);
239 	} else {
240 		config.hide_calendar = FALSE;
241 		gtk_widget_show (GTK_WIDGET (appGUI->cal->vbox));
242 		if (options) gtk_widget_show (appGUI->opt->calendar);
243 		gtk_widget_show (appGUI->trayicon_menu_calendar_item);
244 	}
245 
246 #ifdef TASKS_ENABLED
247 	if (tsk) {
248 		config.hide_tasks = TRUE;
249 		gtk_widget_hide(GTK_WIDGET (appGUI->tsk->vbox));
250 		if (options) gtk_widget_hide (appGUI->opt->tasks);
251 		gtk_widget_hide (appGUI->trayicon_menu_tasks_item);
252 	} else {
253 		config.hide_tasks = FALSE;
254 		gtk_widget_show (GTK_WIDGET (appGUI->tsk->vbox));
255 		if (options) gtk_widget_show (appGUI->opt->tasks);
256 		gtk_widget_show (appGUI->trayicon_menu_tasks_item);
257 	}
258 #endif /* TASKS_ENABLED */
259 
260 #ifdef CONTACTS_ENABLED
261 	if (cnt) {
262 		config.hide_contacts = TRUE;
263 		gtk_widget_hide (GTK_WIDGET (appGUI->cnt->vbox));
264 		if (options) gtk_widget_hide (appGUI->opt->contacts);
265 		gtk_widget_hide (appGUI->trayicon_menu_contacts_item);
266 	} else {
267 		config.hide_contacts = FALSE;
268 		gtk_widget_show (GTK_WIDGET (appGUI->cnt->vbox));
269 		if (options) gtk_widget_show (appGUI->opt->contacts);
270 		gtk_widget_show (appGUI->trayicon_menu_contacts_item);
271 	}
272 #endif /* CONTACTS_ENABLED */
273 
274 #ifdef NOTES_ENABLED
275 	if (nte) {
276 		config.hide_notes = TRUE;
277 		gtk_widget_hide (GTK_WIDGET (appGUI->nte->vbox));
278 		if (options) gtk_widget_hide (appGUI->opt->notes);
279 		gtk_widget_hide (appGUI->trayicon_menu_notes_item);
280 	} else {
281 		config.hide_notes = FALSE;
282 		gtk_widget_show (GTK_WIDGET (appGUI->nte->vbox));
283 		if (options) gtk_widget_show (appGUI->opt->notes);
284 		gtk_widget_show (appGUI->trayicon_menu_notes_item);
285 	}
286 #endif /* NOTES_ENABLED */
287 }
288 
289 /* ========================================================================== */
290 
291 static void
create_hide_section(GtkWidget * hide_vbox,GUI * appGUI)292 create_hide_section (GtkWidget *hide_vbox, GUI *appGUI)
293 {
294 	GtkWidget *table, *checkbutton;
295 
296 	table = gtk_grid_new ();
297 	gtk_box_pack_start (GTK_BOX (hide_vbox), table, TRUE, TRUE, 0);
298 	gtk_grid_set_column_spacing (GTK_GRID (table), 16);
299 
300 	checkbutton = gtk_check_button_new_with_mnemonic (_("Calendar"));
301 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton), config.hide_calendar);
302         gtk_widget_set_hexpand(checkbutton, TRUE);
303 	gtk_grid_attach (GTK_GRID (table), checkbutton, 0, 0, 1, 1);
304 	g_signal_connect (G_OBJECT (checkbutton), "toggled", G_CALLBACK (hide_module_cb), appGUI);
305 	appGUI->opt->hide_calendar_checkbutton = checkbutton;
306 
307 #ifdef TASKS_ENABLED
308 	checkbutton = gtk_check_button_new_with_mnemonic (_("Tasks"));
309 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton), config.hide_tasks);
310         gtk_widget_set_hexpand(checkbutton, TRUE);
311 	gtk_grid_attach (GTK_GRID (table), checkbutton, 1, 0, 1, 1);
312 	g_signal_connect (G_OBJECT (checkbutton), "toggled", G_CALLBACK (hide_module_cb), appGUI);
313 	appGUI->opt->hide_tasks_checkbutton = checkbutton;
314 #endif /* TASKS_ENABLED */
315 
316 #ifdef CONTACTS_ENABLED
317 	checkbutton = gtk_check_button_new_with_mnemonic (_("Contacts"));
318 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton), config.hide_contacts);
319         gtk_widget_set_hexpand(checkbutton, TRUE);
320 	gtk_grid_attach (GTK_GRID (table), checkbutton, 2, 0, 1, 1);
321 	g_signal_connect (G_OBJECT (checkbutton), "toggled", G_CALLBACK (hide_module_cb), appGUI);
322 	appGUI->opt->hide_contacts_checkbutton = checkbutton;
323 #endif /* CONTACTS_ENABLED */
324 
325 #ifdef NOTES_ENABLED
326 	checkbutton = gtk_check_button_new_with_mnemonic (_("Notes"));
327 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton), config.hide_notes);
328         gtk_widget_set_hexpand(checkbutton, TRUE);
329 	gtk_grid_attach (GTK_GRID (table), checkbutton, 3, 0, 1, 1);
330 	g_signal_connect (G_OBJECT (checkbutton), "toggled", G_CALLBACK (hide_module_cb), appGUI);
331 	appGUI->opt->hide_notes_checkbutton = checkbutton;
332 #endif /* NOTES_ENABLED */
333 
334 }
335 
336 #endif /* defined(TASKS_ENABLED) || defined(CONTACTS_ENABLED) || defined(NOTES_ENABLED) */
337 
338 /* ========================================================================== */
339 
340 static void
override_locale_changed_cb(GtkToggleButton * togglebutton,GUI * appGUI)341 override_locale_changed_cb (GtkToggleButton *togglebutton, GUI *appGUI)
342 {
343 	config.override_locale_settings = gtk_toggle_button_get_active (togglebutton);
344 
345 	gtk_widget_set_sensitive (appGUI->opt->override_locale_label_1, config.override_locale_settings);
346 	gtk_widget_set_sensitive (appGUI->opt->override_locale_label_2, config.override_locale_settings);
347 	gtk_widget_set_sensitive (appGUI->opt->date_format_combobox, config.override_locale_settings);
348 	gtk_widget_set_sensitive (appGUI->opt->time_format_combobox, config.override_locale_settings);
349 
350 #ifdef HAVE_GSPELL
351 	gtk_widget_set_sensitive (appGUI->opt->override_locale_label_3, config.override_locale_settings);
352 	gtk_widget_set_sensitive (appGUI->opt->entry_spell_lang, config.override_locale_settings);
353 #endif  /* HAVE_GSPELL */
354 
355 #ifdef TASKS_ENABLED
356 	refresh_tasks (appGUI);
357 #endif  /* TASKS_ENABLED */
358 
359 #ifdef NOTES_ENABLED
360 	refresh_notes (appGUI);
361 #endif  /* NOTES_ENABLED */
362 }
363 
364 /* ========================================================================== */
365 
366 static void
date_format_changed_cb(GtkComboBox * widget,GUI * appGUI)367 date_format_changed_cb (GtkComboBox *widget, GUI *appGUI)
368 {
369 	config.date_format = gtk_combo_box_get_active (widget);
370 
371 #ifdef NOTES_ENABLED
372 	refresh_notes (appGUI);
373 #endif  /* NOTES_NOTES */
374 
375 #ifdef TASKS_ENABLED
376 	refresh_tasks (appGUI);
377 #endif  /* TASKS_ENABLED */
378 }
379 
380 /* ========================================================================== */
381 
382 static void
time_format_changed_cb(GtkComboBox * widget,GUI * appGUI)383 time_format_changed_cb (GtkComboBox *widget, GUI *appGUI)
384 {
385 	config.time_format = gtk_combo_box_get_active (widget);
386 	update_clock (appGUI);
387 
388 #ifdef NOTES_ENABLED
389 	refresh_notes (appGUI);
390 #endif  /* NOTES_NOTES */
391 
392 #ifdef TASKS_ENABLED
393 	refresh_tasks (appGUI);
394 #endif  /* TASKS_ENABLED */
395 }
396 
397 /* ========================================================================== */
398 
399 #ifdef HAVE_GSPELL
400 
401 static void
spell_checker_entry_changed_cb(GtkEntry * entry,GUI * appGUI)402 spell_checker_entry_changed_cb (GtkEntry *entry, GUI *appGUI)
403 {
404 	if (strlen (gtk_entry_get_text (entry)))
405 		g_strlcpy (config.spell_lang, gtk_entry_get_text (entry), MAXNAME);
406 
407 	utl_gui_change_bg_widget_state (GTK_WIDGET (entry), NULL, appGUI);
408 }
409 
410 /* ========================================================================== */
411 
412 static gint
spell_checker_key_press_cb(GtkWidget * widget,GdkEventKey * event,GUI * appGUI)413 spell_checker_key_press_cb (GtkWidget *widget, GdkEventKey *event, GUI *appGUI)
414 {
415 	utl_gui_change_bg_widget_state (widget, COLOR_BG_OK, appGUI);
416 	return FALSE;
417 }
418 
419 #endif  /* HAVE_GSPELL */
420 
421 /* ========================================================================== */
422 
423 static void
create_general_section(GtkWidget * general_vbox,GUI * appGUI)424 create_general_section (GtkWidget *general_vbox, GUI *appGUI)
425 {
426 	GtkWidget *table, *checkbutton, *combobox;
427 	gchar *str;
428 	gint i = 0;
429 
430 	table = gtk_grid_new ();
431 	gtk_box_pack_start (GTK_BOX (general_vbox), table, FALSE, FALSE, 0);
432 	gtk_grid_set_column_spacing (GTK_GRID (table), 16);
433 	gtk_grid_set_row_spacing (GTK_GRID (table), 4);
434 
435 	checkbutton = gtk_check_button_new_with_mnemonic (_("Override locale settings"));
436 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton), config.override_locale_settings);
437 	gtk_grid_attach (GTK_GRID (table), checkbutton, 0, i, 4, 1);
438 	g_signal_connect (G_OBJECT (checkbutton), "toggled", G_CALLBACK (override_locale_changed_cb), appGUI);
439 	appGUI->opt->override_locale_checkbutton = checkbutton;
440 
441 	i++;
442 
443 	appGUI->opt->override_locale_label_1 = utl_gui_create_label ("%s:", _("Date format"));
444 	gtk_grid_attach (GTK_GRID (table), appGUI->opt->override_locale_label_1, 0, i, 1, 1);
445 
446 	combobox = gtk_combo_box_text_new ();
447 	gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combobox), NULL, _("DD-MM-YYYY"));
448 	gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combobox), NULL, _("MM-DD-YYYY"));
449 	gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combobox), NULL, _("YYYY-MM-DD"));
450 	gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combobox), NULL, _("YYYY-DD-MM"));
451 	gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), config.date_format);
452 	gtk_grid_attach (GTK_GRID (table), combobox, 1, i, 1, 1);
453 	g_signal_connect (G_OBJECT (combobox), "changed", G_CALLBACK (date_format_changed_cb), appGUI);
454 	appGUI->opt->date_format_combobox = combobox;
455 
456 	i++;
457 
458 	appGUI->opt->override_locale_label_2 = utl_gui_create_label ("%s:", _("Time format"));
459 	gtk_grid_attach (GTK_GRID (table), appGUI->opt->override_locale_label_2, 0, i, 1, 1);
460 
461 	combobox = gtk_combo_box_text_new ();
462 	str = g_strdup_printf ("24 %s", _("hours"));
463 	gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combobox), NULL, str);
464 	g_free (str);
465 	str = g_strdup_printf ("12 %s", _("hours"));
466 	gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combobox), NULL, str);
467 	g_free (str);
468 	gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), config.time_format);
469 	gtk_grid_attach (GTK_GRID (table), combobox, 1, i, 1, 1);
470 	g_signal_connect (G_OBJECT (combobox), "changed", G_CALLBACK (time_format_changed_cb), appGUI);
471 	appGUI->opt->time_format_combobox = combobox;
472 
473 	i++;
474 
475 #ifdef HAVE_GSPELL
476 
477 	GtkWidget *entry;
478 
479 	appGUI->opt->override_locale_label_3 = utl_gui_create_label ("%s:", _("Spell checker language"));
480 	gtk_grid_attach (GTK_GRID (table), appGUI->opt->override_locale_label_3, 0, i, 1, 1);
481 
482 	entry = gtk_entry_new ();
483 	gtk_entry_set_max_length (GTK_ENTRY (entry), MAXNAME);
484         gtk_entry_set_text (GTK_ENTRY (entry), config.spell_lang);
485 	gtk_grid_attach (GTK_GRID (table), entry, 1, i, 1, 1);
486 	g_signal_connect (G_OBJECT (entry), "activate", G_CALLBACK (spell_checker_entry_changed_cb), appGUI);
487 	g_signal_connect (G_OBJECT (entry), "key_press_event", G_CALLBACK (spell_checker_key_press_cb), appGUI);
488 	appGUI->opt->entry_spell_lang = entry;
489 
490 	i++;
491 
492 #endif /* HAVE_GSPELL */
493 	/* update the button enablement */
494 	override_locale_changed_cb(GTK_TOGGLE_BUTTON (appGUI->opt->override_locale_checkbutton), appGUI);
495 
496 	checkbutton = gtk_check_button_new_with_mnemonic (_("Enable tooltips"));
497 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton), config.enable_tooltips);
498 	gtk_grid_attach (GTK_GRID (table), checkbutton, 0, i, 4, 1);
499 	g_signal_connect (G_OBJECT (checkbutton), "toggled", G_CALLBACK (checkbutton_clicked_cb), &(config.enable_tooltips));
500 
501 	i++;
502 
503 	checkbutton = gtk_check_button_new_with_mnemonic (_("Remember last selected page"));
504 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton), config.remember_latest_tab);
505 	gtk_grid_attach (GTK_GRID (table), checkbutton, 0, i, 4, 1);
506 	g_signal_connect (G_OBJECT (checkbutton), "toggled", G_CALLBACK (checkbutton_clicked_cb), &(config.remember_latest_tab));
507 
508 	i++;
509 
510 	checkbutton = gtk_check_button_new_with_mnemonic (_("Save data after every modification"));
511 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton), config.save_data_after_modification);
512 	gtk_grid_attach (GTK_GRID (table), checkbutton, 0, i, 4, 1);
513 	g_signal_connect (G_OBJECT (checkbutton), "toggled", G_CALLBACK (checkbutton_clicked_cb), &(config.save_data_after_modification));
514 
515 }
516 
517 /* ========================================================================== */
518 
519 static void
helper_entry_changed_cb(GtkEntry * entry,GUI * appGUI)520 helper_entry_changed_cb (GtkEntry *entry, GUI *appGUI)
521 {
522 	if (strlen (gtk_entry_get_text (GTK_ENTRY (appGUI->opt->entry_web_browser))))
523 		g_strlcpy (config.web_browser, gtk_entry_get_text (GTK_ENTRY (appGUI->opt->entry_web_browser)), MAXHELPERCMD);
524 
525 	if (strlen (gtk_entry_get_text (GTK_ENTRY (appGUI->opt->entry_email_client))))
526 		g_strlcpy (config.email_client, gtk_entry_get_text (GTK_ENTRY (appGUI->opt->entry_email_client)), MAXHELPERCMD);
527 
528 	if (strlen (gtk_entry_get_text (GTK_ENTRY (appGUI->opt->entry_sound_player))))
529 		g_strlcpy (config.sound_player, gtk_entry_get_text (GTK_ENTRY (appGUI->opt->entry_sound_player)), MAXHELPERCMD);
530 
531 	utl_gui_change_bg_widget_state (appGUI->opt->entry_web_browser, NULL, appGUI);
532 	utl_gui_change_bg_widget_state (appGUI->opt->entry_email_client, NULL, appGUI);
533 	utl_gui_change_bg_widget_state (appGUI->opt->entry_sound_player, NULL, appGUI);
534 }
535 
536 /* ========================================================================== */
537 
538 static gint
helper_key_press_cb(GtkWidget * widget,GdkEventKey * event,GUI * appGUI)539 helper_key_press_cb (GtkWidget *widget, GdkEventKey *event, GUI *appGUI)
540 {
541     utl_gui_change_bg_widget_state (widget, COLOR_BG_OK, appGUI);
542     return FALSE;
543 }
544 
545 /* ========================================================================== */
546 
547 void
create_helpers_section(GtkWidget * helpers_vbox,GUI * appGUI)548 create_helpers_section (GtkWidget *helpers_vbox, GUI *appGUI)
549 {
550 	GtkWidget *table, *label, *entry;
551 
552 	table = gtk_grid_new ();
553 	gtk_box_pack_start (GTK_BOX (helpers_vbox), table, FALSE, FALSE, 0);
554 	gtk_grid_set_row_spacing (GTK_GRID (table), 8);
555 	gtk_grid_set_column_spacing (GTK_GRID (table), 8);
556 
557 	label = utl_gui_create_label ("%s:", _("Web browser"));
558 	gtk_grid_attach (GTK_GRID (table), label, 0, 0, 1, 1);
559         gtk_widget_set_valign(label, GTK_ALIGN_START);
560         gtk_widget_set_halign(label, GTK_ALIGN_CENTER);
561 
562 	label = utl_gui_create_label ("%s:", _("E-mail client"));
563 	gtk_grid_attach (GTK_GRID (table), label, 0, 1, 1, 1);
564 
565 	label = utl_gui_create_label ("%s:", _("Sound player"));
566 	gtk_grid_attach (GTK_GRID (table), label, 0, 2, 1, 1);
567 
568 	entry = gtk_entry_new ();
569 	gtk_entry_set_max_length (GTK_ENTRY (entry), MAXHELPERCMD);
570 	gtk_entry_set_text (GTK_ENTRY (entry), config.web_browser);
571 	if (config.enable_tooltips) {
572 		gtk_widget_set_tooltip_text (entry, _("The %s pattern will be replaced with web address"));
573 	}
574         gtk_widget_set_hexpand(entry, TRUE);
575 	gtk_grid_attach (GTK_GRID (table), entry, 1, 0, 1, 1);
576 	g_signal_connect (G_OBJECT (entry), "activate", G_CALLBACK (helper_entry_changed_cb), appGUI);
577 	g_signal_connect (G_OBJECT (entry), "key_press_event", G_CALLBACK (helper_key_press_cb), appGUI);
578 	appGUI->opt->entry_web_browser = entry;
579 
580 	entry = gtk_entry_new ();
581 	gtk_entry_set_max_length (GTK_ENTRY (entry), MAXHELPERCMD);
582 	gtk_entry_set_text (GTK_ENTRY (entry), config.email_client);
583 	if (config.enable_tooltips)
584 		gtk_widget_set_tooltip_text (entry, _("The %s pattern will be replaced with e-mail address"));
585         gtk_widget_set_hexpand(entry, TRUE);
586 	gtk_grid_attach (GTK_GRID (table), entry, 1, 1, 1, 1);
587 	g_signal_connect (G_OBJECT (entry), "activate", G_CALLBACK (helper_entry_changed_cb), appGUI);
588 	g_signal_connect (G_OBJECT (entry), "key_press_event", G_CALLBACK (helper_key_press_cb), appGUI);
589 	appGUI->opt->entry_email_client = entry;
590 
591 	entry = gtk_entry_new ();
592 	gtk_entry_set_max_length (GTK_ENTRY (entry), MAXHELPERCMD);
593 	gtk_entry_set_text (GTK_ENTRY (entry), config.sound_player);
594 	if (config.enable_tooltips)
595 		gtk_widget_set_tooltip_text (entry, _("The %s pattern will be replaced with sound filename"));
596         gtk_widget_set_hexpand(entry, TRUE);
597 	gtk_grid_attach (GTK_GRID (table), entry, 1, 2, 1, 1);
598 	g_signal_connect (G_OBJECT (entry), "activate", G_CALLBACK (helper_entry_changed_cb), appGUI);
599 	g_signal_connect (G_OBJECT (entry), "key_press_event", G_CALLBACK (helper_key_press_cb), appGUI);
600 	appGUI->opt->entry_sound_player = entry;
601 }
602 
603 /* ========================================================================== */
604 
605 static void
enable_systray_changed_cb(GtkToggleButton * togglebutton,GUI * appGUI)606 enable_systray_changed_cb (GtkToggleButton *togglebutton, GUI *appGUI)
607 {
608 	if (gtk_toggle_button_get_active (togglebutton)) {
609 		config.enable_systray = 1;
610 		gtk_widget_set_sensitive (appGUI->opt->start_minimised_checkbutton, TRUE);
611 		gtk_widget_set_sensitive (appGUI->opt->ignore_day_note_events_checkbutton, TRUE);
612 		gtk_status_icon_set_visible (appGUI->osmo_trayicon, TRUE);
613 	} else {
614 		config.enable_systray = 0;
615 		gtk_widget_set_sensitive (appGUI->opt->start_minimised_checkbutton, FALSE);
616 		gtk_widget_set_sensitive (appGUI->opt->ignore_day_note_events_checkbutton, FALSE);
617 		gtk_status_icon_set_visible (appGUI->osmo_trayicon, FALSE);
618 	}
619 }
620 
621 /* ========================================================================== */
622 
623 void
create_system_tray_section(GtkWidget * system_tray_vbox,GUI * appGUI)624 create_system_tray_section (GtkWidget *system_tray_vbox, GUI *appGUI)
625 {
626 	GtkWidget *table, *checkbutton;
627 
628 	table = gtk_grid_new ();
629 	gtk_widget_show (table);
630 	gtk_box_pack_start (GTK_BOX (system_tray_vbox), table, FALSE, FALSE, 0);
631 	gtk_grid_set_column_spacing (GTK_GRID (table), 4);
632 	gtk_grid_set_row_spacing (GTK_GRID (table), 4);
633 
634 	checkbutton = gtk_check_button_new_with_mnemonic (_("Enable system tray"));
635 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton), config.enable_systray);
636 	gtk_grid_attach (GTK_GRID (table), checkbutton, 0, 0, 1, 1);
637 	g_signal_connect (G_OBJECT (checkbutton), "toggled", G_CALLBACK (enable_systray_changed_cb), appGUI);
638 	appGUI->opt->enable_systray_checkbutton = checkbutton;
639 
640 	checkbutton = gtk_check_button_new_with_mnemonic (_("Start minimised"));
641 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton), config.start_minimised_in_systray);
642 	gtk_widget_set_sensitive (checkbutton, config.enable_systray);
643 	gtk_grid_attach (GTK_GRID (table), checkbutton, 1, 0, 1, 1);
644 	g_signal_connect (G_OBJECT (checkbutton), "toggled", G_CALLBACK (checkbutton_clicked_cb), &(config.start_minimised_in_systray));
645 	appGUI->opt->start_minimised_checkbutton = checkbutton;
646 
647 	checkbutton = gtk_check_button_new_with_mnemonic (_("Ignore day note events"));
648 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton), config.ignore_day_note_events);
649 	gtk_widget_set_sensitive (checkbutton, config.enable_systray);
650 	gtk_grid_attach (GTK_GRID (table), checkbutton, 2, 0, 1, 1);
651 	g_signal_connect (G_OBJECT (checkbutton), "toggled", G_CALLBACK (checkbutton_clicked_cb), &(config.ignore_day_note_events));
652 	appGUI->opt->ignore_day_note_events_checkbutton = checkbutton;
653 }
654 
655 /* ========================================================================== */
656 
657 static GtkWidget *
create_general_page(GtkWidget * notebook,GUI * appGUI)658 create_general_page (GtkWidget *notebook, GUI *appGUI)
659 {
660 	GtkWidget *vbox_top, *vbox_icon, *vbox, *scrolledwindow;
661 
662 	vbox_top = gtk_box_new (GTK_ORIENTATION_VERTICAL, VBOX_SPACING);
663 	gtk_container_set_border_width (GTK_CONTAINER (vbox_top), BORDER_WIDTH);
664 	scrolledwindow = utl_gui_insert_in_scrolled_window (vbox_top, GTK_SHADOW_ETCHED_IN);
665 	gtk_container_set_border_width (GTK_CONTAINER (scrolledwindow), 2);
666 	vbox_icon = utl_gui_create_icon_with_label (OSMO_STOCK_PREFERENCES, _("General"));
667 
668 	vbox = utl_gui_create_vbox_in_frame (vbox_top, _("Appearance"));
669 	create_appearance_section (vbox, appGUI);
670 
671 #if defined(TASKS_ENABLED) || defined(CONTACTS_ENABLED) || defined(NOTES_ENABLED)
672 	vbox = utl_gui_create_vbox_in_frame (vbox_top, _("Hide"));
673 	create_hide_section (vbox, appGUI);
674 #endif /* defined(TASKS_ENABLED) || defined(CONTACTS_ENABLED) || defined(NOTES_ENABLED) */
675 
676 	vbox = utl_gui_create_vbox_in_frame (vbox_top, _("General"));
677 	create_general_section (vbox, appGUI);
678 
679 	vbox = utl_gui_create_vbox_in_frame (vbox_top, _("Helpers"));
680 	create_helpers_section (vbox, appGUI);
681 
682 	vbox = utl_gui_create_vbox_in_frame (vbox_top, _("System tray"));
683 	create_system_tray_section (vbox, appGUI);
684 
685 	gtk_notebook_append_page (GTK_NOTEBOOK (notebook), scrolledwindow, vbox_icon);
686 	gtk_widget_show_all (scrolledwindow);
687 
688 	return scrolledwindow;
689 }
690 
691 /* ========================================================================== */
692 
693 static void
close_window(GtkWidget * widget,GtkWidget * window)694 close_window (GtkWidget *widget, GtkWidget *window)
695 {
696 	gtk_widget_destroy (window);
697 }
698 
699 /* ========================================================================== */
700 
701 static gint
key_press(GtkWidget * widget,GdkEventKey * event,GUI * appGUI)702 key_press (GtkWidget *widget, GdkEventKey *event, GUI *appGUI)
703 {
704 	switch (event->keyval) {
705 		case GDK_KEY_Escape:
706 			close_window (NULL, widget);
707 			return TRUE;
708 	}
709 
710 	return FALSE;
711 }
712 
713 /* ========================================================================== */
714 
715 GtkWidget *
opt_create_preferences_window(GUI * appGUI)716 opt_create_preferences_window (GUI *appGUI)
717 {
718 	GtkWidget *window, *vbox_top;
719 	GtkWidget *notebook;
720 	GtkWidget *hbuttonbox, *close_button;
721 
722 	window = utl_gui_create_window (_("Preferences"), 700, 600, appGUI);
723 	g_signal_connect (G_OBJECT (window), "key_press_event", G_CALLBACK (key_press), appGUI);
724 
725 	vbox_top = gtk_box_new (GTK_ORIENTATION_VERTICAL, VBOX_SPACING);
726 	gtk_container_add (GTK_CONTAINER (window), vbox_top);
727 
728 	appGUI->opt->notebook = notebook = gtk_notebook_new ();
729 	gtk_box_pack_start (GTK_BOX (vbox_top), notebook, TRUE, TRUE, 0);
730 	gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_LEFT);
731 	gtk_widget_show (notebook);
732 
733 	appGUI->opt->general = create_general_page (notebook, appGUI);
734 	appGUI->opt->calendar = cal_create_preferences_page (notebook, appGUI);
735 	if (config.hide_calendar)
736 		gtk_widget_hide (appGUI->opt->calendar);
737 
738 #ifdef TASKS_ENABLED
739 	appGUI->opt->tasks = tsk_create_preferences_page (notebook, appGUI);
740 	if (config.hide_tasks)
741 		gtk_widget_hide (appGUI->opt->tasks);
742 #endif /* TASKS_ENABLED */
743 
744 #ifdef CONTACTS_ENABLED
745 	appGUI->opt->contacts = cnt_create_preferences_page (notebook, appGUI);
746 	if (config.hide_contacts)
747 		gtk_widget_hide (appGUI->opt->contacts);
748 #endif /* CONTACTS_ENABLED */
749 
750 #ifdef NOTES_ENABLED
751 	appGUI->opt->notes = nte_create_preferences_page (notebook, appGUI);
752 	if (config.hide_notes)
753 		gtk_widget_hide (appGUI->opt->notes);
754 #endif /* NOTES_ENABLED */
755 
756 	/* Close button */
757 	hbuttonbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
758 	gtk_box_pack_start (GTK_BOX (vbox_top), hbuttonbox, FALSE, TRUE, 0);
759 	gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox), GTK_BUTTONBOX_END);
760 	gtk_box_set_spacing (GTK_BOX (hbuttonbox), HBOX_SPACING);
761 
762 	close_button = gtk_button_new_with_mnemonic (_("_Close"));
763 	gtk_container_add (GTK_CONTAINER (hbuttonbox), close_button);
764 	gtk_widget_set_can_default (close_button, TRUE);
765 	g_signal_connect (G_OBJECT (close_button), "clicked", G_CALLBACK (close_window), window);
766 	gtk_widget_grab_focus (close_button);
767 	gtk_widget_show_all (hbuttonbox);
768 
769 	gtk_widget_show (vbox_top);
770 
771 	return window;
772 }
773 
774 /* ========================================================================== */
775 
776