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