Merge branch '2170_separate_colors'
[pantumic.git] / src / setup.c
bloba0a20487d47e5a718a85fdab517255543f8cf197
1 /* Setup loading/saving.
2 Copyright (C) 1994, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
19 /** \file setup.c
20 * \brief Source: setup loading/saving
23 #include <config.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdio.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
31 #include "lib/global.h"
33 #include "lib/tty/tty.h"
34 #include "lib/tty/key.h"
35 #include "lib/mcconfig.h"
36 #include "lib/fileloc.h"
37 #include "lib/util.h" /* time formats */
39 #include "lib/vfs/mc-vfs/vfs.h"
41 #ifdef ENABLE_VFS_FTP
42 #include "lib/vfs/mc-vfs/ftpfs.h"
43 #endif
44 #ifdef ENABLE_VFS_FISH
45 #include "lib/vfs/mc-vfs/fish.h"
46 #endif
48 #include "args.h"
49 #include "dir.h"
50 #include "panel.h"
51 #include "main.h"
52 #include "tree.h" /* xtree_mode */
53 #include "hotlist.h" /* load/save/done hotlist */
54 #include "panelize.h" /* load/save/done panelize */
55 #include "layout.h"
56 #include "menu.h" /* menubar_visible declaration */
57 #include "cmd.h"
58 #include "file.h" /* safe_delete */
59 #include "keybind.h" /* lookup_action */
60 #include "wtools.h"
62 #ifdef HAVE_CHARSET
63 #include "charsets.h"
64 #endif
66 #ifdef USE_INTERNAL_EDIT
67 #include "src/editor/edit.h"
68 #endif
70 #include "src/viewer/mcviewer.h" /* For the externs */
72 #include "setup.h"
74 /*** global variables **************************************************/
76 char *profile_name; /* .mc/ini */
77 char *global_profile_name; /* mc.lib */
79 char *setup_color_string;
80 char *term_color_string;
81 char *color_terminal_string;
83 panel_view_mode_t startup_left_mode;
84 panel_view_mode_t startup_right_mode;
86 int setup_copymove_persistent_attr = 1;
88 /* Tab size */
89 int option_tab_spacing = DEFAULT_TAB_SPACING;
91 /* Ugly hack to allow panel_save_setup to work as a place holder for */
92 /* default panel values */
93 int saving_setup;
95 panels_options_t panels_options = {
96 .kilobyte_si = FALSE,
97 .mix_all_files = FALSE,
98 .show_backups = TRUE,
99 .show_dot_files = TRUE,
100 .fast_reload = FALSE,
101 .fast_reload_msg_shown = FALSE,
102 .mark_moves_down = TRUE,
103 .reverse_files_only = TRUE,
104 .auto_save_setup = FALSE,
105 .navigate_with_arrows = FALSE,
106 .scroll_pages = TRUE,
107 .mouse_move_pages = TRUE,
108 .filetype_mode = TRUE,
109 .permission_mode = FALSE,
110 .qsearch_mode = QSEARCH_PANEL_CASE
113 /*** file scope macro definitions **************************************/
115 /* In order to use everywhere the same setup for the locale we use defines */
116 #define FMTYEAR _("%b %e %Y")
117 #define FMTTIME _("%b %e %H:%M")
119 /*** file scope type declarations **************************************/
121 /*** file scope variables **********************************************/
123 static char *panels_profile_name = NULL; /* .mc/panels.ini */
125 /* *INDENT-OFF* */
126 static const struct
128 const char *key;
129 int list_type;
130 } list_types [] = {
131 { "full", list_full },
132 { "brief", list_brief },
133 { "long", list_long },
134 { "user", list_user },
135 { NULL, 0 }
138 static const struct
140 const char *opt_name;
141 panel_view_mode_t opt_type;
142 } panel_types [] = {
143 { "listing", view_listing },
144 { "quickview", view_quick },
145 { "info", view_info },
146 { "tree", view_tree },
147 { NULL, view_listing }
150 static const struct
152 const char *opt_name;
153 int *opt_addr;
154 } layout [] = {
155 { "equal_split", &equal_split },
156 { "first_panel_size", &first_panel_size },
157 { "message_visible", &message_visible },
158 { "keybar_visible", &keybar_visible },
159 { "xterm_title", &xterm_title },
160 { "output_lines", &output_lines },
161 { "command_prompt", &command_prompt },
162 { "menubar_visible", &menubar_visible },
163 { "show_mini_info", &show_mini_info },
164 { "free_space", &free_space },
165 { NULL, NULL }
168 static const struct
170 const char *opt_name;
171 int *opt_addr;
172 } int_options [] = {
173 { "verbose", &verbose },
174 { "pause_after_run", &pause_after_run },
175 { "shell_patterns", &easy_patterns },
176 { "auto_save_setup", &auto_save_setup },
177 { "auto_menu", &auto_menu },
178 { "use_internal_view", &use_internal_view },
179 { "use_internal_edit", &use_internal_edit },
180 { "clear_before_exec", &clear_before_exec },
181 { "confirm_delete", &confirm_delete },
182 { "confirm_overwrite", &confirm_overwrite },
183 { "confirm_execute", &confirm_execute },
184 { "confirm_history_cleanup", &confirm_history_cleanup },
185 { "confirm_exit", &confirm_exit },
186 { "confirm_directory_hotlist_delete", &confirm_directory_hotlist_delete },
187 { "safe_delete", &safe_delete },
188 { "mouse_repeat_rate", &mou_auto_repeat },
189 { "double_click_speed", &double_click_speed },
190 #ifndef HAVE_CHARSET
191 { "eight_bit_clean", &eight_bit_clean },
192 { "full_eight_bits", &full_eight_bits },
193 #endif /* !HAVE_CHARSET */
194 { "use_8th_bit_as_meta", &use_8th_bit_as_meta },
195 { "confirm_view_dir", &confirm_view_dir },
196 { "mouse_move_pages_viewer", &mcview_mouse_move_pages },
197 { "mouse_close_dialog", &mouse_close_dialog},
198 { "fast_refresh", &fast_refresh },
199 { "drop_menus", &drop_menus },
200 { "wrap_mode", &mcview_global_wrap_mode},
201 { "old_esc_mode", &old_esc_mode },
202 { "old_esc_mode_timeout", &old_esc_mode_timeout },
203 { "cd_symlinks", &cd_symlinks },
204 { "show_all_if_ambiguous", &show_all_if_ambiguous },
205 { "max_dirt_limit", &mcview_max_dirt_limit },
206 { "torben_fj_mode", &torben_fj_mode },
207 { "use_file_to_guess_type", &use_file_to_check_type },
208 { "alternate_plus_minus", &alternate_plus_minus },
209 { "only_leading_plus_minus", &only_leading_plus_minus },
210 { "show_output_starts_shell", &output_starts_shell },
211 { "xtree_mode", &xtree_mode },
212 { "num_history_items_recorded", &num_history_items_recorded },
213 { "file_op_compute_totals", &file_op_compute_totals },
214 { "classic_progressbar", &classic_progressbar},
215 #ifdef ENABLE_VFS
216 { "vfs_timeout", &vfs_timeout },
217 #ifdef ENABLE_VFS_FTP
218 { "ftpfs_directory_timeout", &ftpfs_directory_timeout },
219 { "use_netrc", &ftpfs_use_netrc },
220 { "ftpfs_retry_seconds", &ftpfs_retry_seconds },
221 { "ftpfs_always_use_proxy", &ftpfs_always_use_proxy },
222 { "ftpfs_use_passive_connections", &ftpfs_use_passive_connections },
223 { "ftpfs_use_passive_connections_over_proxy", &ftpfs_use_passive_connections_over_proxy },
224 { "ftpfs_use_unix_list_options", &ftpfs_use_unix_list_options },
225 { "ftpfs_first_cd_then_ls", &ftpfs_first_cd_then_ls },
226 #endif /* ENABLE_VFS_FTP */
227 #ifdef ENABLE_VFS_FISH
228 { "fish_directory_timeout", &fish_directory_timeout },
229 #endif /* ENABLE_VFS_FISH */
230 #endif /* ENABLE_VFS */
231 /* option_tab_spacing is used in internal viewer */
232 { "editor_tab_spacing", &option_tab_spacing },
233 #ifdef USE_INTERNAL_EDIT
234 { "editor_word_wrap_line_length", &option_word_wrap_line_length },
235 { "editor_fill_tabs_with_spaces", &option_fill_tabs_with_spaces },
236 { "editor_return_does_auto_indent", &option_return_does_auto_indent },
237 { "editor_backspace_through_tabs", &option_backspace_through_tabs },
238 { "editor_fake_half_tabs", &option_fake_half_tabs },
239 { "editor_option_save_mode", &option_save_mode },
240 { "editor_option_save_position", &option_save_position },
241 { "editor_option_auto_para_formatting", &option_auto_para_formatting },
242 { "editor_option_typewriter_wrap", &option_typewriter_wrap },
243 { "editor_edit_confirm_save", &edit_confirm_save },
244 { "editor_syntax_highlighting", &option_syntax_highlighting },
245 { "editor_persistent_selections", &option_persistent_selections },
246 { "editor_cursor_beyond_eol", &option_cursor_beyond_eol },
247 { "editor_visible_tabs", &visible_tabs },
248 { "editor_visible_spaces", &visible_tws },
249 { "editor_line_state", &option_line_state },
250 { "editor_simple_statusbar", &simple_statusbar },
251 { "editor_check_new_line", &option_check_nl_at_eof },
252 { "editor_show_right_margin", &show_right_margin },
253 #endif /* USE_INTERNAL_EDIT */
254 { "nice_rotating_dash", &nice_rotating_dash },
255 { "horizontal_split", &horizontal_split },
256 { "mcview_remember_file_position", &mcview_remember_file_position },
257 { "auto_fill_mkdir_name", &auto_fill_mkdir_name },
258 { "copymove_persistent_attr", &setup_copymove_persistent_attr },
259 { "select_flags", &select_flags },
260 { NULL, NULL }
263 static const struct
265 const char *opt_name;
266 char **opt_addr;
267 const char *opt_defval;
268 } str_options[] = {
269 #ifdef USE_INTERNAL_EDIT
270 { "editor_backup_extension", &option_backup_ext, "~" },
271 #endif
272 { "mcview_eof", &mcview_show_eof, "" },
273 { NULL, NULL, NULL }
276 static const struct
278 const char *opt_name;
279 const char *opt_old_name;
280 gboolean *opt_addr;
281 } panels_ini_options[] = {
282 { "kilobyte_si", NULL, &panels_options.kilobyte_si },
283 { "mix_all_files", NULL, &panels_options.mix_all_files },
284 { "show_backups", NULL, &panels_options.show_backups },
285 { "show_dot_files", NULL, &panels_options.show_dot_files },
286 { "fast_reload", NULL, &panels_options.fast_reload },
287 { "fast_reload_msg_shown", NULL, &panels_options.fast_reload_msg_shown },
288 { "mark_moves_down", NULL, &panels_options.mark_moves_down },
289 { "reverse_files_only", NULL, &panels_options.reverse_files_only },
290 { "auto_save_setup_panels", "auto_save_setup", &panels_options.auto_save_setup },
291 { "navigate_with_arrows", NULL, &panels_options.navigate_with_arrows },
292 { "panel_scroll_pages", "scroll_pages", &panels_options.scroll_pages },
293 { "mouse_move_pages", NULL, &panels_options.mouse_move_pages },
294 { "filetype_mode", NULL, &panels_options.filetype_mode },
295 { "permission_mode", NULL, &panels_options.permission_mode },
296 { NULL, NULL, NULL }
298 /* *INDENT-ON* */
300 static const char *panels_section = "Panels";
302 /*** file scope functions **********************************************/
305 Get name of config file.
307 \param subdir
308 if not NULL, then config also search into specified subdir.
310 \param config_file_name
311 If specified filename is relative, then will search in standart patches.
313 \return
314 Newly allocated path to config name or NULL if file not found.
316 If config_file_name is a relative path, then search config in stantart pathes.
318 static char *
319 load_setup_get_full_config_name (const char *subdir, const char *config_file_name)
322 TODO: IMHO, in future this function must be placed into mc_config module.
323 Also, need to rename stupid mc_home and mc_home_alt to mc_sysconfdir and mc_datadir;
324 home_mc => mc_user_homedir
326 char *lc_basename, *ret;
328 if (config_file_name == NULL)
329 return NULL;
331 if (g_path_is_absolute (config_file_name))
332 return g_strdup (config_file_name);
335 lc_basename = g_path_get_basename (config_file_name);
336 if (lc_basename == NULL)
337 return NULL;
339 if (subdir != NULL)
340 ret = g_build_filename (home_dir, MC_USERCONF_DIR, subdir, lc_basename, NULL);
341 else
342 ret = g_build_filename (home_dir, MC_USERCONF_DIR, lc_basename, NULL);
344 if (exist_file (ret))
346 g_free (lc_basename);
347 return ret;
349 g_free (ret);
351 if (subdir != NULL)
352 ret = g_build_filename (mc_home, subdir, lc_basename, NULL);
353 else
354 ret = g_build_filename (mc_home, lc_basename, NULL);
356 if (exist_file (ret))
358 g_free (lc_basename);
359 return ret;
361 g_free (ret);
363 if (subdir != NULL)
364 ret = g_build_filename (mc_home_alt, subdir, lc_basename, NULL);
365 else
366 ret = g_build_filename (mc_home_alt, lc_basename, NULL);
368 g_free (lc_basename);
370 if (exist_file (ret))
371 return ret;
373 g_free (ret);
374 return NULL;
378 static const char *
379 setup__is_cfg_group_must_panel_config (const char *grp)
381 return (!strcasecmp ("Dirs", grp) ||
382 !strcasecmp ("Temporal:New Right Panel", grp) ||
383 !strcasecmp ("Temporal:New Left Panel", grp) ||
384 !strcasecmp ("New Left Panel", grp) || !strcasecmp ("New Right Panel", grp))
385 ? grp : NULL;
388 static void
389 setup__move_panels_config_into_separate_file (const char *profile)
391 mc_config_t *tmp_cfg;
392 char **groups, **curr_grp;
393 const char *need_grp;
395 if (!exist_file (profile))
396 return;
398 tmp_cfg = mc_config_init (profile);
399 if (!tmp_cfg)
400 return;
402 curr_grp = groups = mc_config_get_groups (tmp_cfg, NULL);
403 if (!groups)
405 mc_config_deinit (tmp_cfg);
406 return;
409 while (*curr_grp)
411 if (setup__is_cfg_group_must_panel_config (*curr_grp) == NULL)
412 mc_config_del_group (tmp_cfg, *curr_grp);
413 curr_grp++;
416 mc_config_save_to_file (tmp_cfg, panels_profile_name, NULL);
417 mc_config_deinit (tmp_cfg);
419 tmp_cfg = mc_config_init (profile);
420 if (!tmp_cfg)
422 g_strfreev (groups);
423 return;
426 curr_grp = groups;
428 while (*curr_grp)
430 need_grp = setup__is_cfg_group_must_panel_config (*curr_grp);
431 if (need_grp != NULL)
433 mc_config_del_group (tmp_cfg, need_grp);
435 curr_grp++;
437 g_strfreev (groups);
439 mc_config_save_file (tmp_cfg, NULL);
440 mc_config_deinit (tmp_cfg);
444 Create new mc_config object from specified ini-file or
445 append data to existing mc_config object from ini-file
448 static void
449 load_setup_init_config_from_file (mc_config_t ** config, const char *fname)
452 TODO: IMHO, in future this function must be placed into mc_config module.
454 if (exist_file (fname))
456 if (*config != NULL)
457 mc_config_read_file (*config, fname);
458 else
459 *config = mc_config_init (fname);
463 static void
464 load_layout (void)
466 size_t i;
468 for (i = 0; layout[i].opt_name != NULL; i++)
469 *layout[i].opt_addr = mc_config_get_int (mc_main_config, "Layout",
470 layout[i].opt_name, *layout[i].opt_addr);
473 static void
474 load_keys_from_section (const char *terminal, mc_config_t * cfg)
476 char *section_name;
477 gchar **profile_keys, **keys;
478 gchar **values, **curr_values;
479 char *valcopy, *value;
480 long key_code;
481 gsize len, values_len;
483 if (terminal == NULL)
484 return;
486 section_name = g_strconcat ("terminal:", terminal, (char *) NULL);
487 profile_keys = keys = mc_config_get_keys (cfg, section_name, &len);
489 while (*profile_keys != NULL)
491 /* copy=other causes all keys from [terminal:other] to be loaded. */
492 if (g_ascii_strcasecmp (*profile_keys, "copy") == 0)
494 valcopy = mc_config_get_string (cfg, section_name, *profile_keys, "");
495 load_keys_from_section (valcopy, cfg);
496 g_free (valcopy);
497 profile_keys++;
498 continue;
501 curr_values = values =
502 mc_config_get_string_list (cfg, section_name, *profile_keys, &values_len);
504 key_code = lookup_key (*profile_keys, NULL);
506 if (key_code != 0)
508 if (curr_values != NULL)
510 while (*curr_values != NULL)
512 valcopy = convert_controls (*curr_values);
513 define_sequence (key_code, valcopy, MCKEY_NOACTION);
514 g_free (valcopy);
515 curr_values++;
518 else
520 value = mc_config_get_string (cfg, section_name, *profile_keys, "");
521 valcopy = convert_controls (value);
522 define_sequence (key_code, valcopy, MCKEY_NOACTION);
523 g_free (valcopy);
524 g_free (value);
528 profile_keys++;
530 if (values != NULL)
531 g_strfreev (values);
533 g_strfreev (keys);
534 g_free (section_name);
537 static void
538 load_keymap_from_section (const char *section_name, GArray * keymap, mc_config_t * cfg)
540 gchar **profile_keys, **keys;
541 gchar **values, **curr_values;
542 char *valcopy, *value;
543 int action;
544 gsize len, values_len;
546 if (section_name == NULL)
547 return;
549 profile_keys = keys = mc_config_get_keys (cfg, section_name, &len);
551 while (*profile_keys != NULL)
553 curr_values = values =
554 mc_config_get_string_list (cfg, section_name, *profile_keys, &values_len);
556 action = lookup_action (*profile_keys);
558 if (action > 0)
560 if (curr_values != NULL)
562 while (*curr_values != NULL)
564 valcopy = convert_controls (*curr_values);
565 keybind_cmd_bind (keymap, valcopy, action);
566 g_free (valcopy);
567 curr_values++;
570 else
572 value = mc_config_get_string (cfg, section_name, *profile_keys, "");
573 valcopy = convert_controls (value);
574 /* define_sequence (key_code, valcopy, MCKEY_NOACTION); */
575 g_free (valcopy);
576 g_free (value);
580 profile_keys++;
582 if (values != NULL)
583 g_strfreev (values);
585 g_strfreev (keys);
588 static mc_config_t *
589 load_setup_get_keymap_profile_config (void)
592 TODO: IMHO, in future this function must be placed into mc_config module.
594 mc_config_t *keymap_config = NULL;
595 char *fname, *fname2;
597 /* 1) /usr/share/mc (mc_home_alt) */
598 fname = g_build_filename (mc_home_alt, GLOBAL_KEYMAP_FILE, NULL);
599 load_setup_init_config_from_file (&keymap_config, fname);
600 g_free (fname);
602 /* 2) /etc/mc (mc_home) */
603 fname = g_build_filename (mc_home, GLOBAL_KEYMAP_FILE, NULL);
604 load_setup_init_config_from_file (&keymap_config, fname);
605 g_free (fname);
607 /* 3) ~/.mc (home_dir?) */
608 fname = g_build_filename (home_dir, MC_USERCONF_DIR, GLOBAL_KEYMAP_FILE, NULL);
609 load_setup_init_config_from_file (&keymap_config, fname);
610 g_free (fname);
612 /* 4) main config; [Midnight Commander] -> keymap */
614 fname2 =
615 mc_config_get_string (mc_main_config, CONFIG_APP_SECTION, "keymap", GLOBAL_KEYMAP_FILE);
616 fname = load_setup_get_full_config_name (NULL, fname2);
617 if (fname != NULL)
619 load_setup_init_config_from_file (&keymap_config, fname);
620 g_free (fname);
622 g_free (fname2);
624 /* 5) getenv("MC_KEYMAP") */
625 fname = load_setup_get_full_config_name (NULL, g_getenv ("MC_KEYMAP"));
626 if (fname != NULL)
628 load_setup_init_config_from_file (&keymap_config, fname);
629 g_free (fname);
632 /* 6) --keymap=<keymap> */
633 fname = load_setup_get_full_config_name (NULL, mc_args__keymap_file);
634 if (fname != NULL)
636 load_setup_init_config_from_file (&keymap_config, fname);
637 g_free (fname);
640 return keymap_config;
643 static panel_view_mode_t
644 setup__load_panel_state (const char *section)
646 char *buffer;
647 size_t i;
648 panel_view_mode_t mode = view_listing;
650 /* Load the display mode */
651 buffer = mc_config_get_string (mc_panels_config, section, "display", "listing");
653 for (i = 0; panel_types[i].opt_name != NULL; i++)
654 if (g_ascii_strcasecmp (panel_types[i].opt_name, buffer) == 0)
656 mode = panel_types[i].opt_type;
657 break;
660 g_free (buffer);
662 return mode;
665 static void
666 panel_save_type (const char *section, panel_view_mode_t type)
668 size_t i;
670 for (i = 0; panel_types[i].opt_name != NULL; i++)
671 if (panel_types[i].opt_type == type)
673 mc_config_set_string (mc_panels_config, section, "display", panel_types[i].opt_name);
674 break;
678 /*** public functions **************************************************/
680 char *
681 setup_init (void)
683 char *profile;
684 char *inifile;
686 if (profile_name != NULL)
687 return profile_name;
689 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
690 if (!exist_file (profile))
692 inifile = concat_dir_and_file (mc_home, "mc.ini");
693 if (exist_file (inifile))
695 g_free (profile);
696 profile = inifile;
698 else
700 g_free (inifile);
701 inifile = concat_dir_and_file (mc_home_alt, "mc.ini");
702 if (exist_file (inifile))
704 g_free (profile);
705 profile = inifile;
707 else
708 g_free (inifile);
712 profile_name = profile;
714 return profile;
717 void
718 load_setup (void)
720 char *profile;
721 size_t i;
722 char *buffer;
723 const char *kt;
724 #ifdef HAVE_CHARSET
725 int cpages = -1;
727 cpages = load_codepages_list ();
728 #endif /* HAVE_CHARSET */
730 profile = setup_init ();
732 /* mc.lib is common for all users, but has priority lower than
733 ~/.mc/ini. FIXME: it's only used for keys and treestore now */
734 global_profile_name = concat_dir_and_file (mc_home, MC_GLOBAL_CONFIG_FILE);
735 if (!exist_file (global_profile_name))
737 g_free (global_profile_name);
738 global_profile_name = concat_dir_and_file (mc_home_alt, MC_GLOBAL_CONFIG_FILE);
741 panels_profile_name = g_build_filename (home_dir, MC_USERCONF_DIR, MC_PANELS_FILE, NULL);
743 mc_main_config = mc_config_init (profile);
745 if (!exist_file (panels_profile_name))
746 setup__move_panels_config_into_separate_file (profile);
748 mc_panels_config = mc_config_init (panels_profile_name);
750 /* Load integer boolean options */
751 for (i = 0; int_options[i].opt_name != NULL; i++)
752 *int_options[i].opt_addr =
753 mc_config_get_int (mc_main_config, CONFIG_APP_SECTION, int_options[i].opt_name,
754 *int_options[i].opt_addr);
756 if (option_tab_spacing <= 0)
757 option_tab_spacing = DEFAULT_TAB_SPACING;
759 #ifdef USE_INTERNAL_EDIT
760 if (option_word_wrap_line_length <= 0)
761 option_word_wrap_line_length = DEFAULT_WRAP_LINE_LENGTH;
762 #endif /* USE_INTERNAL_EDIT */
764 /* overwrite old_esc_mode_timeout */
765 kt = getenv ("KEYBOARD_KEY_TIMEOUT_US");
766 if ((kt != NULL) && (kt[0] != '\0'))
767 old_esc_mode_timeout = atoi (kt);
769 /* Load string options */
770 for (i = 0; str_options[i].opt_name != NULL; i++)
771 *str_options[i].opt_addr =
772 mc_config_get_string (mc_main_config, CONFIG_APP_SECTION, str_options[i].opt_name,
773 str_options[i].opt_defval);
775 load_layout ();
776 panels_load_options ();
777 load_panelize ();
779 startup_left_mode = setup__load_panel_state ("New Left Panel");
780 startup_right_mode = setup__load_panel_state ("New Right Panel");
782 /* At least one of the panels is a listing panel */
783 if (startup_left_mode != view_listing && startup_right_mode != view_listing)
784 startup_left_mode = view_listing;
786 if (mc_run_param1 == NULL)
788 buffer = mc_config_get_string (mc_panels_config, "Dirs", "other_dir", ".");
789 if (vfs_file_is_local (buffer))
790 mc_run_param1 = buffer;
791 else
792 g_free (buffer);
795 boot_current_is_left = mc_config_get_int (mc_panels_config, "Dirs", "current_is_left", 1);
797 /* Load time formats */
798 user_recent_timeformat =
799 mc_config_get_string (mc_main_config, "Misc", "timeformat_recent", FMTTIME);
800 user_old_timeformat = mc_config_get_string (mc_main_config, "Misc", "timeformat_old", FMTYEAR);
802 #ifdef ENABLE_VFS_FTP
803 ftpfs_proxy_host = mc_config_get_string (mc_main_config, "Misc", "ftp_proxy_host", "gate");
804 ftpfs_ignore_chattr_errors = mc_config_get_bool (mc_main_config, CONFIG_APP_SECTION,
805 "ignore_ftp_chattr_errors", TRUE);
806 ftpfs_init_passwd ();
807 #endif /* ENABLE_VFS_FTP */
809 /* The default color and the terminal dependent color */
810 setup_color_string = mc_config_get_string (mc_main_config, "Colors", "base_color", "");
811 term_color_string = mc_config_get_string (mc_main_config, "Colors", getenv ("TERM"), "");
812 color_terminal_string = mc_config_get_string (mc_main_config, "Colors", "color_terminals", "");
814 /* Load the directory history */
815 /* directory_history_load (); */
816 /* Remove the temporal entries */
818 #ifdef HAVE_CHARSET
819 if (cpages > 0)
821 buffer = mc_config_get_string (mc_main_config, "Misc", "display_codepage", "");
822 if (buffer[0] != '\0')
824 display_codepage = get_codepage_index (buffer);
825 cp_display = get_codepage_id (display_codepage);
827 g_free (buffer);
828 buffer = mc_config_get_string (mc_main_config, "Misc", "source_codepage", "");
829 if (buffer[0] != '\0')
831 default_source_codepage = get_codepage_index (buffer);
832 source_codepage = default_source_codepage; /* May be source_codepage doesn't need this */
833 cp_source = get_codepage_id (source_codepage);
835 g_free (buffer);
838 autodetect_codeset = mc_config_get_string (mc_main_config, "Misc", "autodetect_codeset", "");
839 if ((autodetect_codeset[0] != '\0') && (strcmp (autodetect_codeset, "off") != 0))
840 is_autodetect_codeset_enabled = TRUE;
842 g_free (init_translation_table (source_codepage, display_codepage));
843 buffer = (char *) get_codepage_id (display_codepage);
844 if (buffer != NULL)
845 utf8_display = str_isutf8 (buffer);
846 #endif /* HAVE_CHARSET */
848 clipboard_store_path = mc_config_get_string (mc_main_config, "Misc", "clipboard_store", "");
849 clipboard_paste_path = mc_config_get_string (mc_main_config, "Misc", "clipboard_paste", "");
852 gboolean
853 save_setup (void)
855 char *tmp_profile;
856 gboolean ret;
858 saving_setup = 1;
860 save_config ();
861 save_layout ();
862 panels_save_options ();
863 save_hotlist ();
864 save_panelize ();
865 save_panel_types ();
866 /* directory_history_save (); */
868 #ifdef ENABLE_VFS_FTP
869 mc_config_set_string (mc_main_config, "Misc", "ftpfs_password", ftpfs_anonymous_passwd);
870 if (ftpfs_proxy_host)
871 mc_config_set_string (mc_main_config, "Misc", "ftp_proxy_host", ftpfs_proxy_host);
872 #endif /* ENABLE_VFS_FTP */
874 #ifdef HAVE_CHARSET
875 mc_config_set_string (mc_main_config, "Misc", "display_codepage",
876 get_codepage_id (display_codepage));
877 mc_config_set_string (mc_main_config, "Misc", "source_codepage",
878 get_codepage_id (default_source_codepage));
879 mc_config_set_string (mc_main_config, "Misc", "autodetect_codeset", autodetect_codeset);
880 #endif /* HAVE_CHARSET */
881 mc_config_set_string (mc_main_config, "Misc", "clipboard_store", clipboard_store_path);
882 mc_config_set_string (mc_main_config, "Misc", "clipboard_paste", clipboard_paste_path);
884 tmp_profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
885 ret = mc_config_save_to_file (mc_main_config, tmp_profile, NULL);
887 g_free (tmp_profile);
888 saving_setup = 0;
889 return ret;
892 void
893 done_setup (void)
895 size_t i;
897 g_free (profile_name);
898 g_free (global_profile_name);
899 g_free (color_terminal_string);
900 g_free (term_color_string);
901 g_free (setup_color_string);
902 g_free (panels_profile_name);
903 mc_config_deinit (mc_main_config);
904 mc_config_deinit (mc_panels_config);
906 g_free (user_recent_timeformat);
907 g_free (user_old_timeformat);
909 for (i = 0; str_options[i].opt_name != NULL; i++)
910 g_free (*str_options[i].opt_addr);
912 done_hotlist ();
913 done_panelize ();
914 /* directory_history_free (); */
917 void
918 save_config (void)
920 char *profile;
921 GError *error = NULL;
922 size_t i;
924 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
926 /* Save integer options */
927 for (i = 0; int_options[i].opt_name != NULL; i++)
928 mc_config_set_int (mc_main_config, CONFIG_APP_SECTION, int_options[i].opt_name,
929 *int_options[i].opt_addr);
931 /* Save string options */
932 for (i = 0; str_options[i].opt_name != NULL; i++)
933 mc_config_set_string (mc_main_config, CONFIG_APP_SECTION, str_options[i].opt_name,
934 *str_options[i].opt_addr);
936 if (!mc_config_save_to_file (mc_main_config, profile, &error))
937 setup_save_config_show_error (profile, &error);
939 g_free (profile);
942 void
943 setup_save_config_show_error (const char *filename, GError ** error)
945 if (error != NULL && *error != NULL)
947 message (D_ERROR, MSG_ERROR, _("Cannot save file %s:\n%s"), filename, (*error)->message);
948 g_error_free (*error);
949 *error = NULL;
953 void
954 save_layout (void)
956 char *profile;
957 size_t i;
959 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
960 /* Save integer options */
961 for (i = 0; layout[i].opt_name != NULL; i++)
962 mc_config_set_int (mc_main_config, "Layout", layout[i].opt_name, *layout[i].opt_addr);
963 mc_config_save_to_file (mc_main_config, profile, NULL);
964 g_free (profile);
967 void
968 load_key_defs (void)
971 * Load keys from mc.lib before ~/.mc/ini, so that the user
972 * definitions override global settings.
974 mc_config_t *mc_global_config;
976 mc_global_config = mc_config_init (global_profile_name);
977 if (mc_global_config != NULL)
979 load_keys_from_section ("general", mc_global_config);
980 load_keys_from_section (getenv ("TERM"), mc_global_config);
981 mc_config_deinit (mc_global_config);
984 load_keys_from_section ("general", mc_main_config);
985 load_keys_from_section (getenv ("TERM"), mc_main_config);
988 #ifdef ENABLE_VFS_FTP
989 char *
990 load_anon_passwd (void)
992 char *buffer;
994 buffer = mc_config_get_string (mc_main_config, "Misc", "ftpfs_password", "");
996 if ((buffer != NULL) && (buffer[0] != '\0'))
997 return buffer;
999 g_free (buffer);
1000 return NULL;
1002 #endif /* ENABLE_VFS_FTP */
1004 void
1005 load_keymap_defs (void)
1008 * Load keymap from GLOBAL_KEYMAP_FILE before ~/.mc/keymap, so that the user
1009 * definitions override global settings.
1011 mc_config_t *mc_global_keymap;
1013 mc_global_keymap = load_setup_get_keymap_profile_config ();
1015 if (mc_global_keymap != NULL)
1017 #ifdef USE_INTERNAL_EDIT
1018 editor_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1019 load_keymap_from_section ("editor", editor_keymap, mc_global_keymap);
1020 editor_x_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1021 load_keymap_from_section ("editor:xmap", editor_x_keymap, mc_global_keymap);
1022 #endif
1024 viewer_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1025 load_keymap_from_section ("viewer", viewer_keymap, mc_global_keymap);
1026 viewer_hex_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1027 load_keymap_from_section ("viewer:hex", viewer_hex_keymap, mc_global_keymap);
1029 main_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1030 load_keymap_from_section ("main", main_keymap, mc_global_keymap);
1031 main_x_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1032 load_keymap_from_section ("main:xmap", main_x_keymap, mc_global_keymap);
1034 panel_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1035 load_keymap_from_section ("panel", panel_keymap, mc_global_keymap);
1037 input_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1038 load_keymap_from_section ("input", input_keymap, mc_global_keymap);
1040 listbox_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1041 load_keymap_from_section ("listbox", listbox_keymap, mc_global_keymap);
1043 tree_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1044 load_keymap_from_section ("tree", tree_keymap, mc_global_keymap);
1046 help_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1047 load_keymap_from_section ("help", help_keymap, mc_global_keymap);
1049 dialog_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1050 load_keymap_from_section ("dialog", dialog_keymap, mc_global_keymap);
1052 #ifdef USE_DIFF_VIEW
1053 diff_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1054 load_keymap_from_section ("diffviewer", diff_keymap, mc_global_keymap);
1055 #endif
1056 mc_config_deinit (mc_global_keymap);
1059 main_map = default_main_map;
1060 if (main_keymap && main_keymap->len > 0)
1061 main_map = (global_keymap_t *) main_keymap->data;
1063 main_x_map = default_main_x_map;
1064 if (main_x_keymap && main_x_keymap->len > 0)
1065 main_x_map = (global_keymap_t *) main_x_keymap->data;
1067 panel_map = default_panel_keymap;
1068 if (panel_keymap && panel_keymap->len > 0)
1069 panel_map = (global_keymap_t *) panel_keymap->data;
1071 input_map = default_input_keymap;
1072 if (input_keymap && input_keymap->len > 0)
1073 input_map = (global_keymap_t *) input_keymap->data;
1075 listbox_map = default_listbox_keymap;
1076 if (listbox_keymap && listbox_keymap->len > 0)
1077 listbox_map = (global_keymap_t *) listbox_keymap->data;
1079 tree_map = default_tree_keymap;
1080 if (tree_keymap && tree_keymap->len > 0)
1081 tree_map = (global_keymap_t *) tree_keymap->data;
1083 help_map = default_help_keymap;
1084 if (help_keymap && help_keymap->len > 0)
1085 help_map = (global_keymap_t *) help_keymap->data;
1087 dialog_map = default_dialog_keymap;
1088 if (dialog_keymap && dialog_keymap->len > 0)
1089 dialog_map = (global_keymap_t *) dialog_keymap->data;
1091 #ifdef USE_DIFF_VIEW
1092 diff_map = default_diff_keymap;
1093 if (diff_keymap && diff_keymap->len > 0)
1094 diff_map = (global_keymap_t *) diff_keymap->data;
1095 #endif
1099 void
1100 free_keymap_defs (void)
1102 #ifdef USE_INTERNAL_EDIT
1103 if (editor_keymap != NULL)
1104 g_array_free (editor_keymap, TRUE);
1105 if (editor_x_keymap != NULL)
1106 g_array_free (editor_x_keymap, TRUE);
1107 #endif
1108 if (viewer_keymap != NULL)
1109 g_array_free (viewer_keymap, TRUE);
1110 if (viewer_hex_keymap != NULL)
1111 g_array_free (viewer_hex_keymap, TRUE);
1112 if (main_keymap != NULL)
1113 g_array_free (main_keymap, TRUE);
1114 if (main_x_keymap != NULL)
1115 g_array_free (main_x_keymap, TRUE);
1116 if (panel_keymap != NULL)
1117 g_array_free (panel_keymap, TRUE);
1118 if (input_keymap != NULL)
1119 g_array_free (input_keymap, TRUE);
1120 if (listbox_keymap != NULL)
1121 g_array_free (listbox_keymap, TRUE);
1122 if (tree_keymap != NULL)
1123 g_array_free (tree_keymap, TRUE);
1124 if (help_keymap != NULL)
1125 g_array_free (help_keymap, TRUE);
1126 if (dialog_keymap != NULL)
1127 g_array_free (dialog_keymap, TRUE);
1128 #ifdef USE_DIFF_VIEW
1129 if (diff_keymap != NULL)
1130 g_array_free (diff_keymap, TRUE);
1131 #endif
1134 void
1135 panel_load_setup (WPanel * panel, const char *section)
1137 size_t i;
1138 char *buffer, buffer2[BUF_TINY];
1140 panel->reverse = mc_config_get_int (mc_panels_config, section, "reverse", 0);
1141 panel->case_sensitive =
1142 mc_config_get_int (mc_panels_config, section, "case_sensitive",
1143 OS_SORT_CASE_SENSITIVE_DEFAULT);
1144 panel->exec_first = mc_config_get_int (mc_panels_config, section, "exec_first", 0);
1146 /* Load sort order */
1147 buffer = mc_config_get_string (mc_panels_config, section, "sort_order", "name");
1148 panel->current_sort_field = panel_get_field_by_id (buffer);
1149 if (panel->current_sort_field == NULL)
1150 panel->current_sort_field = panel_get_field_by_id ("name");
1152 g_free (buffer);
1154 /* Load the listing mode */
1155 buffer = mc_config_get_string (mc_panels_config, section, "list_mode", "full");
1156 panel->list_type = list_full;
1157 for (i = 0; list_types[i].key != NULL; i++)
1158 if (g_ascii_strcasecmp (list_types[i].key, buffer) == 0)
1160 panel->list_type = list_types[i].list_type;
1161 break;
1163 g_free (buffer);
1165 /* User formats */
1166 g_free (panel->user_format);
1167 panel->user_format =
1168 mc_config_get_string (mc_panels_config, section, "user_format", DEFAULT_USER_FORMAT);
1170 for (i = 0; i < LIST_TYPES; i++)
1172 g_free (panel->user_status_format[i]);
1173 g_snprintf (buffer2, BUF_TINY, "user_status%lld", (long long) i);
1174 panel->user_status_format[i] =
1175 mc_config_get_string (mc_panels_config, section, buffer2, DEFAULT_USER_FORMAT);
1178 panel->user_mini_status = mc_config_get_int (mc_panels_config, section, "user_mini_status", 0);
1181 void
1182 panel_save_setup (struct WPanel *panel, const char *section)
1184 char buffer[BUF_TINY];
1185 size_t i;
1187 mc_config_set_int (mc_panels_config, section, "reverse", panel->reverse);
1188 mc_config_set_int (mc_panels_config, section, "case_sensitive", panel->case_sensitive);
1189 mc_config_set_int (mc_panels_config, section, "exec_first", panel->exec_first);
1191 mc_config_set_string (mc_panels_config, section, "sort_order", panel->current_sort_field->id);
1193 for (i = 0; list_types[i].key != NULL; i++)
1194 if (list_types[i].list_type == panel->list_type)
1196 mc_config_set_string (mc_panels_config, section, "list_mode", list_types[i].key);
1197 break;
1200 mc_config_set_string (mc_panels_config, section, "user_format", panel->user_format);
1202 for (i = 0; i < LIST_TYPES; i++)
1204 g_snprintf (buffer, BUF_TINY, "user_status%lld", (long long) i);
1205 mc_config_set_string (mc_panels_config, section, buffer, panel->user_status_format[i]);
1208 mc_config_set_int (mc_panels_config, section, "user_mini_status", panel->user_mini_status);
1211 void
1212 save_panel_types (void)
1214 panel_view_mode_t type;
1216 if (mc_run_mode != MC_RUN_FULL)
1217 return;
1219 if (!panels_options.auto_save_setup)
1220 return;
1222 type = get_display_type (0);
1223 panel_save_type ("New Left Panel", type);
1224 if (type == view_listing)
1225 panel_save_setup (left_panel, left_panel->panel_name);
1226 type = get_display_type (1);
1227 panel_save_type ("New Right Panel", type);
1228 if (type == view_listing)
1229 panel_save_setup (right_panel, right_panel->panel_name);
1231 mc_config_set_string (mc_panels_config, "Dirs", "other_dir", get_panel_dir_for (other_panel));
1233 if (current_panel != NULL)
1234 mc_config_set_string (mc_panels_config, "Dirs", "current_is_left",
1235 get_current_index () == 0 ? "1" : "0");
1237 if (mc_panels_config->ini_path == NULL)
1238 mc_panels_config->ini_path = g_strdup (panels_profile_name);
1240 mc_config_del_group (mc_panels_config, "Temporal:New Left Panel");
1241 mc_config_del_group (mc_panels_config, "Temporal:New Right Panel");
1243 mc_config_save_file (mc_panels_config, NULL);
1247 Load panels options from [Panels] section.
1249 void
1250 panels_load_options (void)
1252 size_t i;
1253 int qmode;
1255 /* Backward compatibility: load old parameters */
1256 for (i = 0; panels_ini_options[i].opt_name != NULL; i++)
1257 *panels_ini_options[i].opt_addr =
1258 mc_config_get_int (mc_main_config, CONFIG_APP_SECTION,
1259 panels_ini_options[i].opt_old_name != NULL
1260 ? panels_ini_options[i].opt_old_name : panels_ini_options[i].opt_name,
1261 *panels_ini_options[i].opt_addr);
1263 qmode = mc_config_get_int (mc_main_config, CONFIG_APP_SECTION,
1264 "quick_search_case_sensitive", (int) panels_options.qsearch_mode);
1265 if (qmode < 0)
1266 panels_options.qsearch_mode = QSEARCH_CASE_INSENSITIVE;
1267 else if (qmode >= QSEARCH_NUM)
1268 panels_options.qsearch_mode = QSEARCH_PANEL_CASE;
1269 else
1270 panels_options.qsearch_mode = (qsearch_mode_t) qmode;
1272 /* overwrite by new parameters */
1273 if (mc_config_has_group (mc_main_config, panels_section))
1275 for (i = 0; panels_ini_options[i].opt_name != NULL; i++)
1276 *panels_ini_options[i].opt_addr =
1277 mc_config_get_bool (mc_main_config, panels_section,
1278 panels_ini_options[i].opt_name,
1279 *panels_ini_options[i].opt_addr);
1281 qmode = mc_config_get_int (mc_main_config, panels_section,
1282 "quick_search_mode", (int) panels_options.qsearch_mode);
1283 if (qmode < 0)
1284 panels_options.qsearch_mode = QSEARCH_CASE_INSENSITIVE;
1285 else if (qmode >= QSEARCH_NUM)
1286 panels_options.qsearch_mode = QSEARCH_PANEL_CASE;
1287 else
1288 panels_options.qsearch_mode = (qsearch_mode_t) qmode;
1293 Save panels options in [Panels] section.
1295 void
1296 panels_save_options (void)
1298 size_t i;
1300 for (i = 0; panels_ini_options[i].opt_name != NULL; i++)
1301 mc_config_set_bool (mc_main_config, panels_section,
1302 panels_ini_options[i].opt_name, *panels_ini_options[i].opt_addr);
1304 mc_config_set_int (mc_main_config, panels_section,
1305 "quick_search_mode", (int) panels_options.qsearch_mode);