7 * This software is released under the GNU General Public License (GNU GPL).
8 * Please read the included file COPYING for more information.
9 * This software comes with no warranty of any kind, use at your own risk!
12 #include <glib/gstdio.h>
20 #include "secure_save.h"
21 #include "slideshow.h"
22 #include "ui_fileops.h"
26 *-----------------------------------------------------------------------------
27 * line write/parse routines (private)
28 *-----------------------------------------------------------------------------
32 returns text without quotes or NULL for empty or broken string
33 any text up to first '"' is skipped
34 tail is set to point at the char after the second '"'
39 gchar *quoted_value(const gchar *text, const gchar **tail)
43 gint l = strlen(text);
46 if (tail) *tail = text;
48 if (l == 0) return retval;
50 while (c < l && text[c] !='"') c++;
59 if (text[e-1] != '\\' && text[e] == '"') break;
66 gchar *substring = g_strndup(ptr, e - c);
70 retval = g_strcompress(substring);
75 if (tail) *tail = text + e + 1;
78 /* for compatibility with older formats (<0.3.7)
79 * read a line without quotes too */
82 while (c < l && text[c] !=' ' && text[c] !=8 && text[c] != '\n') c++;
85 retval = g_strndup(text, c);
87 if (tail) *tail = text + c;
93 gchar *escquote_value(const gchar *text)
97 if (!text) return g_strdup("\"\"");
99 e = g_strescape(text, "");
102 gchar *retval = g_strdup_printf("\"%s\"", e);
106 return g_strdup("\"\"");
109 static void write_char_option(SecureSaveInfo *ssi, gchar *label, gchar *text)
111 gchar *escval = escquote_value(text);
113 secure_fprintf(ssi, "%s: %s\n", label, escval);
117 static void read_char_option(FILE *f, gchar *option, gchar *label, gchar *value, gchar **text)
119 if (text && strcasecmp(option, label) == 0)
122 *text = quoted_value(value, NULL);
126 /* Since gdk_color_to_string() is only available since gtk 2.12
127 * here is an equivalent stub function. */
128 static gchar *color_to_string(GdkColor *color)
130 return g_strdup_printf("#%04X%04X%04X", color->red, color->green, color->blue);
133 static void write_color_option(SecureSaveInfo *ssi, gchar *label, GdkColor *color)
137 gchar *colorstring = color_to_string(color);
139 write_char_option(ssi, label, colorstring);
143 secure_fprintf(ssi, "%s: \n", label);
146 static void read_color_option(FILE *f, gchar *option, gchar *label, gchar *value, GdkColor *color)
148 if (color && strcasecmp(option, label) == 0)
150 gchar *colorstr = quoted_value(value, NULL);
151 if (colorstr) gdk_color_parse(colorstr, color);
157 static void write_int_option(SecureSaveInfo *ssi, gchar *label, gint n)
159 secure_fprintf(ssi, "%s: %d\n", label, n);
162 static void read_int_option(FILE *f, gchar *option, gchar *label, gchar *value, gint *n)
164 if (n && strcasecmp(option, label) == 0)
166 *n = strtol(value, NULL, 10);
170 static void read_uint_option(FILE *f, gchar *option, gchar *label, gchar *value, guint *n)
172 if (n && strcasecmp(option, label) == 0)
174 *n = strtoul(value, NULL, 10);
180 static void read_int_option_clamp(FILE *f, gchar *option, gchar *label, gchar *value, gint *n, gint min, gint max)
182 if (n && strcasecmp(option, label) == 0)
184 *n = CLAMP(strtol(value, NULL, 10), min, max);
189 static void write_int_unit_option(SecureSaveInfo *ssi, gchar *label, gint n, gint subunits)
204 secure_fprintf(ssi, "%s: %d.%d\n", label, l, r);
207 static void read_int_unit_option(FILE *f, gchar *option, gchar *label, gchar *value, gint *n, gint subunits)
209 if (n && strcasecmp(option, label) == 0)
215 while (*ptr != '\0' && *ptr != '.') ptr++;
219 l = strtol(value, NULL, 10);
222 r = strtol(ptr, NULL, 10);
226 l = strtol(value, NULL, 10);
230 *n = l * subunits + r;
234 static void write_bool_option(SecureSaveInfo *ssi, gchar *label, gint n)
236 secure_fprintf(ssi, "%s: ", label);
237 if (n) secure_fprintf(ssi, "true\n"); else secure_fprintf(ssi, "false\n");
240 static void read_bool_option(FILE *f, gchar *option, gchar *label, gchar *value, gint *n)
242 if (n && strcasecmp(option, label) == 0)
244 if (strcasecmp(value, "true") == 0 || strcmp(value, "1") == 0)
252 *-----------------------------------------------------------------------------
253 * save configuration (public)
254 *-----------------------------------------------------------------------------
257 void save_options(void)
264 rc_path = g_strconcat(homedir(), "/", GQ_RC_DIR, "/", RC_FILE_NAME, NULL);
266 rc_pathl = path_from_utf8(rc_path);
267 ssi = secure_open(rc_pathl);
273 buf = g_strdup_printf(_("error saving config file: %s\n"), rc_path);
281 secure_fprintf(ssi, "######################################################################\n");
282 secure_fprintf(ssi, "# %30s config file version %7s #\n", GQ_APPNAME, VERSION);
283 secure_fprintf(ssi, "######################################################################\n");
284 secure_fputc(ssi, '\n');
286 secure_fprintf(ssi, "# Note: This file is autogenerated. Options can be changed here,\n");
287 secure_fprintf(ssi, "# but user comments and formatting will be lost.\n");
288 secure_fputc(ssi, '\n');
290 secure_fprintf(ssi, "##### General Options #####\n\n");
292 write_bool_option(ssi, "show_icon_names", options->show_icon_names);
293 secure_fputc(ssi, '\n');
295 write_bool_option(ssi, "tree_descend_subdirs", options->tree_descend_subdirs);
296 write_bool_option(ssi, "lazy_image_sync", options->lazy_image_sync);
297 write_bool_option(ssi, "update_on_time_change", options->update_on_time_change);
298 secure_fputc(ssi, '\n');
300 write_bool_option(ssi, "startup_path_enable", options->startup_path_enable);
301 write_char_option(ssi, "startup_path", options->startup_path);
303 write_bool_option(ssi, "progressive_key_scrolling", options->progressive_key_scrolling);
304 write_bool_option(ssi, "enable_metadata_dirs", options->enable_metadata_dirs);
306 write_int_option(ssi, "duplicates_similarity_threshold", options->duplicates_similarity_threshold);
307 secure_fputc(ssi, '\n');
309 write_bool_option(ssi, "mousewheel_scrolls", options->mousewheel_scrolls);
310 write_int_option(ssi, "open_recent_list_maxsize", options->open_recent_list_maxsize);
311 write_bool_option(ssi, "place_dialogs_under_mouse", options->place_dialogs_under_mouse);
314 secure_fprintf(ssi, "\n##### File operations Options #####\n\n");
316 write_bool_option(ssi, "file_ops.enable_in_place_rename", options->file_ops.enable_in_place_rename);
317 write_bool_option(ssi, "file_ops.confirm_delete", options->file_ops.confirm_delete);
318 write_bool_option(ssi, "file_ops.enable_delete_key", options->file_ops.enable_delete_key);
319 write_bool_option(ssi, "file_ops.safe_delete_enable", options->file_ops.safe_delete_enable);
320 write_char_option(ssi, "file_ops.safe_delete_path", options->file_ops.safe_delete_path);
321 write_int_option(ssi, "file_ops.safe_delete_folder_maxsize", options->file_ops.safe_delete_folder_maxsize);
324 secure_fprintf(ssi, "\n##### Layout Options #####\n\n");
326 write_int_option(ssi, "layout.style", options->layout.style);
327 write_char_option(ssi, "layout.order", options->layout.order);
328 write_bool_option(ssi, "layout.view_as_icons", options->layout.view_as_icons);
329 write_bool_option(ssi, "layout.view_as_tree", options->layout.view_as_tree);
330 write_bool_option(ssi, "layout.show_thumbnails", options->layout.show_thumbnails);
331 secure_fputc(ssi, '\n');
333 write_bool_option(ssi, "layout.save_window_positions", options->layout.save_window_positions);
334 secure_fputc(ssi, '\n');
336 write_int_option(ssi, "layout.main_window.x", options->layout.main_window.x);
337 write_int_option(ssi, "layout.main_window.y", options->layout.main_window.y);
338 write_int_option(ssi, "layout.main_window.w", options->layout.main_window.w);
339 write_int_option(ssi, "layout.main_window.h", options->layout.main_window.h);
340 write_bool_option(ssi, "layout.main_window.maximized", options->layout.main_window.maximized);
341 write_int_option(ssi, "layout.main_window.hdivider_pos", options->layout.main_window.hdivider_pos);
342 write_int_option(ssi, "layout.main_window.vdivider_pos", options->layout.main_window.vdivider_pos);
343 secure_fputc(ssi, '\n');
345 write_int_option(ssi, "layout.float_window.x", options->layout.float_window.x);
346 write_int_option(ssi, "layout.float_window.y", options->layout.float_window.y);
347 write_int_option(ssi, "layout.float_window.w", options->layout.float_window.w);
348 write_int_option(ssi, "layout.float_window.h", options->layout.float_window.h);
349 write_int_option(ssi, "layout.float_window.vdivider_pos", options->layout.float_window.vdivider_pos);
350 secure_fputc(ssi, '\n');
352 write_bool_option(ssi, "layout.tools_float", options->layout.tools_float);
353 write_bool_option(ssi, "layout.tools_hidden", options->layout.tools_hidden);
354 write_bool_option(ssi, "layout.tools_restore_state", options->layout.tools_restore_state);
355 secure_fputc(ssi, '\n');
357 write_bool_option(ssi, "layout.toolbar_hidden", options->layout.toolbar_hidden);
360 secure_fprintf(ssi, "\n##### Image Options #####\n\n");
362 secure_fprintf(ssi, "image.zoom_mode: ");
363 if (options->image.zoom_mode == ZOOM_RESET_ORIGINAL) secure_fprintf(ssi, "original\n");
364 if (options->image.zoom_mode == ZOOM_RESET_FIT_WINDOW) secure_fprintf(ssi, "fit\n");
365 if (options->image.zoom_mode == ZOOM_RESET_NONE) secure_fprintf(ssi, "dont_change\n");
366 write_bool_option(ssi, "image.zoom_2pass", options->image.zoom_2pass);
367 write_bool_option(ssi, "image.zoom_to_fit_allow_expand", options->image.zoom_to_fit_allow_expand);
368 write_int_option(ssi, "image.zoom_quality", options->image.zoom_quality);
369 write_int_option(ssi, "image.zoom_increment", options->image.zoom_increment);
370 write_bool_option(ssi, "image.fit_window_to_image", options->image.fit_window_to_image);
371 write_bool_option(ssi, "image.limit_window_size", options->image.limit_window_size);
372 write_int_option(ssi, "image.max_window_size", options->image.max_window_size);
373 write_bool_option(ssi, "image.limit_autofit_size", options->image.limit_autofit_size);
374 write_int_option(ssi, "image.max_autofit_size", options->image.max_autofit_size);
375 write_int_option(ssi, "image.scroll_reset_method", options->image.scroll_reset_method);
376 write_int_option(ssi, "image.tile_cache_max", options->image.tile_cache_max);
377 write_int_option(ssi, "image.dither_quality", options->image.dither_quality);
378 write_bool_option(ssi, "image.enable_read_ahead", options->image.enable_read_ahead);
379 write_bool_option(ssi, "image.exif_rotate_enable", options->image.exif_rotate_enable);
380 write_bool_option(ssi, "image.use_custom_border_color", options->image.use_custom_border_color);
381 write_color_option(ssi, "image.border_color", &options->image.border_color);
384 secure_fprintf(ssi, "\n##### Thumbnails Options #####\n\n");
386 write_int_option(ssi, "thumbnails.max_width", options->thumbnails.max_width);
387 write_int_option(ssi, "thumbnails.max_height", options->thumbnails.max_height);
388 write_bool_option(ssi, "thumbnails.enable_caching", options->thumbnails.enable_caching);
389 write_bool_option(ssi, "thumbnails.cache_into_dirs", options->thumbnails.cache_into_dirs);
390 write_bool_option(ssi, "thumbnails.fast", options->thumbnails.fast);
391 write_bool_option(ssi, "thumbnails.use_xvpics", options->thumbnails.use_xvpics);
392 write_bool_option(ssi, "thumbnails.spec_standard", options->thumbnails.spec_standard);
393 write_int_option(ssi, "thumbnails.quality", options->thumbnails.quality);
396 secure_fprintf(ssi, "\n##### File sorting Options #####\n\n");
398 write_int_option(ssi, "file_sort.method", (gint)options->file_sort.method);
399 write_bool_option(ssi, "file_sort.ascending", options->file_sort.ascending);
400 write_bool_option(ssi, "file_sort.case_sensitive", options->file_sort.case_sensitive);
403 secure_fprintf(ssi, "\n##### Fullscreen Options #####\n\n");
405 write_int_option(ssi, "fullscreen.screen", options->fullscreen.screen);
406 write_bool_option(ssi, "fullscreen.clean_flip", options->fullscreen.clean_flip);
407 write_bool_option(ssi, "fullscreen.disable_saver", options->fullscreen.disable_saver);
408 write_bool_option(ssi, "fullscreen.above", options->fullscreen.above);
409 write_bool_option(ssi, "fullscreen.show_info", options->fullscreen.show_info);
410 write_char_option(ssi, "fullscreen.info", options->fullscreen.info);
412 secure_fprintf(ssi, "\n##### Slideshow Options #####\n\n");
414 write_int_unit_option(ssi, "slideshow.delay", options->slideshow.delay, SLIDESHOW_SUBSECOND_PRECISION);
415 write_bool_option(ssi, "slideshow.random", options->slideshow.random);
416 write_bool_option(ssi, "slideshow.repeat", options->slideshow.repeat);
419 secure_fprintf(ssi, "\n##### Collection Options #####\n\n");
421 write_bool_option(ssi, "collections.rectangular_selection", options->collections.rectangular_selection);
424 secure_fprintf(ssi, "\n##### Filtering Options #####\n\n");
426 write_bool_option(ssi, "file_filter.show_dot_files", options->file_filter.show_dot_files);
427 write_bool_option(ssi, "file_filter.disable", options->file_filter.disable);
428 secure_fputc(ssi, '\n');
430 filter_write_list(ssi);
433 secure_fprintf(ssi, "\n##### Sidecars Options #####\n\n");
435 sidecar_ext_write(ssi);
438 secure_fprintf(ssi, "\n##### Color Profiles #####\n\n");
441 secure_fprintf(ssi, "# NOTICE: %s was not built with support for color profiles,\n"
442 "# color profile options will have no effect.\n\n", GQ_APPNAME);
445 write_bool_option(ssi, "color_profile.enabled", options->color_profile.enabled);
446 write_bool_option(ssi, "color_profile.use_image", options->color_profile.use_image);
447 write_int_option(ssi, "color_profile.input_type", options->color_profile.input_type);
448 secure_fputc(ssi, '\n');
450 for (i = 0; i < COLOR_PROFILE_INPUTS; i++)
454 buf = g_strdup_printf("color_profile.input_file_%d", i + 1);
455 write_char_option(ssi, buf, options->color_profile.input_file[i]);
458 buf = g_strdup_printf("color_profile.input_name_%d", i + 1);
459 write_char_option(ssi, buf, options->color_profile.input_name[i]);
462 secure_fputc(ssi, '\n');
463 write_int_option(ssi, "color_profile.screen_type", options->color_profile.screen_type);
464 write_char_option(ssi, "color_profile.screen_file", options->color_profile.screen_file);
466 secure_fprintf(ssi, "\n##### External Programs #####\n");
467 secure_fprintf(ssi, "# Maximum of %d programs (external_1 through external_%d)\n", GQ_EDITOR_GENERIC_SLOTS, GQ_EDITOR_GENERIC_SLOTS);
468 secure_fprintf(ssi, "# external_%d through external_%d are used for file ops\n", GQ_EDITOR_GENERIC_SLOTS + 1, GQ_EDITOR_SLOTS);
469 secure_fprintf(ssi, "# format: external_n: \"menu name\" \"command line\"\n\n");
471 for (i = 0; i < GQ_EDITOR_SLOTS; i++)
473 if (i == GQ_EDITOR_GENERIC_SLOTS) secure_fputc(ssi, '\n');
474 gchar *qname = escquote_value(options->editor_name[i]);
475 gchar *qcommand = escquote_value(options->editor_command[i]);
476 secure_fprintf(ssi, "external_%d: %s %s\n", i+1, qname, qcommand);
482 secure_fprintf(ssi, "\n##### Exif Options #####\n# Display:\n# 0: never\n# 1: if set\n# 2: always\n\n");
483 for (i = 0; ExifUIList[i].key; i++)
485 secure_fprintf(ssi, "exif.display.");
486 write_int_option(ssi, (gchar *)ExifUIList[i].key, ExifUIList[i].current);
489 secure_fputc(ssi, '\n');
490 secure_fprintf(ssi, "######################################################################\n");
491 secure_fprintf(ssi, "# end of config file #\n");
492 secure_fprintf(ssi, "######################################################################\n");
495 if (secure_close(ssi))
499 buf = g_strdup_printf(_("error saving config file: %s\nerror: %s\n"), rc_path,
500 secsave_strerror(secsave_errno));
512 *-----------------------------------------------------------------------------
513 * load configuration (public)
514 *-----------------------------------------------------------------------------
517 void load_options(void)
525 gchar value_all[1024];
528 for (i = 0; ExifUIList[i].key; i++)
529 ExifUIList[i].current = ExifUIList[i].default_value;
531 rc_path = g_strconcat(homedir(), "/", GQ_RC_DIR, "/", RC_FILE_NAME, NULL);
533 rc_pathl = path_from_utf8(rc_path);
534 f = fopen(rc_pathl,"r");
542 while (fgets(s_buf, sizeof(s_buf), f))
544 gchar *option_start, *value_start;
547 while(g_ascii_isspace(*p)) p++;
548 if (!*p || *p == '\n' || *p == '#') continue;
550 while(*p && *p != ':') p++;
554 strncpy(option, option_start, sizeof(option));
555 while(g_ascii_isspace(*p)) p++;
557 strncpy(value_all, value_start, sizeof(value_all));
558 while(*p && !g_ascii_isspace(*p) && *p != '\n') p++;
560 strncpy(value, value_start, sizeof(value));
562 #define READ_BOOL(_name_) read_bool_option(f, option, #_name_, value, &options->_name_)
563 #define READ_INT(_name_) read_int_option(f, option, #_name_, value, &options->_name_)
564 #define READ_UINT(_name_) read_uint_option(f, option, #_name_, value, &options->_name_)
565 #define READ_INT_CLAMP(_name_, _min_, _max_) read_int_option_clamp(f, option, #_name_, value, &options->_name_, _min_, _max_)
566 #define READ_INT_UNIT(_name_, _unit_) read_int_unit_option(f, option, #_name_, value, &options->_name_, _unit_)
567 #define READ_CHAR(_name_) read_char_option(f, option, #_name_, value_all, &options->_name_)
568 #define READ_COLOR(_name_) read_color_option(f, option, #_name_, value, &options->_name_)
570 /* general options */
571 READ_BOOL(show_icon_names);
572 READ_BOOL(show_icon_names);
574 READ_BOOL(tree_descend_subdirs);
575 READ_BOOL(lazy_image_sync);
576 READ_BOOL(update_on_time_change);
578 READ_BOOL(startup_path_enable);
579 READ_CHAR(startup_path);
581 READ_INT(duplicates_similarity_threshold);
583 READ_BOOL(progressive_key_scrolling);
585 READ_BOOL(enable_metadata_dirs);
587 READ_BOOL(mousewheel_scrolls);
589 READ_INT(open_recent_list_maxsize);
591 READ_BOOL(place_dialogs_under_mouse);
596 READ_INT(layout.style);
597 READ_CHAR(layout.order);
598 READ_BOOL(layout.view_as_icons);
599 READ_BOOL(layout.view_as_tree);
600 READ_BOOL(layout.show_thumbnails);
602 /* window positions */
604 READ_BOOL(layout.save_window_positions);
606 READ_INT(layout.main_window.x);
607 READ_INT(layout.main_window.y);
608 READ_INT(layout.main_window.w);
609 READ_INT(layout.main_window.h);
610 READ_BOOL(layout.main_window.maximized);
611 READ_INT(layout.float_window.x);
612 READ_INT(layout.float_window.y);
613 READ_INT(layout.float_window.w);
614 READ_INT(layout.float_window.h);
615 READ_INT(layout.float_window.vdivider_pos);
616 READ_INT(layout.main_window.hdivider_pos);
617 READ_INT(layout.main_window.vdivider_pos);
618 READ_BOOL(layout.tools_float);
619 READ_BOOL(layout.tools_hidden);
620 READ_BOOL(layout.tools_restore_state);
621 READ_BOOL(layout.toolbar_hidden);
625 if (strcasecmp(option, "image.zoom_mode") == 0)
627 if (strcasecmp(value, "original") == 0) options->image.zoom_mode = ZOOM_RESET_ORIGINAL;
628 if (strcasecmp(value, "fit") == 0) options->image.zoom_mode = ZOOM_RESET_FIT_WINDOW;
629 if (strcasecmp(value, "dont_change") == 0) options->image.zoom_mode = ZOOM_RESET_NONE;
631 READ_BOOL(image.zoom_2pass);
632 READ_BOOL(image.zoom_to_fit_allow_expand);
633 READ_BOOL(image.fit_window_to_image);
634 READ_BOOL(image.limit_window_size);
635 READ_INT(image.max_window_size);
636 READ_BOOL(image.limit_autofit_size);
637 READ_INT(image.max_autofit_size);
638 READ_INT(image.scroll_reset_method);
639 READ_INT(image.tile_cache_max);
640 READ_INT_CLAMP(image.zoom_quality, GDK_INTERP_NEAREST, GDK_INTERP_HYPER);
641 READ_INT_CLAMP(image.dither_quality, GDK_RGB_DITHER_NONE, GDK_RGB_DITHER_MAX);
642 READ_INT(image.zoom_increment);
643 READ_BOOL(image.enable_read_ahead);
644 READ_BOOL(image.exif_rotate_enable);
645 READ_BOOL(image.use_custom_border_color);
646 READ_COLOR(image.border_color);
649 /* thumbnails options */
650 READ_INT_CLAMP(thumbnails.max_width, 16, 512);
651 READ_INT_CLAMP(thumbnails.max_height, 16, 512);
653 READ_BOOL(thumbnails.enable_caching);
654 READ_BOOL(thumbnails.cache_into_dirs);
655 READ_BOOL(thumbnails.fast);
656 READ_BOOL(thumbnails.use_xvpics);
657 READ_BOOL(thumbnails.spec_standard);
658 READ_INT_CLAMP(thumbnails.quality, GDK_INTERP_NEAREST, GDK_INTERP_HYPER);
660 /* file sorting options */
661 READ_UINT(file_sort.method);
662 READ_BOOL(file_sort.ascending);
663 READ_BOOL(file_sort.case_sensitive);
665 /* file operations options */
666 READ_BOOL(file_ops.enable_in_place_rename);
667 READ_BOOL(file_ops.confirm_delete);
668 READ_BOOL(file_ops.enable_delete_key);
669 READ_BOOL(file_ops.safe_delete_enable);
670 READ_CHAR(file_ops.safe_delete_path);
671 READ_INT(file_ops.safe_delete_folder_maxsize);
673 /* fullscreen options */
674 READ_INT(fullscreen.screen);
675 READ_BOOL(fullscreen.clean_flip);
676 READ_BOOL(fullscreen.disable_saver);
677 READ_BOOL(fullscreen.above);
678 READ_BOOL(fullscreen.show_info);
679 READ_CHAR(fullscreen.info);
681 /* slideshow options */
683 READ_INT_UNIT(slideshow.delay, SLIDESHOW_SUBSECOND_PRECISION);
684 READ_BOOL(slideshow.random);
685 READ_BOOL(slideshow.repeat);
687 /* collection options */
689 READ_BOOL(collections.rectangular_selection);
691 /* filtering options */
693 READ_BOOL(file_filter.show_dot_files);
694 READ_BOOL(file_filter.disable);
696 if (strcasecmp(option, "file_filter.ext") == 0)
698 filter_parse(value_all);
701 if (strcasecmp(option, "sidecar.ext") == 0)
703 sidecar_ext_parse(value_all, TRUE);
708 READ_BOOL(color_profile.enabled);
709 READ_BOOL(color_profile.use_image);
710 READ_INT(color_profile.input_type);
712 if (strncasecmp(option, "color_profile.input_file_", 25) == 0)
714 i = strtol(option + 25, NULL, 0) - 1;
715 if (i >= 0 && i < COLOR_PROFILE_INPUTS)
717 read_char_option(f, option, option, value, &options->color_profile.input_file[i]);
720 if (strncasecmp(option, "color_profile.input_name_", 25) == 0)
722 i = strtol(option + 25, NULL, 0) - 1;
723 if (i >= 0 && i < COLOR_PROFILE_INPUTS)
725 read_char_option(f, option, option, value, &options->color_profile.input_name[i]);
729 READ_INT(color_profile.screen_type);
730 READ_CHAR(color_profile.screen_file);
732 /* External Programs */
734 if (strncasecmp(option, "external_", 9) == 0)
736 i = strtol(option + 9, NULL, 0);
737 if (i > 0 && i <= GQ_EDITOR_SLOTS)
741 g_free(options->editor_name[i]);
742 g_free(options->editor_command[i]);
744 options->editor_name[i] = quoted_value(value_all, &ptr);
745 options->editor_command[i] = quoted_value(ptr, NULL);
750 if (0 == strncasecmp(option, "exif.display.", 13))
752 for (i = 0; ExifUIList[i].key; i++)
753 if (0 == strcasecmp(option + 13, ExifUIList[i].key))
754 ExifUIList[i].current = strtol(value, NULL, 10);