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