1 /*  HomeBank -- Free, easy, personal accounting for everyone.
2  *  Copyright (C) 1995-2021 Maxime DOYEN
3  *
4  *  This file is part of HomeBank.
5  *
6  *  HomeBank is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  HomeBank is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 
21 #include "homebank.h"
22 
23 #include "hb-preferences.h"
24 #include "hb-filter.h"
25 #include "gtk-chart-colors.h"
26 
27 #ifdef G_OS_WIN32
28 #include <windows.h>
29 #endif
30 
31 /****************************************************************************/
32 /* Debug macros                                                             */
33 /****************************************************************************/
34 #define MYDEBUG 0
35 
36 #if MYDEBUG
37 #define DB(x) (x);
38 #else
39 #define DB(x);
40 #endif
41 
42 /* our global datas */
43 extern struct HomeBank *GLOBALS;
44 extern struct Preferences *PREFS;
45 
46 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
47 
48 
homebank_pref_init_wingeometry(struct WinGeometry * wg,gint l,gint t,gint w,gint h)49 static void homebank_pref_init_wingeometry(struct WinGeometry *wg, gint l, gint t, gint w, gint h)
50 {
51 	wg->l = l;
52 	wg->t = t;
53 	wg->w = w;
54 	wg->h = h;
55 	wg->s = 0;
56 }
57 
58 
59 //vehicle_unit_100
60 //vehicle_unit_distbyvol
61 //=> used for column title
62 
_homebank_pref_init_measurement_units(void)63 static void _homebank_pref_init_measurement_units(void)
64 {
65 	// unit is kilometer
66 	if(!PREFS->vehicle_unit_ismile)
67 	{
68 		PREFS->vehicle_unit_dist0 = "%d km";
69 		PREFS->vehicle_unit_dist1 = "%.1f km";
70 		PREFS->vehicle_unit_100  = "100 km";
71 	}
72 	// unit is miles
73 	else
74 	{
75 		PREFS->vehicle_unit_dist0 = "%d mi.";
76 		PREFS->vehicle_unit_dist1 = "%.1f mi.";
77 		PREFS->vehicle_unit_100  = "100 mi.";
78 	}
79 
80 	// unit is Liters
81 	if(!PREFS->vehicle_unit_isgal)
82 	{
83 		//TRANSLATORS: format a liter number with l/L as abbreviation
84 		PREFS->vehicle_unit_vol  = _("%.2f l");
85 		if(!PREFS->vehicle_unit_ismile)
86 			//TRANSLATORS: kilometer per liter
87 			PREFS->vehicle_unit_distbyvol  = _("km/l");
88 		else
89 			//TRANSLATORS: miles per liter
90 			PREFS->vehicle_unit_distbyvol  = _("mi./l");
91 	}
92 	// unit is gallon
93 	else
94 	{
95 		PREFS->vehicle_unit_vol  = "%.2f gal.";
96 		if(!PREFS->vehicle_unit_ismile)
97 			PREFS->vehicle_unit_distbyvol  = "km/gal.";
98 		else
99 			PREFS->vehicle_unit_distbyvol  = "mi./gal.";
100 	}
101 
102 }
103 
104 
homebank_pref_free(void)105 void homebank_pref_free(void)
106 {
107 	DB( g_print("\n[preferences] free\n") );
108 
109 
110 	g_free(PREFS->date_format);
111 
112 	g_free(PREFS->color_exp);
113 	g_free(PREFS->color_inc);
114 	g_free(PREFS->color_warn);
115 
116 	g_free(PREFS->path_hbfile);
117 	g_free(PREFS->path_import);
118 	g_free(PREFS->path_export);
119 	//g_free(PREFS->path_navigator);
120 
121 	g_free(PREFS->language);
122 
123 	g_free(PREFS->pnl_list_tab);
124 
125 	g_free(PREFS->minor_cur.symbol);
126 	g_free(PREFS->minor_cur.decimal_char);
127 	g_free(PREFS->minor_cur.grouping_char);
128 
129 	memset(PREFS, 0, sizeof(struct Preferences));
130 }
131 
132 
133 gint
homebank_pref_list_column_get(gint * cols_id,gint uid,gint maxcol)134 homebank_pref_list_column_get(gint *cols_id, gint uid, gint maxcol)
135 {
136 gint i;
137 
138 	for(i=0; i < maxcol ; i++ )
139 	{
140 		if( uid == ABS(cols_id[i]) )
141 			return cols_id[i];
142 
143 		/* secure point */
144 		if( i > 50)
145 			break;
146 	}
147 	return uid;
148 }
149 
150 
homebank_pref_setdefault(void)151 void homebank_pref_setdefault(void)
152 {
153 gint i;
154 
155 	DB( g_print("\n[preferences] pref init\n") );
156 
157 	homebank_pref_free();
158 
159 	PREFS->language = NULL;
160 
161 	PREFS->date_format = g_strdup(DEFAULT_FORMAT_DATE);
162 
163 	PREFS->path_hbfile = g_strdup_printf("%s", g_get_home_dir ());
164 	PREFS->path_hbbak  = g_strdup_printf("%s", g_get_home_dir ());
165 	PREFS->path_import = g_strdup_printf("%s", g_get_home_dir ());
166 	PREFS->path_export = g_strdup_printf("%s", g_get_home_dir ());
167 	//PREFS->path_navigator = g_strdup(DEFAULT_PATH_NAVIGATOR);
168 
169 	PREFS->showsplash = TRUE;
170 	PREFS->showwelcome = TRUE;
171 	PREFS->loadlast = TRUE;
172 	PREFS->appendscheduled = FALSE;
173 	PREFS->do_update_currency = FALSE;
174 
175 	PREFS->bak_is_automatic = TRUE;
176 	PREFS->bak_max_num_copies = 5;
177 
178 	PREFS->heritdate = FALSE;
179 	PREFS->txn_showconfirm = FALSE;
180 	PREFS->hidereconciled = FALSE;
181 	PREFS->showremind = TRUE;
182 	PREFS->showvoid = TRUE;
183 	PREFS->includeremind = FALSE;
184 	//#1673048
185 	PREFS->txn_memoacp = TRUE;
186 	PREFS->txn_memoacp_days = 365;
187 	//#1887212
188 	PREFS->txn_xfer_daygap = 2;
189 
190 	PREFS->toolbar_style = 4;	//text beside icons
191 	PREFS->grid_lines = GTK_TREE_VIEW_GRID_LINES_NONE;
192 
193 	PREFS->gtk_override = FALSE;
194 	PREFS->gtk_fontsize = 10;
195 
196 	PREFS->custom_colors = TRUE;
197 	PREFS->color_exp  = g_strdup(DEFAULT_EXP_COLOR);
198 	PREFS->color_inc  = g_strdup(DEFAULT_INC_COLOR);
199 	PREFS->color_warn = g_strdup(DEFAULT_WARN_COLOR);
200 
201 	/* fiscal year */
202 	PREFS->fisc_year_day = 1;
203 	PREFS->fisc_year_month = 1;
204 
205 	/* windows position/size */
206 	homebank_pref_init_wingeometry(&PREFS->wal_wg, 0, 0, 1024, 600);
207 	homebank_pref_init_wingeometry(&PREFS->acc_wg, 0, 0, 1024, 600);
208 	homebank_pref_init_wingeometry(&PREFS->sta_wg, 0, 0, 800, 494);
209 	homebank_pref_init_wingeometry(&PREFS->tme_wg, 0, 0, 800, 494);
210 	homebank_pref_init_wingeometry(&PREFS->ove_wg, 0, 0, 800, 494);
211 	homebank_pref_init_wingeometry(&PREFS->bud_wg, 0, 0, 800, 494);
212 	homebank_pref_init_wingeometry(&PREFS->cst_wg, 0, 0, 800, 494);
213 
214 	homebank_pref_init_wingeometry(&PREFS->txn_wg, 0, 0, -1, -1);
215 
216 	currency_get_system_iso();
217 
218 	PREFS->wal_toolbar = TRUE;
219 	PREFS->wal_spending = TRUE;
220 	PREFS->wal_upcoming = TRUE;
221 	PREFS->wal_vpaned = 600/2;
222 	PREFS->wal_hpaned = 1024/2;
223 
224 	PREFS->pnl_acc_col_acc_width = -1;
225 	PREFS->pnl_acc_show_by = 0;
226 	i = 0;
227 	PREFS->lst_acc_columns[i++] = COL_DSPACC_STATUS;
228 	PREFS->lst_acc_columns[i++] = COL_DSPACC_ACCOUNTS;
229 	PREFS->lst_acc_columns[i++] = COL_DSPACC_CLEAR;
230 	PREFS->lst_acc_columns[i++] = COL_DSPACC_RECON;
231 	PREFS->lst_acc_columns[i++] = COL_DSPACC_TODAY;
232 	PREFS->lst_acc_columns[i++] = COL_DSPACC_FUTURE;
233 
234 	PREFS->pnl_upc_col_pay_width = -1;
235 	PREFS->pnl_upc_col_mem_width = -1;
236 	PREFS->pnl_upc_range = FLT_SCHEDULED_ALLDATE;
237 
238 	i = 0;
239 	PREFS->lst_impope_columns[i++] = LST_DSPOPE_DATE;	  //always displayed
240 	PREFS->lst_impope_columns[i++] = LST_DSPOPE_MEMO;
241 	PREFS->lst_impope_columns[i++] = LST_DSPOPE_AMOUNT;
242 	PREFS->lst_impope_columns[i++] = LST_DSPOPE_INFO;
243 	PREFS->lst_impope_columns[i++] = LST_DSPOPE_PAYEE;
244 	PREFS->lst_impope_columns[i++] = LST_DSPOPE_CATEGORY;
245 	PREFS->lst_impope_columns[i++] = -LST_DSPOPE_TAGS;
246 	PREFS->lst_impope_columns[i++] = -LST_DSPOPE_CLR;
247 	PREFS->lst_impope_columns[i++] = -LST_DSPOPE_STATUS;  //always displayed
248 	PREFS->lst_impope_columns[i++] = -LST_DSPOPE_EXPENSE;
249 	PREFS->lst_impope_columns[i++] = -LST_DSPOPE_INCOME;
250 	PREFS->lst_impope_columns[i++] = -LST_DSPOPE_BALANCE;
251 	PREFS->lst_impope_columns[i++] = -LST_DSPOPE_ACCOUNT;
252 
253 	i = 0;
254 	PREFS->lst_ope_columns[i++] = LST_DSPOPE_STATUS;  //always displayed
255 	PREFS->lst_ope_columns[i++] = LST_DSPOPE_DATE;	  //always displayed
256 	PREFS->lst_ope_columns[i++] = LST_DSPOPE_INFO;
257 	PREFS->lst_ope_columns[i++] = LST_DSPOPE_PAYEE;
258 	PREFS->lst_ope_columns[i++] = LST_DSPOPE_CATEGORY;
259 	PREFS->lst_ope_columns[i++] = LST_DSPOPE_TAGS;
260 	PREFS->lst_ope_columns[i++] = LST_DSPOPE_CLR;
261 	PREFS->lst_ope_columns[i++] = -LST_DSPOPE_AMOUNT;
262 	PREFS->lst_ope_columns[i++] = LST_DSPOPE_EXPENSE;
263 	PREFS->lst_ope_columns[i++] = LST_DSPOPE_INCOME;
264 	PREFS->lst_ope_columns[i++] = LST_DSPOPE_BALANCE;
265 	PREFS->lst_ope_columns[i++] = LST_DSPOPE_MEMO;
266 	PREFS->lst_ope_columns[i++] = -LST_DSPOPE_ACCOUNT;
267 
268 	PREFS->lst_ope_sort_id    = LST_DSPOPE_DATE;
269 	PREFS->lst_ope_sort_order = GTK_SORT_ASCENDING;
270 
271 	for( i=0;i<NUM_LST_DSPOPE;i++)
272 		PREFS->lst_ope_col_width[i] = -1;
273 
274 	//PREFS->base_cur.nbdecimal = 2;
275 	//PREFS->base_cur.separator = TRUE;
276 
277 	//PREFS->date_range_wal = FLT_RANGE_LASTMONTH;
278 	//PREFS->date_range_txn = FLT_RANGE_LAST12MONTHS;
279 	//PREFS->date_range_rep = FLT_RANGE_THISYEAR;
280 
281 	//v5.2 change to let the example file show things
282 	PREFS->date_range_wal = FLT_RANGE_ALLDATE;
283 	PREFS->date_range_txn = FLT_RANGE_ALLDATE;
284 	PREFS->date_range_rep = FLT_RANGE_ALLDATE;
285 	PREFS->date_future_nbdays = 0;
286 	PREFS->rep_maxspenditems = 10;
287 
288 	//import/export
289 	PREFS->dtex_nointro = TRUE;
290 	PREFS->dtex_dodefpayee = FALSE;
291 	PREFS->dtex_doautoassign = FALSE;
292 
293 	PREFS->dtex_ucfirst = FALSE;
294 	//PREFS->dtex_datefmt
295 	PREFS->dtex_ofxname = 1;
296 	PREFS->dtex_ofxmemo = 2;
297 	PREFS->dtex_qifmemo = TRUE;
298 	PREFS->dtex_qifswap = FALSE;
299 	PREFS->dtex_csvsep = PRF_DTEX_CSVSEP_SEMICOLON;
300 
301 	//todo: add intelligence here
302 	PREFS->euro_active  = FALSE;
303 
304 	PREFS->euro_country = 0;
305 	PREFS->euro_value   = 1.0;
306 
307 	da_cur_initformat(&PREFS->minor_cur);
308 
309 	//PREFS->euro_nbdec   = 2;
310 	//PREFS->euro_thsep   = TRUE;
311 	//PREFS->euro_symbol	= g_strdup("??");
312 
313 	PREFS->stat_byamount   = FALSE;
314 	PREFS->stat_showdetail = FALSE;
315 	PREFS->stat_showrate   = FALSE;
316 	PREFS->budg_showdetail = FALSE;
317 	PREFS->report_color_scheme = CHART_COLMAP_HOMEBANK;
318 
319 	//PREFS->chart_legend = FALSE;
320 
321 	PREFS->vehicle_unit_ismile = FALSE;
322 	PREFS->vehicle_unit_isgal  = FALSE;
323 
324 	_homebank_pref_init_measurement_units();
325 
326 }
327 
328 
329 /*
330 ** load preference from homedir/.homebank (HB_DATA_PATH)
331 */
homebank_pref_get_wingeometry(GKeyFile * key_file,const gchar * group_name,const gchar * key,struct WinGeometry * storage)332 static void homebank_pref_get_wingeometry(
333 	GKeyFile *key_file,
334     const gchar *group_name,
335     const gchar *key,
336 	struct WinGeometry *storage)
337 {
338 	if( g_key_file_has_key(key_file, group_name, key, NULL) )
339 	{
340 	gint *wg;
341 	gsize length;
342 
343 		wg = g_key_file_get_integer_list(key_file, group_name, key, &length, NULL);
344 		memcpy(storage, wg, 5*sizeof(gint));
345 		g_free(wg);
346 		// #606613 ensure left/top to be > 0
347 		if(storage->l < 0)
348 			storage->l = 0;
349 
350 		if(storage->t < 0)
351 			storage->t = 0;
352 	}
353 }
354 
355 
356 
357 
homebank_pref_get_boolean(GKeyFile * key_file,const gchar * group_name,const gchar * key,gboolean * storage)358 static void homebank_pref_get_boolean(
359 	GKeyFile *key_file,
360     const gchar *group_name,
361     const gchar *key,
362 	gboolean *storage)
363 {
364 	DB( g_print(" search %s in %s\n", key, group_name) );
365 
366 	if( g_key_file_has_key(key_file, group_name, key, NULL) )
367 	{
368 		*storage = g_key_file_get_boolean(key_file, group_name, key, NULL);
369 		DB( g_print(" stored boolean %d for %s at %x\n", *storage, key, *storage) );
370 	}
371 }
372 
homebank_pref_get_integer(GKeyFile * key_file,const gchar * group_name,const gchar * key,gint * storage)373 static void homebank_pref_get_integer(
374 	GKeyFile *key_file,
375     const gchar *group_name,
376     const gchar *key,
377 	gint *storage)
378 {
379 	DB( g_print(" search %s in %s\n", key, group_name) );
380 
381 	if( g_key_file_has_key(key_file, group_name, key, NULL) )
382 	{
383 		*storage = g_key_file_get_integer(key_file, group_name, key, NULL);
384 		DB( g_print(" stored integer %d for %s at %x\n", *storage, key, *storage) );
385 	}
386 }
387 
homebank_pref_get_guint32(GKeyFile * key_file,const gchar * group_name,const gchar * key,guint32 * storage)388 static void homebank_pref_get_guint32(
389 	GKeyFile *key_file,
390     const gchar *group_name,
391     const gchar *key,
392 	guint32 *storage)
393 {
394 	DB( g_print(" search %s in %s\n", key, group_name) );
395 
396 	if( g_key_file_has_key(key_file, group_name, key, NULL) )
397 	{
398 		*storage = g_key_file_get_integer(key_file, group_name, key, NULL);
399 		DB( g_print(" stored guint32 %d for %s at %x\n", *storage, key, *storage) );
400 	}
401 }
402 
homebank_pref_get_short(GKeyFile * key_file,const gchar * group_name,const gchar * key,gshort * storage)403 static void homebank_pref_get_short(
404 	GKeyFile *key_file,
405     const gchar *group_name,
406     const gchar *key,
407 	gshort *storage)
408 {
409 	DB( g_print(" search %s in %s\n", key, group_name) );
410 
411 	if( g_key_file_has_key(key_file, group_name, key, NULL) )
412 	{
413 		*storage = (gshort)g_key_file_get_integer(key_file, group_name, key, NULL);
414 		DB( g_print(" stored short %d for %s at %x\n", *storage, key, *storage) );
415 	}
416 }
417 
homebank_pref_get_string(GKeyFile * key_file,const gchar * group_name,const gchar * key,gchar ** storage)418 static void homebank_pref_get_string(
419 	GKeyFile *key_file,
420     const gchar *group_name,
421     const gchar *key,
422 	gchar **storage)
423 {
424 gchar *string;
425 
426 	if( g_key_file_has_key(key_file, group_name, key, NULL) )
427 	{
428 		/* free any previous string */
429 		if( *storage != NULL )
430 		{
431 			//DB( g_print(" storage was not null, freeing\n") );
432 
433 			g_free(*storage);
434 		}
435 
436 		*storage = NULL;
437 
438 		string = g_key_file_get_string(key_file, group_name, key, NULL);
439 		if( string != NULL )
440 		{
441 			//*storage = g_strdup(string);
442 			//leak
443 			*storage = string;	//already a new allocated string
444 
445 			//DB( g_print(" store '%s' for %s at %x\n", string, key, *storage) );
446 		}
447 	}
448 
449 /*
450 	if (error)
451     {
452       g_warning ("error: %s\n", error->message);
453       g_error_free(error);
454       error = NULL;
455     }
456 */
457 
458 
459 }
460 
461 
homebank_pref_currfmt_convert(Currency * cur,gchar * prefix,gchar * suffix)462 static void homebank_pref_currfmt_convert(Currency *cur, gchar *prefix, gchar *suffix)
463 {
464 
465 	if( (prefix != NULL) && (strlen(prefix) > 0) )
466 	{
467 		cur->symbol = g_strdup(prefix);
468 		cur->sym_prefix = TRUE;
469 	}
470 	else if( (suffix != NULL) )
471 	{
472 		cur->symbol = g_strdup(suffix);
473 		cur->sym_prefix = FALSE;
474 	}
475 }
476 
477 
homebank_pref_apply(void)478 void homebank_pref_apply(void)
479 {
480 GtkSettings *settings = gtk_settings_get_default();
481 
482 	DB( g_print("\n[preferences] pref apply\n") );
483 
484 	if( PREFS->gtk_override == TRUE )
485 	{
486 	PangoFontDescription *pfd;
487 	gchar *oldfn, *newfn;
488 
489 		g_object_get(settings, "gtk-font-name", &oldfn, NULL);
490 		pfd = pango_font_description_from_string(oldfn);
491 		DB( g_print(" font-name '%s' == '%s' %d\n", oldfn, pango_font_description_get_family(pfd), pango_font_description_get_size(pfd)/PANGO_SCALE) );
492 		g_free(oldfn);
493 
494 		pango_font_description_set_size(pfd, PREFS->gtk_fontsize*PANGO_SCALE);
495 
496 		newfn = pango_font_description_to_string(pfd);
497 		DB( g_print(" font-name '%s' == '%s' %d\n", newfn, pango_font_description_get_family(fd), pango_font_description_get_size(fd)/PANGO_SCALE) );
498 		g_object_set(settings, "gtk-font-name", newfn, NULL);
499 		g_free(newfn);
500 
501 		pango_font_description_free(pfd);
502 	}
503 	else
504 	{
505 		gtk_settings_reset_property(settings, "gtk-font-name");
506 	}
507 
508 	g_object_set(settings, "gtk-application-prefer-dark-theme", PREFS->gtk_darktheme, NULL);
509 	//gtk_settings_reset_property(settings, "gtk-application-prefer-dark-theme");
510 
511 }
512 
513 
homebank_pref_load(void)514 gboolean homebank_pref_load(void)
515 {
516 GKeyFile *keyfile;
517 gboolean retval = FALSE;
518 gchar *group, *filename;
519 guint32 version = 0;
520 gboolean loaded;
521 GError *error = NULL;
522 
523 	DB( g_print("\n[preferences] pref load\n") );
524 
525 	keyfile = g_key_file_new();
526 	if(keyfile)
527 	{
528 		filename = g_build_filename(homebank_app_get_config_dir(), "preferences", NULL );
529 
530 		DB( g_print(" - filename: %s\n", filename) );
531 
532 		error = NULL;
533 		loaded = g_key_file_load_from_file (keyfile, filename, G_KEY_FILE_NONE, &error);
534 		if( error )
535 		{
536 			g_warning("unable to load file %s: %s", filename, error->message);
537 			g_error_free (error);
538 		}
539 
540 		if( loaded == TRUE )
541 		{
542 
543 			group = "General";
544 
545 				DB( g_print(" -> ** General\n") );
546 
547 				//since 4.51 version is integer
548 				homebank_pref_get_guint32 (keyfile, group, "Version", &version);
549 				if(version == 0)	// old double number
550 				{
551 					gdouble v = g_key_file_get_double (keyfile, group, "Version", NULL);
552 					version = (guint32)(v * 10);
553 				}
554 
555 				DB( g_print(" - version: %d\n", version) );
556 
557 				homebank_pref_get_string(keyfile, group, "Language", &PREFS->language);
558 
559 				homebank_pref_get_short(keyfile, group, "BarStyle" , &PREFS->toolbar_style);
560 
561 				if(version <= 6 && PREFS->toolbar_style == 0)	// force system to text beside
562 				{
563 					PREFS->toolbar_style = 4;
564 				}
565 
566 				//5.4.3
567 				homebank_pref_get_boolean(keyfile, group, "GtkOverride", &PREFS->gtk_override);
568 				homebank_pref_get_short(keyfile, group, "GtkFontSize" , &PREFS->gtk_fontsize);
569 				homebank_pref_get_boolean(keyfile, group, "GtkDarkTheme", &PREFS->gtk_darktheme);
570 
571 				if(version <= 2)	// retrieve old settings
572 				{
573 				guint32 color = 0;
574 
575 					homebank_pref_get_guint32(keyfile, group, "ColorExp" , &color);
576 					g_free(PREFS->color_exp);
577 					PREFS->color_exp = g_strdup_printf("#%06x", color);
578 
579 					homebank_pref_get_guint32(keyfile, group, "ColorInc" , &color);
580 					g_free(PREFS->color_inc);
581 					PREFS->color_inc = g_strdup_printf("#%06x", color);
582 
583 					homebank_pref_get_guint32(keyfile, group, "ColorWarn", &color);
584 					g_free(PREFS->color_warn);
585 					PREFS->color_warn = g_strdup_printf("#%06x", color);
586 				}
587 				else
588 				{
589 					homebank_pref_get_boolean(keyfile, group, "CustomColors", &PREFS->custom_colors);
590 
591 					homebank_pref_get_string(keyfile, group, "ColorExp" , &PREFS->color_exp);
592 					homebank_pref_get_string(keyfile, group, "ColorInc" , &PREFS->color_inc);
593 					homebank_pref_get_string(keyfile, group, "ColorWarn", &PREFS->color_warn);
594 
595 					if( version <= 500 )
596 					{
597 					gboolean rules_hint = FALSE;
598 
599 						homebank_pref_get_boolean(keyfile, group, "RulesHint", &rules_hint);
600 						if( rules_hint == TRUE )
601 							PREFS->grid_lines = GTK_TREE_VIEW_GRID_LINES_HORIZONTAL;
602 
603 					}
604 					else
605 						homebank_pref_get_short(keyfile, group, "GridLines", &PREFS->grid_lines);
606 
607 					//we disable showwelcome for old users
608 					if( version < 540 )
609 						PREFS->showwelcome = FALSE;
610 				}
611 
612 				DB( g_print(" - color exp: %s\n", PREFS->color_exp) );
613 				DB( g_print(" - color inc: %s\n", PREFS->color_inc) );
614 				DB( g_print(" - color wrn: %s\n", PREFS->color_warn) );
615 
616 
617 				homebank_pref_get_string(keyfile, group, "WalletPath", &PREFS->path_hbfile);
618 				homebank_pref_get_string(keyfile, group, "BackupPath", &PREFS->path_hbbak);
619 				//#1870433 default backup path folder not initialized with wallet folder
620 				if( version < 530 )
621 				{
622 					homebank_pref_get_string(keyfile, group, "WalletPath", &PREFS->path_hbbak);
623 				}
624 				homebank_pref_get_string(keyfile, group, "ImportPath", &PREFS->path_import);
625 				homebank_pref_get_string(keyfile, group, "ExportPath", &PREFS->path_export);
626 
627 				homebank_pref_get_boolean(keyfile, group, "ShowSplash", &PREFS->showsplash);
628 				homebank_pref_get_boolean(keyfile, group, "ShowWelcome", &PREFS->showwelcome);
629 				homebank_pref_get_boolean(keyfile, group, "LoadLast", &PREFS->loadlast);
630 				homebank_pref_get_boolean(keyfile, group, "AppendScheduled", &PREFS->appendscheduled);
631 				homebank_pref_get_boolean(keyfile, group, "UpdateCurrency", &PREFS->do_update_currency);
632 
633 				homebank_pref_get_boolean(keyfile, group, "BakIsAutomatic", &PREFS->bak_is_automatic);
634 				homebank_pref_get_short  (keyfile, group, "BakMaxNumCopies", &PREFS->bak_max_num_copies);
635 
636 				homebank_pref_get_boolean(keyfile, group, "HeritDate", &PREFS->heritdate);
637 				homebank_pref_get_boolean(keyfile, group, "ShowConfirm", &PREFS->txn_showconfirm);
638 				homebank_pref_get_boolean(keyfile, group, "HideReconciled", &PREFS->hidereconciled);
639 				homebank_pref_get_boolean(keyfile, group, "ShowRemind", &PREFS->showremind);
640 				homebank_pref_get_boolean(keyfile, group, "ShowVoid", &PREFS->showvoid);
641 				homebank_pref_get_boolean(keyfile, group, "IncludeRemind", &PREFS->includeremind);
642 				homebank_pref_get_boolean(keyfile, group, "TxnMemoAcp", &PREFS->txn_memoacp);
643 				homebank_pref_get_short  (keyfile, group, "TxnMemoAcpDays", &PREFS->txn_memoacp_days);
644 				homebank_pref_get_short  (keyfile, group, "TxnXferDayGap", &PREFS->txn_xfer_daygap);
645 
646 				if( g_key_file_has_key(keyfile, group, "ColumnsOpe", NULL) )
647 				{
648 				gboolean *bsrc;
649 				gint *src, i, j;
650 				gsize length;
651 
652 					if(version <= 2)	//retrieve old 0.1 or 0.2 visibility boolean
653 					{
654 						bsrc = g_key_file_get_boolean_list(keyfile, group, "ColumnsOpe", &length, NULL);
655 						if( length == NUM_LST_DSPOPE-1 )
656 						{
657 							//and convert
658 							for(i=0; i<NUM_LST_DSPOPE-1 ; i++)
659 							{
660 								PREFS->lst_ope_columns[i] = (bsrc[i] == TRUE) ? i+1 : -(i+1);
661 							}
662 						}
663 						g_free(bsrc);
664 					}
665 					else
666 					{
667 						src = g_key_file_get_integer_list(keyfile, group, "ColumnsOpe", &length, NULL);
668 
669 						DB( g_print(" - length %d (max=%d)\n", length, NUM_LST_DSPOPE) );
670 
671 						if( length == NUM_LST_DSPOPE )
672 						{
673 							DB( g_print(" - copying column order from pref file\n") );
674 							memcpy(PREFS->lst_ope_columns, src, length*sizeof(gint));
675 						}
676 						else
677 						{
678 							if(version <= 7)
679 							{
680 								if( length == NUM_LST_DSPOPE-2 )	//1 less column before v4.5.1
681 								{
682 									DB( g_print(" - upgrade from v7\n") );
683 									DB( g_print(" - copying column order from pref file\n") );
684 									memcpy(PREFS->lst_ope_columns, src, length*sizeof(gint));
685 									//append balance column
686 									PREFS->lst_ope_columns[10] = LST_DSPOPE_BALANCE;
687 								}
688 							}
689 
690 							if(version < 500)
691 							{
692 								if( length == NUM_LST_DSPOPE-2 )	//1 less column before v4.5.1
693 								{
694 									DB( g_print(" - upgrade prior v5.0\n") );
695 									DB( g_print(" - copying column order from pref file\n") );
696 									gboolean added = FALSE;
697 									for(i=0,j=0; i<NUM_LST_DSPOPE-1 ; i++)
698 									{
699 										if( added == FALSE &&
700 										    (ABS(src[i]) == LST_DSPOPE_AMOUNT ||
701 										    ABS(src[i]) == LST_DSPOPE_EXPENSE ||
702 										    ABS(src[i]) == LST_DSPOPE_INCOME) )
703 										{
704 											PREFS->lst_ope_columns[j++] = LST_DSPOPE_CLR;
705 											added = TRUE;
706 										}
707 										PREFS->lst_ope_columns[j++] = src[i];
708 									}
709 								}
710 							}
711 
712 						}
713 
714 						g_free(src);
715 					}
716 
717 				}
718 
719 				if( g_key_file_has_key(keyfile, group, "ColumnsOpeWidth", NULL) )
720 				{
721 				gint *src;
722 				gsize length;
723 
724 					src = g_key_file_get_integer_list(keyfile, group, "ColumnsOpeWidth", &length, NULL);
725 
726 					DB( g_print(" - length %d (max=%d)\n", length, NUM_LST_DSPOPE) );
727 
728 					if( length == NUM_LST_DSPOPE )
729 					{
730 						DB( g_print(" - copying column width from pref file\n") );
731 						memcpy(PREFS->lst_ope_col_width, src, length*sizeof(gint));
732 					}
733 
734 					//leak
735 					g_free(src);
736 
737 				}
738 
739 				homebank_pref_get_integer(keyfile, group, "OpeSortId", &PREFS->lst_ope_sort_id);
740 				homebank_pref_get_integer(keyfile, group, "OpeSortOrder", &PREFS->lst_ope_sort_order);
741 
742 			    DB( g_print(" - set sort to %d %d\n", PREFS->lst_ope_sort_id, PREFS->lst_ope_sort_order) );
743 
744 				homebank_pref_get_short(keyfile, group, "FiscYearDay", &PREFS->fisc_year_day);
745 				homebank_pref_get_short(keyfile, group, "FiscYearMonth", &PREFS->fisc_year_month);
746 
747 
748 			group = "Windows";
749 
750 				DB( g_print(" -> ** Windows\n") );
751 
752 				homebank_pref_get_wingeometry(keyfile, group, "Wal", &PREFS->wal_wg);
753 				homebank_pref_get_wingeometry(keyfile, group, "Acc", &PREFS->acc_wg);
754 				homebank_pref_get_wingeometry(keyfile, group, "Sta", &PREFS->sta_wg);
755 				homebank_pref_get_wingeometry(keyfile, group, "Tme", &PREFS->tme_wg);
756 				homebank_pref_get_wingeometry(keyfile, group, "Ove", &PREFS->ove_wg);
757 				homebank_pref_get_wingeometry(keyfile, group, "Bud", &PREFS->bud_wg);
758 				homebank_pref_get_wingeometry(keyfile, group, "Car", &PREFS->cst_wg);
759 
760 				homebank_pref_get_wingeometry(keyfile, group, "Txn", &PREFS->txn_wg);
761 
762 				if(version <= 7)	//set maximize to 0
763 				{
764 					PREFS->wal_wg.s = 0;
765 					PREFS->acc_wg.s = 0;
766 					PREFS->txn_wg.s = 0;
767 					PREFS->sta_wg.s = 0;
768 					PREFS->tme_wg.s = 0;
769 					PREFS->ove_wg.s = 0;
770 					PREFS->bud_wg.s = 0;
771 					PREFS->cst_wg.s = 0;
772 				}
773 				homebank_pref_get_integer(keyfile, group, "WalVPaned", &PREFS->wal_vpaned);
774 				homebank_pref_get_integer(keyfile, group, "WalHPaned", &PREFS->wal_hpaned);
775 				homebank_pref_get_boolean(keyfile, group, "WalToolbar", &PREFS->wal_toolbar);
776 				homebank_pref_get_boolean(keyfile, group, "WalSpending", &PREFS->wal_spending);
777 				homebank_pref_get_boolean(keyfile, group, "WalUpcoming", &PREFS->wal_upcoming);
778 
779 			//since 5.1.3
780 			group = "Panels";
781 
782 				DB( g_print(" -> ** Panels\n") );
783 
784 				homebank_pref_get_short(keyfile, group, "AccColAccW", &PREFS->pnl_acc_col_acc_width);
785 				homebank_pref_get_short(keyfile, group, "AccShowBy" , &PREFS->pnl_acc_show_by);
786 
787 				{
788 				gint *src;
789 				gsize length;
790 					src = g_key_file_get_integer_list(keyfile, group, "AccColumns", &length, NULL);
791 
792 					DB( g_print(" - length %d (max=%d)\n", length, NUM_LST_DSPOPE) );
793 
794 					if( length == NUM_LST_COL_DSPACC )
795 					{
796 						DB( g_print(" - copying column order from pref file\n") );
797 						memcpy(PREFS->lst_acc_columns, src, length*sizeof(gint));
798 					}
799 					g_free(src);
800 				}
801 
802 				homebank_pref_get_short(keyfile, group, "UpcColPayW", &PREFS->pnl_upc_col_pay_width);
803 				homebank_pref_get_short(keyfile, group, "UpcColMemW", &PREFS->pnl_upc_col_mem_width);
804 				homebank_pref_get_integer(keyfile, group, "UpcRange", &PREFS->pnl_upc_range);
805 
806 				homebank_pref_get_string(keyfile, group, "PnlLstTab", &PREFS->pnl_list_tab);
807 
808 			group = "Format";
809 
810 				DB( g_print(" -> ** Format\n") );
811 
812 				homebank_pref_get_string(keyfile, group, "DateFmt", &PREFS->date_format);
813 
814 				if(version < 460)
815 				{
816 				gboolean useimperial = FALSE;
817 
818 					homebank_pref_get_boolean(keyfile, group, "UKUnits", &useimperial);
819 					if(useimperial)
820 					{
821 						PREFS->vehicle_unit_ismile = TRUE;
822 						PREFS->vehicle_unit_isgal = TRUE;
823 					}
824 				}
825 
826 				homebank_pref_get_boolean(keyfile, group, "UnitIsMile", &PREFS->vehicle_unit_ismile);
827 				homebank_pref_get_boolean(keyfile, group, "UnitIsGal", &PREFS->vehicle_unit_isgal);
828 
829 
830 			group = "Filter";
831 
832 				DB( g_print(" -> ** Filter\n") );
833 
834 				homebank_pref_get_integer(keyfile, group, "DateRangeWal", &PREFS->date_range_wal);
835 				homebank_pref_get_integer(keyfile, group, "DateRangeTxn", &PREFS->date_range_txn);
836 				homebank_pref_get_integer(keyfile, group, "DateFutureNbDays", &PREFS->date_future_nbdays);
837 				homebank_pref_get_integer(keyfile, group, "DateRangeRep", &PREFS->date_range_rep);
838 
839 				if(version <= 7)
840 				{
841 					// shift date range >= 5, since we inserted a new one at position 5
842 					if(PREFS->date_range_wal >= FLT_RANGE_LASTYEAR)
843 						PREFS->date_range_wal++;
844 					if(PREFS->date_range_txn >= FLT_RANGE_LASTYEAR)
845 						PREFS->date_range_txn++;
846 					if(PREFS->date_range_rep >= FLT_RANGE_LASTYEAR)
847 						PREFS->date_range_rep++;
848 				}
849 
850 
851 			group = "Euro";
852 
853 				DB( g_print(" -> ** Euro\n") );
854 
855 				//homebank_pref_get_string(keyfile, group, "DefCurrency" , &PREFS->curr_default);
856 
857 				homebank_pref_get_boolean(keyfile, group, "Active", &PREFS->euro_active);
858 				homebank_pref_get_integer(keyfile, group, "Country", &PREFS->euro_country);
859 
860 				gchar *ratestr = g_key_file_get_string (keyfile, group, "ChangeRate", NULL);
861 				if(ratestr != NULL) PREFS->euro_value = g_ascii_strtod(ratestr, NULL);
862 
863 				if(version <= 1)
864 				{
865 					homebank_pref_get_string(keyfile, group, "Symbol", &PREFS->minor_cur.symbol);
866 					PREFS->minor_cur.frac_digits = g_key_file_get_integer (keyfile, group, "NBDec", NULL);
867 
868 					//PREFS->euro_nbdec = g_key_file_get_integer (keyfile, group, "NBDec", NULL);
869 					//PREFS->euro_thsep = g_key_file_get_boolean (keyfile, group, "Sep", NULL);
870 					//gchar *tmpstr = g_key_file_get_string  (keyfile, group, "Symbol", &error);
871 				}
872 				else
873 				{
874 					if(version < 460)
875 					{
876 					gchar *prefix = NULL;
877 					gchar *suffix = NULL;
878 
879 						homebank_pref_get_string(keyfile, group, "PreSymbol", &prefix);
880 						homebank_pref_get_string(keyfile, group, "SufSymbol", &suffix);
881 						homebank_pref_currfmt_convert(&PREFS->minor_cur, prefix, suffix);
882 						g_free(prefix);
883 						g_free(suffix);
884 					}
885 					else
886 					{
887 						homebank_pref_get_string(keyfile, group, "Symbol", &PREFS->minor_cur.symbol);
888 						homebank_pref_get_boolean(keyfile, group, "IsPrefix", &PREFS->minor_cur.sym_prefix);
889 					}
890 					homebank_pref_get_string(keyfile, group, "DecChar"  , &PREFS->minor_cur.decimal_char);
891 					homebank_pref_get_string(keyfile, group, "GroupChar", &PREFS->minor_cur.grouping_char);
892 					homebank_pref_get_short(keyfile, group, "FracDigits", &PREFS->minor_cur.frac_digits);
893 
894 					//fix 378992/421228
895 					if( PREFS->minor_cur.frac_digits > MAX_FRAC_DIGIT )
896 						PREFS->minor_cur.frac_digits = MAX_FRAC_DIGIT;
897 
898 					da_cur_initformat(&PREFS->minor_cur);
899 				}
900 
901 			//PREFS->euro_symbol = g_locale_to_utf8(tmpstr, -1, NULL, NULL, NULL);
902 
903 			group = "Report";
904 
905 				DB( g_print(" -> ** Report\n") );
906 
907 				homebank_pref_get_boolean(keyfile, group, "StatByAmount", &PREFS->stat_byamount);
908 				homebank_pref_get_boolean(keyfile, group, "StatDetail", &PREFS->stat_showdetail);
909 				homebank_pref_get_boolean(keyfile, group, "StatRate", &PREFS->stat_showrate);
910 				homebank_pref_get_boolean(keyfile, group, "BudgDetail", &PREFS->budg_showdetail);
911 				homebank_pref_get_integer(keyfile, group, "ColorScheme", &PREFS->report_color_scheme);
912 				homebank_pref_get_boolean(keyfile, group, "SmallFont", &PREFS->rep_smallfont);
913 				homebank_pref_get_integer(keyfile, group, "MaxSpendItems", &PREFS->rep_maxspenditems);
914 
915 			group = "Exchange";
916 
917 				DB( g_print(" -> ** Exchange\n") );
918 
919 				homebank_pref_get_boolean(keyfile, group, "DoIntro", &PREFS->dtex_nointro);
920 				homebank_pref_get_boolean(keyfile, group, "UcFirst", &PREFS->dtex_ucfirst);
921 				homebank_pref_get_integer(keyfile, group, "DateFmt", &PREFS->dtex_datefmt);
922 				homebank_pref_get_integer(keyfile, group, "DayGap", &PREFS->dtex_daygap);
923 				homebank_pref_get_integer(keyfile, group, "OfxName", &PREFS->dtex_ofxname);
924 				homebank_pref_get_integer(keyfile, group, "OfxMemo", &PREFS->dtex_ofxmemo);
925 				homebank_pref_get_boolean(keyfile, group, "QifMemo", &PREFS->dtex_qifmemo);
926 				homebank_pref_get_boolean(keyfile, group, "QifSwap", &PREFS->dtex_qifswap);
927 				homebank_pref_get_integer(keyfile, group, "CsvSep", &PREFS->dtex_csvsep);
928 				homebank_pref_get_boolean(keyfile, group, "DoDefPayee", &PREFS->dtex_dodefpayee);
929 				homebank_pref_get_boolean(keyfile, group, "DoAutoAssign", &PREFS->dtex_doautoassign);
930 
931 			//group = "Chart";
932 			//PREFS->chart_legend = g_key_file_get_boolean (keyfile, group, "Legend", NULL);
933 
934 
935 			/*
936 			#if MYDEBUG == 1
937 			gsize length;
938 			gchar *contents = g_key_file_to_data (keyfile, &length, NULL);
939 			//g_print(" keyfile:\n%s\n len=%d\n", contents, length);
940 			g_free(contents);
941 			#endif
942 			*/
943 
944 		}
945 		g_free(filename);
946 		g_key_file_free (keyfile);
947 
948 		_homebank_pref_init_measurement_units();
949 	}
950 
951 	return retval;
952 }
953 
954 
homebank_pref_set_string(GKeyFile * key_file,const gchar * group_name,const gchar * key,gchar * string)955 static void homebank_pref_set_string(
956 	GKeyFile *key_file,
957     const gchar *group_name,
958     const gchar *key,
959 	gchar *string)
960 {
961 
962 	DB( g_print(" - homebank_pref_set_string :: group='%s' key='%s' value='%s'\n", group_name, key, string) );
963 
964 	if( string != NULL && *string != '\0')
965 		g_key_file_set_string  (key_file, group_name, key, string);
966 	else
967 		g_key_file_set_string  (key_file, group_name, key, "");
968 
969 }
970 
971 
972 /*
973 ** save preference to homedir/.homebank (HB_DATA_PATH)
974 */
homebank_pref_save(void)975 gboolean homebank_pref_save(void)
976 {
977 GKeyFile *keyfile;
978 gboolean retval = FALSE;
979 gchar *group, *filename;
980 gsize length;
981 GError *error = NULL;
982 
983 	DB( g_print("\n[preferences] pref save\n") );
984 
985 	keyfile = g_key_file_new();
986 	if(keyfile )
987 	{
988 
989 		DB( g_print(" -> ** general\n") );
990 
991 
992 		group = "General";
993 		g_key_file_set_integer  (keyfile, group, "Version", PREF_VERSION);
994 
995 		homebank_pref_set_string  (keyfile, group, "Language", PREFS->language);
996 
997 		g_key_file_set_integer (keyfile, group, "BarStyle", PREFS->toolbar_style);
998 		//g_key_file_set_integer (keyfile, group, "BarImageSize", PREFS->image_size);
999 
1000 		g_key_file_set_boolean (keyfile, group, "GtkOverride", PREFS->gtk_override);
1001 		g_key_file_set_integer (keyfile, group, "GtkFontSize", PREFS->gtk_fontsize);
1002 		g_key_file_set_boolean (keyfile, group, "GtkDarkTheme", PREFS->gtk_darktheme);
1003 
1004 
1005 		g_key_file_set_boolean (keyfile, group, "CustomColors", PREFS->custom_colors);
1006 		g_key_file_set_string (keyfile, group, "ColorExp" , PREFS->color_exp);
1007 		g_key_file_set_string (keyfile, group, "ColorInc" , PREFS->color_inc);
1008 		g_key_file_set_string (keyfile, group, "ColorWarn", PREFS->color_warn);
1009 
1010 		g_key_file_set_integer (keyfile, group, "GridLines", PREFS->grid_lines);
1011 
1012 		homebank_pref_set_string  (keyfile, group, "WalletPath"   , PREFS->path_hbfile);
1013 		homebank_pref_set_string  (keyfile, group, "BackupPath"   , PREFS->path_hbbak);
1014 		homebank_pref_set_string  (keyfile, group, "ImportPath"   , PREFS->path_import);
1015 		homebank_pref_set_string  (keyfile, group, "ExportPath"   , PREFS->path_export);
1016 		//g_key_file_set_string  (keyfile, group, "NavigatorPath", PREFS->path_navigator);
1017 
1018 		g_key_file_set_boolean (keyfile, group, "BakIsAutomatic", PREFS->bak_is_automatic);
1019 		g_key_file_set_integer (keyfile, group, "BakMaxNumCopies", PREFS->bak_max_num_copies);
1020 
1021 		g_key_file_set_boolean (keyfile, group, "ShowSplash", PREFS->showsplash);
1022 		g_key_file_set_boolean (keyfile, group, "ShowWelcome", PREFS->showwelcome);
1023 		g_key_file_set_boolean (keyfile, group, "LoadLast", PREFS->loadlast);
1024 		g_key_file_set_boolean (keyfile, group, "AppendScheduled", PREFS->appendscheduled);
1025 		g_key_file_set_boolean (keyfile, group, "UpdateCurrency", PREFS->do_update_currency);
1026 
1027 		g_key_file_set_boolean (keyfile, group, "HeritDate", PREFS->heritdate);
1028 		g_key_file_set_boolean (keyfile, group, "ShowConfirm", PREFS->txn_showconfirm);
1029 		g_key_file_set_boolean (keyfile, group, "HideReconciled", PREFS->hidereconciled);
1030 		g_key_file_set_boolean (keyfile, group, "ShowRemind", PREFS->showremind);
1031 		g_key_file_set_boolean (keyfile, group, "ShowVoid", PREFS->showvoid);
1032 		g_key_file_set_boolean (keyfile, group, "IncludeRemind", PREFS->includeremind);
1033 		g_key_file_set_boolean (keyfile, group, "TxnMemoAcp", PREFS->txn_memoacp);
1034 		g_key_file_set_integer (keyfile, group, "TxnMemoAcpDays" , PREFS->txn_memoacp_days);
1035 		g_key_file_set_integer (keyfile, group, "TxnXferDayGap" , PREFS->txn_xfer_daygap);
1036 
1037 		g_key_file_set_integer_list(keyfile, group, "ColumnsOpe", PREFS->lst_ope_columns, NUM_LST_DSPOPE);
1038 		g_key_file_set_integer_list(keyfile, group, "ColumnsOpeWidth", PREFS->lst_ope_col_width, NUM_LST_DSPOPE);
1039 		g_key_file_set_integer     (keyfile, group, "OpeSortId" , PREFS->lst_ope_sort_id);
1040 		g_key_file_set_integer     (keyfile, group, "OpeSortOrder" , PREFS->lst_ope_sort_order);
1041 
1042 		g_key_file_set_integer     (keyfile, group, "FiscYearDay" , PREFS->fisc_year_day);
1043 		g_key_file_set_integer     (keyfile, group, "FiscYearMonth" , PREFS->fisc_year_month);
1044 
1045 		// added v3.4
1046 		DB( g_print(" -> ** windows\n") );
1047 
1048 		group = "Windows";
1049 		g_key_file_set_integer_list(keyfile, group, "Wal", (gint *)&PREFS->wal_wg, 5);
1050 		g_key_file_set_integer_list(keyfile, group, "Acc", (gint *)&PREFS->acc_wg, 5);
1051 		g_key_file_set_integer_list(keyfile, group, "Sta", (gint *)&PREFS->sta_wg, 5);
1052 		g_key_file_set_integer_list(keyfile, group, "Tme", (gint *)&PREFS->tme_wg, 5);
1053 		g_key_file_set_integer_list(keyfile, group, "Ove", (gint *)&PREFS->ove_wg, 5);
1054 		g_key_file_set_integer_list(keyfile, group, "Bud", (gint *)&PREFS->bud_wg, 5);
1055 		g_key_file_set_integer_list(keyfile, group, "Car", (gint *)&PREFS->cst_wg, 5);
1056 
1057 		g_key_file_set_integer_list(keyfile, group, "Txn", (gint *)&PREFS->txn_wg, 5);
1058 
1059 		g_key_file_set_integer (keyfile, group, "WalVPaned" , PREFS->wal_vpaned);
1060 		g_key_file_set_integer (keyfile, group, "WalHPaned" , PREFS->wal_hpaned);
1061 		g_key_file_set_boolean (keyfile, group, "WalToolbar", PREFS->wal_toolbar);
1062 		g_key_file_set_boolean (keyfile, group, "WalSpending", PREFS->wal_spending);
1063 		g_key_file_set_boolean (keyfile, group, "WalUpcoming", PREFS->wal_upcoming);
1064 
1065 		//since 5.1.3
1066 		DB( g_print(" -> ** Panels\n") );
1067 
1068 		group = "Panels";
1069 		g_key_file_set_integer(keyfile, group, "AccColAccW", PREFS->pnl_acc_col_acc_width);
1070 		g_key_file_set_integer(keyfile, group, "AccShowBy" , PREFS->pnl_acc_show_by);
1071 		g_key_file_set_integer_list(keyfile, group, "AccColumns", PREFS->lst_acc_columns, NUM_LST_COL_DSPACC);
1072 
1073 		g_key_file_set_integer(keyfile, group, "UpcColPayW", PREFS->pnl_upc_col_pay_width);
1074 		g_key_file_set_integer(keyfile, group, "UpcColMemW", PREFS->pnl_upc_col_mem_width);
1075 		g_key_file_set_integer(keyfile, group, "UpcRange", PREFS->pnl_upc_range);
1076 
1077 		homebank_pref_set_string  (keyfile, group, "PnlLstTab", PREFS->pnl_list_tab);
1078 
1079 		DB( g_print(" -> ** format\n") );
1080 
1081 		group = "Format";
1082 		homebank_pref_set_string  (keyfile, group, "DateFmt"   , PREFS->date_format);
1083 
1084 		//g_key_file_set_boolean (keyfile, group, "UKUnits" , PREFS->imperial_unit);
1085 		g_key_file_set_boolean (keyfile, group, "UnitIsMile" , PREFS->vehicle_unit_ismile);
1086 		g_key_file_set_boolean (keyfile, group, "UnitIsGal" , PREFS->vehicle_unit_isgal);
1087 
1088 
1089 		DB( g_print(" -> ** filter\n") );
1090 
1091 		group = "Filter";
1092 		g_key_file_set_integer (keyfile, group, "DateRangeWal", PREFS->date_range_wal);
1093 		g_key_file_set_integer (keyfile, group, "DateRangeTxn", PREFS->date_range_txn);
1094 		g_key_file_set_integer (keyfile, group, "DateFutureNbDays", PREFS->date_future_nbdays);
1095 		g_key_file_set_integer (keyfile, group, "DateRangeRep", PREFS->date_range_rep);
1096 
1097 		DB( g_print(" -> ** euro\n") );
1098 
1099 	//euro options
1100 		group = "Euro";
1101 
1102 		//homebank_pref_set_string(keyfile, group, "DefCurrency" , PREFS->curr_default);
1103 
1104 		g_key_file_set_boolean (keyfile, group, "Active" , PREFS->euro_active);
1105 		if( PREFS->euro_active )
1106 		{
1107 			g_key_file_set_integer (keyfile, group, "Country", PREFS->euro_country);
1108 			gchar ratestr[64];
1109 			g_ascii_dtostr(ratestr, 63, PREFS->euro_value);
1110 			homebank_pref_set_string  (keyfile, group, "ChangeRate", ratestr);
1111 			homebank_pref_set_string  (keyfile, group, "Symbol" , PREFS->minor_cur.symbol);
1112 			g_key_file_set_boolean    (keyfile, group, "IsPrefix" , PREFS->minor_cur.sym_prefix);
1113 			homebank_pref_set_string  (keyfile, group, "DecChar"   , PREFS->minor_cur.decimal_char);
1114 			homebank_pref_set_string  (keyfile, group, "GroupChar" , PREFS->minor_cur.grouping_char);
1115 			g_key_file_set_integer (keyfile, group, "FracDigits", PREFS->minor_cur.frac_digits);
1116 		}
1117 
1118 	//report options
1119 		DB( g_print(" -> ** report\n") );
1120 
1121 		group = "Report";
1122 		g_key_file_set_boolean (keyfile, group, "StatByAmount" , PREFS->stat_byamount);
1123 		g_key_file_set_boolean (keyfile, group, "StatDetail"   , PREFS->stat_showdetail);
1124 		g_key_file_set_boolean (keyfile, group, "StatRate"     , PREFS->stat_showrate);
1125 		g_key_file_set_boolean (keyfile, group, "BudgDetail"   , PREFS->budg_showdetail);
1126 		g_key_file_set_integer (keyfile, group, "ColorScheme"  , PREFS->report_color_scheme);
1127 		g_key_file_set_boolean (keyfile, group, "SmallFont"    , PREFS->rep_smallfont);
1128 		g_key_file_set_integer (keyfile, group, "MaxSpendItems", PREFS->rep_maxspenditems);
1129 
1130 		group = "Exchange";
1131 		g_key_file_set_boolean (keyfile, group, "DoIntro", PREFS->dtex_nointro);
1132 		g_key_file_set_boolean (keyfile, group, "UcFirst", PREFS->dtex_ucfirst);
1133 		g_key_file_set_integer (keyfile, group, "DateFmt", PREFS->dtex_datefmt);
1134 		g_key_file_set_integer (keyfile, group, "DayGap", PREFS->dtex_daygap);
1135 		g_key_file_set_integer (keyfile, group, "OfxName", PREFS->dtex_ofxname);
1136 		g_key_file_set_integer (keyfile, group, "OfxMemo", PREFS->dtex_ofxmemo);
1137 		g_key_file_set_boolean (keyfile, group, "QifMemo", PREFS->dtex_qifmemo);
1138 		g_key_file_set_boolean (keyfile, group, "QifSwap", PREFS->dtex_qifswap);
1139 		g_key_file_set_integer (keyfile, group, "CsvSep", PREFS->dtex_csvsep);
1140 		g_key_file_set_boolean (keyfile, group, "DoDefPayee", PREFS->dtex_dodefpayee);
1141 		g_key_file_set_boolean (keyfile, group, "DoAutoAssign", PREFS->dtex_doautoassign);
1142 
1143 		//group = "Chart";
1144 		//g_key_file_set_boolean (keyfile, group, "Legend", PREFS->chart_legend);
1145 
1146 		//g_key_file_set_string  (keyfile, group, "", PREFS->);
1147 		//g_key_file_set_boolean (keyfile, group, "", PREFS->);
1148 		//g_key_file_set_integer (keyfile, group, "", PREFS->);
1149 
1150 		DB( g_print(" -> ** g_key_file_to_data\n") );
1151 
1152 		gchar *contents = g_key_file_to_data (keyfile, &length, NULL);
1153 
1154 		//DB( g_print(" keyfile:\n%s\nlen=%d\n", contents, length) );
1155 
1156 		filename = g_build_filename(homebank_app_get_config_dir(), "preferences", NULL );
1157 
1158 		DB( g_print(" -> filename: %s\n", filename) );
1159 
1160 		g_file_set_contents(filename, contents, length, &error);
1161 		if( error )
1162 		{
1163 			g_warning("unable to save file %s: %s", filename, error->message);
1164 			g_error_free (error);
1165 			error = NULL;
1166 		}
1167 
1168 		DB( g_print(" -> contents: %s\n", contents) );
1169 
1170 		DB( g_print(" -> freeing filename\n") );
1171 		g_free(filename);
1172 
1173 		DB( g_print(" -> freeing buffer\n") );
1174 
1175 		g_free(contents);
1176 
1177 		DB( g_print(" -> freeing keyfile\n") );
1178 
1179 		g_key_file_free (keyfile);
1180 	}
1181 
1182 	_homebank_pref_init_measurement_units();
1183 
1184 	return retval;
1185 }
1186 
1187