/* vifm * Copyright (C) 2001 Ken Steen. * Copyright (C) 2011 xaizek. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include "modes.h" #include <curses.h> #include <stddef.h> /* wchar_t */ #include "../engine/keys.h" #include "../engine/mode.h" #include "../ui/statusbar.h" #include "../ui/statusline.h" #include "../ui/ui.h" #include "../utils/log.h" #include "../utils/macros.h" #include "../compare.h" #include "../event_loop.h" #include "../status.h" #include "dialogs/attr_dialog.h" #include "dialogs/change_dialog.h" #include "dialogs/msg_dialog.h" #include "dialogs/sort_dialog.h" #include "cmdline.h" #include "file_info.h" #include "menu.h" #include "more.h" #include "normal.h" #include "view.h" #include "visual.h" static int mode_flags[] = { MF_USES_COUNT | MF_USES_REGS, /* NORMAL_MODE */ MF_USES_INPUT, /* CMDLINE_MODE */ MF_USES_INPUT, /* NAV_MODE */ MF_USES_COUNT | MF_USES_REGS, /* VISUAL_MODE */ MF_USES_COUNT, /* MENU_MODE */ MF_USES_COUNT, /* SORT_MODE */ MF_USES_COUNT, /* ATTR_MODE */ MF_USES_COUNT, /* CHANGE_MODE */ MF_USES_COUNT, /* VIEW_MODE */ 0, /* FILE_INFO_MODE */ 0, /* MSG_MODE */ 0, /* MORE_MODE */ }; ARRAY_GUARD(mode_flags, MODES_COUNT); static char uses_input_bar[] = { 1, /* NORMAL_MODE */ 0, /* CMDLINE_MODE */ 0, /* NAV_MODE */ 1, /* VISUAL_MODE */ 1, /* MENU_MODE */ 1, /* SORT_MODE */ 1, /* ATTR_MODE */ 1, /* CHANGE_MODE */ 1, /* VIEW_MODE */ 1, /* FILE_INFO_MODE */ 0, /* MSG_MODE */ 0, /* MORE_MODE */ }; ARRAY_GUARD(uses_input_bar, MODES_COUNT); typedef void (*mode_init_func)(void); static mode_init_func mode_init_funcs[] = { &modnorm_init, /* NORMAL_MODE */ &modcline_init, /* CMDLINE_MODE */ &modnav_init, /* NAV_MODE */ &modvis_init, /* VISUAL_MODE */ &modmenu_init, /* MENU_MODE */ &init_sort_dialog_mode, /* SORT_MODE */ &init_attr_dialog_mode, /* ATTR_MODE */ &init_change_dialog_mode, /* CHANGE_MODE */ &modview_init, /* VIEW_MODE */ &modfinfo_init, /* FILE_INFO_MODE */ &init_msg_dialog_mode, /* MSG_MODE */ &modmore_init, /* MORE_MODE */ }; ARRAY_GUARD(mode_init_funcs, MODES_COUNT); static void print_compare_stats(void); static void update_vmode_input(void); void modes_init(void) { LOG_FUNC_ENTER; vle_keys_init(MODES_COUNT, mode_flags, &stats_silence_ui); vle_mode_set(NORMAL_MODE, VMT_PRIMARY); int i; for(i = 0; i < MODES_COUNT; ++i) { mode_init_funcs[i](); } } void modes_pre(void) { if(ANY(vle_mode_is, SORT_MODE, CHANGE_MODE, ATTR_MODE, MORE_MODE)) { /* Do nothing for these modes. */ } else if(modes_is_cmdline_like()) { touchwin(status_bar); ui_refresh_win(status_bar); } else if(vle_mode_is(VIEW_MODE)) { modview_pre(); } else if(modes_is_menu_like()) { modmenu_pre(); } else if(!curr_stats.save_msg) { ui_sb_clear(); ui_refresh_win(status_bar); } } void modes_periodic(void) { /* Trigger possible view updates. */ modview_check_for_updates(); } void modes_post(void) { if(ANY(vle_mode_is, CMDLINE_MODE, NAV_MODE, SORT_MODE, CHANGE_MODE, ATTR_MODE, MORE_MODE)) { /* Do nothing for these modes. */ return; } else if(vle_mode_is(VIEW_MODE)) { modview_post(); return; } else if(modes_is_menu_like()) { modmenu_post(); return; } update_screen(stats_update_fetch()); if(curr_stats.save_msg) { ui_sb_msg(NULL); } if(!vle_mode_is(FILE_INFO_MODE) && curr_view->list_rows > 0) { if(!ui_sb_multiline()) { ui_stat_update(curr_view, 0); ui_ruler_update(curr_view, 1); } } modes_statusbar_update(); } void modes_statusbar_update(void) { if(ANY(vle_mode_is, MORE_MODE, CMDLINE_MODE, NAV_MODE)) { return; } else if(curr_stats.save_msg != 0) { if(vle_mode_is(VISUAL_MODE)) { update_vmode_input(); } return; } if(modes_is_menu_like()) { ui_sb_clear(); return; } if(vle_mode_is(VISUAL_MODE)) { ui_sb_msgf("-- %s -- ", modvis_describe()); update_vmode_input(); curr_stats.save_msg = 2; } else if(curr_view->selected_files) { ui_sb_msgf("%d %s selected", curr_view->selected_files, curr_view->selected_files == 1 ? "file" : "files"); curr_stats.save_msg = 2; } else if(cv_compare(curr_view->custom.type)) { print_compare_stats(); } else { ui_sb_clear(); } } void modes_redraw(void) { LOG_FUNC_ENTER; static int in_here; if(curr_stats.load_stage < 2) { return; } if(in_here++ > 0) { /* TODO: is this still needed? Update scheduling might have solved issues * caused by asynchronous execution of this function in the past. */ return; } if(curr_stats.term_state != TS_NORMAL) { update_screen(UT_REDRAW); goto finish; } if(modes_is_cmdline_like()) { modcline_redraw(); goto finish; } else if(vle_primary_mode_is(MENU_MODE)) { modmenu_full_redraw(); if(vle_mode_is(MSG_MODE)) { redraw_msg_dialog(0); } goto finish; } else if(vle_mode_is(FILE_INFO_MODE)) { modfinfo_redraw(); goto finish; } else if(vle_mode_is(MORE_MODE)) { modmore_redraw(); goto finish; } UpdateType update = stats_update_fetch(); if(update == UT_NONE) { update_screen(UT_REDRAW); } else { update_screen(update); } if(curr_stats.save_msg) { ui_sb_msg(NULL); } if(vle_mode_is(SORT_MODE)) { redraw_sort_dialog(); } else if(vle_mode_is(CHANGE_MODE)) { redraw_change_dialog(); } else if(vle_mode_is(ATTR_MODE)) { redraw_attr_dialog(); } else if(vle_mode_is(VIEW_MODE)) { modview_redraw(); } else if(vle_mode_is(MSG_MODE)) { redraw_msg_dialog(0); } finish: if(--in_here > 0) { modes_redraw(); } } void modes_update(void) { if(modes_is_cmdline_like()) { modcline_redraw(); return; } else if(vle_mode_is(MENU_MODE)) { modmenu_full_redraw(); return; } else if(vle_mode_is(FILE_INFO_MODE)) { modfinfo_redraw(); return; } touchwin(stdscr); update_all_windows(); if(vle_mode_is(SORT_MODE)) { redraw_sort_dialog(); } else if(vle_mode_is(CHANGE_MODE)) { redraw_change_dialog(); } else if(vle_mode_is(ATTR_MODE)) { redraw_attr_dialog(); } } void modes_input_bar_update(const wchar_t str[]) { if(vle_mode_is(VISUAL_MODE)) { modes_input_bar_clear(); } if(uses_input_bar[vle_mode_get()]) { update_input_bar(str); } } void modes_input_bar_clear(void) { if(uses_input_bar[vle_mode_get()] && !vle_mode_is(VISUAL_MODE)) { clear_num_window(); } } int modes_is_menu_like(void) { return ANY(vle_primary_mode_is, MENU_MODE, FILE_INFO_MODE, MORE_MODE); } int modes_is_dialog_like(void) { return ANY(vle_mode_is, SORT_MODE, ATTR_MODE, CHANGE_MODE, MSG_MODE); } int modes_is_cmdline_like(void) { return ANY(vle_mode_is, CMDLINE_MODE, NAV_MODE); } void modes_abort_menu_like(void) { if(vle_primary_mode_is(MENU_MODE)) { modmenu_abort(); } else if(vle_primary_mode_is(FILE_INFO_MODE)) { modfinfo_abort(); } else if(vle_primary_mode_is(MORE_MODE)) { modmore_abort(); } } /* Prints compare stats on status line. */ static void print_compare_stats(void) { int flags = curr_view->custom.diff_cmp_flags; const compare_stats_t *stats = &curr_view->custom.diff_stats; if(flags & CF_SINGLE_PANE) { return; } if(flags & CF_GROUP_PATHS) { ui_sb_msgf("(on compare) " "%cidentical: %d, %cdifferent: %d, %c/%cunique: %d/%d", flags & CF_SHOW_IDENTICAL ? '+' : '-', stats->identical, flags & CF_SHOW_DIFFERENT ? '+' : '-', stats->different, flags & CF_SHOW_UNIQUE_LEFT ? '+' : '-', flags & CF_SHOW_UNIQUE_RIGHT ? '+' : '-', stats->unique_left, stats->unique_right); } else { ui_sb_msgf("(on compare) %cidentical: %d, %c/%cunique: %d/%d", flags & CF_SHOW_IDENTICAL ? '+' : '-', stats->identical, flags & CF_SHOW_UNIQUE_LEFT ? '+' : '-', flags & CF_SHOW_UNIQUE_RIGHT ? '+' : '-', stats->unique_left, stats->unique_right); } curr_stats.save_msg = 2; } static void update_vmode_input(void) { if(is_input_buf_empty()) { werase(input_win); checked_wmove(input_win, 0, 0); wprintw(input_win, "%d", curr_view->selected_files); ui_refresh_win(input_win); } } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */ /* vim: set cinoptions+=t0 filetype=c : */