avoid often memory alocation&release
[midnight-commander.git] / src / setup.c
blobad9eba5576461efdffd69428c57e48431e72bffc
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[BUF_TINY];
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 g_snprintf (buffer, BUF_TINY, "user_status%lld", (long long) i);
282 mc_config_set_string(mc_panels_config, section, buffer, panel->user_status_format [i]);
285 mc_config_set_int(mc_panels_config, section, "user_mini_status", panel->user_mini_status);
288 void
289 save_layout (void)
291 char *profile;
292 int i;
294 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
296 /* Save integer options */
297 for (i = 0; layout [i].opt_name; i++){
298 mc_config_set_int(mc_main_config, "Layout", layout [i].opt_name, *layout [i].opt_addr);
300 mc_config_save_to_file (mc_main_config, profile, NULL);
302 g_free (profile);
305 void
306 save_configure (void)
308 char *profile;
309 GError *error = NULL;
310 int i;
312 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
314 /* Save integer options */
315 for (i = 0; int_options[i].opt_name; i++)
316 mc_config_set_int(mc_main_config, CONFIG_APP_SECTION, int_options[i].opt_name, *int_options[i].opt_addr);
318 /* Save string options */
319 for (i = 0; str_options[i].opt_name != NULL; i++)
320 mc_config_set_string(mc_main_config, CONFIG_APP_SECTION, str_options[i].opt_name, *str_options[i].opt_addr);
322 if (! mc_config_save_to_file (mc_main_config, profile, &error))
323 setup_save_config_show_error(profile, &error);
325 g_free (profile);
328 static void
329 panel_save_type (const char *section, panel_view_mode_t type)
331 int i;
333 for (i = 0; panel_types [i].opt_name != NULL; i++)
334 if (panel_types [i].opt_type == type) {
335 mc_config_set_string (mc_panels_config, section,
336 "display", panel_types [i].opt_name);
337 break;
341 void
342 save_panel_types (void)
344 panel_view_mode_t type;
346 if ((view_one_file != NULL) || (edit_one_file != NULL))
347 return;
349 if (!mc_config_get_int (mc_main_config, CONFIG_APP_SECTION,
350 "auto_save_setup_panels", auto_save_setup))
351 return;
353 type = get_display_type (0);
354 panel_save_type ("New Left Panel", type);
355 if (type == view_listing)
356 panel_save_setup (left_panel, left_panel->panel_name);
357 type = get_display_type (1);
358 panel_save_type ("New Right Panel", type);
359 if (type == view_listing)
360 panel_save_setup (right_panel, right_panel->panel_name);
362 mc_config_set_string (mc_panels_config, "Dirs" , "other_dir",
363 get_panel_dir_for (other_panel));
365 if (current_panel != NULL)
366 mc_config_set_string (mc_panels_config, "Dirs" , "current_is_left",
367 get_current_index () == 0 ? "1" : "0");
369 if (mc_panels_config->ini_path == NULL)
370 mc_panels_config->ini_path = g_strdup (panels_profile_name);
372 mc_config_del_group (mc_panels_config, "Temporal:New Left Panel");
373 mc_config_del_group (mc_panels_config, "Temporal:New Right Panel");
375 mc_config_save_file (mc_panels_config, NULL);
378 gboolean
379 save_setup (void)
381 char *tmp_profile;
382 gboolean ret;
384 saving_setup = 1;
386 save_configure ();
388 save_layout ();
390 save_hotlist ();
392 save_panelize ();
393 save_panel_types ();
394 /* directory_history_save (); */
396 #if defined(ENABLE_VFS) && defined (USE_NETCODE)
397 mc_config_set_string(mc_main_config, "Misc" , "ftpfs_password",
398 ftpfs_anonymous_passwd);
399 if (ftpfs_proxy_host)
400 mc_config_set_string(mc_main_config, "Misc" , "ftp_proxy_host",
401 ftpfs_proxy_host);
402 #endif /* ENABLE_VFS && USE_NETCODE */
404 #ifdef HAVE_CHARSET
405 mc_config_set_string (mc_main_config, "Misc" , "display_codepage",
406 get_codepage_id( display_codepage ));
407 mc_config_set_string (mc_main_config, "Misc" , "source_codepage",
408 get_codepage_id( default_source_codepage ));
409 mc_config_set_string (mc_main_config, "Misc" , "autodetect_codeset",
410 autodetect_codeset );
411 #endif /* HAVE_CHARSET */
412 tmp_profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
413 ret = mc_config_save_to_file (mc_main_config, tmp_profile, NULL);
415 g_free (tmp_profile);
416 saving_setup = 0;
417 return ret;
420 void
421 panel_load_setup (WPanel *panel, const char *section)
423 size_t i;
424 char *buffer, buffer2[BUF_TINY];
426 panel->reverse = mc_config_get_int(mc_panels_config, section, "reverse", 0);
427 panel->case_sensitive = mc_config_get_int(mc_panels_config, section, "case_sensitive", OS_SORT_CASE_SENSITIVE_DEFAULT);
428 panel->exec_first = mc_config_get_int(mc_panels_config, section, "exec_first", 0);
430 /* Load sort order */
431 buffer = mc_config_get_string(mc_panels_config, section, "sort_order", "name");
432 panel->current_sort_field = panel_get_field_by_id(buffer);
433 if (panel->current_sort_field == NULL )
434 panel->current_sort_field = panel_get_field_by_id("name");
436 g_free(buffer);
438 /* Load the listing mode */
439 buffer = mc_config_get_string(mc_panels_config, section, "list_mode", "full");
440 panel->list_type = list_full;
441 for (i = 0; list_types [i].key; i++)
442 if ( g_strcasecmp (list_types [i].key, buffer) == 0){
443 panel->list_type = list_types [i].list_type;
444 break;
446 g_free(buffer);
448 /* User formats */
449 g_free (panel->user_format);
450 panel->user_format = mc_config_get_string(mc_panels_config, section, "user_format", DEFAULT_USER_FORMAT);
452 for (i = 0; i < LIST_TYPES; i++){
453 g_free (panel->user_status_format [i]);
454 g_snprintf (buffer2, BUF_TINY, "user_status%lld", (long long) i);
455 panel->user_status_format [i] =
456 mc_config_get_string(mc_panels_config, section, buffer2, DEFAULT_USER_FORMAT);
459 panel->user_mini_status =
460 mc_config_get_int(mc_panels_config, section, "user_mini_status", 0);
464 static void
465 load_layout ()
467 int i;
469 for (i = 0; layout [i].opt_name; i++)
470 *layout [i].opt_addr =
471 mc_config_get_int(mc_main_config,"Layout", layout [i].opt_name, *layout [i].opt_addr);
474 static panel_view_mode_t
475 setup__load_panel_state (const char *section)
477 char *buffer;
478 size_t i;
479 panel_view_mode_t mode = view_listing;
481 /* Load the display mode */
482 buffer = mc_config_get_string (mc_panels_config, section, "display", "listing");
484 for (i = 0; panel_types [i].opt_name != NULL; i++)
485 if (g_strcasecmp (panel_types [i].opt_name, buffer) == 0) {
486 mode = panel_types [i].opt_type;
487 break;
489 g_free (buffer);
490 return mode;
493 static const char *
494 setup__is_cfg_group_must_panel_config(const char *grp)
496 if (
497 ! strcasecmp("Dirs",grp) ||
498 ! strcasecmp("Temporal:New Right Panel",grp) ||
499 ! strcasecmp("Temporal:New Left Panel",grp) ||
500 ! strcasecmp("New Left Panel",grp) ||
501 ! strcasecmp("New Right Panel",grp)
503 return grp;
504 return NULL;
507 static void
508 setup__move_panels_config_into_separate_file(const char*profile)
510 mc_config_t *tmp_cfg;
511 char **groups, **curr_grp;
512 const char *need_grp;
514 if (!exist_file(profile))
515 return;
517 tmp_cfg = mc_config_init(profile);
518 if (!tmp_cfg)
519 return;
521 curr_grp = groups = mc_config_get_groups (tmp_cfg, NULL);
522 if (!groups)
524 mc_config_deinit(tmp_cfg);
525 return;
527 while (*curr_grp)
529 if ( setup__is_cfg_group_must_panel_config(*curr_grp) == NULL)
531 mc_config_del_group (tmp_cfg, *curr_grp);
533 curr_grp++;
536 mc_config_save_to_file (tmp_cfg, panels_profile_name, NULL);
537 mc_config_deinit(tmp_cfg);
539 tmp_cfg = mc_config_init(profile);
540 if (!tmp_cfg)
542 g_strfreev(groups);
543 return;
546 curr_grp = groups;
548 while (*curr_grp)
550 need_grp = setup__is_cfg_group_must_panel_config(*curr_grp);
551 if ( need_grp != NULL)
553 mc_config_del_group (tmp_cfg, need_grp);
555 curr_grp++;
557 g_strfreev(groups);
558 mc_config_save_file (tmp_cfg, NULL);
559 mc_config_deinit(tmp_cfg);
564 Get name of config file.
566 \param subdir
567 if not NULL, then config also search into specified subdir
569 \param config_file_name
570 If specified filename is relative, then will search in standart patches.
572 \return
573 Newly allocated path to config name or NULL if file not found
575 If config_file_name is a relative path, then search config in stantart pathes */
576 static char*
577 load_setup_get_full_config_name(const char *subdir, const char *config_file_name)
580 TODO: IMHO, in future this function must be placed into mc_config module.
581 Also, need to rename stupid mc_home and mc_home_alt to mc_sysconfdir and mc_datadir;
582 home_mc => mc_user_homedir
584 char *lc_basename, *ret;
586 if (config_file_name == NULL)
587 return NULL;
589 if (g_path_is_absolute (config_file_name))
590 return g_strdup(config_file_name);
593 lc_basename = g_path_get_basename(config_file_name);
594 if (lc_basename == NULL)
595 return NULL;
598 if (subdir)
599 ret = g_build_filename (home_dir, MC_USERCONF_DIR, subdir, lc_basename, NULL);
600 else
601 ret = g_build_filename (home_dir, MC_USERCONF_DIR, lc_basename, NULL);
603 if (exist_file(ret)) {
604 g_free(lc_basename);
605 return ret;
607 g_free(ret);
610 if (subdir)
611 ret = g_build_filename (mc_home, subdir, lc_basename, NULL);
612 else
613 ret = g_build_filename (mc_home, lc_basename, NULL);
615 if (exist_file(ret)) {
616 g_free(lc_basename);
617 return ret;
619 g_free(ret);
621 if (subdir)
622 ret = g_build_filename (mc_home_alt, subdir, lc_basename, NULL);
623 else
624 ret = g_build_filename (mc_home_alt, lc_basename, NULL);
626 if (exist_file(ret)) {
627 g_free(lc_basename);
628 return ret;
630 g_free(ret);
631 g_free(lc_basename);
632 return NULL;
637 Create new mc_config object from specified ini-file or
638 append data to existing mc_config object from ini-file
641 static void
642 load_setup_init_config_from_file(mc_config_t **config, const char *fname)
645 TODO: IMHO, in future this function must be placed into mc_config module.
647 if (exist_file(fname)) {
648 if (*config)
649 mc_config_read_file( *config, fname);
650 else
651 *config = mc_config_init(fname);
657 static mc_config_t *
658 load_setup_get_keymap_profile_config(void)
661 TODO: IMHO, in future this function must be placed into mc_config module.
663 mc_config_t *keymap_config = NULL ;
665 char *fname, *fname2;
667 /* 1) /usr/share/mc (mc_home_alt) */
668 fname = g_build_filename (mc_home_alt, GLOBAL_KEYMAP_FILE, NULL);
669 load_setup_init_config_from_file( &keymap_config, fname);
670 g_free(fname);
672 /* 2) /etc/mc (mc_home) */
673 fname = g_build_filename (mc_home, GLOBAL_KEYMAP_FILE, NULL);
674 load_setup_init_config_from_file( &keymap_config, fname);
675 g_free(fname);
677 /* 3) ~/.mc (home_dir?) */
678 fname = g_build_filename (home_dir, MC_USERCONF_DIR, GLOBAL_KEYMAP_FILE, NULL);
679 load_setup_init_config_from_file( &keymap_config, fname);
680 g_free(fname);
682 /* 4) main config; [Midnight Commander] -> keymap*/
684 fname2 = mc_config_get_string(mc_main_config, CONFIG_APP_SECTION, "keymap" , GLOBAL_KEYMAP_FILE);
685 fname = load_setup_get_full_config_name(NULL, fname2);
686 if (fname)
688 load_setup_init_config_from_file( &keymap_config, fname);
689 g_free(fname);
691 g_free(fname2);
693 /* 5) getenv("MC_KEYMAP") */
694 fname = load_setup_get_full_config_name(NULL, g_getenv ("MC_KEYMAP"));
695 if (fname)
697 load_setup_init_config_from_file( &keymap_config, fname);
698 g_free(fname);
701 /* 6) --keymap=<keymap> */
702 fname = load_setup_get_full_config_name(NULL, mc_args__keymap_file);
703 if (fname)
705 load_setup_init_config_from_file( &keymap_config, fname);
706 g_free(fname);
709 return keymap_config;
712 char *
713 setup_init (void)
715 char *profile;
716 char *inifile;
718 if (profile_name)
719 return profile_name;
721 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
722 if (!exist_file (profile)){
723 inifile = concat_dir_and_file (mc_home, "mc.ini");
724 if (exist_file (inifile)){
725 g_free (profile);
726 profile = inifile;
727 } else {
728 g_free (inifile);
729 inifile = concat_dir_and_file (mc_home_alt, "mc.ini");
730 if (exist_file (inifile)) {
731 g_free (profile);
732 profile = inifile;
733 } else
734 g_free (inifile);
738 profile_name = profile;
740 return profile;
743 void
744 load_setup (void)
746 char *profile;
747 int i;
748 char *buffer;
750 profile = setup_init ();
752 /* mc.lib is common for all users, but has priority lower than
753 ~/.mc/ini. FIXME: it's only used for keys and treestore now */
754 global_profile_name = concat_dir_and_file (mc_home, MC_GLOBAL_CONFIG_FILE);
755 if (!exist_file (global_profile_name)) {
756 g_free (global_profile_name);
757 global_profile_name = concat_dir_and_file (mc_home_alt, MC_GLOBAL_CONFIG_FILE);
760 panels_profile_name = g_build_filename (home_dir, MC_USERCONF_DIR, MC_PANELS_FILE, NULL);
762 mc_main_config = mc_config_init (profile);
764 if (!exist_file(panels_profile_name))
765 setup__move_panels_config_into_separate_file (profile);
767 mc_panels_config = mc_config_init (panels_profile_name);
769 /* Load integer boolean options */
770 for (i = 0; int_options[i].opt_name; i++)
771 *int_options[i].opt_addr =
772 mc_config_get_int(mc_main_config, CONFIG_APP_SECTION, int_options[i].opt_name, *int_options[i].opt_addr);
774 /* Load string options */
775 for (i = 0; str_options[i].opt_name != NULL; i++)
776 *str_options[i].opt_addr =
777 mc_config_get_string (mc_main_config, CONFIG_APP_SECTION, str_options[i].opt_name, str_options[i].opt_defval);
779 load_layout ();
781 load_panelize ();
783 startup_left_mode = setup__load_panel_state ("New Left Panel");
784 startup_right_mode = setup__load_panel_state ("New Right Panel");
786 /* At least one of the panels is a listing panel */
787 if (startup_left_mode != view_listing && startup_right_mode != view_listing)
788 startup_left_mode = view_listing;
790 if (!other_dir){
791 buffer = mc_config_get_string (mc_panels_config, "Dirs", "other_dir", ".");
792 if (vfs_file_is_local (buffer))
793 other_dir = buffer;
794 else
795 g_free (buffer);
798 boot_current_is_left =
799 mc_config_get_int (mc_panels_config, "Dirs", "current_is_left", 1);
801 /* Load time formats */
802 user_recent_timeformat = mc_config_get_string (mc_main_config, "Misc", "timeformat_recent", FMTTIME);
803 user_old_timeformat = mc_config_get_string (mc_main_config, "Misc", "timeformat_old", FMTYEAR);
805 #ifdef USE_NETCODE
806 ftpfs_proxy_host = mc_config_get_string (mc_main_config, "Misc", "ftp_proxy_host", "gate");
807 #endif
809 /* The default color and the terminal dependent color */
810 setup_color_string = mc_config_get_string (mc_main_config, "Colors", "base_color", "");
811 term_color_string = mc_config_get_string (mc_main_config, "Colors", getenv ("TERM"), "");
812 color_terminal_string = mc_config_get_string (mc_main_config, "Colors", "color_terminals", "");
814 /* Load the directory history */
815 /* directory_history_load (); */
816 /* Remove the temporal entries */
817 #if defined(ENABLE_VFS) && defined (USE_NETCODE)
818 ftpfs_init_passwd ();
819 #endif /* ENABLE_VFS && USE_NETCODE */
821 #ifdef HAVE_CHARSET
822 if (load_codepages_list () > 0) {
823 buffer = mc_config_get_string (mc_main_config, "Misc", "display_codepage", "");
824 if (buffer[0] != '\0') {
825 display_codepage = get_codepage_index (buffer);
826 cp_display = get_codepage_id (display_codepage);
828 g_free(buffer);
829 buffer = mc_config_get_string(mc_main_config, "Misc", "source_codepage", "");
830 if (buffer[0] != '\0') {
831 default_source_codepage = get_codepage_index (buffer);
832 source_codepage = default_source_codepage; /* May be source_codepage don't needed this */
833 cp_source = get_codepage_id (source_codepage);
835 g_free(buffer);
838 autodetect_codeset = mc_config_get_string (mc_main_config, "Misc", "autodetect_codeset", "");
839 if ((autodetect_codeset[0] != '\0') && (strcmp(autodetect_codeset, "off")))
840 is_autodetect_codeset_enabled=TRUE;
842 init_translation_table (source_codepage, display_codepage);
843 if (get_codepage_id (display_codepage))
844 utf8_display = str_isutf8 (get_codepage_id (display_codepage));
845 #endif /* HAVE_CHARSET */
848 #if defined(ENABLE_VFS) && defined (USE_NETCODE)
849 char *
850 load_anon_passwd ()
852 char *buffer;
854 buffer = mc_config_get_string(mc_main_config, "Misc", "ftpfs_password", "");
855 if (buffer [0])
856 return buffer;
858 g_free(buffer);
859 return NULL;
861 #endif /* ENABLE_VFS && USE_NETCODE */
863 void
864 done_setup (void)
866 int i;
868 g_free (profile_name);
869 g_free (global_profile_name);
870 g_free (color_terminal_string);
871 g_free (term_color_string);
872 g_free (setup_color_string);
873 g_free (panels_profile_name);
874 mc_config_deinit (mc_main_config);
875 mc_config_deinit (mc_panels_config);
877 g_free(user_recent_timeformat);
878 g_free(user_old_timeformat);
880 for (i = 0; str_options[i].opt_name != NULL; i++)
881 g_free (*str_options[i].opt_addr);
883 done_hotlist ();
884 done_panelize ();
885 /* directory_history_free (); */
888 static void
889 load_keys_from_section (const char *terminal, mc_config_t *cfg)
891 char *section_name;
892 gchar **profile_keys, **keys;
893 gchar **values, **curr_values;
894 char *valcopy, *value;
895 long key_code;
896 gsize len, values_len;
898 if (!terminal)
899 return;
901 section_name = g_strconcat ("terminal:", terminal, (char *) NULL);
902 profile_keys = keys = mc_config_get_keys (cfg, section_name, &len);
904 while (*profile_keys){
906 /* copy=other causes all keys from [terminal:other] to be loaded. */
907 if (g_strcasecmp (*profile_keys, "copy") == 0) {
908 valcopy = mc_config_get_string (cfg, section_name, *profile_keys, "");
909 load_keys_from_section (valcopy, cfg);
910 g_free(valcopy);
911 profile_keys++;
912 continue;
914 curr_values = values = mc_config_get_string_list (cfg, section_name, *profile_keys, &values_len);
916 key_code = lookup_key (*profile_keys, NULL);
917 if (key_code != 0) {
918 if (curr_values){
919 while (*curr_values){
920 valcopy = convert_controls (*curr_values);
921 define_sequence (key_code, valcopy, MCKEY_NOACTION);
922 g_free (valcopy);
923 curr_values++;
925 } else {
926 value = mc_config_get_string (cfg, section_name, *profile_keys, "");
927 valcopy = convert_controls (value);
928 define_sequence (key_code, valcopy, MCKEY_NOACTION);
929 g_free (valcopy);
930 g_free (value);
933 profile_keys++;
934 if (values)
935 g_strfreev (values);
937 g_strfreev (keys);
938 g_free (section_name);
941 void load_key_defs (void)
944 * Load keys from mc.lib before ~/.mc/ini, so that the user
945 * definitions override global settings.
947 mc_config_t *mc_global_config;
949 mc_global_config = mc_config_init(global_profile_name);
950 if (mc_global_config != NULL)
952 load_keys_from_section ("general", mc_global_config);
953 load_keys_from_section (getenv ("TERM"), mc_global_config);
954 mc_config_deinit(mc_global_config);
956 load_keys_from_section ("general", mc_main_config);
957 load_keys_from_section (getenv ("TERM"), mc_main_config);
961 static void
962 load_keymap_from_section (const char *section_name, GArray *keymap, mc_config_t *cfg)
964 gchar **profile_keys, **keys;
965 gchar **values, **curr_values;
966 char *valcopy, *value;
967 int action;
968 gsize len, values_len;
970 if (!section_name)
971 return;
973 profile_keys = keys = mc_config_get_keys (cfg, section_name, &len);
975 while (*profile_keys) {
976 curr_values = values = mc_config_get_string_list (cfg, section_name, *profile_keys, &values_len);
977 action = lookup_action (*profile_keys);
978 if (action>0) {
979 if (curr_values) {
980 while (*curr_values) {
981 valcopy = convert_controls (*curr_values);
982 keybind_cmd_bind (keymap, valcopy, action);
983 g_free (valcopy);
984 curr_values++;
986 } else {
987 value = mc_config_get_string (cfg, section_name, *profile_keys, "");
988 valcopy = convert_controls (value);
989 /* define_sequence (key_code, valcopy, MCKEY_NOACTION); */
990 g_free (valcopy);
991 g_free (value);
994 profile_keys++;
995 if (values)
996 g_strfreev(values);
998 g_strfreev(keys);
1001 void
1002 load_keymap_defs (void)
1005 * Load keymap from GLOBAL_KEYMAP_FILE before ~/.mc/keymap, so that the user
1006 * definitions override global settings.
1008 mc_config_t *mc_global_keymap;
1010 mc_global_keymap = load_setup_get_keymap_profile_config();
1012 if (mc_global_keymap != NULL)
1014 #ifdef USE_INTERNAL_EDIT
1015 editor_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1016 load_keymap_from_section ("editor", editor_keymap, mc_global_keymap);
1017 editor_x_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1018 load_keymap_from_section ("editor:xmap", editor_x_keymap, mc_global_keymap);
1019 #endif
1021 viewer_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1022 load_keymap_from_section ("viewer", viewer_keymap, mc_global_keymap);
1023 viewer_hex_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1024 load_keymap_from_section ("viewer:hex", viewer_hex_keymap, mc_global_keymap);
1026 main_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1027 load_keymap_from_section ("main", main_keymap, mc_global_keymap);
1028 main_x_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1029 load_keymap_from_section ("main:xmap", main_x_keymap, mc_global_keymap);
1031 panel_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1032 load_keymap_from_section ("panel", panel_keymap, mc_global_keymap);
1034 input_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1035 load_keymap_from_section ("input", input_keymap, mc_global_keymap);
1037 tree_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1038 load_keymap_from_section ("tree", tree_keymap, mc_global_keymap);
1040 help_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1041 load_keymap_from_section ("help", help_keymap, mc_global_keymap);
1043 mc_config_deinit (mc_global_keymap);
1047 void
1048 free_keymap_defs (void)
1050 #ifdef USE_INTERNAL_EDIT
1051 if (editor_keymap != NULL)
1052 g_array_free (editor_keymap, TRUE);
1053 if (editor_x_keymap != NULL)
1054 g_array_free (editor_x_keymap, TRUE);
1055 #endif
1056 if (viewer_keymap != NULL)
1057 g_array_free (viewer_keymap, TRUE);
1058 if (viewer_hex_keymap != NULL)
1059 g_array_free (viewer_hex_keymap, TRUE);
1060 if (main_keymap != NULL)
1061 g_array_free (main_keymap, TRUE);
1062 if (main_x_keymap != NULL)
1063 g_array_free (main_x_keymap, TRUE);
1064 if (panel_keymap != NULL)
1065 g_array_free (panel_keymap, TRUE);
1066 if (input_keymap != NULL)
1067 g_array_free (input_keymap, TRUE);
1068 if (tree_keymap != NULL)
1069 g_array_free (tree_keymap, TRUE);
1070 if (help_keymap != NULL)
1071 g_array_free (help_keymap, TRUE);
1074 void
1075 setup_save_config_show_error(const char *filename, GError **error)
1077 if (error == NULL || *error == NULL)
1078 return;
1080 message (D_ERROR, MSG_ERROR, _("Cannot save file %s:\n%s"),
1081 filename, (*error)->message);
1083 g_error_free(*error);
1084 *error = NULL;