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>
21 #include "filefilter.h"
22 #include "secure_save.h"
23 #include "slideshow.h"
24 #include "ui_fileops.h"
28 *-----------------------------------------------------------------------------
29 * line write/parse routines (private)
30 *-----------------------------------------------------------------------------
34 returns text without quotes or NULL for empty or broken string
35 any text up to first '"' is skipped
36 tail is set to point at the char after the second '"'
41 gchar *quoted_value(const gchar *text, const gchar **tail)
45 gint l = strlen(text);
48 if (tail) *tail = text;
50 if (l == 0) return retval;
52 while (c < l && text[c] != '"') c++;
61 if (text[e-1] != '\\' && text[e] == '"') break;
68 gchar *substring = g_strndup(ptr, e - c);
72 retval = g_strcompress(substring);
77 if (tail) *tail = text + e + 1;
80 /* for compatibility with older formats (<0.3.7)
81 * read a line without quotes too */
84 while (c < l && text[c] != '\n' && !g_ascii_isspace(text[c])) c++;
87 retval = g_strndup(text, c);
89 if (tail) *tail = text + c;
95 gchar *escquote_value(const gchar *text)
99 if (!text) return g_strdup("\"\"");
101 e = g_strescape(text, "");
104 gchar *retval = g_strdup_printf("\"%s\"", e);
108 return g_strdup("\"\"");
111 static void write_char_option(SecureSaveInfo *ssi, gchar *label, gchar *text)
113 gchar *escval = escquote_value(text);
115 secure_fprintf(ssi, "%s: %s\n", label, escval);
119 static gboolean read_char_option(FILE *f, gchar *option, gchar *label, gchar *value, gchar **text)
121 if (g_ascii_strcasecmp(option, label) != 0) return FALSE;
122 if (!text) return FALSE;
125 *text = quoted_value(value, NULL);
129 /* Since gdk_color_to_string() is only available since gtk 2.12
130 * here is an equivalent stub function. */
131 static gchar *color_to_string(GdkColor *color)
133 return g_strdup_printf("#%04X%04X%04X", color->red, color->green, color->blue);
136 static void write_color_option(SecureSaveInfo *ssi, gchar *label, GdkColor *color)
140 gchar *colorstring = color_to_string(color);
142 write_char_option(ssi, label, colorstring);
146 secure_fprintf(ssi, "%s: \n", label);
149 static gboolean read_color_option(FILE *f, gchar *option, gchar *label, gchar *value, GdkColor *color)
153 if (g_ascii_strcasecmp(option, label) != 0) return FALSE;
154 if (!color) return FALSE;
156 colorstr = quoted_value(value, NULL);
157 if (!colorstr) return FALSE;
158 gdk_color_parse(colorstr, color);
163 static void write_int_option(SecureSaveInfo *ssi, gchar *label, gint n)
165 secure_fprintf(ssi, "%s: %d\n", label, n);
168 static gboolean read_int_option(FILE *f, gchar *option, gchar *label, gchar *value, gint *n)
170 if (g_ascii_strcasecmp(option, label) != 0) return FALSE;
171 if (!n) return FALSE;
173 if (g_ascii_isdigit(value[0]) || (value[0] == '-' && g_ascii_isdigit(value[1])))
175 *n = strtol(value, NULL, 10);
179 if (g_ascii_strcasecmp(value, "true") == 0)
188 static void write_uint_option(SecureSaveInfo *ssi, gchar *label, guint n)
190 secure_fprintf(ssi, "%s: %u\n", label, n);
193 static gboolean read_uint_option(FILE *f, gchar *option, gchar *label, gchar *value, guint *n)
195 if (g_ascii_strcasecmp(option, label) != 0) return FALSE;
196 if (!n) return FALSE;
198 if (g_ascii_isdigit(value[0]))
200 *n = strtoul(value, NULL, 10);
204 if (g_ascii_strcasecmp(value, "true") == 0)
213 static gboolean read_int_option_clamp(FILE *f, gchar *option, gchar *label, gchar *value, gint *n, gint min, gint max)
217 ret = read_int_option(f, option, label, value, n);
218 if (ret) *n = CLAMP(*n, min, max);
223 static void write_int_unit_option(SecureSaveInfo *ssi, gchar *label, gint n, gint subunits)
238 secure_fprintf(ssi, "%s: %d.%d\n", label, l, r);
241 static gboolean read_int_unit_option(FILE *f, gchar *option, gchar *label, gchar *value, gint *n, gint subunits)
246 if (g_ascii_strcasecmp(option, label) != 0) return FALSE;
247 if (!n) return FALSE;
250 while (*ptr != '\0' && *ptr != '.') ptr++;
254 l = strtol(value, NULL, 10);
257 r = strtol(ptr, NULL, 10);
261 l = strtol(value, NULL, 10);
265 *n = l * subunits + r;
270 static void write_bool_option(SecureSaveInfo *ssi, gchar *label, gint n)
272 secure_fprintf(ssi, "%s: ", label);
273 if (n) secure_fprintf(ssi, "true\n"); else secure_fprintf(ssi, "false\n");
276 static gboolean read_bool_option(FILE *f, gchar *option, gchar *label, gchar *value, gint *n)
278 if (g_ascii_strcasecmp(option, label) != 0) return FALSE;
279 if (!n) return FALSE;
281 if (g_ascii_strcasecmp(value, "true") == 0 || atoi(value) != 0)
291 *-----------------------------------------------------------------------------
292 * save configuration (public)
293 *-----------------------------------------------------------------------------
296 static gboolean save_options_to(const gchar *utf8_path, ConfOptions *options)
302 rc_pathl = path_from_utf8(utf8_path);
303 ssi = secure_open(rc_pathl);
307 log_printf(_("error saving config file: %s\n"), utf8_path);
311 #define WRITE_BOOL(_name_) write_bool_option(ssi, #_name_, options->_name_)
312 #define WRITE_INT(_name_) write_int_option(ssi, #_name_, options->_name_)
313 #define WRITE_UINT(_name_) write_uint_option(ssi, #_name_, options->_name_)
314 #define WRITE_INT_UNIT(_name_, _unit_) write_int_unit_option(ssi, #_name_, options->_name_, _unit_)
315 #define WRITE_CHAR(_name_) write_char_option(ssi, #_name_, options->_name_)
316 #define WRITE_COLOR(_name_) write_color_option(ssi, #_name_, &options->_name_)
318 #define WRITE_SEPARATOR() secure_fputc(ssi, '\n')
319 #define WRITE_SUBTITLE(_title_) secure_fprintf(ssi, "\n\n##### "_title_" #####\n\n")
321 secure_fprintf(ssi, "######################################################################\n");
322 secure_fprintf(ssi, "# %30s config file version %-10s #\n", GQ_APPNAME, VERSION);
323 secure_fprintf(ssi, "######################################################################\n");
326 secure_fprintf(ssi, "# Note: This file is autogenerated. Options can be changed here,\n");
327 secure_fprintf(ssi, "# but user comments and formatting will be lost.\n");
330 WRITE_SUBTITLE("General Options");
332 WRITE_BOOL(show_icon_names);
333 WRITE_BOOL(show_copy_path);
336 WRITE_BOOL(tree_descend_subdirs);
337 WRITE_BOOL(lazy_image_sync);
338 WRITE_BOOL(update_on_time_change);
341 WRITE_BOOL(progressive_key_scrolling);
342 WRITE_BOOL(enable_metadata_dirs);
343 WRITE_BOOL(save_metadata_in_image_file);
345 WRITE_INT(duplicates_similarity_threshold);
348 WRITE_BOOL(mousewheel_scrolls);
349 WRITE_INT(open_recent_list_maxsize);
350 WRITE_INT(dnd_icon_size);
351 WRITE_BOOL(place_dialogs_under_mouse);
354 WRITE_SUBTITLE("Startup Options");
356 WRITE_BOOL(startup.restore_path);
357 WRITE_BOOL(startup.use_last_path);
358 WRITE_CHAR(startup.path);
361 WRITE_SUBTITLE("File operations Options");
363 WRITE_BOOL(file_ops.enable_in_place_rename);
364 WRITE_BOOL(file_ops.confirm_delete);
365 WRITE_BOOL(file_ops.enable_delete_key);
366 WRITE_BOOL(file_ops.safe_delete_enable);
367 WRITE_CHAR(file_ops.safe_delete_path);
368 WRITE_INT(file_ops.safe_delete_folder_maxsize);
371 WRITE_SUBTITLE("Layout Options");
373 WRITE_INT(layout.style);
374 WRITE_CHAR(layout.order);
375 WRITE_UINT(layout.dir_view_type);
376 WRITE_UINT(layout.file_view_type);
377 WRITE_BOOL(layout.show_marks);
378 WRITE_BOOL(layout.show_thumbnails);
379 WRITE_BOOL(layout.show_directory_date);
382 WRITE_BOOL(layout.save_window_positions);
385 WRITE_INT(layout.main_window.x);
386 WRITE_INT(layout.main_window.y);
387 WRITE_INT(layout.main_window.w);
388 WRITE_INT(layout.main_window.h);
389 WRITE_BOOL(layout.main_window.maximized);
390 WRITE_INT(layout.main_window.hdivider_pos);
391 WRITE_INT(layout.main_window.vdivider_pos);
394 WRITE_INT(layout.float_window.x);
395 WRITE_INT(layout.float_window.y);
396 WRITE_INT(layout.float_window.w);
397 WRITE_INT(layout.float_window.h);
398 WRITE_INT(layout.float_window.vdivider_pos);
401 WRITE_INT(layout.properties_window.w);
402 WRITE_INT(layout.properties_window.h);
405 WRITE_BOOL(layout.tools_float);
406 WRITE_BOOL(layout.tools_hidden);
407 WRITE_BOOL(layout.tools_restore_state);
410 WRITE_BOOL(layout.toolbar_hidden);
412 WRITE_SUBTITLE("Panels Options");
414 WRITE_BOOL(panels.exif.enabled);
415 WRITE_INT(panels.exif.width);
416 WRITE_BOOL(panels.info.enabled);
417 WRITE_INT(panels.info.width);
418 WRITE_BOOL(panels.sort.enabled);
419 WRITE_INT(panels.sort.action_state);
420 WRITE_INT(panels.sort.mode_state);
421 WRITE_INT(panels.sort.selection_state);
423 WRITE_SUBTITLE("Properties dialog Options");
424 WRITE_CHAR(properties.tabs_order);
426 WRITE_SUBTITLE("Image Options");
428 secure_fprintf(ssi, "# image.zoom_mode possible values are:\n"
432 secure_fprintf(ssi, "image.zoom_mode: ");
433 if (options->image.zoom_mode == ZOOM_RESET_ORIGINAL)
434 secure_fprintf(ssi, "original\n");
435 else if (options->image.zoom_mode == ZOOM_RESET_FIT_WINDOW)
436 secure_fprintf(ssi, "fit\n");
437 else if (options->image.zoom_mode == ZOOM_RESET_NONE)
438 secure_fprintf(ssi, "dont_change\n");
440 WRITE_BOOL(image.zoom_2pass);
441 WRITE_BOOL(image.zoom_to_fit_allow_expand);
442 WRITE_INT(image.zoom_quality);
443 WRITE_INT(image.zoom_increment);
444 WRITE_BOOL(image.fit_window_to_image);
445 WRITE_BOOL(image.limit_window_size);
446 WRITE_INT(image.max_window_size);
447 WRITE_BOOL(image.limit_autofit_size);
448 WRITE_INT(image.max_autofit_size);
449 WRITE_INT(image.scroll_reset_method);
450 WRITE_INT(image.tile_cache_max);
451 WRITE_INT(image.image_cache_max);
452 WRITE_INT(image.dither_quality);
453 WRITE_BOOL(image.enable_read_ahead);
454 WRITE_BOOL(image.exif_rotate_enable);
455 WRITE_BOOL(image.use_custom_border_color);
456 WRITE_COLOR(image.border_color);
457 WRITE_INT(image.read_buffer_size);
458 WRITE_INT(image.idle_read_loop_count);
460 WRITE_SUBTITLE("Thumbnails Options");
462 WRITE_INT(thumbnails.max_width);
463 WRITE_INT(thumbnails.max_height);
464 WRITE_BOOL(thumbnails.enable_caching);
465 WRITE_BOOL(thumbnails.cache_into_dirs);
466 WRITE_BOOL(thumbnails.fast);
467 WRITE_BOOL(thumbnails.use_xvpics);
468 WRITE_BOOL(thumbnails.spec_standard);
469 WRITE_INT(thumbnails.quality);
472 WRITE_SUBTITLE("File sorting Options");
474 WRITE_INT(file_sort.method);
475 WRITE_BOOL(file_sort.ascending);
476 WRITE_BOOL(file_sort.case_sensitive);
479 WRITE_SUBTITLE("Fullscreen Options");
481 WRITE_INT(fullscreen.screen);
482 WRITE_BOOL(fullscreen.clean_flip);
483 WRITE_BOOL(fullscreen.disable_saver);
484 WRITE_BOOL(fullscreen.above);
487 WRITE_SUBTITLE("Histogram Options");
488 WRITE_UINT(histogram.last_channel_mode);
489 WRITE_UINT(histogram.last_log_mode);
492 WRITE_SUBTITLE("Image Overlay Options");
493 WRITE_UINT(image_overlay.common.state);
494 WRITE_BOOL(image_overlay.common.show_at_startup);
495 WRITE_CHAR(image_overlay.common.template_string);
498 secure_fprintf(ssi, "# these are relative positions:\n");
499 secure_fprintf(ssi, "# x >= 0: |x| pixels from left border\n");
500 secure_fprintf(ssi, "# x < 0 : |x| pixels from right border\n");
501 secure_fprintf(ssi, "# y >= 0: |y| pixels from top border\n");
502 secure_fprintf(ssi, "# y < 0 : |y| pixels from bottom border\n");
503 WRITE_INT(image_overlay.common.x);
504 WRITE_INT(image_overlay.common.y);
507 WRITE_SUBTITLE("Slideshow Options");
509 WRITE_INT_UNIT(slideshow.delay, SLIDESHOW_SUBSECOND_PRECISION);
510 WRITE_BOOL(slideshow.random);
511 WRITE_BOOL(slideshow.repeat);
514 WRITE_SUBTITLE("Collection Options");
516 WRITE_BOOL(collections.rectangular_selection);
519 WRITE_SUBTITLE("Filtering Options");
521 WRITE_BOOL(file_filter.show_hidden_files);
522 WRITE_BOOL(file_filter.show_dot_directory);
523 WRITE_BOOL(file_filter.disable);
526 filter_write_list(ssi);
529 WRITE_SUBTITLE("Sidecars Options");
531 sidecar_ext_write(ssi);
534 WRITE_SUBTITLE("Color Profiles");
537 secure_fprintf(ssi, "# NOTICE: %s was not built with support for color profiles,\n"
538 "# color profile options will have no effect.\n\n", GQ_APPNAME);
541 WRITE_BOOL(color_profile.enabled);
542 WRITE_BOOL(color_profile.use_image);
543 WRITE_INT(color_profile.input_type);
546 for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
550 buf = g_strdup_printf("color_profile.input_file_%d", i + 1);
551 write_char_option(ssi, buf, options->color_profile.input_file[i]);
554 buf = g_strdup_printf("color_profile.input_name_%d", i + 1);
555 write_char_option(ssi, buf, options->color_profile.input_name[i]);
560 WRITE_INT(color_profile.screen_type);
561 WRITE_CHAR(color_profile.screen_file);
564 WRITE_SUBTITLE("Shell command");
565 WRITE_CHAR(shell.path);
566 WRITE_CHAR(shell.options);
569 WRITE_SUBTITLE("External Programs");
570 secure_fprintf(ssi, "# Maximum of %d programs (external_1 through external_%d)\n", GQ_EDITOR_GENERIC_SLOTS, GQ_EDITOR_GENERIC_SLOTS);
571 secure_fprintf(ssi, "# external_%d through external_%d are used for file ops\n", GQ_EDITOR_GENERIC_SLOTS + 1, GQ_EDITOR_SLOTS);
572 secure_fprintf(ssi, "# format: external_n: \"menu name\" \"command line\"\n\n");
574 for (i = 0; i < GQ_EDITOR_SLOTS; i++)
576 if (i == GQ_EDITOR_GENERIC_SLOTS) secure_fputc(ssi, '\n');
577 gchar *qname = escquote_value(options->editor[i].name);
578 gchar *qcommand = escquote_value(options->editor[i].command);
579 secure_fprintf(ssi, "external_%d: %s %s\n", i+1, qname, qcommand);
585 WRITE_SUBTITLE("Exif Options");
586 secure_fprintf(ssi, "# Display: 0: never\n"
589 for (i = 0; ExifUIList[i].key; i++)
591 secure_fprintf(ssi, "exif.display.");
592 write_int_option(ssi, (gchar *)ExifUIList[i].key, ExifUIList[i].current);
598 secure_fprintf(ssi, "######################################################################\n");
599 secure_fprintf(ssi, "# end of config file #\n");
600 secure_fprintf(ssi, "######################################################################\n");
603 if (secure_close(ssi))
605 log_printf(_("error saving config file: %s\nerror: %s\n"), utf8_path,
606 secsave_strerror(secsave_errno));
613 void save_options(ConfOptions *options)
617 rc_path = g_build_filename(homedir(), GQ_RC_DIR, RC_FILE_NAME, NULL);
618 save_options_to(rc_path, options);
625 *-----------------------------------------------------------------------------
626 * load configuration (public)
627 *-----------------------------------------------------------------------------
630 static gboolean is_numbered_option(const gchar *option, const gchar *prefix, gint *number)
633 gsize option_len = strlen(option);
634 gsize prefix_len = strlen(prefix);
636 if (option_len <= prefix_len) return FALSE;
637 if (g_ascii_strncasecmp(option, prefix, prefix_len) != 0) return FALSE;
640 while (g_ascii_isdigit(option[n])) n++;
641 if (n < option_len) return FALSE;
643 if (number) *number = atoi(option + prefix_len);
647 #define OPTION_READ_BUFFER_SIZE 1024
649 static gboolean load_options_from(const gchar *utf8_path, ConfOptions *options)
653 gchar s_buf[OPTION_READ_BUFFER_SIZE];
654 gchar value_all[OPTION_READ_BUFFER_SIZE];
659 rc_pathl = path_from_utf8(utf8_path);
660 f = fopen(rc_pathl,"r");
662 if (!f) return FALSE;
664 while (fgets(s_buf, sizeof(s_buf), f))
669 /* skip empty lines and comments */
670 while (g_ascii_isspace(*p)) p++;
671 if (!*p || *p == '\n' || *p == '#') continue;
673 /* parse option name */
675 while (g_ascii_isalnum(*p) || *p == '_' || *p == '.') p++;
680 /* search for value start, name and value are normally separated by ': '
681 * but we allow relaxed syntax here, so '=', ':=' or just a tab will work too */
682 while (*p == ':' || g_ascii_isspace(*p) || *p == '=') p++;
685 while (*p && !g_ascii_isspace(*p) && *p != '\n') p++;
686 value_end = p; /* value part up to the first whitespace or end of line */
687 while (*p != '\0') p++;
688 memcpy(value_all, value, 1 + p - value);
692 #define READ_BOOL(_name_) if (read_bool_option(f, option, #_name_, value, &options->_name_)) continue;
693 #define READ_INT(_name_) if (read_int_option(f, option, #_name_, value, &options->_name_)) continue;
694 #define READ_UINT(_name_) if (read_uint_option(f, option, #_name_, value, &options->_name_)) continue;
695 #define READ_INT_CLAMP(_name_, _min_, _max_) if (read_int_option_clamp(f, option, #_name_, value, &options->_name_, _min_, _max_)) continue;
696 #define READ_INT_UNIT(_name_, _unit_) if (read_int_unit_option(f, option, #_name_, value, &options->_name_, _unit_)) continue;
697 #define READ_CHAR(_name_) if (read_char_option(f, option, #_name_, value_all, &options->_name_)) continue;
698 #define READ_COLOR(_name_) if (read_color_option(f, option, #_name_, value, &options->_name_)) continue;
700 #define COMPAT_READ_BOOL(_oldname_, _name_) if (read_bool_option(f, option, #_oldname_, value, &options->_name_)) continue;
701 #define COMPAT_READ_INT(_oldname_, _name_) if (read_int_option(f, option, #_oldname_, value, &options->_name_)) continue;
702 #define COMPAT_READ_UINT(_oldname_, _name_) if (read_uint_option(f, option, #_oldname_, value, &options->_name_)) continue;
703 #define COMPAT_READ_INT_CLAMP(_oldname_, _name_, _min_, _max_) if (read_int_option_clamp(f, option, #_oldname_, value, &options->_name_, _min_, _max_)) continue;
704 #define COMPAT_READ_INT_UNIT(_oldname_, _name_, _unit_) if (read_int_unit_option(f, option, #_oldname_, value, &options->_name_, _unit_)) continue;
705 #define COMPAT_READ_CHAR(_oldname_, _name_) if (read_char_option(f, option, #_oldname_, value_all, &options->_name_)) continue;
706 #define COMPAT_READ_COLOR(_oldname_, _name_) if (read_color_option(f, option, #_oldname_, value, &options->_name_)) continue;
708 /* general options */
709 READ_BOOL(show_icon_names);
710 READ_BOOL(show_copy_path);
712 READ_BOOL(tree_descend_subdirs);
713 READ_BOOL(lazy_image_sync);
714 READ_BOOL(update_on_time_change);
716 READ_INT(duplicates_similarity_threshold);
718 READ_BOOL(progressive_key_scrolling);
720 READ_BOOL(enable_metadata_dirs);
721 READ_BOOL(save_metadata_in_image_file);
723 READ_BOOL(mousewheel_scrolls);
725 READ_INT(open_recent_list_maxsize);
726 READ_INT(dnd_icon_size);
727 READ_BOOL(place_dialogs_under_mouse);
729 /* startup options */
731 COMPAT_READ_BOOL(startup_path_enable, startup.restore_path); /* 2008/05/11 */
732 READ_BOOL(startup.restore_path);
734 READ_BOOL(startup.use_last_path);
736 COMPAT_READ_CHAR(startup_path, startup.path); /* 2008/05/11 */
737 READ_CHAR(startup.path);
741 READ_INT(layout.style);
742 READ_CHAR(layout.order);
744 COMPAT_READ_UINT(layout.view_as_icons, layout.file_view_type); /* 2008/05/03 */
746 READ_UINT(layout.dir_view_type);
747 READ_UINT(layout.file_view_type);
748 READ_BOOL(layout.show_marks);
749 READ_BOOL(layout.show_thumbnails);
750 READ_BOOL(layout.show_directory_date);
752 /* window positions */
754 READ_BOOL(layout.save_window_positions);
756 READ_INT(layout.main_window.x);
757 READ_INT(layout.main_window.y);
758 READ_INT(layout.main_window.w);
759 READ_INT(layout.main_window.h);
760 READ_BOOL(layout.main_window.maximized);
761 READ_INT(layout.main_window.hdivider_pos);
762 READ_INT(layout.main_window.vdivider_pos);
764 READ_INT(layout.float_window.x);
765 READ_INT(layout.float_window.y);
766 READ_INT(layout.float_window.w);
767 READ_INT(layout.float_window.h);
768 READ_INT(layout.float_window.vdivider_pos);
770 READ_INT(layout.properties_window.w);
771 READ_INT(layout.properties_window.h);
773 READ_BOOL(layout.tools_float);
774 READ_BOOL(layout.tools_hidden);
775 READ_BOOL(layout.tools_restore_state);
776 READ_BOOL(layout.toolbar_hidden);
779 READ_BOOL(panels.exif.enabled);
780 READ_INT_CLAMP(panels.exif.width, PANEL_MIN_WIDTH, PANEL_MAX_WIDTH);
781 READ_BOOL(panels.info.enabled);
782 READ_INT_CLAMP(panels.info.width, PANEL_MIN_WIDTH, PANEL_MAX_WIDTH);
783 READ_BOOL(panels.sort.enabled);
784 READ_INT(panels.sort.action_state);
785 READ_INT(panels.sort.mode_state);
786 READ_INT(panels.sort.selection_state);
788 /* properties dialog options */
789 READ_CHAR(properties.tabs_order);
792 if (g_ascii_strcasecmp(option, "image.zoom_mode") == 0)
794 if (g_ascii_strcasecmp(value, "original") == 0)
795 options->image.zoom_mode = ZOOM_RESET_ORIGINAL;
796 else if (g_ascii_strcasecmp(value, "fit") == 0)
797 options->image.zoom_mode = ZOOM_RESET_FIT_WINDOW;
798 else if (g_ascii_strcasecmp(value, "dont_change") == 0)
799 options->image.zoom_mode = ZOOM_RESET_NONE;
802 READ_BOOL(image.zoom_2pass);
803 READ_BOOL(image.zoom_to_fit_allow_expand);
804 READ_BOOL(image.fit_window_to_image);
805 READ_BOOL(image.limit_window_size);
806 READ_INT(image.max_window_size);
807 READ_BOOL(image.limit_autofit_size);
808 READ_INT(image.max_autofit_size);
809 READ_INT(image.scroll_reset_method);
810 READ_INT(image.tile_cache_max);
811 READ_INT(image.image_cache_max);
812 READ_INT_CLAMP(image.zoom_quality, GDK_INTERP_NEAREST, GDK_INTERP_HYPER);
813 READ_INT_CLAMP(image.dither_quality, GDK_RGB_DITHER_NONE, GDK_RGB_DITHER_MAX);
814 READ_INT(image.zoom_increment);
815 READ_BOOL(image.enable_read_ahead);
816 READ_BOOL(image.exif_rotate_enable);
817 READ_BOOL(image.use_custom_border_color);
818 READ_COLOR(image.border_color);
819 READ_INT_CLAMP(image.read_buffer_size, IMAGE_LOADER_READ_BUFFER_SIZE_MIN, IMAGE_LOADER_READ_BUFFER_SIZE_MAX);
820 READ_INT_CLAMP(image.idle_read_loop_count, IMAGE_LOADER_IDLE_READ_LOOP_COUNT_MIN, IMAGE_LOADER_IDLE_READ_LOOP_COUNT_MAX);
823 /* thumbnails options */
824 READ_INT_CLAMP(thumbnails.max_width, 16, 512);
825 READ_INT_CLAMP(thumbnails.max_height, 16, 512);
827 READ_BOOL(thumbnails.enable_caching);
828 READ_BOOL(thumbnails.cache_into_dirs);
829 READ_BOOL(thumbnails.fast);
830 READ_BOOL(thumbnails.use_xvpics);
831 READ_BOOL(thumbnails.spec_standard);
832 READ_INT_CLAMP(thumbnails.quality, GDK_INTERP_NEAREST, GDK_INTERP_HYPER);
834 /* file sorting options */
835 READ_UINT(file_sort.method);
836 READ_BOOL(file_sort.ascending);
837 READ_BOOL(file_sort.case_sensitive);
839 /* file operations options */
840 READ_BOOL(file_ops.enable_in_place_rename);
841 READ_BOOL(file_ops.confirm_delete);
842 READ_BOOL(file_ops.enable_delete_key);
843 READ_BOOL(file_ops.safe_delete_enable);
844 READ_CHAR(file_ops.safe_delete_path);
845 READ_INT(file_ops.safe_delete_folder_maxsize);
847 /* fullscreen options */
848 READ_INT(fullscreen.screen);
849 READ_BOOL(fullscreen.clean_flip);
850 READ_BOOL(fullscreen.disable_saver);
851 READ_BOOL(fullscreen.above);
854 READ_UINT(histogram.last_channel_mode);
855 READ_UINT(histogram.last_log_mode);
858 COMPAT_READ_UINT(image_overlay.common.enabled, image_overlay.common.state); /* 2008-05-12 */
859 READ_UINT(image_overlay.common.state);
860 COMPAT_READ_BOOL(fullscreen.show_info, image_overlay.common.show_at_startup); /* 2008-04-21 */
861 READ_BOOL(image_overlay.common.show_at_startup);
862 COMPAT_READ_CHAR(fullscreen.info, image_overlay.common.template_string); /* 2008-04-21 */
863 READ_CHAR(image_overlay.common.template_string);
865 READ_INT(image_overlay.common.x);
866 READ_INT(image_overlay.common.y);
869 /* slideshow options */
870 READ_INT_UNIT(slideshow.delay, SLIDESHOW_SUBSECOND_PRECISION);
871 READ_BOOL(slideshow.random);
872 READ_BOOL(slideshow.repeat);
874 /* collection options */
876 READ_BOOL(collections.rectangular_selection);
878 /* filtering options */
880 READ_BOOL(file_filter.show_hidden_files);
881 READ_BOOL(file_filter.show_dot_directory);
882 READ_BOOL(file_filter.disable);
884 if (g_ascii_strcasecmp(option, "file_filter.ext") == 0)
886 filter_parse(value_all);
890 if (g_ascii_strcasecmp(option, "sidecar.ext") == 0)
892 sidecar_ext_parse(value_all, TRUE);
898 READ_BOOL(color_profile.enabled);
899 READ_BOOL(color_profile.use_image);
900 READ_INT(color_profile.input_type);
902 if (is_numbered_option(option, "color_profile.input_file_", &i))
904 if (i > 0 && i <= COLOR_PROFILE_INPUTS)
907 read_char_option(f, option, option, value, &options->color_profile.input_file[i]);
912 if (is_numbered_option(option, "color_profile.input_name_", &i))
914 if (i > 0 && i <= COLOR_PROFILE_INPUTS)
917 read_char_option(f, option, option, value, &options->color_profile.input_name[i]);
922 READ_INT(color_profile.screen_type);
923 READ_CHAR(color_profile.screen_file);
926 READ_CHAR(shell.path);
927 READ_CHAR(shell.options);
929 /* External Programs */
931 if (is_numbered_option(option, "external_", &i))
933 if (i > 0 && i <= GQ_EDITOR_SLOTS)
938 editor_set_name(i, quoted_value(value_all, &ptr));
939 editor_set_command(i, quoted_value(ptr, NULL));
945 if (0 == g_ascii_strncasecmp(option, "exif.display.", 13))
947 for (i = 0; ExifUIList[i].key; i++)
948 if (0 == g_ascii_strcasecmp(option + 13, ExifUIList[i].key))
949 ExifUIList[i].current = strtol(value, NULL, 10);
958 void load_options(ConfOptions *options)
963 if (isdir(GQ_SYSTEM_WIDE_DIR))
965 rc_path = g_build_filename(GQ_SYSTEM_WIDE_DIR, RC_FILE_NAME, NULL);
966 success = load_options_from(rc_path, options);
967 DEBUG_1("Loading options from %s ... %s", rc_path, success ? "done" : "failed");
971 rc_path = g_build_filename(homedir(), GQ_RC_DIR, RC_FILE_NAME, NULL);
972 success = load_options_from(rc_path, options);
973 DEBUG_1("Loading options from %s ... %s", rc_path, success ? "done" : "failed");