1 
2 /*
3  * Osmo - a handy personal organizer
4  *
5  * Copyright (C) 2007 Tomasz Maka <pasp@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 <errno.h>
23 
24 #include "options_prefs.h"
25 #include "i18n.h"
26 #include "utils.h"
27 #include "utils_date.h"
28 #include "contacts.h"
29 #include "contacts_import.h"
30 #include "contacts_export.h"
31 #include "calendar.h"
32 #include "calendar_widget.h"
33 #include "calendar_notes.h"
34 #include "calendar_utils.h"
35 
36 /*------------------------------------------------------------------------------*/
37 static gchar *
build_app_specific_dir(const gchar * basedir)38 build_app_specific_dir(const gchar *basedir) {
39     static gchar result[PATH_MAX];
40     gchar *dirname = g_build_filename(basedir, CONFIG_SUBDIR, NULL);
41     g_strlcpy(result, dirname, PATH_MAX);
42     g_free(dirname);
43     return result;
44 }
45 
46 gchar *
prefs_get_config_dir(GUI * appGUI)47 prefs_get_config_dir(GUI *appGUI) {
48     return (build_app_specific_dir(g_get_user_config_dir()));
49 }
50 
51 gchar *
prefs_get_data_dir(GUI * appGUI)52 prefs_get_data_dir(GUI *appGUI) {
53     return (build_app_specific_dir(g_get_user_data_dir()));
54 }
55 /*------------------------------------------------------------------------------*/
56 
57 static gchar *
get_filename(const gchar * filename,const gchar * basedir)58 get_filename(const gchar *filename, const gchar *basedir) {
59     static gchar result[PATH_MAX];
60     gchar *file, *dir;
61     struct stat st;
62 
63     g_return_val_if_fail(basedir != NULL, NULL);
64     file = g_build_filename(basedir, filename, NULL);
65     dir = g_path_get_dirname(file);
66 
67     if (g_stat(dir, &st) < 0) {
68         gint rc = g_mkdir_with_parents(dir, S_IRUSR | S_IWUSR | S_IXUSR);
69         if (rc) {
70             g_free(dir);
71             g_free(file);
72             return NULL;
73         }
74     }
75 
76     if (g_access(dir, R_OK | W_OK) == -1) {
77         g_free(dir);
78         g_free(file);
79         return NULL;
80     }
81 
82     g_strlcpy(result, file, PATH_MAX);
83     g_free(dir);
84     g_free(file);
85 
86     return result;
87 }
88 
89 gchar *
prefs_get_config_filename(gchar * filename,GUI * appGUI)90 prefs_get_config_filename(gchar *filename, GUI *appGUI) {
91     return get_filename(filename, prefs_get_config_dir(appGUI));
92 }
93 
94 gchar *
prefs_get_data_filename(gchar * filename,GUI * appGUI)95 prefs_get_data_filename(gchar *filename, GUI *appGUI) {
96     return get_filename(filename, prefs_get_data_dir(appGUI));
97 }
98 
99 gchar*
prefs_get_cache_filename(gchar * filename)100 prefs_get_cache_filename(gchar *filename) {
101     return get_filename(filename, build_app_specific_dir(g_get_user_cache_dir()));
102 }
103 
104 gchar*
prefs_get_runtime_filename(gchar * filename,GUI * appGUI)105 prefs_get_runtime_filename(gchar *filename, GUI *appGUI) {
106     return get_filename("lockfile", prefs_get_config_dir(appGUI));
107 }
108 
109 /*------------------------------------------------------------------------------*/
110 
111 void
prefs_set_default_values(void)112 prefs_set_default_values (void) {
113 
114 gint i;
115 
116     /* general */
117     config.window_x = 0;
118     config.window_y = 0;
119     config.window_size_x = 950;
120     config.window_size_y = 560;
121     config.fullscreen = 0;
122     config.enable_tooltips = TRUE;
123     config.latest_tab = 0;      /* calendar */
124     config.tabs_position = GTK_POS_TOP;
125     config.remember_latest_tab = TRUE;
126     config.save_data_after_modification = TRUE;
127     config.disable_underline_links = FALSE;
128     config.toolbar_exit_button = FALSE;
129     config.date_format = DATE_YYYY_MM_DD;
130     config.time_format = TIME_24;
131     config.enable_systray = TRUE;
132     config.start_minimised_in_systray = FALSE;
133     config.ignore_day_note_events = FALSE;
134     config.run_counter = 0;
135     config.lastrun_date = utl_date_get_current_julian ();
136     config.lastrun_time = utl_time_get_current_seconds ();
137     config.hide_calendar = FALSE;
138     config.hide_tasks = FALSE;
139     config.hide_contacts = FALSE;
140     config.hide_notes = FALSE;
141     config.override_locale_settings = FALSE;
142     config.gui_layout = 1;      /* 0 - vertical, 1 - horizontal */
143     config.sound_alarm_repeat = 1;
144 	g_strlcpy (config.link_color, "blue", MAXCOLORNAME);
145     g_strlcpy (config.spell_lang, g_getenv("LANG"), MAXNAME);
146     /* FIXME: DO NOT USE xdg-open AS IT CANNOT OPEN MULTIPLE LINKS AT ONCE */
147 	/*g_strlcpy (config.web_browser, "xdg-open %s", MAXHELPERCMD);*/
148 	g_strlcpy (config.web_browser, "firefox %s", MAXHELPERCMD);
149 	g_strlcpy (config.email_client, "xdg-email %s", MAXHELPERCMD);
150 	/* play command requires SoX */
151 	/*g_strlcpy (config.sound_player, "play %s", MAXHELPERCMD);*/
152 	g_strlcpy (config.sound_player, "aplay %s", MAXHELPERCMD);
153 
154     /* calendar */
155     config.fy_window_size_x = 750;
156     config.fy_window_size_y = 550;
157     config.fy_simple_view = TRUE;
158     config.fy_alternative_view = FALSE;
159     config.cb_window_size_x = 570;
160     config.cb_window_size_y = 680;
161     config.ib_window_size_x = 550;
162     config.ib_window_size_y = 650;
163     config.display_options = GUI_CALENDAR_SHOW_DAY_NAMES | GUI_CALENDAR_NO_MONTH_CHANGE | GUI_CALENDAR_WEEK_START_MONDAY;
164     config.day_notes_visible = FALSE;
165     config.timeline_start = 8*60;
166     config.timeline_end = 15*60;
167     config.timeline_step = 60;
168     config.di_show_current_time = TRUE;
169     config.di_show_current_time_seconds = TRUE;
170     config.di_show_day_number = TRUE;
171     config.di_show_current_day_distance = TRUE;
172     config.di_show_marked_days = TRUE;
173     config.di_show_week_number = TRUE;
174     config.di_show_weekend_days = TRUE;
175     config.di_show_day_category = TRUE;
176     config.di_show_moon_phase = TRUE;
177     config.di_show_notes = TRUE;
178     config.di_show_zodiac_sign = FALSE;
179     config.cursor_type = CURSOR_FRAME;
180     config.frame_cursor_thickness = 2;
181     config.enable_auxilary_calendars = TRUE;
182     config.enable_day_mark = TRUE;
183     config.strikethrough_past_notes = FALSE;
184     config.ascending_sorting_in_day_notes_browser = FALSE;
185     config.auxilary_calendars_state = FALSE;
186     config.day_note_spell_checker = FALSE;
187     g_strlcpy (config.day_note_marker, "\'", MAXNAME);
188     g_strlcpy (config.date_header_format, DEFAULT_DATE_HEADER_FORMAT, MAXNAME);
189     config.event_marker_type = EVENT_MARKER_CIRCLE;
190     config.today_marker_type = TODAY_MARKER_FREEHAND_CIRCLE;
191     config.day_notes_browser_filter = DN_FILTER_CURRENT_MONTH;
192     config.ical_export_pane_pos = 180;
193 	g_strlcpy (config.background_color, "#FFFFFF", MAXCOLORNAME);
194 	g_strlcpy (config.header_bg_color, "#404048", MAXCOLORNAME);
195 	g_strlcpy (config.header_fg_color, "#DDDDDD", MAXCOLORNAME);
196 	g_strlcpy (config.day_color, "#555555", MAXCOLORNAME);
197 	g_strlcpy (config.pf_day_color, "#CCCCCC", MAXCOLORNAME);
198 	g_strlcpy (config.weekend_color, "#880000", MAXCOLORNAME);
199 	g_strlcpy (config.selection_color, "#86ABD9", MAXCOLORNAME);
200 	g_strlcpy (config.mark_color, "#CBE140", MAXCOLORNAME);
201 	g_strlcpy (config.mark_current_day_color, "#E37751", MAXCOLORNAME);
202 	g_strlcpy (config.birthday_mark_color, "#EDD400", MAXCOLORNAME);
203     config.mark_current_day_alpha = 32768;
204     config.selector_alpha = 32768;
205 	g_strlcpy (config.day_name_font, "Sans Bold 20", MAXFONTNAME);
206 	g_strlcpy (config.calendar_font, "Sans 18", MAXFONTNAME);
207 	g_strlcpy (config.notes_font, "Sans 11", MAXFONTNAME);
208 	g_strlcpy (config.cal_print_month_name_font, "Sans Bold 40", MAXFONTNAME);
209 	g_strlcpy (config.cal_print_day_name_font, "Sans Bold 10", MAXFONTNAME);
210 	g_strlcpy (config.cal_print_day_num_font, "Sans Bold 16", MAXFONTNAME);
211 	g_strlcpy (config.cal_print_event_font, "Sans 7", MAXFONTNAME);
212 	config.cal_print_event_length = 256;
213 	config.cal_print_padding = 4;
214 	config.cal_print_page_orientation = PORTRAIT;
215 	config.cal_print_tasks = TRUE;
216 	config.cal_print_birthdays = TRUE;
217 	config.cal_print_namedays = TRUE;
218 	config.cal_print_day_notes = TRUE;
219 	config.cal_print_ical = TRUE;
220 	config.cal_print_disable_background	= FALSE;
221 
222     /* tasks */
223     config.tasks_high_in_bold = TRUE;
224     config.hide_completed = FALSE;
225     config.delete_completed = FALSE;
226     config.add_edit = FALSE;
227     config.remember_category_in_tasks = FALSE;
228     config.current_category_in_tasks = 0;
229     config.tasks_pane_pos = DEFAULT_PANED_SPLIT_POSITION;
230     config.tasks_sorting_order = GTK_SORT_ASCENDING;
231     config.tasks_sorting_column = TA_COLUMN_DUE_DATE;
232     config.tsk_visible_due_date_column = TRUE;
233     config.tsk_visible_type_column = TRUE;
234     config.tsk_visible_priority_column = FALSE;
235     config.tsk_visible_category_column = FALSE;
236     config.tasks_addedit_win_w = 370;
237     config.tasks_addedit_win_h = 440;
238     config.tasks_addedit_win_x = config.window_x+config.window_size_x/2-config.tasks_addedit_win_w/2;
239     config.tasks_addedit_win_y = config.window_y+20;
240     config.postpone_time = 10;
241 	config.tasks_column_idx_0 = 0;
242 	config.tasks_column_idx_0_width = 50;
243 	config.tasks_column_idx_1 = 1;
244 	config.tasks_column_idx_1_width = 50;
245 	config.tasks_column_idx_2 = 2;
246 	config.tasks_column_idx_2_width = 100;
247 	config.tasks_column_idx_3 = 3;
248 	config.tasks_column_idx_3_width = 100;
249 	config.tasks_column_idx_4 = 4;
250 	config.tasks_column_idx_4_width = 100;
251 	config.tasks_column_idx_5 = 5;
252 	config.tasks_column_idx_5_width = 100;
253 	g_strlcpy (config.due_today_color, "#00981E", MAXCOLORNAME);
254 	g_strlcpy (config.due_7days_color, "#0047B7", MAXCOLORNAME);
255 	g_strlcpy (config.past_due_color, "#CB362C", MAXCOLORNAME);
256 	g_strlcpy (config.task_info_font, "Sans 14", MAXFONTNAME);
257 	config.global_notification_command[0] = '\0';
258 
259     /* contacts */
260     config.find_mode = CONTACTS_FF_FIRST_NAME;
261     config.hide_group_column = FALSE;
262     config.maps_provider = 0;
263     config.contacts_pane_pos = DEFAULT_PANED_SPLIT_POSITION;
264     config.photo_width = 80;
265     config.cnt_visible_age_column = TRUE;
266     config.cnt_visible_birthday_date_column = TRUE;
267     config.cnt_visible_zodiac_sign_column = TRUE;
268     config.contacts_sorting_order = GTK_SORT_ASCENDING;
269     config.contacts_sorting_column = COLUMN_GROUP;
270     config.contacts_addedit_win_w = 500;
271     config.contacts_addedit_win_h = 600;
272     config.contacts_addedit_win_x = config.window_x+config.window_size_x/2-config.contacts_addedit_win_w/2;
273     config.contacts_addedit_win_y = config.window_y+20;
274     config.contacts_export_win_w = 500;
275     config.contacts_export_win_h = 400;
276     config.contacts_export_win_x = config.window_x+config.window_size_x/2-config.contacts_export_win_w/2;
277     config.contacts_export_win_y = config.window_y+20;
278     config.contacts_import_win_w = 650;
279     config.contacts_import_win_h = 450;
280     config.contacts_import_win_x = config.window_x+config.window_size_x/2-config.contacts_import_win_w/2;
281     config.contacts_import_win_y = config.window_y+20;
282     config.contacts_import_sel_win_x = config.window_x+60;
283     config.contacts_import_sel_win_y = config.window_y+20;
284     config.contacts_birthdays_win_w = 650;
285     config.contacts_birthdays_win_h = 700;
286 	config.contacts_column_idx_0 = 0;
287 	config.contacts_column_idx_0_width = 150;
288 	config.contacts_column_idx_1 = 1;
289 	config.contacts_column_idx_1_width = 150;
290 	config.contacts_column_idx_2 = 2;
291 	config.contacts_column_idx_2_width = 150;
292 	config.import_type = IMPORT_TYPE_FILE;
293     config.import_interface_type = 0;
294     config.import_bluetooth_channel = 1;
295     config.import_usb_interface = 0;
296     config.import_binary_xml = 0;
297 	config.contact_name_font_size = 18;
298 	config.contact_item_font_size = 11;
299 	g_strlcpy (config.import_bluetooth_address, "00:00:00:00:00:00", MAXADDRESS);
300 	g_strlcpy (config.contact_tag_color, "#228B22", MAXCOLORNAME);
301 	g_strlcpy (config.contact_link_color, "blue", MAXCOLORNAME);
302 
303     config.export_format = EXPORT_TO_CSV;
304 
305     for(i=0; i < CONTACTS_NUM_COLUMNS; i++) {
306         config.export_fields[i] = '-';
307     }
308     config.export_fields[COLUMN_GROUP] = '+';
309     config.export_fields[COLUMN_FIRST_NAME] = '+';
310     config.export_fields[COLUMN_LAST_NAME] = '+';
311     config.export_fields[COLUMN_NICK_NAME] = '+';
312 
313     /* notes */
314     config.notes_enc_algorithm = 1;         /* Serpent */
315     config.notes_enc_hashing = 1;           /* RIPEMD-160 */
316     config.notes_comp_algorithm = 0;        /* ZLib */
317     config.notes_comp_ratio = 3;            /* BEST */
318     config.notes_sorting_order = GTK_SORT_ASCENDING;
319     config.notes_sorting_column = N_COLUMN_NAME;
320     config.nte_visible_type_column = TRUE;
321     config.nte_visible_category_column = TRUE;
322     config.nte_visible_last_changes_column = TRUE;
323     config.nte_visible_created_column = TRUE;
324 	config.notes_column_idx_0 = 0;
325 	config.notes_column_idx_0_width = 50;
326 	config.notes_column_idx_1 = 1;
327 	config.notes_column_idx_1_width = 200;
328 	config.notes_column_idx_2 = 2;
329 	config.notes_column_idx_2_width = 80;
330 	config.notes_column_idx_3 = 3;
331 	config.notes_column_idx_3_width = 150;
332 	config.notes_column_idx_4 = 4;
333 	config.notes_column_idx_4_width = 150;
334     config.remember_category_in_notes = FALSE;
335     config.current_category_in_notes = 0;
336     config.use_system_date_in_notes = FALSE;
337     config.text_separator = '=';
338 	g_strlcpy (config.notes_editor_font, "Sans 11", MAXFONTNAME);
339 }
340 
341 /*------------------------------------------------------------------------------*/
342 
343 void
prefs_read_config(GUI * appGUI)344 prefs_read_config (GUI *appGUI)
345 {
346 gboolean cfg_file;
347 xmlDocPtr doc;
348 xmlNodePtr node, general_node, calendar_node, tasks_node, contacts_node, notes_node;
349 
350 	cfg_file = g_file_test (prefs_get_config_filename (CONFIG_FILENAME, appGUI), G_FILE_TEST_IS_REGULAR);
351 
352 	if (cfg_file == TRUE) {
353 		doc = xmlParseFile (prefs_get_config_filename (CONFIG_FILENAME, appGUI));
354 		if (doc == NULL) return;
355 
356 		node = xmlDocGetRootElement (doc);
357 		if (node == NULL) {
358 			xmlFreeDoc (doc);
359 			return;
360 		}
361 
362 		if (xmlStrcmp (node->name, (const xmlChar *) CONFIG_NAME)) {
363 			xmlFreeDoc (doc);
364 			return;
365 		}
366 
367 		prefs_set_default_values ();
368 		node = node->xmlChildrenNode;
369 
370 		while (node != NULL) {
371 
372 			/*---------------------------------------------------------------------------------------*/
373 			/* general */
374 
375 			if ((!xmlStrcmp (node->name, (const xmlChar *) "general"))) {
376 				general_node = node->xmlChildrenNode;
377 
378 				while (general_node != NULL) {
379 					utl_xml_get_int ("window_x", &config.window_x, general_node);
380 					utl_xml_get_int ("window_y", &config.window_y, general_node);
381 					utl_xml_get_int ("window_size_x", &config.window_size_x, general_node);
382 					utl_xml_get_int ("window_size_y", &config.window_size_y, general_node);
383 					utl_xml_get_int ("fullscreen", &config.fullscreen, general_node);
384 					utl_xml_get_int ("enable_tooltips", &config.enable_tooltips, general_node);
385 					utl_xml_get_int ("latest_tab", &config.latest_tab, general_node);
386 					utl_xml_get_int ("tabs_position", &config.tabs_position, general_node);
387 					utl_xml_get_int ("remember_latest_tab", &config.remember_latest_tab, general_node);
388 					utl_xml_get_int ("save_data_after_modification", &config.save_data_after_modification, general_node);
389 					utl_xml_get_int ("disable_underline_links", &config.disable_underline_links, general_node);
390 					utl_xml_get_int ("toolbar_exit_button", &config.toolbar_exit_button, general_node);
391 					utl_xml_get_int ("date_format", &config.date_format, general_node);
392 					utl_xml_get_int ("time_format", &config.time_format, general_node);
393 					utl_xml_get_int ("enable_systray", &config.enable_systray, general_node);
394 					utl_xml_get_int ("start_minimised_in_systray", &config.start_minimised_in_systray, general_node);
395 					utl_xml_get_int ("ignore_day_note_events", &config.ignore_day_note_events, general_node);
396 					utl_xml_get_int ("run_counter", &config.run_counter, general_node);
397 					utl_xml_get_int ("lastrun_date", &config.lastrun_date, general_node);
398 					utl_xml_get_int ("lastrun_time", &config.lastrun_time, general_node);
399 					utl_xml_get_int ("hide_calendar", &config.hide_calendar, general_node);
400 					utl_xml_get_int ("hide_tasks", &config.hide_tasks, general_node);
401 					utl_xml_get_int ("hide_contacts", &config.hide_contacts, general_node);
402 					utl_xml_get_int ("hide_notes", &config.hide_notes, general_node);
403 					utl_xml_get_int ("override_locale_settings", &config.override_locale_settings, general_node);
404 					utl_xml_get_int ("gui_layout", &config.gui_layout, general_node);
405 					utl_xml_get_int ("sound_alarm_repeat", &config.sound_alarm_repeat, general_node);
406 					utl_xml_get_strn ("spell_lang", config.spell_lang, MAXNAME, general_node);
407 					utl_xml_get_strn ("web_browser", config.web_browser, MAXHELPERCMD, general_node);
408 					utl_xml_get_strn ("email_client", config.email_client, MAXHELPERCMD, general_node);
409 					utl_xml_get_strn ("sound_player", config.sound_player, MAXHELPERCMD, general_node);
410 
411 					general_node = general_node->next;
412 				}
413 
414 			}
415 
416 			/*---------------------------------------------------------------------------------------*/
417 			/* calendar */
418 
419 			if ((!xmlStrcmp (node->name, (const xmlChar *) "calendar"))) {
420 				calendar_node = node->xmlChildrenNode;
421 
422 				while (calendar_node != NULL) {
423 					utl_xml_get_int ("fy_window_size_x", &config.fy_window_size_x, calendar_node);
424 					utl_xml_get_int ("fy_window_size_y", &config.fy_window_size_y, calendar_node);
425 					utl_xml_get_int ("fy_simple_view", &config.fy_simple_view, calendar_node);
426 					utl_xml_get_int ("fy_alternative_view", &config.fy_alternative_view, calendar_node);
427 					utl_xml_get_int ("cb_window_size_x", &config.cb_window_size_x, calendar_node);
428 					utl_xml_get_int ("cb_window_size_y", &config.cb_window_size_y, calendar_node);
429 					utl_xml_get_int ("ib_window_size_x", &config.ib_window_size_x, calendar_node);
430 					utl_xml_get_int ("ib_window_size_y", &config.ib_window_size_y, calendar_node);
431 					utl_xml_get_int ("display_options", &config.display_options, calendar_node);
432 					utl_xml_get_int ("day_notes_visible", &config.day_notes_visible, calendar_node);
433 					utl_xml_get_int ("timeline_start", &config.timeline_start, calendar_node);
434 					utl_xml_get_int ("timeline_end", &config.timeline_end, calendar_node);
435 					utl_xml_get_int ("timeline_step", &config.timeline_step, calendar_node);
436 					utl_xml_get_int ("di_show_current_time", &config.di_show_current_time, calendar_node);
437 					utl_xml_get_int ("di_show_current_time_seconds", &config.di_show_current_time_seconds, calendar_node);
438 					utl_xml_get_int ("di_show_day_number", &config.di_show_day_number, calendar_node);
439 					utl_xml_get_int ("di_show_current_day_distance", &config.di_show_current_day_distance, calendar_node);
440 					utl_xml_get_int ("di_show_marked_days", &config.di_show_marked_days, calendar_node);
441 					utl_xml_get_int ("di_show_week_number", &config.di_show_week_number, calendar_node);
442 					utl_xml_get_int ("di_show_weekend_days", &config.di_show_weekend_days, calendar_node);
443 					utl_xml_get_int ("di_show_day_category", &config.di_show_day_category, calendar_node);
444 					utl_xml_get_int ("di_show_moon_phase", &config.di_show_moon_phase, calendar_node);
445 					utl_xml_get_int ("di_show_notes", &config.di_show_notes, calendar_node);
446 					utl_xml_get_int ("di_show_zodiac_sign", &config.di_show_zodiac_sign, calendar_node);
447 					utl_xml_get_int ("cursor_type", &config.cursor_type, calendar_node);
448 					utl_xml_get_int ("frame_cursor_thickness", &config.frame_cursor_thickness, calendar_node);
449 					utl_xml_get_int ("enable_auxilary_calendars", &config.enable_auxilary_calendars, calendar_node);
450 					utl_xml_get_int ("enable_day_mark", &config.enable_day_mark, calendar_node);
451 					utl_xml_get_int ("strikethrough_past_notes", &config.strikethrough_past_notes, calendar_node);
452 					utl_xml_get_int ("ascending_sorting_in_day_notes_browser", &config.ascending_sorting_in_day_notes_browser, calendar_node);
453 					utl_xml_get_int ("auxilary_calendars_state", &config.auxilary_calendars_state, calendar_node);
454 					utl_xml_get_int ("day_note_spell_checker", &config.day_note_spell_checker, calendar_node);
455 					utl_xml_get_strn ("day_note_marker", config.day_note_marker, MAXNAME, calendar_node);
456 					utl_xml_get_strn ("date_header_format", config.date_header_format, MAXNAME, calendar_node);
457 					utl_xml_get_int ("event_marker_type", &config.event_marker_type, calendar_node);
458 					utl_xml_get_int ("today_marker_type", &config.today_marker_type, calendar_node);
459 					utl_xml_get_int ("day_notes_browser_filter", &config.day_notes_browser_filter, calendar_node);
460 					utl_xml_get_int ("ical_export_pane_pos", &config.ical_export_pane_pos, calendar_node);
461 					utl_xml_get_strn ("background_color", config.background_color, MAXCOLORNAME, calendar_node);
462 					utl_xml_get_strn ("header_bg_color", config.header_bg_color, MAXCOLORNAME, calendar_node);
463 					utl_xml_get_strn ("header_fg_color", config.header_fg_color, MAXCOLORNAME, calendar_node);
464 					utl_xml_get_strn ("day_color", config.day_color, MAXCOLORNAME, calendar_node);
465 					utl_xml_get_strn ("pf_day_color", config.pf_day_color, MAXCOLORNAME, calendar_node);
466 					utl_xml_get_strn ("weekend_color", config.weekend_color, MAXCOLORNAME, calendar_node);
467 					utl_xml_get_strn ("selection_color", config.selection_color, MAXCOLORNAME, calendar_node);
468 					utl_xml_get_strn ("mark_color", config.mark_color, MAXCOLORNAME, calendar_node);
469 					utl_xml_get_strn ("mark_current_day_color", config.mark_current_day_color, MAXCOLORNAME, calendar_node);
470 					utl_xml_get_int ("mark_current_day_alpha", &config.mark_current_day_alpha, calendar_node);
471 					utl_xml_get_strn ("birthday_mark_color", config.birthday_mark_color, MAXCOLORNAME, calendar_node);
472 					utl_xml_get_int ("selector_alpha", &config.selector_alpha, calendar_node);
473 					utl_xml_get_strn ("day_name_font", config.day_name_font, MAXFONTNAME, calendar_node);
474 					utl_xml_get_strn ("calendar_font", config.calendar_font, MAXFONTNAME, calendar_node);
475 					utl_xml_get_strn ("notes_font", config.notes_font, MAXFONTNAME, calendar_node);
476 					utl_xml_get_strn ("cal_print_month_name_font", config.cal_print_month_name_font, MAXFONTNAME, calendar_node);
477 					utl_xml_get_strn ("cal_print_day_name_font", config.cal_print_day_name_font, MAXFONTNAME, calendar_node);
478 					utl_xml_get_strn ("cal_print_day_num_font", config.cal_print_day_num_font, MAXFONTNAME, calendar_node);
479 					utl_xml_get_strn ("cal_print_event_font", config.cal_print_event_font, MAXFONTNAME, calendar_node);
480 					utl_xml_get_int ("cal_print_event_length", &config.cal_print_event_length, calendar_node);
481 					utl_xml_get_int ("cal_print_padding", &config.cal_print_padding, calendar_node);
482 					utl_xml_get_int ("cal_print_page_orientation", &config.cal_print_page_orientation, calendar_node);
483 					utl_xml_get_int ("cal_print_tasks", &config.cal_print_tasks, calendar_node);
484 					utl_xml_get_int ("cal_print_birthdays", &config.cal_print_birthdays, calendar_node);
485 					utl_xml_get_int ("cal_print_namedays", &config.cal_print_namedays, calendar_node);
486 					utl_xml_get_int ("cal_print_day_notes", &config.cal_print_day_notes, calendar_node);
487 					utl_xml_get_int ("cal_print_ical", &config.cal_print_ical, calendar_node);
488 					utl_xml_get_int ("cal_print_disable_background", &config.cal_print_disable_background, calendar_node);
489 
490 					calendar_node = calendar_node->next;
491 				}
492 			}
493 
494 			/*---------------------------------------------------------------------------------------*/
495 			/* tasks */
496 
497 			if ((!xmlStrcmp (node->name, (const xmlChar *) "tasks"))) {
498 				tasks_node = node->xmlChildrenNode;
499 
500 				while (tasks_node != NULL) {
501 					utl_xml_get_int ("high_priority_in_bold", &config.tasks_high_in_bold, tasks_node);
502 					utl_xml_get_int ("hide_completed", &config.hide_completed, tasks_node);
503 					utl_xml_get_int ("delete_completed", &config.delete_completed, tasks_node);
504 					utl_xml_get_int ("add_edit", &config.add_edit, tasks_node);
505 					utl_xml_get_int ("remember_category", &config.remember_category_in_tasks, tasks_node);
506 					utl_xml_get_int ("current_category", &config.current_category_in_tasks, tasks_node);
507 					utl_xml_get_int ("pane_pos", &config.tasks_pane_pos, tasks_node);
508 					utl_xml_get_int ("tasks_sorting_order", &config.tasks_sorting_order, tasks_node);
509 					utl_xml_get_int ("tasks_sorting_column", &config.tasks_sorting_column, tasks_node);
510 					utl_xml_get_int ("visible_due_date_column", &config.tsk_visible_due_date_column, tasks_node);
511 					utl_xml_get_int ("visible_type_column", &config.tsk_visible_type_column, tasks_node);
512 					utl_xml_get_int ("visible_priority_column", &config.tsk_visible_priority_column, tasks_node);
513 					utl_xml_get_int ("visible_category_column", &config.tsk_visible_category_column, tasks_node);
514 					utl_xml_get_int ("tasks_addedit_win_x", &config.tasks_addedit_win_x, tasks_node);
515 					utl_xml_get_int ("tasks_addedit_win_y", &config.tasks_addedit_win_y, tasks_node);
516 					utl_xml_get_int ("tasks_addedit_win_w", &config.tasks_addedit_win_w, tasks_node);
517 					utl_xml_get_int ("tasks_addedit_win_h", &config.tasks_addedit_win_h, tasks_node);
518 					utl_xml_get_int ("postpone_time", &config.postpone_time, tasks_node);
519 					utl_xml_get_int ("column_idx_0", &config.tasks_column_idx_0, tasks_node);
520 					utl_xml_get_int ("column_idx_0_width", &config.tasks_column_idx_0_width, tasks_node);
521 					utl_xml_get_int ("column_idx_1", &config.tasks_column_idx_1, tasks_node);
522 					utl_xml_get_int ("column_idx_1_width", &config.tasks_column_idx_1_width, tasks_node);
523 					utl_xml_get_int ("column_idx_2", &config.tasks_column_idx_2, tasks_node);
524 					utl_xml_get_int ("column_idx_2_width", &config.tasks_column_idx_2_width, tasks_node);
525 					utl_xml_get_int ("column_idx_3", &config.tasks_column_idx_3, tasks_node);
526 					utl_xml_get_int ("column_idx_3_width", &config.tasks_column_idx_3_width, tasks_node);
527 					utl_xml_get_int ("column_idx_4", &config.tasks_column_idx_4, tasks_node);
528 					utl_xml_get_int ("column_idx_4_width", &config.tasks_column_idx_4_width, tasks_node);
529 					utl_xml_get_int ("column_idx_5", &config.tasks_column_idx_5, tasks_node);
530 					utl_xml_get_int ("column_idx_5_width", &config.tasks_column_idx_5_width, tasks_node);
531 					utl_xml_get_strn ("due_today_color", config.due_today_color, MAXCOLORNAME, tasks_node);
532 					utl_xml_get_strn ("due_7days_color", config.due_7days_color, MAXCOLORNAME, tasks_node);
533 					utl_xml_get_strn ("past_due_color", config.past_due_color, MAXCOLORNAME, tasks_node);
534 					utl_xml_get_strn ("task_info_font", config.task_info_font, MAXFONTNAME, tasks_node);
535 					utl_xml_get_strn ("global_notification_command", config.global_notification_command, MAXHELPERCMD, tasks_node);
536 
537 					tasks_node = tasks_node->next;
538 				}
539 			}
540 
541 			/*---------------------------------------------------------------------------------------*/
542 			/* contacts */
543 
544 			if ((!xmlStrcmp (node->name, (const xmlChar *) "contacts"))) {
545 				contacts_node = node->xmlChildrenNode;
546 
547 				while (contacts_node != NULL) {
548 					utl_xml_get_int ("find_mode", &config.find_mode, contacts_node);
549 					utl_xml_get_int ("hide_group_column", &config.hide_group_column, contacts_node);
550 					utl_xml_get_int ("maps_provider", &config.maps_provider, contacts_node);
551 					utl_xml_get_int ("pane_pos", &config.contacts_pane_pos, contacts_node);
552 					utl_xml_get_int ("photo_width", &config.photo_width, contacts_node);
553 					utl_xml_get_int ("visible_age_column", &config.cnt_visible_age_column, contacts_node);
554 					utl_xml_get_int ("visible_birthday_date_column", &config.cnt_visible_birthday_date_column, contacts_node);
555 					utl_xml_get_int ("visible_zodiac_sign_column", &config.cnt_visible_zodiac_sign_column, contacts_node);
556 					utl_xml_get_strn ("contact_tag_color", config.contact_tag_color, MAXCOLORNAME, contacts_node);
557 					utl_xml_get_strn ("contact_link_color", config.contact_link_color, MAXCOLORNAME, contacts_node);
558 					utl_xml_get_int ("contact_name_font_size", &config.contact_name_font_size, contacts_node);
559 					utl_xml_get_int ("contact_item_font_size", &config.contact_item_font_size, contacts_node);
560 					utl_xml_get_int ("export_format", &config.export_format, contacts_node);
561 					utl_xml_get_strn ("export_fields", config.export_fields, MAXCONTACTFIELDS, contacts_node);
562 					utl_xml_get_int ("contacts_sorting_order", &config.contacts_sorting_order, contacts_node);
563 					utl_xml_get_int ("contacts_sorting_column", &config.contacts_sorting_column, contacts_node);
564 					utl_xml_get_int ("contacts_addedit_win_x", &config.contacts_addedit_win_x, contacts_node);
565 					utl_xml_get_int ("contacts_addedit_win_y", &config.contacts_addedit_win_y, contacts_node);
566 					utl_xml_get_int ("contacts_addedit_win_w", &config.contacts_addedit_win_w, contacts_node);
567 					utl_xml_get_int ("contacts_addedit_win_h", &config.contacts_addedit_win_h, contacts_node);
568 					utl_xml_get_int ("contacts_export_win_x", &config.contacts_export_win_x, contacts_node);
569 					utl_xml_get_int ("contacts_export_win_y", &config.contacts_export_win_y, contacts_node);
570 					utl_xml_get_int ("contacts_export_win_w", &config.contacts_export_win_w, contacts_node);
571 					utl_xml_get_int ("contacts_export_win_h", &config.contacts_export_win_h, contacts_node);
572 					utl_xml_get_int ("contacts_import_sel_win_x", &config.contacts_import_sel_win_x, contacts_node);
573 					utl_xml_get_int ("contacts_import_sel_win_y", &config.contacts_import_sel_win_y, contacts_node);
574 					utl_xml_get_int ("contacts_import_win_x", &config.contacts_import_win_x, contacts_node);
575 					utl_xml_get_int ("contacts_import_win_y", &config.contacts_import_win_y, contacts_node);
576 					utl_xml_get_int ("contacts_import_win_w", &config.contacts_import_win_w, contacts_node);
577 					utl_xml_get_int ("contacts_import_win_h", &config.contacts_import_win_h, contacts_node);
578 					utl_xml_get_int ("contacts_birthdays_win_w", &config.contacts_birthdays_win_w, contacts_node);
579 					utl_xml_get_int ("contacts_birthdays_win_h", &config.contacts_birthdays_win_h, contacts_node);
580 					utl_xml_get_int ("column_idx_0", &config.contacts_column_idx_0, contacts_node);
581 					utl_xml_get_int ("column_idx_0_width", &config.contacts_column_idx_0_width, contacts_node);
582 					utl_xml_get_int ("column_idx_1", &config.contacts_column_idx_1, contacts_node);
583 					utl_xml_get_int ("column_idx_1_width", &config.contacts_column_idx_1_width, contacts_node);
584 					utl_xml_get_int ("column_idx_2", &config.contacts_column_idx_2, contacts_node);
585 					utl_xml_get_int ("column_idx_2_width", &config.contacts_column_idx_2_width, contacts_node);
586 					utl_xml_get_int ("import_type", &config.import_type, contacts_node);
587 					utl_xml_get_int ("import_interface_type", &config.import_interface_type, contacts_node);
588 					utl_xml_get_int ("import_bluetooth_channel", &config.import_bluetooth_channel, contacts_node);
589 					utl_xml_get_int ("import_usb_interface", &config.import_usb_interface, contacts_node);
590 					utl_xml_get_int ("import_binary_xml", &config.import_binary_xml, contacts_node);
591 					utl_xml_get_strn ("import_bluetooth_address", config.import_bluetooth_address, MAXADDRESS, contacts_node);
592 
593 					contacts_node = contacts_node->next;
594 				}
595 			}
596 
597 			/*---------------------------------------------------------------------------------------*/
598 			/* notes */
599 
600 			if ((!xmlStrcmp (node->name, (const xmlChar *) "notes"))) {
601 				notes_node = node->xmlChildrenNode;
602 
603 				while (notes_node != NULL) {
604 					utl_xml_get_int ("enc_algorithm", &config.notes_enc_algorithm, notes_node);
605 					utl_xml_get_int ("enc_hashing", &config.notes_enc_hashing, notes_node);
606 					utl_xml_get_int ("comp_algorithm", &config.notes_comp_algorithm, notes_node);
607 					utl_xml_get_int ("comp_ratio", &config.notes_comp_ratio, notes_node);
608 					utl_xml_get_int ("sorting_order", &config.notes_sorting_order, notes_node);
609 					utl_xml_get_int ("sorting_column", &config.notes_sorting_column, notes_node);
610 					utl_xml_get_int ("visible_type_column", &config.nte_visible_type_column, notes_node);
611 					utl_xml_get_int ("visible_category_column", &config.nte_visible_category_column, notes_node);
612 					utl_xml_get_int ("visible_last_changes_column", &config.nte_visible_last_changes_column, notes_node);
613 					utl_xml_get_int ("visible_created_column", &config.nte_visible_created_column, notes_node);
614 					utl_xml_get_int ("column_idx_0", &config.notes_column_idx_0, notes_node);
615 					utl_xml_get_int ("column_idx_0_width", &config.notes_column_idx_0_width, notes_node);
616 					utl_xml_get_int ("column_idx_1", &config.notes_column_idx_1, notes_node);
617 					utl_xml_get_int ("column_idx_1_width", &config.notes_column_idx_1_width, notes_node);
618 					utl_xml_get_int ("column_idx_2", &config.notes_column_idx_2, notes_node);
619 					utl_xml_get_int ("column_idx_2_width", &config.notes_column_idx_2_width, notes_node);
620 					utl_xml_get_int ("column_idx_3", &config.notes_column_idx_3, notes_node);
621 					utl_xml_get_int ("column_idx_3_width", &config.notes_column_idx_3_width, notes_node);
622 					utl_xml_get_int ("column_idx_4", &config.notes_column_idx_4, notes_node);
623 					utl_xml_get_int ("column_idx_4_width", &config.notes_column_idx_4_width, notes_node);
624 					utl_xml_get_int ("remember_category", &config.remember_category_in_notes, notes_node);
625 					utl_xml_get_int ("current_category", &config.current_category_in_notes, notes_node);
626 					utl_xml_get_int ("use_system_date", &config.use_system_date_in_notes, notes_node);
627 					utl_xml_get_char ("text_separator", &config.text_separator, notes_node);
628 					utl_xml_get_strn ("editor_font", config.notes_editor_font, MAXFONTNAME, notes_node);
629 
630 					notes_node = notes_node->next;
631 				}
632 
633 				if (config.notes_comp_ratio == 0 /* GRG_LVL_NONE */) {      /* ignore 'None' option */
634 					config.notes_comp_ratio = 1 /* GRG_LVL_FAST */;
635 				}
636 			}
637 
638 			/*---------------------------------------------------------------------------------------*/
639 
640 			node = node->next;
641 		}
642 
643 		xmlFreeDoc (doc);
644 	} else {
645 		prefs_set_default_values ();
646 		prefs_write_config (appGUI);
647 	}
648 
649 }
650 
651 /*------------------------------------------------------------------------------*/
652 
653 void
prefs_write_config(GUI * appGUI)654 prefs_write_config (GUI *appGUI)
655 {
656 xmlDocPtr doc;
657 xmlNodePtr node, general_node, calendar_node, tasks_node, contacts_node, notes_node;
658 
659 	doc = xmlNewDoc ((const xmlChar *) "1.0");
660 	node = xmlNewNode (NULL, (const xmlChar *) CONFIG_NAME);
661 	xmlDocSetRootElement (doc, node);
662 
663 	/*---------------------------------------------------------------------------------------*/
664 	/* general */
665 
666 	general_node = xmlNewNode (NULL, (const xmlChar *) "general");
667 	xmlAddChild (node, general_node);
668 
669 	utl_xml_put_int ("window_x", config.window_x, general_node);
670 	utl_xml_put_int ("window_y", config.window_y, general_node);
671 	utl_xml_put_int ("window_size_x", config.window_size_x, general_node);
672 	utl_xml_put_int ("window_size_y", config.window_size_y, general_node);
673 	utl_xml_put_int ("fullscreen", config.fullscreen, general_node);
674 	utl_xml_put_int ("enable_tooltips", config.enable_tooltips, general_node);
675 	utl_xml_put_int ("latest_tab", config.latest_tab, general_node);
676 	utl_xml_put_int ("tabs_position", config.tabs_position, general_node);
677 	utl_xml_put_int ("remember_latest_tab", config.remember_latest_tab, general_node);
678 	utl_xml_put_int ("save_data_after_modification", config.save_data_after_modification, general_node);
679 	utl_xml_put_int ("disable_underline_links", config.disable_underline_links, general_node);
680 	utl_xml_put_int ("toolbar_exit_button", config.toolbar_exit_button, general_node);
681 	utl_xml_put_int ("date_format", config.date_format, general_node);
682 	utl_xml_put_int ("time_format", config.time_format, general_node);
683 	utl_xml_put_int ("enable_systray", config.enable_systray, general_node);
684 	utl_xml_put_int ("start_minimised_in_systray", config.start_minimised_in_systray, general_node);
685 	utl_xml_put_int ("ignore_day_note_events", config.ignore_day_note_events, general_node);
686 	utl_xml_put_int ("run_counter", config.run_counter, general_node);
687 	utl_xml_put_int ("lastrun_date", config.lastrun_date, general_node);
688 	utl_xml_put_int ("lastrun_time", config.lastrun_time, general_node);
689 	utl_xml_put_int ("hide_calendar", config.hide_calendar, general_node);
690 	utl_xml_put_int ("hide_tasks", config.hide_tasks, general_node);
691 	utl_xml_put_int ("hide_contacts", config.hide_contacts, general_node);
692 	utl_xml_put_int ("hide_notes", config.hide_notes, general_node);
693 	utl_xml_put_int ("override_locale_settings", config.override_locale_settings, general_node);
694 	utl_xml_put_int ("gui_layout", config.gui_layout, general_node);
695 	utl_xml_put_int ("sound_alarm_repeat", config.sound_alarm_repeat, general_node);
696 	utl_xml_put_strn ("spell_lang", config.spell_lang, MAXNAME, general_node);
697 	utl_xml_put_strn ("web_browser", config.web_browser, MAXHELPERCMD, general_node);
698 	utl_xml_put_strn ("email_client", config.email_client, MAXHELPERCMD, general_node);
699 	utl_xml_put_strn ("sound_player", config.sound_player, MAXHELPERCMD, general_node);
700 
701 	/*---------------------------------------------------------------------------------------*/
702 	/* calendar */
703 
704 	calendar_node = xmlNewNode (NULL, (const xmlChar *) "calendar");
705 	xmlAddChild (node, calendar_node);
706 
707 	utl_xml_put_int ("fy_window_size_x", config.fy_window_size_x, calendar_node);
708 	utl_xml_put_int ("fy_window_size_y", config.fy_window_size_y, calendar_node);
709 	utl_xml_put_int ("fy_simple_view", config.fy_simple_view, calendar_node);
710 	utl_xml_put_int ("fy_alternative_view", config.fy_alternative_view, calendar_node);
711 	utl_xml_put_int ("cb_window_size_x", config.cb_window_size_x, calendar_node);
712 	utl_xml_put_int ("cb_window_size_y", config.cb_window_size_y, calendar_node);
713 	utl_xml_put_int ("ib_window_size_x", config.ib_window_size_x, calendar_node);
714 	utl_xml_put_int ("ib_window_size_y", config.ib_window_size_y, calendar_node);
715 	utl_xml_put_int ("display_options", config.display_options, calendar_node);
716 	utl_xml_put_int ("day_notes_visible", config.day_notes_visible, calendar_node);
717 	utl_xml_put_int ("timeline_start", config.timeline_start, calendar_node);
718 	utl_xml_put_int ("timeline_end", config.timeline_end, calendar_node);
719 	utl_xml_put_int ("timeline_step", config.timeline_step, calendar_node);
720 	utl_xml_put_int ("di_show_current_time", config.di_show_current_time, calendar_node);
721 	utl_xml_put_int ("di_show_current_time_seconds", config.di_show_current_time_seconds, calendar_node);
722 	utl_xml_put_int ("di_show_day_number", config.di_show_day_number, calendar_node);
723 	utl_xml_put_int ("di_show_current_day_distance", config.di_show_current_day_distance, calendar_node);
724 	utl_xml_put_int ("di_show_marked_days", config.di_show_marked_days, calendar_node);
725 	utl_xml_put_int ("di_show_week_number", config.di_show_week_number, calendar_node);
726 	utl_xml_put_int ("di_show_weekend_days", config.di_show_weekend_days, calendar_node);
727 	utl_xml_put_int ("di_show_day_category", config.di_show_day_category, calendar_node);
728 	utl_xml_put_int ("di_show_moon_phase", config.di_show_moon_phase, calendar_node);
729 	utl_xml_put_int ("di_show_notes", config.di_show_notes, calendar_node);
730 	utl_xml_put_int ("di_show_zodiac_sign", config.di_show_zodiac_sign, calendar_node);
731 	utl_xml_put_int ("cursor_type", config.cursor_type, calendar_node);
732 	utl_xml_put_int ("frame_cursor_thickness", config.frame_cursor_thickness, calendar_node);
733 	utl_xml_put_int ("enable_auxilary_calendars", config.enable_auxilary_calendars, calendar_node);
734 	utl_xml_put_int ("enable_day_mark", config.enable_day_mark, calendar_node);
735 	utl_xml_put_int ("strikethrough_past_notes", config.strikethrough_past_notes, calendar_node);
736 	utl_xml_put_int ("ascending_sorting_in_day_notes_browser", config.ascending_sorting_in_day_notes_browser, calendar_node);
737 	utl_xml_put_int ("auxilary_calendars_state", config.auxilary_calendars_state, calendar_node);
738 	utl_xml_put_int ("day_note_spell_checker", config.day_note_spell_checker, calendar_node);
739 	utl_xml_put_strn ("day_note_marker", config.day_note_marker, MAXNAME, calendar_node);
740 	utl_xml_put_strn ("date_header_format", config.date_header_format, MAXNAME, calendar_node);
741 	utl_xml_put_int ("event_marker_type", config.event_marker_type, calendar_node);
742 	utl_xml_put_int ("today_marker_type", config.today_marker_type, calendar_node);
743 	utl_xml_put_int ("day_notes_browser_filter", config.day_notes_browser_filter, calendar_node);
744 	utl_xml_put_int ("ical_export_pane_pos", config.ical_export_pane_pos, calendar_node);
745 	utl_xml_put_strn ("background_color", config.background_color, MAXCOLORNAME, calendar_node);
746 	utl_xml_put_strn ("header_bg_color", config.header_bg_color, MAXCOLORNAME, calendar_node);
747 	utl_xml_put_strn ("header_fg_color", config.header_fg_color, MAXCOLORNAME, calendar_node);
748 	utl_xml_put_strn ("day_color", config.day_color, MAXCOLORNAME, calendar_node);
749 	utl_xml_put_strn ("pf_day_color", config.pf_day_color, MAXCOLORNAME, calendar_node);
750 	utl_xml_put_strn ("weekend_color", config.weekend_color, MAXCOLORNAME, calendar_node);
751 	utl_xml_put_strn ("selection_color", config.selection_color, MAXCOLORNAME, calendar_node);
752 	utl_xml_put_strn ("mark_color", config.mark_color, MAXCOLORNAME, calendar_node);
753 	utl_xml_put_strn ("mark_current_day_color", config.mark_current_day_color, MAXCOLORNAME, calendar_node);
754 	utl_xml_put_int ("mark_current_day_alpha", config.mark_current_day_alpha, calendar_node);
755 	utl_xml_put_strn ("birthday_mark_color", config.birthday_mark_color, MAXCOLORNAME, calendar_node);
756 	utl_xml_put_int ("selector_alpha", config.selector_alpha, calendar_node);
757 	utl_xml_put_strn ("day_name_font", config.day_name_font, MAXFONTNAME, calendar_node);
758 	utl_xml_put_strn ("calendar_font", config.calendar_font, MAXFONTNAME, calendar_node);
759 	utl_xml_put_strn ("notes_font", config.notes_font, MAXFONTNAME, calendar_node);
760 	utl_xml_put_strn ("cal_print_month_name_font", config.cal_print_month_name_font, MAXFONTNAME, calendar_node);
761 	utl_xml_put_strn ("cal_print_day_name_font", config.cal_print_day_name_font, MAXFONTNAME, calendar_node);
762 	utl_xml_put_strn ("cal_print_day_num_font", config.cal_print_day_num_font, MAXFONTNAME, calendar_node);
763 	utl_xml_put_strn ("cal_print_event_font", config.cal_print_event_font, MAXFONTNAME, calendar_node);
764 	utl_xml_put_int ("cal_print_event_length", config.cal_print_event_length, calendar_node);
765 	utl_xml_put_int ("cal_print_padding", config.cal_print_padding, calendar_node);
766 	utl_xml_put_int ("cal_print_page_orientation", config.cal_print_page_orientation, calendar_node);
767 	utl_xml_put_int ("cal_print_tasks", config.cal_print_tasks, calendar_node);
768 	utl_xml_put_int ("cal_print_birthdays", config.cal_print_birthdays, calendar_node);
769 	utl_xml_put_int ("cal_print_namedays", config.cal_print_namedays, calendar_node);
770 	utl_xml_put_int ("cal_print_day_notes", config.cal_print_day_notes, calendar_node);
771 	utl_xml_put_int ("cal_print_ical", config.cal_print_ical, calendar_node);
772 	utl_xml_put_int ("cal_print_disable_background", config.cal_print_disable_background, calendar_node);
773 
774 	/*---------------------------------------------------------------------------------------*/
775 	/* tasks */
776 
777 	tasks_node = xmlNewNode (NULL, (const xmlChar *) "tasks");
778 	xmlAddChild (node, tasks_node);
779 
780 	utl_xml_put_int ("high_priority_in_bold", config.tasks_high_in_bold, tasks_node);
781 	utl_xml_put_int ("hide_completed", config.hide_completed, tasks_node);
782 	utl_xml_put_int ("delete_completed", config.delete_completed, tasks_node);
783 	utl_xml_put_int ("add_edit", config.add_edit, tasks_node);
784 	utl_xml_put_int ("remember_category", config.remember_category_in_tasks, tasks_node);
785 	utl_xml_put_int ("current_category", config.current_category_in_tasks, tasks_node);
786 	utl_xml_put_int ("pane_pos", config.tasks_pane_pos, tasks_node);
787 	utl_xml_put_int ("tasks_sorting_order", config.tasks_sorting_order, tasks_node);
788 	utl_xml_put_int ("tasks_sorting_column", config.tasks_sorting_column, tasks_node);
789 	utl_xml_put_int ("visible_due_date_column", config.tsk_visible_due_date_column, tasks_node);
790 	utl_xml_put_int ("visible_type_column", config.tsk_visible_type_column, tasks_node);
791 	utl_xml_put_int ("visible_priority_column", config.tsk_visible_priority_column, tasks_node);
792 	utl_xml_put_int ("visible_category_column", config.tsk_visible_category_column, tasks_node);
793 	utl_xml_put_int ("tasks_addedit_win_x", config.tasks_addedit_win_x, tasks_node);
794 	utl_xml_put_int ("tasks_addedit_win_y", config.tasks_addedit_win_y, tasks_node);
795 	utl_xml_put_int ("tasks_addedit_win_w", config.tasks_addedit_win_w, tasks_node);
796 	utl_xml_put_int ("tasks_addedit_win_h", config.tasks_addedit_win_h, tasks_node);
797 	utl_xml_put_int ("postpone_time", config.postpone_time, tasks_node);
798 	utl_xml_put_int ("column_idx_0", config.tasks_column_idx_0, tasks_node);
799 	utl_xml_put_int ("column_idx_0_width", config.tasks_column_idx_0_width, tasks_node);
800 	utl_xml_put_int ("column_idx_1", config.tasks_column_idx_1, tasks_node);
801 	utl_xml_put_int ("column_idx_1_width", config.tasks_column_idx_1_width, tasks_node);
802 	utl_xml_put_int ("column_idx_2", config.tasks_column_idx_2, tasks_node);
803 	utl_xml_put_int ("column_idx_2_width", config.tasks_column_idx_2_width, tasks_node);
804 	utl_xml_put_int ("column_idx_3", config.tasks_column_idx_3, tasks_node);
805 	utl_xml_put_int ("column_idx_3_width", config.tasks_column_idx_3_width, tasks_node);
806 	utl_xml_put_int ("column_idx_4", config.tasks_column_idx_4, tasks_node);
807 	utl_xml_put_int ("column_idx_4_width", config.tasks_column_idx_4_width, tasks_node);
808 	utl_xml_put_int ("column_idx_5", config.tasks_column_idx_5, tasks_node);
809 	utl_xml_put_int ("column_idx_5_width", config.tasks_column_idx_5_width, tasks_node);
810 	utl_xml_put_strn ("due_today_color", config.due_today_color, MAXCOLORNAME, tasks_node);
811 	utl_xml_put_strn ("due_7days_color", config.due_7days_color, MAXCOLORNAME, tasks_node);
812 	utl_xml_put_strn ("past_due_color", config.past_due_color, MAXCOLORNAME, tasks_node);
813 	utl_xml_put_strn ("task_info_font", config.task_info_font, MAXFONTNAME, tasks_node);
814 	utl_xml_put_strn ("global_notification_command", config.global_notification_command, MAXHELPERCMD, tasks_node);
815 
816 	/*---------------------------------------------------------------------------------------*/
817 	/* contacts */
818 
819 	contacts_node = xmlNewNode (NULL, (const xmlChar *) "contacts");
820 	xmlAddChild (node, contacts_node);
821 
822 	utl_xml_put_int ("find_mode", config.find_mode, contacts_node);
823 	utl_xml_put_int ("hide_group_column", config.hide_group_column, contacts_node);
824 	utl_xml_put_int ("maps_provider", config.maps_provider, contacts_node);
825 	utl_xml_put_int ("pane_pos", config.contacts_pane_pos, contacts_node);
826 	utl_xml_put_int ("photo_width", config.photo_width, contacts_node);
827 	utl_xml_put_int ("visible_age_column", config.cnt_visible_age_column, contacts_node);
828 	utl_xml_put_int ("visible_birthday_date_column", config.cnt_visible_birthday_date_column, contacts_node);
829 	utl_xml_put_int ("visible_zodiac_sign_column", config.cnt_visible_zodiac_sign_column, contacts_node);
830 	utl_xml_put_strn ("contact_tag_color", config.contact_tag_color, MAXCOLORNAME, contacts_node);
831 	utl_xml_put_strn ("contact_link_color", config.contact_link_color, MAXCOLORNAME, contacts_node);
832 	utl_xml_put_int ("contact_name_font_size", config.contact_name_font_size, contacts_node);
833 	utl_xml_put_int ("contact_item_font_size", config.contact_item_font_size, contacts_node);
834 	utl_xml_put_int ("export_format", config.export_format, contacts_node);
835 	utl_xml_put_strn ("export_fields", config.export_fields, MAXCONTACTFIELDS, contacts_node);
836 	utl_xml_put_int ("contacts_sorting_order", config.contacts_sorting_order, contacts_node);
837 	utl_xml_put_int ("contacts_sorting_column", config.contacts_sorting_column, contacts_node);
838 	utl_xml_put_int ("contacts_addedit_win_x", config.contacts_addedit_win_x, contacts_node);
839 	utl_xml_put_int ("contacts_addedit_win_y", config.contacts_addedit_win_y, contacts_node);
840 	utl_xml_put_int ("contacts_addedit_win_w", config.contacts_addedit_win_w, contacts_node);
841 	utl_xml_put_int ("contacts_addedit_win_h", config.contacts_addedit_win_h, contacts_node);
842 	utl_xml_put_int ("contacts_export_win_x", config.contacts_export_win_x, contacts_node);
843 	utl_xml_put_int ("contacts_export_win_y", config.contacts_export_win_y, contacts_node);
844 	utl_xml_put_int ("contacts_export_win_w", config.contacts_export_win_w, contacts_node);
845 	utl_xml_put_int ("contacts_export_win_h", config.contacts_export_win_h, contacts_node);
846 	utl_xml_put_int ("contacts_import_sel_win_x", config.contacts_import_sel_win_x, contacts_node);
847 	utl_xml_put_int ("contacts_import_sel_win_y", config.contacts_import_sel_win_y, contacts_node);
848 	utl_xml_put_int ("contacts_import_win_x", config.contacts_import_win_x, contacts_node);
849 	utl_xml_put_int ("contacts_import_win_y", config.contacts_import_win_y, contacts_node);
850 	utl_xml_put_int ("contacts_import_win_w", config.contacts_import_win_w, contacts_node);
851 	utl_xml_put_int ("contacts_import_win_h", config.contacts_import_win_h, contacts_node);
852 	utl_xml_put_int ("contacts_birthdays_win_w", config.contacts_birthdays_win_w, contacts_node);
853 	utl_xml_put_int ("contacts_birthdays_win_h", config.contacts_birthdays_win_h, contacts_node);
854 	utl_xml_put_int ("column_idx_0", config.contacts_column_idx_0, contacts_node);
855 	utl_xml_put_int ("column_idx_0_width", config.contacts_column_idx_0_width, contacts_node);
856 	utl_xml_put_int ("column_idx_1", config.contacts_column_idx_1, contacts_node);
857 	utl_xml_put_int ("column_idx_1_width", config.contacts_column_idx_1_width, contacts_node);
858 	utl_xml_put_int ("column_idx_2", config.contacts_column_idx_2, contacts_node);
859 	utl_xml_put_int ("column_idx_2_width", config.contacts_column_idx_2_width, contacts_node);
860 	utl_xml_put_int ("import_type", config.import_type, contacts_node);
861 	utl_xml_put_int ("import_interface_type", config.import_interface_type, contacts_node);
862 	utl_xml_put_int ("import_bluetooth_channel", config.import_bluetooth_channel, contacts_node);
863 	utl_xml_put_int ("import_usb_interface", config.import_usb_interface, contacts_node);
864 	utl_xml_put_int ("import_binary_xml", config.import_binary_xml, contacts_node);
865 	utl_xml_put_strn ("import_bluetooth_address", config.import_bluetooth_address, MAXADDRESS, contacts_node);
866 
867 	/*---------------------------------------------------------------------------------------*/
868 	/* notes */
869 
870 	notes_node = xmlNewNode (NULL, (const xmlChar *) "notes");
871 	xmlAddChild (node, notes_node);
872 
873 	utl_xml_put_int ("enc_algorithm", config.notes_enc_algorithm, notes_node);
874 	utl_xml_put_int ("enc_hashing", config.notes_enc_hashing, notes_node);
875 	utl_xml_put_int ("comp_algorithm", config.notes_comp_algorithm, notes_node);
876 	utl_xml_put_int ("comp_ratio", config.notes_comp_ratio, notes_node);
877 	utl_xml_put_int ("sorting_order", config.notes_sorting_order, notes_node);
878 	utl_xml_put_int ("sorting_column", config.notes_sorting_column, notes_node);
879 	utl_xml_put_int ("visible_type_column", config.nte_visible_type_column, notes_node);
880 	utl_xml_put_int ("visible_category_column", config.nte_visible_category_column, notes_node);
881 	utl_xml_put_int ("visible_last_changes_column", config.nte_visible_last_changes_column, notes_node);
882 	utl_xml_put_int ("visible_created_column", config.nte_visible_created_column, notes_node);
883 	utl_xml_put_int ("column_idx_0", config.notes_column_idx_0, notes_node);
884 	utl_xml_put_int ("column_idx_0_width", config.notes_column_idx_0_width, notes_node);
885 	utl_xml_put_int ("column_idx_1", config.notes_column_idx_1, notes_node);
886 	utl_xml_put_int ("column_idx_1_width", config.notes_column_idx_1_width, notes_node);
887 	utl_xml_put_int ("column_idx_2", config.notes_column_idx_2, notes_node);
888 	utl_xml_put_int ("column_idx_2_width", config.notes_column_idx_2_width, notes_node);
889 	utl_xml_put_int ("column_idx_3", config.notes_column_idx_3, notes_node);
890 	utl_xml_put_int ("column_idx_3_width", config.notes_column_idx_3_width, notes_node);
891 	utl_xml_put_int ("column_idx_4", config.notes_column_idx_4, notes_node);
892 	utl_xml_put_int ("column_idx_4_width", config.notes_column_idx_4_width, notes_node);
893 	utl_xml_put_int ("remember_category", config.remember_category_in_notes, notes_node);
894 	utl_xml_put_int ("current_category", config.current_category_in_notes, notes_node);
895 	utl_xml_put_int ("use_system_date", config.use_system_date_in_notes, notes_node);
896 	utl_xml_put_char ("text_separator", config.text_separator, notes_node);
897 	utl_xml_put_strn ("editor_font", config.notes_editor_font, MAXFONTNAME, notes_node);
898 
899 	/*---------------------------------------------------------------------------------------*/
900 
901 	utl_xml_write_doc (prefs_get_config_filename (CONFIG_FILENAME, appGUI), doc);
902 	xmlFreeDoc (doc);
903 }
904 /*------------------------------------------------------------------------------*/
905 static int
copy(gchar * source,gchar * target)906 copy(gchar *source, gchar *target) {
907     int source_fd, target_fd;
908     ssize_t len;
909     gchar buff[8192];
910     struct stat st;
911     mode_t perm;
912 
913     if (stat(source, &st)) {
914         return -1;
915     }
916     perm = st.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
917     source_fd = open(source, O_RDONLY);
918     if (source_fd == -1) {
919         return -1;
920     }
921     g_remove(target);
922     target_fd = open(target, O_WRONLY | O_CREAT | O_EXCL, perm);
923     if (target_fd == -1) {
924         close(source_fd);
925         return -1;
926     }
927 
928     len = read(source_fd, buff, sizeof (buff));
929     while (len > 0) {
930         write(target_fd, buff, len);
931         len = read(source_fd, buff, sizeof (buff));
932     }
933     close(source_fd);
934     close(target_fd);
935 
936     return 0;
937 }
938 
939 static gboolean
restore_from_dir(gchar * source_dirname,gchar * target_name,GUI * appGUI)940 restore_from_dir(gchar *source_dirname, gchar *target_name, GUI *appGUI) {
941     GDir *source_dir = g_dir_open(source_dirname, 0, NULL);
942     if (source_dir) {
943         const gchar *old_name = g_dir_read_name(source_dir);
944         for (; old_name; old_name = g_dir_read_name(source_dir)) {
945             gchar *old_fullname = g_build_filename(source_dirname, old_name, NULL);
946 
947             if (g_file_test(old_fullname, G_FILE_TEST_IS_REGULAR)) {
948                 gchar *new_name = g_build_filename(target_name, old_name, NULL);
949                 gboolean is_config = utl_text_strcmp(CONFIG_FILENAME, new_name) == 0;
950                 gchar *new_fullname = is_config ? prefs_get_config_filename(new_name, appGUI) : prefs_get_data_filename(new_name, appGUI);
951                 int rc = copy(old_fullname, new_fullname);
952                 g_free(new_name);
953                 if (rc == -1) {
954                     g_warning("Failed to move the old file %s to the new location %s. Aborting migration.", old_fullname, new_fullname);
955                     g_free(old_fullname);
956                     return FALSE;
957                 }
958             } else if (g_file_test(old_fullname, G_FILE_TEST_IS_DIR)) {
959                 gchar *new_target_name = g_build_filename(target_name, old_name, NULL);
960                 gboolean rc = restore_from_dir(old_fullname, new_target_name, appGUI);
961                 g_free(new_target_name);
962                 if (rc == FALSE) {
963                     return FALSE;
964                 }
965             } else {
966                 g_warning("Do not know how to handle entry %s. Aborting migration.", old_fullname);
967                 g_free(old_fullname);
968                 return FALSE;
969             }
970 
971             g_free(old_fullname);
972         }
973 
974         g_dir_close(source_dir);
975     }
976     return TRUE;
977 }
978 
979 gboolean
prefs_restore(gchar * source_dir,GUI * appGUI)980 prefs_restore (gchar *source_dir, GUI *appGUI) {
981     return restore_from_dir(source_dir, "", appGUI);
982 }
983 /*------------------------------------------------------------------------------*/
984 
985 
986