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_INT(layout.properties_window.w);
400 WRITE_INT(layout.properties_window.h);
403 WRITE_BOOL(layout.tools_float);
404 WRITE_BOOL(layout.tools_hidden);
405 WRITE_BOOL(layout.tools_restore_state);
408 WRITE_BOOL(layout.toolbar_hidden);
410 WRITE_SUBTITLE("Panels Options");
412 WRITE_BOOL(panels.exif.enabled);
413 WRITE_INT(panels.exif.width);
414 WRITE_BOOL(panels.info.enabled);
415 WRITE_INT(panels.info.width);
416 WRITE_BOOL(panels.sort.enabled);
417 WRITE_INT(panels.sort.action_state);
418 WRITE_INT(panels.sort.mode_state);
419 WRITE_INT(panels.sort.selection_state);
421 WRITE_SUBTITLE("Properties dialog Options");
422 WRITE_CHAR(properties.tabs_order);
424 WRITE_SUBTITLE("Image Options");
426 secure_fprintf(ssi, "# image.zoom_mode possible values are:\n"
430 secure_fprintf(ssi, "image.zoom_mode: ");
431 if (options->image.zoom_mode == ZOOM_RESET_ORIGINAL)
432 secure_fprintf(ssi, "original\n");
433 else if (options->image.zoom_mode == ZOOM_RESET_FIT_WINDOW)
434 secure_fprintf(ssi, "fit\n");
435 else if (options->image.zoom_mode == ZOOM_RESET_NONE)
436 secure_fprintf(ssi, "dont_change\n");
438 WRITE_BOOL(image.zoom_2pass);
439 WRITE_BOOL(image.zoom_to_fit_allow_expand);
440 WRITE_INT(image.zoom_quality);
441 WRITE_INT(image.zoom_increment);
442 WRITE_BOOL(image.fit_window_to_image);
443 WRITE_BOOL(image.limit_window_size);
444 WRITE_INT(image.max_window_size);
445 WRITE_BOOL(image.limit_autofit_size);
446 WRITE_INT(image.max_autofit_size);
447 WRITE_INT(image.scroll_reset_method);
448 WRITE_INT(image.tile_cache_max);
449 WRITE_INT(image.dither_quality);
450 WRITE_BOOL(image.enable_read_ahead);
451 WRITE_BOOL(image.exif_rotate_enable);
452 WRITE_BOOL(image.use_custom_border_color);
453 WRITE_COLOR(image.border_color);
454 WRITE_INT(image.read_buffer_size);
455 WRITE_INT(image.idle_read_loop_count);
457 WRITE_SUBTITLE("Thumbnails Options");
459 WRITE_INT(thumbnails.max_width);
460 WRITE_INT(thumbnails.max_height);
461 WRITE_BOOL(thumbnails.enable_caching);
462 WRITE_BOOL(thumbnails.cache_into_dirs);
463 WRITE_BOOL(thumbnails.fast);
464 WRITE_BOOL(thumbnails.use_xvpics);
465 WRITE_BOOL(thumbnails.spec_standard);
466 WRITE_INT(thumbnails.quality);
469 WRITE_SUBTITLE("File sorting Options");
471 WRITE_INT(file_sort.method);
472 WRITE_BOOL(file_sort.ascending);
473 WRITE_BOOL(file_sort.case_sensitive);
476 WRITE_SUBTITLE("Fullscreen Options");
478 WRITE_INT(fullscreen.screen);
479 WRITE_BOOL(fullscreen.clean_flip);
480 WRITE_BOOL(fullscreen.disable_saver);
481 WRITE_BOOL(fullscreen.above);
484 WRITE_SUBTITLE("Histogram Options");
485 WRITE_UINT(histogram.last_channel_mode);
486 WRITE_UINT(histogram.last_log_mode);
489 WRITE_SUBTITLE("Image Overlay Options");
490 WRITE_UINT(image_overlay.common.state);
491 WRITE_BOOL(image_overlay.common.show_at_startup);
492 WRITE_CHAR(image_overlay.common.template_string);
495 WRITE_SUBTITLE("Slideshow Options");
497 WRITE_INT_UNIT(slideshow.delay, SLIDESHOW_SUBSECOND_PRECISION);
498 WRITE_BOOL(slideshow.random);
499 WRITE_BOOL(slideshow.repeat);
502 WRITE_SUBTITLE("Collection Options");
504 WRITE_BOOL(collections.rectangular_selection);
507 WRITE_SUBTITLE("Filtering Options");
509 WRITE_BOOL(file_filter.show_hidden_files);
510 WRITE_BOOL(file_filter.show_dot_directory);
511 WRITE_BOOL(file_filter.disable);
514 filter_write_list(ssi);
517 WRITE_SUBTITLE("Sidecars Options");
519 sidecar_ext_write(ssi);
522 WRITE_SUBTITLE("Color Profiles");
525 secure_fprintf(ssi, "# NOTICE: %s was not built with support for color profiles,\n"
526 "# color profile options will have no effect.\n\n", GQ_APPNAME);
529 WRITE_BOOL(color_profile.enabled);
530 WRITE_BOOL(color_profile.use_image);
531 WRITE_INT(color_profile.input_type);
534 for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
538 buf = g_strdup_printf("color_profile.input_file_%d", i + 1);
539 write_char_option(ssi, buf, options->color_profile.input_file[i]);
542 buf = g_strdup_printf("color_profile.input_name_%d", i + 1);
543 write_char_option(ssi, buf, options->color_profile.input_name[i]);
548 WRITE_INT(color_profile.screen_type);
549 WRITE_CHAR(color_profile.screen_file);
552 WRITE_SUBTITLE("Shell command");
553 WRITE_CHAR(shell.path);
554 WRITE_CHAR(shell.options);
557 WRITE_SUBTITLE("External Programs");
558 secure_fprintf(ssi, "# Maximum of %d programs (external_1 through external_%d)\n", GQ_EDITOR_GENERIC_SLOTS, GQ_EDITOR_GENERIC_SLOTS);
559 secure_fprintf(ssi, "# external_%d through external_%d are used for file ops\n", GQ_EDITOR_GENERIC_SLOTS + 1, GQ_EDITOR_SLOTS);
560 secure_fprintf(ssi, "# format: external_n: \"menu name\" \"command line\"\n\n");
562 for (i = 0; i < GQ_EDITOR_SLOTS; i++)
564 if (i == GQ_EDITOR_GENERIC_SLOTS) secure_fputc(ssi, '\n');
565 gchar *qname = escquote_value(options->editor[i].name);
566 gchar *qcommand = escquote_value(options->editor[i].command);
567 secure_fprintf(ssi, "external_%d: %s %s\n", i+1, qname, qcommand);
573 WRITE_SUBTITLE("Exif Options");
574 secure_fprintf(ssi, "# Display: 0: never\n"
577 for (i = 0; ExifUIList[i].key; i++)
579 secure_fprintf(ssi, "exif.display.");
580 write_int_option(ssi, (gchar *)ExifUIList[i].key, ExifUIList[i].current);
586 secure_fprintf(ssi, "######################################################################\n");
587 secure_fprintf(ssi, "# end of config file #\n");
588 secure_fprintf(ssi, "######################################################################\n");
591 if (secure_close(ssi))
593 log_printf(_("error saving config file: %s\nerror: %s\n"), utf8_path,
594 secsave_strerror(secsave_errno));
601 void save_options(ConfOptions *options)
605 rc_path = g_build_filename(homedir(), GQ_RC_DIR, RC_FILE_NAME, NULL);
606 save_options_to(rc_path, options);
613 *-----------------------------------------------------------------------------
614 * load configuration (public)
615 *-----------------------------------------------------------------------------
618 static gboolean is_numbered_option(const gchar *option, const gchar *prefix, gint *number)
621 gsize option_len = strlen(option);
622 gsize prefix_len = strlen(prefix);
624 if (option_len <= prefix_len) return FALSE;
625 if (g_ascii_strncasecmp(option, prefix, prefix_len) != 0) return FALSE;
628 while (g_ascii_isdigit(option[n])) n++;
629 if (n < option_len) return FALSE;
631 if (number) *number = atoi(option + prefix_len);
637 static gboolean load_options_from(const gchar *utf8_path, ConfOptions *options)
644 gchar value_all[1024];
647 rc_pathl = path_from_utf8(utf8_path);
648 f = fopen(rc_pathl,"r");
650 if (!f) return FALSE;
652 while (fgets(s_buf, sizeof(s_buf), f))
654 gchar *option_start, *value_start;
657 while (g_ascii_isspace(*p)) p++;
658 if (!*p || *p == '\n' || *p == '#') continue;
660 while (*p && *p != ':') p++;
664 strncpy(option, option_start, sizeof(option));
665 while (g_ascii_isspace(*p)) p++;
667 strncpy(value_all, value_start, sizeof(value_all));
668 while (*p && !g_ascii_isspace(*p) && *p != '\n') p++;
670 strncpy(value, value_start, sizeof(value));
672 #define READ_BOOL(_name_) if (read_bool_option(f, option, #_name_, value, &options->_name_)) continue;
673 #define READ_INT(_name_) if (read_int_option(f, option, #_name_, value, &options->_name_)) continue;
674 #define READ_UINT(_name_) if (read_uint_option(f, option, #_name_, value, &options->_name_)) continue;
675 #define READ_INT_CLAMP(_name_, _min_, _max_) if (read_int_option_clamp(f, option, #_name_, value, &options->_name_, _min_, _max_)) continue;
676 #define READ_INT_UNIT(_name_, _unit_) if (read_int_unit_option(f, option, #_name_, value, &options->_name_, _unit_)) continue;
677 #define READ_CHAR(_name_) if (read_char_option(f, option, #_name_, value_all, &options->_name_)) continue;
678 #define READ_COLOR(_name_) if (read_color_option(f, option, #_name_, value, &options->_name_)) continue;
680 #define COMPAT_READ_BOOL(_oldname_, _name_) if (read_bool_option(f, option, #_oldname_, value, &options->_name_)) continue;
681 #define COMPAT_READ_INT(_oldname_, _name_) if (read_int_option(f, option, #_oldname_, value, &options->_name_)) continue;
682 #define COMPAT_READ_UINT(_oldname_, _name_) if (read_uint_option(f, option, #_oldname_, value, &options->_name_)) continue;
683 #define COMPAT_READ_INT_CLAMP(_oldname_, _name_, _min_, _max_) if (read_int_option_clamp(f, option, #_oldname_, value, &options->_name_, _min_, _max_)) continue;
684 #define COMPAT_READ_INT_UNIT(_oldname_, _name_, _unit_) if (read_int_unit_option(f, option, #_oldname_, value, &options->_name_, _unit_)) continue;
685 #define COMPAT_READ_CHAR(_oldname_, _name_) if (read_char_option(f, option, #_oldname_, value_all, &options->_name_)) continue;
686 #define COMPAT_READ_COLOR(_oldname_, _name_) if (read_color_option(f, option, #_oldname_, value, &options->_name_)) continue;
688 /* general options */
689 READ_BOOL(show_icon_names);
690 READ_BOOL(show_copy_path);
692 READ_BOOL(tree_descend_subdirs);
693 READ_BOOL(lazy_image_sync);
694 READ_BOOL(update_on_time_change);
696 READ_INT(duplicates_similarity_threshold);
698 READ_BOOL(progressive_key_scrolling);
700 READ_BOOL(enable_metadata_dirs);
701 READ_BOOL(save_metadata_in_image_file);
703 READ_BOOL(mousewheel_scrolls);
705 READ_INT(open_recent_list_maxsize);
706 READ_INT(dnd_icon_size);
707 READ_BOOL(place_dialogs_under_mouse);
709 /* startup options */
711 COMPAT_READ_BOOL(startup_path_enable, startup.restore_path); /* 2008/05/11 */
712 READ_BOOL(startup.restore_path);
714 READ_BOOL(startup.use_last_path);
716 COMPAT_READ_CHAR(startup_path, startup.path); /* 2008/05/11 */
717 READ_CHAR(startup.path);
721 READ_INT(layout.style);
722 READ_CHAR(layout.order);
724 COMPAT_READ_UINT(layout.view_as_icons, layout.file_view_type); /* 2008/05/03 */
726 READ_UINT(layout.dir_view_type);
727 READ_UINT(layout.file_view_type);
728 READ_BOOL(layout.show_marks);
729 READ_BOOL(layout.show_thumbnails);
731 /* window positions */
733 READ_BOOL(layout.save_window_positions);
735 READ_INT(layout.main_window.x);
736 READ_INT(layout.main_window.y);
737 READ_INT(layout.main_window.w);
738 READ_INT(layout.main_window.h);
739 READ_BOOL(layout.main_window.maximized);
740 READ_INT(layout.main_window.hdivider_pos);
741 READ_INT(layout.main_window.vdivider_pos);
743 READ_INT(layout.float_window.x);
744 READ_INT(layout.float_window.y);
745 READ_INT(layout.float_window.w);
746 READ_INT(layout.float_window.h);
747 READ_INT(layout.float_window.vdivider_pos);
749 READ_INT(layout.properties_window.w);
750 READ_INT(layout.properties_window.h);
752 READ_BOOL(layout.tools_float);
753 READ_BOOL(layout.tools_hidden);
754 READ_BOOL(layout.tools_restore_state);
755 READ_BOOL(layout.toolbar_hidden);
758 READ_BOOL(panels.exif.enabled);
759 READ_INT_CLAMP(panels.exif.width, PANEL_MIN_WIDTH, PANEL_MAX_WIDTH);
760 READ_BOOL(panels.info.enabled);
761 READ_INT_CLAMP(panels.info.width, PANEL_MIN_WIDTH, PANEL_MAX_WIDTH);
762 READ_BOOL(panels.sort.enabled);
763 READ_INT(panels.sort.action_state);
764 READ_INT(panels.sort.mode_state);
765 READ_INT(panels.sort.selection_state);
767 /* properties dialog options */
768 READ_CHAR(properties.tabs_order);
771 if (g_ascii_strcasecmp(option, "image.zoom_mode") == 0)
773 if (g_ascii_strcasecmp(value, "original") == 0)
774 options->image.zoom_mode = ZOOM_RESET_ORIGINAL;
775 else if (g_ascii_strcasecmp(value, "fit") == 0)
776 options->image.zoom_mode = ZOOM_RESET_FIT_WINDOW;
777 else if (g_ascii_strcasecmp(value, "dont_change") == 0)
778 options->image.zoom_mode = ZOOM_RESET_NONE;
781 READ_BOOL(image.zoom_2pass);
782 READ_BOOL(image.zoom_to_fit_allow_expand);
783 READ_BOOL(image.fit_window_to_image);
784 READ_BOOL(image.limit_window_size);
785 READ_INT(image.max_window_size);
786 READ_BOOL(image.limit_autofit_size);
787 READ_INT(image.max_autofit_size);
788 READ_INT(image.scroll_reset_method);
789 READ_INT(image.tile_cache_max);
790 READ_INT_CLAMP(image.zoom_quality, GDK_INTERP_NEAREST, GDK_INTERP_HYPER);
791 READ_INT_CLAMP(image.dither_quality, GDK_RGB_DITHER_NONE, GDK_RGB_DITHER_MAX);
792 READ_INT(image.zoom_increment);
793 READ_BOOL(image.enable_read_ahead);
794 READ_BOOL(image.exif_rotate_enable);
795 READ_BOOL(image.use_custom_border_color);
796 READ_COLOR(image.border_color);
797 READ_INT_CLAMP(image.read_buffer_size, IMAGE_LOADER_READ_BUFFER_SIZE_MIN, IMAGE_LOADER_READ_BUFFER_SIZE_MAX);
798 READ_INT_CLAMP(image.idle_read_loop_count, IMAGE_LOADER_IDLE_READ_LOOP_COUNT_MIN, IMAGE_LOADER_IDLE_READ_LOOP_COUNT_MAX);
801 /* thumbnails options */
802 READ_INT_CLAMP(thumbnails.max_width, 16, 512);
803 READ_INT_CLAMP(thumbnails.max_height, 16, 512);
805 READ_BOOL(thumbnails.enable_caching);
806 READ_BOOL(thumbnails.cache_into_dirs);
807 READ_BOOL(thumbnails.fast);
808 READ_BOOL(thumbnails.use_xvpics);
809 READ_BOOL(thumbnails.spec_standard);
810 READ_INT_CLAMP(thumbnails.quality, GDK_INTERP_NEAREST, GDK_INTERP_HYPER);
812 /* file sorting options */
813 READ_UINT(file_sort.method);
814 READ_BOOL(file_sort.ascending);
815 READ_BOOL(file_sort.case_sensitive);
817 /* file operations options */
818 READ_BOOL(file_ops.enable_in_place_rename);
819 READ_BOOL(file_ops.confirm_delete);
820 READ_BOOL(file_ops.enable_delete_key);
821 READ_BOOL(file_ops.safe_delete_enable);
822 READ_CHAR(file_ops.safe_delete_path);
823 READ_INT(file_ops.safe_delete_folder_maxsize);
825 /* fullscreen options */
826 READ_INT(fullscreen.screen);
827 READ_BOOL(fullscreen.clean_flip);
828 READ_BOOL(fullscreen.disable_saver);
829 READ_BOOL(fullscreen.above);
832 READ_UINT(histogram.last_channel_mode);
833 READ_UINT(histogram.last_log_mode);
836 COMPAT_READ_UINT(image_overlay.common.enabled, image_overlay.common.state); /* 2008-05-12 */
837 READ_UINT(image_overlay.common.state);
838 COMPAT_READ_BOOL(fullscreen.show_info, image_overlay.common.show_at_startup); /* 2008-04-21 */
839 READ_BOOL(image_overlay.common.show_at_startup);
840 COMPAT_READ_CHAR(fullscreen.info, image_overlay.common.template_string); /* 2008-04-21 */
841 READ_CHAR(image_overlay.common.template_string);
843 /* slideshow options */
844 READ_INT_UNIT(slideshow.delay, SLIDESHOW_SUBSECOND_PRECISION);
845 READ_BOOL(slideshow.random);
846 READ_BOOL(slideshow.repeat);
848 /* collection options */
850 READ_BOOL(collections.rectangular_selection);
852 /* filtering options */
854 READ_BOOL(file_filter.show_hidden_files);
855 READ_BOOL(file_filter.show_dot_directory);
856 READ_BOOL(file_filter.disable);
858 if (g_ascii_strcasecmp(option, "file_filter.ext") == 0)
860 filter_parse(value_all);
864 if (g_ascii_strcasecmp(option, "sidecar.ext") == 0)
866 sidecar_ext_parse(value_all, TRUE);
872 READ_BOOL(color_profile.enabled);
873 READ_BOOL(color_profile.use_image);
874 READ_INT(color_profile.input_type);
876 if (is_numbered_option(option, "color_profile.input_file_", &i))
878 if (i > 0 && i <= COLOR_PROFILE_INPUTS)
881 read_char_option(f, option, option, value, &options->color_profile.input_file[i]);
886 if (is_numbered_option(option, "color_profile.input_name_", &i))
888 if (i > 0 && i <= COLOR_PROFILE_INPUTS)
891 read_char_option(f, option, option, value, &options->color_profile.input_name[i]);
896 READ_INT(color_profile.screen_type);
897 READ_CHAR(color_profile.screen_file);
900 READ_CHAR(shell.path);
901 READ_CHAR(shell.options);
903 /* External Programs */
905 if (is_numbered_option(option, "external_", &i))
907 if (i > 0 && i <= GQ_EDITOR_SLOTS)
911 g_free(options->editor[i].name);
912 g_free(options->editor[i].command);
914 options->editor[i].name = quoted_value(value_all, &ptr);
915 options->editor[i].command = quoted_value(ptr, NULL);
921 if (0 == g_ascii_strncasecmp(option, "exif.display.", 13))
923 for (i = 0; ExifUIList[i].key; i++)
924 if (0 == g_ascii_strcasecmp(option + 13, ExifUIList[i].key))
925 ExifUIList[i].current = strtol(value, NULL, 10);
934 void load_options(ConfOptions *options)
939 if (isdir(GQ_SYSTEM_WIDE_DIR))
941 rc_path = g_build_filename(GQ_SYSTEM_WIDE_DIR, RC_FILE_NAME, NULL);
942 success = load_options_from(rc_path, options);
943 DEBUG_1("Loading options from %s ... %s", rc_path, success ? "done" : "failed");
947 rc_path = g_build_filename(homedir(), GQ_RC_DIR, RC_FILE_NAME, NULL);
948 success = load_options_from(rc_path, options);
949 DEBUG_1("Loading options from %s ... %s", rc_path, success ? "done" : "failed");