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);
392 WRITE_CHAR(layout.home_path);
395 WRITE_BOOL(layout.save_window_positions);
398 WRITE_INT(layout.main_window.x);
399 WRITE_INT(layout.main_window.y);
400 WRITE_INT(layout.main_window.w);
401 WRITE_INT(layout.main_window.h);
402 WRITE_BOOL(layout.main_window.maximized);
403 WRITE_INT(layout.main_window.hdivider_pos);
404 WRITE_INT(layout.main_window.vdivider_pos);
407 WRITE_INT(layout.float_window.x);
408 WRITE_INT(layout.float_window.y);
409 WRITE_INT(layout.float_window.w);
410 WRITE_INT(layout.float_window.h);
411 WRITE_INT(layout.float_window.vdivider_pos);
414 WRITE_INT(layout.properties_window.w);
415 WRITE_INT(layout.properties_window.h);
418 WRITE_BOOL(layout.tools_float);
419 WRITE_BOOL(layout.tools_hidden);
420 WRITE_BOOL(layout.tools_restore_state);
423 WRITE_BOOL(layout.toolbar_hidden);
425 WRITE_SUBTITLE("Panels Options");
427 WRITE_BOOL(panels.exif.enabled);
428 WRITE_INT(panels.exif.width);
429 WRITE_BOOL(panels.info.enabled);
430 WRITE_INT(panels.info.width);
431 WRITE_BOOL(panels.sort.enabled);
432 WRITE_INT(panels.sort.action_state);
433 WRITE_INT(panels.sort.mode_state);
434 WRITE_INT(panels.sort.selection_state);
436 WRITE_SUBTITLE("Properties dialog Options");
437 WRITE_CHAR(properties.tabs_order);
439 WRITE_SUBTITLE("Image Options");
441 secure_fprintf(ssi, "# image.zoom_mode possible values are:\n"
445 secure_fprintf(ssi, "image.zoom_mode: ");
446 switch (options->image.zoom_mode)
448 case ZOOM_RESET_ORIGINAL: secure_fprintf(ssi, "original\n"); break;
449 case ZOOM_RESET_FIT_WINDOW: secure_fprintf(ssi, "fit\n"); break;
450 case ZOOM_RESET_NONE: secure_fprintf(ssi, "dont_change\n"); break;
453 WRITE_BOOL(image.zoom_2pass);
454 WRITE_BOOL(image.zoom_to_fit_allow_expand);
455 WRITE_UINT(image.zoom_quality);
456 WRITE_INT(image.zoom_increment);
457 WRITE_BOOL(image.fit_window_to_image);
458 WRITE_BOOL(image.limit_window_size);
459 WRITE_INT(image.max_window_size);
460 WRITE_BOOL(image.limit_autofit_size);
461 WRITE_INT(image.max_autofit_size);
462 WRITE_UINT(image.scroll_reset_method);
463 WRITE_INT(image.tile_cache_max);
464 WRITE_INT(image.image_cache_max);
465 WRITE_UINT(image.dither_quality);
466 WRITE_BOOL(image.enable_read_ahead);
467 WRITE_BOOL(image.exif_rotate_enable);
468 WRITE_BOOL(image.use_custom_border_color);
469 WRITE_COLOR(image.border_color);
470 WRITE_INT(image.read_buffer_size);
471 WRITE_INT(image.idle_read_loop_count);
473 WRITE_SUBTITLE("Thumbnails Options");
475 WRITE_INT(thumbnails.max_width);
476 WRITE_INT(thumbnails.max_height);
477 WRITE_BOOL(thumbnails.enable_caching);
478 WRITE_BOOL(thumbnails.cache_into_dirs);
479 WRITE_BOOL(thumbnails.fast);
480 WRITE_BOOL(thumbnails.use_xvpics);
481 WRITE_BOOL(thumbnails.spec_standard);
482 WRITE_UINT(thumbnails.quality);
485 WRITE_SUBTITLE("File sorting Options");
487 WRITE_INT(file_sort.method);
488 WRITE_BOOL(file_sort.ascending);
489 WRITE_BOOL(file_sort.case_sensitive);
492 WRITE_SUBTITLE("Fullscreen Options");
494 WRITE_INT(fullscreen.screen);
495 WRITE_BOOL(fullscreen.clean_flip);
496 WRITE_BOOL(fullscreen.disable_saver);
497 WRITE_BOOL(fullscreen.above);
500 WRITE_SUBTITLE("Histogram Options");
501 WRITE_UINT(histogram.last_channel_mode);
502 WRITE_UINT(histogram.last_log_mode);
505 WRITE_SUBTITLE("Image Overlay Options");
506 WRITE_UINT(image_overlay.common.state);
507 WRITE_BOOL(image_overlay.common.show_at_startup);
508 WRITE_CHAR(image_overlay.common.template_string);
511 secure_fprintf(ssi, "# these are relative positions:\n");
512 secure_fprintf(ssi, "# x >= 0: |x| pixels from left border\n");
513 secure_fprintf(ssi, "# x < 0 : |x| pixels from right border\n");
514 secure_fprintf(ssi, "# y >= 0: |y| pixels from top border\n");
515 secure_fprintf(ssi, "# y < 0 : |y| pixels from bottom border\n");
516 WRITE_INT(image_overlay.common.x);
517 WRITE_INT(image_overlay.common.y);
520 WRITE_SUBTITLE("Slideshow Options");
522 WRITE_INT_UNIT(slideshow.delay, SLIDESHOW_SUBSECOND_PRECISION);
523 WRITE_BOOL(slideshow.random);
524 WRITE_BOOL(slideshow.repeat);
527 WRITE_SUBTITLE("Collection Options");
529 WRITE_BOOL(collections.rectangular_selection);
532 WRITE_SUBTITLE("Filtering Options");
534 WRITE_BOOL(file_filter.show_hidden_files);
535 WRITE_BOOL(file_filter.show_dot_directory);
536 WRITE_BOOL(file_filter.disable);
539 filter_write_list(ssi);
542 WRITE_SUBTITLE("Sidecars Options");
544 sidecar_ext_write(ssi);
547 WRITE_SUBTITLE("Color Profiles");
550 secure_fprintf(ssi, "# NOTICE: %s was not built with support for color profiles,\n"
551 "# color profile options will have no effect.\n\n", GQ_APPNAME);
554 WRITE_BOOL(color_profile.enabled);
555 WRITE_BOOL(color_profile.use_image);
556 WRITE_INT(color_profile.input_type);
559 for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
563 buf = g_strdup_printf("color_profile.input_file_%d", i + 1);
564 write_char_option(ssi, buf, options->color_profile.input_file[i]);
567 buf = g_strdup_printf("color_profile.input_name_%d", i + 1);
568 write_char_option(ssi, buf, options->color_profile.input_name[i]);
573 WRITE_INT(color_profile.screen_type);
574 WRITE_CHAR(color_profile.screen_file);
577 WRITE_SUBTITLE("Shell command");
578 WRITE_CHAR(shell.path);
579 WRITE_CHAR(shell.options);
582 WRITE_SUBTITLE("Helpers");
583 secure_fprintf(ssi, "# Html browser\n");
584 secure_fprintf(ssi, "# command_name is: the binary's name to look for in the path\n");
585 secure_fprintf(ssi, "# If command_name is empty, the program will try various common html browsers\n");
586 secure_fprintf(ssi, "# command_line is:\n");
587 secure_fprintf(ssi, "# \"\" (empty string) = execute binary with html file path as command line\n");
588 secure_fprintf(ssi, "# \"string\" = execute string and use results for command line\n");
589 secure_fprintf(ssi, "# \"!string\" = use text following ! as command line, replacing optional %%s with html file path\n");
590 WRITE_CHAR(helpers.html_browser.command_name);
591 WRITE_CHAR(helpers.html_browser.command_line);
594 WRITE_SUBTITLE("External Programs");
595 secure_fprintf(ssi, "# Maximum of %d programs (external_1 through external_%d)\n", GQ_EDITOR_GENERIC_SLOTS, GQ_EDITOR_GENERIC_SLOTS);
596 secure_fprintf(ssi, "# external_%d through external_%d are used for file ops\n", GQ_EDITOR_GENERIC_SLOTS + 1, GQ_EDITOR_SLOTS);
597 secure_fprintf(ssi, "# format: external_n: \"menu name\" \"command line\"\n\n");
599 for (i = 0; i < GQ_EDITOR_SLOTS; i++)
601 if (i == GQ_EDITOR_GENERIC_SLOTS) secure_fputc(ssi, '\n');
602 gchar *qname = escquote_value(options->editor[i].name);
603 gchar *qcommand = escquote_value(options->editor[i].command);
604 secure_fprintf(ssi, "external_%d: %s %s\n", i+1, qname, qcommand);
610 WRITE_SUBTITLE("Exif Options");
611 secure_fprintf(ssi, "# Display: 0: never\n"
614 for (i = 0; ExifUIList[i].key; i++)
616 secure_fprintf(ssi, "exif.display.");
617 write_int_option(ssi, (gchar *)ExifUIList[i].key, ExifUIList[i].current);
620 WRITE_SUBTITLE("Documentation Options");
621 WRITE_CHAR(documentation.helpdir);
622 WRITE_CHAR(documentation.htmldir);
627 secure_fprintf(ssi, "######################################################################\n");
628 secure_fprintf(ssi, "# end of config file #\n");
629 secure_fprintf(ssi, "######################################################################\n");
632 if (secure_close(ssi))
634 log_printf(_("error saving config file: %s\nerror: %s\n"), utf8_path,
635 secsave_strerror(secsave_errno));
642 void save_options(ConfOptions *options)
646 sync_options_with_current_state(options);
648 rc_path = g_build_filename(homedir(), GQ_RC_DIR, RC_FILE_NAME, NULL);
649 save_options_to(rc_path, options);
656 *-----------------------------------------------------------------------------
657 * load configuration (public)
658 *-----------------------------------------------------------------------------
661 static gboolean is_numbered_option(const gchar *option, const gchar *prefix, gint *number)
664 gsize option_len = strlen(option);
665 gsize prefix_len = strlen(prefix);
667 if (option_len <= prefix_len) return FALSE;
668 if (g_ascii_strncasecmp(option, prefix, prefix_len) != 0) return FALSE;
671 while (g_ascii_isdigit(option[n])) n++;
672 if (n < option_len) return FALSE;
674 if (number) *number = atoi(option + prefix_len);
678 #define OPTION_READ_BUFFER_SIZE 1024
680 static gboolean load_options_from(const gchar *utf8_path, ConfOptions *options)
684 gchar s_buf[OPTION_READ_BUFFER_SIZE];
685 gchar value_all[OPTION_READ_BUFFER_SIZE];
690 rc_pathl = path_from_utf8(utf8_path);
691 f = fopen(rc_pathl,"r");
693 if (!f) return FALSE;
695 while (fgets(s_buf, sizeof(s_buf), f))
700 /* skip empty lines and comments */
701 while (g_ascii_isspace(*p)) p++;
702 if (!*p || *p == '\n' || *p == '#') continue;
704 /* parse option name */
706 while (g_ascii_isalnum(*p) || *p == '_' || *p == '.') p++;
711 /* search for value start, name and value are normally separated by ': '
712 * but we allow relaxed syntax here, so '=', ':=' or just a tab will work too */
713 while (*p == ':' || g_ascii_isspace(*p) || *p == '=') p++;
716 while (*p && !g_ascii_isspace(*p) && *p != '\n') p++;
717 value_end = p; /* value part up to the first whitespace or end of line */
718 while (*p != '\0') p++;
719 memcpy(value_all, value, 1 + p - value);
723 #define READ_BOOL(_name_) if (read_bool_option(f, option, #_name_, value, &options->_name_)) continue;
724 #define READ_INT(_name_) if (read_int_option(f, option, #_name_, value, &options->_name_)) continue;
725 #define READ_UINT(_name_) if (read_uint_option(f, option, #_name_, value, &options->_name_)) continue;
726 #define READ_INT_CLAMP(_name_, _min_, _max_) if (read_int_option_clamp(f, option, #_name_, value, &options->_name_, _min_, _max_)) continue;
727 #define READ_UINT_CLAMP(_name_, _min_, _max_) if (read_uint_option_clamp(f, option, #_name_, value, &options->_name_, _min_, _max_)) continue;
728 #define READ_INT_UNIT(_name_, _unit_) if (read_int_unit_option(f, option, #_name_, value, &options->_name_, _unit_)) continue;
729 #define READ_CHAR(_name_) if (read_char_option(f, option, #_name_, value_all, &options->_name_)) continue;
730 #define READ_COLOR(_name_) if (read_color_option(f, option, #_name_, value, &options->_name_)) continue;
732 #define COMPAT_READ_BOOL(_oldname_, _name_) if (read_bool_option(f, option, #_oldname_, value, &options->_name_)) continue;
733 #define COMPAT_READ_INT(_oldname_, _name_) if (read_int_option(f, option, #_oldname_, value, &options->_name_)) continue;
734 #define COMPAT_READ_UINT(_oldname_, _name_) if (read_uint_option(f, option, #_oldname_, value, &options->_name_)) continue;
735 #define COMPAT_READ_INT_CLAMP(_oldname_, _name_, _min_, _max_) if (read_int_option_clamp(f, option, #_oldname_, value, &options->_name_, _min_, _max_)) continue;
736 #define COMPAT_READ_INT_UNIT(_oldname_, _name_, _unit_) if (read_int_unit_option(f, option, #_oldname_, value, &options->_name_, _unit_)) continue;
737 #define COMPAT_READ_CHAR(_oldname_, _name_) if (read_char_option(f, option, #_oldname_, value_all, &options->_name_)) continue;
738 #define COMPAT_READ_COLOR(_oldname_, _name_) if (read_color_option(f, option, #_oldname_, value, &options->_name_)) continue;
740 /* general options */
741 READ_BOOL(show_icon_names);
742 READ_BOOL(show_copy_path);
744 READ_BOOL(tree_descend_subdirs);
745 READ_BOOL(lazy_image_sync);
746 READ_BOOL(update_on_time_change);
748 READ_UINT_CLAMP(duplicates_similarity_threshold, 0, 100);
750 READ_BOOL(progressive_key_scrolling);
752 READ_BOOL(enable_metadata_dirs);
753 READ_BOOL(save_metadata_in_image_file);
755 READ_BOOL(mousewheel_scrolls);
757 READ_INT(open_recent_list_maxsize);
758 READ_INT(dnd_icon_size);
759 READ_BOOL(place_dialogs_under_mouse);
761 /* startup options */
763 COMPAT_READ_BOOL(startup_path_enable, startup.restore_path); /* 2008/05/11 */
764 READ_BOOL(startup.restore_path);
766 READ_BOOL(startup.use_last_path);
768 COMPAT_READ_CHAR(startup_path, startup.path); /* 2008/05/11 */
769 READ_CHAR(startup.path);
773 READ_INT(layout.style);
774 READ_CHAR(layout.order);
776 COMPAT_READ_UINT(layout.view_as_icons, layout.file_view_type); /* 2008/05/03 */
778 READ_UINT(layout.dir_view_type);
779 READ_UINT(layout.file_view_type);
780 READ_BOOL(layout.show_marks);
781 READ_BOOL(layout.show_thumbnails);
782 READ_BOOL(layout.show_directory_date);
783 READ_CHAR(layout.home_path);
785 /* window positions */
787 READ_BOOL(layout.save_window_positions);
789 READ_INT(layout.main_window.x);
790 READ_INT(layout.main_window.y);
791 READ_INT(layout.main_window.w);
792 READ_INT(layout.main_window.h);
793 READ_BOOL(layout.main_window.maximized);
794 READ_INT(layout.main_window.hdivider_pos);
795 READ_INT(layout.main_window.vdivider_pos);
797 READ_INT(layout.float_window.x);
798 READ_INT(layout.float_window.y);
799 READ_INT(layout.float_window.w);
800 READ_INT(layout.float_window.h);
801 READ_INT(layout.float_window.vdivider_pos);
803 READ_INT(layout.properties_window.w);
804 READ_INT(layout.properties_window.h);
806 READ_BOOL(layout.tools_float);
807 READ_BOOL(layout.tools_hidden);
808 READ_BOOL(layout.tools_restore_state);
809 READ_BOOL(layout.toolbar_hidden);
812 READ_BOOL(panels.exif.enabled);
813 READ_INT_CLAMP(panels.exif.width, PANEL_MIN_WIDTH, PANEL_MAX_WIDTH);
814 READ_BOOL(panels.info.enabled);
815 READ_INT_CLAMP(panels.info.width, PANEL_MIN_WIDTH, PANEL_MAX_WIDTH);
816 READ_BOOL(panels.sort.enabled);
817 READ_INT(panels.sort.action_state);
818 READ_INT(panels.sort.mode_state);
819 READ_INT(panels.sort.selection_state);
821 /* properties dialog options */
822 READ_CHAR(properties.tabs_order);
825 if (g_ascii_strcasecmp(option, "image.zoom_mode") == 0)
827 if (g_ascii_strcasecmp(value, "original") == 0)
828 options->image.zoom_mode = ZOOM_RESET_ORIGINAL;
829 else if (g_ascii_strcasecmp(value, "fit") == 0)
830 options->image.zoom_mode = ZOOM_RESET_FIT_WINDOW;
831 else if (g_ascii_strcasecmp(value, "dont_change") == 0)
832 options->image.zoom_mode = ZOOM_RESET_NONE;
835 READ_BOOL(image.zoom_2pass);
836 READ_BOOL(image.zoom_to_fit_allow_expand);
837 READ_BOOL(image.fit_window_to_image);
838 READ_BOOL(image.limit_window_size);
839 READ_INT(image.max_window_size);
840 READ_BOOL(image.limit_autofit_size);
841 READ_INT(image.max_autofit_size);
842 READ_UINT_CLAMP(image.scroll_reset_method, 0, PR_SCROLL_RESET_COUNT - 1);
843 READ_INT(image.tile_cache_max);
844 READ_INT(image.image_cache_max);
845 READ_UINT_CLAMP(image.zoom_quality, GDK_INTERP_NEAREST, GDK_INTERP_HYPER);
846 READ_UINT_CLAMP(image.dither_quality, GDK_RGB_DITHER_NONE, GDK_RGB_DITHER_MAX);
847 READ_INT(image.zoom_increment);
848 READ_BOOL(image.enable_read_ahead);
849 READ_BOOL(image.exif_rotate_enable);
850 READ_BOOL(image.use_custom_border_color);
851 READ_COLOR(image.border_color);
852 READ_INT_CLAMP(image.read_buffer_size, IMAGE_LOADER_READ_BUFFER_SIZE_MIN, IMAGE_LOADER_READ_BUFFER_SIZE_MAX);
853 READ_INT_CLAMP(image.idle_read_loop_count, IMAGE_LOADER_IDLE_READ_LOOP_COUNT_MIN, IMAGE_LOADER_IDLE_READ_LOOP_COUNT_MAX);
856 /* thumbnails options */
857 READ_INT_CLAMP(thumbnails.max_width, 16, 512);
858 READ_INT_CLAMP(thumbnails.max_height, 16, 512);
860 READ_BOOL(thumbnails.enable_caching);
861 READ_BOOL(thumbnails.cache_into_dirs);
862 READ_BOOL(thumbnails.fast);
863 READ_BOOL(thumbnails.use_xvpics);
864 READ_BOOL(thumbnails.spec_standard);
865 READ_UINT_CLAMP(thumbnails.quality, GDK_INTERP_NEAREST, GDK_INTERP_HYPER);
867 /* file sorting options */
868 READ_UINT(file_sort.method);
869 READ_BOOL(file_sort.ascending);
870 READ_BOOL(file_sort.case_sensitive);
872 /* file operations options */
873 READ_BOOL(file_ops.enable_in_place_rename);
874 READ_BOOL(file_ops.confirm_delete);
875 READ_BOOL(file_ops.enable_delete_key);
876 READ_BOOL(file_ops.safe_delete_enable);
877 READ_CHAR(file_ops.safe_delete_path);
878 READ_INT(file_ops.safe_delete_folder_maxsize);
880 /* fullscreen options */
881 READ_INT(fullscreen.screen);
882 READ_BOOL(fullscreen.clean_flip);
883 READ_BOOL(fullscreen.disable_saver);
884 READ_BOOL(fullscreen.above);
887 READ_UINT(histogram.last_channel_mode);
888 READ_UINT(histogram.last_log_mode);
891 COMPAT_READ_UINT(image_overlay.common.enabled, image_overlay.common.state); /* 2008-05-12 */
892 READ_UINT(image_overlay.common.state);
893 COMPAT_READ_BOOL(fullscreen.show_info, image_overlay.common.show_at_startup); /* 2008-04-21 */
894 READ_BOOL(image_overlay.common.show_at_startup);
895 COMPAT_READ_CHAR(fullscreen.info, image_overlay.common.template_string); /* 2008-04-21 */
896 READ_CHAR(image_overlay.common.template_string);
898 READ_INT(image_overlay.common.x);
899 READ_INT(image_overlay.common.y);
902 /* slideshow options */
903 READ_INT_UNIT(slideshow.delay, SLIDESHOW_SUBSECOND_PRECISION);
904 READ_BOOL(slideshow.random);
905 READ_BOOL(slideshow.repeat);
907 /* collection options */
909 READ_BOOL(collections.rectangular_selection);
911 /* filtering options */
913 READ_BOOL(file_filter.show_hidden_files);
914 READ_BOOL(file_filter.show_dot_directory);
915 READ_BOOL(file_filter.disable);
917 if (g_ascii_strcasecmp(option, "file_filter.ext") == 0)
919 filter_parse(value_all);
923 if (g_ascii_strcasecmp(option, "sidecar.ext") == 0)
925 sidecar_ext_parse(value_all, TRUE);
931 READ_BOOL(color_profile.enabled);
932 READ_BOOL(color_profile.use_image);
933 READ_INT(color_profile.input_type);
935 if (is_numbered_option(option, "color_profile.input_file_", &i))
937 if (i > 0 && i <= COLOR_PROFILE_INPUTS)
940 read_char_option(f, option, option, value, &options->color_profile.input_file[i]);
945 if (is_numbered_option(option, "color_profile.input_name_", &i))
947 if (i > 0 && i <= COLOR_PROFILE_INPUTS)
950 read_char_option(f, option, option, value, &options->color_profile.input_name[i]);
955 READ_INT(color_profile.screen_type);
956 READ_CHAR(color_profile.screen_file);
959 READ_CHAR(shell.path);
960 READ_CHAR(shell.options);
963 READ_CHAR(helpers.html_browser.command_name);
964 READ_CHAR(helpers.html_browser.command_line);
966 /* External Programs */
968 if (is_numbered_option(option, "external_", &i))
970 if (i > 0 && i <= GQ_EDITOR_SLOTS)
975 editor_set_name(i, quoted_value(value_all, &ptr));
976 editor_set_command(i, quoted_value(ptr, NULL));
982 if (0 == g_ascii_strncasecmp(option, "exif.display.", 13))
984 for (i = 0; ExifUIList[i].key; i++)
985 if (0 == g_ascii_strcasecmp(option + 13, ExifUIList[i].key))
986 ExifUIList[i].current = strtol(value, NULL, 10);
991 READ_CHAR(documentation.helpdir);
992 READ_CHAR(documentation.htmldir);
1000 void load_options(ConfOptions *options)
1005 if (isdir(GQ_SYSTEM_WIDE_DIR))
1007 rc_path = g_build_filename(GQ_SYSTEM_WIDE_DIR, RC_FILE_NAME, NULL);
1008 success = load_options_from(rc_path, options);
1009 DEBUG_1("Loading options from %s ... %s", rc_path, success ? "done" : "failed");
1013 rc_path = g_build_filename(homedir(), GQ_RC_DIR, RC_FILE_NAME, NULL);
1014 success = load_options_from(rc_path, options);
1015 DEBUG_1("Loading options from %s ... %s", rc_path, success ? "done" : "failed");