Rename options:
[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 "filefilter.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 && g_ascii_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 && g_ascii_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 && g_ascii_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 && g_ascii_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 && g_ascii_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 && g_ascii_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 && g_ascii_strcasecmp(option, label) == 0)
249                 {
250                 if (g_ascii_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_BOOL(show_copy_path);
305         WRITE_SEPARATOR();
306
307         WRITE_BOOL(tree_descend_subdirs);
308         WRITE_BOOL(lazy_image_sync);
309         WRITE_BOOL(update_on_time_change);
310         WRITE_SEPARATOR();
311
312         WRITE_BOOL(progressive_key_scrolling);
313         WRITE_BOOL(enable_metadata_dirs);
314         WRITE_BOOL(save_metadata_in_image_file);
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("Startup Options");
326
327         WRITE_BOOL(startup.restore_path);
328         WRITE_CHAR(startup.path);
329
330
331         WRITE_SUBTITLE("File operations Options");
332
333         WRITE_BOOL(file_ops.enable_in_place_rename);
334         WRITE_BOOL(file_ops.confirm_delete);
335         WRITE_BOOL(file_ops.enable_delete_key);
336         WRITE_BOOL(file_ops.safe_delete_enable);
337         WRITE_CHAR(file_ops.safe_delete_path);
338         WRITE_INT(file_ops.safe_delete_folder_maxsize);
339
340
341         WRITE_SUBTITLE("Layout Options");
342
343         WRITE_INT(layout.style);
344         WRITE_CHAR(layout.order);
345         WRITE_UINT(layout.dir_view_type);
346         WRITE_UINT(layout.file_view_type);
347         WRITE_BOOL(layout.show_marks);
348         WRITE_BOOL(layout.show_thumbnails);
349         WRITE_SEPARATOR();
350
351         WRITE_BOOL(layout.save_window_positions);
352         WRITE_SEPARATOR();
353
354         WRITE_INT(layout.main_window.x);
355         WRITE_INT(layout.main_window.y);
356         WRITE_INT(layout.main_window.w);
357         WRITE_INT(layout.main_window.h);
358         WRITE_BOOL(layout.main_window.maximized);
359         WRITE_INT(layout.main_window.hdivider_pos);
360         WRITE_INT(layout.main_window.vdivider_pos);
361         WRITE_SEPARATOR();
362
363         WRITE_INT(layout.float_window.x);
364         WRITE_INT(layout.float_window.y);
365         WRITE_INT(layout.float_window.w);
366         WRITE_INT(layout.float_window.h);
367         WRITE_INT(layout.float_window.vdivider_pos);
368         WRITE_SEPARATOR();
369
370         WRITE_BOOL(layout.tools_float);
371         WRITE_BOOL(layout.tools_hidden);
372         WRITE_BOOL(layout.tools_restore_state);
373         WRITE_SEPARATOR();
374
375         WRITE_BOOL(layout.toolbar_hidden);
376
377         WRITE_SUBTITLE("Panels Options");
378
379         WRITE_BOOL(panels.exif.enabled);
380         WRITE_INT(panels.exif.width);
381         WRITE_BOOL(panels.info.enabled);
382         WRITE_INT(panels.info.width);
383         WRITE_BOOL(panels.sort.enabled);
384         WRITE_INT(panels.sort.action_state);
385         WRITE_INT(panels.sort.mode_state);
386         WRITE_INT(panels.sort.selection_state);
387
388         WRITE_SUBTITLE("Image Options");
389
390         secure_fprintf(ssi, "# image.zoom_mode possible values are:\n"
391                             "#   original\n"
392                             "#   fit\n"
393                             "#   dont_change\n");
394         secure_fprintf(ssi, "image.zoom_mode: ");
395         if (options->image.zoom_mode == ZOOM_RESET_ORIGINAL)
396                 secure_fprintf(ssi, "original\n");
397         else if (options->image.zoom_mode == ZOOM_RESET_FIT_WINDOW)
398                 secure_fprintf(ssi, "fit\n");
399         else if (options->image.zoom_mode == ZOOM_RESET_NONE)
400                 secure_fprintf(ssi, "dont_change\n");
401         WRITE_SEPARATOR();
402         WRITE_BOOL(image.zoom_2pass);
403         WRITE_BOOL(image.zoom_to_fit_allow_expand);
404         WRITE_INT(image.zoom_quality);
405         WRITE_INT(image.zoom_increment);
406         WRITE_BOOL(image.fit_window_to_image);
407         WRITE_BOOL(image.limit_window_size);
408         WRITE_INT(image.max_window_size);
409         WRITE_BOOL(image.limit_autofit_size);
410         WRITE_INT(image.max_autofit_size);
411         WRITE_INT(image.scroll_reset_method);
412         WRITE_INT(image.tile_cache_max);
413         WRITE_INT(image.dither_quality);
414         WRITE_BOOL(image.enable_read_ahead);
415         WRITE_BOOL(image.exif_rotate_enable);
416         WRITE_BOOL(image.use_custom_border_color);
417         WRITE_COLOR(image.border_color);
418         WRITE_INT(image.read_buffer_size);
419         WRITE_INT(image.idle_read_loop_count);
420
421         WRITE_SUBTITLE("Thumbnails Options");
422
423         WRITE_INT(thumbnails.max_width);
424         WRITE_INT(thumbnails.max_height);
425         WRITE_BOOL(thumbnails.enable_caching);
426         WRITE_BOOL(thumbnails.cache_into_dirs);
427         WRITE_BOOL(thumbnails.fast);
428         WRITE_BOOL(thumbnails.use_xvpics);
429         WRITE_BOOL(thumbnails.spec_standard);
430         WRITE_INT(thumbnails.quality);
431
432
433         WRITE_SUBTITLE("File sorting Options");
434
435         WRITE_INT(file_sort.method);
436         WRITE_BOOL(file_sort.ascending);
437         WRITE_BOOL(file_sort.case_sensitive);
438
439
440         WRITE_SUBTITLE("Fullscreen Options");
441
442         WRITE_INT(fullscreen.screen);
443         WRITE_BOOL(fullscreen.clean_flip);
444         WRITE_BOOL(fullscreen.disable_saver);
445         WRITE_BOOL(fullscreen.above);
446
447
448         WRITE_SUBTITLE("Histogram Options");
449         WRITE_UINT(histogram.last_channel_mode);
450         WRITE_UINT(histogram.last_log_mode);
451
452
453         WRITE_SUBTITLE("Image Overlay Options");
454         WRITE_UINT(image_overlay.common.enabled);
455         WRITE_BOOL(image_overlay.common.show_at_startup);
456         WRITE_CHAR(image_overlay.common.template_string);
457
458
459         WRITE_SUBTITLE("Slideshow Options");
460
461         WRITE_INT_UNIT(slideshow.delay, SLIDESHOW_SUBSECOND_PRECISION);
462         WRITE_BOOL(slideshow.random);
463         WRITE_BOOL(slideshow.repeat);
464
465
466         WRITE_SUBTITLE("Collection Options");
467
468         WRITE_BOOL(collections.rectangular_selection);
469
470
471         WRITE_SUBTITLE("Filtering Options");
472
473         WRITE_BOOL(file_filter.show_hidden_files);
474         WRITE_BOOL(file_filter.show_dot_directory);
475         WRITE_BOOL(file_filter.disable);
476         WRITE_SEPARATOR();
477
478         filter_write_list(ssi);
479
480
481         WRITE_SUBTITLE("Sidecars Options");
482
483         sidecar_ext_write(ssi);
484
485
486         WRITE_SUBTITLE("Color Profiles");
487
488 #ifndef HAVE_LCMS
489         secure_fprintf(ssi, "# NOTICE: %s was not built with support for color profiles,\n"
490                             "#         color profile options will have no effect.\n\n", GQ_APPNAME);
491 #endif
492
493         WRITE_BOOL(color_profile.enabled);
494         WRITE_BOOL(color_profile.use_image);
495         WRITE_INT(color_profile.input_type);
496         WRITE_SEPARATOR();
497
498         for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
499                 {
500                 gchar *buf;
501
502                 buf = g_strdup_printf("color_profile.input_file_%d", i + 1);
503                 write_char_option(ssi, buf, options->color_profile.input_file[i]);
504                 g_free(buf);
505
506                 buf = g_strdup_printf("color_profile.input_name_%d", i + 1);
507                 write_char_option(ssi, buf, options->color_profile.input_name[i]);
508                 g_free(buf);
509                 }
510
511         WRITE_SEPARATOR();
512         WRITE_INT(color_profile.screen_type);
513         WRITE_CHAR(color_profile.screen_file);
514
515         WRITE_SUBTITLE("External Programs");
516         secure_fprintf(ssi, "# Maximum of %d programs (external_1 through external_%d)\n", GQ_EDITOR_GENERIC_SLOTS, GQ_EDITOR_GENERIC_SLOTS);
517         secure_fprintf(ssi, "# external_%d through external_%d are used for file ops\n", GQ_EDITOR_GENERIC_SLOTS + 1, GQ_EDITOR_SLOTS);
518         secure_fprintf(ssi, "# format: external_n: \"menu name\" \"command line\"\n\n");
519
520         for (i = 0; i < GQ_EDITOR_SLOTS; i++)
521                 {
522                 if (i == GQ_EDITOR_GENERIC_SLOTS) secure_fputc(ssi, '\n');
523                 gchar *qname = escquote_value(options->editor_name[i]);
524                 gchar *qcommand = escquote_value(options->editor_command[i]);
525                 secure_fprintf(ssi, "external_%d: %s %s\n", i+1, qname, qcommand);
526                 g_free(qname);
527                 g_free(qcommand);
528                 }
529
530
531         WRITE_SUBTITLE("Exif Options");
532         secure_fprintf(ssi, "# Display: 0: never\n"
533                             "#          1: if set\n"
534                             "#          2: always\n\n");
535         for (i = 0; ExifUIList[i].key; i++)
536                 {
537                 secure_fprintf(ssi, "exif.display.");
538                 write_int_option(ssi, (gchar *)ExifUIList[i].key, ExifUIList[i].current);
539                 }
540
541         WRITE_SEPARATOR();
542         WRITE_SEPARATOR();
543
544         secure_fprintf(ssi, "######################################################################\n");
545         secure_fprintf(ssi, "#                         end of config file                         #\n");
546         secure_fprintf(ssi, "######################################################################\n");
547
548
549         if (secure_close(ssi))
550                 printf_term(_("error saving config file: %s\nerror: %s\n"), rc_path,
551                             secsave_strerror(secsave_errno));
552
553         g_free(rc_path);
554 }
555
556 /*
557  *-----------------------------------------------------------------------------
558  * load configuration (public)
559  *-----------------------------------------------------------------------------
560  */
561
562 void load_options(void)
563 {
564         FILE *f;
565         gchar *rc_path;
566         gchar *rc_pathl;
567         gchar s_buf[1024];
568         gchar option[1024];
569         gchar value[1024];
570         gchar value_all[1024];
571         gint i;
572
573         for (i = 0; ExifUIList[i].key; i++)
574                 ExifUIList[i].current = ExifUIList[i].default_value;
575
576         rc_path = g_strconcat(homedir(), "/", GQ_RC_DIR, "/", RC_FILE_NAME, NULL);
577
578         rc_pathl = path_from_utf8(rc_path);
579         f = fopen(rc_pathl,"r");
580         g_free(rc_pathl);
581         if (!f)
582                 {
583                 g_free(rc_path);
584                 return;
585                 }
586
587         while (fgets(s_buf, sizeof(s_buf), f))
588                 {
589                 gchar *option_start, *value_start;
590                 gchar *p = s_buf;
591
592                 while (g_ascii_isspace(*p)) p++;
593                 if (!*p || *p == '\n' || *p == '#') continue;
594                 option_start = p;
595                 while (*p && *p != ':') p++;
596                 if (!*p) continue;
597                 *p = '\0';
598                 p++;
599                 strncpy(option, option_start, sizeof(option));
600                 while (g_ascii_isspace(*p)) p++;
601                 value_start = p;
602                 strncpy(value_all, value_start, sizeof(value_all));
603                 while (*p && !g_ascii_isspace(*p) && *p != '\n') p++;
604                 *p = '\0';
605                 strncpy(value, value_start, sizeof(value));
606
607 #define READ_BOOL(_name_) read_bool_option(f, option, #_name_, value, &options->_name_)
608 #define READ_INT(_name_) read_int_option(f, option, #_name_, value, &options->_name_)
609 #define READ_UINT(_name_) read_uint_option(f, option, #_name_, value, &options->_name_)
610 #define READ_INT_CLAMP(_name_, _min_, _max_) read_int_option_clamp(f, option, #_name_, value, &options->_name_, _min_, _max_)
611 #define READ_INT_UNIT(_name_, _unit_) read_int_unit_option(f, option, #_name_, value, &options->_name_, _unit_)
612 #define READ_CHAR(_name_) read_char_option(f, option, #_name_, value_all, &options->_name_)
613 #define READ_COLOR(_name_) read_color_option(f, option, #_name_, value, &options->_name_)
614
615 #define COMPAT_READ_BOOL(_oldname_, _name_) read_bool_option(f, option, #_oldname_, value, &options->_name_)
616 #define COMPAT_READ_INT(_oldname_, _name_) read_int_option(f, option, #_oldname_, value, &options->_name_)
617 #define COMPAT_READ_UINT(_oldname_, _name_) read_uint_option(f, option, #_oldname_, value, &options->_name_)
618 #define COMPAT_READ_INT_CLAMP(_oldname_, _name_, _min_, _max_) read_int_option_clamp(f, option, #_oldname_, value, &options->_name_, _min_, _max_)
619 #define COMPAT_READ_INT_UNIT(_oldname_, _name_, _unit_) read_int_unit_option(f, option, #_oldname_, value, &options->_name_, _unit_)
620 #define COMPAT_READ_CHAR(_oldname_, _name_) read_char_option(f, option, #_oldname_, value_all, &options->_name_)
621 #define COMPAT_READ_COLOR(_oldname_, _name_) read_color_option(f, option, #_oldname_, value, &options->_name_)
622
623                 /* general options */
624                 READ_BOOL(show_icon_names);
625                 READ_BOOL(show_copy_path);
626
627                 READ_BOOL(tree_descend_subdirs);
628                 READ_BOOL(lazy_image_sync);
629                 READ_BOOL(update_on_time_change);
630
631                 READ_INT(duplicates_similarity_threshold);
632
633                 READ_BOOL(progressive_key_scrolling);
634
635                 READ_BOOL(enable_metadata_dirs);
636                 READ_BOOL(save_metadata_in_image_file);
637
638                 READ_BOOL(mousewheel_scrolls);
639
640                 READ_INT(open_recent_list_maxsize);
641                 READ_INT(dnd_icon_size);
642                 READ_BOOL(place_dialogs_under_mouse);
643
644                 /* startup options */
645                 
646                 COMPAT_READ_BOOL(startup_path_enable, startup.restore_path); /* 2008/05/11 */
647                 READ_BOOL(startup.restore_path);
648
649                 COMPAT_READ_CHAR(startup_path, startup.path); /* 2008/05/11 */
650                 READ_CHAR(startup.path);
651         
652                 /* layout options */
653
654                 READ_INT(layout.style);
655                 READ_CHAR(layout.order);
656                 
657                 COMPAT_READ_UINT(layout.view_as_icons, layout.file_view_type); /* 2008/05/03 */
658
659                 READ_UINT(layout.dir_view_type);
660                 READ_UINT(layout.file_view_type);
661                 READ_BOOL(layout.show_marks);
662                 READ_BOOL(layout.show_thumbnails);
663
664                 /* window positions */
665
666                 READ_BOOL(layout.save_window_positions);
667
668                 READ_INT(layout.main_window.x);
669                 READ_INT(layout.main_window.y);
670                 READ_INT(layout.main_window.w);
671                 READ_INT(layout.main_window.h);
672                 READ_BOOL(layout.main_window.maximized);
673                 READ_INT(layout.float_window.x);
674                 READ_INT(layout.float_window.y);
675                 READ_INT(layout.float_window.w);
676                 READ_INT(layout.float_window.h);
677                 READ_INT(layout.float_window.vdivider_pos);
678                 READ_INT(layout.main_window.hdivider_pos);
679                 READ_INT(layout.main_window.vdivider_pos);
680                 READ_BOOL(layout.tools_float);
681                 READ_BOOL(layout.tools_hidden);
682                 READ_BOOL(layout.tools_restore_state);
683                 READ_BOOL(layout.toolbar_hidden);
684
685                 /* panels */
686                 READ_BOOL(panels.exif.enabled);
687                 READ_INT_CLAMP(panels.exif.width, PANEL_MIN_WIDTH, PANEL_MAX_WIDTH);
688                 READ_BOOL(panels.info.enabled);
689                 READ_INT_CLAMP(panels.info.width, PANEL_MIN_WIDTH, PANEL_MAX_WIDTH);
690                 READ_BOOL(panels.sort.enabled);
691                 READ_INT(panels.sort.action_state);
692                 READ_INT(panels.sort.mode_state);
693                 READ_INT(panels.sort.selection_state);
694
695                 /* image options */
696                 if (g_ascii_strcasecmp(option, "image.zoom_mode") == 0)
697                         {
698                         if (g_ascii_strcasecmp(value, "original") == 0)
699                                 options->image.zoom_mode = ZOOM_RESET_ORIGINAL;
700                         else if (g_ascii_strcasecmp(value, "fit") == 0)
701                                 options->image.zoom_mode = ZOOM_RESET_FIT_WINDOW;
702                         else if (g_ascii_strcasecmp(value, "dont_change") == 0)
703                                 options->image.zoom_mode = ZOOM_RESET_NONE;
704                         }
705                 READ_BOOL(image.zoom_2pass);
706                 READ_BOOL(image.zoom_to_fit_allow_expand);
707                 READ_BOOL(image.fit_window_to_image);
708                 READ_BOOL(image.limit_window_size);
709                 READ_INT(image.max_window_size);
710                 READ_BOOL(image.limit_autofit_size);
711                 READ_INT(image.max_autofit_size);
712                 READ_INT(image.scroll_reset_method);
713                 READ_INT(image.tile_cache_max);
714                 READ_INT_CLAMP(image.zoom_quality, GDK_INTERP_NEAREST, GDK_INTERP_HYPER);
715                 READ_INT_CLAMP(image.dither_quality, GDK_RGB_DITHER_NONE, GDK_RGB_DITHER_MAX);
716                 READ_INT(image.zoom_increment);
717                 READ_BOOL(image.enable_read_ahead);
718                 READ_BOOL(image.exif_rotate_enable);
719                 READ_BOOL(image.use_custom_border_color);
720                 READ_COLOR(image.border_color);
721                 READ_INT_CLAMP(image.read_buffer_size, IMAGE_LOADER_READ_BUFFER_SIZE_MIN, IMAGE_LOADER_READ_BUFFER_SIZE_MAX);
722                 READ_INT_CLAMP(image.idle_read_loop_count, IMAGE_LOADER_IDLE_READ_LOOP_COUNT_MIN, IMAGE_LOADER_IDLE_READ_LOOP_COUNT_MAX);
723
724
725                 /* thumbnails options */
726                 READ_INT_CLAMP(thumbnails.max_width, 16, 512);
727                 READ_INT_CLAMP(thumbnails.max_height, 16, 512);
728
729                 READ_BOOL(thumbnails.enable_caching);
730                 READ_BOOL(thumbnails.cache_into_dirs);
731                 READ_BOOL(thumbnails.fast);
732                 READ_BOOL(thumbnails.use_xvpics);
733                 READ_BOOL(thumbnails.spec_standard);
734                 READ_INT_CLAMP(thumbnails.quality, GDK_INTERP_NEAREST, GDK_INTERP_HYPER);
735
736                 /* file sorting options */
737                 READ_UINT(file_sort.method);
738                 READ_BOOL(file_sort.ascending);
739                 READ_BOOL(file_sort.case_sensitive);
740
741                 /* file operations options */
742                 READ_BOOL(file_ops.enable_in_place_rename);
743                 READ_BOOL(file_ops.confirm_delete);
744                 READ_BOOL(file_ops.enable_delete_key);
745                 READ_BOOL(file_ops.safe_delete_enable);
746                 READ_CHAR(file_ops.safe_delete_path);
747                 READ_INT(file_ops.safe_delete_folder_maxsize);
748
749                 /* fullscreen options */
750                 READ_INT(fullscreen.screen);
751                 READ_BOOL(fullscreen.clean_flip);
752                 READ_BOOL(fullscreen.disable_saver);
753                 READ_BOOL(fullscreen.above);
754
755                 /* histogram */
756                 READ_UINT(histogram.last_channel_mode);
757                 READ_UINT(histogram.last_log_mode);
758
759                 /* image overlay */
760                 COMPAT_READ_BOOL(fullscreen.show_info, image_overlay.common.show_at_startup);
761                 COMPAT_READ_CHAR(fullscreen.info, image_overlay.common.template_string);
762                 READ_UINT(image_overlay.common.enabled);
763                 READ_BOOL(image_overlay.common.show_at_startup);
764                 READ_CHAR(image_overlay.common.template_string);
765         
766                 /* slideshow options */
767                 READ_INT_UNIT(slideshow.delay, SLIDESHOW_SUBSECOND_PRECISION);
768                 READ_BOOL(slideshow.random);
769                 READ_BOOL(slideshow.repeat);
770
771                 /* collection options */
772
773                 READ_BOOL(collections.rectangular_selection);
774
775                 /* filtering options */
776
777                 READ_BOOL(file_filter.show_hidden_files);
778                 READ_BOOL(file_filter.show_dot_directory);
779                 READ_BOOL(file_filter.disable);
780
781                 if (g_ascii_strcasecmp(option, "file_filter.ext") == 0)
782                         {
783                         filter_parse(value_all);
784                         }
785
786                 if (g_ascii_strcasecmp(option, "sidecar.ext") == 0)
787                         {
788                         sidecar_ext_parse(value_all, TRUE);
789                         }
790
791                 /* Color Profiles */
792
793                 READ_BOOL(color_profile.enabled);
794                 READ_BOOL(color_profile.use_image);
795                 READ_INT(color_profile.input_type);
796
797                 if (g_ascii_strncasecmp(option, "color_profile.input_file_", 25) == 0)
798                         {
799                         i = strtol(option + 25, NULL, 0) - 1;
800                         if (i >= 0 && i < COLOR_PROFILE_INPUTS)
801                                 {
802                                 read_char_option(f, option, option, value, &options->color_profile.input_file[i]);
803                                 }
804                         }
805                 if (g_ascii_strncasecmp(option, "color_profile.input_name_", 25) == 0)
806                         {
807                         i = strtol(option + 25, NULL, 0) - 1;
808                         if (i >= 0 && i < COLOR_PROFILE_INPUTS)
809                                 {
810                                 read_char_option(f, option, option, value, &options->color_profile.input_name[i]);
811                                 }
812                         }
813
814                 READ_INT(color_profile.screen_type);
815                 READ_CHAR(color_profile.screen_file);
816
817                 /* External Programs */
818
819                 if (g_ascii_strncasecmp(option, "external_", 9) == 0)
820                         {
821                         i = strtol(option + 9, NULL, 0);
822                         if (i > 0 && i <= GQ_EDITOR_SLOTS)
823                                 {
824                                 const gchar *ptr;
825                                 i--;
826                                 g_free(options->editor_name[i]);
827                                 g_free(options->editor_command[i]);
828
829                                 options->editor_name[i] = quoted_value(value_all, &ptr);
830                                 options->editor_command[i] = quoted_value(ptr, NULL);
831                                 }
832                         }
833
834                 /* Exif */
835                 if (0 == g_ascii_strncasecmp(option, "exif.display.", 13))
836                         {
837                         for (i = 0; ExifUIList[i].key; i++)
838                                 if (0 == g_ascii_strcasecmp(option + 13, ExifUIList[i].key))
839                                         ExifUIList[i].current = strtol(value, NULL, 10);
840                         }
841                 }
842
843         fclose(f);
844         g_free(rc_path);
845 }