g_strcasecmp() function is deprecated.
[midnight-commander.git] / src / setup.c
blob7e0c0c58497e8d0b3de0f1e071bf2a70bf37570f
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
42 #include "lib/vfs/mc-vfs/gc.h"
43 #endif
45 #ifdef USE_NETCODE
46 #include "lib/vfs/mc-vfs/ftpfs.h"
47 #include "lib/vfs/mc-vfs/fish.h"
48 #endif
50 #include "args.h"
51 #include "dir.h"
52 #include "panel.h"
53 #include "main.h"
54 #include "tree.h" /* xtree_mode */
55 #include "hotlist.h" /* load/save/done hotlist */
56 #include "panelize.h" /* load/save/done panelize */
57 #include "layout.h"
58 #include "menu.h" /* menubar_visible declaration */
59 #include "cmd.h"
60 #include "file.h" /* safe_delete */
61 #include "keybind.h" /* lookup_action */
62 #include "wtools.h"
64 #ifdef HAVE_CHARSET
65 #include "charsets.h"
66 #endif
68 #ifdef USE_INTERNAL_EDIT
69 #include "src/editor/edit.h"
70 #endif
72 #include "src/viewer/mcviewer.h" /* For the externs */
74 #include "setup.h"
76 /*** global variables **************************************************/
78 char *profile_name; /* .mc/ini */
79 char *global_profile_name; /* mc.lib */
81 char *setup_color_string;
82 char *term_color_string;
83 char *color_terminal_string;
85 panel_view_mode_t startup_left_mode;
86 panel_view_mode_t startup_right_mode;
88 int setup_copymove_persistent_attr = 1;
90 /* Ugly hack to allow panel_save_setup to work as a place holder for */
91 /* default panel values */
92 int saving_setup;
94 panels_options_t panels_options = {
95 .kilobyte_si = FALSE,
96 .mix_all_files = FALSE,
97 .show_backups = TRUE,
98 .show_dot_files = TRUE,
99 .fast_reload = FALSE,
100 .fast_reload_msg_shown = FALSE,
101 .mark_moves_down = TRUE,
102 .reverse_files_only = TRUE,
103 .auto_save_setup = FALSE,
104 .navigate_with_arrows = FALSE,
105 .scroll_pages = TRUE,
106 .mouse_move_pages = TRUE,
107 .filetype_mode = TRUE,
108 .permission_mode = FALSE,
109 .qsearch_mode = QSEARCH_PANEL_CASE
112 /*** file scope macro definitions **************************************/
114 /* In order to use everywhere the same setup for the locale we use defines */
115 #define FMTYEAR _("%b %e %Y")
116 #define FMTTIME _("%b %e %H:%M")
118 /*** file scope type declarations **************************************/
120 /*** file scope variables **********************************************/
122 static char *panels_profile_name = NULL; /* .mc/panels.ini */
124 /* *INDENT-OFF* */
125 static const struct
127 const char *key;
128 int list_type;
129 } list_types [] = {
130 { "full", list_full },
131 { "brief", list_brief },
132 { "long", list_long },
133 { "user", list_user },
134 { NULL, 0 }
137 static const struct
139 const char *opt_name;
140 panel_view_mode_t opt_type;
141 } panel_types [] = {
142 { "listing", view_listing },
143 { "quickview", view_quick },
144 { "info", view_info },
145 { "tree", view_tree },
146 { NULL, view_listing }
149 static const struct
151 const char *opt_name;
152 int *opt_addr;
153 } layout [] = {
154 { "equal_split", &equal_split },
155 { "first_panel_size", &first_panel_size },
156 { "message_visible", &message_visible },
157 { "keybar_visible", &keybar_visible },
158 { "xterm_title", &xterm_title },
159 { "output_lines", &output_lines },
160 { "command_prompt", &command_prompt },
161 { "menubar_visible", &menubar_visible },
162 { "show_mini_info", &show_mini_info },
163 { "free_space", &free_space },
164 { NULL, NULL }
167 static const struct
169 const char *opt_name;
170 int *opt_addr;
171 } int_options [] = {
172 { "verbose", &verbose },
173 { "pause_after_run", &pause_after_run },
174 { "shell_patterns", &easy_patterns },
175 { "auto_save_setup", &auto_save_setup },
176 { "auto_menu", &auto_menu },
177 { "use_internal_view", &use_internal_view },
178 { "use_internal_edit", &use_internal_edit },
179 { "clear_before_exec", &clear_before_exec },
180 { "confirm_delete", &confirm_delete },
181 { "confirm_overwrite", &confirm_overwrite },
182 { "confirm_execute", &confirm_execute },
183 { "confirm_history_cleanup", &confirm_history_cleanup },
184 { "confirm_exit", &confirm_exit },
185 { "confirm_directory_hotlist_delete", &confirm_directory_hotlist_delete },
186 { "safe_delete", &safe_delete },
187 { "mouse_repeat_rate", &mou_auto_repeat },
188 { "double_click_speed", &double_click_speed },
189 #ifndef HAVE_CHARSET
190 { "eight_bit_clean", &eight_bit_clean },
191 { "full_eight_bits", &full_eight_bits },
192 #endif /* !HAVE_CHARSET */
193 { "use_8th_bit_as_meta", &use_8th_bit_as_meta },
194 { "confirm_view_dir", &confirm_view_dir },
195 { "mouse_move_pages_viewer", &mcview_mouse_move_pages },
196 { "mouse_close_dialog", &mouse_close_dialog},
197 { "fast_refresh", &fast_refresh },
198 { "drop_menus", &drop_menus },
199 { "wrap_mode", &mcview_global_wrap_mode},
200 { "old_esc_mode", &old_esc_mode },
201 { "old_esc_mode_timeout", &old_esc_mode_timeout },
202 { "cd_symlinks", &cd_symlinks },
203 { "show_all_if_ambiguous", &show_all_if_ambiguous },
204 { "max_dirt_limit", &mcview_max_dirt_limit },
205 { "torben_fj_mode", &torben_fj_mode },
206 { "use_file_to_guess_type", &use_file_to_check_type },
207 { "alternate_plus_minus", &alternate_plus_minus },
208 { "only_leading_plus_minus", &only_leading_plus_minus },
209 { "show_output_starts_shell", &output_starts_shell },
210 { "xtree_mode", &xtree_mode },
211 { "num_history_items_recorded", &num_history_items_recorded },
212 { "file_op_compute_totals", &file_op_compute_totals },
213 { "classic_progressbar", &classic_progressbar},
214 #ifdef ENABLE_VFS
215 { "vfs_timeout", &vfs_timeout },
216 #ifdef USE_NETCODE
217 { "ftpfs_directory_timeout", &ftpfs_directory_timeout },
218 { "use_netrc", &use_netrc },
219 { "ftpfs_retry_seconds", &ftpfs_retry_seconds },
220 { "ftpfs_always_use_proxy", &ftpfs_always_use_proxy },
221 { "ftpfs_use_passive_connections", &ftpfs_use_passive_connections },
222 { "ftpfs_use_passive_connections_over_proxy", &ftpfs_use_passive_connections_over_proxy },
223 { "ftpfs_use_unix_list_options", &ftpfs_use_unix_list_options },
224 { "ftpfs_first_cd_then_ls", &ftpfs_first_cd_then_ls },
225 { "fish_directory_timeout", &fish_directory_timeout },
226 #endif /* USE_NETCODE */
227 #endif /* ENABLE_VFS */
228 #ifdef USE_INTERNAL_EDIT
229 { "editor_word_wrap_line_length", &option_word_wrap_line_length },
230 { "editor_tab_spacing", &option_tab_spacing },
231 { "editor_fill_tabs_with_spaces", &option_fill_tabs_with_spaces },
232 { "editor_return_does_auto_indent", &option_return_does_auto_indent },
233 { "editor_backspace_through_tabs", &option_backspace_through_tabs },
234 { "editor_fake_half_tabs", &option_fake_half_tabs },
235 { "editor_option_save_mode", &option_save_mode },
236 { "editor_option_save_position", &option_save_position },
237 { "editor_option_auto_para_formatting", &option_auto_para_formatting },
238 { "editor_option_typewriter_wrap", &option_typewriter_wrap },
239 { "editor_edit_confirm_save", &edit_confirm_save },
240 { "editor_syntax_highlighting", &option_syntax_highlighting },
241 { "editor_persistent_selections", &option_persistent_selections },
242 { "editor_cursor_beyond_eol", &option_cursor_beyond_eol },
243 { "editor_visible_tabs", &visible_tabs },
244 { "editor_visible_spaces", &visible_tws },
245 { "editor_line_state", &option_line_state },
246 { "editor_simple_statusbar", &simple_statusbar },
247 { "editor_check_new_line", &option_check_nl_at_eof },
248 { "editor_show_right_margin", &show_right_margin },
249 #endif /* USE_INTERNAL_EDIT */
250 { "nice_rotating_dash", &nice_rotating_dash },
251 { "horizontal_split", &horizontal_split },
252 { "mcview_remember_file_position", &mcview_remember_file_position },
253 { "auto_fill_mkdir_name", &auto_fill_mkdir_name },
254 { "copymove_persistent_attr", &setup_copymove_persistent_attr },
255 { "select_flags", &select_flags },
256 { NULL, NULL }
259 static const struct
261 const char *opt_name;
262 char **opt_addr;
263 const char *opt_defval;
264 } str_options[] = {
265 #ifdef USE_INTERNAL_EDIT
266 { "editor_backup_extension", &option_backup_ext, "~" },
267 #endif
268 { "mcview_eof", &mcview_show_eof, "" },
269 { NULL, NULL, NULL }
272 static const struct
274 const char *opt_name;
275 const char *opt_old_name;
276 gboolean *opt_addr;
277 } panels_ini_options[] = {
278 { "kilobyte_si", NULL, &panels_options.kilobyte_si },
279 { "mix_all_files", NULL, &panels_options.mix_all_files },
280 { "show_backups", NULL, &panels_options.show_backups },
281 { "show_dot_files", NULL, &panels_options.show_dot_files },
282 { "fast_reload", NULL, &panels_options.fast_reload },
283 { "fast_reload_msg_shown", NULL, &panels_options.fast_reload_msg_shown },
284 { "mark_moves_down", NULL, &panels_options.mark_moves_down },
285 { "reverse_files_only", NULL, &panels_options.reverse_files_only },
286 { "auto_save_setup_panels", "auto_save_setup", &panels_options.auto_save_setup },
287 { "navigate_with_arrows", NULL, &panels_options.navigate_with_arrows },
288 { "panel_scroll_pages", "scroll_pages", &panels_options.scroll_pages },
289 { "mouse_move_pages", NULL, &panels_options.mouse_move_pages },
290 { "filetype_mode", NULL, &panels_options.filetype_mode },
291 { "permission_mode", NULL, &panels_options.permission_mode },
292 { NULL, NULL, NULL }
294 /* *INDENT-ON* */
296 static const char *panels_section = "Panels";
298 /*** file scope functions **********************************************/
301 Get name of config file.
303 \param subdir
304 if not NULL, then config also search into specified subdir.
306 \param config_file_name
307 If specified filename is relative, then will search in standart patches.
309 \return
310 Newly allocated path to config name or NULL if file not found.
312 If config_file_name is a relative path, then search config in stantart pathes.
314 static char *
315 load_setup_get_full_config_name (const char *subdir, const char *config_file_name)
318 TODO: IMHO, in future this function must be placed into mc_config module.
319 Also, need to rename stupid mc_home and mc_home_alt to mc_sysconfdir and mc_datadir;
320 home_mc => mc_user_homedir
322 char *lc_basename, *ret;
324 if (config_file_name == NULL)
325 return NULL;
327 if (g_path_is_absolute (config_file_name))
328 return g_strdup (config_file_name);
331 lc_basename = g_path_get_basename (config_file_name);
332 if (lc_basename == NULL)
333 return NULL;
335 if (subdir != NULL)
336 ret = g_build_filename (home_dir, MC_USERCONF_DIR, subdir, lc_basename, NULL);
337 else
338 ret = g_build_filename (home_dir, MC_USERCONF_DIR, lc_basename, NULL);
340 if (exist_file (ret))
342 g_free (lc_basename);
343 return ret;
345 g_free (ret);
347 if (subdir != NULL)
348 ret = g_build_filename (mc_home, subdir, lc_basename, NULL);
349 else
350 ret = g_build_filename (mc_home, lc_basename, NULL);
352 if (exist_file (ret))
354 g_free (lc_basename);
355 return ret;
357 g_free (ret);
359 if (subdir != NULL)
360 ret = g_build_filename (mc_home_alt, subdir, lc_basename, NULL);
361 else
362 ret = g_build_filename (mc_home_alt, lc_basename, NULL);
364 g_free (lc_basename);
366 if (exist_file (ret))
367 return ret;
369 g_free (ret);
370 return NULL;
374 static const char *
375 setup__is_cfg_group_must_panel_config (const char *grp)
377 return (!strcasecmp ("Dirs", grp) ||
378 !strcasecmp ("Temporal:New Right Panel", grp) ||
379 !strcasecmp ("Temporal:New Left Panel", grp) ||
380 !strcasecmp ("New Left Panel", grp) || !strcasecmp ("New Right Panel", grp))
381 ? grp : NULL;
384 static void
385 setup__move_panels_config_into_separate_file (const char *profile)
387 mc_config_t *tmp_cfg;
388 char **groups, **curr_grp;
389 const char *need_grp;
391 if (!exist_file (profile))
392 return;
394 tmp_cfg = mc_config_init (profile);
395 if (!tmp_cfg)
396 return;
398 curr_grp = groups = mc_config_get_groups (tmp_cfg, NULL);
399 if (!groups)
401 mc_config_deinit (tmp_cfg);
402 return;
405 while (*curr_grp)
407 if (setup__is_cfg_group_must_panel_config (*curr_grp) == NULL)
408 mc_config_del_group (tmp_cfg, *curr_grp);
409 curr_grp++;
412 mc_config_save_to_file (tmp_cfg, panels_profile_name, NULL);
413 mc_config_deinit (tmp_cfg);
415 tmp_cfg = mc_config_init (profile);
416 if (!tmp_cfg)
418 g_strfreev (groups);
419 return;
422 curr_grp = groups;
424 while (*curr_grp)
426 need_grp = setup__is_cfg_group_must_panel_config (*curr_grp);
427 if (need_grp != NULL)
429 mc_config_del_group (tmp_cfg, need_grp);
431 curr_grp++;
433 g_strfreev (groups);
435 mc_config_save_file (tmp_cfg, NULL);
436 mc_config_deinit (tmp_cfg);
440 Create new mc_config object from specified ini-file or
441 append data to existing mc_config object from ini-file
444 static void
445 load_setup_init_config_from_file (mc_config_t ** config, const char *fname)
448 TODO: IMHO, in future this function must be placed into mc_config module.
450 if (exist_file (fname))
452 if (*config != NULL)
453 mc_config_read_file (*config, fname);
454 else
455 *config = mc_config_init (fname);
459 static void
460 load_layout (void)
462 size_t i;
464 for (i = 0; layout[i].opt_name != NULL; i++)
465 *layout[i].opt_addr = mc_config_get_int (mc_main_config, "Layout",
466 layout[i].opt_name, *layout[i].opt_addr);
469 static void
470 load_keys_from_section (const char *terminal, mc_config_t * cfg)
472 char *section_name;
473 gchar **profile_keys, **keys;
474 gchar **values, **curr_values;
475 char *valcopy, *value;
476 long key_code;
477 gsize len, values_len;
479 if (terminal == NULL)
480 return;
482 section_name = g_strconcat ("terminal:", terminal, (char *) NULL);
483 profile_keys = keys = mc_config_get_keys (cfg, section_name, &len);
485 while (*profile_keys != NULL)
487 /* copy=other causes all keys from [terminal:other] to be loaded. */
488 if (g_ascii_strcasecmp (*profile_keys, "copy") == 0)
490 valcopy = mc_config_get_string (cfg, section_name, *profile_keys, "");
491 load_keys_from_section (valcopy, cfg);
492 g_free (valcopy);
493 profile_keys++;
494 continue;
497 curr_values = values =
498 mc_config_get_string_list (cfg, section_name, *profile_keys, &values_len);
500 key_code = lookup_key (*profile_keys, NULL);
502 if (key_code != 0)
504 if (curr_values != NULL)
506 while (*curr_values != NULL)
508 valcopy = convert_controls (*curr_values);
509 define_sequence (key_code, valcopy, MCKEY_NOACTION);
510 g_free (valcopy);
511 curr_values++;
514 else
516 value = mc_config_get_string (cfg, section_name, *profile_keys, "");
517 valcopy = convert_controls (value);
518 define_sequence (key_code, valcopy, MCKEY_NOACTION);
519 g_free (valcopy);
520 g_free (value);
524 profile_keys++;
526 if (values != NULL)
527 g_strfreev (values);
529 g_strfreev (keys);
530 g_free (section_name);
533 static void
534 load_keymap_from_section (const char *section_name, GArray * keymap, mc_config_t * cfg)
536 gchar **profile_keys, **keys;
537 gchar **values, **curr_values;
538 char *valcopy, *value;
539 int action;
540 gsize len, values_len;
542 if (section_name == NULL)
543 return;
545 profile_keys = keys = mc_config_get_keys (cfg, section_name, &len);
547 while (*profile_keys != NULL)
549 curr_values = values =
550 mc_config_get_string_list (cfg, section_name, *profile_keys, &values_len);
552 action = lookup_action (*profile_keys);
554 if (action > 0)
556 if (curr_values != NULL)
558 while (*curr_values != NULL)
560 valcopy = convert_controls (*curr_values);
561 keybind_cmd_bind (keymap, valcopy, action);
562 g_free (valcopy);
563 curr_values++;
566 else
568 value = mc_config_get_string (cfg, section_name, *profile_keys, "");
569 valcopy = convert_controls (value);
570 /* define_sequence (key_code, valcopy, MCKEY_NOACTION); */
571 g_free (valcopy);
572 g_free (value);
576 profile_keys++;
578 if (values != NULL)
579 g_strfreev (values);
581 g_strfreev (keys);
584 static mc_config_t *
585 load_setup_get_keymap_profile_config (void)
588 TODO: IMHO, in future this function must be placed into mc_config module.
590 mc_config_t *keymap_config = NULL;
591 char *fname, *fname2;
593 /* 1) /usr/share/mc (mc_home_alt) */
594 fname = g_build_filename (mc_home_alt, GLOBAL_KEYMAP_FILE, NULL);
595 load_setup_init_config_from_file (&keymap_config, fname);
596 g_free (fname);
598 /* 2) /etc/mc (mc_home) */
599 fname = g_build_filename (mc_home, GLOBAL_KEYMAP_FILE, NULL);
600 load_setup_init_config_from_file (&keymap_config, fname);
601 g_free (fname);
603 /* 3) ~/.mc (home_dir?) */
604 fname = g_build_filename (home_dir, MC_USERCONF_DIR, GLOBAL_KEYMAP_FILE, NULL);
605 load_setup_init_config_from_file (&keymap_config, fname);
606 g_free (fname);
608 /* 4) main config; [Midnight Commander] -> keymap */
610 fname2 =
611 mc_config_get_string (mc_main_config, CONFIG_APP_SECTION, "keymap", GLOBAL_KEYMAP_FILE);
612 fname = load_setup_get_full_config_name (NULL, fname2);
613 if (fname != NULL)
615 load_setup_init_config_from_file (&keymap_config, fname);
616 g_free (fname);
618 g_free (fname2);
620 /* 5) getenv("MC_KEYMAP") */
621 fname = load_setup_get_full_config_name (NULL, g_getenv ("MC_KEYMAP"));
622 if (fname != NULL)
624 load_setup_init_config_from_file (&keymap_config, fname);
625 g_free (fname);
628 /* 6) --keymap=<keymap> */
629 fname = load_setup_get_full_config_name (NULL, mc_args__keymap_file);
630 if (fname != NULL)
632 load_setup_init_config_from_file (&keymap_config, fname);
633 g_free (fname);
636 return keymap_config;
639 static panel_view_mode_t
640 setup__load_panel_state (const char *section)
642 char *buffer;
643 size_t i;
644 panel_view_mode_t mode = view_listing;
646 /* Load the display mode */
647 buffer = mc_config_get_string (mc_panels_config, section, "display", "listing");
649 for (i = 0; panel_types[i].opt_name != NULL; i++)
650 if (g_ascii_strcasecmp (panel_types[i].opt_name, buffer) == 0)
652 mode = panel_types[i].opt_type;
653 break;
656 g_free (buffer);
658 return mode;
661 static void
662 panel_save_type (const char *section, panel_view_mode_t type)
664 size_t i;
666 for (i = 0; panel_types[i].opt_name != NULL; i++)
667 if (panel_types[i].opt_type == type)
669 mc_config_set_string (mc_panels_config, section, "display", panel_types[i].opt_name);
670 break;
674 /*** public functions **************************************************/
676 char *
677 setup_init (void)
679 char *profile;
680 char *inifile;
682 if (profile_name != NULL)
683 return profile_name;
685 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
686 if (!exist_file (profile))
688 inifile = concat_dir_and_file (mc_home, "mc.ini");
689 if (exist_file (inifile))
691 g_free (profile);
692 profile = inifile;
694 else
696 g_free (inifile);
697 inifile = concat_dir_and_file (mc_home_alt, "mc.ini");
698 if (exist_file (inifile))
700 g_free (profile);
701 profile = inifile;
703 else
704 g_free (inifile);
708 profile_name = profile;
710 return profile;
713 void
714 load_setup (void)
716 char *profile;
717 size_t i;
718 char *buffer;
719 const char *kt;
721 profile = setup_init ();
723 /* mc.lib is common for all users, but has priority lower than
724 ~/.mc/ini. FIXME: it's only used for keys and treestore now */
725 global_profile_name = concat_dir_and_file (mc_home, MC_GLOBAL_CONFIG_FILE);
726 if (!exist_file (global_profile_name))
728 g_free (global_profile_name);
729 global_profile_name = concat_dir_and_file (mc_home_alt, MC_GLOBAL_CONFIG_FILE);
732 panels_profile_name = g_build_filename (home_dir, MC_USERCONF_DIR, MC_PANELS_FILE, NULL);
734 mc_main_config = mc_config_init (profile);
736 if (!exist_file (panels_profile_name))
737 setup__move_panels_config_into_separate_file (profile);
739 mc_panels_config = mc_config_init (panels_profile_name);
741 /* Load integer boolean options */
742 for (i = 0; int_options[i].opt_name != NULL; i++)
743 *int_options[i].opt_addr =
744 mc_config_get_int (mc_main_config, CONFIG_APP_SECTION, int_options[i].opt_name,
745 *int_options[i].opt_addr);
747 /* overwrite old_esc_mode_timeout */
748 kt = getenv ("KEYBOARD_KEY_TIMEOUT_US");
749 if ((kt != NULL) && (kt[0] != '\0'))
750 old_esc_mode_timeout = atoi (kt);
752 /* Load string options */
753 for (i = 0; str_options[i].opt_name != NULL; i++)
754 *str_options[i].opt_addr =
755 mc_config_get_string (mc_main_config, CONFIG_APP_SECTION, str_options[i].opt_name,
756 str_options[i].opt_defval);
758 load_layout ();
759 panels_load_options ();
760 load_panelize ();
762 startup_left_mode = setup__load_panel_state ("New Left Panel");
763 startup_right_mode = setup__load_panel_state ("New Right Panel");
765 /* At least one of the panels is a listing panel */
766 if (startup_left_mode != view_listing && startup_right_mode != view_listing)
767 startup_left_mode = view_listing;
769 if (mc_run_param1 == NULL)
771 buffer = mc_config_get_string (mc_panels_config, "Dirs", "other_dir", ".");
772 if (vfs_file_is_local (buffer))
773 mc_run_param1 = buffer;
774 else
775 g_free (buffer);
778 boot_current_is_left = mc_config_get_int (mc_panels_config, "Dirs", "current_is_left", 1);
780 /* Load time formats */
781 user_recent_timeformat =
782 mc_config_get_string (mc_main_config, "Misc", "timeformat_recent", FMTTIME);
783 user_old_timeformat = mc_config_get_string (mc_main_config, "Misc", "timeformat_old", FMTYEAR);
785 #ifdef USE_NETCODE
786 ftpfs_proxy_host = mc_config_get_string (mc_main_config, "Misc", "ftp_proxy_host", "gate");
787 #endif
789 /* The default color and the terminal dependent color */
790 setup_color_string = mc_config_get_string (mc_main_config, "Colors", "base_color", "");
791 term_color_string = mc_config_get_string (mc_main_config, "Colors", getenv ("TERM"), "");
792 color_terminal_string = mc_config_get_string (mc_main_config, "Colors", "color_terminals", "");
794 /* Load the directory history */
795 /* directory_history_load (); */
796 /* Remove the temporal entries */
797 #if defined(ENABLE_VFS) && defined (USE_NETCODE)
798 ftpfs_init_passwd ();
799 #endif /* ENABLE_VFS && USE_NETCODE */
801 #ifdef HAVE_CHARSET
802 if (load_codepages_list () > 0)
804 buffer = mc_config_get_string (mc_main_config, "Misc", "display_codepage", "");
805 if (buffer[0] != '\0')
807 display_codepage = get_codepage_index (buffer);
808 cp_display = get_codepage_id (display_codepage);
810 g_free (buffer);
811 buffer = mc_config_get_string (mc_main_config, "Misc", "source_codepage", "");
812 if (buffer[0] != '\0')
814 default_source_codepage = get_codepage_index (buffer);
815 source_codepage = default_source_codepage; /* May be source_codepage don't needed this */
816 cp_source = get_codepage_id (source_codepage);
818 g_free (buffer);
821 autodetect_codeset = mc_config_get_string (mc_main_config, "Misc", "autodetect_codeset", "");
822 if ((autodetect_codeset[0] != '\0') && (strcmp (autodetect_codeset, "off") != 0))
823 is_autodetect_codeset_enabled = TRUE;
825 g_free (init_translation_table (source_codepage, display_codepage));
826 buffer = (char *) get_codepage_id (display_codepage);
827 if (buffer != NULL)
828 utf8_display = str_isutf8 (buffer);
829 #endif /* HAVE_CHARSET */
832 gboolean
833 save_setup (void)
835 char *tmp_profile;
836 gboolean ret;
838 saving_setup = 1;
840 save_config ();
841 save_layout ();
842 panels_save_options ();
843 save_hotlist ();
844 save_panelize ();
845 save_panel_types ();
846 /* directory_history_save (); */
848 #if defined(ENABLE_VFS) && defined (USE_NETCODE)
849 mc_config_set_string (mc_main_config, "Misc", "ftpfs_password", ftpfs_anonymous_passwd);
850 if (ftpfs_proxy_host)
851 mc_config_set_string (mc_main_config, "Misc", "ftp_proxy_host", ftpfs_proxy_host);
852 #endif /* ENABLE_VFS && USE_NETCODE */
854 #ifdef HAVE_CHARSET
855 mc_config_set_string (mc_main_config, "Misc", "display_codepage",
856 get_codepage_id (display_codepage));
857 mc_config_set_string (mc_main_config, "Misc", "source_codepage",
858 get_codepage_id (default_source_codepage));
859 mc_config_set_string (mc_main_config, "Misc", "autodetect_codeset", autodetect_codeset);
860 #endif /* HAVE_CHARSET */
861 tmp_profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
862 ret = mc_config_save_to_file (mc_main_config, tmp_profile, NULL);
864 g_free (tmp_profile);
865 saving_setup = 0;
866 return ret;
869 void
870 done_setup (void)
872 size_t i;
874 g_free (profile_name);
875 g_free (global_profile_name);
876 g_free (color_terminal_string);
877 g_free (term_color_string);
878 g_free (setup_color_string);
879 g_free (panels_profile_name);
880 mc_config_deinit (mc_main_config);
881 mc_config_deinit (mc_panels_config);
883 g_free (user_recent_timeformat);
884 g_free (user_old_timeformat);
886 for (i = 0; str_options[i].opt_name != NULL; i++)
887 g_free (*str_options[i].opt_addr);
889 done_hotlist ();
890 done_panelize ();
891 /* directory_history_free (); */
894 void
895 save_config (void)
897 char *profile;
898 GError *error = NULL;
899 size_t i;
901 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
903 /* Save integer options */
904 for (i = 0; int_options[i].opt_name != NULL; i++)
905 mc_config_set_int (mc_main_config, CONFIG_APP_SECTION, int_options[i].opt_name,
906 *int_options[i].opt_addr);
908 /* Save string options */
909 for (i = 0; str_options[i].opt_name != NULL; i++)
910 mc_config_set_string (mc_main_config, CONFIG_APP_SECTION, str_options[i].opt_name,
911 *str_options[i].opt_addr);
913 if (!mc_config_save_to_file (mc_main_config, profile, &error))
914 setup_save_config_show_error (profile, &error);
916 g_free (profile);
919 void
920 setup_save_config_show_error (const char *filename, GError ** error)
922 if (error != NULL && *error != NULL)
924 message (D_ERROR, MSG_ERROR, _("Cannot save file %s:\n%s"), filename, (*error)->message);
925 g_error_free (*error);
926 *error = NULL;
930 void
931 save_layout (void)
933 char *profile;
934 size_t i;
936 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
937 /* Save integer options */
938 for (i = 0; layout[i].opt_name != NULL; i++)
939 mc_config_set_int (mc_main_config, "Layout", layout[i].opt_name, *layout[i].opt_addr);
940 mc_config_save_to_file (mc_main_config, profile, NULL);
941 g_free (profile);
944 void
945 load_key_defs (void)
948 * Load keys from mc.lib before ~/.mc/ini, so that the user
949 * definitions override global settings.
951 mc_config_t *mc_global_config;
953 mc_global_config = mc_config_init (global_profile_name);
954 if (mc_global_config != NULL)
956 load_keys_from_section ("general", mc_global_config);
957 load_keys_from_section (getenv ("TERM"), mc_global_config);
958 mc_config_deinit (mc_global_config);
961 load_keys_from_section ("general", mc_main_config);
962 load_keys_from_section (getenv ("TERM"), mc_main_config);
965 #if defined(ENABLE_VFS) && defined (USE_NETCODE)
966 char *
967 load_anon_passwd (void)
969 char *buffer;
971 buffer = mc_config_get_string (mc_main_config, "Misc", "ftpfs_password", "");
973 if ((buffer != NULL) && (buffer[0] != '\0'))
974 return buffer;
976 g_free (buffer);
977 return NULL;
979 #endif /* ENABLE_VFS && USE_NETCODE */
981 void
982 load_keymap_defs (void)
985 * Load keymap from GLOBAL_KEYMAP_FILE before ~/.mc/keymap, so that the user
986 * definitions override global settings.
988 mc_config_t *mc_global_keymap;
990 mc_global_keymap = load_setup_get_keymap_profile_config ();
992 if (mc_global_keymap != NULL)
994 #ifdef USE_INTERNAL_EDIT
995 editor_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
996 load_keymap_from_section ("editor", editor_keymap, mc_global_keymap);
997 editor_x_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
998 load_keymap_from_section ("editor:xmap", editor_x_keymap, mc_global_keymap);
999 #endif
1001 viewer_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1002 load_keymap_from_section ("viewer", viewer_keymap, mc_global_keymap);
1003 viewer_hex_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1004 load_keymap_from_section ("viewer:hex", viewer_hex_keymap, mc_global_keymap);
1006 main_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1007 load_keymap_from_section ("main", main_keymap, mc_global_keymap);
1008 main_x_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1009 load_keymap_from_section ("main:xmap", main_x_keymap, mc_global_keymap);
1011 panel_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1012 load_keymap_from_section ("panel", panel_keymap, mc_global_keymap);
1014 input_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1015 load_keymap_from_section ("input", input_keymap, mc_global_keymap);
1017 tree_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1018 load_keymap_from_section ("tree", tree_keymap, mc_global_keymap);
1020 help_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1021 load_keymap_from_section ("help", help_keymap, mc_global_keymap);
1023 dialog_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1024 load_keymap_from_section ("dialog", dialog_keymap, mc_global_keymap);
1026 #ifdef USE_DIFF_VIEW
1027 diff_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1028 load_keymap_from_section ("diffviewer", diff_keymap, mc_global_keymap);
1029 #endif
1030 mc_config_deinit (mc_global_keymap);
1033 main_map = default_main_map;
1034 if (main_keymap && main_keymap->len > 0)
1035 main_map = (global_keymap_t *) main_keymap->data;
1037 main_x_map = default_main_x_map;
1038 if (main_x_keymap && main_x_keymap->len > 0)
1039 main_x_map = (global_keymap_t *) main_x_keymap->data;
1041 panel_map = default_panel_keymap;
1042 if (panel_keymap && panel_keymap->len > 0)
1043 panel_map = (global_keymap_t *) panel_keymap->data;
1045 input_map = default_input_keymap;
1046 if (input_keymap && input_keymap->len > 0)
1047 input_map = (global_keymap_t *) input_keymap->data;
1049 tree_map = default_tree_keymap;
1050 if (tree_keymap && tree_keymap->len > 0)
1051 tree_map = (global_keymap_t *) tree_keymap->data;
1053 help_map = default_help_keymap;
1054 if (help_keymap && help_keymap->len > 0)
1055 help_map = (global_keymap_t *) help_keymap->data;
1057 dialog_map = default_dialog_keymap;
1058 if (dialog_keymap && dialog_keymap->len > 0)
1059 dialog_map = (global_keymap_t *) dialog_keymap->data;
1061 #ifdef USE_DIFF_VIEW
1062 diff_map = default_diff_keymap;
1063 if (diff_keymap && diff_keymap->len > 0)
1064 diff_map = (global_keymap_t *) diff_keymap->data;
1065 #endif
1069 void
1070 free_keymap_defs (void)
1072 #ifdef USE_INTERNAL_EDIT
1073 if (editor_keymap != NULL)
1074 g_array_free (editor_keymap, TRUE);
1075 if (editor_x_keymap != NULL)
1076 g_array_free (editor_x_keymap, TRUE);
1077 #endif
1078 if (viewer_keymap != NULL)
1079 g_array_free (viewer_keymap, TRUE);
1080 if (viewer_hex_keymap != NULL)
1081 g_array_free (viewer_hex_keymap, TRUE);
1082 if (main_keymap != NULL)
1083 g_array_free (main_keymap, TRUE);
1084 if (main_x_keymap != NULL)
1085 g_array_free (main_x_keymap, TRUE);
1086 if (panel_keymap != NULL)
1087 g_array_free (panel_keymap, TRUE);
1088 if (input_keymap != NULL)
1089 g_array_free (input_keymap, TRUE);
1090 if (tree_keymap != NULL)
1091 g_array_free (tree_keymap, TRUE);
1092 if (help_keymap != NULL)
1093 g_array_free (help_keymap, TRUE);
1094 if (dialog_keymap != NULL)
1095 g_array_free (dialog_keymap, TRUE);
1096 #ifdef USE_DIFF_VIEW
1097 if (diff_keymap != NULL)
1098 g_array_free (diff_keymap, TRUE);
1099 #endif
1102 void
1103 panel_load_setup (WPanel * panel, const char *section)
1105 size_t i;
1106 char *buffer, buffer2[BUF_TINY];
1108 panel->reverse = mc_config_get_int (mc_panels_config, section, "reverse", 0);
1109 panel->case_sensitive =
1110 mc_config_get_int (mc_panels_config, section, "case_sensitive",
1111 OS_SORT_CASE_SENSITIVE_DEFAULT);
1112 panel->exec_first = mc_config_get_int (mc_panels_config, section, "exec_first", 0);
1114 /* Load sort order */
1115 buffer = mc_config_get_string (mc_panels_config, section, "sort_order", "name");
1116 panel->current_sort_field = panel_get_field_by_id (buffer);
1117 if (panel->current_sort_field == NULL)
1118 panel->current_sort_field = panel_get_field_by_id ("name");
1120 g_free (buffer);
1122 /* Load the listing mode */
1123 buffer = mc_config_get_string (mc_panels_config, section, "list_mode", "full");
1124 panel->list_type = list_full;
1125 for (i = 0; list_types[i].key != NULL; i++)
1126 if (g_ascii_strcasecmp (list_types[i].key, buffer) == 0)
1128 panel->list_type = list_types[i].list_type;
1129 break;
1131 g_free (buffer);
1133 /* User formats */
1134 g_free (panel->user_format);
1135 panel->user_format =
1136 mc_config_get_string (mc_panels_config, section, "user_format", DEFAULT_USER_FORMAT);
1138 for (i = 0; i < LIST_TYPES; i++)
1140 g_free (panel->user_status_format[i]);
1141 g_snprintf (buffer2, BUF_TINY, "user_status%lld", (long long) i);
1142 panel->user_status_format[i] =
1143 mc_config_get_string (mc_panels_config, section, buffer2, DEFAULT_USER_FORMAT);
1146 panel->user_mini_status = mc_config_get_int (mc_panels_config, section, "user_mini_status", 0);
1149 void
1150 panel_save_setup (struct WPanel *panel, const char *section)
1152 char buffer[BUF_TINY];
1153 size_t i;
1155 mc_config_set_int (mc_panels_config, section, "reverse", panel->reverse);
1156 mc_config_set_int (mc_panels_config, section, "case_sensitive", panel->case_sensitive);
1157 mc_config_set_int (mc_panels_config, section, "exec_first", panel->exec_first);
1159 mc_config_set_string (mc_panels_config, section, "sort_order", panel->current_sort_field->id);
1161 for (i = 0; list_types[i].key != NULL; i++)
1162 if (list_types[i].list_type == panel->list_type)
1164 mc_config_set_string (mc_panels_config, section, "list_mode", list_types[i].key);
1165 break;
1168 mc_config_set_string (mc_panels_config, section, "user_format", panel->user_format);
1170 for (i = 0; i < LIST_TYPES; i++)
1172 g_snprintf (buffer, BUF_TINY, "user_status%lld", (long long) i);
1173 mc_config_set_string (mc_panels_config, section, buffer, panel->user_status_format[i]);
1176 mc_config_set_int (mc_panels_config, section, "user_mini_status", panel->user_mini_status);
1179 void
1180 save_panel_types (void)
1182 panel_view_mode_t type;
1184 if (mc_run_mode != MC_RUN_FULL)
1185 return;
1187 if (!panels_options.auto_save_setup)
1188 return;
1190 type = get_display_type (0);
1191 panel_save_type ("New Left Panel", type);
1192 if (type == view_listing)
1193 panel_save_setup (left_panel, left_panel->panel_name);
1194 type = get_display_type (1);
1195 panel_save_type ("New Right Panel", type);
1196 if (type == view_listing)
1197 panel_save_setup (right_panel, right_panel->panel_name);
1199 mc_config_set_string (mc_panels_config, "Dirs", "other_dir", get_panel_dir_for (other_panel));
1201 if (current_panel != NULL)
1202 mc_config_set_string (mc_panels_config, "Dirs", "current_is_left",
1203 get_current_index () == 0 ? "1" : "0");
1205 if (mc_panels_config->ini_path == NULL)
1206 mc_panels_config->ini_path = g_strdup (panels_profile_name);
1208 mc_config_del_group (mc_panels_config, "Temporal:New Left Panel");
1209 mc_config_del_group (mc_panels_config, "Temporal:New Right Panel");
1211 mc_config_save_file (mc_panels_config, NULL);
1215 Load panels options from [Panels] section.
1217 void
1218 panels_load_options (void)
1220 size_t i;
1221 int qmode;
1223 /* Backward compatibility: load old parameters */
1224 for (i = 0; panels_ini_options[i].opt_name != NULL; i++)
1225 *panels_ini_options[i].opt_addr =
1226 mc_config_get_int (mc_main_config, CONFIG_APP_SECTION,
1227 panels_ini_options[i].opt_old_name != NULL
1228 ? panels_ini_options[i].opt_old_name : panels_ini_options[i].opt_name,
1229 *panels_ini_options[i].opt_addr);
1231 qmode = mc_config_get_int (mc_main_config, CONFIG_APP_SECTION,
1232 "quick_search_case_sensitive", (int) panels_options.qsearch_mode);
1233 if (qmode < 0)
1234 panels_options.qsearch_mode = QSEARCH_CASE_INSENSITIVE;
1235 else if (qmode >= QSEARCH_NUM)
1236 panels_options.qsearch_mode = QSEARCH_PANEL_CASE;
1237 else
1238 panels_options.qsearch_mode = (qsearch_mode_t) qmode;
1240 /* overwrite by new parameters */
1241 if (mc_config_has_group (mc_main_config, panels_section))
1243 for (i = 0; panels_ini_options[i].opt_name != NULL; i++)
1244 *panels_ini_options[i].opt_addr =
1245 mc_config_get_bool (mc_main_config, panels_section,
1246 panels_ini_options[i].opt_name,
1247 *panels_ini_options[i].opt_addr);
1249 qmode = mc_config_get_int (mc_main_config, panels_section,
1250 "quick_search_mode", (int) panels_options.qsearch_mode);
1251 if (qmode < 0)
1252 panels_options.qsearch_mode = QSEARCH_CASE_INSENSITIVE;
1253 else if (qmode >= QSEARCH_NUM)
1254 panels_options.qsearch_mode = QSEARCH_PANEL_CASE;
1255 else
1256 panels_options.qsearch_mode = (qsearch_mode_t) qmode;
1261 Save panels options in [Panels] section.
1263 void
1264 panels_save_options (void)
1266 size_t i;
1268 for (i = 0; panels_ini_options[i].opt_name != NULL; i++)
1269 mc_config_set_bool (mc_main_config, panels_section,
1270 panels_ini_options[i].opt_name, *panels_ini_options[i].opt_addr);
1272 mc_config_set_int (mc_main_config, panels_section,
1273 "quick_search_mode", (int) panels_options.qsearch_mode);