Ticket #2689 (fix fallocate detection for xBSD)
[midnight-commander.git] / src / setup.c
blobf97f4d438c0f41b8aa4344692cde176e38e9bd81
1 /*
2 Setup loading/saving.
4 Copyright (C) 1994, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
5 2006, 2007, 2009, 2010, 2011
6 The Free Software Foundation, Inc.
8 This file is part of the Midnight Commander.
10 The Midnight Commander is free software: you can redistribute it
11 and/or modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation, either version 3 of the License,
13 or (at your option) any later version.
15 The Midnight Commander is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 /** \file setup.c
25 * \brief Source: setup loading/saving
28 #include <config.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <stdio.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
36 #include "lib/global.h"
38 #include "lib/tty/tty.h"
39 #include "lib/tty/key.h"
40 #include "lib/mcconfig.h"
41 #include "lib/fileloc.h"
42 #include "lib/timefmt.h"
43 #include "lib/util.h"
44 #include "lib/widget.h"
46 #include "lib/vfs/vfs.h"
48 #ifdef ENABLE_VFS_FTP
49 #include "src/vfs/ftpfs/ftpfs.h"
50 #endif
51 #ifdef ENABLE_VFS_FISH
52 #include "src/vfs/fish/fish.h"
53 #endif
55 #ifdef HAVE_CHARSET
56 #include "lib/charsets.h"
57 #endif
59 #include "filemanager/dir.h"
60 #include "filemanager/midnight.h"
61 #include "filemanager/tree.h" /* xtree_mode */
62 #include "filemanager/hotlist.h" /* load/save/done hotlist */
63 #include "filemanager/panelize.h" /* load/save/done panelize */
64 #include "filemanager/layout.h"
65 #include "filemanager/cmd.h"
67 #include "args.h"
68 #include "execute.h" /* pause_after_run */
69 #include "clipboard.h"
70 #include "keybind-defaults.h" /* keybind_lookup_action */
72 #ifdef HAVE_CHARSET
73 #include "selcodepage.h"
74 #endif
76 #ifdef USE_INTERNAL_EDIT
77 #include "src/editor/edit.h"
78 #endif
80 #include "src/viewer/mcviewer.h" /* For the externs */
82 #include "setup.h"
84 /*** global variables ****************************************************************************/
86 char *profile_name; /* ${XDG_CONFIG_HOME}/mc/ini */
87 char *global_profile_name; /* mc.lib */
89 /* Only used at program boot */
90 gboolean boot_current_is_left = TRUE;
92 /* If on, default for "No" in delete operations */
93 int safe_delete = 0;
95 /* Controls screen clearing before an exec */
96 int clear_before_exec = 1;
98 /* Asks for confirmation before deleting a file */
99 int confirm_delete = 1;
100 /* Asks for confirmation before deleting a hotlist entry */
101 int confirm_directory_hotlist_delete = 1;
102 /* Asks for confirmation before overwriting a file */
103 int confirm_overwrite = 1;
104 /* Asks for confirmation before executing a program by pressing enter */
105 int confirm_execute = 0;
106 /* Asks for confirmation before leaving the program */
107 int confirm_exit = 1;
109 /* If true, at startup the user-menu is invoked */
110 int auto_menu = 0;
111 /* This flag indicates if the pull down menus by default drop down */
112 int drop_menus = 0;
114 /* Asks for confirmation when using F3 to view a directory and there
115 are tagged files */
116 int confirm_view_dir = 0;
118 panel_view_mode_t startup_left_mode;
119 panel_view_mode_t startup_right_mode;
121 int setup_copymove_persistent_attr = 1;
123 /* Tab size */
124 int option_tab_spacing = DEFAULT_TAB_SPACING;
126 /* Ugly hack to allow panel_save_setup to work as a place holder for */
127 /* default panel values */
128 int saving_setup;
130 panels_options_t panels_options = {
131 .show_mini_info = TRUE,
132 .kilobyte_si = FALSE,
133 .mix_all_files = FALSE,
134 .show_backups = TRUE,
135 .show_dot_files = TRUE,
136 .fast_reload = FALSE,
137 .fast_reload_msg_shown = FALSE,
138 .mark_moves_down = TRUE,
139 .reverse_files_only = TRUE,
140 .auto_save_setup = FALSE,
141 .navigate_with_arrows = FALSE,
142 .scroll_pages = TRUE,
143 .mouse_move_pages = TRUE,
144 .filetype_mode = TRUE,
145 .permission_mode = FALSE,
146 .qsearch_mode = QSEARCH_PANEL_CASE,
147 .torben_fj_mode = FALSE
150 int easy_patterns = 1;
152 /* It true saves the setup when quitting */
153 int auto_save_setup = 1;
155 /* If true, then the +, - and \ keys have their special meaning only if the
156 * command line is emtpy, otherwise they behave like regular letters
158 int only_leading_plus_minus = 1;
160 /* Automatically fills name with current selected item name on mkdir */
161 int auto_fill_mkdir_name = 1;
163 /* If set and you don't have subshell support,then C-o will give you a shell */
164 int output_starts_shell = 0;
166 /* If set, we execute the file command to check the file type */
167 int use_file_to_check_type = 1;
169 int verbose = 1;
172 * Whether the Midnight Commander tries to provide more
173 * information about copy/move sizes and bytes transfered
174 * at the expense of some speed
176 int file_op_compute_totals = 1;
178 /*** file scope macro definitions ****************************************************************/
180 /* In order to use everywhere the same setup for the locale we use defines */
181 #define FMTYEAR _("%b %e %Y")
182 #define FMTTIME _("%b %e %H:%M")
184 /*** file scope type declarations ****************************************************************/
186 /*** file scope variables ************************************************************************/
188 static char *panels_profile_name = NULL; /* ${XDG_CACHE_HOME}/mc/panels.ini */
190 /* *INDENT-OFF* */
191 static const struct
193 const char *key;
194 int list_type;
195 } list_types [] = {
196 { "full", list_full },
197 { "brief", list_brief },
198 { "long", list_long },
199 { "user", list_user },
200 { NULL, 0 }
203 static const struct
205 const char *opt_name;
206 panel_view_mode_t opt_type;
207 } panel_types [] = {
208 { "listing", view_listing },
209 { "quickview", view_quick },
210 { "info", view_info },
211 { "tree", view_tree },
212 { NULL, view_listing }
215 static const struct
217 const char *opt_name;
218 int *opt_addr;
219 } layout [] = {
220 { "equal_split", &equal_split },
221 { "first_panel_size", &first_panel_size },
222 { "message_visible", &mc_global.message_visible },
223 { "keybar_visible", &mc_global.keybar_visible },
224 { "xterm_title", &xterm_title },
225 { "output_lines", &output_lines },
226 { "command_prompt", &command_prompt },
227 { "menubar_visible", &menubar_visible },
228 { "free_space", &free_space },
229 { NULL, NULL }
232 static const struct
234 const char *opt_name;
235 int *opt_addr;
236 } int_options [] = {
237 { "verbose", &verbose },
238 { "pause_after_run", &pause_after_run },
239 { "shell_patterns", &easy_patterns },
240 { "auto_save_setup", &auto_save_setup },
241 { "preallocate_space", &mc_global.vfs.preallocate_space },
242 { "auto_menu", &auto_menu },
243 { "use_internal_view", &use_internal_view },
244 { "use_internal_edit", &use_internal_edit },
245 { "clear_before_exec", &clear_before_exec },
246 { "confirm_delete", &confirm_delete },
247 { "confirm_overwrite", &confirm_overwrite },
248 { "confirm_execute", &confirm_execute },
249 { "confirm_history_cleanup", &mc_global.widget.confirm_history_cleanup },
250 { "confirm_exit", &confirm_exit },
251 { "confirm_directory_hotlist_delete", &confirm_directory_hotlist_delete },
252 { "safe_delete", &safe_delete },
253 { "mouse_repeat_rate", &mou_auto_repeat },
254 { "double_click_speed", &double_click_speed },
255 #ifndef HAVE_CHARSET
256 { "eight_bit_clean", &mc_global.eight_bit_clean },
257 { "full_eight_bits", &mc_global.full_eight_bits },
258 #endif /* !HAVE_CHARSET */
259 { "use_8th_bit_as_meta", &use_8th_bit_as_meta },
260 { "confirm_view_dir", &confirm_view_dir },
261 { "mouse_move_pages_viewer", &mcview_mouse_move_pages },
262 { "mouse_close_dialog", &mouse_close_dialog},
263 { "fast_refresh", &fast_refresh },
264 { "drop_menus", &drop_menus },
265 { "wrap_mode", &mcview_global_wrap_mode},
266 { "old_esc_mode", &old_esc_mode },
267 { "old_esc_mode_timeout", &old_esc_mode_timeout },
268 { "cd_symlinks", &mc_global.vfs.cd_symlinks },
269 { "show_all_if_ambiguous", &mc_global.widget.show_all_if_ambiguous },
270 { "max_dirt_limit", &mcview_max_dirt_limit },
271 { "use_file_to_guess_type", &use_file_to_check_type },
272 { "alternate_plus_minus", &mc_global.tty.alternate_plus_minus },
273 { "only_leading_plus_minus", &only_leading_plus_minus },
274 { "show_output_starts_shell", &output_starts_shell },
275 { "xtree_mode", &xtree_mode },
276 { "num_history_items_recorded", &num_history_items_recorded },
277 { "file_op_compute_totals", &file_op_compute_totals },
278 { "classic_progressbar", &classic_progressbar},
279 #ifdef ENABLE_VFS
280 { "vfs_timeout", &vfs_timeout },
281 #ifdef ENABLE_VFS_FTP
282 { "ftpfs_directory_timeout", &ftpfs_directory_timeout },
283 { "use_netrc", &ftpfs_use_netrc },
284 { "ftpfs_retry_seconds", &ftpfs_retry_seconds },
285 { "ftpfs_always_use_proxy", &ftpfs_always_use_proxy },
286 { "ftpfs_use_passive_connections", &ftpfs_use_passive_connections },
287 { "ftpfs_use_passive_connections_over_proxy", &ftpfs_use_passive_connections_over_proxy },
288 { "ftpfs_use_unix_list_options", &ftpfs_use_unix_list_options },
289 { "ftpfs_first_cd_then_ls", &ftpfs_first_cd_then_ls },
290 #endif /* ENABLE_VFS_FTP */
291 #ifdef ENABLE_VFS_FISH
292 { "fish_directory_timeout", &fish_directory_timeout },
293 #endif /* ENABLE_VFS_FISH */
294 #endif /* ENABLE_VFS */
295 /* option_tab_spacing is used in internal viewer */
296 { "editor_tab_spacing", &option_tab_spacing },
297 #ifdef USE_INTERNAL_EDIT
298 { "editor_word_wrap_line_length", &option_word_wrap_line_length },
299 { "editor_fill_tabs_with_spaces", &option_fill_tabs_with_spaces },
300 { "editor_return_does_auto_indent", &option_return_does_auto_indent },
301 { "editor_backspace_through_tabs", &option_backspace_through_tabs },
302 { "editor_fake_half_tabs", &option_fake_half_tabs },
303 { "editor_option_save_mode", &option_save_mode },
304 { "editor_option_save_position", &option_save_position },
305 { "editor_option_auto_para_formatting", &option_auto_para_formatting },
306 { "editor_option_typewriter_wrap", &option_typewriter_wrap },
307 { "editor_edit_confirm_save", &edit_confirm_save },
308 { "editor_syntax_highlighting", &option_syntax_highlighting },
309 { "editor_persistent_selections", &option_persistent_selections },
310 { "editor_cursor_beyond_eol", &option_cursor_beyond_eol },
311 { "editor_visible_tabs", &visible_tabs },
312 { "editor_visible_spaces", &visible_tws },
313 { "editor_line_state", &option_line_state },
314 { "editor_simple_statusbar", &simple_statusbar },
315 { "editor_check_new_line", &option_check_nl_at_eof },
316 { "editor_show_right_margin", &show_right_margin },
317 { "editor_group_undo", &option_group_undo },
318 #endif /* USE_INTERNAL_EDIT */
319 { "nice_rotating_dash", &nice_rotating_dash },
320 { "horizontal_split", &horizontal_split },
321 { "mcview_remember_file_position", &mcview_remember_file_position },
322 { "auto_fill_mkdir_name", &auto_fill_mkdir_name },
323 { "copymove_persistent_attr", &setup_copymove_persistent_attr },
324 { "select_flags", &select_flags },
325 { NULL, NULL }
328 static const struct
330 const char *opt_name;
331 char **opt_addr;
332 const char *opt_defval;
333 } str_options[] = {
334 #ifdef USE_INTERNAL_EDIT
335 { "editor_backup_extension", &option_backup_ext, "~" },
336 #endif
337 { "mcview_eof", &mcview_show_eof, "" },
338 { NULL, NULL, NULL }
341 static const struct
343 const char *opt_name;
344 gboolean *opt_addr;
345 } panels_ini_options[] = {
346 { "show_mini_info", &panels_options.show_mini_info },
347 { "kilobyte_si", &panels_options.kilobyte_si },
348 { "mix_all_files", &panels_options.mix_all_files },
349 { "show_backups", &panels_options.show_backups },
350 { "show_dot_files", &panels_options.show_dot_files },
351 { "fast_reload", &panels_options.fast_reload },
352 { "fast_reload_msg_shown", &panels_options.fast_reload_msg_shown },
353 { "mark_moves_down", &panels_options.mark_moves_down },
354 { "reverse_files_only", &panels_options.reverse_files_only },
355 { "auto_save_setup_panels", &panels_options.auto_save_setup },
356 { "navigate_with_arrows", &panels_options.navigate_with_arrows },
357 { "panel_scroll_pages", &panels_options.scroll_pages },
358 { "mouse_move_pages", &panels_options.mouse_move_pages },
359 { "filetype_mode", &panels_options.filetype_mode },
360 { "permission_mode", &panels_options.permission_mode },
361 { "torben_fj_mode", &panels_options.torben_fj_mode },
362 { NULL, NULL }
364 /* *INDENT-ON* */
366 /*** file scope functions ************************************************************************/
367 /* --------------------------------------------------------------------------------------------- */
370 Get name of config file.
372 \param subdir
373 if not NULL, then config also search into specified subdir.
375 \param config_file_name
376 If specified filename is relative, then will search in standart patches.
378 \return
379 Newly allocated path to config name or NULL if file not found.
381 If config_file_name is a relative path, then search config in stantart paths.
383 static char *
384 load_setup_get_full_config_name (const char *subdir, const char *config_file_name)
387 TODO: IMHO, in future this function must be placed into mc_config module.
389 char *lc_basename, *ret;
391 if (config_file_name == NULL)
392 return NULL;
394 if (g_path_is_absolute (config_file_name))
395 return g_strdup (config_file_name);
398 lc_basename = g_path_get_basename (config_file_name);
399 if (lc_basename == NULL)
400 return NULL;
402 if (subdir != NULL)
403 ret = g_build_filename (mc_config_get_path (), subdir, lc_basename, NULL);
404 else
405 ret = g_build_filename (mc_config_get_path (), lc_basename, NULL);
407 if (exist_file (ret))
409 g_free (lc_basename);
410 return ret;
412 g_free (ret);
414 if (subdir != NULL)
415 ret = g_build_filename (mc_global.sysconfig_dir, subdir, lc_basename, NULL);
416 else
417 ret = g_build_filename (mc_global.sysconfig_dir, lc_basename, NULL);
419 if (exist_file (ret))
421 g_free (lc_basename);
422 return ret;
424 g_free (ret);
426 if (subdir != NULL)
427 ret = g_build_filename (mc_global.share_data_dir, subdir, lc_basename, NULL);
428 else
429 ret = g_build_filename (mc_global.share_data_dir, lc_basename, NULL);
431 g_free (lc_basename);
433 if (exist_file (ret))
434 return ret;
436 g_free (ret);
437 return NULL;
441 /* --------------------------------------------------------------------------------------------- */
443 static const char *
444 setup__is_cfg_group_must_panel_config (const char *grp)
446 return (!strcasecmp ("Dirs", grp) ||
447 !strcasecmp ("Temporal:New Right Panel", grp) ||
448 !strcasecmp ("Temporal:New Left Panel", grp) ||
449 !strcasecmp ("New Left Panel", grp) || !strcasecmp ("New Right Panel", grp))
450 ? grp : NULL;
453 /* --------------------------------------------------------------------------------------------- */
455 static void
456 setup__move_panels_config_into_separate_file (const char *profile)
458 mc_config_t *tmp_cfg;
459 char **groups, **curr_grp;
460 const char *need_grp;
462 if (!exist_file (profile))
463 return;
465 tmp_cfg = mc_config_init (profile);
466 if (!tmp_cfg)
467 return;
469 curr_grp = groups = mc_config_get_groups (tmp_cfg, NULL);
470 if (!groups)
472 mc_config_deinit (tmp_cfg);
473 return;
476 while (*curr_grp)
478 if (setup__is_cfg_group_must_panel_config (*curr_grp) == NULL)
479 mc_config_del_group (tmp_cfg, *curr_grp);
480 curr_grp++;
483 mc_config_save_to_file (tmp_cfg, panels_profile_name, NULL);
484 mc_config_deinit (tmp_cfg);
486 tmp_cfg = mc_config_init (profile);
487 if (!tmp_cfg)
489 g_strfreev (groups);
490 return;
493 curr_grp = groups;
495 while (*curr_grp)
497 need_grp = setup__is_cfg_group_must_panel_config (*curr_grp);
498 if (need_grp != NULL)
500 mc_config_del_group (tmp_cfg, need_grp);
502 curr_grp++;
504 g_strfreev (groups);
506 mc_config_save_file (tmp_cfg, NULL);
507 mc_config_deinit (tmp_cfg);
510 /* --------------------------------------------------------------------------------------------- */
512 Create new mc_config object from specified ini-file or
513 append data to existing mc_config object from ini-file
516 static void
517 load_setup_init_config_from_file (mc_config_t ** config, const char *fname)
520 TODO: IMHO, in future this function must be placed into mc_config module.
522 if (exist_file (fname))
524 if (*config != NULL)
525 mc_config_read_file (*config, fname, TRUE);
526 else
527 *config = mc_config_init (fname);
531 /* --------------------------------------------------------------------------------------------- */
533 static void
534 load_layout (void)
536 size_t i;
538 for (i = 0; layout[i].opt_name != NULL; i++)
539 *layout[i].opt_addr = mc_config_get_int (mc_main_config, "Layout",
540 layout[i].opt_name, *layout[i].opt_addr);
543 /* --------------------------------------------------------------------------------------------- */
545 static void
546 load_keys_from_section (const char *terminal, mc_config_t * cfg)
548 char *section_name;
549 gchar **profile_keys, **keys;
550 gchar **values, **curr_values;
551 char *valcopy, *value;
552 long key_code;
553 gsize len, values_len;
555 if (terminal == NULL)
556 return;
558 section_name = g_strconcat ("terminal:", terminal, (char *) NULL);
559 profile_keys = keys = mc_config_get_keys (cfg, section_name, &len);
561 while (*profile_keys != NULL)
563 /* copy=other causes all keys from [terminal:other] to be loaded. */
564 if (g_ascii_strcasecmp (*profile_keys, "copy") == 0)
566 valcopy = mc_config_get_string (cfg, section_name, *profile_keys, "");
567 load_keys_from_section (valcopy, cfg);
568 g_free (valcopy);
569 profile_keys++;
570 continue;
573 curr_values = values =
574 mc_config_get_string_list (cfg, section_name, *profile_keys, &values_len);
576 key_code = lookup_key (*profile_keys, NULL);
578 if (key_code != 0)
580 if (curr_values != NULL)
582 while (*curr_values != NULL)
584 valcopy = convert_controls (*curr_values);
585 define_sequence (key_code, valcopy, MCKEY_NOACTION);
586 g_free (valcopy);
587 curr_values++;
590 else
592 value = mc_config_get_string (cfg, section_name, *profile_keys, "");
593 valcopy = convert_controls (value);
594 define_sequence (key_code, valcopy, MCKEY_NOACTION);
595 g_free (valcopy);
596 g_free (value);
600 profile_keys++;
601 g_strfreev (values);
603 g_strfreev (keys);
604 g_free (section_name);
607 /* --------------------------------------------------------------------------------------------- */
609 static void
610 load_keymap_from_section (const char *section_name, GArray * keymap, mc_config_t * cfg)
612 gchar **profile_keys, **keys;
613 gsize len;
615 if (section_name == NULL)
616 return;
618 profile_keys = keys = mc_config_get_keys (cfg, section_name, &len);
620 while (*profile_keys != NULL)
622 gchar **values, **curr_values;
624 curr_values = values = mc_config_get_string_list (cfg, section_name, *profile_keys, &len);
626 if (curr_values != NULL)
628 int action;
630 action = keybind_lookup_action (*profile_keys);
631 if (action > 0)
632 while (*curr_values != NULL)
634 keybind_cmd_bind (keymap, *curr_values, action);
635 curr_values++;
638 g_strfreev (values);
641 profile_keys++;
644 g_strfreev (keys);
647 /* --------------------------------------------------------------------------------------------- */
649 static mc_config_t *
650 load_setup_get_keymap_profile_config (gboolean load_from_file)
653 TODO: IMHO, in future this function must be placed into mc_config module.
655 mc_config_t *keymap_config;
656 char *fname, *fname2;
658 /* 0) Create default keymap */
659 keymap_config = create_default_keymap ();
660 if (!load_from_file)
661 return keymap_config;
663 /* 1) /usr/share/mc (mc_global.share_data_dir) */
664 fname = g_build_filename (mc_global.share_data_dir, GLOBAL_KEYMAP_FILE, NULL);
665 load_setup_init_config_from_file (&keymap_config, fname);
666 g_free (fname);
668 /* 2) /etc/mc (mc_global.sysconfig_dir) */
669 fname = g_build_filename (mc_global.sysconfig_dir, GLOBAL_KEYMAP_FILE, NULL);
670 load_setup_init_config_from_file (&keymap_config, fname);
671 g_free (fname);
673 /* 3) ${XDG_CONFIG_HOME}/mc */
674 fname = mc_config_get_full_path (GLOBAL_KEYMAP_FILE);
675 load_setup_init_config_from_file (&keymap_config, fname);
676 g_free (fname);
678 /* 4) main config; [Midnight Commander] -> keymap */
679 fname2 =
680 mc_config_get_string (mc_main_config, CONFIG_APP_SECTION, "keymap", GLOBAL_KEYMAP_FILE);
681 fname = load_setup_get_full_config_name (NULL, fname2);
682 if (fname != NULL)
684 load_setup_init_config_from_file (&keymap_config, fname);
685 g_free (fname);
687 g_free (fname2);
689 /* 5) getenv("MC_KEYMAP") */
690 fname = load_setup_get_full_config_name (NULL, g_getenv ("MC_KEYMAP"));
691 if (fname != NULL)
693 load_setup_init_config_from_file (&keymap_config, fname);
694 g_free (fname);
697 /* 6) --keymap=<keymap> */
698 fname = load_setup_get_full_config_name (NULL, mc_args__keymap_file);
699 if (fname != NULL)
701 load_setup_init_config_from_file (&keymap_config, fname);
702 g_free (fname);
705 return keymap_config;
708 /* --------------------------------------------------------------------------------------------- */
710 static panel_view_mode_t
711 setup__load_panel_state (const char *section)
713 char *buffer;
714 size_t i;
715 panel_view_mode_t mode = view_listing;
717 /* Load the display mode */
718 buffer = mc_config_get_string (mc_panels_config, section, "display", "listing");
720 for (i = 0; panel_types[i].opt_name != NULL; i++)
721 if (g_ascii_strcasecmp (panel_types[i].opt_name, buffer) == 0)
723 mode = panel_types[i].opt_type;
724 break;
727 g_free (buffer);
729 return mode;
732 /* --------------------------------------------------------------------------------------------- */
734 static void
735 panel_save_type (const char *section, panel_view_mode_t type)
737 size_t i;
739 for (i = 0; panel_types[i].opt_name != NULL; i++)
740 if (panel_types[i].opt_type == type)
742 mc_config_set_string (mc_panels_config, section, "display", panel_types[i].opt_name);
743 break;
747 /* --------------------------------------------------------------------------------------------- */
749 /* save panels.ini */
750 static void
751 save_panel_types (void)
753 panel_view_mode_t type;
755 if (mc_global.mc_run_mode != MC_RUN_FULL)
756 return;
758 type = get_display_type (0);
759 panel_save_type ("New Left Panel", type);
760 if (type == view_listing)
761 panel_save_setup (left_panel, left_panel->panel_name);
762 type = get_display_type (1);
763 panel_save_type ("New Right Panel", type);
764 if (type == view_listing)
765 panel_save_setup (right_panel, right_panel->panel_name);
767 mc_config_set_string (mc_panels_config, "Dirs", "other_dir", get_panel_dir_for (other_panel));
769 if (current_panel != NULL)
770 mc_config_set_string (mc_panels_config, "Dirs", "current_is_left",
771 get_current_index () == 0 ? "1" : "0");
773 if (mc_panels_config->ini_path == NULL)
774 mc_panels_config->ini_path = g_strdup (panels_profile_name);
776 mc_config_del_group (mc_panels_config, "Temporal:New Left Panel");
777 mc_config_del_group (mc_panels_config, "Temporal:New Right Panel");
779 mc_config_save_file (mc_panels_config, NULL);
782 /* --------------------------------------------------------------------------------------------- */
783 /*** public functions ****************************************************************************/
784 /* --------------------------------------------------------------------------------------------- */
786 char *
787 setup_init (void)
789 char *profile;
790 char *inifile;
792 if (profile_name != NULL)
793 return profile_name;
795 profile = mc_config_get_full_path (MC_CONFIG_FILE);
796 if (!exist_file (profile))
798 inifile = concat_dir_and_file (mc_global.sysconfig_dir, "mc.ini");
799 if (exist_file (inifile))
801 g_free (profile);
802 profile = inifile;
804 else
806 g_free (inifile);
807 inifile = concat_dir_and_file (mc_global.share_data_dir, "mc.ini");
808 if (exist_file (inifile))
810 g_free (profile);
811 profile = inifile;
813 else
814 g_free (inifile);
818 profile_name = profile;
820 return profile;
823 /* --------------------------------------------------------------------------------------------- */
825 void
826 load_setup (void)
828 char *profile;
829 size_t i;
830 char *buffer;
831 const char *kt;
833 #ifdef HAVE_CHARSET
834 load_codepages_list ();
835 #endif /* HAVE_CHARSET */
837 profile = setup_init ();
839 /* mc.lib is common for all users, but has priority lower than
840 ${XDG_CONFIG_HOME}/mc/ini. FIXME: it's only used for keys and treestore now */
841 global_profile_name =
842 g_build_filename (mc_global.sysconfig_dir, MC_GLOBAL_CONFIG_FILE, (char *) NULL);
843 if (!exist_file (global_profile_name))
845 g_free (global_profile_name);
846 global_profile_name =
847 g_build_filename (mc_global.share_data_dir, MC_GLOBAL_CONFIG_FILE, (char *) NULL);
850 panels_profile_name = mc_config_get_full_path (MC_PANELS_FILE);
852 mc_main_config = mc_config_init (profile);
854 if (!exist_file (panels_profile_name))
855 setup__move_panels_config_into_separate_file (profile);
857 mc_panels_config = mc_config_init (panels_profile_name);
859 /* Load integer boolean options */
860 for (i = 0; int_options[i].opt_name != NULL; i++)
861 *int_options[i].opt_addr =
862 mc_config_get_int (mc_main_config, CONFIG_APP_SECTION, int_options[i].opt_name,
863 *int_options[i].opt_addr);
865 if (option_tab_spacing <= 0)
866 option_tab_spacing = DEFAULT_TAB_SPACING;
868 #ifdef USE_INTERNAL_EDIT
869 if (option_word_wrap_line_length <= 0)
870 option_word_wrap_line_length = DEFAULT_WRAP_LINE_LENGTH;
871 #endif /* USE_INTERNAL_EDIT */
873 /* overwrite old_esc_mode_timeout */
874 kt = getenv ("KEYBOARD_KEY_TIMEOUT_US");
875 if ((kt != NULL) && (kt[0] != '\0'))
876 old_esc_mode_timeout = atoi (kt);
878 /* Load string options */
879 for (i = 0; str_options[i].opt_name != NULL; i++)
880 *str_options[i].opt_addr =
881 mc_config_get_string (mc_main_config, CONFIG_APP_SECTION, str_options[i].opt_name,
882 str_options[i].opt_defval);
884 load_layout ();
885 panels_load_options ();
886 load_panelize ();
888 startup_left_mode = setup__load_panel_state ("New Left Panel");
889 startup_right_mode = setup__load_panel_state ("New Right Panel");
891 /* At least one of the panels is a listing panel */
892 if (startup_left_mode != view_listing && startup_right_mode != view_listing)
893 startup_left_mode = view_listing;
895 if (mc_run_param1 == NULL)
897 vfs_path_t *vpath;
898 buffer = mc_config_get_string (mc_panels_config, "Dirs", "other_dir", ".");
899 vpath = vfs_path_from_str (buffer);
900 if (vfs_file_is_local (vpath))
901 mc_run_param1 = buffer;
902 else
903 g_free (buffer);
904 vfs_path_free (vpath);
907 boot_current_is_left = mc_config_get_bool (mc_panels_config, "Dirs", "current_is_left", TRUE);
909 /* Load time formats */
910 user_recent_timeformat =
911 mc_config_get_string (mc_main_config, "Misc", "timeformat_recent", FMTTIME);
912 user_old_timeformat = mc_config_get_string (mc_main_config, "Misc", "timeformat_old", FMTYEAR);
914 #ifdef ENABLE_VFS_FTP
915 ftpfs_proxy_host = mc_config_get_string (mc_main_config, "Misc", "ftp_proxy_host", "gate");
916 ftpfs_ignore_chattr_errors = mc_config_get_bool (mc_main_config, CONFIG_APP_SECTION,
917 "ignore_ftp_chattr_errors", TRUE);
918 ftpfs_init_passwd ();
919 #endif /* ENABLE_VFS_FTP */
921 /* The default color and the terminal dependent color */
922 mc_global.tty.setup_color_string =
923 mc_config_get_string (mc_main_config, "Colors", "base_color", "");
924 mc_global.tty.term_color_string =
925 mc_config_get_string (mc_main_config, "Colors", getenv ("TERM"), "");
926 mc_global.tty.color_terminal_string =
927 mc_config_get_string (mc_main_config, "Colors", "color_terminals", "");
929 /* Load the directory history */
930 /* directory_history_load (); */
931 /* Remove the temporal entries */
933 #ifdef HAVE_CHARSET
934 if (codepages->len > 1)
936 buffer = mc_config_get_string (mc_main_config, "Misc", "display_codepage", "");
937 if (buffer[0] != '\0')
939 mc_global.display_codepage = get_codepage_index (buffer);
940 cp_display = get_codepage_id (mc_global.display_codepage);
942 g_free (buffer);
943 buffer = mc_config_get_string (mc_main_config, "Misc", "source_codepage", "");
944 if (buffer[0] != '\0')
946 default_source_codepage = get_codepage_index (buffer);
947 mc_global.source_codepage = default_source_codepage; /* May be source_codepage doesn't need this */
948 cp_source = get_codepage_id (mc_global.source_codepage);
950 g_free (buffer);
953 autodetect_codeset = mc_config_get_string (mc_main_config, "Misc", "autodetect_codeset", "");
954 if ((autodetect_codeset[0] != '\0') && (strcmp (autodetect_codeset, "off") != 0))
955 is_autodetect_codeset_enabled = TRUE;
957 g_free (init_translation_table (mc_global.source_codepage, mc_global.display_codepage));
958 buffer = (char *) get_codepage_id (mc_global.display_codepage);
959 if (buffer != NULL)
960 mc_global.utf8_display = str_isutf8 (buffer);
961 #endif /* HAVE_CHARSET */
963 clipboard_store_path = mc_config_get_string (mc_main_config, "Misc", "clipboard_store", "");
964 clipboard_paste_path = mc_config_get_string (mc_main_config, "Misc", "clipboard_paste", "");
967 /* --------------------------------------------------------------------------------------------- */
969 gboolean
970 save_setup (gboolean save_options, gboolean save_panel_options)
972 gboolean ret = TRUE;
974 saving_setup = 1;
976 save_hotlist ();
978 if (save_panel_options)
979 save_panel_types ();
981 if (save_options)
983 char *tmp_profile;
985 save_config ();
986 save_layout ();
987 panels_save_options ();
988 save_panelize ();
989 /* directory_history_save (); */
991 #ifdef ENABLE_VFS_FTP
992 mc_config_set_string (mc_main_config, "Misc", "ftpfs_password", ftpfs_anonymous_passwd);
993 if (ftpfs_proxy_host)
994 mc_config_set_string (mc_main_config, "Misc", "ftp_proxy_host", ftpfs_proxy_host);
995 #endif /* ENABLE_VFS_FTP */
997 #ifdef HAVE_CHARSET
998 mc_config_set_string (mc_main_config, "Misc", "display_codepage",
999 get_codepage_id (mc_global.display_codepage));
1000 mc_config_set_string (mc_main_config, "Misc", "source_codepage",
1001 get_codepage_id (default_source_codepage));
1002 mc_config_set_string (mc_main_config, "Misc", "autodetect_codeset", autodetect_codeset);
1003 #endif /* HAVE_CHARSET */
1004 mc_config_set_string (mc_main_config, "Misc", "clipboard_store", clipboard_store_path);
1005 mc_config_set_string (mc_main_config, "Misc", "clipboard_paste", clipboard_paste_path);
1007 tmp_profile = mc_config_get_full_path (MC_CONFIG_FILE);
1008 ret = mc_config_save_to_file (mc_main_config, tmp_profile, NULL);
1009 g_free (tmp_profile);
1012 saving_setup = 0;
1014 return ret;
1017 /* --------------------------------------------------------------------------------------------- */
1019 void
1020 done_setup (void)
1022 size_t i;
1024 g_free (clipboard_store_path);
1025 g_free (clipboard_paste_path);
1026 g_free (profile_name);
1027 g_free (global_profile_name);
1028 g_free (mc_global.tty.color_terminal_string);
1029 g_free (mc_global.tty.term_color_string);
1030 g_free (mc_global.tty.setup_color_string);
1031 g_free (panels_profile_name);
1032 mc_config_deinit (mc_main_config);
1033 mc_config_deinit (mc_panels_config);
1035 g_free (user_recent_timeformat);
1036 g_free (user_old_timeformat);
1038 for (i = 0; str_options[i].opt_name != NULL; i++)
1039 g_free (*str_options[i].opt_addr);
1041 done_hotlist ();
1042 done_panelize ();
1043 /* directory_history_free (); */
1045 #ifdef HAVE_CHARSET
1046 g_free (autodetect_codeset);
1047 free_codepages_list ();
1048 #endif
1051 /* --------------------------------------------------------------------------------------------- */
1053 void
1054 save_config (void)
1056 size_t i;
1058 /* Save integer options */
1059 for (i = 0; int_options[i].opt_name != NULL; i++)
1060 mc_config_set_int (mc_main_config, CONFIG_APP_SECTION, int_options[i].opt_name,
1061 *int_options[i].opt_addr);
1063 /* Save string options */
1064 for (i = 0; str_options[i].opt_name != NULL; i++)
1065 mc_config_set_string (mc_main_config, CONFIG_APP_SECTION, str_options[i].opt_name,
1066 *str_options[i].opt_addr);
1069 /* --------------------------------------------------------------------------------------------- */
1071 void
1072 setup_save_config_show_error (const char *filename, GError ** error)
1074 if (error != NULL && *error != NULL)
1076 message (D_ERROR, MSG_ERROR, _("Cannot save file %s:\n%s"), filename, (*error)->message);
1077 g_error_free (*error);
1078 *error = NULL;
1082 /* --------------------------------------------------------------------------------------------- */
1084 void
1085 save_layout (void)
1087 size_t i;
1089 /* Save integer options */
1090 for (i = 0; layout[i].opt_name != NULL; i++)
1091 mc_config_set_int (mc_main_config, "Layout", layout[i].opt_name, *layout[i].opt_addr);
1094 /* --------------------------------------------------------------------------------------------- */
1096 void
1097 load_key_defs (void)
1100 * Load keys from mc.lib before ${XDG_CONFIG_HOME}/mc/ini, so that the user
1101 * definitions override global settings.
1103 mc_config_t *mc_global_config;
1105 mc_global_config = mc_config_init (global_profile_name);
1106 if (mc_global_config != NULL)
1108 load_keys_from_section ("general", mc_global_config);
1109 load_keys_from_section (getenv ("TERM"), mc_global_config);
1110 mc_config_deinit (mc_global_config);
1113 load_keys_from_section ("general", mc_main_config);
1114 load_keys_from_section (getenv ("TERM"), mc_main_config);
1117 /* --------------------------------------------------------------------------------------------- */
1119 #ifdef ENABLE_VFS_FTP
1120 char *
1121 load_anon_passwd (void)
1123 char *buffer;
1125 buffer = mc_config_get_string (mc_main_config, "Misc", "ftpfs_password", "");
1127 if ((buffer != NULL) && (buffer[0] != '\0'))
1128 return buffer;
1130 g_free (buffer);
1131 return NULL;
1133 #endif /* ENABLE_VFS_FTP */
1135 /* --------------------------------------------------------------------------------------------- */
1137 void
1138 load_keymap_defs (gboolean load_from_file)
1141 * Load keymap from GLOBAL_KEYMAP_FILE before ${XDG_CONFIG_HOME}/mc/mc.keymap, so that the user
1142 * definitions override global settings.
1144 mc_config_t *mc_global_keymap;
1146 mc_global_keymap = load_setup_get_keymap_profile_config (load_from_file);
1148 if (mc_global_keymap != NULL)
1150 main_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1151 load_keymap_from_section (KEYMAP_SECTION_MAIN, main_keymap, mc_global_keymap);
1152 main_x_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1153 load_keymap_from_section (KEYMAP_SECTION_MAIN_EXT, main_x_keymap, mc_global_keymap);
1155 panel_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1156 load_keymap_from_section (KEYMAP_SECTION_PANEL, panel_keymap, mc_global_keymap);
1158 dialog_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1159 load_keymap_from_section (KEYMAP_SECTION_DIALOG, dialog_keymap, mc_global_keymap);
1161 input_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1162 load_keymap_from_section (KEYMAP_SECTION_INPUT, input_keymap, mc_global_keymap);
1164 listbox_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1165 load_keymap_from_section (KEYMAP_SECTION_LISTBOX, listbox_keymap, mc_global_keymap);
1167 tree_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1168 load_keymap_from_section (KEYMAP_SECTION_TREE, tree_keymap, mc_global_keymap);
1170 help_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1171 load_keymap_from_section (KEYMAP_SECTION_HELP, help_keymap, mc_global_keymap);
1173 #ifdef USE_INTERNAL_EDIT
1174 editor_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1175 load_keymap_from_section (KEYMAP_SECTION_EDITOR, editor_keymap, mc_global_keymap);
1176 editor_x_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1177 load_keymap_from_section (KEYMAP_SECTION_EDITOR_EXT, editor_x_keymap, mc_global_keymap);
1178 #endif
1180 viewer_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1181 load_keymap_from_section (KEYMAP_SECTION_VIEWER, viewer_keymap, mc_global_keymap);
1182 viewer_hex_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1183 load_keymap_from_section (KEYMAP_SECTION_VIEWER_HEX, viewer_hex_keymap, mc_global_keymap);
1185 #ifdef USE_DIFF_VIEW
1186 diff_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t));
1187 load_keymap_from_section (KEYMAP_SECTION_DIFFVIEWER, diff_keymap, mc_global_keymap);
1188 #endif
1190 mc_config_deinit (mc_global_keymap);
1193 main_map = (global_keymap_t *) main_keymap->data;
1194 main_x_map = (global_keymap_t *) main_x_keymap->data;
1195 panel_map = (global_keymap_t *) panel_keymap->data;
1196 dialog_map = (global_keymap_t *) dialog_keymap->data;
1197 input_map = (global_keymap_t *) input_keymap->data;
1198 listbox_map = (global_keymap_t *) listbox_keymap->data;
1199 tree_map = (global_keymap_t *) tree_keymap->data;
1200 help_map = (global_keymap_t *) help_keymap->data;
1201 #ifdef USE_INTERNAL_EDIT
1202 editor_map = (global_keymap_t *) editor_keymap->data;
1203 editor_x_map = (global_keymap_t *) editor_x_keymap->data;
1204 #endif
1205 viewer_map = (global_keymap_t *) viewer_keymap->data;
1206 viewer_hex_map = (global_keymap_t *) viewer_hex_keymap->data;
1207 #ifdef USE_DIFF_VIEW
1208 diff_map = (global_keymap_t *) diff_keymap->data;
1209 #endif
1212 /* --------------------------------------------------------------------------------------------- */
1214 void
1215 free_keymap_defs (void)
1217 if (main_keymap != NULL)
1218 g_array_free (main_keymap, TRUE);
1219 if (main_x_keymap != NULL)
1220 g_array_free (main_x_keymap, TRUE);
1221 if (panel_keymap != NULL)
1222 g_array_free (panel_keymap, TRUE);
1223 if (dialog_keymap != NULL)
1224 g_array_free (dialog_keymap, TRUE);
1225 if (input_keymap != NULL)
1226 g_array_free (input_keymap, TRUE);
1227 if (listbox_keymap != NULL)
1228 g_array_free (listbox_keymap, TRUE);
1229 if (tree_keymap != NULL)
1230 g_array_free (tree_keymap, TRUE);
1231 if (help_keymap != NULL)
1232 g_array_free (help_keymap, TRUE);
1233 #ifdef USE_INTERNAL_EDIT
1234 if (editor_keymap != NULL)
1235 g_array_free (editor_keymap, TRUE);
1236 if (editor_x_keymap != NULL)
1237 g_array_free (editor_x_keymap, TRUE);
1238 #endif
1239 if (viewer_keymap != NULL)
1240 g_array_free (viewer_keymap, TRUE);
1241 if (viewer_hex_keymap != NULL)
1242 g_array_free (viewer_hex_keymap, TRUE);
1243 #ifdef USE_DIFF_VIEW
1244 if (diff_keymap != NULL)
1245 g_array_free (diff_keymap, TRUE);
1246 #endif
1249 /* --------------------------------------------------------------------------------------------- */
1251 void
1252 panel_load_setup (WPanel * panel, const char *section)
1254 size_t i;
1255 char *buffer, buffer2[BUF_TINY];
1257 panel->sort_info.reverse = mc_config_get_int (mc_panels_config, section, "reverse", 0);
1258 panel->sort_info.case_sensitive =
1259 mc_config_get_int (mc_panels_config, section, "case_sensitive",
1260 OS_SORT_CASE_SENSITIVE_DEFAULT);
1261 panel->sort_info.exec_first = mc_config_get_int (mc_panels_config, section, "exec_first", 0);
1263 /* Load sort order */
1264 buffer = mc_config_get_string (mc_panels_config, section, "sort_order", "name");
1265 panel->sort_info.sort_field = panel_get_field_by_id (buffer);
1266 if (panel->sort_info.sort_field == NULL)
1267 panel->sort_info.sort_field = panel_get_field_by_id ("name");
1269 g_free (buffer);
1271 /* Load the listing mode */
1272 buffer = mc_config_get_string (mc_panels_config, section, "list_mode", "full");
1273 panel->list_type = list_full;
1274 for (i = 0; list_types[i].key != NULL; i++)
1275 if (g_ascii_strcasecmp (list_types[i].key, buffer) == 0)
1277 panel->list_type = list_types[i].list_type;
1278 break;
1280 g_free (buffer);
1282 /* User formats */
1283 g_free (panel->user_format);
1284 panel->user_format =
1285 mc_config_get_string (mc_panels_config, section, "user_format", DEFAULT_USER_FORMAT);
1287 for (i = 0; i < LIST_TYPES; i++)
1289 g_free (panel->user_status_format[i]);
1290 g_snprintf (buffer2, BUF_TINY, "user_status%lld", (long long) i);
1291 panel->user_status_format[i] =
1292 mc_config_get_string (mc_panels_config, section, buffer2, DEFAULT_USER_FORMAT);
1295 panel->user_mini_status = mc_config_get_int (mc_panels_config, section, "user_mini_status", 0);
1298 /* --------------------------------------------------------------------------------------------- */
1300 void
1301 panel_save_setup (struct WPanel *panel, const char *section)
1303 char buffer[BUF_TINY];
1304 size_t i;
1306 mc_config_set_int (mc_panels_config, section, "reverse", panel->sort_info.reverse);
1307 mc_config_set_int (mc_panels_config, section, "case_sensitive",
1308 panel->sort_info.case_sensitive);
1309 mc_config_set_int (mc_panels_config, section, "exec_first", panel->sort_info.exec_first);
1311 mc_config_set_string (mc_panels_config, section, "sort_order", panel->sort_info.sort_field->id);
1313 for (i = 0; list_types[i].key != NULL; i++)
1314 if (list_types[i].list_type == panel->list_type)
1316 mc_config_set_string (mc_panels_config, section, "list_mode", list_types[i].key);
1317 break;
1320 mc_config_set_string (mc_panels_config, section, "user_format", panel->user_format);
1322 for (i = 0; i < LIST_TYPES; i++)
1324 g_snprintf (buffer, BUF_TINY, "user_status%lld", (long long) i);
1325 mc_config_set_string (mc_panels_config, section, buffer, panel->user_status_format[i]);
1328 mc_config_set_int (mc_panels_config, section, "user_mini_status", panel->user_mini_status);
1331 /* --------------------------------------------------------------------------------------------- */
1334 Load panels options from [Panels] section.
1336 void
1337 panels_load_options (void)
1339 if (mc_config_has_group (mc_main_config, CONFIG_PANELS_SECTION))
1341 size_t i;
1342 int qmode;
1344 for (i = 0; panels_ini_options[i].opt_name != NULL; i++)
1345 *panels_ini_options[i].opt_addr =
1346 mc_config_get_bool (mc_main_config, CONFIG_PANELS_SECTION,
1347 panels_ini_options[i].opt_name,
1348 *panels_ini_options[i].opt_addr);
1350 qmode = mc_config_get_int (mc_main_config, CONFIG_PANELS_SECTION,
1351 "quick_search_mode", (int) panels_options.qsearch_mode);
1352 if (qmode < 0)
1353 panels_options.qsearch_mode = QSEARCH_CASE_INSENSITIVE;
1354 else if (qmode >= QSEARCH_NUM)
1355 panels_options.qsearch_mode = QSEARCH_PANEL_CASE;
1356 else
1357 panels_options.qsearch_mode = (qsearch_mode_t) qmode;
1361 /* --------------------------------------------------------------------------------------------- */
1364 Save panels options in [Panels] section.
1366 void
1367 panels_save_options (void)
1369 size_t i;
1371 for (i = 0; panels_ini_options[i].opt_name != NULL; i++)
1372 mc_config_set_bool (mc_main_config, CONFIG_PANELS_SECTION,
1373 panels_ini_options[i].opt_name, *panels_ini_options[i].opt_addr);
1375 mc_config_set_int (mc_main_config, CONFIG_PANELS_SECTION,
1376 "quick_search_mode", (int) panels_options.qsearch_mode);
1379 /* --------------------------------------------------------------------------------------------- */