Moved src/util.[ch] into lib, also moved unixcompat.h and utilunix.c.
[midnight-commander.git] / src / setup.c
blobb2a787bd0dc3e19254fd9bfc0648f9972bddf38f
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/mcconfig.h"
38 #include "lib/fileloc.h"
40 #include "args.h"
41 #include "dir.h"
42 #include "panel.h"
43 #include "main.h"
44 #include "tree.h" /* xtree_mode */
45 #include "setup.h"
46 #include "src/viewer/mcviewer.h" /* For the externs */
47 #include "hotlist.h" /* load/save/done hotlist */
48 #include "panelize.h" /* load/save/done panelize */
49 #include "layout.h"
50 #include "menu.h" /* menubar_visible declaration */
51 #include "cmd.h"
52 #include "file.h" /* safe_delete */
53 #include "keybind.h" /* lookup_action */
54 #include "wtools.h"
56 #ifdef ENABLE_VFS
57 #include "lib/vfs/mc-vfs/gc.h"
58 #endif
60 #ifdef HAVE_CHARSET
61 #include "charsets.h"
62 #endif
64 #ifdef USE_NETCODE
65 # include "lib/vfs/mc-vfs/ftpfs.h"
66 # include "lib/vfs/mc-vfs/fish.h"
67 #endif
69 #ifdef USE_INTERNAL_EDIT
70 # include "src/editor/edit.h"
71 #endif
73 #include "src/strutil.h" /* str_isutf8 () */
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_exit", &confirm_exit },
159 { "confirm_directory_hotlist_delete", &confirm_directory_hotlist_delete },
160 { "safe_delete", &safe_delete },
161 { "mouse_repeat_rate", &mou_auto_repeat },
162 { "double_click_speed", &double_click_speed },
163 #ifndef HAVE_CHARSET
164 { "eight_bit_clean", &eight_bit_clean },
165 { "full_eight_bits", &full_eight_bits },
166 #endif /* !HAVE_CHARSET */
167 { "use_8th_bit_as_meta", &use_8th_bit_as_meta },
168 { "confirm_view_dir", &confirm_view_dir },
169 { "mouse_move_pages", &mouse_move_pages },
170 { "mouse_move_pages_viewer", &mcview_mouse_move_pages },
171 { "mouse_close_dialog", &mouse_close_dialog},
172 { "fast_refresh", &fast_refresh },
173 { "navigate_with_arrows", &navigate_with_arrows },
174 { "drop_menus", &drop_menus },
175 { "wrap_mode", &mcview_global_wrap_mode},
176 { "old_esc_mode", &old_esc_mode },
177 { "cd_symlinks", &cd_symlinks },
178 { "show_all_if_ambiguous", &show_all_if_ambiguous },
179 { "max_dirt_limit", &mcview_max_dirt_limit },
180 { "torben_fj_mode", &torben_fj_mode },
181 { "use_file_to_guess_type", &use_file_to_check_type },
182 { "alternate_plus_minus", &alternate_plus_minus },
183 { "only_leading_plus_minus", &only_leading_plus_minus },
184 { "show_output_starts_shell", &output_starts_shell },
185 { "panel_scroll_pages", &panel_scroll_pages },
186 { "xtree_mode", &xtree_mode },
187 { "num_history_items_recorded", &num_history_items_recorded },
188 { "file_op_compute_totals", &file_op_compute_totals },
189 #ifdef ENABLE_VFS
190 { "vfs_timeout", &vfs_timeout },
191 #ifdef USE_NETCODE
192 { "ftpfs_directory_timeout", &ftpfs_directory_timeout },
193 { "use_netrc", &use_netrc },
194 { "ftpfs_retry_seconds", &ftpfs_retry_seconds },
195 { "ftpfs_always_use_proxy", &ftpfs_always_use_proxy },
196 { "ftpfs_use_passive_connections", &ftpfs_use_passive_connections },
197 { "ftpfs_use_passive_connections_over_proxy", &ftpfs_use_passive_connections_over_proxy },
198 { "ftpfs_use_unix_list_options", &ftpfs_use_unix_list_options },
199 { "ftpfs_first_cd_then_ls", &ftpfs_first_cd_then_ls },
200 { "fish_directory_timeout", &fish_directory_timeout },
201 #endif /* USE_NETCODE */
202 #endif /* ENABLE_VFS */
203 #ifdef USE_INTERNAL_EDIT
204 { "editor_word_wrap_line_length", &option_word_wrap_line_length },
205 { "editor_tab_spacing", &option_tab_spacing },
206 { "editor_fill_tabs_with_spaces", &option_fill_tabs_with_spaces },
207 { "editor_return_does_auto_indent", &option_return_does_auto_indent },
208 { "editor_backspace_through_tabs", &option_backspace_through_tabs },
209 { "editor_fake_half_tabs", &option_fake_half_tabs },
210 { "editor_option_save_mode", &option_save_mode },
211 { "editor_option_save_position", &option_save_position },
212 { "editor_option_auto_para_formatting", &option_auto_para_formatting },
213 { "editor_option_typewriter_wrap", &option_typewriter_wrap },
214 { "editor_edit_confirm_save", &edit_confirm_save },
215 { "editor_syntax_highlighting", &option_syntax_highlighting },
216 { "editor_persistent_selections", &option_persistent_selections },
217 { "editor_cursor_beyond_eol", &option_cursor_beyond_eol },
218 { "editor_visible_tabs", &visible_tabs },
219 { "editor_visible_spaces", &visible_tws },
220 { "editor_line_state", &option_line_state },
221 { "editor_simple_statusbar", &simple_statusbar },
222 { "editor_check_new_line", &option_check_nl_at_eof },
223 { "editor_show_right_margin", &show_right_margin },
224 #endif /* USE_INTERNAL_EDIT */
226 { "nice_rotating_dash", &nice_rotating_dash },
227 { "horizontal_split", &horizontal_split },
228 { "mcview_remember_file_position", &mcview_remember_file_position },
229 { "auto_fill_mkdir_name", &auto_fill_mkdir_name },
230 { "reverse_files_only", &reverse_files_only },
231 { "copymove_persistent_attr", &setup_copymove_persistent_attr },
232 { "select_flags", &select_flags },
233 { 0, 0 }
236 static const struct {
237 const char *opt_name;
238 char **opt_addr;
239 const char *opt_defval;
240 } str_options [] = {
241 #ifdef USE_INTERNAL_EDIT
242 { "editor_backup_extension", &option_backup_ext, "~" },
243 #endif
244 { "mcview_eof", &mcview_show_eof, "" },
245 { NULL, NULL, NULL }
248 void
249 panel_save_setup (struct WPanel *panel, const char *section)
251 char *buffer;
252 size_t i;
254 mc_config_set_int(mc_panels_config, section, "reverse", panel->reverse);
255 mc_config_set_int(mc_panels_config, section, "case_sensitive", panel->case_sensitive);
256 mc_config_set_int(mc_panels_config, section, "exec_first", panel->exec_first);
259 mc_config_set_string(mc_panels_config, section, "sort_order", panel->current_sort_field->id);
261 for (i = 0; list_types [i].key; i++)
262 if (list_types [i].list_type == panel->list_type){
263 mc_config_set_string(mc_panels_config, section, "list_mode", list_types [i].key);
264 break;
267 mc_config_set_string(mc_panels_config, section, "user_format", panel->user_format);
269 for (i = 0; i < LIST_TYPES; i++){
270 buffer = g_strdup_printf("user_status%d", i);
271 mc_config_set_string(mc_panels_config, section, buffer, panel->user_status_format [i]);
272 g_free(buffer);
275 mc_config_set_int(mc_panels_config, section, "user_mini_status", panel->user_mini_status);
278 void
279 save_layout (void)
281 char *profile;
282 int i;
284 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
286 /* Save integer options */
287 for (i = 0; layout [i].opt_name; i++){
288 mc_config_set_int(mc_main_config, "Layout", layout [i].opt_name, *layout [i].opt_addr);
290 mc_config_save_to_file (mc_main_config, profile, NULL);
292 g_free (profile);
295 void
296 save_configure (void)
298 char *profile;
299 GError *error = NULL;
300 int i;
302 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
304 /* Save integer options */
305 for (i = 0; int_options[i].opt_name; i++)
306 mc_config_set_int(mc_main_config, CONFIG_APP_SECTION, int_options[i].opt_name, *int_options[i].opt_addr);
308 /* Save string options */
309 for (i = 0; str_options[i].opt_name != NULL; i++)
310 mc_config_set_string(mc_main_config, CONFIG_APP_SECTION, str_options[i].opt_name, *str_options[i].opt_addr);
312 if (! mc_config_save_to_file (mc_main_config, profile, &error))
313 setup_save_config_show_error(profile, &error);
315 g_free (profile);
318 static void
319 panel_save_type (const char *section, panel_view_mode_t type)
321 int i;
323 for (i = 0; panel_types [i].opt_name != NULL; i++)
324 if (panel_types [i].opt_type == type) {
325 mc_config_set_string (mc_panels_config, section,
326 "display", panel_types [i].opt_name);
327 break;
331 void
332 save_panel_types (void)
334 panel_view_mode_t type;
336 if (!mc_config_get_int (mc_main_config, CONFIG_APP_SECTION,
337 "auto_save_setup_panels", auto_save_setup))
338 return;
340 type = get_display_type (0);
341 panel_save_type ("New Left Panel", type);
342 if (type == view_listing)
343 panel_save_setup (left_panel, left_panel->panel_name);
344 type = get_display_type (1);
345 panel_save_type ("New Right Panel", type);
346 if (type == view_listing)
347 panel_save_setup (right_panel, right_panel->panel_name);
349 mc_config_set_string (mc_panels_config, "Dirs" , "other_dir",
350 get_panel_dir_for (other_panel));
352 if (current_panel != NULL)
353 mc_config_set_string (mc_panels_config, "Dirs" , "current_is_left",
354 get_current_index () == 0 ? "1" : "0");
356 if (mc_panels_config->ini_path == NULL)
357 mc_panels_config->ini_path = g_strdup (panels_profile_name);
359 mc_config_del_group (mc_panels_config, "Temporal:New Left Panel");
360 mc_config_del_group (mc_panels_config, "Temporal:New Right Panel");
362 mc_config_save_file (mc_panels_config, NULL);
365 gboolean
366 save_setup (void)
368 char *tmp_profile;
369 gboolean ret;
371 saving_setup = 1;
373 save_configure ();
375 save_layout ();
377 save_hotlist ();
379 save_panelize ();
380 save_panel_types ();
381 /* directory_history_save (); */
383 #if defined(ENABLE_VFS) && defined (USE_NETCODE)
384 mc_config_set_string(mc_main_config, "Misc" , "ftpfs_password",
385 ftpfs_anonymous_passwd);
386 if (ftpfs_proxy_host)
387 mc_config_set_string(mc_main_config, "Misc" , "ftp_proxy_host",
388 ftpfs_proxy_host);
389 #endif /* ENABLE_VFS && USE_NETCODE */
391 #ifdef HAVE_CHARSET
392 mc_config_set_string(mc_main_config, "Misc" , "display_codepage",
393 get_codepage_id( display_codepage ));
394 mc_config_set_string(mc_main_config, "Misc" , "source_codepage",
395 get_codepage_id( source_codepage ));
396 #endif /* HAVE_CHARSET */
397 tmp_profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
398 ret = mc_config_save_to_file (mc_main_config, tmp_profile, NULL);
400 g_free (tmp_profile);
401 saving_setup = 0;
402 return ret;
405 void
406 panel_load_setup (WPanel *panel, const char *section)
408 size_t i;
409 char *buffer;
411 panel->reverse = mc_config_get_int(mc_panels_config, section, "reverse", 0);
412 panel->case_sensitive = mc_config_get_int(mc_panels_config, section, "case_sensitive", OS_SORT_CASE_SENSITIVE_DEFAULT);
413 panel->exec_first = mc_config_get_int(mc_panels_config, section, "exec_first", 0);
415 /* Load sort order */
416 buffer = mc_config_get_string(mc_panels_config, section, "sort_order", "name");
417 panel->current_sort_field = panel_get_field_by_id(buffer);
418 if (panel->current_sort_field == NULL )
419 panel->current_sort_field = panel_get_field_by_id("name");
421 g_free(buffer);
423 /* Load the listing mode */
424 buffer = mc_config_get_string(mc_panels_config, section, "list_mode", "full");
425 panel->list_type = list_full;
426 for (i = 0; list_types [i].key; i++)
427 if ( g_strcasecmp (list_types [i].key, buffer) == 0){
428 panel->list_type = list_types [i].list_type;
429 break;
431 g_free(buffer);
433 /* User formats */
434 g_free (panel->user_format);
435 panel->user_format = mc_config_get_string(mc_panels_config, section, "user_format", DEFAULT_USER_FORMAT);
437 for (i = 0; i < LIST_TYPES; i++){
438 g_free (panel->user_status_format [i]);
439 buffer = g_strdup_printf("user_status%d",i);
440 panel->user_status_format [i] =
441 mc_config_get_string(mc_panels_config, section, buffer, DEFAULT_USER_FORMAT);
442 g_free(buffer);
445 panel->user_mini_status =
446 mc_config_get_int(mc_panels_config, section, "user_mini_status", 0);
450 static void
451 load_layout ()
453 int i;
455 for (i = 0; layout [i].opt_name; i++)
456 *layout [i].opt_addr =
457 mc_config_get_int(mc_main_config,"Layout", layout [i].opt_name, *layout [i].opt_addr);
460 static panel_view_mode_t
461 setup__load_panel_state (const char *section)
463 char *buffer;
464 size_t i;
465 panel_view_mode_t mode = view_listing;
467 /* Load the display mode */
468 buffer = mc_config_get_string (mc_panels_config, section, "display", "listing");
470 for (i = 0; panel_types [i].opt_name != NULL; i++)
471 if (g_strcasecmp (panel_types [i].opt_name, buffer) == 0) {
472 mode = panel_types [i].opt_type;
473 break;
475 g_free (buffer);
476 return mode;
479 static const char *
480 setup__is_cfg_group_must_panel_config(const char *grp)
482 if (
483 ! strcasecmp("Dirs",grp) ||
484 ! strcasecmp("Temporal:New Right Panel",grp) ||
485 ! strcasecmp("Temporal:New Left Panel",grp) ||
486 ! strcasecmp("New Left Panel",grp) ||
487 ! strcasecmp("New Right Panel",grp)
489 return grp;
490 return NULL;
493 static void
494 setup__move_panels_config_into_separate_file(const char*profile)
496 mc_config_t *tmp_cfg;
497 char **groups, **curr_grp;
498 const char *need_grp;
500 if (!exist_file(profile))
501 return;
503 tmp_cfg = mc_config_init(profile);
504 if (!tmp_cfg)
505 return;
507 curr_grp = groups = mc_config_get_groups (tmp_cfg, NULL);
508 if (!groups)
510 mc_config_deinit(tmp_cfg);
511 return;
513 while (*curr_grp)
515 if ( setup__is_cfg_group_must_panel_config(*curr_grp) == NULL)
517 mc_config_del_group (tmp_cfg, *curr_grp);
519 curr_grp++;
522 mc_config_save_to_file (tmp_cfg, panels_profile_name, NULL);
523 mc_config_deinit(tmp_cfg);
525 tmp_cfg = mc_config_init(profile);
526 if (!tmp_cfg)
528 g_strfreev(groups);
529 return;
532 curr_grp = groups;
534 while (*curr_grp)
536 need_grp = setup__is_cfg_group_must_panel_config(*curr_grp);
537 if ( need_grp != NULL)
539 mc_config_del_group (tmp_cfg, need_grp);
541 curr_grp++;
543 g_strfreev(groups);
544 mc_config_save_file (tmp_cfg, NULL);
545 mc_config_deinit(tmp_cfg);
550 Get name of config file.
552 \param subdir
553 if not NULL, then config also search into specified subdir
555 \param config_file_name
556 If specified filename is relative, then will search in standart patches.
558 \return
559 Newly allocated path to config name or NULL if file not found
561 If config_file_name is a relative path, then search config in stantart pathes */
562 static char*
563 load_setup_get_full_config_name(const char *subdir, const char *config_file_name)
566 TODO: IMHO, in future this function must be placed into mc_config module.
567 Also, need to rename stupid mc_home and mc_home_alt to mc_sysconfdir and mc_datadir;
568 home_mc => mc_user_homedir
570 char *lc_basename, *ret;
572 if (config_file_name == NULL)
573 return NULL;
575 if (g_path_is_absolute (config_file_name))
576 return g_strdup(config_file_name);
579 lc_basename = g_path_get_basename(config_file_name);
580 if (lc_basename == NULL)
581 return NULL;
584 if (subdir)
585 ret = g_build_filename (home_dir, MC_USERCONF_DIR, subdir, lc_basename, NULL);
586 else
587 ret = g_build_filename (home_dir, MC_USERCONF_DIR, lc_basename, NULL);
589 if (exist_file(ret)) {
590 g_free(lc_basename);
591 return ret;
593 g_free(ret);
596 if (subdir)
597 ret = g_build_filename (mc_home, subdir, lc_basename, NULL);
598 else
599 ret = g_build_filename (mc_home, lc_basename, NULL);
601 if (exist_file(ret)) {
602 g_free(lc_basename);
603 return ret;
605 g_free(ret);
607 if (subdir)
608 ret = g_build_filename (mc_home_alt, subdir, lc_basename, NULL);
609 else
610 ret = g_build_filename (mc_home_alt, lc_basename, NULL);
612 if (exist_file(ret)) {
613 g_free(lc_basename);
614 return ret;
616 g_free(ret);
617 g_free(lc_basename);
618 return NULL;
623 Create new mc_config object from specified ini-file or
624 append data to existing mc_config object from ini-file
627 static void
628 load_setup_init_config_from_file(mc_config_t **config, const char *fname)
631 TODO: IMHO, in future this function must be placed into mc_config module.
633 if (exist_file(fname)) {
634 if (*config)
635 mc_config_read_file( *config, fname);
636 else
637 *config = mc_config_init(fname);
643 static mc_config_t *
644 load_setup_get_keymap_profile_config(void)
647 TODO: IMHO, in future this function must be placed into mc_config module.
649 mc_config_t *keymap_config = NULL ;
651 char *fname, *fname2;
653 /* 1) /usr/share/mc (mc_home_alt) */
654 fname = g_build_filename (mc_home_alt, GLOBAL_KEYMAP_FILE, NULL);
655 load_setup_init_config_from_file( &keymap_config, fname);
656 g_free(fname);
658 /* 2) /etc/mc (mc_home) */
659 fname = g_build_filename (mc_home, GLOBAL_KEYMAP_FILE, NULL);
660 load_setup_init_config_from_file( &keymap_config, fname);
661 g_free(fname);
663 /* 3) ~/.mc (home_dir?) */
664 fname = g_build_filename (home_dir, MC_USERCONF_DIR, GLOBAL_KEYMAP_FILE, NULL);
665 load_setup_init_config_from_file( &keymap_config, fname);
666 g_free(fname);
668 /* 4) main config; [Midnight Commander] -> keymap*/
670 fname2 = mc_config_get_string(mc_main_config, CONFIG_APP_SECTION, "keymap" , GLOBAL_KEYMAP_FILE);
671 fname = load_setup_get_full_config_name(NULL, fname2);
672 if (fname)
674 load_setup_init_config_from_file( &keymap_config, fname);
675 g_free(fname);
677 g_free(fname2);
679 /* 5) getenv("MC_KEYMAP") */
680 fname = load_setup_get_full_config_name(NULL, g_getenv ("MC_KEYMAP"));
681 if (fname)
683 load_setup_init_config_from_file( &keymap_config, fname);
684 g_free(fname);
687 /* 6) --keymap=<keymap> */
688 fname = load_setup_get_full_config_name(NULL, mc_args__keymap_file);
689 if (fname)
691 load_setup_init_config_from_file( &keymap_config, fname);
692 g_free(fname);
695 return keymap_config;
698 char *
699 setup_init (void)
701 char *profile;
702 char *inifile;
704 if (profile_name)
705 return profile_name;
707 profile = g_build_filename (home_dir, MC_USERCONF_DIR, MC_CONFIG_FILE, NULL);
708 if (!exist_file (profile)){
709 inifile = concat_dir_and_file (mc_home, "mc.ini");
710 if (exist_file (inifile)){
711 g_free (profile);
712 profile = inifile;
713 } else {
714 g_free (inifile);
715 inifile = concat_dir_and_file (mc_home_alt, "mc.ini");
716 if (exist_file (inifile)) {
717 g_free (profile);
718 profile = inifile;
719 } else
720 g_free (inifile);
724 profile_name = profile;
726 return profile;
729 void
730 load_setup (void)
732 char *profile;
733 int i;
734 char *buffer;
736 profile = setup_init ();
738 /* mc.lib is common for all users, but has priority lower than
739 ~/.mc/ini. FIXME: it's only used for keys and treestore now */
740 global_profile_name = concat_dir_and_file (mc_home, MC_GLOBAL_CONFIG_FILE);
741 if (!exist_file(global_profile_name)) {
742 g_free (global_profile_name);
743 global_profile_name = concat_dir_and_file (mc_home_alt, MC_GLOBAL_CONFIG_FILE);
746 panels_profile_name = g_build_filename (home_dir, MC_USERCONF_DIR, MC_PANELS_FILE, NULL);
748 mc_main_config = mc_config_init(profile);
750 if (!exist_file(panels_profile_name))
751 setup__move_panels_config_into_separate_file(profile);
753 mc_panels_config = mc_config_init(panels_profile_name);
755 /* Load integer boolean options */
756 for (i = 0; int_options[i].opt_name; i++)
757 *int_options[i].opt_addr =
758 mc_config_get_int(mc_main_config, CONFIG_APP_SECTION, int_options[i].opt_name, *int_options[i].opt_addr);
760 /* Load string options */
761 for (i = 0; str_options[i].opt_name != NULL; i++)
762 *str_options[i].opt_addr =
763 mc_config_get_string (mc_main_config, CONFIG_APP_SECTION, str_options[i].opt_name, str_options[i].opt_defval);
765 load_layout ();
767 load_panelize ();
769 startup_left_mode = setup__load_panel_state ("New Left Panel");
770 startup_right_mode = setup__load_panel_state ("New Right Panel");
772 /* At least one of the panels is a listing panel */
773 if (startup_left_mode != view_listing && startup_right_mode != view_listing)
774 startup_left_mode = view_listing;
776 if (!other_dir){
777 buffer = mc_config_get_string(mc_panels_config, "Dirs", "other_dir", ".");
778 if (vfs_file_is_local (buffer))
779 other_dir = buffer;
780 else
781 g_free (buffer);
784 boot_current_is_left =
785 mc_config_get_int(mc_panels_config, "Dirs", "current_is_left", 1);
787 #ifdef USE_NETCODE
788 ftpfs_proxy_host = mc_config_get_string(mc_main_config, "Misc", "ftp_proxy_host", "gate");
789 #endif
791 /* The default color and the terminal dependent color */
792 setup_color_string = mc_config_get_string(mc_main_config, "Colors", "base_color", "");
793 term_color_string = mc_config_get_string(mc_main_config, "Colors", getenv ("TERM"), "");
794 color_terminal_string = mc_config_get_string(mc_main_config, "Colors", "color_terminals", "");
796 /* Load the directory history */
797 /* directory_history_load (); */
798 /* Remove the temporal entries */
799 #if defined(ENABLE_VFS) && defined (USE_NETCODE)
800 ftpfs_init_passwd ();
801 #endif /* ENABLE_VFS && USE_NETCODE */
803 #ifdef HAVE_CHARSET
804 if ( load_codepages_list() > 0 ) {
805 buffer = mc_config_get_string(mc_main_config, "Misc", "display_codepage", "");
806 if ( buffer[0] != '\0' )
808 display_codepage = get_codepage_index( buffer );
809 cp_display = get_codepage_id (display_codepage);
811 g_free(buffer);
812 buffer = mc_config_get_string(mc_main_config, "Misc", "source_codepage", "");
813 if ( buffer[0] != '\0' )
815 source_codepage = get_codepage_index( buffer );
816 cp_source = get_codepage_id (source_codepage);
818 g_free(buffer);
820 init_translation_table( source_codepage, display_codepage );
821 if ( get_codepage_id( display_codepage ) )
822 utf8_display = str_isutf8 (get_codepage_id( display_codepage ));
823 #endif /* HAVE_CHARSET */
826 #if defined(ENABLE_VFS) && defined (USE_NETCODE)
827 char *
828 load_anon_passwd ()
830 char *buffer;
832 buffer = mc_config_get_string(mc_main_config, "Misc", "ftpfs_password", "");
833 if (buffer [0])
834 return buffer;
836 g_free(buffer);
837 return NULL;
839 #endif /* ENABLE_VFS && USE_NETCODE */
841 void
842 done_setup (void)
844 int i;
846 g_free (profile_name);
847 g_free (global_profile_name);
848 g_free (color_terminal_string);
849 g_free (term_color_string);
850 g_free (setup_color_string);
851 g_free (panels_profile_name);
852 mc_config_deinit (mc_main_config);
853 mc_config_deinit (mc_panels_config);
855 for (i = 0; str_options[i].opt_name != NULL; i++)
856 g_free (*str_options[i].opt_addr);
858 done_hotlist ();
859 done_panelize ();
860 /* directory_history_free (); */
863 static void
864 load_keys_from_section (const char *terminal, mc_config_t *cfg)
866 char *section_name;
867 gchar **profile_keys, **keys;
868 gchar **values, **curr_values;
869 char *valcopy, *value;
870 long key_code;
871 gsize len, values_len;
873 if (!terminal)
874 return;
876 section_name = g_strconcat ("terminal:", terminal, (char *) NULL);
877 profile_keys = keys = mc_config_get_keys (cfg, section_name, &len);
879 while (*profile_keys){
881 /* copy=other causes all keys from [terminal:other] to be loaded. */
882 if (g_strcasecmp (*profile_keys, "copy") == 0) {
883 valcopy = mc_config_get_string (cfg, section_name, *profile_keys, "");
884 load_keys_from_section (valcopy, cfg);
885 g_free(valcopy);
886 profile_keys++;
887 continue;
889 curr_values = values = mc_config_get_string_list (cfg, section_name, *profile_keys, &values_len);
891 key_code = lookup_key (*profile_keys, NULL);
892 if (key_code != 0) {
893 if (curr_values){
894 while (*curr_values){
895 valcopy = convert_controls (*curr_values);
896 define_sequence (key_code, valcopy, MCKEY_NOACTION);
897 g_free (valcopy);
898 curr_values++;
900 } else {
901 value = mc_config_get_string (cfg, section_name, *profile_keys, "");
902 valcopy = convert_controls (value);
903 define_sequence (key_code, valcopy, MCKEY_NOACTION);
904 g_free (valcopy);
905 g_free (value);
908 profile_keys++;
909 if (values)
910 g_strfreev (values);
912 g_strfreev (keys);
913 g_free (section_name);
916 void load_key_defs (void)
919 * Load keys from mc.lib before ~/.mc/ini, so that the user
920 * definitions override global settings.
922 mc_config_t *mc_global_config;
924 mc_global_config = mc_config_init(global_profile_name);
925 if (mc_global_config != NULL)
927 load_keys_from_section ("general", mc_global_config);
928 load_keys_from_section (getenv ("TERM"), mc_global_config);
929 mc_config_deinit(mc_global_config);
931 load_keys_from_section ("general", mc_main_config);
932 load_keys_from_section (getenv ("TERM"), mc_main_config);
936 static void
937 load_keymap_from_section (const char *section_name, GArray *keymap, mc_config_t *cfg)
939 gchar **profile_keys, **keys;
940 gchar **values, **curr_values;
941 char *valcopy, *value;
942 int action;
943 gsize len, values_len;
945 if (!section_name)
946 return;
948 profile_keys = keys = mc_config_get_keys (cfg, section_name, &len);
950 while (*profile_keys) {
951 curr_values = values = mc_config_get_string_list (cfg, section_name, *profile_keys, &values_len);
952 action = lookup_action (*profile_keys);
953 if (action>0) {
954 if (curr_values) {
955 while (*curr_values) {
956 valcopy = convert_controls (*curr_values);
957 keybind_cmd_bind (keymap, valcopy, action);
958 g_free (valcopy);
959 curr_values++;
961 } else {
962 value = mc_config_get_string (cfg, section_name, *profile_keys, "");
963 valcopy = convert_controls (value);
964 /* define_sequence (key_code, valcopy, MCKEY_NOACTION); */
965 g_free (valcopy);
966 g_free (value);
969 profile_keys++;
970 if (values)
971 g_strfreev(values);
973 g_strfreev(keys);
976 void
977 load_keymap_defs (void)
980 * Load keymap from GLOBAL_KEYMAP_FILE before ~/.mc/keymap, so that the user
981 * definitions override global settings.
983 mc_config_t *mc_global_keymap;
985 mc_global_keymap = load_setup_get_keymap_profile_config();
987 if (mc_global_keymap != NULL)
989 #ifdef USE_INTERNAL_EDIT
990 editor_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
991 load_keymap_from_section ("editor", editor_keymap, mc_global_keymap);
992 editor_x_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
993 load_keymap_from_section ("editor:xmap", editor_x_keymap, mc_global_keymap);
994 #endif
996 viewer_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
997 load_keymap_from_section ("viewer", viewer_keymap, mc_global_keymap);
998 viewer_hex_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
999 load_keymap_from_section ("viewer:hex", viewer_hex_keymap, mc_global_keymap);
1001 main_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1002 load_keymap_from_section ("main", main_keymap, mc_global_keymap);
1003 main_x_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1004 load_keymap_from_section ("main:xmap", main_x_keymap, mc_global_keymap);
1006 panel_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1007 load_keymap_from_section ("panel", panel_keymap, mc_global_keymap);
1009 input_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1010 load_keymap_from_section ("input", input_keymap, mc_global_keymap);
1012 tree_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1013 load_keymap_from_section ("tree", tree_keymap, mc_global_keymap);
1015 help_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1016 load_keymap_from_section ("help", help_keymap, mc_global_keymap);
1018 mc_config_deinit (mc_global_keymap);
1022 void
1023 free_keymap_defs (void)
1025 #ifdef USE_INTERNAL_EDIT
1026 if (editor_keymap != NULL)
1027 g_array_free (editor_keymap, TRUE);
1028 if (editor_x_keymap != NULL)
1029 g_array_free (editor_x_keymap, TRUE);
1030 #endif
1031 if (viewer_keymap != NULL)
1032 g_array_free (viewer_keymap, TRUE);
1033 if (viewer_hex_keymap != NULL)
1034 g_array_free (viewer_hex_keymap, TRUE);
1035 if (main_keymap != NULL)
1036 g_array_free (main_keymap, TRUE);
1037 if (main_x_keymap != NULL)
1038 g_array_free (main_x_keymap, TRUE);
1039 if (panel_keymap != NULL)
1040 g_array_free (panel_keymap, TRUE);
1041 if (input_keymap != NULL)
1042 g_array_free (input_keymap, TRUE);
1043 if (tree_keymap != NULL)
1044 g_array_free (tree_keymap, TRUE);
1045 if (help_keymap != NULL)
1046 g_array_free (help_keymap, TRUE);
1049 void
1050 setup_save_config_show_error(const char *filename, GError **error)
1052 if (error == NULL || *error == NULL)
1053 return;
1055 message (D_ERROR, MSG_ERROR, _("Cannot save file %s:\n%s"),
1056 filename, (*error)->message);
1058 g_error_free(*error);
1059 *error = NULL;