Split file src/keybind.[ch] to lib/keybind.[ch] and src/keybind-defaults.[ch].
[midnight-commander.git] / src / setup.c
blob09c64eb24c62604e317a46dfcb99ae7b7a28545b
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/timefmt.h"
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 "lib/util.h"
49 #include "lib/widget.h"
50 #ifdef HAVE_CHARSET
51 #include "lib/charsets.h"
52 #endif
54 #include "args.h"
55 #include "dir.h"
56 #include "panel.h"
57 #include "main.h"
58 #include "tree.h" /* xtree_mode */
59 #include "hotlist.h" /* load/save/done hotlist */
60 #include "panelize.h" /* load/save/done panelize */
61 #include "layout.h"
62 #include "cmd.h"
63 #include "file.h" /* safe_delete */
64 #include "keybind-defaults.h" /* keybind_lookup_action */
67 #ifdef USE_INTERNAL_EDIT
68 #include "src/editor/edit.h"
69 #endif
71 #include "src/viewer/mcviewer.h" /* For the externs */
73 #include "setup.h"
75 /*** 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 int easy_patterns = 1;
115 /*** file scope macro definitions ****************************************************************/
117 /* In order to use everywhere the same setup for the locale we use defines */
118 #define FMTYEAR _("%b %e %Y")
119 #define FMTTIME _("%b %e %H:%M")
121 /*** file scope type declarations ****************************************************************/
123 /*** file scope variables ************************************************************************/
125 static char *panels_profile_name = NULL; /* .mc/panels.ini */
127 /* *INDENT-OFF* */
128 static const struct
130 const char *key;
131 int list_type;
132 } list_types [] = {
133 { "full", list_full },
134 { "brief", list_brief },
135 { "long", list_long },
136 { "user", list_user },
137 { NULL, 0 }
140 static const struct
142 const char *opt_name;
143 panel_view_mode_t opt_type;
144 } panel_types [] = {
145 { "listing", view_listing },
146 { "quickview", view_quick },
147 { "info", view_info },
148 { "tree", view_tree },
149 { NULL, view_listing }
152 static const struct
154 const char *opt_name;
155 int *opt_addr;
156 } layout [] = {
157 { "equal_split", &equal_split },
158 { "first_panel_size", &first_panel_size },
159 { "message_visible", &message_visible },
160 { "keybar_visible", &keybar_visible },
161 { "xterm_title", &xterm_title },
162 { "output_lines", &output_lines },
163 { "command_prompt", &command_prompt },
164 { "menubar_visible", &menubar_visible },
165 { "show_mini_info", &show_mini_info },
166 { "free_space", &free_space },
167 { NULL, NULL }
170 static const struct
172 const char *opt_name;
173 int *opt_addr;
174 } int_options [] = {
175 { "verbose", &verbose },
176 { "pause_after_run", &pause_after_run },
177 { "shell_patterns", &easy_patterns },
178 { "auto_save_setup", &auto_save_setup },
179 { "auto_menu", &auto_menu },
180 { "use_internal_view", &use_internal_view },
181 { "use_internal_edit", &use_internal_edit },
182 { "clear_before_exec", &clear_before_exec },
183 { "confirm_delete", &confirm_delete },
184 { "confirm_overwrite", &confirm_overwrite },
185 { "confirm_execute", &confirm_execute },
186 { "confirm_history_cleanup", &confirm_history_cleanup },
187 { "confirm_exit", &confirm_exit },
188 { "confirm_directory_hotlist_delete", &confirm_directory_hotlist_delete },
189 { "safe_delete", &safe_delete },
190 { "mouse_repeat_rate", &mou_auto_repeat },
191 { "double_click_speed", &double_click_speed },
192 #ifndef HAVE_CHARSET
193 { "eight_bit_clean", &eight_bit_clean },
194 { "full_eight_bits", &full_eight_bits },
195 #endif /* !HAVE_CHARSET */
196 { "use_8th_bit_as_meta", &use_8th_bit_as_meta },
197 { "confirm_view_dir", &confirm_view_dir },
198 { "mouse_move_pages_viewer", &mcview_mouse_move_pages },
199 { "mouse_close_dialog", &mouse_close_dialog},
200 { "fast_refresh", &fast_refresh },
201 { "drop_menus", &drop_menus },
202 { "wrap_mode", &mcview_global_wrap_mode},
203 { "old_esc_mode", &old_esc_mode },
204 { "old_esc_mode_timeout", &old_esc_mode_timeout },
205 { "cd_symlinks", &cd_symlinks },
206 { "show_all_if_ambiguous", &show_all_if_ambiguous },
207 { "max_dirt_limit", &mcview_max_dirt_limit },
208 { "torben_fj_mode", &torben_fj_mode },
209 { "use_file_to_guess_type", &use_file_to_check_type },
210 { "alternate_plus_minus", &alternate_plus_minus },
211 { "only_leading_plus_minus", &only_leading_plus_minus },
212 { "show_output_starts_shell", &output_starts_shell },
213 { "xtree_mode", &xtree_mode },
214 { "num_history_items_recorded", &num_history_items_recorded },
215 { "file_op_compute_totals", &file_op_compute_totals },
216 { "classic_progressbar", &classic_progressbar},
217 #ifdef ENABLE_VFS
218 { "vfs_timeout", &vfs_timeout },
219 #ifdef ENABLE_VFS_FTP
220 { "ftpfs_directory_timeout", &ftpfs_directory_timeout },
221 { "use_netrc", &ftpfs_use_netrc },
222 { "ftpfs_retry_seconds", &ftpfs_retry_seconds },
223 { "ftpfs_always_use_proxy", &ftpfs_always_use_proxy },
224 { "ftpfs_use_passive_connections", &ftpfs_use_passive_connections },
225 { "ftpfs_use_passive_connections_over_proxy", &ftpfs_use_passive_connections_over_proxy },
226 { "ftpfs_use_unix_list_options", &ftpfs_use_unix_list_options },
227 { "ftpfs_first_cd_then_ls", &ftpfs_first_cd_then_ls },
228 #endif /* ENABLE_VFS_FTP */
229 #ifdef ENABLE_VFS_FISH
230 { "fish_directory_timeout", &fish_directory_timeout },
231 #endif /* ENABLE_VFS_FISH */
232 #endif /* ENABLE_VFS */
233 /* option_tab_spacing is used in internal viewer */
234 { "editor_tab_spacing", &option_tab_spacing },
235 #ifdef USE_INTERNAL_EDIT
236 { "editor_word_wrap_line_length", &option_word_wrap_line_length },
237 { "editor_fill_tabs_with_spaces", &option_fill_tabs_with_spaces },
238 { "editor_return_does_auto_indent", &option_return_does_auto_indent },
239 { "editor_backspace_through_tabs", &option_backspace_through_tabs },
240 { "editor_fake_half_tabs", &option_fake_half_tabs },
241 { "editor_option_save_mode", &option_save_mode },
242 { "editor_option_save_position", &option_save_position },
243 { "editor_option_auto_para_formatting", &option_auto_para_formatting },
244 { "editor_option_typewriter_wrap", &option_typewriter_wrap },
245 { "editor_edit_confirm_save", &edit_confirm_save },
246 { "editor_syntax_highlighting", &option_syntax_highlighting },
247 { "editor_persistent_selections", &option_persistent_selections },
248 { "editor_cursor_beyond_eol", &option_cursor_beyond_eol },
249 { "editor_visible_tabs", &visible_tabs },
250 { "editor_visible_spaces", &visible_tws },
251 { "editor_line_state", &option_line_state },
252 { "editor_simple_statusbar", &simple_statusbar },
253 { "editor_check_new_line", &option_check_nl_at_eof },
254 { "editor_show_right_margin", &show_right_margin },
255 #endif /* USE_INTERNAL_EDIT */
256 { "nice_rotating_dash", &nice_rotating_dash },
257 { "horizontal_split", &horizontal_split },
258 { "mcview_remember_file_position", &mcview_remember_file_position },
259 { "auto_fill_mkdir_name", &auto_fill_mkdir_name },
260 { "copymove_persistent_attr", &setup_copymove_persistent_attr },
261 { "select_flags", &select_flags },
262 { NULL, NULL }
265 static const struct
267 const char *opt_name;
268 char **opt_addr;
269 const char *opt_defval;
270 } str_options[] = {
271 #ifdef USE_INTERNAL_EDIT
272 { "editor_backup_extension", &option_backup_ext, "~" },
273 #endif
274 { "mcview_eof", &mcview_show_eof, "" },
275 { NULL, NULL, NULL }
278 static const struct
280 const char *opt_name;
281 const char *opt_old_name;
282 gboolean *opt_addr;
283 } panels_ini_options[] = {
284 { "kilobyte_si", NULL, &panels_options.kilobyte_si },
285 { "mix_all_files", NULL, &panels_options.mix_all_files },
286 { "show_backups", NULL, &panels_options.show_backups },
287 { "show_dot_files", NULL, &panels_options.show_dot_files },
288 { "fast_reload", NULL, &panels_options.fast_reload },
289 { "fast_reload_msg_shown", NULL, &panels_options.fast_reload_msg_shown },
290 { "mark_moves_down", NULL, &panels_options.mark_moves_down },
291 { "reverse_files_only", NULL, &panels_options.reverse_files_only },
292 { "auto_save_setup_panels", "auto_save_setup", &panels_options.auto_save_setup },
293 { "navigate_with_arrows", NULL, &panels_options.navigate_with_arrows },
294 { "panel_scroll_pages", "scroll_pages", &panels_options.scroll_pages },
295 { "mouse_move_pages", NULL, &panels_options.mouse_move_pages },
296 { "filetype_mode", NULL, &panels_options.filetype_mode },
297 { "permission_mode", NULL, &panels_options.permission_mode },
298 { NULL, NULL, NULL }
300 /* *INDENT-ON* */
302 static const char *panels_section = "Panels";
304 /*** file scope functions ************************************************************************/
305 /* --------------------------------------------------------------------------------------------- */
309 Get name of config file.
311 \param subdir
312 if not NULL, then config also search into specified subdir.
314 \param config_file_name
315 If specified filename is relative, then will search in standart patches.
317 \return
318 Newly allocated path to config name or NULL if file not found.
320 If config_file_name is a relative path, then search config in stantart pathes.
322 static char *
323 load_setup_get_full_config_name (const char *subdir, const char *config_file_name)
326 TODO: IMHO, in future this function must be placed into mc_config module.
327 Also, need to rename stupid mc_home and mc_home_alt to mc_sysconfdir and mc_datadir;
328 home_mc => mc_user_homedir
330 char *lc_basename, *ret;
332 if (config_file_name == NULL)
333 return NULL;
335 if (g_path_is_absolute (config_file_name))
336 return g_strdup (config_file_name);
339 lc_basename = g_path_get_basename (config_file_name);
340 if (lc_basename == NULL)
341 return NULL;
343 if (subdir != NULL)
344 ret = g_build_filename (home_dir, MC_USERCONF_DIR, subdir, lc_basename, NULL);
345 else
346 ret = g_build_filename (home_dir, MC_USERCONF_DIR, lc_basename, NULL);
348 if (exist_file (ret))
350 g_free (lc_basename);
351 return ret;
353 g_free (ret);
355 if (subdir != NULL)
356 ret = g_build_filename (mc_home, subdir, lc_basename, NULL);
357 else
358 ret = g_build_filename (mc_home, lc_basename, NULL);
360 if (exist_file (ret))
362 g_free (lc_basename);
363 return ret;
365 g_free (ret);
367 if (subdir != NULL)
368 ret = g_build_filename (mc_home_alt, subdir, lc_basename, NULL);
369 else
370 ret = g_build_filename (mc_home_alt, lc_basename, NULL);
372 g_free (lc_basename);
374 if (exist_file (ret))
375 return ret;
377 g_free (ret);
378 return NULL;
382 /* --------------------------------------------------------------------------------------------- */
384 static const char *
385 setup__is_cfg_group_must_panel_config (const char *grp)
387 return (!strcasecmp ("Dirs", grp) ||
388 !strcasecmp ("Temporal:New Right Panel", grp) ||
389 !strcasecmp ("Temporal:New Left Panel", grp) ||
390 !strcasecmp ("New Left Panel", grp) || !strcasecmp ("New Right Panel", grp))
391 ? grp : NULL;
394 /* --------------------------------------------------------------------------------------------- */
396 static void
397 setup__move_panels_config_into_separate_file (const char *profile)
399 mc_config_t *tmp_cfg;
400 char **groups, **curr_grp;
401 const char *need_grp;
403 if (!exist_file (profile))
404 return;
406 tmp_cfg = mc_config_init (profile);
407 if (!tmp_cfg)
408 return;
410 curr_grp = groups = mc_config_get_groups (tmp_cfg, NULL);
411 if (!groups)
413 mc_config_deinit (tmp_cfg);
414 return;
417 while (*curr_grp)
419 if (setup__is_cfg_group_must_panel_config (*curr_grp) == NULL)
420 mc_config_del_group (tmp_cfg, *curr_grp);
421 curr_grp++;
424 mc_config_save_to_file (tmp_cfg, panels_profile_name, NULL);
425 mc_config_deinit (tmp_cfg);
427 tmp_cfg = mc_config_init (profile);
428 if (!tmp_cfg)
430 g_strfreev (groups);
431 return;
434 curr_grp = groups;
436 while (*curr_grp)
438 need_grp = setup__is_cfg_group_must_panel_config (*curr_grp);
439 if (need_grp != NULL)
441 mc_config_del_group (tmp_cfg, need_grp);
443 curr_grp++;
445 g_strfreev (groups);
447 mc_config_save_file (tmp_cfg, NULL);
448 mc_config_deinit (tmp_cfg);
451 /* --------------------------------------------------------------------------------------------- */
453 Create new mc_config object from specified ini-file or
454 append data to existing mc_config object from ini-file
458 static void
459 load_setup_init_config_from_file (mc_config_t ** config, const char *fname)
462 TODO: IMHO, in future this function must be placed into mc_config module.
464 if (exist_file (fname))
466 if (*config != NULL)
467 mc_config_read_file (*config, fname);
468 else
469 *config = mc_config_init (fname);
473 /* --------------------------------------------------------------------------------------------- */
475 static void
476 load_layout (void)
478 size_t i;
480 for (i = 0; layout[i].opt_name != NULL; i++)
481 *layout[i].opt_addr = mc_config_get_int (mc_main_config, "Layout",
482 layout[i].opt_name, *layout[i].opt_addr);
485 /* --------------------------------------------------------------------------------------------- */
487 static void
488 load_keys_from_section (const char *terminal, mc_config_t * cfg)
490 char *section_name;
491 gchar **profile_keys, **keys;
492 gchar **values, **curr_values;
493 char *valcopy, *value;
494 long key_code;
495 gsize len, values_len;
497 if (terminal == NULL)
498 return;
500 section_name = g_strconcat ("terminal:", terminal, (char *) NULL);
501 profile_keys = keys = mc_config_get_keys (cfg, section_name, &len);
503 while (*profile_keys != NULL)
505 /* copy=other causes all keys from [terminal:other] to be loaded. */
506 if (g_ascii_strcasecmp (*profile_keys, "copy") == 0)
508 valcopy = mc_config_get_string (cfg, section_name, *profile_keys, "");
509 load_keys_from_section (valcopy, cfg);
510 g_free (valcopy);
511 profile_keys++;
512 continue;
515 curr_values = values =
516 mc_config_get_string_list (cfg, section_name, *profile_keys, &values_len);
518 key_code = lookup_key (*profile_keys, NULL);
520 if (key_code != 0)
522 if (curr_values != NULL)
524 while (*curr_values != NULL)
526 valcopy = convert_controls (*curr_values);
527 define_sequence (key_code, valcopy, MCKEY_NOACTION);
528 g_free (valcopy);
529 curr_values++;
532 else
534 value = mc_config_get_string (cfg, section_name, *profile_keys, "");
535 valcopy = convert_controls (value);
536 define_sequence (key_code, valcopy, MCKEY_NOACTION);
537 g_free (valcopy);
538 g_free (value);
542 profile_keys++;
544 if (values != NULL)
545 g_strfreev (values);
547 g_strfreev (keys);
548 g_free (section_name);
551 /* --------------------------------------------------------------------------------------------- */
553 static void
554 load_keymap_from_section (const char *section_name, GArray * keymap, mc_config_t * cfg)
556 gchar **profile_keys, **keys;
557 gchar **values, **curr_values;
558 char *valcopy, *value;
559 int action;
560 gsize len, values_len;
562 if (section_name == NULL)
563 return;
565 profile_keys = keys = mc_config_get_keys (cfg, section_name, &len);
567 while (*profile_keys != NULL)
569 curr_values = values =
570 mc_config_get_string_list (cfg, section_name, *profile_keys, &values_len);
572 action = keybind_lookup_action (*profile_keys);
574 if (action > 0)
576 if (curr_values != NULL)
578 while (*curr_values != NULL)
580 valcopy = convert_controls (*curr_values);
581 keybind_cmd_bind (keymap, valcopy, action);
582 g_free (valcopy);
583 curr_values++;
586 else
588 value = mc_config_get_string (cfg, section_name, *profile_keys, "");
589 valcopy = convert_controls (value);
590 /* define_sequence (key_code, valcopy, MCKEY_NOACTION); */
591 g_free (valcopy);
592 g_free (value);
596 profile_keys++;
598 if (values != NULL)
599 g_strfreev (values);
601 g_strfreev (keys);
604 /* --------------------------------------------------------------------------------------------- */
606 static mc_config_t *
607 load_setup_get_keymap_profile_config (void)
610 TODO: IMHO, in future this function must be placed into mc_config module.
612 mc_config_t *keymap_config = NULL;
613 char *fname, *fname2;
615 /* 1) /usr/share/mc (mc_home_alt) */
616 fname = g_build_filename (mc_home_alt, GLOBAL_KEYMAP_FILE, NULL);
617 load_setup_init_config_from_file (&keymap_config, fname);
618 g_free (fname);
620 /* 2) /etc/mc (mc_home) */
621 fname = g_build_filename (mc_home, GLOBAL_KEYMAP_FILE, NULL);
622 load_setup_init_config_from_file (&keymap_config, fname);
623 g_free (fname);
625 /* 3) ~/.mc (home_dir?) */
626 fname = g_build_filename (home_dir, MC_USERCONF_DIR, GLOBAL_KEYMAP_FILE, NULL);
627 load_setup_init_config_from_file (&keymap_config, fname);
628 g_free (fname);
630 /* 4) main config; [Midnight Commander] -> keymap */
632 fname2 =
633 mc_config_get_string (mc_main_config, CONFIG_APP_SECTION, "keymap", GLOBAL_KEYMAP_FILE);
634 fname = load_setup_get_full_config_name (NULL, fname2);
635 if (fname != NULL)
637 load_setup_init_config_from_file (&keymap_config, fname);
638 g_free (fname);
640 g_free (fname2);
642 /* 5) getenv("MC_KEYMAP") */
643 fname = load_setup_get_full_config_name (NULL, g_getenv ("MC_KEYMAP"));
644 if (fname != NULL)
646 load_setup_init_config_from_file (&keymap_config, fname);
647 g_free (fname);
650 /* 6) --keymap=<keymap> */
651 fname = load_setup_get_full_config_name (NULL, mc_args__keymap_file);
652 if (fname != NULL)
654 load_setup_init_config_from_file (&keymap_config, fname);
655 g_free (fname);
658 return keymap_config;
661 /* --------------------------------------------------------------------------------------------- */
663 static panel_view_mode_t
664 setup__load_panel_state (const char *section)
666 char *buffer;
667 size_t i;
668 panel_view_mode_t mode = view_listing;
670 /* Load the display mode */
671 buffer = mc_config_get_string (mc_panels_config, section, "display", "listing");
673 for (i = 0; panel_types[i].opt_name != NULL; i++)
674 if (g_ascii_strcasecmp (panel_types[i].opt_name, buffer) == 0)
676 mode = panel_types[i].opt_type;
677 break;
680 g_free (buffer);
682 return mode;
685 /* --------------------------------------------------------------------------------------------- */
687 static void
688 panel_save_type (const char *section, panel_view_mode_t type)
690 size_t i;
692 for (i = 0; panel_types[i].opt_name != NULL; i++)
693 if (panel_types[i].opt_type == type)
695 mc_config_set_string (mc_panels_config, section, "display", panel_types[i].opt_name);
696 break;
700 /* --------------------------------------------------------------------------------------------- */
701 /*** public functions ****************************************************************************/
702 /* --------------------------------------------------------------------------------------------- */
704 char *
705 setup_init (void)
707 char *profile;
708 char *inifile;
710 if (profile_name != NULL)
711 return profile_name;
713 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
714 if (!exist_file (profile))
716 inifile = concat_dir_and_file (mc_home, "mc.ini");
717 if (exist_file (inifile))
719 g_free (profile);
720 profile = inifile;
722 else
724 g_free (inifile);
725 inifile = concat_dir_and_file (mc_home_alt, "mc.ini");
726 if (exist_file (inifile))
728 g_free (profile);
729 profile = inifile;
731 else
732 g_free (inifile);
736 profile_name = profile;
738 return profile;
741 /* --------------------------------------------------------------------------------------------- */
743 void
744 load_setup (void)
746 char *profile;
747 size_t i;
748 char *buffer;
749 const char *kt;
751 #ifdef HAVE_CHARSET
752 load_codepages_list ();
753 #endif /* HAVE_CHARSET */
755 profile = setup_init ();
757 /* mc.lib is common for all users, but has priority lower than
758 ~/.mc/ini. FIXME: it's only used for keys and treestore now */
759 global_profile_name = g_build_filename (mc_home, MC_GLOBAL_CONFIG_FILE, (char *) NULL);
760 if (!exist_file (global_profile_name))
762 g_free (global_profile_name);
763 global_profile_name = g_build_filename (mc_home_alt, MC_GLOBAL_CONFIG_FILE, (char *) NULL);
766 panels_profile_name = g_build_filename (home_dir, MC_USERCONF_DIR, MC_PANELS_FILE, NULL);
768 mc_main_config = mc_config_init (profile);
770 if (!exist_file (panels_profile_name))
771 setup__move_panels_config_into_separate_file (profile);
773 mc_panels_config = mc_config_init (panels_profile_name);
775 /* Load integer boolean options */
776 for (i = 0; int_options[i].opt_name != NULL; i++)
777 *int_options[i].opt_addr =
778 mc_config_get_int (mc_main_config, CONFIG_APP_SECTION, int_options[i].opt_name,
779 *int_options[i].opt_addr);
781 if (option_tab_spacing <= 0)
782 option_tab_spacing = DEFAULT_TAB_SPACING;
784 #ifdef USE_INTERNAL_EDIT
785 if (option_word_wrap_line_length <= 0)
786 option_word_wrap_line_length = DEFAULT_WRAP_LINE_LENGTH;
787 #endif /* USE_INTERNAL_EDIT */
789 /* overwrite old_esc_mode_timeout */
790 kt = getenv ("KEYBOARD_KEY_TIMEOUT_US");
791 if ((kt != NULL) && (kt[0] != '\0'))
792 old_esc_mode_timeout = atoi (kt);
794 /* Load string options */
795 for (i = 0; str_options[i].opt_name != NULL; i++)
796 *str_options[i].opt_addr =
797 mc_config_get_string (mc_main_config, CONFIG_APP_SECTION, str_options[i].opt_name,
798 str_options[i].opt_defval);
800 load_layout ();
801 panels_load_options ();
802 load_panelize ();
804 startup_left_mode = setup__load_panel_state ("New Left Panel");
805 startup_right_mode = setup__load_panel_state ("New Right Panel");
807 /* At least one of the panels is a listing panel */
808 if (startup_left_mode != view_listing && startup_right_mode != view_listing)
809 startup_left_mode = view_listing;
811 if (mc_run_param1 == NULL)
813 buffer = mc_config_get_string (mc_panels_config, "Dirs", "other_dir", ".");
814 if (vfs_file_is_local (buffer))
815 mc_run_param1 = buffer;
816 else
817 g_free (buffer);
820 boot_current_is_left = mc_config_get_int (mc_panels_config, "Dirs", "current_is_left", 1);
822 /* Load time formats */
823 user_recent_timeformat =
824 mc_config_get_string (mc_main_config, "Misc", "timeformat_recent", FMTTIME);
825 user_old_timeformat = mc_config_get_string (mc_main_config, "Misc", "timeformat_old", FMTYEAR);
827 #ifdef ENABLE_VFS_FTP
828 ftpfs_proxy_host = mc_config_get_string (mc_main_config, "Misc", "ftp_proxy_host", "gate");
829 ftpfs_ignore_chattr_errors = mc_config_get_bool (mc_main_config, CONFIG_APP_SECTION,
830 "ignore_ftp_chattr_errors", TRUE);
831 ftpfs_init_passwd ();
832 #endif /* ENABLE_VFS_FTP */
834 /* The default color and the terminal dependent color */
835 setup_color_string = mc_config_get_string (mc_main_config, "Colors", "base_color", "");
836 term_color_string = mc_config_get_string (mc_main_config, "Colors", getenv ("TERM"), "");
837 color_terminal_string = mc_config_get_string (mc_main_config, "Colors", "color_terminals", "");
839 /* Load the directory history */
840 /* directory_history_load (); */
841 /* Remove the temporal entries */
843 #ifdef HAVE_CHARSET
844 if (codepages->len > 1)
846 buffer = mc_config_get_string (mc_main_config, "Misc", "display_codepage", "");
847 if (buffer[0] != '\0')
849 display_codepage = get_codepage_index (buffer);
850 cp_display = get_codepage_id (display_codepage);
852 g_free (buffer);
853 buffer = mc_config_get_string (mc_main_config, "Misc", "source_codepage", "");
854 if (buffer[0] != '\0')
856 default_source_codepage = get_codepage_index (buffer);
857 source_codepage = default_source_codepage; /* May be source_codepage doesn't need this */
858 cp_source = get_codepage_id (source_codepage);
860 g_free (buffer);
863 autodetect_codeset = mc_config_get_string (mc_main_config, "Misc", "autodetect_codeset", "");
864 if ((autodetect_codeset[0] != '\0') && (strcmp (autodetect_codeset, "off") != 0))
865 is_autodetect_codeset_enabled = TRUE;
867 g_free (init_translation_table (source_codepage, display_codepage));
868 buffer = (char *) get_codepage_id (display_codepage);
869 if (buffer != NULL)
870 utf8_display = str_isutf8 (buffer);
871 #endif /* HAVE_CHARSET */
873 clipboard_store_path = mc_config_get_string (mc_main_config, "Misc", "clipboard_store", "");
874 clipboard_paste_path = mc_config_get_string (mc_main_config, "Misc", "clipboard_paste", "");
877 /* --------------------------------------------------------------------------------------------- */
879 gboolean
880 save_setup (void)
882 char *tmp_profile;
883 gboolean ret;
885 saving_setup = 1;
887 save_config ();
888 save_layout ();
889 panels_save_options ();
890 save_hotlist ();
891 save_panelize ();
892 save_panel_types ();
893 /* directory_history_save (); */
895 #ifdef ENABLE_VFS_FTP
896 mc_config_set_string (mc_main_config, "Misc", "ftpfs_password", ftpfs_anonymous_passwd);
897 if (ftpfs_proxy_host)
898 mc_config_set_string (mc_main_config, "Misc", "ftp_proxy_host", ftpfs_proxy_host);
899 #endif /* ENABLE_VFS_FTP */
901 #ifdef HAVE_CHARSET
902 mc_config_set_string (mc_main_config, "Misc", "display_codepage",
903 get_codepage_id (display_codepage));
904 mc_config_set_string (mc_main_config, "Misc", "source_codepage",
905 get_codepage_id (default_source_codepage));
906 mc_config_set_string (mc_main_config, "Misc", "autodetect_codeset", autodetect_codeset);
907 #endif /* HAVE_CHARSET */
908 mc_config_set_string (mc_main_config, "Misc", "clipboard_store", clipboard_store_path);
909 mc_config_set_string (mc_main_config, "Misc", "clipboard_paste", clipboard_paste_path);
911 tmp_profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
912 ret = mc_config_save_to_file (mc_main_config, tmp_profile, NULL);
914 g_free (tmp_profile);
915 saving_setup = 0;
916 return ret;
919 /* --------------------------------------------------------------------------------------------- */
921 void
922 done_setup (void)
924 size_t i;
926 g_free (profile_name);
927 g_free (global_profile_name);
928 g_free (color_terminal_string);
929 g_free (term_color_string);
930 g_free (setup_color_string);
931 g_free (panels_profile_name);
932 mc_config_deinit (mc_main_config);
933 mc_config_deinit (mc_panels_config);
935 g_free (user_recent_timeformat);
936 g_free (user_old_timeformat);
938 for (i = 0; str_options[i].opt_name != NULL; i++)
939 g_free (*str_options[i].opt_addr);
941 done_hotlist ();
942 done_panelize ();
943 /* directory_history_free (); */
946 /* --------------------------------------------------------------------------------------------- */
948 void
949 save_config (void)
951 char *profile;
952 GError *error = NULL;
953 size_t i;
955 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
957 /* Save integer options */
958 for (i = 0; int_options[i].opt_name != NULL; i++)
959 mc_config_set_int (mc_main_config, CONFIG_APP_SECTION, int_options[i].opt_name,
960 *int_options[i].opt_addr);
962 /* Save string options */
963 for (i = 0; str_options[i].opt_name != NULL; i++)
964 mc_config_set_string (mc_main_config, CONFIG_APP_SECTION, str_options[i].opt_name,
965 *str_options[i].opt_addr);
967 if (!mc_config_save_to_file (mc_main_config, profile, &error))
968 setup_save_config_show_error (profile, &error);
970 g_free (profile);
973 /* --------------------------------------------------------------------------------------------- */
975 void
976 setup_save_config_show_error (const char *filename, GError ** error)
978 if (error != NULL && *error != NULL)
980 message (D_ERROR, MSG_ERROR, _("Cannot save file %s:\n%s"), filename, (*error)->message);
981 g_error_free (*error);
982 *error = NULL;
986 /* --------------------------------------------------------------------------------------------- */
988 void
989 save_layout (void)
991 char *profile;
992 size_t i;
994 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
995 /* Save integer options */
996 for (i = 0; layout[i].opt_name != NULL; i++)
997 mc_config_set_int (mc_main_config, "Layout", layout[i].opt_name, *layout[i].opt_addr);
998 mc_config_save_to_file (mc_main_config, profile, NULL);
999 g_free (profile);
1002 /* --------------------------------------------------------------------------------------------- */
1004 void
1005 load_key_defs (void)
1008 * Load keys from mc.lib before ~/.mc/ini, so that the user
1009 * definitions override global settings.
1011 mc_config_t *mc_global_config;
1013 mc_global_config = mc_config_init (global_profile_name);
1014 if (mc_global_config != NULL)
1016 load_keys_from_section ("general", mc_global_config);
1017 load_keys_from_section (getenv ("TERM"), mc_global_config);
1018 mc_config_deinit (mc_global_config);
1021 load_keys_from_section ("general", mc_main_config);
1022 load_keys_from_section (getenv ("TERM"), mc_main_config);
1025 /* --------------------------------------------------------------------------------------------- */
1027 #ifdef ENABLE_VFS_FTP
1028 char *
1029 load_anon_passwd (void)
1031 char *buffer;
1033 buffer = mc_config_get_string (mc_main_config, "Misc", "ftpfs_password", "");
1035 if ((buffer != NULL) && (buffer[0] != '\0'))
1036 return buffer;
1038 g_free (buffer);
1039 return NULL;
1041 #endif /* ENABLE_VFS_FTP */
1043 /* --------------------------------------------------------------------------------------------- */
1045 void
1046 load_keymap_defs (void)
1049 * Load keymap from GLOBAL_KEYMAP_FILE before ~/.mc/keymap, so that the user
1050 * definitions override global settings.
1052 mc_config_t *mc_global_keymap;
1054 mc_global_keymap = load_setup_get_keymap_profile_config ();
1056 if (mc_global_keymap != NULL)
1058 #ifdef USE_INTERNAL_EDIT
1059 editor_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1060 load_keymap_from_section ("editor", editor_keymap, mc_global_keymap);
1061 editor_x_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1062 load_keymap_from_section ("editor:xmap", editor_x_keymap, mc_global_keymap);
1063 #endif
1065 viewer_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1066 load_keymap_from_section ("viewer", viewer_keymap, mc_global_keymap);
1067 viewer_hex_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1068 load_keymap_from_section ("viewer:hex", viewer_hex_keymap, mc_global_keymap);
1070 main_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1071 load_keymap_from_section ("main", main_keymap, mc_global_keymap);
1072 main_x_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1073 load_keymap_from_section ("main:xmap", main_x_keymap, mc_global_keymap);
1075 panel_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1076 load_keymap_from_section ("panel", panel_keymap, mc_global_keymap);
1078 input_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1079 load_keymap_from_section ("input", input_keymap, mc_global_keymap);
1081 listbox_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1082 load_keymap_from_section ("listbox", listbox_keymap, mc_global_keymap);
1084 tree_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1085 load_keymap_from_section ("tree", tree_keymap, mc_global_keymap);
1087 help_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1088 load_keymap_from_section ("help", help_keymap, mc_global_keymap);
1090 dialog_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1091 load_keymap_from_section ("dialog", dialog_keymap, mc_global_keymap);
1093 #ifdef USE_DIFF_VIEW
1094 diff_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1095 load_keymap_from_section ("diffviewer", diff_keymap, mc_global_keymap);
1096 #endif
1097 mc_config_deinit (mc_global_keymap);
1100 main_map = default_main_map;
1101 if (main_keymap && main_keymap->len > 0)
1102 main_map = (global_keymap_t *) main_keymap->data;
1104 main_x_map = default_main_x_map;
1105 if (main_x_keymap && main_x_keymap->len > 0)
1106 main_x_map = (global_keymap_t *) main_x_keymap->data;
1108 panel_map = default_panel_keymap;
1109 if (panel_keymap && panel_keymap->len > 0)
1110 panel_map = (global_keymap_t *) panel_keymap->data;
1112 input_map = default_input_keymap;
1113 if (input_keymap && input_keymap->len > 0)
1114 input_map = (global_keymap_t *) input_keymap->data;
1116 listbox_map = default_listbox_keymap;
1117 if (listbox_keymap && listbox_keymap->len > 0)
1118 listbox_map = (global_keymap_t *) listbox_keymap->data;
1120 tree_map = default_tree_keymap;
1121 if (tree_keymap && tree_keymap->len > 0)
1122 tree_map = (global_keymap_t *) tree_keymap->data;
1124 help_map = default_help_keymap;
1125 if (help_keymap && help_keymap->len > 0)
1126 help_map = (global_keymap_t *) help_keymap->data;
1128 dialog_map = default_dialog_keymap;
1129 if (dialog_keymap && dialog_keymap->len > 0)
1130 dialog_map = (global_keymap_t *) dialog_keymap->data;
1132 #ifdef USE_DIFF_VIEW
1133 diff_map = default_diff_keymap;
1134 if (diff_keymap && diff_keymap->len > 0)
1135 diff_map = (global_keymap_t *) diff_keymap->data;
1136 #endif
1140 /* --------------------------------------------------------------------------------------------- */
1142 void
1143 free_keymap_defs (void)
1145 #ifdef USE_INTERNAL_EDIT
1146 if (editor_keymap != NULL)
1147 g_array_free (editor_keymap, TRUE);
1148 if (editor_x_keymap != NULL)
1149 g_array_free (editor_x_keymap, TRUE);
1150 #endif
1151 if (viewer_keymap != NULL)
1152 g_array_free (viewer_keymap, TRUE);
1153 if (viewer_hex_keymap != NULL)
1154 g_array_free (viewer_hex_keymap, TRUE);
1155 if (main_keymap != NULL)
1156 g_array_free (main_keymap, TRUE);
1157 if (main_x_keymap != NULL)
1158 g_array_free (main_x_keymap, TRUE);
1159 if (panel_keymap != NULL)
1160 g_array_free (panel_keymap, TRUE);
1161 if (input_keymap != NULL)
1162 g_array_free (input_keymap, TRUE);
1163 if (listbox_keymap != NULL)
1164 g_array_free (listbox_keymap, TRUE);
1165 if (tree_keymap != NULL)
1166 g_array_free (tree_keymap, TRUE);
1167 if (help_keymap != NULL)
1168 g_array_free (help_keymap, TRUE);
1169 if (dialog_keymap != NULL)
1170 g_array_free (dialog_keymap, TRUE);
1171 #ifdef USE_DIFF_VIEW
1172 if (diff_keymap != NULL)
1173 g_array_free (diff_keymap, TRUE);
1174 #endif
1177 /* --------------------------------------------------------------------------------------------- */
1179 void
1180 panel_load_setup (WPanel * panel, const char *section)
1182 size_t i;
1183 char *buffer, buffer2[BUF_TINY];
1185 panel->reverse = mc_config_get_int (mc_panels_config, section, "reverse", 0);
1186 panel->case_sensitive =
1187 mc_config_get_int (mc_panels_config, section, "case_sensitive",
1188 OS_SORT_CASE_SENSITIVE_DEFAULT);
1189 panel->exec_first = mc_config_get_int (mc_panels_config, section, "exec_first", 0);
1191 /* Load sort order */
1192 buffer = mc_config_get_string (mc_panels_config, section, "sort_order", "name");
1193 panel->current_sort_field = panel_get_field_by_id (buffer);
1194 if (panel->current_sort_field == NULL)
1195 panel->current_sort_field = panel_get_field_by_id ("name");
1197 g_free (buffer);
1199 /* Load the listing mode */
1200 buffer = mc_config_get_string (mc_panels_config, section, "list_mode", "full");
1201 panel->list_type = list_full;
1202 for (i = 0; list_types[i].key != NULL; i++)
1203 if (g_ascii_strcasecmp (list_types[i].key, buffer) == 0)
1205 panel->list_type = list_types[i].list_type;
1206 break;
1208 g_free (buffer);
1210 /* User formats */
1211 g_free (panel->user_format);
1212 panel->user_format =
1213 mc_config_get_string (mc_panels_config, section, "user_format", DEFAULT_USER_FORMAT);
1215 for (i = 0; i < LIST_TYPES; i++)
1217 g_free (panel->user_status_format[i]);
1218 g_snprintf (buffer2, BUF_TINY, "user_status%lld", (long long) i);
1219 panel->user_status_format[i] =
1220 mc_config_get_string (mc_panels_config, section, buffer2, DEFAULT_USER_FORMAT);
1223 panel->user_mini_status = mc_config_get_int (mc_panels_config, section, "user_mini_status", 0);
1226 /* --------------------------------------------------------------------------------------------- */
1228 void
1229 panel_save_setup (struct WPanel *panel, const char *section)
1231 char buffer[BUF_TINY];
1232 size_t i;
1234 mc_config_set_int (mc_panels_config, section, "reverse", panel->reverse);
1235 mc_config_set_int (mc_panels_config, section, "case_sensitive", panel->case_sensitive);
1236 mc_config_set_int (mc_panels_config, section, "exec_first", panel->exec_first);
1238 mc_config_set_string (mc_panels_config, section, "sort_order", panel->current_sort_field->id);
1240 for (i = 0; list_types[i].key != NULL; i++)
1241 if (list_types[i].list_type == panel->list_type)
1243 mc_config_set_string (mc_panels_config, section, "list_mode", list_types[i].key);
1244 break;
1247 mc_config_set_string (mc_panels_config, section, "user_format", panel->user_format);
1249 for (i = 0; i < LIST_TYPES; i++)
1251 g_snprintf (buffer, BUF_TINY, "user_status%lld", (long long) i);
1252 mc_config_set_string (mc_panels_config, section, buffer, panel->user_status_format[i]);
1255 mc_config_set_int (mc_panels_config, section, "user_mini_status", panel->user_mini_status);
1258 /* --------------------------------------------------------------------------------------------- */
1260 void
1261 save_panel_types (void)
1263 panel_view_mode_t type;
1265 if (mc_run_mode != MC_RUN_FULL)
1266 return;
1268 if (!panels_options.auto_save_setup)
1269 return;
1271 type = get_display_type (0);
1272 panel_save_type ("New Left Panel", type);
1273 if (type == view_listing)
1274 panel_save_setup (left_panel, left_panel->panel_name);
1275 type = get_display_type (1);
1276 panel_save_type ("New Right Panel", type);
1277 if (type == view_listing)
1278 panel_save_setup (right_panel, right_panel->panel_name);
1280 mc_config_set_string (mc_panels_config, "Dirs", "other_dir", get_panel_dir_for (other_panel));
1282 if (current_panel != NULL)
1283 mc_config_set_string (mc_panels_config, "Dirs", "current_is_left",
1284 get_current_index () == 0 ? "1" : "0");
1286 if (mc_panels_config->ini_path == NULL)
1287 mc_panels_config->ini_path = g_strdup (panels_profile_name);
1289 mc_config_del_group (mc_panels_config, "Temporal:New Left Panel");
1290 mc_config_del_group (mc_panels_config, "Temporal:New Right Panel");
1292 mc_config_save_file (mc_panels_config, NULL);
1295 /* --------------------------------------------------------------------------------------------- */
1298 Load panels options from [Panels] section.
1300 void
1301 panels_load_options (void)
1303 size_t i;
1304 int qmode;
1306 /* Backward compatibility: load old parameters */
1307 for (i = 0; panels_ini_options[i].opt_name != NULL; i++)
1308 *panels_ini_options[i].opt_addr =
1309 mc_config_get_int (mc_main_config, CONFIG_APP_SECTION,
1310 panels_ini_options[i].opt_old_name != NULL
1311 ? panels_ini_options[i].
1312 opt_old_name : panels_ini_options[i].opt_name,
1313 *panels_ini_options[i].opt_addr);
1315 qmode = mc_config_get_int (mc_main_config, CONFIG_APP_SECTION,
1316 "quick_search_case_sensitive", (int) panels_options.qsearch_mode);
1317 if (qmode < 0)
1318 panels_options.qsearch_mode = QSEARCH_CASE_INSENSITIVE;
1319 else if (qmode >= QSEARCH_NUM)
1320 panels_options.qsearch_mode = QSEARCH_PANEL_CASE;
1321 else
1322 panels_options.qsearch_mode = (qsearch_mode_t) qmode;
1324 /* overwrite by new parameters */
1325 if (mc_config_has_group (mc_main_config, panels_section))
1327 for (i = 0; panels_ini_options[i].opt_name != NULL; i++)
1328 *panels_ini_options[i].opt_addr =
1329 mc_config_get_bool (mc_main_config, panels_section,
1330 panels_ini_options[i].opt_name,
1331 *panels_ini_options[i].opt_addr);
1333 qmode = mc_config_get_int (mc_main_config, panels_section,
1334 "quick_search_mode", (int) panels_options.qsearch_mode);
1335 if (qmode < 0)
1336 panels_options.qsearch_mode = QSEARCH_CASE_INSENSITIVE;
1337 else if (qmode >= QSEARCH_NUM)
1338 panels_options.qsearch_mode = QSEARCH_PANEL_CASE;
1339 else
1340 panels_options.qsearch_mode = (qsearch_mode_t) qmode;
1344 /* --------------------------------------------------------------------------------------------- */
1347 Save panels options in [Panels] section.
1349 void
1350 panels_save_options (void)
1352 size_t i;
1354 for (i = 0; panels_ini_options[i].opt_name != NULL; i++)
1355 mc_config_set_bool (mc_main_config, panels_section,
1356 panels_ini_options[i].opt_name, *panels_ini_options[i].opt_addr);
1358 mc_config_set_int (mc_main_config, panels_section,
1359 "quick_search_mode", (int) panels_options.qsearch_mode);
1362 /* --------------------------------------------------------------------------------------------- */