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 "pixbuf-renderer.h"
23 #include "secure_save.h"
24 #include "slideshow.h"
25 #include "ui_fileops.h"
29 *-----------------------------------------------------------------------------
30 * line write/parse routines (private)
31 *-----------------------------------------------------------------------------
35 returns text without quotes or NULL for empty or broken string
36 any text up to first '"' is skipped
37 tail is set to point at the char after the second '"'
42 gchar *quoted_value(const gchar *text, const gchar **tail)
46 gint l = strlen(text);
49 if (tail) *tail = text;
51 if (l == 0) return retval;
53 while (c < l && text[c] != '"') c++;
62 if (text[e-1] != '\\' && text[e] == '"') break;
69 gchar *substring = g_strndup(ptr, e - c);
73 retval = g_strcompress(substring);
78 if (tail) *tail = text + e + 1;
81 /* for compatibility with older formats (<0.3.7)
82 * read a line without quotes too */
85 while (c < l && text[c] != '\n' && !g_ascii_isspace(text[c])) c++;
88 retval = g_strndup(text, c);
90 if (tail) *tail = text + c;
96 gchar *escquote_value(const gchar *text)
100 if (!text) return g_strdup("\"\"");
102 e = g_strescape(text, "");
105 gchar *retval = g_strdup_printf("\"%s\"", e);
109 return g_strdup("\"\"");
112 static void write_char_option(SecureSaveInfo *ssi, gchar *label, gchar *text)
114 gchar *escval = escquote_value(text);
116 secure_fprintf(ssi, "%s: %s\n", label, escval);
120 static gboolean read_char_option(FILE *f, gchar *option, gchar *label, gchar *value, gchar **text)
122 if (g_ascii_strcasecmp(option, label) != 0) return FALSE;
123 if (!text) return FALSE;
126 *text = quoted_value(value, NULL);
130 /* Since gdk_color_to_string() is only available since gtk 2.12
131 * here is an equivalent stub function. */
132 static gchar *color_to_string(GdkColor *color)
134 return g_strdup_printf("#%04X%04X%04X", color->red, color->green, color->blue);
137 static void write_color_option(SecureSaveInfo *ssi, gchar *label, GdkColor *color)
141 gchar *colorstring = color_to_string(color);
143 write_char_option(ssi, label, colorstring);
147 secure_fprintf(ssi, "%s: \n", label);
150 static gboolean read_color_option(FILE *f, gchar *option, gchar *label, gchar *value, GdkColor *color)
154 if (g_ascii_strcasecmp(option, label) != 0) return FALSE;
155 if (!color) return FALSE;
157 colorstr = quoted_value(value, NULL);
158 if (!colorstr) return FALSE;
159 gdk_color_parse(colorstr, color);
164 static void write_int_option(SecureSaveInfo *ssi, gchar *label, gint n)
166 secure_fprintf(ssi, "%s: %d\n", label, n);
169 static gboolean read_int_option(FILE *f, gchar *option, gchar *label, gchar *value, gint *n)
171 if (g_ascii_strcasecmp(option, label) != 0) return FALSE;
172 if (!n) return FALSE;
174 if (g_ascii_isdigit(value[0]) || (value[0] == '-' && g_ascii_isdigit(value[1])))
176 *n = strtol(value, NULL, 10);
180 if (g_ascii_strcasecmp(value, "true") == 0)
189 static void write_uint_option(SecureSaveInfo *ssi, gchar *label, guint n)
191 secure_fprintf(ssi, "%s: %u\n", label, n);
194 static gboolean read_uint_option(FILE *f, gchar *option, gchar *label, gchar *value, guint *n)
196 if (g_ascii_strcasecmp(option, label) != 0) return FALSE;
197 if (!n) return FALSE;
199 if (g_ascii_isdigit(value[0]))
201 *n = strtoul(value, NULL, 10);
205 if (g_ascii_strcasecmp(value, "true") == 0)
214 static gboolean read_uint_option_clamp(FILE *f, gchar *option, gchar *label, gchar *value, guint *n, guint min, guint max)
218 ret = read_uint_option(f, option, label, value, n);
219 if (ret) *n = CLAMP(*n, min, max);
225 static gboolean read_int_option_clamp(FILE *f, gchar *option, gchar *label, gchar *value, gint *n, gint min, gint max)
229 ret = read_int_option(f, option, label, value, n);
230 if (ret) *n = CLAMP(*n, min, max);
235 static void write_int_unit_option(SecureSaveInfo *ssi, gchar *label, gint n, gint subunits)
250 secure_fprintf(ssi, "%s: %d.%d\n", label, l, r);
253 static gboolean read_int_unit_option(FILE *f, gchar *option, gchar *label, gchar *value, gint *n, gint subunits)
258 if (g_ascii_strcasecmp(option, label) != 0) return FALSE;
259 if (!n) return FALSE;
262 while (*ptr != '\0' && *ptr != '.') ptr++;
266 l = strtol(value, NULL, 10);
269 r = strtol(ptr, NULL, 10);
273 l = strtol(value, NULL, 10);
277 *n = l * subunits + r;
282 static void write_bool_option(SecureSaveInfo *ssi, gchar *label, gint n)
284 secure_fprintf(ssi, "%s: ", label);
285 if (n) secure_fprintf(ssi, "true\n"); else secure_fprintf(ssi, "false\n");
288 static gboolean read_bool_option(FILE *f, gchar *option, gchar *label, gchar *value, gint *n)
290 if (g_ascii_strcasecmp(option, label) != 0) return FALSE;
291 if (!n) return FALSE;
293 if (g_ascii_strcasecmp(value, "true") == 0 || atoi(value) != 0)
303 *-----------------------------------------------------------------------------
304 * save configuration (public)
305 *-----------------------------------------------------------------------------
308 static gboolean save_options_to(const gchar *utf8_path, ConfOptions *options)
314 rc_pathl = path_from_utf8(utf8_path);
315 ssi = secure_open(rc_pathl);
319 log_printf(_("error saving config file: %s\n"), utf8_path);
323 #define WRITE_BOOL(_name_) write_bool_option(ssi, #_name_, options->_name_)
324 #define WRITE_INT(_name_) write_int_option(ssi, #_name_, options->_name_)
325 #define WRITE_UINT(_name_) write_uint_option(ssi, #_name_, options->_name_)
326 #define WRITE_INT_UNIT(_name_, _unit_) write_int_unit_option(ssi, #_name_, options->_name_, _unit_)
327 #define WRITE_CHAR(_name_) write_char_option(ssi, #_name_, options->_name_)
328 #define WRITE_COLOR(_name_) write_color_option(ssi, #_name_, &options->_name_)
330 #define WRITE_SEPARATOR() secure_fputc(ssi, '\n')
331 #define WRITE_SUBTITLE(_title_) secure_fprintf(ssi, "\n\n##### "_title_" #####\n\n")
333 secure_fprintf(ssi, "######################################################################\n");
334 secure_fprintf(ssi, "# %30s config file version %-10s #\n", GQ_APPNAME, VERSION);
335 secure_fprintf(ssi, "######################################################################\n");
338 secure_fprintf(ssi, "# Note: This file is autogenerated. Options can be changed here,\n");
339 secure_fprintf(ssi, "# but user comments and formatting will be lost.\n");
342 WRITE_SUBTITLE("General Options");
344 WRITE_BOOL(show_icon_names);
345 WRITE_BOOL(show_copy_path);
348 WRITE_BOOL(tree_descend_subdirs);
349 WRITE_BOOL(lazy_image_sync);
350 WRITE_BOOL(update_on_time_change);
353 WRITE_BOOL(progressive_key_scrolling);
354 WRITE_BOOL(enable_metadata_dirs);
355 WRITE_BOOL(save_metadata_in_image_file);
357 WRITE_UINT(duplicates_similarity_threshold);
360 WRITE_BOOL(mousewheel_scrolls);
361 WRITE_INT(open_recent_list_maxsize);
362 WRITE_INT(dnd_icon_size);
363 WRITE_BOOL(place_dialogs_under_mouse);
366 WRITE_SUBTITLE("Startup Options");
368 WRITE_BOOL(startup.restore_path);
369 WRITE_BOOL(startup.use_last_path);
370 WRITE_CHAR(startup.path);
373 WRITE_SUBTITLE("File operations Options");
375 WRITE_BOOL(file_ops.enable_in_place_rename);
376 WRITE_BOOL(file_ops.confirm_delete);
377 WRITE_BOOL(file_ops.enable_delete_key);
378 WRITE_BOOL(file_ops.safe_delete_enable);
379 WRITE_CHAR(file_ops.safe_delete_path);
380 WRITE_INT(file_ops.safe_delete_folder_maxsize);
383 WRITE_SUBTITLE("Layout Options");
385 WRITE_INT(layout.style);
386 WRITE_CHAR(layout.order);
387 WRITE_UINT(layout.dir_view_type);
388 WRITE_UINT(layout.file_view_type);
389 WRITE_BOOL(layout.show_marks);
390 WRITE_BOOL(layout.show_thumbnails);
391 WRITE_BOOL(layout.show_directory_date);
394 WRITE_BOOL(layout.save_window_positions);
397 WRITE_INT(layout.main_window.x);
398 WRITE_INT(layout.main_window.y);
399 WRITE_INT(layout.main_window.w);
400 WRITE_INT(layout.main_window.h);
401 WRITE_BOOL(layout.main_window.maximized);
402 WRITE_INT(layout.main_window.hdivider_pos);
403 WRITE_INT(layout.main_window.vdivider_pos);
406 WRITE_INT(layout.float_window.x);
407 WRITE_INT(layout.float_window.y);
408 WRITE_INT(layout.float_window.w);
409 WRITE_INT(layout.float_window.h);
410 WRITE_INT(layout.float_window.vdivider_pos);
413 WRITE_INT(layout.properties_window.w);
414 WRITE_INT(layout.properties_window.h);
417 WRITE_BOOL(layout.tools_float);
418 WRITE_BOOL(layout.tools_hidden);
419 WRITE_BOOL(layout.tools_restore_state);
422 WRITE_BOOL(layout.toolbar_hidden);
424 WRITE_SUBTITLE("Panels Options");
426 WRITE_BOOL(panels.exif.enabled);
427 WRITE_INT(panels.exif.width);
428 WRITE_BOOL(panels.info.enabled);
429 WRITE_INT(panels.info.width);
430 WRITE_BOOL(panels.sort.enabled);
431 WRITE_INT(panels.sort.action_state);
432 WRITE_INT(panels.sort.mode_state);
433 WRITE_INT(panels.sort.selection_state);
435 WRITE_SUBTITLE("Properties dialog Options");
436 WRITE_CHAR(properties.tabs_order);
438 WRITE_SUBTITLE("Image Options");
440 secure_fprintf(ssi, "# image.zoom_mode possible values are:\n"
444 secure_fprintf(ssi, "image.zoom_mode: ");
445 if (options->image.zoom_mode == ZOOM_RESET_ORIGINAL)
446 secure_fprintf(ssi, "original\n");
447 else if (options->image.zoom_mode == ZOOM_RESET_FIT_WINDOW)
448 secure_fprintf(ssi, "fit\n");
449 else if (options->image.zoom_mode == ZOOM_RESET_NONE)
450 secure_fprintf(ssi, "dont_change\n");
452 WRITE_BOOL(image.zoom_2pass);
453 WRITE_BOOL(image.zoom_to_fit_allow_expand);
454 WRITE_UINT(image.zoom_quality);
455 WRITE_INT(image.zoom_increment);
456 WRITE_BOOL(image.fit_window_to_image);
457 WRITE_BOOL(image.limit_window_size);
458 WRITE_INT(image.max_window_size);
459 WRITE_BOOL(image.limit_autofit_size);
460 WRITE_INT(image.max_autofit_size);
461 WRITE_UINT(image.scroll_reset_method);
462 WRITE_INT(image.tile_cache_max);
463 WRITE_INT(image.image_cache_max);
464 WRITE_UINT(image.dither_quality);
465 WRITE_BOOL(image.enable_read_ahead);
466 WRITE_BOOL(image.exif_rotate_enable);
467 WRITE_BOOL(image.use_custom_border_color);
468 WRITE_COLOR(image.border_color);
469 WRITE_INT(image.read_buffer_size);
470 WRITE_INT(image.idle_read_loop_count);
472 WRITE_SUBTITLE("Thumbnails Options");
474 WRITE_INT(thumbnails.max_width);
475 WRITE_INT(thumbnails.max_height);
476 WRITE_BOOL(thumbnails.enable_caching);
477 WRITE_BOOL(thumbnails.cache_into_dirs);
478 WRITE_BOOL(thumbnails.fast);
479 WRITE_BOOL(thumbnails.use_xvpics);
480 WRITE_BOOL(thumbnails.spec_standard);
481 WRITE_UINT(thumbnails.quality);
484 WRITE_SUBTITLE("File sorting Options");
486 WRITE_INT(file_sort.method);
487 WRITE_BOOL(file_sort.ascending);
488 WRITE_BOOL(file_sort.case_sensitive);
491 WRITE_SUBTITLE("Fullscreen Options");
493 WRITE_INT(fullscreen.screen);
494 WRITE_BOOL(fullscreen.clean_flip);
495 WRITE_BOOL(fullscreen.disable_saver);
496 WRITE_BOOL(fullscreen.above);
499 WRITE_SUBTITLE("Histogram Options");
500 WRITE_UINT(histogram.last_channel_mode);
501 WRITE_UINT(histogram.last_log_mode);
504 WRITE_SUBTITLE("Image Overlay Options");
505 WRITE_UINT(image_overlay.common.state);
506 WRITE_BOOL(image_overlay.common.show_at_startup);
507 WRITE_CHAR(image_overlay.common.template_string);
510 secure_fprintf(ssi, "# these are relative positions:\n");
511 secure_fprintf(ssi, "# x >= 0: |x| pixels from left border\n");
512 secure_fprintf(ssi, "# x < 0 : |x| pixels from right border\n");
513 secure_fprintf(ssi, "# y >= 0: |y| pixels from top border\n");
514 secure_fprintf(ssi, "# y < 0 : |y| pixels from bottom border\n");
515 WRITE_INT(image_overlay.common.x);
516 WRITE_INT(image_overlay.common.y);
519 WRITE_SUBTITLE("Slideshow Options");
521 WRITE_INT_UNIT(slideshow.delay, SLIDESHOW_SUBSECOND_PRECISION);
522 WRITE_BOOL(slideshow.random);
523 WRITE_BOOL(slideshow.repeat);
526 WRITE_SUBTITLE("Collection Options");
528 WRITE_BOOL(collections.rectangular_selection);
531 WRITE_SUBTITLE("Filtering Options");
533 WRITE_BOOL(file_filter.show_hidden_files);
534 WRITE_BOOL(file_filter.show_dot_directory);
535 WRITE_BOOL(file_filter.disable);
538 filter_write_list(ssi);
541 WRITE_SUBTITLE("Sidecars Options");
543 sidecar_ext_write(ssi);
546 WRITE_SUBTITLE("Color Profiles");
549 secure_fprintf(ssi, "# NOTICE: %s was not built with support for color profiles,\n"
550 "# color profile options will have no effect.\n\n", GQ_APPNAME);
553 WRITE_BOOL(color_profile.enabled);
554 WRITE_BOOL(color_profile.use_image);
555 WRITE_INT(color_profile.input_type);
558 for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
562 buf = g_strdup_printf("color_profile.input_file_%d", i + 1);
563 write_char_option(ssi, buf, options->color_profile.input_file[i]);
566 buf = g_strdup_printf("color_profile.input_name_%d", i + 1);
567 write_char_option(ssi, buf, options->color_profile.input_name[i]);
572 WRITE_INT(color_profile.screen_type);
573 WRITE_CHAR(color_profile.screen_file);
576 WRITE_SUBTITLE("Shell command");
577 WRITE_CHAR(shell.path);
578 WRITE_CHAR(shell.options);
581 WRITE_SUBTITLE("External Programs");
582 secure_fprintf(ssi, "# Maximum of %d programs (external_1 through external_%d)\n", GQ_EDITOR_GENERIC_SLOTS, GQ_EDITOR_GENERIC_SLOTS);
583 secure_fprintf(ssi, "# external_%d through external_%d are used for file ops\n", GQ_EDITOR_GENERIC_SLOTS + 1, GQ_EDITOR_SLOTS);
584 secure_fprintf(ssi, "# format: external_n: \"menu name\" \"command line\"\n\n");
586 for (i = 0; i < GQ_EDITOR_SLOTS; i++)
588 if (i == GQ_EDITOR_GENERIC_SLOTS) secure_fputc(ssi, '\n');
589 gchar *qname = escquote_value(options->editor[i].name);
590 gchar *qcommand = escquote_value(options->editor[i].command);
591 secure_fprintf(ssi, "external_%d: %s %s\n", i+1, qname, qcommand);
597 WRITE_SUBTITLE("Exif Options");
598 secure_fprintf(ssi, "# Display: 0: never\n"
601 for (i = 0; ExifUIList[i].key; i++)
603 secure_fprintf(ssi, "exif.display.");
604 write_int_option(ssi, (gchar *)ExifUIList[i].key, ExifUIList[i].current);
610 secure_fprintf(ssi, "######################################################################\n");
611 secure_fprintf(ssi, "# end of config file #\n");
612 secure_fprintf(ssi, "######################################################################\n");
615 if (secure_close(ssi))
617 log_printf(_("error saving config file: %s\nerror: %s\n"), utf8_path,
618 secsave_strerror(secsave_errno));
625 void save_options(ConfOptions *options)
629 rc_path = g_build_filename(homedir(), GQ_RC_DIR, RC_FILE_NAME, NULL);
630 save_options_to(rc_path, options);
637 *-----------------------------------------------------------------------------
638 * load configuration (public)
639 *-----------------------------------------------------------------------------
642 static gboolean is_numbered_option(const gchar *option, const gchar *prefix, gint *number)
645 gsize option_len = strlen(option);
646 gsize prefix_len = strlen(prefix);
648 if (option_len <= prefix_len) return FALSE;
649 if (g_ascii_strncasecmp(option, prefix, prefix_len) != 0) return FALSE;
652 while (g_ascii_isdigit(option[n])) n++;
653 if (n < option_len) return FALSE;
655 if (number) *number = atoi(option + prefix_len);
659 #define OPTION_READ_BUFFER_SIZE 1024
661 static gboolean load_options_from(const gchar *utf8_path, ConfOptions *options)
665 gchar s_buf[OPTION_READ_BUFFER_SIZE];
666 gchar value_all[OPTION_READ_BUFFER_SIZE];
671 rc_pathl = path_from_utf8(utf8_path);
672 f = fopen(rc_pathl,"r");
674 if (!f) return FALSE;
676 while (fgets(s_buf, sizeof(s_buf), f))
681 /* skip empty lines and comments */
682 while (g_ascii_isspace(*p)) p++;
683 if (!*p || *p == '\n' || *p == '#') continue;
685 /* parse option name */
687 while (g_ascii_isalnum(*p) || *p == '_' || *p == '.') p++;
692 /* search for value start, name and value are normally separated by ': '
693 * but we allow relaxed syntax here, so '=', ':=' or just a tab will work too */
694 while (*p == ':' || g_ascii_isspace(*p) || *p == '=') p++;
697 while (*p && !g_ascii_isspace(*p) && *p != '\n') p++;
698 value_end = p; /* value part up to the first whitespace or end of line */
699 while (*p != '\0') p++;
700 memcpy(value_all, value, 1 + p - value);
704 #define READ_BOOL(_name_) if (read_bool_option(f, option, #_name_, value, &options->_name_)) continue;
705 #define READ_INT(_name_) if (read_int_option(f, option, #_name_, value, &options->_name_)) continue;
706 #define READ_UINT(_name_) if (read_uint_option(f, option, #_name_, value, &options->_name_)) continue;
707 #define READ_INT_CLAMP(_name_, _min_, _max_) if (read_int_option_clamp(f, option, #_name_, value, &options->_name_, _min_, _max_)) continue;
708 #define READ_UINT_CLAMP(_name_, _min_, _max_) if (read_uint_option_clamp(f, option, #_name_, value, &options->_name_, _min_, _max_)) continue;
709 #define READ_INT_UNIT(_name_, _unit_) if (read_int_unit_option(f, option, #_name_, value, &options->_name_, _unit_)) continue;
710 #define READ_CHAR(_name_) if (read_char_option(f, option, #_name_, value_all, &options->_name_)) continue;
711 #define READ_COLOR(_name_) if (read_color_option(f, option, #_name_, value, &options->_name_)) continue;
713 #define COMPAT_READ_BOOL(_oldname_, _name_) if (read_bool_option(f, option, #_oldname_, value, &options->_name_)) continue;
714 #define COMPAT_READ_INT(_oldname_, _name_) if (read_int_option(f, option, #_oldname_, value, &options->_name_)) continue;
715 #define COMPAT_READ_UINT(_oldname_, _name_) if (read_uint_option(f, option, #_oldname_, value, &options->_name_)) continue;
716 #define COMPAT_READ_INT_CLAMP(_oldname_, _name_, _min_, _max_) if (read_int_option_clamp(f, option, #_oldname_, value, &options->_name_, _min_, _max_)) continue;
717 #define COMPAT_READ_INT_UNIT(_oldname_, _name_, _unit_) if (read_int_unit_option(f, option, #_oldname_, value, &options->_name_, _unit_)) continue;
718 #define COMPAT_READ_CHAR(_oldname_, _name_) if (read_char_option(f, option, #_oldname_, value_all, &options->_name_)) continue;
719 #define COMPAT_READ_COLOR(_oldname_, _name_) if (read_color_option(f, option, #_oldname_, value, &options->_name_)) continue;
721 /* general options */
722 READ_BOOL(show_icon_names);
723 READ_BOOL(show_copy_path);
725 READ_BOOL(tree_descend_subdirs);
726 READ_BOOL(lazy_image_sync);
727 READ_BOOL(update_on_time_change);
729 READ_UINT_CLAMP(duplicates_similarity_threshold, 0, 100);
731 READ_BOOL(progressive_key_scrolling);
733 READ_BOOL(enable_metadata_dirs);
734 READ_BOOL(save_metadata_in_image_file);
736 READ_BOOL(mousewheel_scrolls);
738 READ_INT(open_recent_list_maxsize);
739 READ_INT(dnd_icon_size);
740 READ_BOOL(place_dialogs_under_mouse);
742 /* startup options */
744 COMPAT_READ_BOOL(startup_path_enable, startup.restore_path); /* 2008/05/11 */
745 READ_BOOL(startup.restore_path);
747 READ_BOOL(startup.use_last_path);
749 COMPAT_READ_CHAR(startup_path, startup.path); /* 2008/05/11 */
750 READ_CHAR(startup.path);
754 READ_INT(layout.style);
755 READ_CHAR(layout.order);
757 COMPAT_READ_UINT(layout.view_as_icons, layout.file_view_type); /* 2008/05/03 */
759 READ_UINT(layout.dir_view_type);
760 READ_UINT(layout.file_view_type);
761 READ_BOOL(layout.show_marks);
762 READ_BOOL(layout.show_thumbnails);
763 READ_BOOL(layout.show_directory_date);
765 /* window positions */
767 READ_BOOL(layout.save_window_positions);
769 READ_INT(layout.main_window.x);
770 READ_INT(layout.main_window.y);
771 READ_INT(layout.main_window.w);
772 READ_INT(layout.main_window.h);
773 READ_BOOL(layout.main_window.maximized);
774 READ_INT(layout.main_window.hdivider_pos);
775 READ_INT(layout.main_window.vdivider_pos);
777 READ_INT(layout.float_window.x);
778 READ_INT(layout.float_window.y);
779 READ_INT(layout.float_window.w);
780 READ_INT(layout.float_window.h);
781 READ_INT(layout.float_window.vdivider_pos);
783 READ_INT(layout.properties_window.w);
784 READ_INT(layout.properties_window.h);
786 READ_BOOL(layout.tools_float);
787 READ_BOOL(layout.tools_hidden);
788 READ_BOOL(layout.tools_restore_state);
789 READ_BOOL(layout.toolbar_hidden);
792 READ_BOOL(panels.exif.enabled);
793 READ_INT_CLAMP(panels.exif.width, PANEL_MIN_WIDTH, PANEL_MAX_WIDTH);
794 READ_BOOL(panels.info.enabled);
795 READ_INT_CLAMP(panels.info.width, PANEL_MIN_WIDTH, PANEL_MAX_WIDTH);
796 READ_BOOL(panels.sort.enabled);
797 READ_INT(panels.sort.action_state);
798 READ_INT(panels.sort.mode_state);
799 READ_INT(panels.sort.selection_state);
801 /* properties dialog options */
802 READ_CHAR(properties.tabs_order);
805 if (g_ascii_strcasecmp(option, "image.zoom_mode") == 0)
807 if (g_ascii_strcasecmp(value, "original") == 0)
808 options->image.zoom_mode = ZOOM_RESET_ORIGINAL;
809 else if (g_ascii_strcasecmp(value, "fit") == 0)
810 options->image.zoom_mode = ZOOM_RESET_FIT_WINDOW;
811 else if (g_ascii_strcasecmp(value, "dont_change") == 0)
812 options->image.zoom_mode = ZOOM_RESET_NONE;
815 READ_BOOL(image.zoom_2pass);
816 READ_BOOL(image.zoom_to_fit_allow_expand);
817 READ_BOOL(image.fit_window_to_image);
818 READ_BOOL(image.limit_window_size);
819 READ_INT(image.max_window_size);
820 READ_BOOL(image.limit_autofit_size);
821 READ_INT(image.max_autofit_size);
822 READ_UINT_CLAMP(image.scroll_reset_method, 0, PR_SCROLL_RESET_COUNT - 1);
823 READ_INT(image.tile_cache_max);
824 READ_INT(image.image_cache_max);
825 READ_UINT_CLAMP(image.zoom_quality, GDK_INTERP_NEAREST, GDK_INTERP_HYPER);
826 READ_UINT_CLAMP(image.dither_quality, GDK_RGB_DITHER_NONE, GDK_RGB_DITHER_MAX);
827 READ_INT(image.zoom_increment);
828 READ_BOOL(image.enable_read_ahead);
829 READ_BOOL(image.exif_rotate_enable);
830 READ_BOOL(image.use_custom_border_color);
831 READ_COLOR(image.border_color);
832 READ_INT_CLAMP(image.read_buffer_size, IMAGE_LOADER_READ_BUFFER_SIZE_MIN, IMAGE_LOADER_READ_BUFFER_SIZE_MAX);
833 READ_INT_CLAMP(image.idle_read_loop_count, IMAGE_LOADER_IDLE_READ_LOOP_COUNT_MIN, IMAGE_LOADER_IDLE_READ_LOOP_COUNT_MAX);
836 /* thumbnails options */
837 READ_INT_CLAMP(thumbnails.max_width, 16, 512);
838 READ_INT_CLAMP(thumbnails.max_height, 16, 512);
840 READ_BOOL(thumbnails.enable_caching);
841 READ_BOOL(thumbnails.cache_into_dirs);
842 READ_BOOL(thumbnails.fast);
843 READ_BOOL(thumbnails.use_xvpics);
844 READ_BOOL(thumbnails.spec_standard);
845 READ_UINT_CLAMP(thumbnails.quality, GDK_INTERP_NEAREST, GDK_INTERP_HYPER);
847 /* file sorting options */
848 READ_UINT(file_sort.method);
849 READ_BOOL(file_sort.ascending);
850 READ_BOOL(file_sort.case_sensitive);
852 /* file operations options */
853 READ_BOOL(file_ops.enable_in_place_rename);
854 READ_BOOL(file_ops.confirm_delete);
855 READ_BOOL(file_ops.enable_delete_key);
856 READ_BOOL(file_ops.safe_delete_enable);
857 READ_CHAR(file_ops.safe_delete_path);
858 READ_INT(file_ops.safe_delete_folder_maxsize);
860 /* fullscreen options */
861 READ_INT(fullscreen.screen);
862 READ_BOOL(fullscreen.clean_flip);
863 READ_BOOL(fullscreen.disable_saver);
864 READ_BOOL(fullscreen.above);
867 READ_UINT(histogram.last_channel_mode);
868 READ_UINT(histogram.last_log_mode);
871 COMPAT_READ_UINT(image_overlay.common.enabled, image_overlay.common.state); /* 2008-05-12 */
872 READ_UINT(image_overlay.common.state);
873 COMPAT_READ_BOOL(fullscreen.show_info, image_overlay.common.show_at_startup); /* 2008-04-21 */
874 READ_BOOL(image_overlay.common.show_at_startup);
875 COMPAT_READ_CHAR(fullscreen.info, image_overlay.common.template_string); /* 2008-04-21 */
876 READ_CHAR(image_overlay.common.template_string);
878 READ_INT(image_overlay.common.x);
879 READ_INT(image_overlay.common.y);
882 /* slideshow options */
883 READ_INT_UNIT(slideshow.delay, SLIDESHOW_SUBSECOND_PRECISION);
884 READ_BOOL(slideshow.random);
885 READ_BOOL(slideshow.repeat);
887 /* collection options */
889 READ_BOOL(collections.rectangular_selection);
891 /* filtering options */
893 READ_BOOL(file_filter.show_hidden_files);
894 READ_BOOL(file_filter.show_dot_directory);
895 READ_BOOL(file_filter.disable);
897 if (g_ascii_strcasecmp(option, "file_filter.ext") == 0)
899 filter_parse(value_all);
903 if (g_ascii_strcasecmp(option, "sidecar.ext") == 0)
905 sidecar_ext_parse(value_all, TRUE);
911 READ_BOOL(color_profile.enabled);
912 READ_BOOL(color_profile.use_image);
913 READ_INT(color_profile.input_type);
915 if (is_numbered_option(option, "color_profile.input_file_", &i))
917 if (i > 0 && i <= COLOR_PROFILE_INPUTS)
920 read_char_option(f, option, option, value, &options->color_profile.input_file[i]);
925 if (is_numbered_option(option, "color_profile.input_name_", &i))
927 if (i > 0 && i <= COLOR_PROFILE_INPUTS)
930 read_char_option(f, option, option, value, &options->color_profile.input_name[i]);
935 READ_INT(color_profile.screen_type);
936 READ_CHAR(color_profile.screen_file);
939 READ_CHAR(shell.path);
940 READ_CHAR(shell.options);
942 /* External Programs */
944 if (is_numbered_option(option, "external_", &i))
946 if (i > 0 && i <= GQ_EDITOR_SLOTS)
951 editor_set_name(i, quoted_value(value_all, &ptr));
952 editor_set_command(i, quoted_value(ptr, NULL));
958 if (0 == g_ascii_strncasecmp(option, "exif.display.", 13))
960 for (i = 0; ExifUIList[i].key; i++)
961 if (0 == g_ascii_strcasecmp(option + 13, ExifUIList[i].key))
962 ExifUIList[i].current = strtol(value, NULL, 10);
971 void load_options(ConfOptions *options)
976 if (isdir(GQ_SYSTEM_WIDE_DIR))
978 rc_path = g_build_filename(GQ_SYSTEM_WIDE_DIR, RC_FILE_NAME, NULL);
979 success = load_options_from(rc_path, options);
980 DEBUG_1("Loading options from %s ... %s", rc_path, success ? "done" : "failed");
984 rc_path = g_build_filename(homedir(), GQ_RC_DIR, RC_FILE_NAME, NULL);
985 success = load_options_from(rc_path, options);
986 DEBUG_1("Loading options from %s ... %s", rc_path, success ? "done" : "failed");