Merge branch '1992_mc_startup'
[midnight-commander.git] / src / setup.c
blob2c9d2c32b3f375787c40d6df231dae99df3e786d
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 static const struct {
96 const char *key;
97 int list_type;
98 } list_types [] = {
99 { "full", list_full },
100 { "brief", list_brief },
101 { "long", list_long },
102 { "user", list_user },
103 { 0, 0 }
106 static const struct {
107 const char *opt_name;
108 panel_view_mode_t opt_type;
109 } panel_types [] = {
110 { "listing", view_listing },
111 { "quickview", view_quick },
112 { "info", view_info },
113 { "tree", view_tree },
114 { NULL, view_listing }
117 static const struct {
118 const char *opt_name;
119 int *opt_addr;
120 } layout [] = {
121 { "equal_split", &equal_split },
122 { "first_panel_size", &first_panel_size },
123 { "message_visible", &message_visible },
124 { "keybar_visible", &keybar_visible },
125 { "xterm_title", &xterm_title },
126 { "output_lines", &output_lines },
127 { "command_prompt", &command_prompt },
128 { "menubar_visible", &menubar_visible },
129 { "show_mini_info", &show_mini_info },
130 { "permission_mode", &permission_mode },
131 { "filetype_mode", &filetype_mode },
132 { "free_space", &free_space },
133 { 0, 0 }
136 static const struct {
137 const char *opt_name;
138 int *opt_addr;
139 } int_options [] = {
140 { "show_backups", &show_backups },
141 { "kilobyte_si", &kilobyte_si },
142 { "show_dot_files", &show_dot_files },
143 { "verbose", &verbose },
144 { "mark_moves_down", &mark_moves_down },
145 { "pause_after_run", &pause_after_run },
146 { "shell_patterns", &easy_patterns },
147 { "auto_save_setup", &auto_save_setup },
148 { "auto_menu", &auto_menu },
149 { "use_internal_view", &use_internal_view },
150 { "use_internal_edit", &use_internal_edit },
151 { "clear_before_exec", &clear_before_exec },
152 { "mix_all_files", &mix_all_files },
153 { "fast_reload", &fast_reload },
154 { "fast_reload_msg_shown", &fast_reload_w },
155 { "confirm_delete", &confirm_delete },
156 { "confirm_overwrite", &confirm_overwrite },
157 { "confirm_execute", &confirm_execute },
158 { "confirm_history_cleanup", &confirm_history_cleanup },
159 { "confirm_exit", &confirm_exit },
160 { "confirm_directory_hotlist_delete", &confirm_directory_hotlist_delete },
161 { "safe_delete", &safe_delete },
162 { "mouse_repeat_rate", &mou_auto_repeat },
163 { "double_click_speed", &double_click_speed },
164 #ifndef HAVE_CHARSET
165 { "eight_bit_clean", &eight_bit_clean },
166 { "full_eight_bits", &full_eight_bits },
167 #endif /* !HAVE_CHARSET */
168 { "use_8th_bit_as_meta", &use_8th_bit_as_meta },
169 { "confirm_view_dir", &confirm_view_dir },
170 { "mouse_move_pages", &mouse_move_pages },
171 { "mouse_move_pages_viewer", &mcview_mouse_move_pages },
172 { "mouse_close_dialog", &mouse_close_dialog},
173 { "fast_refresh", &fast_refresh },
174 { "navigate_with_arrows", &navigate_with_arrows },
175 { "drop_menus", &drop_menus },
176 { "wrap_mode", &mcview_global_wrap_mode},
177 { "old_esc_mode", &old_esc_mode },
178 { "cd_symlinks", &cd_symlinks },
179 { "show_all_if_ambiguous", &show_all_if_ambiguous },
180 { "max_dirt_limit", &mcview_max_dirt_limit },
181 { "torben_fj_mode", &torben_fj_mode },
182 { "use_file_to_guess_type", &use_file_to_check_type },
183 { "alternate_plus_minus", &alternate_plus_minus },
184 { "only_leading_plus_minus", &only_leading_plus_minus },
185 { "show_output_starts_shell", &output_starts_shell },
186 { "panel_scroll_pages", &panel_scroll_pages },
187 { "xtree_mode", &xtree_mode },
188 { "num_history_items_recorded", &num_history_items_recorded },
189 { "file_op_compute_totals", &file_op_compute_totals },
190 #ifdef ENABLE_VFS
191 { "vfs_timeout", &vfs_timeout },
192 #ifdef USE_NETCODE
193 { "ftpfs_directory_timeout", &ftpfs_directory_timeout },
194 { "use_netrc", &use_netrc },
195 { "ftpfs_retry_seconds", &ftpfs_retry_seconds },
196 { "ftpfs_always_use_proxy", &ftpfs_always_use_proxy },
197 { "ftpfs_use_passive_connections", &ftpfs_use_passive_connections },
198 { "ftpfs_use_passive_connections_over_proxy", &ftpfs_use_passive_connections_over_proxy },
199 { "ftpfs_use_unix_list_options", &ftpfs_use_unix_list_options },
200 { "ftpfs_first_cd_then_ls", &ftpfs_first_cd_then_ls },
201 { "fish_directory_timeout", &fish_directory_timeout },
202 #endif /* USE_NETCODE */
203 #endif /* ENABLE_VFS */
204 #ifdef USE_INTERNAL_EDIT
205 { "editor_word_wrap_line_length", &option_word_wrap_line_length },
206 { "editor_tab_spacing", &option_tab_spacing },
207 { "editor_fill_tabs_with_spaces", &option_fill_tabs_with_spaces },
208 { "editor_return_does_auto_indent", &option_return_does_auto_indent },
209 { "editor_backspace_through_tabs", &option_backspace_through_tabs },
210 { "editor_fake_half_tabs", &option_fake_half_tabs },
211 { "editor_option_save_mode", &option_save_mode },
212 { "editor_option_save_position", &option_save_position },
213 { "editor_option_auto_para_formatting", &option_auto_para_formatting },
214 { "editor_option_typewriter_wrap", &option_typewriter_wrap },
215 { "editor_edit_confirm_save", &edit_confirm_save },
216 { "editor_syntax_highlighting", &option_syntax_highlighting },
217 { "editor_persistent_selections", &option_persistent_selections },
218 { "editor_cursor_beyond_eol", &option_cursor_beyond_eol },
219 { "editor_visible_tabs", &visible_tabs },
220 { "editor_visible_spaces", &visible_tws },
221 { "editor_line_state", &option_line_state },
222 { "editor_simple_statusbar", &simple_statusbar },
223 { "editor_check_new_line", &option_check_nl_at_eof },
224 { "editor_show_right_margin", &show_right_margin },
225 #endif /* USE_INTERNAL_EDIT */
227 { "nice_rotating_dash", &nice_rotating_dash },
228 { "horizontal_split", &horizontal_split },
229 { "mcview_remember_file_position", &mcview_remember_file_position },
230 { "auto_fill_mkdir_name", &auto_fill_mkdir_name },
231 { "reverse_files_only", &reverse_files_only },
232 { "copymove_persistent_attr", &setup_copymove_persistent_attr },
233 { "select_flags", &select_flags },
234 { 0, 0 }
237 extern char *user_recent_timeformat;
238 extern char *user_old_timeformat;
241 In order to use everywhere the same setup
242 for the locale we use defines
244 #define FMTYEAR _("%b %e %Y")
245 #define FMTTIME _("%b %e %H:%M")
247 static const struct {
248 const char *opt_name;
249 char **opt_addr;
250 const char *opt_defval;
251 } str_options [] = {
252 #ifdef USE_INTERNAL_EDIT
253 { "editor_backup_extension", &option_backup_ext, "~" },
254 #endif
255 { "mcview_eof", &mcview_show_eof, "" },
256 { NULL, NULL, NULL }
259 void
260 panel_save_setup (struct WPanel *panel, const char *section)
262 char *buffer;
263 size_t i;
265 mc_config_set_int(mc_panels_config, section, "reverse", panel->reverse);
266 mc_config_set_int(mc_panels_config, section, "case_sensitive", panel->case_sensitive);
267 mc_config_set_int(mc_panels_config, section, "exec_first", panel->exec_first);
270 mc_config_set_string(mc_panels_config, section, "sort_order", panel->current_sort_field->id);
272 for (i = 0; list_types [i].key; i++)
273 if (list_types [i].list_type == panel->list_type){
274 mc_config_set_string(mc_panels_config, section, "list_mode", list_types [i].key);
275 break;
278 mc_config_set_string(mc_panels_config, section, "user_format", panel->user_format);
280 for (i = 0; i < LIST_TYPES; i++){
281 buffer = g_strdup_printf("user_status%d", i);
282 mc_config_set_string(mc_panels_config, section, buffer, panel->user_status_format [i]);
283 g_free(buffer);
286 mc_config_set_int(mc_panels_config, section, "user_mini_status", panel->user_mini_status);
289 void
290 save_layout (void)
292 char *profile;
293 int i;
295 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
297 /* Save integer options */
298 for (i = 0; layout [i].opt_name; i++){
299 mc_config_set_int(mc_main_config, "Layout", layout [i].opt_name, *layout [i].opt_addr);
301 mc_config_save_to_file (mc_main_config, profile, NULL);
303 g_free (profile);
306 void
307 save_configure (void)
309 char *profile;
310 GError *error = NULL;
311 int i;
313 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
315 /* Save integer options */
316 for (i = 0; int_options[i].opt_name; i++)
317 mc_config_set_int(mc_main_config, CONFIG_APP_SECTION, int_options[i].opt_name, *int_options[i].opt_addr);
319 /* Save string options */
320 for (i = 0; str_options[i].opt_name != NULL; i++)
321 mc_config_set_string(mc_main_config, CONFIG_APP_SECTION, str_options[i].opt_name, *str_options[i].opt_addr);
323 if (! mc_config_save_to_file (mc_main_config, profile, &error))
324 setup_save_config_show_error(profile, &error);
326 g_free (profile);
329 static void
330 panel_save_type (const char *section, panel_view_mode_t type)
332 int i;
334 for (i = 0; panel_types [i].opt_name != NULL; i++)
335 if (panel_types [i].opt_type == type) {
336 mc_config_set_string (mc_panels_config, section,
337 "display", panel_types [i].opt_name);
338 break;
342 void
343 save_panel_types (void)
345 panel_view_mode_t type;
347 if ((view_one_file != NULL) || (edit_one_file != NULL))
348 return;
350 if (!mc_config_get_int (mc_main_config, CONFIG_APP_SECTION,
351 "auto_save_setup_panels", auto_save_setup))
352 return;
354 type = get_display_type (0);
355 panel_save_type ("New Left Panel", type);
356 if (type == view_listing)
357 panel_save_setup (left_panel, left_panel->panel_name);
358 type = get_display_type (1);
359 panel_save_type ("New Right Panel", type);
360 if (type == view_listing)
361 panel_save_setup (right_panel, right_panel->panel_name);
363 mc_config_set_string (mc_panels_config, "Dirs" , "other_dir",
364 get_panel_dir_for (other_panel));
366 if (current_panel != NULL)
367 mc_config_set_string (mc_panels_config, "Dirs" , "current_is_left",
368 get_current_index () == 0 ? "1" : "0");
370 if (mc_panels_config->ini_path == NULL)
371 mc_panels_config->ini_path = g_strdup (panels_profile_name);
373 mc_config_del_group (mc_panels_config, "Temporal:New Left Panel");
374 mc_config_del_group (mc_panels_config, "Temporal:New Right Panel");
376 mc_config_save_file (mc_panels_config, NULL);
379 gboolean
380 save_setup (void)
382 char *tmp_profile;
383 gboolean ret;
385 saving_setup = 1;
387 save_configure ();
389 save_layout ();
391 save_hotlist ();
393 save_panelize ();
394 save_panel_types ();
395 /* directory_history_save (); */
397 #if defined(ENABLE_VFS) && defined (USE_NETCODE)
398 mc_config_set_string(mc_main_config, "Misc" , "ftpfs_password",
399 ftpfs_anonymous_passwd);
400 if (ftpfs_proxy_host)
401 mc_config_set_string(mc_main_config, "Misc" , "ftp_proxy_host",
402 ftpfs_proxy_host);
403 #endif /* ENABLE_VFS && USE_NETCODE */
405 #ifdef HAVE_CHARSET
406 mc_config_set_string (mc_main_config, "Misc" , "display_codepage",
407 get_codepage_id( display_codepage ));
408 mc_config_set_string (mc_main_config, "Misc" , "source_codepage",
409 get_codepage_id( default_source_codepage ));
410 mc_config_set_string (mc_main_config, "Misc" , "autodetect_codeset",
411 autodetect_codeset );
412 #endif /* HAVE_CHARSET */
413 tmp_profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
414 ret = mc_config_save_to_file (mc_main_config, tmp_profile, NULL);
416 g_free (tmp_profile);
417 saving_setup = 0;
418 return ret;
421 void
422 panel_load_setup (WPanel *panel, const char *section)
424 size_t i;
425 char *buffer;
427 panel->reverse = mc_config_get_int(mc_panels_config, section, "reverse", 0);
428 panel->case_sensitive = mc_config_get_int(mc_panels_config, section, "case_sensitive", OS_SORT_CASE_SENSITIVE_DEFAULT);
429 panel->exec_first = mc_config_get_int(mc_panels_config, section, "exec_first", 0);
431 /* Load sort order */
432 buffer = mc_config_get_string(mc_panels_config, section, "sort_order", "name");
433 panel->current_sort_field = panel_get_field_by_id(buffer);
434 if (panel->current_sort_field == NULL )
435 panel->current_sort_field = panel_get_field_by_id("name");
437 g_free(buffer);
439 /* Load the listing mode */
440 buffer = mc_config_get_string(mc_panels_config, section, "list_mode", "full");
441 panel->list_type = list_full;
442 for (i = 0; list_types [i].key; i++)
443 if ( g_strcasecmp (list_types [i].key, buffer) == 0){
444 panel->list_type = list_types [i].list_type;
445 break;
447 g_free(buffer);
449 /* User formats */
450 g_free (panel->user_format);
451 panel->user_format = mc_config_get_string(mc_panels_config, section, "user_format", DEFAULT_USER_FORMAT);
453 for (i = 0; i < LIST_TYPES; i++){
454 g_free (panel->user_status_format [i]);
455 buffer = g_strdup_printf("user_status%d",i);
456 panel->user_status_format [i] =
457 mc_config_get_string(mc_panels_config, section, buffer, DEFAULT_USER_FORMAT);
458 g_free(buffer);
461 panel->user_mini_status =
462 mc_config_get_int(mc_panels_config, section, "user_mini_status", 0);
466 static void
467 load_layout ()
469 int i;
471 for (i = 0; layout [i].opt_name; i++)
472 *layout [i].opt_addr =
473 mc_config_get_int(mc_main_config,"Layout", layout [i].opt_name, *layout [i].opt_addr);
476 static panel_view_mode_t
477 setup__load_panel_state (const char *section)
479 char *buffer;
480 size_t i;
481 panel_view_mode_t mode = view_listing;
483 /* Load the display mode */
484 buffer = mc_config_get_string (mc_panels_config, section, "display", "listing");
486 for (i = 0; panel_types [i].opt_name != NULL; i++)
487 if (g_strcasecmp (panel_types [i].opt_name, buffer) == 0) {
488 mode = panel_types [i].opt_type;
489 break;
491 g_free (buffer);
492 return mode;
495 static const char *
496 setup__is_cfg_group_must_panel_config(const char *grp)
498 if (
499 ! strcasecmp("Dirs",grp) ||
500 ! strcasecmp("Temporal:New Right Panel",grp) ||
501 ! strcasecmp("Temporal:New Left Panel",grp) ||
502 ! strcasecmp("New Left Panel",grp) ||
503 ! strcasecmp("New Right Panel",grp)
505 return grp;
506 return NULL;
509 static void
510 setup__move_panels_config_into_separate_file(const char*profile)
512 mc_config_t *tmp_cfg;
513 char **groups, **curr_grp;
514 const char *need_grp;
516 if (!exist_file(profile))
517 return;
519 tmp_cfg = mc_config_init(profile);
520 if (!tmp_cfg)
521 return;
523 curr_grp = groups = mc_config_get_groups (tmp_cfg, NULL);
524 if (!groups)
526 mc_config_deinit(tmp_cfg);
527 return;
529 while (*curr_grp)
531 if ( setup__is_cfg_group_must_panel_config(*curr_grp) == NULL)
533 mc_config_del_group (tmp_cfg, *curr_grp);
535 curr_grp++;
538 mc_config_save_to_file (tmp_cfg, panels_profile_name, NULL);
539 mc_config_deinit(tmp_cfg);
541 tmp_cfg = mc_config_init(profile);
542 if (!tmp_cfg)
544 g_strfreev(groups);
545 return;
548 curr_grp = groups;
550 while (*curr_grp)
552 need_grp = setup__is_cfg_group_must_panel_config(*curr_grp);
553 if ( need_grp != NULL)
555 mc_config_del_group (tmp_cfg, need_grp);
557 curr_grp++;
559 g_strfreev(groups);
560 mc_config_save_file (tmp_cfg, NULL);
561 mc_config_deinit(tmp_cfg);
566 Get name of config file.
568 \param subdir
569 if not NULL, then config also search into specified subdir
571 \param config_file_name
572 If specified filename is relative, then will search in standart patches.
574 \return
575 Newly allocated path to config name or NULL if file not found
577 If config_file_name is a relative path, then search config in stantart pathes */
578 static char*
579 load_setup_get_full_config_name(const char *subdir, const char *config_file_name)
582 TODO: IMHO, in future this function must be placed into mc_config module.
583 Also, need to rename stupid mc_home and mc_home_alt to mc_sysconfdir and mc_datadir;
584 home_mc => mc_user_homedir
586 char *lc_basename, *ret;
588 if (config_file_name == NULL)
589 return NULL;
591 if (g_path_is_absolute (config_file_name))
592 return g_strdup(config_file_name);
595 lc_basename = g_path_get_basename(config_file_name);
596 if (lc_basename == NULL)
597 return NULL;
600 if (subdir)
601 ret = g_build_filename (home_dir, MC_USERCONF_DIR, subdir, lc_basename, NULL);
602 else
603 ret = g_build_filename (home_dir, MC_USERCONF_DIR, lc_basename, NULL);
605 if (exist_file(ret)) {
606 g_free(lc_basename);
607 return ret;
609 g_free(ret);
612 if (subdir)
613 ret = g_build_filename (mc_home, subdir, lc_basename, NULL);
614 else
615 ret = g_build_filename (mc_home, lc_basename, NULL);
617 if (exist_file(ret)) {
618 g_free(lc_basename);
619 return ret;
621 g_free(ret);
623 if (subdir)
624 ret = g_build_filename (mc_home_alt, subdir, lc_basename, NULL);
625 else
626 ret = g_build_filename (mc_home_alt, lc_basename, NULL);
628 if (exist_file(ret)) {
629 g_free(lc_basename);
630 return ret;
632 g_free(ret);
633 g_free(lc_basename);
634 return NULL;
639 Create new mc_config object from specified ini-file or
640 append data to existing mc_config object from ini-file
643 static void
644 load_setup_init_config_from_file(mc_config_t **config, const char *fname)
647 TODO: IMHO, in future this function must be placed into mc_config module.
649 if (exist_file(fname)) {
650 if (*config)
651 mc_config_read_file( *config, fname);
652 else
653 *config = mc_config_init(fname);
659 static mc_config_t *
660 load_setup_get_keymap_profile_config(void)
663 TODO: IMHO, in future this function must be placed into mc_config module.
665 mc_config_t *keymap_config = NULL ;
667 char *fname, *fname2;
669 /* 1) /usr/share/mc (mc_home_alt) */
670 fname = g_build_filename (mc_home_alt, GLOBAL_KEYMAP_FILE, NULL);
671 load_setup_init_config_from_file( &keymap_config, fname);
672 g_free(fname);
674 /* 2) /etc/mc (mc_home) */
675 fname = g_build_filename (mc_home, GLOBAL_KEYMAP_FILE, NULL);
676 load_setup_init_config_from_file( &keymap_config, fname);
677 g_free(fname);
679 /* 3) ~/.mc (home_dir?) */
680 fname = g_build_filename (home_dir, MC_USERCONF_DIR, GLOBAL_KEYMAP_FILE, NULL);
681 load_setup_init_config_from_file( &keymap_config, fname);
682 g_free(fname);
684 /* 4) main config; [Midnight Commander] -> keymap*/
686 fname2 = mc_config_get_string(mc_main_config, CONFIG_APP_SECTION, "keymap" , GLOBAL_KEYMAP_FILE);
687 fname = load_setup_get_full_config_name(NULL, fname2);
688 if (fname)
690 load_setup_init_config_from_file( &keymap_config, fname);
691 g_free(fname);
693 g_free(fname2);
695 /* 5) getenv("MC_KEYMAP") */
696 fname = load_setup_get_full_config_name(NULL, g_getenv ("MC_KEYMAP"));
697 if (fname)
699 load_setup_init_config_from_file( &keymap_config, fname);
700 g_free(fname);
703 /* 6) --keymap=<keymap> */
704 fname = load_setup_get_full_config_name(NULL, mc_args__keymap_file);
705 if (fname)
707 load_setup_init_config_from_file( &keymap_config, fname);
708 g_free(fname);
711 return keymap_config;
714 char *
715 setup_init (void)
717 char *profile;
718 char *inifile;
720 if (profile_name)
721 return profile_name;
723 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
724 if (!exist_file (profile)){
725 inifile = concat_dir_and_file (mc_home, "mc.ini");
726 if (exist_file (inifile)){
727 g_free (profile);
728 profile = inifile;
729 } else {
730 g_free (inifile);
731 inifile = concat_dir_and_file (mc_home_alt, "mc.ini");
732 if (exist_file (inifile)) {
733 g_free (profile);
734 profile = inifile;
735 } else
736 g_free (inifile);
740 profile_name = profile;
742 return profile;
745 void
746 load_setup (void)
748 char *profile;
749 int i;
750 char *buffer;
752 profile = setup_init ();
754 /* mc.lib is common for all users, but has priority lower than
755 ~/.mc/ini. FIXME: it's only used for keys and treestore now */
756 global_profile_name = concat_dir_and_file (mc_home, MC_GLOBAL_CONFIG_FILE);
757 if (!exist_file (global_profile_name)) {
758 g_free (global_profile_name);
759 global_profile_name = concat_dir_and_file (mc_home_alt, MC_GLOBAL_CONFIG_FILE);
762 panels_profile_name = g_build_filename (home_dir, MC_USERCONF_DIR, MC_PANELS_FILE, NULL);
764 mc_main_config = mc_config_init (profile);
766 if (!exist_file(panels_profile_name))
767 setup__move_panels_config_into_separate_file (profile);
769 mc_panels_config = mc_config_init (panels_profile_name);
771 /* Load integer boolean options */
772 for (i = 0; int_options[i].opt_name; i++)
773 *int_options[i].opt_addr =
774 mc_config_get_int(mc_main_config, CONFIG_APP_SECTION, int_options[i].opt_name, *int_options[i].opt_addr);
776 /* Load string options */
777 for (i = 0; str_options[i].opt_name != NULL; i++)
778 *str_options[i].opt_addr =
779 mc_config_get_string (mc_main_config, CONFIG_APP_SECTION, str_options[i].opt_name, str_options[i].opt_defval);
781 load_layout ();
783 load_panelize ();
785 startup_left_mode = setup__load_panel_state ("New Left Panel");
786 startup_right_mode = setup__load_panel_state ("New Right Panel");
788 /* At least one of the panels is a listing panel */
789 if (startup_left_mode != view_listing && startup_right_mode != view_listing)
790 startup_left_mode = view_listing;
792 if (!other_dir){
793 buffer = mc_config_get_string (mc_panels_config, "Dirs", "other_dir", ".");
794 if (vfs_file_is_local (buffer))
795 other_dir = buffer;
796 else
797 g_free (buffer);
800 boot_current_is_left =
801 mc_config_get_int (mc_panels_config, "Dirs", "current_is_left", 1);
803 /* Load time formats */
804 user_recent_timeformat = mc_config_get_string (mc_main_config, "Misc", "timeformat_recent", FMTTIME);
805 user_old_timeformat = mc_config_get_string (mc_main_config, "Misc", "timeformat_old", FMTYEAR);
807 #ifdef USE_NETCODE
808 ftpfs_proxy_host = mc_config_get_string (mc_main_config, "Misc", "ftp_proxy_host", "gate");
809 #endif
811 /* The default color and the terminal dependent color */
812 setup_color_string = mc_config_get_string (mc_main_config, "Colors", "base_color", "");
813 term_color_string = mc_config_get_string (mc_main_config, "Colors", getenv ("TERM"), "");
814 color_terminal_string = mc_config_get_string (mc_main_config, "Colors", "color_terminals", "");
816 /* Load the directory history */
817 /* directory_history_load (); */
818 /* Remove the temporal entries */
819 #if defined(ENABLE_VFS) && defined (USE_NETCODE)
820 ftpfs_init_passwd ();
821 #endif /* ENABLE_VFS && USE_NETCODE */
823 #ifdef HAVE_CHARSET
824 if (load_codepages_list () > 0) {
825 buffer = mc_config_get_string (mc_main_config, "Misc", "display_codepage", "");
826 if (buffer[0] != '\0') {
827 display_codepage = get_codepage_index (buffer);
828 cp_display = get_codepage_id (display_codepage);
830 g_free(buffer);
831 buffer = mc_config_get_string(mc_main_config, "Misc", "source_codepage", "");
832 if (buffer[0] != '\0') {
833 default_source_codepage = get_codepage_index (buffer);
834 source_codepage = default_source_codepage; /* May be source_codepage don't needed this */
835 cp_source = get_codepage_id (source_codepage);
837 g_free(buffer);
840 autodetect_codeset = mc_config_get_string (mc_main_config, "Misc", "autodetect_codeset", "");
841 if ((autodetect_codeset[0] != '\0') && (strcmp(autodetect_codeset, "off")))
842 is_autodetect_codeset_enabled=TRUE;
844 init_translation_table (source_codepage, display_codepage);
845 if (get_codepage_id (display_codepage))
846 utf8_display = str_isutf8 (get_codepage_id (display_codepage));
847 #endif /* HAVE_CHARSET */
850 #if defined(ENABLE_VFS) && defined (USE_NETCODE)
851 char *
852 load_anon_passwd ()
854 char *buffer;
856 buffer = mc_config_get_string(mc_main_config, "Misc", "ftpfs_password", "");
857 if (buffer [0])
858 return buffer;
860 g_free(buffer);
861 return NULL;
863 #endif /* ENABLE_VFS && USE_NETCODE */
865 void
866 done_setup (void)
868 int i;
870 g_free (profile_name);
871 g_free (global_profile_name);
872 g_free (color_terminal_string);
873 g_free (term_color_string);
874 g_free (setup_color_string);
875 g_free (panels_profile_name);
876 mc_config_deinit (mc_main_config);
877 mc_config_deinit (mc_panels_config);
879 g_free(user_recent_timeformat);
880 g_free(user_old_timeformat);
882 for (i = 0; str_options[i].opt_name != NULL; i++)
883 g_free (*str_options[i].opt_addr);
885 done_hotlist ();
886 done_panelize ();
887 /* directory_history_free (); */
890 static void
891 load_keys_from_section (const char *terminal, mc_config_t *cfg)
893 char *section_name;
894 gchar **profile_keys, **keys;
895 gchar **values, **curr_values;
896 char *valcopy, *value;
897 long key_code;
898 gsize len, values_len;
900 if (!terminal)
901 return;
903 section_name = g_strconcat ("terminal:", terminal, (char *) NULL);
904 profile_keys = keys = mc_config_get_keys (cfg, section_name, &len);
906 while (*profile_keys){
908 /* copy=other causes all keys from [terminal:other] to be loaded. */
909 if (g_strcasecmp (*profile_keys, "copy") == 0) {
910 valcopy = mc_config_get_string (cfg, section_name, *profile_keys, "");
911 load_keys_from_section (valcopy, cfg);
912 g_free(valcopy);
913 profile_keys++;
914 continue;
916 curr_values = values = mc_config_get_string_list (cfg, section_name, *profile_keys, &values_len);
918 key_code = lookup_key (*profile_keys, NULL);
919 if (key_code != 0) {
920 if (curr_values){
921 while (*curr_values){
922 valcopy = convert_controls (*curr_values);
923 define_sequence (key_code, valcopy, MCKEY_NOACTION);
924 g_free (valcopy);
925 curr_values++;
927 } else {
928 value = mc_config_get_string (cfg, section_name, *profile_keys, "");
929 valcopy = convert_controls (value);
930 define_sequence (key_code, valcopy, MCKEY_NOACTION);
931 g_free (valcopy);
932 g_free (value);
935 profile_keys++;
936 if (values)
937 g_strfreev (values);
939 g_strfreev (keys);
940 g_free (section_name);
943 void load_key_defs (void)
946 * Load keys from mc.lib before ~/.mc/ini, so that the user
947 * definitions override global settings.
949 mc_config_t *mc_global_config;
951 mc_global_config = mc_config_init(global_profile_name);
952 if (mc_global_config != NULL)
954 load_keys_from_section ("general", mc_global_config);
955 load_keys_from_section (getenv ("TERM"), mc_global_config);
956 mc_config_deinit(mc_global_config);
958 load_keys_from_section ("general", mc_main_config);
959 load_keys_from_section (getenv ("TERM"), mc_main_config);
963 static void
964 load_keymap_from_section (const char *section_name, GArray *keymap, mc_config_t *cfg)
966 gchar **profile_keys, **keys;
967 gchar **values, **curr_values;
968 char *valcopy, *value;
969 int action;
970 gsize len, values_len;
972 if (!section_name)
973 return;
975 profile_keys = keys = mc_config_get_keys (cfg, section_name, &len);
977 while (*profile_keys) {
978 curr_values = values = mc_config_get_string_list (cfg, section_name, *profile_keys, &values_len);
979 action = lookup_action (*profile_keys);
980 if (action>0) {
981 if (curr_values) {
982 while (*curr_values) {
983 valcopy = convert_controls (*curr_values);
984 keybind_cmd_bind (keymap, valcopy, action);
985 g_free (valcopy);
986 curr_values++;
988 } else {
989 value = mc_config_get_string (cfg, section_name, *profile_keys, "");
990 valcopy = convert_controls (value);
991 /* define_sequence (key_code, valcopy, MCKEY_NOACTION); */
992 g_free (valcopy);
993 g_free (value);
996 profile_keys++;
997 if (values)
998 g_strfreev(values);
1000 g_strfreev(keys);
1003 void
1004 load_keymap_defs (void)
1007 * Load keymap from GLOBAL_KEYMAP_FILE before ~/.mc/keymap, so that the user
1008 * definitions override global settings.
1010 mc_config_t *mc_global_keymap;
1012 mc_global_keymap = load_setup_get_keymap_profile_config();
1014 if (mc_global_keymap != NULL)
1016 #ifdef USE_INTERNAL_EDIT
1017 editor_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1018 load_keymap_from_section ("editor", editor_keymap, mc_global_keymap);
1019 editor_x_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1020 load_keymap_from_section ("editor:xmap", editor_x_keymap, mc_global_keymap);
1021 #endif
1023 viewer_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1024 load_keymap_from_section ("viewer", viewer_keymap, mc_global_keymap);
1025 viewer_hex_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1026 load_keymap_from_section ("viewer:hex", viewer_hex_keymap, mc_global_keymap);
1028 main_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1029 load_keymap_from_section ("main", main_keymap, mc_global_keymap);
1030 main_x_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1031 load_keymap_from_section ("main:xmap", main_x_keymap, mc_global_keymap);
1033 panel_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1034 load_keymap_from_section ("panel", panel_keymap, mc_global_keymap);
1036 input_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1037 load_keymap_from_section ("input", input_keymap, mc_global_keymap);
1039 tree_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1040 load_keymap_from_section ("tree", tree_keymap, mc_global_keymap);
1042 help_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1043 load_keymap_from_section ("help", help_keymap, mc_global_keymap);
1045 mc_config_deinit (mc_global_keymap);
1049 void
1050 free_keymap_defs (void)
1052 #ifdef USE_INTERNAL_EDIT
1053 if (editor_keymap != NULL)
1054 g_array_free (editor_keymap, TRUE);
1055 if (editor_x_keymap != NULL)
1056 g_array_free (editor_x_keymap, TRUE);
1057 #endif
1058 if (viewer_keymap != NULL)
1059 g_array_free (viewer_keymap, TRUE);
1060 if (viewer_hex_keymap != NULL)
1061 g_array_free (viewer_hex_keymap, TRUE);
1062 if (main_keymap != NULL)
1063 g_array_free (main_keymap, TRUE);
1064 if (main_x_keymap != NULL)
1065 g_array_free (main_x_keymap, TRUE);
1066 if (panel_keymap != NULL)
1067 g_array_free (panel_keymap, TRUE);
1068 if (input_keymap != NULL)
1069 g_array_free (input_keymap, TRUE);
1070 if (tree_keymap != NULL)
1071 g_array_free (tree_keymap, TRUE);
1072 if (help_keymap != NULL)
1073 g_array_free (help_keymap, TRUE);
1076 void
1077 setup_save_config_show_error(const char *filename, GError **error)
1079 if (error == NULL || *error == NULL)
1080 return;
1082 message (D_ERROR, MSG_ERROR, _("Cannot save file %s:\n%s"),
1083 filename, (*error)->message);
1085 g_error_free(*error);
1086 *error = NULL;