Changes into src directory:
[midnight-commander.git] / src / setup.c
blobb195cca7373c71841f598d2e2bb3acbd00fb5ddd
1 /* Setup loading/saving.
2 Copyright (C) 1994, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3 2006, 2007, 2009 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/tty/mouse.h" /* To make view.h happy */
36 #include "lib/vfs/mc-vfs/vfs.h"
37 #include "lib/mcconfig.h"
38 #include "lib/fileloc.h"
40 #ifdef ENABLE_VFS
41 #include "lib/vfs/mc-vfs/gc.h"
42 #endif
44 #ifdef USE_NETCODE
45 # include "lib/vfs/mc-vfs/ftpfs.h"
46 # include "lib/vfs/mc-vfs/fish.h"
47 #endif
48 #include "lib/strutil.h" /* str_isutf8 () */
50 #include "args.h"
51 #include "dir.h"
52 #include "panel.h"
53 #include "main.h"
54 #include "tree.h" /* xtree_mode */
55 #include "setup.h"
56 #include "src/viewer/mcviewer.h" /* For the externs */
57 #include "hotlist.h" /* load/save/done hotlist */
58 #include "panelize.h" /* load/save/done panelize */
59 #include "layout.h"
60 #include "menu.h" /* menubar_visible declaration */
61 #include "cmd.h"
62 #include "file.h" /* safe_delete */
63 #include "keybind.h" /* lookup_action */
64 #include "wtools.h"
66 #ifdef HAVE_CHARSET
67 #include "charsets.h"
68 #endif
70 #ifdef USE_INTERNAL_EDIT
71 # include "src/editor/edit.h"
72 #endif
76 extern int num_history_items_recorded;
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 /* Ugly hack to allow panel_save_setup to work as a place holder for */
89 /* default panel values */
90 int saving_setup;
91 int setup_copymove_persistent_attr = 1;
93 static char *panels_profile_name = NULL; /* .mc/panels.ini */
95 /* *INDENT-OFF* */
96 static const struct {
97 const char *key;
98 int list_type;
99 } list_types [] = {
100 { "full", list_full },
101 { "brief", list_brief },
102 { "long", list_long },
103 { "user", list_user },
104 { 0, 0 }
107 static const struct {
108 const char *opt_name;
109 panel_view_mode_t opt_type;
110 } panel_types [] = {
111 { "listing", view_listing },
112 { "quickview", view_quick },
113 { "info", view_info },
114 { "tree", view_tree },
115 { NULL, view_listing }
118 static const struct {
119 const char *opt_name;
120 int *opt_addr;
121 } layout [] = {
122 { "equal_split", &equal_split },
123 { "first_panel_size", &first_panel_size },
124 { "message_visible", &message_visible },
125 { "keybar_visible", &keybar_visible },
126 { "xterm_title", &xterm_title },
127 { "output_lines", &output_lines },
128 { "command_prompt", &command_prompt },
129 { "menubar_visible", &menubar_visible },
130 { "show_mini_info", &show_mini_info },
131 { "permission_mode", &permission_mode },
132 { "filetype_mode", &filetype_mode },
133 { "free_space", &free_space },
134 { 0, 0 }
137 static const struct {
138 const char *opt_name;
139 int *opt_addr;
140 } int_options [] = {
141 { "show_backups", &show_backups },
142 { "kilobyte_si", &kilobyte_si },
143 { "show_dot_files", &show_dot_files },
144 { "verbose", &verbose },
145 { "mark_moves_down", &mark_moves_down },
146 { "pause_after_run", &pause_after_run },
147 { "shell_patterns", &easy_patterns },
148 { "auto_save_setup", &auto_save_setup },
149 { "auto_menu", &auto_menu },
150 { "use_internal_view", &use_internal_view },
151 { "use_internal_edit", &use_internal_edit },
152 { "clear_before_exec", &clear_before_exec },
153 { "mix_all_files", &mix_all_files },
154 { "fast_reload", &fast_reload },
155 { "fast_reload_msg_shown", &fast_reload_w },
156 { "confirm_delete", &confirm_delete },
157 { "confirm_overwrite", &confirm_overwrite },
158 { "confirm_execute", &confirm_execute },
159 { "confirm_history_cleanup", &confirm_history_cleanup },
160 { "confirm_exit", &confirm_exit },
161 { "confirm_directory_hotlist_delete", &confirm_directory_hotlist_delete },
162 { "safe_delete", &safe_delete },
163 { "mouse_repeat_rate", &mou_auto_repeat },
164 { "double_click_speed", &double_click_speed },
165 #ifndef HAVE_CHARSET
166 { "eight_bit_clean", &eight_bit_clean },
167 { "full_eight_bits", &full_eight_bits },
168 #endif /* !HAVE_CHARSET */
169 { "use_8th_bit_as_meta", &use_8th_bit_as_meta },
170 { "confirm_view_dir", &confirm_view_dir },
171 { "mouse_move_pages", &mouse_move_pages },
172 { "mouse_move_pages_viewer", &mcview_mouse_move_pages },
173 { "mouse_close_dialog", &mouse_close_dialog},
174 { "fast_refresh", &fast_refresh },
175 { "navigate_with_arrows", &navigate_with_arrows },
176 { "drop_menus", &drop_menus },
177 { "wrap_mode", &mcview_global_wrap_mode},
178 { "old_esc_mode", &old_esc_mode },
179 { "cd_symlinks", &cd_symlinks },
180 { "show_all_if_ambiguous", &show_all_if_ambiguous },
181 { "max_dirt_limit", &mcview_max_dirt_limit },
182 { "torben_fj_mode", &torben_fj_mode },
183 { "use_file_to_guess_type", &use_file_to_check_type },
184 { "alternate_plus_minus", &alternate_plus_minus },
185 { "only_leading_plus_minus", &only_leading_plus_minus },
186 { "show_output_starts_shell", &output_starts_shell },
187 { "panel_scroll_pages", &panel_scroll_pages },
188 { "xtree_mode", &xtree_mode },
189 { "num_history_items_recorded", &num_history_items_recorded },
190 { "file_op_compute_totals", &file_op_compute_totals },
191 #ifdef ENABLE_VFS
192 { "vfs_timeout", &vfs_timeout },
193 #ifdef USE_NETCODE
194 { "ftpfs_directory_timeout", &ftpfs_directory_timeout },
195 { "use_netrc", &use_netrc },
196 { "ftpfs_retry_seconds", &ftpfs_retry_seconds },
197 { "ftpfs_always_use_proxy", &ftpfs_always_use_proxy },
198 { "ftpfs_use_passive_connections", &ftpfs_use_passive_connections },
199 { "ftpfs_use_passive_connections_over_proxy", &ftpfs_use_passive_connections_over_proxy },
200 { "ftpfs_use_unix_list_options", &ftpfs_use_unix_list_options },
201 { "ftpfs_first_cd_then_ls", &ftpfs_first_cd_then_ls },
202 { "fish_directory_timeout", &fish_directory_timeout },
203 #endif /* USE_NETCODE */
204 #endif /* ENABLE_VFS */
205 #ifdef USE_INTERNAL_EDIT
206 { "editor_word_wrap_line_length", &option_word_wrap_line_length },
207 { "editor_tab_spacing", &option_tab_spacing },
208 { "editor_fill_tabs_with_spaces", &option_fill_tabs_with_spaces },
209 { "editor_return_does_auto_indent", &option_return_does_auto_indent },
210 { "editor_backspace_through_tabs", &option_backspace_through_tabs },
211 { "editor_fake_half_tabs", &option_fake_half_tabs },
212 { "editor_option_save_mode", &option_save_mode },
213 { "editor_option_save_position", &option_save_position },
214 { "editor_option_auto_para_formatting", &option_auto_para_formatting },
215 { "editor_option_typewriter_wrap", &option_typewriter_wrap },
216 { "editor_edit_confirm_save", &edit_confirm_save },
217 { "editor_syntax_highlighting", &option_syntax_highlighting },
218 { "editor_persistent_selections", &option_persistent_selections },
219 { "editor_cursor_beyond_eol", &option_cursor_beyond_eol },
220 { "editor_visible_tabs", &visible_tabs },
221 { "editor_visible_spaces", &visible_tws },
222 { "editor_line_state", &option_line_state },
223 { "editor_simple_statusbar", &simple_statusbar },
224 { "editor_check_new_line", &option_check_nl_at_eof },
225 { "editor_show_right_margin", &show_right_margin },
226 #endif /* USE_INTERNAL_EDIT */
228 { "nice_rotating_dash", &nice_rotating_dash },
229 { "horizontal_split", &horizontal_split },
230 { "mcview_remember_file_position", &mcview_remember_file_position },
231 { "auto_fill_mkdir_name", &auto_fill_mkdir_name },
232 { "reverse_files_only", &reverse_files_only },
233 { "copymove_persistent_attr", &setup_copymove_persistent_attr },
234 { "select_flags", &select_flags },
235 { "quick_search_case_sensitive", &quick_search_case_sensitive },
236 { 0, 0 }
238 /* *INDENT-ON* */
240 extern char *user_recent_timeformat;
241 extern char *user_old_timeformat;
244 In order to use everywhere the same setup
245 for the locale we use defines
247 #define FMTYEAR _("%b %e %Y")
248 #define FMTTIME _("%b %e %H:%M")
250 static const struct
252 const char *opt_name;
253 char **opt_addr;
254 const char *opt_defval;
255 } str_options[] =
257 #ifdef USE_INTERNAL_EDIT
259 "editor_backup_extension", &option_backup_ext, "~"},
260 #endif
262 "mcview_eof", &mcview_show_eof, ""},
264 NULL, NULL, NULL}
267 void
268 panel_save_setup (struct WPanel *panel, const char *section)
270 char buffer[BUF_TINY];
271 size_t i;
273 mc_config_set_int (mc_panels_config, section, "reverse", panel->reverse);
274 mc_config_set_int (mc_panels_config, section, "case_sensitive", panel->case_sensitive);
275 mc_config_set_int (mc_panels_config, section, "exec_first", panel->exec_first);
278 mc_config_set_string (mc_panels_config, section, "sort_order", panel->current_sort_field->id);
280 for (i = 0; list_types[i].key; i++)
281 if (list_types[i].list_type == panel->list_type)
283 mc_config_set_string (mc_panels_config, section, "list_mode", list_types[i].key);
284 break;
287 mc_config_set_string (mc_panels_config, section, "user_format", panel->user_format);
289 for (i = 0; i < LIST_TYPES; i++)
291 g_snprintf (buffer, BUF_TINY, "user_status%lld", (long long) i);
292 mc_config_set_string (mc_panels_config, section, buffer, panel->user_status_format[i]);
295 mc_config_set_int (mc_panels_config, section, "user_mini_status", panel->user_mini_status);
298 void
299 save_layout (void)
301 char *profile;
302 int i;
304 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
306 /* Save integer options */
307 for (i = 0; layout[i].opt_name; i++)
309 mc_config_set_int (mc_main_config, "Layout", layout[i].opt_name, *layout[i].opt_addr);
311 mc_config_save_to_file (mc_main_config, profile, NULL);
313 g_free (profile);
316 void
317 save_configure (void)
319 char *profile;
320 GError *error = NULL;
321 int i;
323 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
325 /* Save integer options */
326 for (i = 0; int_options[i].opt_name; i++)
327 mc_config_set_int (mc_main_config, CONFIG_APP_SECTION, int_options[i].opt_name,
328 *int_options[i].opt_addr);
330 /* Save string options */
331 for (i = 0; str_options[i].opt_name != NULL; i++)
332 mc_config_set_string (mc_main_config, CONFIG_APP_SECTION, str_options[i].opt_name,
333 *str_options[i].opt_addr);
335 if (!mc_config_save_to_file (mc_main_config, profile, &error))
336 setup_save_config_show_error (profile, &error);
338 g_free (profile);
341 static void
342 panel_save_type (const char *section, panel_view_mode_t type)
344 int i;
346 for (i = 0; panel_types[i].opt_name != NULL; i++)
347 if (panel_types[i].opt_type == type)
349 mc_config_set_string (mc_panels_config, section, "display", panel_types[i].opt_name);
350 break;
354 void
355 save_panel_types (void)
357 panel_view_mode_t type;
359 if (mc_run_mode != MC_RUN_FULL)
360 return;
362 if (!mc_config_get_int (mc_main_config, CONFIG_APP_SECTION,
363 "auto_save_setup_panels", auto_save_setup))
364 return;
366 type = get_display_type (0);
367 panel_save_type ("New Left Panel", type);
368 if (type == view_listing)
369 panel_save_setup (left_panel, left_panel->panel_name);
370 type = get_display_type (1);
371 panel_save_type ("New Right Panel", type);
372 if (type == view_listing)
373 panel_save_setup (right_panel, right_panel->panel_name);
375 mc_config_set_string (mc_panels_config, "Dirs", "other_dir", get_panel_dir_for (other_panel));
377 if (current_panel != NULL)
378 mc_config_set_string (mc_panels_config, "Dirs", "current_is_left",
379 get_current_index () == 0 ? "1" : "0");
381 if (mc_panels_config->ini_path == NULL)
382 mc_panels_config->ini_path = g_strdup (panels_profile_name);
384 mc_config_del_group (mc_panels_config, "Temporal:New Left Panel");
385 mc_config_del_group (mc_panels_config, "Temporal:New Right Panel");
387 mc_config_save_file (mc_panels_config, NULL);
390 gboolean
391 save_setup (void)
393 char *tmp_profile;
394 gboolean ret;
396 saving_setup = 1;
398 save_configure ();
400 save_layout ();
402 save_hotlist ();
404 save_panelize ();
405 save_panel_types ();
406 /* directory_history_save (); */
408 #if defined(ENABLE_VFS) && defined (USE_NETCODE)
409 mc_config_set_string (mc_main_config, "Misc", "ftpfs_password", ftpfs_anonymous_passwd);
410 if (ftpfs_proxy_host)
411 mc_config_set_string (mc_main_config, "Misc", "ftp_proxy_host", ftpfs_proxy_host);
412 #endif /* ENABLE_VFS && USE_NETCODE */
414 #ifdef HAVE_CHARSET
415 mc_config_set_string (mc_main_config, "Misc", "display_codepage",
416 get_codepage_id (display_codepage));
417 mc_config_set_string (mc_main_config, "Misc", "source_codepage",
418 get_codepage_id (default_source_codepage));
419 mc_config_set_string (mc_main_config, "Misc", "autodetect_codeset", autodetect_codeset);
420 #endif /* HAVE_CHARSET */
421 tmp_profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
422 ret = mc_config_save_to_file (mc_main_config, tmp_profile, NULL);
424 g_free (tmp_profile);
425 saving_setup = 0;
426 return ret;
429 void
430 panel_load_setup (WPanel * panel, const char *section)
432 size_t i;
433 char *buffer, buffer2[BUF_TINY];
435 panel->reverse = mc_config_get_int (mc_panels_config, section, "reverse", 0);
436 panel->case_sensitive =
437 mc_config_get_int (mc_panels_config, section, "case_sensitive",
438 OS_SORT_CASE_SENSITIVE_DEFAULT);
439 panel->exec_first = mc_config_get_int (mc_panels_config, section, "exec_first", 0);
441 /* Load sort order */
442 buffer = mc_config_get_string (mc_panels_config, section, "sort_order", "name");
443 panel->current_sort_field = panel_get_field_by_id (buffer);
444 if (panel->current_sort_field == NULL)
445 panel->current_sort_field = panel_get_field_by_id ("name");
447 g_free (buffer);
449 /* Load the listing mode */
450 buffer = mc_config_get_string (mc_panels_config, section, "list_mode", "full");
451 panel->list_type = list_full;
452 for (i = 0; list_types[i].key; i++)
453 if (g_strcasecmp (list_types[i].key, buffer) == 0)
455 panel->list_type = list_types[i].list_type;
456 break;
458 g_free (buffer);
460 /* User formats */
461 g_free (panel->user_format);
462 panel->user_format =
463 mc_config_get_string (mc_panels_config, section, "user_format", DEFAULT_USER_FORMAT);
465 for (i = 0; i < LIST_TYPES; i++)
467 g_free (panel->user_status_format[i]);
468 g_snprintf (buffer2, BUF_TINY, "user_status%lld", (long long) i);
469 panel->user_status_format[i] =
470 mc_config_get_string (mc_panels_config, section, buffer2, DEFAULT_USER_FORMAT);
473 panel->user_mini_status = mc_config_get_int (mc_panels_config, section, "user_mini_status", 0);
477 static void
478 load_layout ()
480 int i;
482 for (i = 0; layout[i].opt_name; i++)
483 *layout[i].opt_addr =
484 mc_config_get_int (mc_main_config, "Layout", layout[i].opt_name, *layout[i].opt_addr);
487 static panel_view_mode_t
488 setup__load_panel_state (const char *section)
490 char *buffer;
491 size_t i;
492 panel_view_mode_t mode = view_listing;
494 /* Load the display mode */
495 buffer = mc_config_get_string (mc_panels_config, section, "display", "listing");
497 for (i = 0; panel_types[i].opt_name != NULL; i++)
498 if (g_strcasecmp (panel_types[i].opt_name, buffer) == 0)
500 mode = panel_types[i].opt_type;
501 break;
503 g_free (buffer);
504 return mode;
507 static const char *
508 setup__is_cfg_group_must_panel_config (const char *grp)
510 if (!strcasecmp ("Dirs", grp) ||
511 !strcasecmp ("Temporal:New Right Panel", grp) ||
512 !strcasecmp ("Temporal:New Left Panel", grp) ||
513 !strcasecmp ("New Left Panel", grp) || !strcasecmp ("New Right Panel", grp))
514 return grp;
515 return NULL;
518 static void
519 setup__move_panels_config_into_separate_file (const char *profile)
521 mc_config_t *tmp_cfg;
522 char **groups, **curr_grp;
523 const char *need_grp;
525 if (!exist_file (profile))
526 return;
528 tmp_cfg = mc_config_init (profile);
529 if (!tmp_cfg)
530 return;
532 curr_grp = groups = mc_config_get_groups (tmp_cfg, NULL);
533 if (!groups)
535 mc_config_deinit (tmp_cfg);
536 return;
538 while (*curr_grp)
540 if (setup__is_cfg_group_must_panel_config (*curr_grp) == NULL)
542 mc_config_del_group (tmp_cfg, *curr_grp);
544 curr_grp++;
547 mc_config_save_to_file (tmp_cfg, panels_profile_name, NULL);
548 mc_config_deinit (tmp_cfg);
550 tmp_cfg = mc_config_init (profile);
551 if (!tmp_cfg)
553 g_strfreev (groups);
554 return;
557 curr_grp = groups;
559 while (*curr_grp)
561 need_grp = setup__is_cfg_group_must_panel_config (*curr_grp);
562 if (need_grp != NULL)
564 mc_config_del_group (tmp_cfg, need_grp);
566 curr_grp++;
568 g_strfreev (groups);
569 mc_config_save_file (tmp_cfg, NULL);
570 mc_config_deinit (tmp_cfg);
575 Get name of config file.
577 \param subdir
578 if not NULL, then config also search into specified subdir
580 \param config_file_name
581 If specified filename is relative, then will search in standart patches.
583 \return
584 Newly allocated path to config name or NULL if file not found
586 If config_file_name is a relative path, then search config in stantart pathes */
587 static char *
588 load_setup_get_full_config_name (const char *subdir, const char *config_file_name)
591 TODO: IMHO, in future this function must be placed into mc_config module.
592 Also, need to rename stupid mc_home and mc_home_alt to mc_sysconfdir and mc_datadir;
593 home_mc => mc_user_homedir
595 char *lc_basename, *ret;
597 if (config_file_name == NULL)
598 return NULL;
600 if (g_path_is_absolute (config_file_name))
601 return g_strdup (config_file_name);
604 lc_basename = g_path_get_basename (config_file_name);
605 if (lc_basename == NULL)
606 return NULL;
609 if (subdir)
610 ret = g_build_filename (home_dir, MC_USERCONF_DIR, subdir, lc_basename, NULL);
611 else
612 ret = g_build_filename (home_dir, MC_USERCONF_DIR, lc_basename, NULL);
614 if (exist_file (ret))
616 g_free (lc_basename);
617 return ret;
619 g_free (ret);
622 if (subdir)
623 ret = g_build_filename (mc_home, subdir, lc_basename, NULL);
624 else
625 ret = g_build_filename (mc_home, lc_basename, NULL);
627 if (exist_file (ret))
629 g_free (lc_basename);
630 return ret;
632 g_free (ret);
634 if (subdir)
635 ret = g_build_filename (mc_home_alt, subdir, lc_basename, NULL);
636 else
637 ret = g_build_filename (mc_home_alt, lc_basename, NULL);
639 if (exist_file (ret))
641 g_free (lc_basename);
642 return ret;
644 g_free (ret);
645 g_free (lc_basename);
646 return NULL;
651 Create new mc_config object from specified ini-file or
652 append data to existing mc_config object from ini-file
655 static void
656 load_setup_init_config_from_file (mc_config_t ** config, const char *fname)
659 TODO: IMHO, in future this function must be placed into mc_config module.
661 if (exist_file (fname))
663 if (*config)
664 mc_config_read_file (*config, fname);
665 else
666 *config = mc_config_init (fname);
672 static mc_config_t *
673 load_setup_get_keymap_profile_config (void)
676 TODO: IMHO, in future this function must be placed into mc_config module.
678 mc_config_t *keymap_config = NULL;
680 char *fname, *fname2;
682 /* 1) /usr/share/mc (mc_home_alt) */
683 fname = g_build_filename (mc_home_alt, GLOBAL_KEYMAP_FILE, NULL);
684 load_setup_init_config_from_file (&keymap_config, fname);
685 g_free (fname);
687 /* 2) /etc/mc (mc_home) */
688 fname = g_build_filename (mc_home, GLOBAL_KEYMAP_FILE, NULL);
689 load_setup_init_config_from_file (&keymap_config, fname);
690 g_free (fname);
692 /* 3) ~/.mc (home_dir?) */
693 fname = g_build_filename (home_dir, MC_USERCONF_DIR, GLOBAL_KEYMAP_FILE, NULL);
694 load_setup_init_config_from_file (&keymap_config, fname);
695 g_free (fname);
697 /* 4) main config; [Midnight Commander] -> keymap */
699 fname2 =
700 mc_config_get_string (mc_main_config, CONFIG_APP_SECTION, "keymap", GLOBAL_KEYMAP_FILE);
701 fname = load_setup_get_full_config_name (NULL, fname2);
702 if (fname)
704 load_setup_init_config_from_file (&keymap_config, fname);
705 g_free (fname);
707 g_free (fname2);
709 /* 5) getenv("MC_KEYMAP") */
710 fname = load_setup_get_full_config_name (NULL, g_getenv ("MC_KEYMAP"));
711 if (fname)
713 load_setup_init_config_from_file (&keymap_config, fname);
714 g_free (fname);
717 /* 6) --keymap=<keymap> */
718 fname = load_setup_get_full_config_name (NULL, mc_args__keymap_file);
719 if (fname)
721 load_setup_init_config_from_file (&keymap_config, fname);
722 g_free (fname);
725 return keymap_config;
728 char *
729 setup_init (void)
731 char *profile;
732 char *inifile;
734 if (profile_name)
735 return profile_name;
737 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
738 if (!exist_file (profile))
740 inifile = concat_dir_and_file (mc_home, "mc.ini");
741 if (exist_file (inifile))
743 g_free (profile);
744 profile = inifile;
746 else
748 g_free (inifile);
749 inifile = concat_dir_and_file (mc_home_alt, "mc.ini");
750 if (exist_file (inifile))
752 g_free (profile);
753 profile = inifile;
755 else
756 g_free (inifile);
760 profile_name = profile;
762 return profile;
765 void
766 load_setup (void)
768 char *profile;
769 int i;
770 char *buffer;
772 profile = setup_init ();
774 /* mc.lib is common for all users, but has priority lower than
775 ~/.mc/ini. FIXME: it's only used for keys and treestore now */
776 global_profile_name = concat_dir_and_file (mc_home, MC_GLOBAL_CONFIG_FILE);
777 if (!exist_file (global_profile_name))
779 g_free (global_profile_name);
780 global_profile_name = concat_dir_and_file (mc_home_alt, MC_GLOBAL_CONFIG_FILE);
783 panels_profile_name = g_build_filename (home_dir, MC_USERCONF_DIR, MC_PANELS_FILE, NULL);
785 mc_main_config = mc_config_init (profile);
787 if (!exist_file (panels_profile_name))
788 setup__move_panels_config_into_separate_file (profile);
790 mc_panels_config = mc_config_init (panels_profile_name);
792 /* Load integer boolean options */
793 for (i = 0; int_options[i].opt_name; i++)
794 *int_options[i].opt_addr =
795 mc_config_get_int (mc_main_config, CONFIG_APP_SECTION, int_options[i].opt_name,
796 *int_options[i].opt_addr);
798 /* Load string options */
799 for (i = 0; str_options[i].opt_name != NULL; i++)
800 *str_options[i].opt_addr =
801 mc_config_get_string (mc_main_config, CONFIG_APP_SECTION, str_options[i].opt_name,
802 str_options[i].opt_defval);
804 load_layout ();
806 load_panelize ();
808 startup_left_mode = setup__load_panel_state ("New Left Panel");
809 startup_right_mode = setup__load_panel_state ("New Right Panel");
811 /* At least one of the panels is a listing panel */
812 if (startup_left_mode != view_listing && startup_right_mode != view_listing)
813 startup_left_mode = view_listing;
815 if (mc_run_param1 == NULL)
817 buffer = mc_config_get_string (mc_panels_config, "Dirs", "other_dir", ".");
818 if (vfs_file_is_local (buffer))
819 mc_run_param1 = buffer;
820 else
821 g_free (buffer);
824 boot_current_is_left = mc_config_get_int (mc_panels_config, "Dirs", "current_is_left", 1);
826 /* Load time formats */
827 user_recent_timeformat =
828 mc_config_get_string (mc_main_config, "Misc", "timeformat_recent", FMTTIME);
829 user_old_timeformat = mc_config_get_string (mc_main_config, "Misc", "timeformat_old", FMTYEAR);
831 #ifdef USE_NETCODE
832 ftpfs_proxy_host = mc_config_get_string (mc_main_config, "Misc", "ftp_proxy_host", "gate");
833 #endif
835 /* The default color and the terminal dependent color */
836 setup_color_string = mc_config_get_string (mc_main_config, "Colors", "base_color", "");
837 term_color_string = mc_config_get_string (mc_main_config, "Colors", getenv ("TERM"), "");
838 color_terminal_string = mc_config_get_string (mc_main_config, "Colors", "color_terminals", "");
840 /* Load the directory history */
841 /* directory_history_load (); */
842 /* Remove the temporal entries */
843 #if defined(ENABLE_VFS) && defined (USE_NETCODE)
844 ftpfs_init_passwd ();
845 #endif /* ENABLE_VFS && USE_NETCODE */
847 #ifdef HAVE_CHARSET
848 if (load_codepages_list () > 0)
850 buffer = mc_config_get_string (mc_main_config, "Misc", "display_codepage", "");
851 if (buffer[0] != '\0')
853 display_codepage = get_codepage_index (buffer);
854 cp_display = get_codepage_id (display_codepage);
856 g_free (buffer);
857 buffer = mc_config_get_string (mc_main_config, "Misc", "source_codepage", "");
858 if (buffer[0] != '\0')
860 default_source_codepage = get_codepage_index (buffer);
861 source_codepage = default_source_codepage; /* May be source_codepage don't needed this */
862 cp_source = get_codepage_id (source_codepage);
864 g_free (buffer);
867 autodetect_codeset = mc_config_get_string (mc_main_config, "Misc", "autodetect_codeset", "");
868 if ((autodetect_codeset[0] != '\0') && (strcmp (autodetect_codeset, "off")))
869 is_autodetect_codeset_enabled = TRUE;
871 init_translation_table (source_codepage, display_codepage);
872 if (get_codepage_id (display_codepage))
873 utf8_display = str_isutf8 (get_codepage_id (display_codepage));
874 #endif /* HAVE_CHARSET */
877 #if defined(ENABLE_VFS) && defined (USE_NETCODE)
878 char *
879 load_anon_passwd ()
881 char *buffer;
883 buffer = mc_config_get_string (mc_main_config, "Misc", "ftpfs_password", "");
884 if (buffer[0])
885 return buffer;
887 g_free (buffer);
888 return NULL;
890 #endif /* ENABLE_VFS && USE_NETCODE */
892 void
893 done_setup (void)
895 int 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 static void
918 load_keys_from_section (const char *terminal, mc_config_t * cfg)
920 char *section_name;
921 gchar **profile_keys, **keys;
922 gchar **values, **curr_values;
923 char *valcopy, *value;
924 long key_code;
925 gsize len, values_len;
927 if (!terminal)
928 return;
930 section_name = g_strconcat ("terminal:", terminal, (char *) NULL);
931 profile_keys = keys = mc_config_get_keys (cfg, section_name, &len);
933 while (*profile_keys)
936 /* copy=other causes all keys from [terminal:other] to be loaded. */
937 if (g_strcasecmp (*profile_keys, "copy") == 0)
939 valcopy = mc_config_get_string (cfg, section_name, *profile_keys, "");
940 load_keys_from_section (valcopy, cfg);
941 g_free (valcopy);
942 profile_keys++;
943 continue;
945 curr_values = values =
946 mc_config_get_string_list (cfg, section_name, *profile_keys, &values_len);
948 key_code = lookup_key (*profile_keys, NULL);
949 if (key_code != 0)
951 if (curr_values)
953 while (*curr_values)
955 valcopy = convert_controls (*curr_values);
956 define_sequence (key_code, valcopy, MCKEY_NOACTION);
957 g_free (valcopy);
958 curr_values++;
961 else
963 value = mc_config_get_string (cfg, section_name, *profile_keys, "");
964 valcopy = convert_controls (value);
965 define_sequence (key_code, valcopy, MCKEY_NOACTION);
966 g_free (valcopy);
967 g_free (value);
970 profile_keys++;
971 if (values)
972 g_strfreev (values);
974 g_strfreev (keys);
975 g_free (section_name);
978 void
979 load_key_defs (void)
982 * Load keys from mc.lib before ~/.mc/ini, so that the user
983 * definitions override global settings.
985 mc_config_t *mc_global_config;
987 mc_global_config = mc_config_init (global_profile_name);
988 if (mc_global_config != NULL)
990 load_keys_from_section ("general", mc_global_config);
991 load_keys_from_section (getenv ("TERM"), mc_global_config);
992 mc_config_deinit (mc_global_config);
994 load_keys_from_section ("general", mc_main_config);
995 load_keys_from_section (getenv ("TERM"), mc_main_config);
999 static void
1000 load_keymap_from_section (const char *section_name, GArray * keymap, mc_config_t * cfg)
1002 gchar **profile_keys, **keys;
1003 gchar **values, **curr_values;
1004 char *valcopy, *value;
1005 int action;
1006 gsize len, values_len;
1008 if (!section_name)
1009 return;
1011 profile_keys = keys = mc_config_get_keys (cfg, section_name, &len);
1013 while (*profile_keys)
1015 curr_values = values =
1016 mc_config_get_string_list (cfg, section_name, *profile_keys, &values_len);
1017 action = lookup_action (*profile_keys);
1018 if (action > 0)
1020 if (curr_values)
1022 while (*curr_values)
1024 valcopy = convert_controls (*curr_values);
1025 keybind_cmd_bind (keymap, valcopy, action);
1026 g_free (valcopy);
1027 curr_values++;
1030 else
1032 value = mc_config_get_string (cfg, section_name, *profile_keys, "");
1033 valcopy = convert_controls (value);
1034 /* define_sequence (key_code, valcopy, MCKEY_NOACTION); */
1035 g_free (valcopy);
1036 g_free (value);
1039 profile_keys++;
1040 if (values)
1041 g_strfreev (values);
1043 g_strfreev (keys);
1046 void
1047 load_keymap_defs (void)
1050 * Load keymap from GLOBAL_KEYMAP_FILE before ~/.mc/keymap, so that the user
1051 * definitions override global settings.
1053 mc_config_t *mc_global_keymap;
1055 mc_global_keymap = load_setup_get_keymap_profile_config ();
1057 if (mc_global_keymap != NULL)
1059 #ifdef USE_INTERNAL_EDIT
1060 editor_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1061 load_keymap_from_section ("editor", editor_keymap, mc_global_keymap);
1062 editor_x_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1063 load_keymap_from_section ("editor:xmap", editor_x_keymap, mc_global_keymap);
1064 #endif
1066 viewer_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1067 load_keymap_from_section ("viewer", viewer_keymap, mc_global_keymap);
1068 viewer_hex_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1069 load_keymap_from_section ("viewer:hex", viewer_hex_keymap, mc_global_keymap);
1071 main_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1072 load_keymap_from_section ("main", main_keymap, mc_global_keymap);
1073 main_x_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1074 load_keymap_from_section ("main:xmap", main_x_keymap, mc_global_keymap);
1076 panel_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1077 load_keymap_from_section ("panel", panel_keymap, mc_global_keymap);
1079 input_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1080 load_keymap_from_section ("input", input_keymap, mc_global_keymap);
1082 tree_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1083 load_keymap_from_section ("tree", tree_keymap, mc_global_keymap);
1085 help_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1086 load_keymap_from_section ("help", help_keymap, mc_global_keymap);
1088 #ifdef USE_DIFF_VIEW
1089 diff_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1090 load_keymap_from_section ("diffviewer", diff_keymap, mc_global_keymap);
1091 #endif
1092 mc_config_deinit (mc_global_keymap);
1096 void
1097 free_keymap_defs (void)
1099 #ifdef USE_INTERNAL_EDIT
1100 if (editor_keymap != NULL)
1101 g_array_free (editor_keymap, TRUE);
1102 if (editor_x_keymap != NULL)
1103 g_array_free (editor_x_keymap, TRUE);
1104 #endif
1105 if (viewer_keymap != NULL)
1106 g_array_free (viewer_keymap, TRUE);
1107 if (viewer_hex_keymap != NULL)
1108 g_array_free (viewer_hex_keymap, TRUE);
1109 if (main_keymap != NULL)
1110 g_array_free (main_keymap, TRUE);
1111 if (main_x_keymap != NULL)
1112 g_array_free (main_x_keymap, TRUE);
1113 if (panel_keymap != NULL)
1114 g_array_free (panel_keymap, TRUE);
1115 if (input_keymap != NULL)
1116 g_array_free (input_keymap, TRUE);
1117 if (tree_keymap != NULL)
1118 g_array_free (tree_keymap, TRUE);
1119 if (help_keymap != NULL)
1120 g_array_free (help_keymap, TRUE);
1121 #ifdef USE_DIFF_VIEW
1122 if (diff_keymap != NULL)
1123 g_array_free (diff_keymap, TRUE);
1124 #endif
1127 void
1128 setup_save_config_show_error (const char *filename, GError ** error)
1130 if (error == NULL || *error == NULL)
1131 return;
1133 message (D_ERROR, MSG_ERROR, _("Cannot save file %s:\n%s"), filename, (*error)->message);
1135 g_error_free (*error);
1136 *error = NULL;