Improve escaping and quoting of strings saved in rc files.
[geeqie.git] / src / rcfile.c
1 /*
2  * Geeqie
3  * (C) 2006 John Ellis
4  *
5  * Author: John Ellis
6  *
7  * This software is released under the GNU General Public License (GNU GPL).
8  * Please read the included file COPYING for more information.
9  * This software comes with no warranty of any kind, use at your own risk!
10  */
11
12
13 #include "gqview.h"
14 #include "rcfile.h"
15
16 #include "filelist.h"
17 #include "slideshow.h"
18 #include "ui_fileops.h"
19
20
21 /*
22  *-----------------------------------------------------------------------------
23  * line write/parse routines (private)
24  *-----------------------------------------------------------------------------
25  */ 
26
27 gchar *quoted_value(const gchar *text)
28 {
29         const gchar *ptr;
30         gint c = 0;
31         gint l = strlen(text);
32         gchar *retval = NULL;
33         
34         if (l == 0) return retval;
35
36         while (c < l && text[c] !='"') c++;
37         if (text[c] == '"')
38                 {
39                 gint e;
40                 c++;
41                 ptr = text + c;
42                 e = c;
43                 while (e < l)
44                         {
45                         if (text[e-1] != '\\' && text[e] == '"') break;
46                         e++;
47                         }
48                 if (text[e] == '"')
49                         {
50                         if (e - c > 0)
51                                 {
52                                 gchar *substring = g_strndup(ptr, e - c);
53                                 
54                                 if (substring)
55                                         {
56                                         retval = g_strcompress(substring);
57                                         g_free(substring);
58                                         }
59                                 }
60                         }
61                 }
62         else
63                 /* for compatibility with older formats (<0.3.7)
64                  * read a line without quotes too */
65                 {
66                 c = 0;
67                 while (c < l && text[c] !=' ' && text[c] !=8 && text[c] != '\n') c++;
68                 if (c != 0)
69                         {
70                         retval = g_strndup(text, c);
71                         }
72                 }
73
74         return retval;
75 }
76
77 gchar *escquote_value(const gchar *text)
78 {
79         gchar *e;
80         gchar *retval;
81
82         if (!text) return g_strdup("");
83
84         e = g_strescape(text, "");
85         if (e)
86                 {
87                 gchar *retval = g_strdup_printf("\"%s\"", e);
88                 g_free(e);
89                 return retval;
90                 }
91         return g_strdup("");
92 }
93
94 static void write_char_option(FILE *f, gchar *label, gchar *text)
95 {
96         gchar *escval = escquote_value(text);
97
98         if (escval)
99                 {
100                 fprintf(f,"%s: %s\n", label, escval);
101                 g_free(escval);
102                 }
103         else
104                 fprintf(f,"%s: \n", label);
105 }
106
107 static gchar *read_char_option(FILE *f, gchar *option, gchar *label, gchar *value, gchar *text)
108 {
109         if (strcasecmp(option, label) == 0)
110                 {
111                 g_free(text);
112                 text = quoted_value(value);
113                 }
114         return text;
115 }
116
117 static void write_color_option(FILE *f, gchar *label, GdkColor *color)
118 {
119         if (color)
120                 {
121                 gchar *colorstring = gdk_color_to_string (color);
122
123                 fprintf(f,"%s: \"%s\"\n", label, colorstring);
124                 g_free(colorstring);
125                 }
126         else
127                 fprintf(f,"%s: \n", label);
128 }
129
130 static GdkColor *read_color_option(FILE *f, gchar *option, gchar *label, gchar *value, GdkColor *color)
131 {
132         if (strcasecmp(option, label) == 0)
133                 {
134                 gdk_color_parse(quoted_value(value), color);
135                 }
136         return color;
137 }
138
139
140 static void write_int_option(FILE *f, gchar *label, gint n)
141 {
142         fprintf(f,"%s: %d\n\n", label, n);
143 }
144
145 static gint read_int_option(FILE *f, gchar *option, gchar *label, gchar *value, gint n)
146 {
147         if (strcasecmp(option, label) == 0)
148                 {
149                 n = strtol(value, NULL, 10);
150                 }
151         return n;
152 }
153
154 static void write_int_unit_option(FILE *f, gchar *label, gint n, gint subunits)
155 {
156         gint l, r;
157
158         if (subunits > 0)
159                 {
160                 l = n / subunits;
161                 r = n % subunits;
162                 }
163         else
164                 {
165                 l = n;
166                 r = 0;
167                 }
168
169         fprintf(f,"%s: %d.%d\n\n", label, l, r);
170 }
171
172 static gint read_int_unit_option(FILE *f, gchar *option, gchar *label, gchar *value, gint n, gint subunits)
173 {
174         if (strcasecmp(option, label) == 0)
175                 {
176                 gint l, r;
177                 gchar *ptr;
178
179                 ptr = value;
180                 while (*ptr != '\0' && *ptr != '.') ptr++;
181                 if (*ptr == '.')
182                         {
183                         *ptr = '\0';
184                         l = strtol(value, NULL, 10);
185                         *ptr = '.';
186                         ptr++;
187                         r = strtol(ptr, NULL, 10);
188                         }
189                 else
190                         {
191                         l = strtol(value, NULL, 10);
192                         r = 0;
193                         }
194
195                 n = l * subunits + r;
196                 }
197         return n;
198 }
199
200 static void write_bool_option(FILE *f, gchar *label, gint n)
201 {
202         fprintf(f,"%s: ", label);
203         if (n) fprintf(f,"true\n"); else fprintf(f,"false\n");
204         fprintf(f,"\n");
205 }
206
207 static gint read_bool_option(FILE *f, gchar *option, gchar *label, gchar *value, gint n)
208 {
209         if (strcasecmp(option, label) == 0)
210                 {
211                 if (strcasecmp(value, "true") == 0)
212                         n = TRUE;
213                 else
214                         n = FALSE;
215                 }
216         return n;
217 }
218
219 /*
220  *-----------------------------------------------------------------------------
221  * save configuration (public)
222  *-----------------------------------------------------------------------------
223  */ 
224
225 void save_options(void)
226 {
227         FILE *f;
228         gchar *rc_path;
229         gchar *rc_pathl;
230         gint i;
231
232         rc_path = g_strconcat(homedir(), "/", GQVIEW_RC_DIR, "/", RC_FILE_NAME, NULL);
233
234         rc_pathl = path_from_utf8(rc_path);
235         f = fopen(rc_pathl, "w");
236         g_free(rc_pathl);
237         if (!f)
238                 {
239                 gchar *buf;
240
241                 buf = g_strdup_printf(_("error saving config file: %s\n"), rc_path);
242                 print_term(buf);
243                 g_free(buf);
244
245                 g_free(rc_path);
246                 return;
247                 }
248
249         fprintf(f,"######################################################################\n");
250         fprintf(f,"#                         Geeqie config file         version %7s #\n", VERSION);
251         fprintf(f,"######################################################################\n");
252         fprintf(f,"\n");
253         fprintf(f,"# Note: This file is autogenerated. Options can be changed here,\n");
254         fprintf(f,"#       but user comments and formatting will be lost.\n");
255         fprintf(f,"\n");
256         fprintf(f,"##### General Options #####\n\n");
257
258         write_int_option(f, "layout_style", layout_style);
259         write_char_option(f, "layout_order", layout_order);
260         fprintf(f,"\n");
261         write_bool_option(f, "layout_view_as_icons", layout_view_icons);
262         write_bool_option(f, "layout_view_as_tree", layout_view_tree);
263         write_bool_option(f, "show_icon_names", show_icon_names);
264         fprintf(f,"\n");
265
266         write_bool_option(f, "tree_descend_folders", tree_descend_subdirs);
267         write_bool_option(f, "lazy_image_sync", lazy_image_sync);
268         write_bool_option(f, "update_on_time_change", update_on_time_change);
269         write_bool_option(f, "exif_auto_rotate", exif_rotate_enable);
270         fprintf(f,"\n");
271
272         write_bool_option(f, "enable_startup_path", startup_path_enable);
273         write_char_option(f, "startup_path", startup_path);
274         fprintf(f,"\n");
275
276         fprintf(f,"zoom_mode: ");
277         if (zoom_mode == ZOOM_RESET_ORIGINAL) fprintf(f,"original\n");
278         if (zoom_mode == ZOOM_RESET_FIT_WINDOW) fprintf(f,"fit\n");
279         if (zoom_mode == ZOOM_RESET_NONE) fprintf(f,"dont_change\n");
280
281         write_bool_option(f, "two_pass_scaling", two_pass_zoom);
282
283         write_bool_option(f, "zoom_to_fit_allow_expand", zoom_to_fit_expands);
284         fprintf(f,"\n");
285
286         write_bool_option(f, "fit_window_to_image", fit_window);
287         write_bool_option(f, "limit_window_size", limit_window_size);
288         write_int_option(f, "max_window_size", max_window_size);
289         write_bool_option(f, "limit_autofit_size", limit_autofit_size);
290         write_int_option(f, "max_autofit_size", max_autofit_size);
291         fprintf(f,"\n");
292
293         write_bool_option(f, "progressive_keyboard_scrolling", progressive_key_scrolling);
294         write_int_option(f, "scroll_reset_method", scroll_reset_method);
295         fprintf(f,"\n");
296
297         write_bool_option(f, "enable_thumbnails", thumbnails_enabled);
298         write_int_option(f, "thumbnail_width", thumb_max_width);
299         write_int_option(f, "thumbnail_height", thumb_max_height);
300         write_bool_option(f, "cache_thumbnails", enable_thumb_caching);
301         write_bool_option(f, "cache_thumbnails_into_dirs", enable_thumb_dirs);
302         write_bool_option(f, "thumbnail_fast", thumbnail_fast);
303         write_bool_option(f, "use_xvpics_thumbnails", use_xvpics_thumbnails);
304         write_bool_option(f, "thumbnail_spec_standard", thumbnail_spec_standard);
305         fprintf(f,"\n");
306
307         write_bool_option(f, "local_metadata", enable_metadata_dirs);
308         fprintf(f,"\n");
309
310         write_int_option(f, "sort_method", (gint)file_sort_method);
311         write_bool_option(f, "sort_ascending", file_sort_ascending);
312         write_bool_option(f, "sort_case_sensitive", file_sort_case_sensitive);
313         fprintf(f,"\n");
314
315         write_bool_option(f, "confirm_delete", confirm_delete);
316         write_bool_option(f, "enable_delete_key", enable_delete_key);
317         write_bool_option(f, "safe_delete", safe_delete_enable);
318         write_char_option(f, "safe_delete_path", safe_delete_path);
319         write_int_option(f, "safe_delete_size", safe_delete_size);
320         fprintf(f,"\n");
321         write_bool_option(f, "tools_float", tools_float);
322         write_bool_option(f, "tools_hidden", tools_hidden);
323         write_bool_option(f, "restore_tool_state", restore_tool);
324
325         write_bool_option(f, "toolbar_hidden", toolbar_hidden);
326
327         write_bool_option(f, "mouse_wheel_scrolls", mousewheel_scrolls);
328         write_bool_option(f, "in_place_rename", enable_in_place_rename);
329
330         write_int_option(f, "open_recent_max", recent_list_max);
331
332         write_int_option(f, "image_cache_size_max", tile_cache_max);
333
334         write_int_option(f, "thumbnail_quality", thumbnail_quality);
335         write_int_option(f, "zoom_quality", zoom_quality);
336         write_int_option(f, "dither_quality", dither_quality);
337
338         write_int_option(f, "zoom_increment", zoom_increment);
339
340         write_bool_option(f, "enable_read_ahead", enable_read_ahead);
341
342         write_bool_option(f, "display_dialogs_under_mouse", place_dialogs_under_mouse);
343
344         write_bool_option(f, "user_specified_window_background", user_specified_window_background);
345         write_color_option(f, "window_background_color", &window_background_color);
346
347         write_int_option(f, "fullscreen_screen", fullscreen_screen);
348         write_bool_option(f, "fullscreen_clean_flip", fullscreen_clean_flip);
349         write_bool_option(f, "fullscreen_disable_saver", fullscreen_disable_saver);
350         write_bool_option(f, "fullscreen_above", fullscreen_above);
351
352         write_int_option(f, "custom_similarity_threshold", dupe_custom_threshold);
353
354         fprintf(f,"\n##### Slideshow Options #####\n\n");
355
356         write_int_unit_option(f, "slideshow_delay", slideshow_delay, SLIDESHOW_SUBSECOND_PRECISION);
357
358         write_bool_option(f, "slideshow_random", slideshow_random);
359         write_bool_option(f, "slideshow_repeat", slideshow_repeat);
360
361         fprintf(f,"\n##### Filtering Options #####\n\n");
362
363         write_bool_option(f, "show_dotfiles", show_dot_files);
364         write_bool_option(f, "disable_filtering", file_filter_disable);
365         filter_write_list(f);
366         
367         sidecar_ext_write(f);
368
369         fprintf(f,"\n##### Color Profiles #####\n\n");
370
371 #ifndef HAVE_LCMS
372         fprintf(f,"# NOTICE: Geeqie was not built with support for color profiles,\n"
373                   "#         color profile options will have no effect.\n\n");
374 #endif
375
376         write_bool_option(f, "color_profile_enabled", color_profile_enabled);
377         write_bool_option(f, "color_profile_use_image", color_profile_use_image);
378         write_int_option(f, "color_profile_input_type", color_profile_input_type);
379         for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
380                 {
381                 gchar *buf;
382
383                 buf = g_strdup_printf("color_profile_input_file_%d", i + 1);
384                 write_char_option(f, buf, color_profile_input_file[i]);
385                 g_free(buf);
386
387                 buf = g_strdup_printf("color_profile_input_name_%d", i + 1);
388                 write_char_option(f, buf, color_profile_input_name[i]);
389                 g_free(buf);
390                 }
391         fprintf(f,"\n");
392         write_int_option(f, "color_profile_screen_type", color_profile_screen_type);
393         write_char_option(f, "color_profile_screen_file_1", color_profile_screen_file);
394
395         fprintf(f,"\n##### External Programs #####\n");
396         fprintf(f,"# Maximum of 10 programs (external_1 through external_10)\n");
397         fprintf(f,"# format: external_n: \"menu name\" \"command line\"\n\n");
398
399         for (i = 0; i < GQVIEW_EDITOR_SLOTS; i++)
400                 {
401                 fprintf(f,"external_%d: \"", i+1);
402                 if (editor_name[i]) fprintf(f, "%s", editor_name[i]);
403                 fprintf(f, "\" \"");
404                 if (editor_command[i]) fprintf(f, "%s", editor_command[i]);
405                 fprintf(f, "\"\n");
406                 }
407
408         fprintf(f,"\n##### Collection Options #####\n\n");
409
410         write_bool_option(f, "rectangular_selections", collection_rectangular_selection);
411
412         fprintf(f,"\n##### Window Positions #####\n\n");
413
414         write_bool_option(f, "restore_window_positions", save_window_positions);
415         fprintf(f,"\n");
416         write_int_option(f, "main_window_x", main_window_x);
417         write_int_option(f, "main_window_y", main_window_y);
418         write_int_option(f, "main_window_width", main_window_w);
419         write_int_option(f, "main_window_height", main_window_h);
420         write_bool_option(f, "main_window_maximized", main_window_maximized);
421         write_int_option(f, "float_window_x", float_window_x);
422         write_int_option(f, "float_window_y", float_window_y);
423         write_int_option(f, "float_window_width", float_window_w);
424         write_int_option(f, "float_window_height", float_window_h);
425         write_int_option(f, "float_window_divider", float_window_divider);
426         write_int_option(f, "divider_position_h", window_hdivider_pos);
427         write_int_option(f, "divider_position_v", window_vdivider_pos);
428
429         fprintf(f,"######################################################################\n");
430         fprintf(f,"#                      end of Geeqie config file                     #\n");
431         fprintf(f,"######################################################################\n");
432
433         fclose(f);
434
435         g_free(rc_path);
436 }
437
438 /*
439  *-----------------------------------------------------------------------------
440  * load configuration (public)
441  *-----------------------------------------------------------------------------
442  */ 
443
444 void load_options(void)
445 {
446         FILE *f;
447         gchar *rc_path;
448         gchar *rc_pathl;
449         gchar s_buf[1024];
450         gchar *s_buf_ptr;
451         gchar option[1024];
452         gchar value[1024];
453         gchar value_all[1024];
454         gint c,l,i;
455
456         rc_path = g_strconcat(homedir(), "/", GQVIEW_RC_DIR, "/", RC_FILE_NAME, NULL);
457
458         rc_pathl = path_from_utf8(rc_path);
459         f = fopen(rc_pathl,"r");
460         g_free(rc_pathl);
461         if (!f)
462                 {
463                 g_free(rc_path);
464                 return;
465                 }
466
467         while (fgets(s_buf,1024,f))
468                 {
469                 if (s_buf[0]=='#') continue;
470                 if (s_buf[0]=='\n') continue;
471                 c = 0;
472                 l = strlen(s_buf);
473                 while (s_buf[c] != ':' && c < l) c++;
474                 if (c >= l) continue;
475                 s_buf[c] = '\0';
476                 c++;
477                 while ((s_buf[c] == ' ' || s_buf[c] == 8) && c < l) c++;
478                 s_buf_ptr = s_buf + c;
479                 strncpy(value_all, s_buf_ptr, sizeof(value_all));
480                 while (s_buf[c] != 8 && s_buf[c] != ' ' && s_buf[c] != '\n' && c < l) c++;
481                 s_buf[c] = '\0';
482                 strncpy(option, s_buf, sizeof(option));
483                 strncpy(value, s_buf_ptr, sizeof(value));
484
485                 /* general options */
486
487                 layout_style = read_int_option(f, option,
488                         "layout_style", value, layout_style);
489                 layout_order = read_char_option(f, option,
490                         "layout_order", value, layout_order);
491                 layout_view_icons = read_bool_option(f, option,
492                         "layout_view_as_icons", value, layout_view_icons);
493                 layout_view_tree = read_bool_option(f, option,
494                         "layout_view_as_tree", value, layout_view_tree);
495                 show_icon_names = read_bool_option(f, option,
496                         "show_icon_names", value, show_icon_names);
497
498                 tree_descend_subdirs = read_bool_option(f, option,
499                         "tree_descend_folders", value, tree_descend_subdirs);
500                 lazy_image_sync = read_bool_option(f, option,
501                         "lazy_image_sync", value, lazy_image_sync);
502                 update_on_time_change = read_bool_option(f, option,
503                         "update_on_time_change", value, update_on_time_change);
504                 exif_rotate_enable = read_bool_option(f, option,
505                         "exif_auto_rotate", value, exif_rotate_enable);
506
507                 startup_path_enable = read_bool_option(f, option,
508                         "enable_startup_path", value, startup_path_enable);
509                 startup_path = read_char_option(f, option,
510                         "startup_path", value_all, startup_path);
511
512                 if (strcasecmp(option,"zoom_mode") == 0)
513                         {
514                         if (strcasecmp(value, "original") == 0) zoom_mode = ZOOM_RESET_ORIGINAL;
515                         if (strcasecmp(value, "fit") == 0) zoom_mode = ZOOM_RESET_FIT_WINDOW;
516                         if (strcasecmp(value, "dont_change") == 0) zoom_mode = ZOOM_RESET_NONE;
517                         }
518                 two_pass_zoom = read_bool_option(f, option,
519                         "two_pass_scaling", value, two_pass_zoom);
520                 zoom_to_fit_expands = read_bool_option(f, option,
521                         "zoom_to_fit_allow_expand", value, zoom_to_fit_expands);
522
523                 fit_window = read_bool_option(f, option,
524                         "fit_window_to_image", value, fit_window);
525                 limit_window_size = read_bool_option(f, option,
526                         "limit_window_size", value, limit_window_size);
527                 max_window_size = read_int_option(f, option,
528                         "max_window_size", value, max_window_size);
529                 limit_autofit_size = read_bool_option(f, option,
530                         "limit_autofit_size", value, limit_autofit_size);
531                 max_autofit_size = read_int_option(f, option,
532                         "max_autofit_size", value, max_autofit_size);
533                 progressive_key_scrolling = read_bool_option(f, option,
534                         "progressive_keyboard_scrolling", value, progressive_key_scrolling);
535                 scroll_reset_method = read_int_option(f, option,
536                         "scroll_reset_method", value, scroll_reset_method);
537
538                 thumbnails_enabled = read_bool_option(f, option,
539                         "enable_thumbnails", value, thumbnails_enabled);
540                 thumb_max_width = read_int_option(f, option,
541                         "thumbnail_width", value, thumb_max_width);
542                 thumb_max_height = read_int_option(f, option,
543                         "thumbnail_height", value, thumb_max_height);
544                 enable_thumb_caching = read_bool_option(f, option,
545                         "cache_thumbnails", value, enable_thumb_caching);
546                 enable_thumb_dirs = read_bool_option(f, option,
547                         "cache_thumbnails_into_dirs", value, enable_thumb_dirs);
548                 thumbnail_fast = read_bool_option(f, option,
549                         "thumbnail_fast", value, thumbnail_fast);
550                 use_xvpics_thumbnails = read_bool_option(f, option,
551                         "use_xvpics_thumbnails", value, use_xvpics_thumbnails);
552                 thumbnail_spec_standard = read_bool_option(f, option,
553                         "thumbnail_spec_standard", value, thumbnail_spec_standard);
554
555                 enable_metadata_dirs = read_bool_option(f, option,
556                         "local_metadata", value, enable_metadata_dirs);
557
558                 file_sort_method = (SortType)read_int_option(f, option,
559                         "sort_method", value, (gint)file_sort_method);
560                 file_sort_ascending = read_bool_option(f, option,
561                         "sort_ascending", value, file_sort_ascending);
562                 file_sort_case_sensitive = read_bool_option(f, option,
563                         "sort_case_sensitive", value, file_sort_case_sensitive);
564
565                 confirm_delete = read_bool_option(f, option,
566                         "confirm_delete", value, confirm_delete);
567                 enable_delete_key = read_bool_option(f, option,
568                         "enable_delete_key", value, enable_delete_key);
569                 safe_delete_enable = read_bool_option(f, option,
570                         "safe_delete",  value, safe_delete_enable);
571                 safe_delete_path = read_char_option(f, option,
572                         "safe_delete_path", value, safe_delete_path);
573                 safe_delete_size = read_int_option(f, option,
574                         "safe_delete_size", value, safe_delete_size);
575
576                 tools_float = read_bool_option(f, option,
577                         "tools_float", value, tools_float);
578                 tools_hidden = read_bool_option(f, option,
579                         "tools_hidden", value, tools_hidden);
580                 restore_tool = read_bool_option(f, option,
581                         "restore_tool_state", value, restore_tool);
582
583                 toolbar_hidden = read_bool_option(f, option,
584                         "toolbar_hidden", value, toolbar_hidden);
585
586                 mousewheel_scrolls = read_bool_option(f, option,
587                         "mouse_wheel_scrolls", value, mousewheel_scrolls);
588                 enable_in_place_rename = read_bool_option(f, option,
589                         "in_place_rename", value, enable_in_place_rename);
590
591                 recent_list_max = read_int_option(f, option,
592                         "open_recent_max", value, recent_list_max);
593
594                 tile_cache_max = read_int_option(f, option,
595                         "image_cache_size_max", value, tile_cache_max);
596
597                 thumbnail_quality = CLAMP(read_int_option(f, option,
598                         "thumbnail_quality", value, thumbnail_quality), GDK_INTERP_NEAREST, GDK_INTERP_HYPER);
599                 zoom_quality = CLAMP(read_int_option(f, option,
600                         "zoom_quality", value, zoom_quality), GDK_INTERP_NEAREST, GDK_INTERP_HYPER);
601                 dither_quality = CLAMP(read_int_option(f, option,
602                         "dither_quality", value, dither_quality), GDK_RGB_DITHER_NONE, GDK_RGB_DITHER_MAX);
603
604                 zoom_increment = read_int_option(f, option,
605                         "zoom_increment", value, zoom_increment);
606
607                 enable_read_ahead = read_bool_option(f, option,
608                         "enable_read_ahead", value, enable_read_ahead);
609
610                 place_dialogs_under_mouse = read_bool_option(f, option,
611                         "display_dialogs_under_mouse", value, place_dialogs_under_mouse);
612
613                 user_specified_window_background = read_bool_option(f, option,
614                         "user_specified_window_background", value, user_specified_window_background);
615                 read_color_option(f, option,
616                         "window_background_color", value, &window_background_color);
617
618                 fullscreen_screen = read_int_option(f, option,
619                         "fullscreen_screen", value, fullscreen_screen);
620                 fullscreen_clean_flip = read_bool_option(f, option,
621                         "fullscreen_clean_flip", value, fullscreen_clean_flip);
622                 fullscreen_disable_saver = read_bool_option(f, option,
623                         "fullscreen_disable_saver", value, fullscreen_disable_saver);
624                 fullscreen_above = read_bool_option(f, option,
625                         "fullscreen_above", value, fullscreen_above);
626
627                 dupe_custom_threshold = read_int_option(f, option,
628                         "custom_similarity_threshold", value, dupe_custom_threshold);
629
630                 /* slideshow options */
631
632                 slideshow_delay = read_int_unit_option(f, option,
633                         "slideshow_delay", value, slideshow_delay, SLIDESHOW_SUBSECOND_PRECISION);
634                 slideshow_random = read_bool_option(f, option,
635                         "slideshow_random", value, slideshow_random);
636                 slideshow_repeat = read_bool_option(f, option,
637                         "slideshow_repeat", value, slideshow_repeat);
638
639                 /* filtering options */
640
641                 show_dot_files = read_bool_option(f, option,
642                         "show_dotfiles", value, show_dot_files);
643                 file_filter_disable = read_bool_option(f, option,
644                         "disable_filtering", value, file_filter_disable);
645
646                 if (strcasecmp(option, "filter_ext") == 0)
647                         {
648                         filter_parse(value_all);
649                         }
650
651                 if (strcasecmp(option, "sidecar_ext") == 0)
652                         {
653                         sidecar_ext_parse(value_all, TRUE);
654                         }
655                 
656                 /* Color Profiles */
657
658                 color_profile_enabled = read_bool_option(f, option,
659                         "color_profile_enabled", value, color_profile_enabled);
660                 color_profile_use_image = read_bool_option(f, option,
661                         "color_profile_use_image", value, color_profile_use_image);
662                 color_profile_input_type = read_int_option(f, option,
663                         "color_profile_input_type", value, color_profile_input_type);
664
665                 if (strncasecmp(option, "color_profile_input_file_", 25) == 0)
666                         {
667                         i = strtol(option + 25, NULL, 0) - 1;
668                         if (i >= 0 && i < COLOR_PROFILE_INPUTS)
669                                 {
670                                 color_profile_input_file[i] = read_char_option(f, option,
671                                         option, value, color_profile_input_file[i]);
672                                 }
673                         }
674                 if (strncasecmp(option, "color_profile_input_name_", 25) == 0)
675                         {
676                         i = strtol(option + 25, NULL, 0) - 1;
677                         if (i >= 0 && i < COLOR_PROFILE_INPUTS)
678                                 {
679                                 color_profile_input_name[i] = read_char_option(f, option,
680                                         option, value, color_profile_input_name[i]);
681                                 }
682                         }
683
684                 color_profile_screen_type = read_int_option(f, option,
685                         "color_profile_screen_type", value, color_profile_screen_type);
686                 color_profile_screen_file = read_char_option(f, option,
687                         "color_profile_screen_file_1", value, color_profile_screen_file);
688
689                 /* External Programs */
690
691                 if (strncasecmp(option, "external_", 9) == 0)
692                         {
693                         i = strtol(option + 9, NULL, 0);
694                         if (i > 0 && i <= GQVIEW_EDITOR_SLOTS)
695                                 {
696                                 gchar *ptr1, *ptr2;
697                                 i--;
698                                 c = 0;
699                                 l = strlen(value_all);
700                                 ptr1 = value_all;
701
702                                 g_free(editor_name[i]);
703                                 editor_name[i] = NULL;
704                                 g_free(editor_command[i]);
705                                 editor_command[i] = NULL;
706
707                                 while (c<l && value_all[c] !='"') c++;
708                                 if (ptr1[c] == '"')
709                                         {
710                                         c++;
711                                         ptr2 = ptr1 + c;
712                                         while (c<l && value_all[c] !='"') c++;
713                                         if (ptr1[c] == '"')
714                                                 {
715                                                 ptr1[c] = '\0';
716                                                 if (ptr1 + c - 1 != ptr2)
717                                                         editor_name[i] = g_strdup(ptr2);
718                                                 c++;
719                                                 while (c<l && value_all[c] !='"') c++;
720                                                 if (ptr1[c] == '"')
721                                                         {
722                                                         c++;
723                                                         ptr2 = ptr1 + c;
724                                                         while (value_all[c] != '\0') c++;
725                                                         while (c > 0 && value_all[c] != '"') c--;
726                                                         if (ptr1[c] == '"' && ptr1 + c > ptr2)
727                                                                 {
728                                                                 ptr1[c] = '\0';
729                                                                 editor_command[i] = g_strdup(ptr2);
730                                                                 }
731                                                         }
732                                                 }
733                                         }
734                                 }
735                         }
736
737                 /* colection options */
738
739                 collection_rectangular_selection = read_bool_option(f, option,
740                         "rectangular_selections", value, collection_rectangular_selection);
741
742                 /* window positions */
743
744                 save_window_positions = read_bool_option(f, option,
745                         "restore_window_positions", value, save_window_positions);
746
747                 main_window_x = read_int_option(f, option,
748                         "main_window_x", value, main_window_x);
749                 main_window_y = read_int_option(f, option,
750                         "main_window_y", value, main_window_y);
751                 main_window_w = read_int_option(f, option,
752                         "main_window_width", value, main_window_w);
753                 main_window_h = read_int_option(f, option,
754                         "main_window_height", value, main_window_h);
755                 main_window_maximized = read_bool_option(f, option,
756                         "main_window_maximized", value, main_window_maximized);
757                 float_window_x = read_int_option(f, option,
758                         "float_window_x", value, float_window_x);
759                 float_window_y = read_int_option(f, option,
760                         "float_window_y", value, float_window_y);
761                 float_window_w = read_int_option(f, option,
762                         "float_window_width", value, float_window_w);
763                 float_window_h = read_int_option(f, option,
764                         "float_window_height", value, float_window_h);
765                 float_window_divider = read_int_option(f, option,
766                         "float_window_divider", value, float_window_divider);
767                 window_hdivider_pos = read_int_option(f, option,
768                         "divider_position_h", value, window_hdivider_pos);
769                 window_vdivider_pos = read_int_option(f, option,
770                         "divider_position_v", value, window_vdivider_pos);
771
772                 }
773
774         fclose(f);
775         g_free(rc_path);
776 }
777