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