4 * Copyright (C) 2008 The Geeqie Team
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!
13 #include <glib/gstdio.h>
20 #include "filefilter.h"
21 #include "secure_save.h"
22 #include "slideshow.h"
23 #include "ui_fileops.h"
27 *-----------------------------------------------------------------------------
28 * line write/parse routines (private)
29 *-----------------------------------------------------------------------------
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 '"'
40 gchar *quoted_value(const gchar *text, const gchar **tail)
44 gint l = strlen(text);
47 if (tail) *tail = text;
49 if (l == 0) return retval;
51 while (c < l && text[c] !='"') c++;
60 if (text[e-1] != '\\' && text[e] == '"') break;
67 gchar *substring = g_strndup(ptr, e - c);
71 retval = g_strcompress(substring);
76 if (tail) *tail = text + e + 1;
79 /* for compatibility with older formats (<0.3.7)
80 * read a line without quotes too */
83 while (c < l && text[c] !=' ' && text[c] !=8 && text[c] != '\n') c++;
86 retval = g_strndup(text, c);
88 if (tail) *tail = text + c;
94 gchar *escquote_value(const gchar *text)
98 if (!text) return g_strdup("\"\"");
100 e = g_strescape(text, "");
103 gchar *retval = g_strdup_printf("\"%s\"", e);
107 return g_strdup("\"\"");
110 static void write_char_option(SecureSaveInfo *ssi, gchar *label, gchar *text)
112 gchar *escval = escquote_value(text);
114 secure_fprintf(ssi, "%s: %s\n", label, escval);
118 static gboolean read_char_option(FILE *f, gchar *option, gchar *label, gchar *value, gchar **text)
120 if (g_ascii_strcasecmp(option, label) != 0) return FALSE;
121 if (!text) return FALSE;
124 *text = quoted_value(value, NULL);
128 /* Since gdk_color_to_string() is only available since gtk 2.12
129 * here is an equivalent stub function. */
130 static gchar *color_to_string(GdkColor *color)
132 return g_strdup_printf("#%04X%04X%04X", color->red, color->green, color->blue);
135 static void write_color_option(SecureSaveInfo *ssi, gchar *label, GdkColor *color)
139 gchar *colorstring = color_to_string(color);
141 write_char_option(ssi, label, colorstring);
145 secure_fprintf(ssi, "%s: \n", label);
148 static gboolean read_color_option(FILE *f, gchar *option, gchar *label, gchar *value, GdkColor *color)
152 if (g_ascii_strcasecmp(option, label) != 0) return FALSE;
153 if (!color) return FALSE;
155 colorstr = quoted_value(value, NULL);
156 if (!colorstr) return FALSE;
157 gdk_color_parse(colorstr, color);
162 static void write_int_option(SecureSaveInfo *ssi, gchar *label, gint n)
164 secure_fprintf(ssi, "%s: %d\n", label, n);
167 static gboolean read_int_option(FILE *f, gchar *option, gchar *label, gchar *value, gint *n)
169 if (g_ascii_strcasecmp(option, label) != 0) return FALSE;
170 if (!n) return FALSE;
172 if (g_ascii_isdigit(value[0]) || (value[0] == '-' && g_ascii_isdigit(value[1])))
174 *n = strtol(value, NULL, 10);
178 if (g_ascii_strcasecmp(value, "true") == 0)
187 static void write_uint_option(SecureSaveInfo *ssi, gchar *label, guint n)
189 secure_fprintf(ssi, "%s: %u\n", label, n);
192 static gboolean read_uint_option(FILE *f, gchar *option, gchar *label, gchar *value, guint *n)
194 if (g_ascii_strcasecmp(option, label) != 0) return FALSE;
195 if (!n) return FALSE;
197 if (g_ascii_isdigit(value[0]))
199 *n = strtoul(value, NULL, 10);
203 if (g_ascii_strcasecmp(value, "true") == 0)
212 static gboolean read_int_option_clamp(FILE *f, gchar *option, gchar *label, gchar *value, gint *n, gint min, gint max)
216 ret = read_int_option(f, option, label, value, n);
217 if (ret) *n = CLAMP(*n, min, max);
222 static void write_int_unit_option(SecureSaveInfo *ssi, gchar *label, gint n, gint subunits)
237 secure_fprintf(ssi, "%s: %d.%d\n", label, l, r);
240 static gboolean read_int_unit_option(FILE *f, gchar *option, gchar *label, gchar *value, gint *n, gint subunits)
245 if (g_ascii_strcasecmp(option, label) != 0) return FALSE;
246 if (!n) return FALSE;
249 while (*ptr != '\0' && *ptr != '.') ptr++;
253 l = strtol(value, NULL, 10);
256 r = strtol(ptr, NULL, 10);
260 l = strtol(value, NULL, 10);
264 *n = l * subunits + r;
269 static void write_bool_option(SecureSaveInfo *ssi, gchar *label, gint n)
271 secure_fprintf(ssi, "%s: ", label);
272 if (n) secure_fprintf(ssi, "true\n"); else secure_fprintf(ssi, "false\n");
275 static gboolean read_bool_option(FILE *f, gchar *option, gchar *label, gchar *value, gint *n)
277 if (g_ascii_strcasecmp(option, label) != 0) return FALSE;
278 if (!n) return FALSE;
280 if (g_ascii_strcasecmp(value, "true") == 0 || atoi(value) != 0)
290 *-----------------------------------------------------------------------------
291 * save configuration (public)
292 *-----------------------------------------------------------------------------
295 static gboolean save_options_to(const gchar *utf8_path, ConfOptions *options)
301 rc_pathl = path_from_utf8(utf8_path);
302 ssi = secure_open(rc_pathl);
306 log_printf(_("error saving config file: %s\n"), utf8_path);
310 #define WRITE_BOOL(_name_) write_bool_option(ssi, #_name_, options->_name_)
311 #define WRITE_INT(_name_) write_int_option(ssi, #_name_, options->_name_)
312 #define WRITE_UINT(_name_) write_uint_option(ssi, #_name_, options->_name_)
313 #define WRITE_INT_UNIT(_name_, _unit_) write_int_unit_option(ssi, #_name_, options->_name_, _unit_)
314 #define WRITE_CHAR(_name_) write_char_option(ssi, #_name_, options->_name_)
315 #define WRITE_COLOR(_name_) write_color_option(ssi, #_name_, &options->_name_)
317 #define WRITE_SEPARATOR() secure_fputc(ssi, '\n')
318 #define WRITE_SUBTITLE(_title_) secure_fprintf(ssi, "\n\n##### "_title_" #####\n\n")
320 secure_fprintf(ssi, "######################################################################\n");
321 secure_fprintf(ssi, "# %30s config file version %-10s #\n", GQ_APPNAME, VERSION);
322 secure_fprintf(ssi, "######################################################################\n");
325 secure_fprintf(ssi, "# Note: This file is autogenerated. Options can be changed here,\n");
326 secure_fprintf(ssi, "# but user comments and formatting will be lost.\n");
329 WRITE_SUBTITLE("General Options");
331 WRITE_BOOL(show_icon_names);
332 WRITE_BOOL(show_copy_path);
335 WRITE_BOOL(tree_descend_subdirs);
336 WRITE_BOOL(lazy_image_sync);
337 WRITE_BOOL(update_on_time_change);
340 WRITE_BOOL(progressive_key_scrolling);
341 WRITE_BOOL(enable_metadata_dirs);
342 WRITE_BOOL(save_metadata_in_image_file);
344 WRITE_INT(duplicates_similarity_threshold);
347 WRITE_BOOL(mousewheel_scrolls);
348 WRITE_INT(open_recent_list_maxsize);
349 WRITE_INT(dnd_icon_size);
350 WRITE_BOOL(place_dialogs_under_mouse);
353 WRITE_SUBTITLE("Startup Options");
355 WRITE_BOOL(startup.restore_path);
356 WRITE_BOOL(startup.use_last_path);
357 WRITE_CHAR(startup.path);
360 WRITE_SUBTITLE("File operations Options");
362 WRITE_BOOL(file_ops.enable_in_place_rename);
363 WRITE_BOOL(file_ops.confirm_delete);
364 WRITE_BOOL(file_ops.enable_delete_key);
365 WRITE_BOOL(file_ops.safe_delete_enable);
366 WRITE_CHAR(file_ops.safe_delete_path);
367 WRITE_INT(file_ops.safe_delete_folder_maxsize);
370 WRITE_SUBTITLE("Layout Options");
372 WRITE_INT(layout.style);
373 WRITE_CHAR(layout.order);
374 WRITE_UINT(layout.dir_view_type);
375 WRITE_UINT(layout.file_view_type);
376 WRITE_BOOL(layout.show_marks);
377 WRITE_BOOL(layout.show_thumbnails);
380 WRITE_BOOL(layout.save_window_positions);
383 WRITE_INT(layout.main_window.x);
384 WRITE_INT(layout.main_window.y);
385 WRITE_INT(layout.main_window.w);
386 WRITE_INT(layout.main_window.h);
387 WRITE_BOOL(layout.main_window.maximized);
388 WRITE_INT(layout.main_window.hdivider_pos);
389 WRITE_INT(layout.main_window.vdivider_pos);
392 WRITE_INT(layout.float_window.x);
393 WRITE_INT(layout.float_window.y);
394 WRITE_INT(layout.float_window.w);
395 WRITE_INT(layout.float_window.h);
396 WRITE_INT(layout.float_window.vdivider_pos);
399 WRITE_BOOL(layout.tools_float);
400 WRITE_BOOL(layout.tools_hidden);
401 WRITE_BOOL(layout.tools_restore_state);
404 WRITE_BOOL(layout.toolbar_hidden);
406 WRITE_SUBTITLE("Panels Options");
408 WRITE_BOOL(panels.exif.enabled);
409 WRITE_INT(panels.exif.width);
410 WRITE_BOOL(panels.info.enabled);
411 WRITE_INT(panels.info.width);
412 WRITE_BOOL(panels.sort.enabled);
413 WRITE_INT(panels.sort.action_state);
414 WRITE_INT(panels.sort.mode_state);
415 WRITE_INT(panels.sort.selection_state);
417 WRITE_SUBTITLE("Properties dialog Options");
418 WRITE_CHAR(properties.tabs_order);
420 WRITE_SUBTITLE("Image Options");
422 secure_fprintf(ssi, "# image.zoom_mode possible values are:\n"
426 secure_fprintf(ssi, "image.zoom_mode: ");
427 if (options->image.zoom_mode == ZOOM_RESET_ORIGINAL)
428 secure_fprintf(ssi, "original\n");
429 else if (options->image.zoom_mode == ZOOM_RESET_FIT_WINDOW)
430 secure_fprintf(ssi, "fit\n");
431 else if (options->image.zoom_mode == ZOOM_RESET_NONE)
432 secure_fprintf(ssi, "dont_change\n");
434 WRITE_BOOL(image.zoom_2pass);
435 WRITE_BOOL(image.zoom_to_fit_allow_expand);
436 WRITE_INT(image.zoom_quality);
437 WRITE_INT(image.zoom_increment);
438 WRITE_BOOL(image.fit_window_to_image);
439 WRITE_BOOL(image.limit_window_size);
440 WRITE_INT(image.max_window_size);
441 WRITE_BOOL(image.limit_autofit_size);
442 WRITE_INT(image.max_autofit_size);
443 WRITE_INT(image.scroll_reset_method);
444 WRITE_INT(image.tile_cache_max);
445 WRITE_INT(image.dither_quality);
446 WRITE_BOOL(image.enable_read_ahead);
447 WRITE_BOOL(image.exif_rotate_enable);
448 WRITE_BOOL(image.use_custom_border_color);
449 WRITE_COLOR(image.border_color);
450 WRITE_INT(image.read_buffer_size);
451 WRITE_INT(image.idle_read_loop_count);
453 WRITE_SUBTITLE("Thumbnails Options");
455 WRITE_INT(thumbnails.max_width);
456 WRITE_INT(thumbnails.max_height);
457 WRITE_BOOL(thumbnails.enable_caching);
458 WRITE_BOOL(thumbnails.cache_into_dirs);
459 WRITE_BOOL(thumbnails.fast);
460 WRITE_BOOL(thumbnails.use_xvpics);
461 WRITE_BOOL(thumbnails.spec_standard);
462 WRITE_INT(thumbnails.quality);
465 WRITE_SUBTITLE("File sorting Options");
467 WRITE_INT(file_sort.method);
468 WRITE_BOOL(file_sort.ascending);
469 WRITE_BOOL(file_sort.case_sensitive);
472 WRITE_SUBTITLE("Fullscreen Options");
474 WRITE_INT(fullscreen.screen);
475 WRITE_BOOL(fullscreen.clean_flip);
476 WRITE_BOOL(fullscreen.disable_saver);
477 WRITE_BOOL(fullscreen.above);
480 WRITE_SUBTITLE("Histogram Options");
481 WRITE_UINT(histogram.last_channel_mode);
482 WRITE_UINT(histogram.last_log_mode);
485 WRITE_SUBTITLE("Image Overlay Options");
486 WRITE_UINT(image_overlay.common.state);
487 WRITE_BOOL(image_overlay.common.show_at_startup);
488 WRITE_CHAR(image_overlay.common.template_string);
491 WRITE_SUBTITLE("Slideshow Options");
493 WRITE_INT_UNIT(slideshow.delay, SLIDESHOW_SUBSECOND_PRECISION);
494 WRITE_BOOL(slideshow.random);
495 WRITE_BOOL(slideshow.repeat);
498 WRITE_SUBTITLE("Collection Options");
500 WRITE_BOOL(collections.rectangular_selection);
503 WRITE_SUBTITLE("Filtering Options");
505 WRITE_BOOL(file_filter.show_hidden_files);
506 WRITE_BOOL(file_filter.show_dot_directory);
507 WRITE_BOOL(file_filter.disable);
510 filter_write_list(ssi);
513 WRITE_SUBTITLE("Sidecars Options");
515 sidecar_ext_write(ssi);
518 WRITE_SUBTITLE("Color Profiles");
521 secure_fprintf(ssi, "# NOTICE: %s was not built with support for color profiles,\n"
522 "# color profile options will have no effect.\n\n", GQ_APPNAME);
525 WRITE_BOOL(color_profile.enabled);
526 WRITE_BOOL(color_profile.use_image);
527 WRITE_INT(color_profile.input_type);
530 for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
534 buf = g_strdup_printf("color_profile.input_file_%d", i + 1);
535 write_char_option(ssi, buf, options->color_profile.input_file[i]);
538 buf = g_strdup_printf("color_profile.input_name_%d", i + 1);
539 write_char_option(ssi, buf, options->color_profile.input_name[i]);
544 WRITE_INT(color_profile.screen_type);
545 WRITE_CHAR(color_profile.screen_file);
548 WRITE_SUBTITLE("Shell command");
549 WRITE_CHAR(shell.path);
550 WRITE_CHAR(shell.options);
553 WRITE_SUBTITLE("External Programs");
554 secure_fprintf(ssi, "# Maximum of %d programs (external_1 through external_%d)\n", GQ_EDITOR_GENERIC_SLOTS, GQ_EDITOR_GENERIC_SLOTS);
555 secure_fprintf(ssi, "# external_%d through external_%d are used for file ops\n", GQ_EDITOR_GENERIC_SLOTS + 1, GQ_EDITOR_SLOTS);
556 secure_fprintf(ssi, "# format: external_n: \"menu name\" \"command line\"\n\n");
558 for (i = 0; i < GQ_EDITOR_SLOTS; i++)
560 if (i == GQ_EDITOR_GENERIC_SLOTS) secure_fputc(ssi, '\n');
561 gchar *qname = escquote_value(options->editor[i].name);
562 gchar *qcommand = escquote_value(options->editor[i].command);
563 secure_fprintf(ssi, "external_%d: %s %s\n", i+1, qname, qcommand);
569 WRITE_SUBTITLE("Exif Options");
570 secure_fprintf(ssi, "# Display: 0: never\n"
573 for (i = 0; ExifUIList[i].key; i++)
575 secure_fprintf(ssi, "exif.display.");
576 write_int_option(ssi, (gchar *)ExifUIList[i].key, ExifUIList[i].current);
582 secure_fprintf(ssi, "######################################################################\n");
583 secure_fprintf(ssi, "# end of config file #\n");
584 secure_fprintf(ssi, "######################################################################\n");
587 if (secure_close(ssi))
589 log_printf(_("error saving config file: %s\nerror: %s\n"), utf8_path,
590 secsave_strerror(secsave_errno));
597 void save_options(ConfOptions *options)
601 rc_path = g_build_filename(homedir(), GQ_RC_DIR, RC_FILE_NAME, NULL);
602 save_options_to(rc_path, options);
609 *-----------------------------------------------------------------------------
610 * load configuration (public)
611 *-----------------------------------------------------------------------------
614 static gboolean is_numbered_option(const gchar *option, const gchar *prefix, gint *number)
617 gsize option_len = strlen(option);
618 gsize prefix_len = strlen(prefix);
620 if (option_len <= prefix_len) return FALSE;
621 if (g_ascii_strncasecmp(option, prefix, prefix_len) != 0) return FALSE;
624 while (g_ascii_isdigit(option[n])) n++;
625 if (n < option_len) return FALSE;
627 if (number) *number = atoi(option + prefix_len);
633 static gboolean load_options_from(const gchar *utf8_path, ConfOptions *options)
640 gchar value_all[1024];
643 rc_pathl = path_from_utf8(utf8_path);
644 f = fopen(rc_pathl,"r");
646 if (!f) return FALSE;
648 while (fgets(s_buf, sizeof(s_buf), f))
650 gchar *option_start, *value_start;
653 while (g_ascii_isspace(*p)) p++;
654 if (!*p || *p == '\n' || *p == '#') continue;
656 while (*p && *p != ':') p++;
660 strncpy(option, option_start, sizeof(option));
661 while (g_ascii_isspace(*p)) p++;
663 strncpy(value_all, value_start, sizeof(value_all));
664 while (*p && !g_ascii_isspace(*p) && *p != '\n') p++;
666 strncpy(value, value_start, sizeof(value));
668 #define READ_BOOL(_name_) if (read_bool_option(f, option, #_name_, value, &options->_name_)) continue;
669 #define READ_INT(_name_) if (read_int_option(f, option, #_name_, value, &options->_name_)) continue;
670 #define READ_UINT(_name_) if (read_uint_option(f, option, #_name_, value, &options->_name_)) continue;
671 #define READ_INT_CLAMP(_name_, _min_, _max_) if (read_int_option_clamp(f, option, #_name_, value, &options->_name_, _min_, _max_)) continue;
672 #define READ_INT_UNIT(_name_, _unit_) if (read_int_unit_option(f, option, #_name_, value, &options->_name_, _unit_)) continue;
673 #define READ_CHAR(_name_) if (read_char_option(f, option, #_name_, value_all, &options->_name_)) continue;
674 #define READ_COLOR(_name_) if (read_color_option(f, option, #_name_, value, &options->_name_)) continue;
676 #define COMPAT_READ_BOOL(_oldname_, _name_) if (read_bool_option(f, option, #_oldname_, value, &options->_name_)) continue;
677 #define COMPAT_READ_INT(_oldname_, _name_) if (read_int_option(f, option, #_oldname_, value, &options->_name_)) continue;
678 #define COMPAT_READ_UINT(_oldname_, _name_) if (read_uint_option(f, option, #_oldname_, value, &options->_name_)) continue;
679 #define COMPAT_READ_INT_CLAMP(_oldname_, _name_, _min_, _max_) if (read_int_option_clamp(f, option, #_oldname_, value, &options->_name_, _min_, _max_)) continue;
680 #define COMPAT_READ_INT_UNIT(_oldname_, _name_, _unit_) if (read_int_unit_option(f, option, #_oldname_, value, &options->_name_, _unit_)) continue;
681 #define COMPAT_READ_CHAR(_oldname_, _name_) if (read_char_option(f, option, #_oldname_, value_all, &options->_name_)) continue;
682 #define COMPAT_READ_COLOR(_oldname_, _name_) if (read_color_option(f, option, #_oldname_, value, &options->_name_)) continue;
684 /* general options */
685 READ_BOOL(show_icon_names);
686 READ_BOOL(show_copy_path);
688 READ_BOOL(tree_descend_subdirs);
689 READ_BOOL(lazy_image_sync);
690 READ_BOOL(update_on_time_change);
692 READ_INT(duplicates_similarity_threshold);
694 READ_BOOL(progressive_key_scrolling);
696 READ_BOOL(enable_metadata_dirs);
697 READ_BOOL(save_metadata_in_image_file);
699 READ_BOOL(mousewheel_scrolls);
701 READ_INT(open_recent_list_maxsize);
702 READ_INT(dnd_icon_size);
703 READ_BOOL(place_dialogs_under_mouse);
705 /* startup options */
707 COMPAT_READ_BOOL(startup_path_enable, startup.restore_path); /* 2008/05/11 */
708 READ_BOOL(startup.restore_path);
710 READ_BOOL(startup.use_last_path);
712 COMPAT_READ_CHAR(startup_path, startup.path); /* 2008/05/11 */
713 READ_CHAR(startup.path);
717 READ_INT(layout.style);
718 READ_CHAR(layout.order);
720 COMPAT_READ_UINT(layout.view_as_icons, layout.file_view_type); /* 2008/05/03 */
722 READ_UINT(layout.dir_view_type);
723 READ_UINT(layout.file_view_type);
724 READ_BOOL(layout.show_marks);
725 READ_BOOL(layout.show_thumbnails);
727 /* window positions */
729 READ_BOOL(layout.save_window_positions);
731 READ_INT(layout.main_window.x);
732 READ_INT(layout.main_window.y);
733 READ_INT(layout.main_window.w);
734 READ_INT(layout.main_window.h);
735 READ_BOOL(layout.main_window.maximized);
736 READ_INT(layout.float_window.x);
737 READ_INT(layout.float_window.y);
738 READ_INT(layout.float_window.w);
739 READ_INT(layout.float_window.h);
740 READ_INT(layout.float_window.vdivider_pos);
741 READ_INT(layout.main_window.hdivider_pos);
742 READ_INT(layout.main_window.vdivider_pos);
743 READ_BOOL(layout.tools_float);
744 READ_BOOL(layout.tools_hidden);
745 READ_BOOL(layout.tools_restore_state);
746 READ_BOOL(layout.toolbar_hidden);
749 READ_BOOL(panels.exif.enabled);
750 READ_INT_CLAMP(panels.exif.width, PANEL_MIN_WIDTH, PANEL_MAX_WIDTH);
751 READ_BOOL(panels.info.enabled);
752 READ_INT_CLAMP(panels.info.width, PANEL_MIN_WIDTH, PANEL_MAX_WIDTH);
753 READ_BOOL(panels.sort.enabled);
754 READ_INT(panels.sort.action_state);
755 READ_INT(panels.sort.mode_state);
756 READ_INT(panels.sort.selection_state);
758 /* properties dialog options */
759 READ_CHAR(properties.tabs_order);
762 if (g_ascii_strcasecmp(option, "image.zoom_mode") == 0)
764 if (g_ascii_strcasecmp(value, "original") == 0)
765 options->image.zoom_mode = ZOOM_RESET_ORIGINAL;
766 else if (g_ascii_strcasecmp(value, "fit") == 0)
767 options->image.zoom_mode = ZOOM_RESET_FIT_WINDOW;
768 else if (g_ascii_strcasecmp(value, "dont_change") == 0)
769 options->image.zoom_mode = ZOOM_RESET_NONE;
772 READ_BOOL(image.zoom_2pass);
773 READ_BOOL(image.zoom_to_fit_allow_expand);
774 READ_BOOL(image.fit_window_to_image);
775 READ_BOOL(image.limit_window_size);
776 READ_INT(image.max_window_size);
777 READ_BOOL(image.limit_autofit_size);
778 READ_INT(image.max_autofit_size);
779 READ_INT(image.scroll_reset_method);
780 READ_INT(image.tile_cache_max);
781 READ_INT_CLAMP(image.zoom_quality, GDK_INTERP_NEAREST, GDK_INTERP_HYPER);
782 READ_INT_CLAMP(image.dither_quality, GDK_RGB_DITHER_NONE, GDK_RGB_DITHER_MAX);
783 READ_INT(image.zoom_increment);
784 READ_BOOL(image.enable_read_ahead);
785 READ_BOOL(image.exif_rotate_enable);
786 READ_BOOL(image.use_custom_border_color);
787 READ_COLOR(image.border_color);
788 READ_INT_CLAMP(image.read_buffer_size, IMAGE_LOADER_READ_BUFFER_SIZE_MIN, IMAGE_LOADER_READ_BUFFER_SIZE_MAX);
789 READ_INT_CLAMP(image.idle_read_loop_count, IMAGE_LOADER_IDLE_READ_LOOP_COUNT_MIN, IMAGE_LOADER_IDLE_READ_LOOP_COUNT_MAX);
792 /* thumbnails options */
793 READ_INT_CLAMP(thumbnails.max_width, 16, 512);
794 READ_INT_CLAMP(thumbnails.max_height, 16, 512);
796 READ_BOOL(thumbnails.enable_caching);
797 READ_BOOL(thumbnails.cache_into_dirs);
798 READ_BOOL(thumbnails.fast);
799 READ_BOOL(thumbnails.use_xvpics);
800 READ_BOOL(thumbnails.spec_standard);
801 READ_INT_CLAMP(thumbnails.quality, GDK_INTERP_NEAREST, GDK_INTERP_HYPER);
803 /* file sorting options */
804 READ_UINT(file_sort.method);
805 READ_BOOL(file_sort.ascending);
806 READ_BOOL(file_sort.case_sensitive);
808 /* file operations options */
809 READ_BOOL(file_ops.enable_in_place_rename);
810 READ_BOOL(file_ops.confirm_delete);
811 READ_BOOL(file_ops.enable_delete_key);
812 READ_BOOL(file_ops.safe_delete_enable);
813 READ_CHAR(file_ops.safe_delete_path);
814 READ_INT(file_ops.safe_delete_folder_maxsize);
816 /* fullscreen options */
817 READ_INT(fullscreen.screen);
818 READ_BOOL(fullscreen.clean_flip);
819 READ_BOOL(fullscreen.disable_saver);
820 READ_BOOL(fullscreen.above);
823 READ_UINT(histogram.last_channel_mode);
824 READ_UINT(histogram.last_log_mode);
827 COMPAT_READ_UINT(image_overlay.common.enabled, image_overlay.common.state); /* 2008-05-12 */
828 READ_UINT(image_overlay.common.state);
829 COMPAT_READ_BOOL(fullscreen.show_info, image_overlay.common.show_at_startup); /* 2008-04-21 */
830 READ_BOOL(image_overlay.common.show_at_startup);
831 COMPAT_READ_CHAR(fullscreen.info, image_overlay.common.template_string); /* 2008-04-21 */
832 READ_CHAR(image_overlay.common.template_string);
834 /* slideshow options */
835 READ_INT_UNIT(slideshow.delay, SLIDESHOW_SUBSECOND_PRECISION);
836 READ_BOOL(slideshow.random);
837 READ_BOOL(slideshow.repeat);
839 /* collection options */
841 READ_BOOL(collections.rectangular_selection);
843 /* filtering options */
845 READ_BOOL(file_filter.show_hidden_files);
846 READ_BOOL(file_filter.show_dot_directory);
847 READ_BOOL(file_filter.disable);
849 if (g_ascii_strcasecmp(option, "file_filter.ext") == 0)
851 filter_parse(value_all);
855 if (g_ascii_strcasecmp(option, "sidecar.ext") == 0)
857 sidecar_ext_parse(value_all, TRUE);
863 READ_BOOL(color_profile.enabled);
864 READ_BOOL(color_profile.use_image);
865 READ_INT(color_profile.input_type);
867 if (is_numbered_option(option, "color_profile.input_file_", &i))
869 if (i > 0 && i <= COLOR_PROFILE_INPUTS)
872 read_char_option(f, option, option, value, &options->color_profile.input_file[i]);
877 if (is_numbered_option(option, "color_profile.input_name_", &i))
879 if (i > 0 && i <= COLOR_PROFILE_INPUTS)
882 read_char_option(f, option, option, value, &options->color_profile.input_name[i]);
887 READ_INT(color_profile.screen_type);
888 READ_CHAR(color_profile.screen_file);
891 READ_CHAR(shell.path);
892 READ_CHAR(shell.options);
894 /* External Programs */
896 if (is_numbered_option(option, "external_", &i))
898 if (i > 0 && i <= GQ_EDITOR_SLOTS)
902 g_free(options->editor[i].name);
903 g_free(options->editor[i].command);
905 options->editor[i].name = quoted_value(value_all, &ptr);
906 options->editor[i].command = quoted_value(ptr, NULL);
912 if (0 == g_ascii_strncasecmp(option, "exif.display.", 13))
914 for (i = 0; ExifUIList[i].key; i++)
915 if (0 == g_ascii_strcasecmp(option + 13, ExifUIList[i].key))
916 ExifUIList[i].current = strtol(value, NULL, 10);
925 void load_options(ConfOptions *options)
929 rc_path = g_build_filename(homedir(), GQ_RC_DIR, RC_FILE_NAME, NULL);
930 load_options_from(rc_path, options);