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